概述
App Inventor 2内置了 Map 组件(基于OpenStreetMap),可以实现:
- 地图显示和交互
- 地图标记(Marker)
- 绘制线和多边形
- 电子围栏(地理围栏)
- 路径追踪
Map组件位于组件面板的 Maps 分类下。
Map组件核心属性
| 属性 | 类型 | 说明 |
|---|---|---|
| CenterFromString | text | 地图中心点(”纬度,经度”格式) |
| ZoomLevel | number | 缩放级别(1-18,越大越详细) |
| MapType | number | 地图类型(1=道路图,2=卫星图) |
| ShowCompass | boolean | 显示指南针 |
| ShowUser | boolean | 显示用户位置 |
| ShowZoom | boolean | 显示缩放按钮 |
| EnableZoom | boolean | 允许缩放手势 |
| LocationSensor | component | 关联的位置传感器 |
基本地图使用
显示地图并定位到指定位置
当 Screen1.初始化
设 Map1.中心点从字符串 = "39.9042,116.4074" ' 北京天安门
设 Map1.缩放级别 = 15
设 Map1.显示用户位置 = true
关联LocationSensor自动定位
当 Screen1.初始化
设 Map1.位置传感器 = LocationSensor1 ' 关联传感器
设 LocationSensor1.启用 = true
设 Map1.显示用户位置 = true
当 LocationSensor1.位置改变(纬度, 经度, 海拔, 速度)
' 地图自动跟随用户位置
设 Map1.中心点从字符串 = 纬度 & "," & 经度
地图标记(Marker)
添加标记
当 按钮_添加标记.被点击
设 标记 = 创建标记(
纬度 → 39.9042,
经度 → 116.4074,
标题 → "天安门",
描述 → "北京市中心",
颜色 → 红色
)
调用 Map1.添加标记(标记)
动态添加多个标记
设 地点列表 = [
{name: "天安门", lat: 39.9042, lng: 116.4074},
{name: "故宫", lat: 39.9163, lng: 116.3972},
{name: "颐和园", lat: 39.9998, lng: 116.2755},
{name: "鸟巢", lat: 39.9929, lng: 116.3966}
]
当 Screen1.初始化
设 i = 1
当 i ≤ 列表长度(地点列表)
设 地点 = 列表第i项(地点列表)
调用 Map1.创建标记(
从字典 地点 获取 "lat",
从字典 地点 获取 "lng",
从字典 地点 获取 "name",
"",
红色)
设 i = i + 1
标记点击事件
当 Map1.标记被点击(标记)
设 标记.显示信息窗口()
标签_选中.文本 = "选中:" & 标记.标题 & "(" & 标记.纬度 & ", " & 标记.经度 & ")"
绘制线条和路径
绘制两点间的线
当 按钮_画线.被点击
调用 Map1.添加折线(
[起点纬度, 终点纬度], ' 纬度列表
[起点经度, 终点经度], ' 经度列表
红色, ' 颜色
3 ' 线宽
)
路径追踪
记录用户移动轨迹并在地图上绘制:
设 纬度列表 = 创建空列表
设 经度列表 = 创建空列表
当 LocationSensor1.位置改变(纬度, 经度, 海拔, 速度)
' 只在移动时记录(速度>0.5m/s)
如果 速度 > 0.5
设 纬度列表 = 添加列表项(纬度列表, 纬度)
设 经度列表 = 添加列表项(经度列表, 经度)
' 更新路径线
如果 列表长度(纬度列表) > 1
调用 Map1.清除折线()
调用 Map1.添加折线(纬度列表, 经度列表, 蓝色, 4)
电子围栏(Geofencing)
电子围栏是在地图上划定的虚拟边界,当用户进入或离开该区域时触发事件。
原理
使用 LocationSensor 持续获取位置,计算与围栏中心的距离,判断是否在围栏内。
计算两点间距离(Haversine公式)
定义 计算距离(纬度1, 经度1, 纬度2, 经度2) 返回 距离米
设 R = 6371000 ' 地球平均半径(米)
设 dLat = (纬度2 - 纬度1) * 数学.PI / 180
设 dLon = (经度2 - 经度1) * 数学.PI / 180
设 a = 数学.正弦(dLat/2) * 数学.正弦(dLat/2) +
数学.余弦(纬度1 * 数学.PI / 180) * 数学.余弦(纬度2 * 数学.PI / 180) *
数学.正弦(dLon/2) * 数学.正弦(dLon/2)
设 c = 2 * 数学.反正切2(数学.平方根(a), 数学.平方根(1-a))
返回 R * c
实现电子围栏
设 围栏中心纬度 = 39.9042
设 围栏中心经度 = 116.4074
设 围栏半径 = 500 ' 500米
设 是否在围栏内 = false
当 LocationSensor1.位置改变(纬度, 经度, 海拔, 速度)
设 距离 = 计算距离(纬度, 经度, 围栏中心纬度, 围栏中心经度)
如果 距离 ≤ 围栏半径
如果 非 是否在围栏内
设 是否在围栏内 = true
调用 通知.显示信息("📍 进入围栏", "你已进入目标区域(距离中心" & 数学.保留小数(距离, 0) & "米)")
否则
如果 是否在围栏内
设 是否在围栏内 = false
调用 通知.显示信息("🚶 离开围栏", "你已离开目标区域(距离中心" & 数学.保留小数(距离, 0) & "米)")
标签_距离.文本 = "距离围栏中心:" & 数学.保留小数(距离, 0) & "米"
在地图上显示围栏
当 Screen1.初始化
' 画一个圆形围栏(用多边形近似)
设 纬度点 = 创建空列表
设 经度点 = 创建空列表
设 i = 0
当 i < 360
设 角度 = i * 数学.PI / 180
' 纬度偏移
设 dLat = 围栏半径 / 111320 ' 1度纬度约111.32km
设 dLon = 围栏半径 / (111320 * 数学.余弦(围栏中心纬度 * 数学.PI / 180))
设 点纬度 = 围栏中心纬度 + dLat * 数学.余弦(角度)
设 点经度 = 围栏中心经度 + dLon * 数学.正弦(角度)
设 纬度点 = 添加列表项(纬度点, 点纬度)
设 经度点 = 添加列表项(经度点, 点经度)
设 i = i + 10 ' 每10度一个点
调用 Map1.添加多边形(纬度点, 经度点, 绿色, 黄色, 2)
实战案例:儿童安全围栏
功能需求
- 在地图上设定安全区域
- 实时监控儿童位置
- 离开安全区域时家长收到通知
- 显示儿童移动轨迹
积木块代码
设 安全区域中心纬度 = 39.9042
设 安全区域中心经度 = 116.4074
设 安全半径 = 300 ' 300米
设 家长电话 = "13800138000"
设 是否安全 = true
当 Screen1.初始化
设 LocationSensor1.启用 = true
设 Map1.中心点从字符串 = 安全区域中心纬度 & "," & 安全区域中心经度
设 Map1.缩放级别 = 16
' 在地图上画安全区域
调用 绘制安全区域()
' 添加安全区域中心标记
调用 Map1.创建标记(安全区域中心纬度, 安全区域中心经度, "🏠 家", "安全区域中心", 绿色)
当 LocationSensor1.位置改变(纬度, 经度, 海拔, 速度)
设 距离 = 计算距离(纬度, 经度, 安全区域中心纬度, 安全区域中心经度)
标签_状态.文本 = "距离家:" & 数学.保留小数(距离, 0) & "米"
' 更新儿童位置标记
设 Map1.中心点从字符串 = 纬度 & "," & 经度
如果 距离 > 安全半径
如果 是否安全
设 是否安全 = false
标签_状态.文本颜色 = 红色
' 发送短信通知家长
调用 短信组件.发送短信(家长电话, "⚠️ 儿童已离开安全区域!当前位置:" & 纬度 & "," & 经度)
否则
如果 非 是否安全
设 是否安全 = true
标签_状态.文本颜色 = 绿色
调用 短信组件.发送短信(家长电话, "✅ 儿童已回到安全区域")
常见问题
Q1: Map组件显示空白?
- 确保有网络连接(Map使用OpenStreetMap在线瓦片)
- 检查CenterFromString格式是否正确(”纬度,经度”,注意纬度在前)
- 确认ZoomLevel设置合理(建议10-16)
Q2: 位置更新不频繁?
- LocationSensor的
DistanceInterval设小一些(如1米) - 但注意频繁更新会增加耗电
Q3: 如何计算两个GPS点之间的距离?
使用上面提供的Haversine公式计算函数。短距离(<1km)精度足够。
Q4: 电子围栏后台运行?
App Inventor应用在后台时传感器会被系统暂停。解决方案:
- 设置
TimerAlwaysFires = true - 使用前台服务(需要扩展)
- 或接受App Inventor的限制,只在App前台运行时监控
总结
| 功能 | 组件 | 方法 |
|---|---|---|
| 地图显示 | Map | 设置中心点和缩放级别 |
| 定位 | LocationSensor | LocationChanged事件 |
| 标记 | Map.CreateMarker | 添加图标和信息窗口 |
| 路径绘制 | Map.AddPolyline | 纬度/经度列表 |
| 电子围栏 | LocationSensor + 数学 | Haversine距离计算 |
| 位置追踪 | LocationSensor + Map | 实时更新位置和路径 |
版权声明:MIT App Inventor 官方文档采用 CC BY-SA 4.0 授权,本文档由 ai2claw 🐝 整理。
扫码添加客服咨询