Files
akmon/doc_chat/位置.md
2026-01-20 08:04:15 +08:00

218 lines
9.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
明白了。你想把“2.4G 网关 + 手环 RSSI”估算出的位置信息接到地图里在 uni-app-xUTS Android上怎么做更稳当。下面给你一套实用建议和可直接复用的代码骨架包含精度圈、外部地图打开、国标坐标处理等
## 建议与实践路径
- 定位算法侧(从 RSSI 到坐标)
- 用对数路径损耗模型把 RSSI 转成距离d = 10^((RSSI0 RSSI) / (10·n))n 在室内一般 2.23.0,需要场地标定得到 RSSI0 和 n。
- 融合多网关:
- 简单稳健加权质心WCL权重用 1/d^p 或用 RSSI 线性/指数映射,抗多径比三边定位更鲁棒。
- 条件好时:三边定位(最小二乘)+ RANSAC 剔除离群网关。
- 平滑与抗抖动35 点中值滤波 + 指数滑动平均,或一维/二维卡尔曼滤波。
- 场景约束将估算点“吸附”到建筑内合法区域、多边形map matching并给出不确定性半径例如距离方差/残差→半径)。
- 坐标系问题(中国大陆必须重视)
- 如果你算出的是 WGS84GPS 原生),大多数国内地图(高德/腾讯/微信小程序/原生 <map>)使用 GCJ-02火星坐标。展示前请转换为 GCJ-02。
- 反向地理编码(坐标→地址)可用高德/腾讯等服务,注意密钥与限频,不要在前端暴露密钥。
- uni-app-xUTS Android地图接入的三种方式
1) 快速方案uni.openLocation 打开系统/第三方地图
- 最快、稳定;不在应用内嵌地图,适合查看/导航跳转。
2) 应用内嵌地图:内置 `<map>` 组件
- App-Android 通常可用 markers/circles/polyline在 uni-app-x 某些版本上功能覆盖可能比标准 uni 稍有限,如遇不支持的属性可退化或走插件方案。
3) UTS 原生插件(高德/腾讯地图 SDK
- 需要更高级能力(离线地图、室内图、海量点渲染、轨迹回放、热力图),建议用官方原生 SDK 的 UTS 插件。去 uni 原生插件市场搜索“高德地图 UTS/定位 UTS”等。
- 工程与性能建议
- 权限Android 申请 ACCESS_FINE_LOCATION在 manifest.json 的 app-plus 节点配置权限。
- 绑定简化:模板里避免函数调用和复杂表达式,预先计算好 markers/circles 字段(已按 UTS 规范给出示例)。
- 批量更新:频繁刷新时做节流/合并更新,避免每条数据都 setData。
- 可视化:用 circle 显示“不确定性半径”;锚点颜色代表置信度;支持点击 marker 查看详情。
## 可复用代码片段
### 1) 坐标转换WGS84 → GCJ-02UTS 版)
```ts
// utils/coord.uts
export function wgs84ToGcj02(lat: number, lng: number): number[] {
if (outOfChina(lat, lng)) return [lat, lng]
const dLat = transformLat(lng - 105.0, lat - 35.0)
const dLng = transformLng(lng - 105.0, lat - 35.0)
const radLat = lat / 180.0 * Math.PI
let magic = Math.sin(radLat)
magic = 1 - 0.00669342162296594323 * magic * magic
const sqrtMagic = Math.sqrt(magic)
const dLat2 = (dLat * 180.0) / ((6335552.717000426 * magic) / (sqrtMagic) * Math.PI)
const dLng2 = (dLng * 180.0) / ((6378245.0 / sqrtMagic * Math.cos(radLat)) * Math.PI)
return [lat + dLat2, lng + dLng2]
}
function outOfChina(lat: number, lng: number): boolean {
return (lng < 72.004 || lng > 137.8347 || lat < 0.8293 || lat > 55.8271)
}
function transformLat(x: number, y: number): number {
let ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x))
ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0 / 3.0
ret += (20.0 * Math.sin(y * Math.PI) + 40.0 * Math.sin(y / 3.0 * Math.PI)) * 2.0 / 3.0
ret += (160.0 * Math.sin(y / 12.0 * Math.PI) + 320 * Math.sin(y * Math.PI / 30.0)) * 2.0 / 3.0
return ret
}
function transformLng(x: number, y: number): number {
let ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x))
ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0 / 3.0
ret += (20.0 * Math.sin(x * Math.PI) + 40.0 * Math.sin(x / 3.0 * Math.PI)) * 2.0 / 3.0
ret += (150.0 * Math.sin(x / 12.0 * Math.PI) + 300.0 * Math.sin(x / 30.0 * Math.PI)) * 2.0 / 3.0
return ret
}
```
使用建议:如果你算出来的是 WGS84就先 `wgs84ToGcj02` 再喂给地图组件/服务。
### 2) 最快路径外部地图打开openLocation
```vue
<!-- pages/location/open.uvue -->
<template>
<view class="page">
<button class="btn" @click="open">在地图中查看</button>
</view>
</template>
<script lang="uts">
export default {
data() { return { name: '手环估计位置', lat: 31.23037, lng: 121.4737 } },
methods: {
open() {
// 确保已转换到 GCJ-02如果在中国大陆
const name = this.name
const latitude = this.lat
const longitude = this.lng
uni.openLocation({ latitude, longitude, name } as any)
}
}
}
</script>
<style scoped>
.page{ padding: 24rpx }
.btn{ padding: 16rpx 24rpx; border:1px solid #ddd; border-radius: 8rpx }
</style>
```
- 优点:零集成、稳定、导航能力强。
- 缺点:不在应用内展示。
### 3) 嵌入式地图(内置 `<map>` 组件,展示 marker + 精度圈)
注意:不同 uni-app-x 版本对 `<map>` 的支持程度略有差异。若你的环境不支持该组件,请选择 openLocation 或 UTS 插件路线。
```vue
<!-- pages/location/map.uvue -->
<template>
<view class="page">
<map class="map"
:latitude="centerLat"
:longitude="centerLng"
:scale="18"
:markers="markers"
:circles="circles">
</map>
<view class="toolbar">
<button @click="recenter">回到中心</button>
<button @click="openSysMap">外部地图</button>
</view>
</view>
</template>
<script lang="uts">
import { wgs84ToGcj02 } from '@/utils/coord.uts'
type MapMarker = {
id: number; latitude: number; longitude: number;
iconPath: string; width: number; height: number; callout?: any
}
export default {
data() {
return {
centerLat: 31.23037,
centerLng: 121.4737,
markers: [] as Array<MapMarker>,
circles: [] as Array<any>,
// 原始估算WGS84
estLat: 31.23037,
estLng: 121.4737,
// 不确定性半径(米),可用 RSSI 残差/方差计算
radius: 20
}
},
onLoad() {
this.refreshDisplay()
},
methods: {
refreshDisplay() {
// 估算坐标→ GCJ-02
const r = wgs84ToGcj02(this.estLat, this.estLng)
const lat = r[0] as number
const lng = r[1] as number
this.centerLat = lat
this.centerLng = lng
// 标点
this.markers = [{
id: 1,
latitude: lat,
longitude: lng,
iconPath: '/static/marker.png',
width: 32, height: 32,
callout: { content: '手环估计位置', color: '#000', display: 'ALWAYS' }
}]
// 精度圈
this.circles = [{
latitude: lat,
longitude: lng,
radius: this.radius,
color: '#3b82f680',
fillColor: '#3b82f633',
strokeWidth: 2
}]
},
recenter() {
this.refreshDisplay()
},
openSysMap() {
uni.openLocation({ latitude: this.centerLat, longitude: this.centerLng, name: '手环估计位置' } as any)
}
}
}
</script>
<style scoped>
.page{ display:flex; flex-direction: column; height:100% }
.map{ flex:1; width:100% }
.toolbar{ padding: 12rpx; border-top:1px solid #eee; display:flex; gap: 12rpx }
</style>
```
要点UTS/uni-app-x 规范友好):
- 模板里用简单绑定;数据在 data/方法中预先整理,不在模板做复杂表达式。
- 属性名、数组结构与 `<map>` 组件文档保持一致;一次性替换 `markers/circles`,避免频繁小更新。
### 4) UTS 原生插件路线(当你需要更强能力)
- 场景:内置 `<map>` 组件受限、需要室内图/离线地图/大量覆盖物/轨迹回放/热力图等。
- 做法:在 uni 原生插件市场搜索“高德地图 UTS/定位 UTS”等选择维护活跃的插件。
- 优点:更强渲染与能力接入;缺点:体积与集成复杂度上升。
## 权限与清单Android
- manifest.json 中的 app-plus > android > permission 添加定位权限(通常 uni 默认已包含)。首次进入地图页或获取定位前提示授权。
- 若做后台定位或持续上传,需额外前台服务与权限申明,注意隐私合规。
## UI/交互建议
- 展示“估计位置 + 不确定性半径”:用户能感知误差而非认为是“点精确到米”。
- 支持点击 marker 查看当前 RSSI 源信息(网关数、残差、权重),便于排障。
- 多手环时,颜色/形状区分,支持列表一键定位到某个手环。
- 大量点位更新做节流(例如 500ms 合并一次),减少渲染压力。
---
如果你愿意,我可以在仓库里加一个 `pages/location` 示例页(含坐标转换工具 `utils/coord.uts`),并把你 RSSI 解算出的结果WGS84接上这个页面页面内展示 marker 与精度圈,同时提供“一键外部地图打开”。你只需要告诉我:页面路由名、是否用内置 `<map>` 还是先用 `openLocation` 路线即可。
Similar code found with 2 license types