uni-app农场地图——高德 JS API 实现全解析(天地图影像作为layers)

1. 适用场景

面向 国内 App(uni-app + renderjs) 的农场地图:

  • 展示农场地块多边形、阀门/网关设备点
  • 手绘圈地、删除地块、点击地块拉设备列表
  • 安装设备时在地图上选址(GCJ02)
  • 长按设备调整安装位置

2. 为什么在 uni-app 里必须用 renderjs?

Vue 逻辑层运行在 App 的 JS 引擎里,不能直接操作 WebView 里的 DOM。高德 AMap.Map 必须跑在浏览器环境。

因此采用 双 Script 分层:

模板桥接:

javascript 复制代码
<view :prop="propList" :change:prop="mapView.receiveAllProps" />

receiveAllProps 是 renderjs 侧的唯一入口,根据 editMode、drawStatus、isAddDevice 等切换地图行为。

3. 与父页面的数据契约(allProps)

index.vue 通过 updateAllPropsData 推送:

字段 含义
farmFloorData 地块列表(坐标已在父层转为地图可用格式)
valve 当前地块设备列表
centerPoint 农场中心 [lng, lat]
drawStatus 2 进入手绘地块
editMode 1 正常 / 3 删除地块
isAddDevice 是否开启安装选址
showScale / showGeolocation 控件显隐

向父组件抛出的事件(与 Mapbox 版一致):

  • polygonData --- 手绘完成坐标(GCJ02)
  • valveMarkerClick / valvePositionUpdate
  • positionSelected --- 安装选址
  • handleDeviceListByZone / deleteFloor / updateFloorData

设计要点:地图组件只做「渲染 + 交互」,农场/设备业务仍在 index.vue。

4. 坐标系策略(高德方案的关键)

  • 接口、uni 定位、addFarm:GCJ-02
  • 高德地图实例内部:也按 GCJ-02 使用(与国标一致,显示上最省事)
  • 父页面 getAllFloor 时会把接口 GCJ02 转成 WGS84 再传给地图

安装选址时,PositionPicker 返回的 positionResult.position 在代码里又做了一次:

javascript 复制代码
coordtransform.wgs84togcj02(positionResult.position.lng, positionResult.position.lat)

统一坐标系标准:上报父组件、写库一律 GCJ02。

定位控件里则将高德定位结果 gcj02towgs84 后 panTo,用于在地图上标蓝点。

5. 地图初始化:高德引擎 + 非高德底图

initAMap() 并非默认高德卫星,而是 自定义 TileLayer 叠瓦片:

  1. 天地图影像 img_w(WMTS,TILEMATRIXSET=w)
  2. Mapbox 卫星(AMap.TileLayer,默认 visible: false)
  3. 天地图注记 cia_w
javascript 复制代码
map = new AMap.Map("container", {
  viewMode: '3D',
  zoom: 17,
  center: centerPointData,
  layers: [tiandituImgLayer, mapboxSatelliteLayer, tiandituRoadLayer],
})

缩放分级切换(zoomchange):

  • zoom <= 17.5:天地图影像
  • zoom > 17.5:隐藏天地图,显示 Mapbox 卫星

思路:日常用合规国内影像,放大看田块细节时用高清卫星。引擎仍是高德,底图可插拔。

还需配置:

javascript 复制代码
window._AMapSecurityConfig = { securityJsCode: '...' }
AMapLoader.load({ key, version: '2.0', plugins: [...] })

插件包括 PolygonEditor、Geolocation、Scale 等。

6. 功能实现思路(按模块)

6.1 地块展示 initPolygon

  1. map.remove(polygons) 清旧多边形
  2. 遍历 FloorList,coordinates → path,首尾闭合
  3. new AMap.Polygon({ path, fillOpacity, strokeColor, extData })
  4. getBounds().getCenter() 得到中心,再 AMap.Marker 显示地块名
  5. 绑定 polygon.on('click') → handlePolygonClick

删除模式 edit === 3:红色虚线边框、加粗 stroke,提高可点区域。

选中逻辑:setOptions 改填充/描边,隐藏当前地块名称 Marker,调用 handleDeviceListByZone。

6.2 手绘地块 drawPolygon

  1. map.on('click') 采点 → polygonSaveTemp
  2. 每点一个 AMap.Marker(红点)
  3. < 3 点:AMap.Polyline 虚线;>= 3 点:AMap.Polygon 预览
  4. 页面 DOM #point-next / #point-cancel(在 index.vue)完成/撤销
  5. 完成 → callMethod('drawFloor', polygonSaveTemp) → 逻辑层 wgs84togcj02 → emit('polygonData')

撤销时用 map.clearMap() 再重绘临时图形(注意会清掉其它覆盖物,需之后 initPolygon 恢复)。

6.3 设备点 initValves / addMarker

  • AMap.Marker + 自定义 content HTML(图标、状态角标、灌溉动画)
  • 点击 → onValveMarkerClick
  • 长按 3s → 进入位置调整(需处理与 dragstart/zoomstart 冲突,代码里用 document 级 touch 监听取消误触)

6.4 安装选址 initPositionPicker

动态加载 AMapUI + misc/PositionPicker:

javascript 复制代码
positionPicker = new PositionPicker({ mode: 'dragMap', map })
positionPicker.start()
positionPicker.on('success', ...) // → onPositionSelected(GCJ02)

mode: 'dragMap':拖地图、中心不动

进入选址时 marker.setClickable(false),避免误点设备。

6.5 定位

AMap.Geolocation + complete 事件更新 locationMarker;error → 逻辑层 Toast。

7. 高德方案优缺点

优点

  • 国内文档、示例、社区成熟
  • GCJ02 与国标、微信/高德定位一致,少一层转换错误
  • Polygon、Marker、PositionPicker 封装高,开发快
  • 可用 PolygonEditor 做顶点编辑(插件已引入)

缺点

  • 强依赖高德 Key + 安全密钥,商业条款与配额需单独评估
  • 自定义底图(天地图 + Mapbox)仍绑在高德引擎上,架构略「拧」
  • clearMap()、多实例 Editor 容易造成状态难控
  • App WebView 里同时拉高德 UI、AMapUI、外部瓦片,包体与网络请求较多

8. 落地检查清单

  • Key / securityJsCode / 域名白名单(H5)/ 包名(App)
  • 确认存入地图的坐标系与接口一致(GCJ02)
  • 手绘完成、选址、拖拽提交三条链路都做 GCJ02 输出
  • zoomchange 切换底图时测试 17.5 临界闪烁
  • 删除模式与名称 Marker、polygon 点击去重(FLOOR_POLYGON_CLICK_DEDUP_MS)
相关推荐
小蒜学长2 天前
基于SpringBoot+uni-app的闪洁家政系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·uni-app·家政服务
anyup_前端梦工厂2 天前
uni-app 模板 Starter 一键清理 Skill 发布
前端·人工智能·uni-app
anyup_前端梦工厂2 天前
将uni-app工程迁移uni-app x,AI 能帮我们做什么?
前端·人工智能·uni-app
蒿豪郝灬号2 天前
UniApp接入鸿蒙版阿里百川
华为·uni-app·harmonyos
2501_915921433 天前
详细教程:使用Perfdog工具测量iOS应用的功耗性能与优化方法
android·macos·ios·小程序·uni-app·cocoa·iphone
梦曦i3 天前
uni-app、uni-app x 与 Flutter 深度对比:2026年跨平台开发框架选型指南
flutter·uni-app·uni-app x
普马萨特4 天前
uni-app x 定位踩坑实录:H5/小程序/App 统一经纬度与逆地理编码
uni-app
Geek_Vison4 天前
保险APP已经用了Flutter,还能接入小程序吗?
flutter·小程序·uni-app·mpaas·小程序容器
郑州光合科技余经理5 天前
本地生活平台搭建:跨业态用户标识怎么贯通
java·开发语言·前端·后端·uni-app·php·ai编程
2501_915909066 天前
iOS应用从开发到上架App Store的完整发布流程与步骤指南
android·ios·小程序·https·uni-app·webview