UniApp跨平台实战:构建智能室内导航系统解决方案
一、架构设计原理
基于蓝牙信标+路径规划算法+跨平台地图渲染的导航系统,支持iOS/Android/小程序多端运行
二、核心功能实现
1. 蓝牙信标定位引擎
// beacon-service.js
export class BeaconService {
constructor() {
this.beacons = new Map()
this.currentPosition = null
}
startScan() {
uni.startBeaconDiscovery({
uuids: ['FDA50693-A4E2-4FB1-AFCF-C6EB07647825'],
success: () => this.onBeaconUpdate(),
fail: (err) => console.error('蓝牙扫描失败', err)
})
uni.onBeaconUpdate(res => {
this.updateBeacons(res.beacons)
this.calculatePosition()
})
}
updateBeacons(beacons) {
beacons.forEach(beacon => {
this.beacons.set(beacon.major + '-' + beacon.minor, {
x: beacon.major,
y: beacon.minor,
distance: this.calculateDistance(beacon.rssi)
})
})
}
calculatePosition() {
// 三点定位算法实现
const [b1, b2, b3] = [...this.beacons.values()]
this.currentPosition = this.trilateration(b1, b2, b3)
}
}
2. 跨平台地图渲染
import { ref, onMounted } from 'vue'
import { useBeacon } from './beacon-service'
const { currentPosition } = useBeacon()
const canvasRef = ref(null)
onMounted(() => {
const ctx = uni.createCanvasContext('mapCanvas', this)
// 绘制地图底图
uni.getImageInfo({
src: '/static/map-floor1.jpg',
success: (res) => {
ctx.drawImage(res.path, 0, 0, 300, 400)
ctx.draw()
}
})
})
watch(currentPosition, (pos) => {
if (pos) {
const ctx = uni.createCanvasContext('mapCanvas', this)
ctx.setFillStyle('#FF0000')
ctx.arc(pos.x, pos.y, 5, 0, 2 * Math.PI)
ctx.fill()
ctx.draw()
}
})
3. 路径规划服务
// path-service.js
export class PathService {
constructor(mapData) {
this.nodes = mapData.nodes
this.edges = mapData.edges
}
findPath(start, end) {
const openSet = [start]
const cameFrom = new Map()
const gScore = new Map(this.nodes.map(n => [n.id, Infinity]))
const fScore = new Map(this.nodes.map(n => [n.id, Infinity]))
gScore.set(start.id, 0)
fScore.set(start.id, this.heuristic(start, end))
while (openSet.length > 0) {
const current = this.getLowestFScore(openSet, fScore)
if (current.id === end.id) {
return this.reconstructPath(cameFrom, current)
}
openSet.splice(openSet.indexOf(current), 1)
this.getNeighbors(current).forEach(neighbor => {
const tentativeGScore = gScore.get(current.id) +
this.distanceBetween(current, neighbor)
if (tentativeGScore < gScore.get(neighbor.id)) {
cameFrom.set(neighbor.id, current)
gScore.set(neighbor.id, tentativeGScore)
fScore.set(neighbor.id,
tentativeGScore + this.heuristic(neighbor, end))
if (!openSet.includes(neighbor)) {
openSet.push(neighbor)
}
}
})
}
return null // 未找到路径
}
}
三、高级功能实现
1. AR实景导航
// ar-navigator.js
export class ARNavigator {
constructor() {
this.ctx = uni.createCameraContext()
this.markers = []
}
startAR(path) {
this.markers = path.map((node, i) => ({
id: i,
latitude: node.lat,
longitude: node.lng,
iconPath: '/static/arrow.png',
width: 20,
height: 20
}))
uni.startDeviceMotionListening({
interval: 'game',
success: () => this.updateCamera()
})
}
updateCamera() {
uni.onDeviceMotionChange(res => {
const angle = Math.atan2(res.beta, res.gamma) * 180 / Math.PI
this.markers.forEach(m => {
m.rotate = angle
})
})
}
}
2. 性能优化方案
- 信标过滤:RSSI动态阈值
- 路径缓存:常用路线预计算
- 按需渲染:可视区域优化
- 节流处理:定位频率控制
四、实战案例演示
1. 完整导航流程
// pages/navigation/index.vue
import { useBeacon, usePath, useAR } from '@/services'
const { currentPosition } = useBeacon()
const { findPath } = usePath()
const { startAR } = useAR()
const startNavigation = (destination) => {
const path = findPath(currentPosition.value, destination)
if (path) {
startAR(path)
}
}
2. 性能测试数据
测试环境:商场场景/10个信标 定位精度:2-3米 响应延迟:平均200ms 内存占用:≈80MB 兼容性:iOS12+/Android8+

