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

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

1. 天地图JavaScript API基础入门第一次接触天地图JavaScript API的开发者可能会觉得有点懵其实它和我们常用的百度地图、高德地图API类似都是用来在网页上展示地图和实现地理信息功能的工具链。我刚开始用的时候也踩过不少坑后来发现只要掌握几个核心概念就能快速上手。天地图最大的特点是使用了国家地理信息公共服务平台提供的基础数据在精度和权威性上有独特优势。要使用它的API首先得去官网申请一个开发者密钥TK这个过程和大多数地图服务商类似填写基本信息就能免费获取。初始化地图的代码非常简单我这里分享一个经过实战验证的模板var map new T.Map(mapContainer, { projection: EPSG:4326 // 使用WGS84坐标系 }); var centerPoint new T.LngLat(116.404, 39.915); // 天安门坐标 map.centerAndZoom(centerPoint, 15); // 15级缩放这里有个实用技巧默认情况下地图会显示天地图的Logo如果觉得影响界面美观可以通过CSS隐藏它document.querySelector(.tdt-control-copyright).style.display none;在实际项目中我建议把地图初始化代码封装成一个独立函数方便重复调用。比如可以创建一个initMap函数接收容器ID、中心点坐标和缩放级别三个参数这样代码复用性会更好。2. 多边形绘制工具深度解析polygonTool是天地图API中非常实用的一个类它封装了完整的多边形绘制交互逻辑。我对比过几种主流地图平台的绘制工具天地图的这个实现算是比较人性化的。不过第一次用的时候有几个细节需要注意首先创建polygonTool实例时需要传入两个参数地图对象和配置项。配置项不是必须的但建议至少设置一下边框颜色和填充透明度var config { color: #3388ff, // 边框颜色 weight: 2, // 边框宽度 opacity: 1, // 边框透明度 fillColor: #3388ff, // 填充颜色 fillOpacity: 0.3 // 填充透明度 }; var drawTool new T.PolygonTool(map, config);开始绘制只需要调用open()方法但这里有个坑要注意如果用户已经在地图上点击了但还没完成绘制直接调用close()会导致地图上残留未完成的图形。我通常的做法是添加一个完成按钮让用户主动结束绘制流程。绘制完成时会触发draw事件这个事件对象中包含了完整的多边形坐标数据。实测发现在移动端和PC端的交互方式略有不同PC端双击结束绘制移动端长按结束绘制 在实际项目中最好做相应的提示避免用户困惑。3. 多边形面积计算原理与实现很多开发者好奇handler.getArea()这个方法背后的计算原理。其实它采用的是球面多边形面积算法比简单的平面几何计算要复杂得多。我专门研究过源码发现它主要考虑了地球曲率的影响所以计算结果比平面算法更精确。计算面积时需要传入一个坐标数组这个数组的结构要注意必须是闭合多边形即第一个点和最后一个点要相同。比如一个三角形的坐标应该是4个点而不是3个点。我遇到过不少开发者在这里踩坑。这里分享一个封装好的计算函数包含错误处理逻辑function calculateArea(points) { if (!handler) { console.error(绘图工具未初始化); return 0; } if (points.length 3) { console.error(至少需要3个点才能构成多边形); return 0; } // 确保多边形闭合 if (points[0] ! points[points.length-1]) { points.push(points[0]); } return handler.getArea(points); }在实际项目中面积单位通常是平方米但有时需要转换成亩或公顷。这里有个换算工具函数function formatArea(area) { return { squareMeters: area.toFixed(2), mu: (area / 666.67).toFixed(2), // 亩 hectares: (area / 10000).toFixed(4) // 公顷 }; }4. 完整项目实战交互式面积测量工具结合前面讲的内容我们来实现一个完整的交互式面积测量工具。这个实现包含以下几个核心功能绘制多边形实时显示面积编辑已有图形保存测量结果首先在HTML中准备界面div idmapContainer/div div classcontrol-panel button iddrawBtn开始绘制/button button ideditBtn disabled编辑图形/button div idresultPanel p面积span idareaValue0/span 平方米/p /div /div然后是JavaScript的核心逻辑var map, drawTool, currentPolygon; // 初始化地图 function initMap() { map new T.Map(mapContainer); map.centerAndZoom(new T.LngLat(116.404, 39.915), 12); // 初始化绘图工具 drawTool new T.PolygonTool(map, { color: #1890ff, fillColor: #1890ff, fillOpacity: 0.3 }); // 监听绘制完成事件 drawTool.addEventListener(draw, function(e) { var polygon e.currentTarget.getPolygons()[0]; currentPolygon polygon; updateArea(polygon); document.getElementById(editBtn).disabled false; }); } // 更新面积显示 function updateArea(polygon) { var points polygon.getLngLats()[0]; var area drawTool.getArea(points); document.getElementById(areaValue).textContent area.toFixed(2); } // 开始绘制 document.getElementById(drawBtn).addEventListener(click, function() { if (currentPolygon) { map.removeOverLay(currentPolygon); currentPolygon null; } drawTool.open(); }); // 编辑图形 document.getElementById(editBtn).addEventListener(click, function() { if (currentPolygon) { currentPolygon.enableEdit(); // 监听编辑完成事件 currentPolygon.addEventListener(edit, function() { updateArea(currentPolygon); }); } }); // 初始化 window.onload initMap;这个实现有几个优化点使用事件委托减少事件监听器数量添加了图形编辑后的面积自动更新界面状态管理按钮禁用/启用清理上一次的绘制结果5. 常见问题与性能优化在实际项目中使用多边形绘制功能时我遇到过几个典型问题这里分享解决方案内存泄漏问题频繁创建和删除多边形会导致内存占用持续增长。解决方法是在移除图形前先调用disableEdit()和removeEventListener()清理相关资源。function cleanUp() { if (currentPolygon) { currentPolygon.disableEdit(); currentPolygon.removeEventListener(edit); map.removeOverLay(currentPolygon); currentPolygon null; } }大数据量性能问题当多边形包含上千个顶点时编辑和计算操作会明显卡顿。我的优化方案是使用web worker在后台线程计算面积对图形进行简化处理减少顶点数量使用防抖技术限制频繁的面积计算坐标精度问题有时从其他系统导入的坐标数据与天地图存在微小偏差。建议在绘制前进行坐标纠偏function adjustCoordinate(lnglat) { // 简单的坐标修正具体参数需要根据实际情况调整 return new T.LngLat( lnglat.lng 0.00012, lnglat.lat - 0.00005 ); }移动端适配问题在手机浏览器上绘制体验需要特别优化增加绘制完成按钮因为移动端双击操作不便顶点标记要放大方便手指点击添加手势识别比如捏合缩放时暂停绘制// 移动端专用配置 if (isMobile()) { drawTool.setOptions({ vertexStyle: { radius: 10, color: #ff0000 } }); addCompleteButton(); }6. 高级应用自定义绘制样式与交互基础的绘制功能满足不了复杂项目需求时就需要自定义实现了。天地图的API提供了足够的扩展性我们可以实现诸如自定义顶点样式添加中间点限制绘制范围自定义面积计算方式比如要实现一个带箭头的测量线可以这样扩展function createArrowMarker(lnglat) { return new T.Marker(lnglat, { icon: new T.Icon({ iconUrl: arrow.png, iconSize: new T.Point(20, 20) }) }); } // 在绘制过程中添加箭头标记 drawTool.addEventListener(vertex, function(e) { var marker createArrowMarker(e.lnglat); map.addOverLay(marker); });再比如限制绘制区域的功能实现var allowedBounds new T.LngLatBounds( new T.LngLat(115.0, 38.0), new T.LngLat(117.0, 40.0) ); function validatePoint(lnglat) { return allowedBounds.contains(lnglat); } drawTool.addEventListener(addvertex, function(e) { if (!validatePoint(e.lnglat)) { e.preventDefault(); alert(超出允许绘制范围); } });对于专业领域应用可能需要实现更复杂的面积计算逻辑。比如农业应用中需要扣除内部建筑物面积function calculateActualArea(polygon) { var outerArea drawTool.getArea(polygon.getLngLats()[0]); var innerArea 0; // 扣除所有内部多边形面积 polygon.getHoles().forEach(function(hole) { innerArea drawTool.getArea(hole); }); return outerArea - innerArea; }7. 与其他地图库的集成方案在实际项目中经常需要同时使用多个地图库。我最近做的一个项目就需要在天地图上叠加Leaflet的绘制功能。这里分享几个集成方案方案一使用地图容器共享// 初始化天地图 var tMap new T.Map(mapContainer); // 在同一个容器上初始化Leaflet var lMap L.map(mapContainer, { crs: L.CRS.EPSG4326 }).setView([39.915, 116.404], 12); // 确保两个地图同步 tMap.addEventListener(moveend, function() { var center tMap.getCenter(); lMap.setView([center.lat, center.lng], tMap.getZoom()); });方案二使用图层叠加// 将天地图作为Leaflet的底图 L.tileLayer(https://t{s}.tianditu.gov.cn/DataServer?Tvec_wx{x}y{y}l{z}tk您的密钥, { subdomains: [0,1,2,3,4,5,6,7], tms: true }).addTo(lMap);方案三使用WebGL渲染对于性能要求高的应用可以考虑使用Mapbox GL JS与天地图瓦片结合var map new mapboxgl.Map({ container: mapContainer, style: { version: 8, sources: { tdt-vec: { type: raster, tiles: [ https://t0.tianditu.gov.cn/vec_w/wmts?SERVICEWMTSREQUESTGetTileVERSION1.0.0LAYERvecSTYLEdefaultTILEMATRIXSETwFORMATtilesTILEMATRIX{z}TILEROW{y}TILECOL{x}tk您的密钥 ], tileSize: 256 } }, layers: [{ id: tdt-layer, type: raster, source: tdt-vec }] }, center: [116.404, 39.915], zoom: 12 });8. 项目经验与实用技巧经过多个天地图相关项目的实战我总结了一些非常实用的技巧调试技巧使用map.getCenter()和map.getZoom()实时获取当前视图状态通过map.getSize()检查地图容器尺寸是否正确使用T.Util.extend()合并配置对象// 调试视图状态 console.log(当前中心点:, map.getCenter()); console.log(当前级别:, map.getZoom());性能监控// 监控帧率 var frames 0; var lastTime Date.now(); function checkFPS() { frames; if (Date.now() - lastTime 1000) { console.log(当前FPS:, frames); frames 0; lastTime Date.now(); } requestAnimationFrame(checkFPS); } checkFPS();错误处理// 全局错误捕获 window.onerror function(message, source, lineno, colno, error) { console.error(地图错误:, message, error); return true; // 阻止默认错误处理 }; // API加载失败处理 if (!window.T) { console.error(天地图API加载失败); document.getElementById(mapContainer).innerHTML div classerror地图加载失败请检查网络连接/div; }移动端优化// 禁用双指缩放避免与绘制操作冲突 map.disablePinchZoom(); // 增加点击延迟避免误触 map.enableTouchZoom({ tapDelay: 300 });数据导出function exportGeoJSON(polygon) { var coordinates polygon.getLngLats()[0].map(function(lnglat) { return [lnglat.lng, lnglat.lat]; }); return { type: Feature, geometry: { type: Polygon, coordinates: [coordinates] }, properties: { area: drawTool.getArea(polygon.getLngLats()[0]) } }; }

相关文章:

天地图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…...

CHORD-X深度研究报告生成终端ComfyUI可视化工作流集成教程

CHORD-X深度研究报告生成终端ComfyUI可视化工作流集成教程 你是不是也遇到过这样的场景:需要生成一份深度行业分析报告,手头有CHORD-X这样强大的研究工具,但每次都要写代码调用API,流程繁琐,调试起来也不直观。或者&a…...

Z-Image-Turbo-辉夜巫女实战:基于卷积神经网络的特征引导图像风格迁移

Z-Image-Turbo-辉夜巫女实战:基于卷积神经网络的特征引导图像风格迁移 你是不是也遇到过这样的烦恼?看到一张特别有感觉的艺术画作,想把自己的照片也变成那种风格,结果用普通的滤镜一处理,要么颜色变得很奇怪&#xf…...

科研小白必看:如何用CiteSpace和VOSviewer快速搞定文献可视化分析(附详细操作步骤)

科研新手必备:CiteSpace与VOSviewer文献可视化实战指南 刚踏入科研领域的研究生们,面对海量文献是否感到无从下手?文献计量学工具能帮你从宏观视角快速把握研究脉络。本文将手把手教你用CiteSpace和VOSviewer这两款神器,把枯燥的文…...

树莓派GPIO上拉下拉电阻实战:为什么你的按键检测总是不稳定?

树莓派GPIO上拉下拉电阻实战:为什么你的按键检测总是不稳定? 树莓派的GPIO接口是开发者最常使用的功能之一,但很多人在按键检测项目中都会遇到信号抖动、误触发等问题。这往往是因为忽略了上拉/下拉电阻的合理配置。本文将带你从电路原理到代…...

WPF图形绘制全攻略:从基础Rectangle到复杂Path几何图形的进阶之路

WPF图形绘制全攻略:从基础Rectangle到复杂Path几何图形的进阶之路 在WPF开发中,图形绘制是实现精美UI的核心技能之一。不同于传统WinForms的GDI绘图,WPF提供了一套基于矢量图形的声明式绘制系统,让开发者能够轻松创建从简单矩形到…...

别再为美术发愁!用即梦AI+腾讯混元3D,零美术基础搞定独立游戏素材(Unity实战)

零美术基础打造独立游戏:AI工具链与Unity实战指南 当我在2023年独立游戏开发者大会上遇到第17个因为美术资源放弃项目的程序员时,突然意识到一个残酷现实:美术门槛正在扼杀无数创意。传统解决方案无非是购买素材包或寻找合作伙伴,…...

OpenCV二值化实战:cv2.threshold()与cv2.adaptiveThreshold()函数对比与应用场景解析

1. 二值化基础与OpenCV实战入门 第一次接触图像处理时,我被"二值化"这个概念难住了——直到把它想象成小时候玩的"黑白剪纸"才恍然大悟。简单来说,二值化就是把彩色或灰度图像转换成只有黑白两种颜色的过程,就像用剪刀把…...

120智慧社区互助平台系统-springboot+vue+微信小程序

文末领取项目源码springbootvue 1.首页请文末卡片dd我获取源码...

工业相机参数解析:曝光时间与运动模糊的“生死博弈”

📷 工业相机参数解析:曝光时间与运动模糊的“生死博弈”导读:在高速产线上,为什么你的照片总是“拖影”严重?是相机不够好,还是参数没设对?今天,我们深入剖析工业相机中最核心的矛盾…...

119养老院管理系统-springboot+vue

文末领取项目源码 springbootvue 1.首页 请文末卡片dd我获取源码...