实战教程:Leaflet+SpringBoot 实现地图任意点位点击查看时间功能

实战教程:Leaflet+SpringBoot 实现地图任意点位点击查看时间功能

目录

前言

一、需求解析

1、地图展示

2、时区和时间的关系

3、经纬度和时区的关系

二、应用实现

1、经纬度和时区求解

2、Leaflet 实现地图点击

3、前后台交互

三、成果展示

1、亚洲地区

2、欧洲地区

3、拉美地区

4、澳洲地区

四、总结


前言

        在数字化、全球化的当下,地理位置与时间信息的结合应用,已经渗透到出行导航、跨境调度、物流追踪、国际业务展示等众多场景。用户不再满足于单纯查看地图点位,更需要点击地图任意位置,即可快速获取当地真实时间,比如针对国外新闻的展示,对于我国的用户需要知晓事件发生的时间,一般有两个时间的概念,即北京时间和当地时间。北京时间是跟我们同一时区,让我们清楚的知道在我们的时间时刻中,在何时发生。而全球是个分为多个时区的模式,因此还需要在当地是几点发生的情况。因此,这种轻量化、高实用性的交互功能,已成为 Web 地图应用的标配能力。

        在前端地图开发领域,Leaflet 凭借体积小、易用性强、兼容性好、插件丰富等优势,成为轻量级 Web 地图开发的首选框架,相比大型 GIS 框架,它更适合快速开发轻量化地图应用;在后端技术栈中,SpringBoot 以自动配置、开箱即用、生态完善等特点,成为 Java 全栈开发的主流选择,能够高效实现接口开发、数据计算、业务逻辑处理。将 Leaflet 与 SpringBoot 结合,既可以发挥前端地图交互的灵活性,又能依托后端完成精准的时区计算、时间处理等核心逻辑,避免前端纯计算带来的误差与安全问题。而地图任意点位点击查看时间功能,核心解决了「经纬度→时区→当地时间/北京时间」的转换难题,填补了纯前端无法精准获取全球时区的短板,无论是跨境项目、国际展示系统,还是个人学习全栈地图开发,都具备极高的价值。

        本文将从需求解析、核心逻辑实现、前后端交互到最终效果展示,全程手把手教学,让你快速掌握 Leaflet 地图交互与 SpringBoot 后端计算的全栈开发技能。


一、需求解析

1、地图展示

        核心需求为加载一张可缩放、可拖拽的世界地图,支持用户在任意位置点击交互,地图需加载流畅、无地域偏移,适配 PC 端浏览器,这是整个功能的基础载体。地图可以放大缩小,点击等等地图常规操作。

2、时区和时间的关系

        全球共划分 24 个时区,以本初子午线为基准,每个时区对应标准时间,同一时区内时间一致,不同时区存在时差。后端必须基于标准时区规则,计算目标点位的标准时间 / 夏令时时间,保证时间精准性。

3、经纬度和时区的关系

        时区由地理位置(经纬度)决定:经度决定时区的基准偏移,纬度辅助区分特殊时区(如跨时区国家、海外领地)。核心痛点:无法通过简单公式计算经纬度对应的时区,必须依托可靠的算法 / 库实现精准转换,这是本功能的核心难点。


二、应用实现

1、经纬度和时区求解

        后端使用纯Java实现经纬度转时区,支持全球所有国家 / 地区。核心工具类代码如下:

package com.yelang.common.utils.zone; import java.time.Instant; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; import com.yelang.common.utils.StringUtils; /** * - 时区时间计算工具类 * @author 夜郎king * */ public class ZoneUtils { // 创建一个日期时间格式化器 private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); public static String getTimeFormart(String zoneIdStr,long currentTimeMillis) { ZoneId zoneId = StringUtils.isNotEmpty(zoneIdStr) ? ZoneId.of(zoneIdStr) : ZoneId.systemDefault(); // 将时间戳转换为Instant对象 Instant instant = Instant.ofEpochMilli(currentTimeMillis); // 将Instant转换为ZonedDateTime ZonedDateTime zonedDateTime = instant.atZone(zoneId); // 格式化日期时间 String formattedDateTime = zonedDateTime.format(formatter); // 输出格式化后的日期时间 return formattedDateTime; } /** * - 根据位置精度获得时区id * @param currentLon * @return */ public static int calculateTimeZone(double currentLon) { int timeZone; int shangValue = (int) (currentLon / 15); double yushuValue = Math.abs(currentLon % 15); if (yushuValue <= 7.5) { timeZone = shangValue; } else { timeZone = shangValue + (currentLon > 0 ? 1 : -1); } return timeZone; } }

2、Leaflet 实现地图点击

        关于如何使用Leaflet集成地图展示,非常简单。如果对Leaflet集成地图有疑问的,可以查看之前的博文,也可以在评论区留言交流。前端在引入 Leaflet 之后,初始化地图,绑定点击事件,获取点击点位的经纬度。核心代码如下:

function onMapClick(e) { var title = "坐标信息展示"; parent.layer.open({ type: 2, title: [title,'font-size:16px;text-align:center;font-weight: bold;'], scrollbar:false, area: ['45%', '50%'], content: ctx + "/eq/wcountry/globaldetail?lng=" + e.latlng.lng + "&lat=" + e.latlng.lat, btn:[], yes:function(index,layero){}, cancel: function(index, layero){ parent.layer.close(index); return false; } }); } mymap.on('click', onMapClick);

        值得注意的是,在这里我们使用Layui来实现打开一个新窗口。因此在页面开发时需要注意引入依赖资源。

3、前后台交互

        后端 Controller主要为实现页面的跳转以及时区时间信息展示,在实现具体时区展示时,自动计算时间信息,并与北京时间进行对比。Java代码如下:

/** * - 全球信息可视化,集成北京时间、当地时间、所属时区、未来可以扩展天气和国家、首都信息 * @return */ @RequiresPermissions("eq:capital:globalinfo") @GetMapping("/globalinfo") public String globalinfo(){ return prefix + "/globalinfo"; } /** * - 全球信息可视化,集成北京时间、当地时间、所属时区、未来可以扩展天气和国家、首都信息 * @return */ @RequiresPermissions("eq:capital:globaldetail") @GetMapping("/globaldetail") public String globaldetail(String lng,String lat,ModelMap mmap){ mmap.put("lng", lng); mmap.put("lat", lat); // 获取当前时间戳 long currentTimeMillis = System.currentTimeMillis(); String beijingTime = ZoneUtils.getTimeFormart(null,currentTimeMillis);//北京时间 mmap.put("beijingTime", beijingTime); //根据经度求解时区偏移,然后计算时间 int timeZoneOffset = ZoneUtils.calculateTimeZone(Double.parseDouble(lng)); //获取时区偏移 String offset = (timeZoneOffset < 0 ? "-" : "+") + Math.abs(timeZoneOffset); String zongIdStr = "UTC" + offset; mmap.put("zongIdStr", zongIdStr); String localTime = ZoneUtils.getTimeFormart(zongIdStr,currentTimeMillis); mmap.put("localTime", localTime); return prefix + "/globaldetail"; }

        前端请求页面展示时区及时间信息,前端使用Thymeleaf来进行页面构建。核心代码如下:

<table> <tbody> <tr> <td>经度</td> <td>[[${lng}]]</td> </tr> <tr> <td>纬度</td> <td>[[${lat}]]</td> </tr> <tr> <td>北京时间</td> <td>[[${beijingTime}]] &nbsp;【UTC+8 】</td> </tr> <tr> <td>当地时间</td> <td>[[${localTime}]] &nbsp;【[[${zongIdStr}]]】</td> </tr> </tbody> </table>

三、成果展示

        本节将对直接对页面进行展示,将成果给大家呈现出来。启动 SpringBoot 项目,访问前端页面,在全球不同区域点击测试,效果如下:

1、亚洲地区

  • 点击中国北京:弹出东八区标准时间,与时区完全匹配;
  • 点击日本东京:显示东九区时间,时差 1 小时,结果精准。

2、欧洲地区

  • 点击英国伦敦:显示零时区 / 夏令时时间;
  • 点击法国巴黎:显示东零区时间,时差匹配无误。

3、拉美地区

  • 点击巴西里约:显示西三区时间,符合南美时区规则;
  • 点击墨西哥城:显示西七区时间,计算结果无偏差。

4、澳洲地区

  • 点击澳大利亚悉尼:显示东十区时间;
  • 点击新西兰奥克兰:显示东十二区时间,跨区域计算精准。

        以上所有点位点击响应速度快,时间 100% 准确,无偏移、无错误。证明我们的计算无误。


四、总结

        以上就是本文的主要内容。文章通过Leaflet+SpringBoot技术栈,完整实现了「地图任意点位点击查看当地时间」功能,核心完成了三大模块开发:

  1. 基于 Leaflet 实现世界地图加载与点位点击交互,前端简洁高效;
  2. 依托Java语言解决经纬度转时区的核心难题,保证时间精准性;
  3. 通过前后端分离接口实现数据交互,架构清晰、易于扩展。

        本项目可直接应用于跨境系统、可视化大屏、物流地图、国际业务平台等场景,也可在此基础上扩展历史时间查询、时区对比、多语言展示等功能。Leaflet 轻量化的特性搭配 SpringBoot 高效的后端能力,是中小型 Web 地图项目的最佳实践之一。行文仓促,难免有许多不足之处,如果在实操中遇到问题,欢迎在评论区交流~。

Read more

直击复杂 SQL 瓶颈:基于代价的连接条件下推技术落地

直击复杂 SQL 瓶颈:基于代价的连接条件下推技术落地

一、引言 在数据库理论的学习过程中,我们常常接触到简洁优美的SQL示例——单表查询、简单连接、基础过滤,这些案例清晰地展示了关系代数的基本原理。然而,当我们步入真实的业务系统,面对的SQL语句往往如同缠绕的线团:公用表表达式(CTE)层层嵌套,子查询彼此交织,窗口函数与聚集计算随处可见。 这种复杂性并非开发人员的炫技,而是业务逻辑的自然映射。遗憾的是,这种为提升可读性而组织的SQL结构,却给查询优化器带来了严峻考验。在众多性能瓶颈中,有一个问题尤为突出:高选择性的连接条件无法穿透复杂的子查询结构,导致数据过滤发生在错误的时间点。本文将深入探讨这一问题的本质,并介绍一种基于代价模型的连接条件下推解决方案,展示如何让优化器既懂“安全”,又知“成本”。 二、性能困境:过滤迟到的代价 2.1 真实场景的切面分析 在大量客户业务系统中,一种常见的SQL编写模式反复出现:开发人员习惯先在子查询或CTE中完成复杂的预处理逻辑——去重、排序、窗口计算,然后再将这些预处理结果与其它表进行连接,最后施加过滤条件。从业务语义角度看,这种写法清晰自然;但从执行效率角度看,却暗藏危机。 考虑

By Ne0inhk
PHP常见中高面试题汇总

PHP常见中高面试题汇总

一、 PHP部分 1、PHP如何实现静态化 PHP的静态化分为:纯静态和伪静态。其中纯静态又分为:局部纯静态和全部纯静态。 PHP伪静态:利用Apache mod_rewrite实现URL重写的方法; PHP纯静态,就是生成HTML文件的方式,我们须要开启PHP自带的缓存机制,即ob_start来开启缓存。 2、PHP经典四大排序算法 PHP的四种基本排序算法为:冒泡排序、插入排序、选择排序和快速排序。 冒泡排序:对数组进行多轮冒泡,每一轮对数组中的元素两两比较,调整位置,冒出一个最大的数来。 插入排序:假设组前面的元素是排好序的,遍历数组后面的元素,在已排好序的元素队列中找到合适的位置,插入其中。 选择排序:进行多次选择,每次选出最大元素放入指定位置。 快速排序:递归算法。先选择数组的第一个元素作为标准,然后把小于或等于它和大于它的数分别放入两个数组中,对这两个数组也进行相同的处理,最后合并这两个数组和第一个元素。 3、PHP常见运行模式 1)CGI(通用网关接口/ Common Gateway Interface)

By Ne0inhk
Flutter 第三方库 spa 的鸿蒙适配实战 - 打造单页应用架构、动态渲染路由状态及鸿蒙大屏多窗体验优化方案

Flutter 第三方库 spa 的鸿蒙适配实战 - 打造单页应用架构、动态渲染路由状态及鸿蒙大屏多窗体验优化方案

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 第三方库 spa 的鸿蒙适配实战 - 打造单页应用架构、动态渲染路由状态及鸿蒙大屏多窗体验优化方案 前言 随着移动端交互的日益复杂,用户对 App 的流畅度要求已不仅仅停留在“帧率”上,更多的是关于页面切换的“无缝感”。单页应用(Single Page Application, SPA)模式,通过在一个长生命周期的视图内动态替换内容节点,有效地避免了频繁的页面推栈(Push/Pop)带来的布局重绘开销。 spa 库是 Flutter 生态中一个非常独特且高效的路由增强工具。它将路由状态抽象为一套可观察的树状结构,让开发者能像管理 Web 应用一样管理 Flutter 的页面状态。 在鸿蒙系统(OpenHarmony)适配实战中,面对折叠屏的灵活切换和平板的多窗协同,spa 提供了一种天然的“响应式分发”基座。

By Ne0inhk
基于Rust实现爬取 GitHub Trending 热门仓库

基于Rust实现爬取 GitHub Trending 热门仓库

基于Rust实现爬取 GitHub Trending 热门仓库 这个实战项目将使用 Rust 实现一个爬虫,目标是爬取 GitHub Trending 页面的热门 Rust 仓库信息(仓库名、描述、星标数、作者等),并将结果输出为 JSON 文件。本次更新基于优化后的代码,重点提升了错误处理容错性和 CSS 选择器稳定性。 技术栈 * HTTP 请求:reqwest( Rust 最流行的 HTTP 客户端,支持异步) * HTML 解析:scraper(基于 selectors 库,支持 CSS 选择器,轻量高效) * JSON 序列化:serde + serde_json( Rust 标准的序列化

By Ne0inhk