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)
相关推荐
多客:duokelijie16 小时前
代练订单系统选型思路:跨品类游戏接入、订单分层管理、自动结算逻辑拆解!
数据库·mysql·微信小程序·前端框架·uni-app·php·持续部署
码间留白1 天前
鸿蒙端对接 BLE 血压计:从一次握手到读数入库(二)设备篇
物联网·uni-app·鸿蒙·蓝牙ble·血压计
华玥作者2 天前
Vue 3 + TypeScript + uni-app 组件库推荐:hy-app(华玥组件库)
vue.js·typescript·uni-app
FinelyYang2 天前
uniapp使用kkfileview在线预览ppt,excel,word,pdf类型文件
pdf·uni-app·powerpoint
2501_916008892 天前
iPhone 设备信息查看,用 KeyMob 看型号、序列号、电池健康和 UDID
android·ios·小程序·https·uni-app·iphone·webview
ModyQyW3 天前
vite-plugin-uni-manifest 0.7:在 uni-app 读取之前生成
前端·uni-app
lyz2468593 天前
uniapp vue3 小程序开发注意事项
uni-app
雪芽蓝域zzs3 天前
WebStorm Uniapp Support + Uniapp Tool + Uniappx Language Service讲解
vue.js·uni-app·webstorm
普通人63 天前
Web端3D模型加载实战指南_Vue3_uni-app_HTML
前端·javascript·uni-app·html
PedroQue995 天前
0.8.2 新增 backFallback 配置,无 tabbar 页返回无忧
前端·uni-app