
1. 电子围栏功能入门指南第一次接触电子围栏这个概念时我正负责一个共享单车管理系统的开发。当时产品经理提出要在APP上实现停车区域监控功能我才开始研究uniapp的map组件。电子围栏说白了就是在地图上画个虚拟边界当设备进入或离开这个区域时触发相应操作。uniapp的map组件内置了多边形绘制功能这为我们实现电子围栏提供了基础支持。相比原生开发uniapp的方案有三大优势跨平台兼容一套代码同时支持iOS和Android开发简单不需要处理复杂的原生API性能稳定经过大量项目验证在开始编码前建议先准备好以下环境HBuilderX最新版我用的3.6.18真机测试设备模拟器定位不准高德或腾讯地图开发者账号用于申请key2. 基础地图配置实战2.1 项目初始化新建uniapp项目时记得勾选微信小程序模板即使不做小程序因为这个模板自带了必要的地图权限配置。我吃过亏用默认模板后来发现安卓机无法定位。在manifest.json中需要添加这些配置permission: { scope.userLocation: { desc: 你的位置信息将用于电子围栏功能 } }, mp-weixin: { appid: , requiredPrivateInfos: [getLocation] }2.2 地图密钥申请很多新手会卡在这一步。以腾讯地图为例登录腾讯位置服务官网创建应用时选择微信小程序在开发管理-开发设置中设置request合法域名将获得的key填入项目配置实测发现一个小技巧iOS和Android可以用不同的key这样在统计时能区分平台数据。3. 围栏绘制核心代码解析3.1 坐标点数据结构先看这段核心代码polygons: [{ points: [ {longitude: 116.439688, latitude: 39.961146}, //...其他坐标点 ], fillColor: #cbdde9, strokeColor: #78addd, strokeWidth: 2 }]这里有个坑我踩过坐标点必须按顺序连接形成闭合区域。曾经因为点序错乱画出了8字形围栏。建议使用高德地图的坐标拾取工具至少需要3个点才能形成面首尾坐标最好相同确保闭合3.2 动态围栏交互通过v-model绑定switch组件可以实现围栏显隐控制switch changetoggleFence :checkedshowFence/在methods中添加toggleFence(e) { this.polygons e.detail.value ? [{ //...围栏配置 }] : [] }4. 高级功能开发技巧4.1 围栏触发检测光有图形展示还不够关键是要检测设备与围栏的位置关系。这里需要用到uni.getLocationsetInterval(async () { const res await uni.getLocation({type: gcj02}) const inside this.checkInFence(res.longitude, res.latitude) if(inside ! this.lastStatus) { uni.showToast({ title: inside ? 进入围栏区域 : 离开围栏区域 }) this.lastStatus inside } }, 5000)checkInFence方法实现射线法判断点是否在多边形内这是计算机图形学的经典算法。4.2 性能优化方案当围栏区域复杂时可能会卡顿。我的优化经验减少坐标点数量用贝塞尔曲线平滑降低检测频率进入敏感区域后再提高频率使用webworker做后台计算避免频繁setData操作5. 常见问题解决方案5.1 真机显示异常遇到过安卓机围栏不显示的问题最终发现是样式必须用rpx单位需要开启硬件加速部分机型需要设置zIndex解决方案map { width: 100%; height: 100vh; transform: translateZ(0); }5.2 坐标偏移问题不同地图平台的坐标系不同腾讯地图使用GCJ-02百度地图使用BD-09谷歌地图使用WGS-84建议全程使用GCJ-02坐标系转换方法function gcj2bd(lng, lat) { //...坐标转换算法 }6. 完整项目实战分享一个我做的共享停车项目中的核心代码// 围栏管理类 class GeoFence { constructor(mapContext) { this.map mapContext this.fences new Map() } addFence(id, points, callback) { this.fences.set(id, {points, callback}) this.updateMap() } checkAll(lng, lat) { this.fences.forEach((fence, id) { const inside this.contains(fence.points, lng, lat) if(inside ! fence.lastStatus) { fence.callback(inside) fence.lastStatus inside } }) } }这个方案支持多围栏管理在实际项目中运行稳定。关键点是使用了Map结构存储围栏状态避免频繁操作DOM。