当前位置: 首页 > article >正文

前端开发必备:用proj4.js搞定地图坐标转换(附完整代码示例)

前端开发必备用proj4.js搞定地图坐标转换附完整代码示例地图数据可视化是前端开发中常见的需求但不同地图服务使用的坐标系可能各不相同。比如百度地图使用BD09坐标系高德地图使用GCJ02坐标系而国际通用的Web墨卡托投影则是EPSG:3857。这种坐标系差异会导致同一个地点在不同地图上显示位置不一致的问题。我在去年开发一个多地图平台对比系统时就遇到了这个痛点。当时需要在同一个页面上叠加显示百度、高德和Leaflet地图的数据结果发现同样的经纬度在三张地图上居然偏移了几百米。经过排查才发现是坐标系转换的问题。最终通过proj4.js这个强大的坐标转换库完美解决了这个问题。1. 理解地图坐标系基础在开始使用proj4.js之前我们需要先了解几种常见的地图坐标系1.1 WGS84 (EPSG:4326)这是最常用的地理坐标系也是GPS设备使用的标准。它的特点是使用经纬度表示位置经度范围[-180,180]纬度范围[-90,90]单位是度(°)// 典型的WGS84坐标表示 const wgs84Point [116.404, 39.915] // [经度, 纬度]1.2 Web墨卡托 (EPSG:3857)这是Web地图最常用的投影坐标系特点是使用米作为单位将地球投影为正方形Google Maps、OpenStreetMap等主流Web地图都使用这种投影// 典型的Web墨卡托坐标表示 const webMercatorPoint [12958193.91, 4852834.51] // [x, y]1.3 国内常用坐标系国内地图服务还使用一些特殊的坐标系坐标系使用平台特点GCJ02高德、腾讯对WGS84坐标进行加密偏移BD09百度地图在GCJ02基础上二次加密2. proj4.js核心用法详解proj4.js是Proj.4库的JavaScript实现它能够处理各种复杂的地图投影和坐标转换。2.1 安装与基本配置首先通过npm安装npm install proj4然后在项目中引入import proj4 from proj4 // 定义常用投影 proj4.defs([ [EPSG:4326, titleWGS 84 (long/lat) projlonglat ellpsWGS84 datumWGS84 unitsdegrees], [EPSG:3857, titleWeb Mercator projmerc a6378137 b6378137 lat_ts0.0 lon_00.0 x_00.0 y_00 k1.0 unitsm nadgridsnull wktext no_defs] ])2.2 基本坐标转换单个坐标点的转换非常简单// 将WGS84坐标转换为Web墨卡托 const wgs84Point [116.404, 39.915] const mercatorPoint proj4(EPSG:4326, EPSG:3857, wgs84Point) console.log(mercatorPoint) // 输出: [12958193.91, 4852834.51]2.3 批量坐标转换实际项目中经常需要转换整个坐标数组function transformCoordinates(coords, from, to) { if (Array.isArray(coords[0])) { return coords.map(coord proj4(from, to, coord)) } return proj4(from, to, coords) } const points [ [116.404, 39.915], [121.474, 31.230] ] const transformed transformCoordinates(points, EPSG:4326, EPSG:3857)3. 实战GeoJSON坐标转换GeoJSON是地理数据交换的常用格式我们可以扩展proj4.js的功能来处理GeoJSON数据。3.1 GeoJSON结构解析一个典型的GeoJSON结构如下{ type: FeatureCollection, features: [ { type: Feature, geometry: { type: Point, coordinates: [116.404, 39.915] } } ] }3.2 实现GeoJSON转换函数function transformGeoJSON(geojson, from, to) { const clone JSON.parse(JSON.stringify(geojson)) if (clone.type FeatureCollection) { clone.features.forEach(feature { feature.geometry transformGeometry(feature.geometry, from, to) }) } else if (clone.type Feature) { clone.geometry transformGeometry(clone.geometry, from, to) } else { clone.coordinates transformCoordinates(clone.coordinates, from, to) } return clone } function transformGeometry(geometry, from, to) { switch (geometry.type) { case Point: case LineString: case MultiPoint: geometry.coordinates transformCoordinates(geometry.coordinates, from, to) break case Polygon: case MultiLineString: geometry.coordinates geometry.coordinates.map(ring transformCoordinates(ring, from, to) ) break case MultiPolygon: geometry.coordinates geometry.coordinates.map(polygon polygon.map(ring transformCoordinates(ring, from, to)) ) break } return geometry }4. 性能优化与常见问题4.1 性能优化技巧批量转换避免在循环中多次调用proj4应该先收集所有坐标再批量转换缓存定义提前定义好所有需要的投影避免运行时动态定义Web Worker对于大量数据转换可以考虑使用Web Worker避免阻塞UI// 使用Web Worker的示例 const worker new Worker(proj4-worker.js) worker.postMessage({ type: transform, coordinates: largeArray, from: EPSG:4326, to: EPSG:3857 }) worker.onmessage (e) { console.log(转换完成, e.data) }4.2 常见问题解决方案问题1坐标转换后位置偏移可能原因使用了错误的源或目标坐标系定义坐标顺序错误proj4默认是[x,y]顺序解决方案// 确保坐标顺序正确 const correctOrder [lng, lat] // 经度,纬度问题2转换大量数据时页面卡顿解决方案分块处理数据使用setTimeout分割任务考虑使用Web Workerfunction batchTransform(coords, from, to, chunkSize 1000) { const results [] let i 0 function processChunk() { const end Math.min(i chunkSize, coords.length) for (; i end; i) { results.push(proj4(from, to, coords[i])) } if (i coords.length) { setTimeout(processChunk, 0) } } processChunk() return results }5. 扩展应用国内地图坐标系转换国内地图服务常用的GCJ02和BD09坐标系需要特殊处理。虽然proj4.js本身不支持这些坐标系但我们可以结合其他库来实现。5.1 集成coordtransformimport { gcj02towgs84, bd09togcj02 } from coordtransform function wgs84ToGcj02(coords) { if (Array.isArray(coords[0])) { return coords.map(coord gcj02towgs84(coord[0], coord[1])) } return gcj02towgs84(coords[0], coords[1]) } // 使用示例 const wgs84Point [116.404, 39.915] const gcj02Point wgs84ToGcj02(wgs84Point)5.2 完整转换流程从百度地图BD09到WGS84的完整转换function bd09ToWgs84(coords) { // 第一步BD09 - GCJ02 const gcj02 bd09togcj02(coords[0], coords[1]) // 第二步GCJ02 - WGS84 return gcj02towgs84(gcj02[0], gcj02[1]) }在实际项目中我通常会将这些转换函数封装成一个统一的工具库根据数据来源自动选择适当的转换流程。这样可以大大简化业务代码避免在多个地方重复实现相同的转换逻辑。

相关文章:

前端开发必备:用proj4.js搞定地图坐标转换(附完整代码示例)

前端开发必备:用proj4.js搞定地图坐标转换(附完整代码示例) 地图数据可视化是前端开发中常见的需求,但不同地图服务使用的坐标系可能各不相同。比如百度地图使用BD09坐标系,高德地图使用GCJ02坐标系,而国际…...

TinyMCE如何完美兼容Word公式粘贴并保留原始样式?

如何在富文本中插入表情,word文档,及数学公式? 前言 校外培训迎来下岗潮,教育行业的小伙伴,大家过的还好吗?不过话说回来,技术过硬,你在哪里都是最靓的仔。今天就给大家补充一点弹…...

R星服务器又抽风?从‘Social Club初始化失败’聊聊国内玩家玩外服游戏的网络生存指南

海外游戏网络连接优化指南:从Social Club故障到全局解决方案 每次打开心爱的海外游戏,却看到"Social Club初始化失败"的提示,那种烦躁感想必每个玩家都深有体会。这背后反映的不仅是某个游戏平台的临时故障,更是国内玩家…...

Nanbeige 4.1-3B一文详解:Streamlit Theming API深度定制像素UI主题方案

Nanbeige 4.1-3B一文详解:Streamlit Theming API深度定制像素UI主题方案 1. 项目背景与设计理念 Nanbeige 4.1-3B像素冒险聊天终端是一款专为对话AI设计的独特前端界面。它突破了传统聊天界面的设计范式,将现代AI交互体验与复古游戏美学完美融合。 1.…...

OpenClaw定时任务实践:GLM-4.7-Flash实现24/7自动化监控

OpenClaw定时任务实践:GLM-4.7-Flash实现24/7自动化监控 1. 为什么需要自动化监控? 去年接手一个数据采集项目时,我每天要手动检查十几个网页的数据更新情况。这种重复性工作不仅耗时,还经常因为时间差错过关键信息。直到发现Op…...

从CTF靶场到实战:手把手复现EasyCMS后台弱口令与主题导出漏洞(附POC)

从CTF靶场到实战:手把手复现EasyCMS后台弱口令与主题导出漏洞 在企业级CMS系统的安全评估中,弱口令和文件操作漏洞往往是最容易被忽视却危害极大的安全隐患。本文将基于真实渗透测试经验,详细拆解EasyCMS(及类似迅睿CMS系统&#…...

Hunyuan-MT-7B模型日志分析:ELK堆栈实战

Hunyuan-MT-7B模型日志分析:ELK堆栈实战 1. 引言 当你运行Hunyuan-MT-7B这样的翻译模型时,有没有遇到过这样的情况:模型突然变慢,却不知道问题出在哪里?或者想知道哪些翻译请求最耗时,但面对一堆杂乱的日…...

用数据说话 10个降AIGC平台测评:论文写作全流程降AI率全解析

在论文写作的全过程中,AI生成内容(AIGC)已经成为学术界和教育界关注的焦点。随着AI技术的广泛应用,许多学生和研究者发现,使用AI辅助写作虽然提升了效率,但也带来了AIGC率偏高、查重率不达标等问题。如何在…...

实测才敢推!降AI率工具 千笔·降AI率助手 VS Checkjie,开源免费首选

在AI技术快速发展的今天,越来越多的学生和研究者开始借助AI工具进行论文写作,以提高效率、优化内容结构。然而,随着学术审查标准的不断升级,AI生成内容的痕迹越来越容易被查重系统识别,导致论文AI率超标,甚…...

亲测好用 10个降AIGC工具:论文写作全流程降AI率必备神器

在学术写作日益依赖AI辅助的当下,如何有效降低论文中的AIGC率、去除明显的AI痕迹,同时保持内容的逻辑性和原创性,已成为众多学生和研究者面临的共同难题。随着各大高校和期刊对AI生成内容的审查日趋严格,传统的“复制粘贴”式写作…...

天地图JavaScript API实战:多边形面积计算与交互式绘制

1. 天地图JavaScript API基础入门 第一次接触天地图JavaScript API的开发者可能会觉得有点懵,其实它和我们常用的百度地图、高德地图API类似,都是用来在网页上展示地图和实现地理信息功能的工具链。我刚开始用的时候也踩过不少坑,后来发现只要…...

Vue3项目实战:如何用@vitejs/plugin-legacy搞定老旧浏览器兼容?

Vue3工程化实践:基于vitejs/plugin-legacy的渐进式兼容方案 当我们在现代前端工程中采用Vue3和Vite的组合时,往往会遇到一个现实矛盾:开发时享受的ES模块原生导入、闪电般的HMR,与生产环境需要支持的旧版浏览器之间的技术代沟。这…...

Qwen3.5-9B长文档理解:PDF解析+关键信息抽取+摘要生成端到端部署

Qwen3.5-9B长文档理解:PDF解析关键信息抽取摘要生成端到端部署 1. 项目概述与核心价值 Qwen3.5-9B是阿里云推出的新一代多模态大语言模型,特别针对长文档处理场景进行了优化。本文将带您从零开始部署一个完整的端到端解决方案,实现PDF文档解…...

实战指南:基于Windows Server构建企业级AAA认证体系

1. 为什么企业需要AAA认证体系 在企业IT环境中,网络设备管理一直是个头疼的问题。想象一下,公司有几十台交换机、路由器,每个设备都要单独维护账号密码,管理员得记住上百组凭证。更可怕的是,当有员工离职时&#xff0c…...

告别托管依赖:用.NET 8 Native AOT把C#代码打包成纯原生DLL,让C++项目轻松调用

告别托管依赖:用.NET 8 Native AOT把C#代码打包成纯原生DLL,让C项目轻松调用 在跨语言开发的世界里,C#和C的协作一直是个既诱人又充满挑战的话题。想象一下,你有一个用C#精心打磨的高性能算法库,或者一个成熟的业务逻辑…...

ESP32 SD卡固件更新库:DSTIKE OLED图形化OTA引导方案

1. 项目概述DstikeUpdater 是一个专为 DSTIKE 系列 ESP32 开发板设计的嵌入式固件在线更新(Over-the-Air, OTA)辅助库,其核心定位并非替代 ESP-IDF 或 Arduino-ESP32 原生 OTA 机制,而是构建一套面向终端用户的、具备图形化交互能…...

UniApp多主题切换实战:从SCSS变量到require动态引入的完整指南

UniApp多主题切换实战:从SCSS变量到require动态引入的完整指南 在移动应用开发中,多主题切换功能已经成为提升用户体验的重要特性。无论是为了适配用户偏好、实现夜间模式,还是满足品牌定制需求,灵活的主题切换机制都能显著提升产…...

PyTorch梯度累积超快

💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 PyTorch梯度累积的极致加速:从理论瓶颈到实战突破目录PyTorch梯度累积的极致加速:从理论瓶颈到实战突破 …...

【实战指南】解决Qt平台插件加载失败:从环境变量配置到PyQt5重装全流程

1. 问题现象与初步诊断 最近在Windows系统下运行labelimg这类基于Qt开发的工具时,不少开发者都遇到了这样的报错提示: qt.qpa.plugin: Could not load the Qt platform plugin "windows" in "" even though it was found. This appl…...

解决高版本VisualStudio编译低版本Unreal源码的常见问题与技巧

1. 环境配置的坑与填坑指南 第一次用Visual Studio 2022打开老版本Unreal工程时,我直接被满屏的报错整懵了。最典型的就是那个"Windows SDK v8.1 must be installed"错误,明明系统里装着最新SDK,它偏要旧版本。后来发现Unreal引擎的…...

前端组件库——shadcn/ui:轻量、自由、可拥有,解锁前端组件库的AI时代未来

从 Element Plus 到 shadcn/ui:前端组件库的进化之路与架构选型思考 ![ 从 Element Plus 到 shadcn/ui:前端组件库的进化之路与架构选型思考摘要 前端组件库作为前端工程化的核心基础设施,历经十余年演进,已从全量安装、强依赖、黑…...

htop安装不了怎么解决

1 安装报错提示[rootjxzn200 log]# yum install htop 上次元数据过期检查:3:54:25 前,执行于 2024年05月29日 星期三 11时56分08秒。 未找到匹配的参数: htop 错误:没有任何匹配: htop 这是因为在你的系统中,默认的软件源中没有ht…...

5分钟搞定串口设备联网:用USR-K5模块搭建TCP通讯的保姆级教程

5分钟搞定串口设备联网:用USR-K5模块搭建TCP通讯的保姆级教程 当你需要将老旧的串口设备接入现代网络时,USR-K5模块就像一位精通双语的翻译官,能在RS-232和TCP/IP协议之间架起无缝桥梁。作为一款即插即用的串口转以太网模块,它特别…...

MMD Ray打光全攻略:从SpotLight设置到阴影优化,让你的模型更立体

MMD Ray打光全攻略:从SpotLight设置到阴影优化,让你的模型更立体 在MMD创作中,光线是赋予模型生命的关键要素。Ray渲染引擎的强大之处在于它能够模拟真实世界的光照行为,而掌握SpotLight的精细调节与阴影优化技巧,则是…...

java毕业设计基于springboot头条文章管理系统-编号:project44558

前言 该系统旨在提供一个高效、可靠的文章发布和管理解决方案,使用户能够轻松地发布、编辑和管理自己的文章,并与其他用户进行评论和互动。通过系统提供的文章分类与标签、搜索与过滤等功能,用户能够快速找到感兴趣的文章并参与讨论。一、项目…...

java毕业设计基于springboot图书管理系统-编号:project64080

前言 随着信息技术的不断发展和图书馆规模的不断扩大,传统的图书管理方式已经难以满足现代图书馆的需求。为了提高图书管理的效率和准确性,开发一个基于Spring Boot的图书管理系统显得尤为重要。该系统能够实现对图书的增删改查(CRUD&#xf…...

java毕业设计基于springboot网上问卷调查系统-编号:project25765

前言 随着互联网的快速发展,人们对于在线服务的需求越来越高,这促使了各种在线调查系统的蓬勃发展。其中,在线问卷调查系统因其操作简便、数据统计快速、受访者覆盖范围广等特点,逐渐成为一种主流的调查方式。传统的问卷调查方式由…...

System.Drawing.Graphics进阶:手把手教你打造可动态更新的Winform纵向标签控件

深度解析System.Drawing.Graphics:构建高性能Winform纵向标签控件实战指南 在Winform开发中,标准控件库提供的横向文本标签往往无法满足特殊排版需求。本文将带您深入System.Drawing.Graphics的核心机制,从底层原理到实战优化,打造…...

UART通信波形解析与硬件时序设计实战

1. UART通信协议波形分析与工程实践详解UART(Universal Asynchronous Receiver/Transmitter)作为嵌入式系统中最基础、应用最广泛的串行通信接口之一,其设计简洁性与实现鲁棒性在数十年工业实践中已得到充分验证。尽管现代SoC普遍集成高速USB…...

通义千问3-Reranker-0.6B与LSTM结合:时序文本分析

通义千问3-Reranker-0.6B与LSTM结合:时序文本分析 你有没有遇到过这样的场景:面对社交媒体上每天海量的用户评论,想快速找出哪些是真正有价值的反馈,哪些只是情绪化的抱怨?或者,在处理新闻资讯流时&#x…...