打造一个简洁实用的经纬度查询工具
打造一个简洁实用的经纬度查询工具
ytkz打造一个简洁实用的经纬度查询工具
最近折腾了一个基于Web的经纬度查询工具,挺有意思的,分享一下开发过程和心得。
我是先做了这个网页再改成小程序。本次将web端版本开源。
这个工具主要是为了方便查询地图上的经纬度坐标,支持实时显示鼠标位置的坐标、点击固定坐标点,还能切换不同的地图和坐标格式,适合需要快速定位或者研究地图数据的朋友。
项目背景
有时候我们需要精确地获取某个地点的经纬度,比如做地理信息相关的开发、户外活动规划,或者只是单纯好奇某个地方的坐标。市面上虽然有不少地图工具,但要么功能复杂,要么需要注册账号,或者界面不够直观。于是我就想着自己动手做一个简单易用的工具,核心需求是:
- 支持高德地图和OpenStreetMap切换
- 鼠标移动时实时显示坐标
- 点击地图可以固定坐标点
- 支持GCJ02、WGS84三种坐标系转换
- 界面简洁,适配手机和电脑
最终成品是一个纯前端的Web应用,部署在GitHub Pages上,打开浏览器就能用,体验还不错。
功能亮点
这个工具虽然简单,但功能还算实用:
- 双地图支持:可以切换高德地图和OpenStreetMap。高德地图适合国内场景,OpenStreetMap则是国际通用,数据覆盖全球。
- 实时坐标显示:鼠标在地图上移动时,右下角会实时显示当前坐标,精确到小数点后6位。
- 固定坐标:点击地图会在点击位置添加一个标记,同时显示固定坐标,方便记录特定地点的经纬度。
- 坐标格式切换:支持小数点格式(比如116.404, 39.904)和度分秒格式(比如116°24’14.4”E, 39°54’14.4”N),满足不同使用习惯。
- 坐标系转换:内置了GCJ02(高德/腾讯地图用)、WGS84(GPS原始坐标)、BD09(百度地图用)之间的转换逻辑,确保坐标在不同场景下都能用。
- 地名搜索:输入地名可以直接定位到对应地点,比如输入“北京天安门”就能跳转过去。
- 响应式设计:界面适配了手机和电脑,触摸屏也能很好地操作。
在线体验地址:https://ytkz.tech/querygps/
技术实现
整个项目用的是前端技术栈,主要包括HTML5、CSS3、JavaScript(ES6+),地图功能基于Leaflet.js实现。以下是核心部分的开发思路。
1. 地图初始化
用Leaflet.js来渲染地图,初始化时默认显示中国中心位置(北京,坐标[39.9042, 116.4074],缩放级别10)。支持两种地图图层:
- 高德地图:通过高德的瓦片服务API加载,国内体验更好。
- OpenStreetMap:用标准的OSM瓦片服务,适合国际场景。
代码上,先初始化地图容器,然后添加图层切换逻辑:
initMap() {
this.map = L.map('map', {
center: [39.9042, 116.4074], // 北京坐标
zoom: 10,
zoomControl: true,
attributionControl: false
});
this.initMapLayers();
}
initMapLayers() {
this.mapLayers.gaode = L.tileLayer('https://webst0{s}.is.autonavi.com/appmaptile?style=7&x={x}&y={y}&z={z}', {
subdomains: ['1', '2', '3', '4'],
attribution: '© 高德地图'
});
this.mapLayers.osm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
});
this.mapLayers.gaode.addTo(this.map);
}
2. 实时坐标和固定坐标
鼠标移动时,通过Leaflet的mousemove
事件捕获鼠标位置的经纬度,实时更新到界面右下角的动态坐标面板。点击地图时,通过click
事件记录固定坐标,并在地图上添加一个红色图钉标记(用emoji📍实现的,挺有趣)。
为了适配移动端,还加了touchend
事件处理,确保单指触摸也能触发固定坐标功能。代码片段如下:
this.map.on('mousemove', (e) => {
this.updateDynamicCoordinates(e.latlng);
});
this.map.on('click', (e) => {
this.setFixedCoordinates(e.latlng);
});
this.map.on('touchend', (e) => {
if (e.originalEvent.changedTouches.length === 1) {
const touch = e.originalEvent.changedTouches[0];
const point = this.map.mouseEventToContainerPoint(touch);
const latlng = this.map.containerPointToLatLng(point);
this.setFixedCoordinates(latlng);
}
});
3. 坐标系转换
国内地图服务(如高德)用的是GCJ02坐标系,和国际通用的WGS84有偏差,直接用WGS84坐标在高德地图上定位会偏离。所以我实现了一个CoordConverter
类,支持GCJ02、WGS84、BD09之间的相互转换。核心算法参考了Python版本的坐标转换代码,移植到JavaScript。
比如,WGS84转GCJ02的代码如下:
wgs84ToGcj02(lng, lat) {
if (this.outOfChina(lng, lat)) {
return [lng, lat];
}
let dlat = this._transformLat(lng - 105.0, lat - 35.0);
let dlng = this._transformLng(lng - 105.0, lat - 35.0);
const radlat = lat / 180.0 * Math.PI;
let magic = Math.sin(radlat);
magic = 1 - this.ee * magic * magic;
const sqrtmagic = Math.sqrt(magic);
dlat = (dlat * 180.0) / ((this.a * (1 - this.ee)) / (magic * sqrtmagic) * Math.PI);
dlng = (dlng * 180.0) / (this.a / sqrtmagic * Math.cos(radlat) * Math.PI);
const mglat = lat + dlat;
const mglng = lng + dlng;
return [mglng, mglat];
}
高德地图显示时,会把WGS84坐标转成GCJ02,确保定位准确。反过来,显示给用户时会把GCJ02转回WGS84,方便在其他平台使用。
4. 地名搜索
地名搜索用的是OpenStreetMap的Nominatim API,输入地名后发送请求获取坐标,然后在地图上定位并添加标记。如果用的是高德地图,会把返回的WGS84坐标转成GCJ02。代码如下:
async searchPlace() {
const query = document.getElementById('placeSearch').value.trim();
if (!query) {
alert('请输入要搜索的地名');
return;
}
try {
const response = await fetch(`https://nominatim.openstreetmap.org/search?format=json&q=${encodeURIComponent(query)}&limit=1`);
const results = await response.json();
if (results.length === 0) {
alert(`未找到"${query}"的位置信息`);
return;
}
const { lat, lon } = results[0];
let mapLng = lon, mapLat = lat;
if (this.currentMapType === 'gaode') {
const gcj02 = this.coordConverter.wgs84ToGcj02(lon, lat);
mapLng = gcj02[0];
mapLat = gcj02[1];
}
this.map.setView([mapLat, mapLng], 15);
this.setFixedCoordinates({lat: mapLat, lng: mapLng});
} catch (error) {
alert('搜索失败,请稍后重试');
}
}
5. 界面设计
界面尽量做得简洁直观,顶部是地图类型选择和搜索框,右下角显示动态和固定坐标,底部有GitHub链接。还加了一个模态框,方便手动输入经纬度定位。CSS用的是纯手写样式,配合媒体查询实现响应式布局。手机上用触摸操作,体验跟PC差不多。
部署和运行
项目是纯前端的,部署在GitHub Pages上,省去了后端服务器的麻烦。想自己跑的话,步骤很简单:
克隆仓库:
git clone https://github.com/your-username/lat-lon-query-tool.git cd lat-lon-query-tool
安装依赖(如果需要本地开发):
npm install
启动本地服务器:
npm start
浏览器访问
http://localhost:3000
直接部署到GitHub Pages的话,把代码推到main
分支,启用Pages功能,选择docs
文件夹就行。
遇到的问题和优化
开发过程中遇到几个小坑:
- 坐标系偏差:高德地图用GCJ02坐标,OpenStreetMap用WGS84,直接用会导致定位偏差。解决办法是加了坐标转换逻辑,确保显示和输入的坐标统一。
- 移动端兼容:一开始没考虑触摸事件,手机上点击没反应。后来加了
touchend
事件处理,单指触摸也能正常固定坐标。 - 搜索API限制:Nominatim API有每秒1次的请求限制,频繁搜索会报错。加了按钮禁用和加载动画,避免用户连续点击。
- 界面适配:手机屏幕小,坐标面板容易挡住地图。调整了面板位置,改成半透明背景,视觉上更舒服。
总结
这个经纬度查询工具虽然小,但从需求设计到开发实现,还是花了不少心思。整个过程让我对地图API和坐标系转换有了更深的理解,也学到了一些前端优化的技巧。如果你也有类似的需求,可以试试这个工具,或者直接拿代码改改,部署到自己的服务器上。
源码和在线演示都在GitHub上,欢迎去体验和提建议!https://ytkz.tech/querygps