小程序开发日记⑦:服务范围、收货地址与地图选点

1057 字
5 分钟
小程序开发日记⑦:服务范围、收货地址与地图选点

无人机并不是“哪里都能送”。用户下单前需要知道服务覆盖到哪里,填写地址时又需要把文字地点落到真实坐标。本篇包含服务范围和地图选点两部分。

1. 服务范围数据#

pages/common/service-range.vue 从配置接口获取中心纬度、经度和半径。接口不可用时页面显示“程序未配置”,开发环境可以保留默认中心用于布局,但不能把默认值当真实范围。

function applyServiceArea(area) {
latitude.value = area.latitude
longitude.value = area.longitude
serviceRadius.value = area.radius
mapScale.value = getScaleByRadius(area.radius, area.latitude)
mapReady.value = true
}

地图的 circles 属性绘制服务区域:

const circles = computed(() => [{
latitude: latitude.value,
longitude: longitude.value,
radius: serviceRadius.value,
color: '#1769e8',
fillColor: '#1769e833',
strokeWidth: 3
}])

2. 根据半径计算缩放级别#

固定 scale 会让小范围太空、大范围被裁掉。页面根据半径估算目标米/像素,再换算缩放级别:

function getScaleByRadius(radius, lat) {
const targetMetersPerPixel = Math.max(1, (radius * 2) / (390 * 0.72))
const cosLat = Math.max(0.2, Math.cos(Number(lat) * Math.PI / 180))
const scale = Math.log2((156543.03392 * cosLat) / targetMetersPerPixel)
return Math.max(5, Math.min(16, Math.round(scale)))
}

纬度会影响同一缩放级别下的地面分辨率,因此计算中保留 cos(lat) 修正。

3. 地图选点页面#

pages/common/location-picker.vue 支持当前位置、地点搜索、拖动地图中心和候选地址列表。地图中间的选点图标是固定在容器中心的视觉指示,真正坐标在 regionchange 结束时通过地图上下文解析。

用户拖动地图
↓
regionchange end
↓
读取地图中心经纬度
↓
逆地理编码获得地址
↓
更新候选地点与选中项

拖动过程中不应连续逆地理编码,否则一次手势会产生大量请求。页面通过序号和短延迟,只处理最后一次中心点变化。

4. 候选地点模型#

无论候选数据来自搜索、当前位置还是地图中心,都统一转换为:

{
id,
title,
subtitle,
fullAreaName,
detailedAddress,
regionId,
latitude,
longitude
}

统一模型使列表选择和地图选择最终都调用 recipient.setSelectedAddress(place),不用为每种来源写一套回填逻辑。

5. 确认前再次检查服务范围#

选择一个地点不代表它一定可配送。确认按钮拿到坐标后调用服务范围判断,超出范围则保留页面并给出提示。校验要在最终坐标确定后执行,而不是只在搜索结果返回时判断,因为用户还可能继续拖动地图。

6. 原生地图与覆盖层#

小程序 map 是原生组件,层级和普通 DOM 不完全相同。地图上的 marker、polyline、circle 尽量使用组件原生属性;普通说明卡片放在地图外层。需要覆盖地图的按钮要控制层级,并在真机环境关注 cover-view 兼容性。

7. 定位权限与降级#

“定位到我”使用 GCJ-02 坐标。用户拒绝位置权限时不阻断页面,仍可搜索或拖动地图选择;页面只提示检查权限。定位是快捷方式,不应成为唯一入口。

8. 本篇小结#

范围判断的计算#

圆形服务区可以使用 Haversine 公式计算选点到中心的球面距离,再和半径比较。页面显示的圆与提交校验必须使用同一组中心和半径,不能一个来自默认配置、另一个来自接口。

const inRange = distanceMeters(point, serviceCenter) <= serviceRadius

靠近边界时要考虑 GPS 精度和业务容差,页面可以显示“接近服务边界,请确认”,最终是否允许下单由后端再次判断。前端范围校验用于即时反馈,不能替代服务端规则。

逆地理编码结果中的省市区 ID、完整地区名和 POI 文本分别保存,避免把一整串可读地址错误地当成行政区字段提交。

文字地址让人知道去哪儿,经纬度让程序知道画在哪儿,服务半径则负责说“能不能去”。三者对齐以后,下单地址才不再是一句模糊的地名,而是地图上一个可以被验证的点。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
小程序开发日记⑦:服务范围、收货地址与地图选点
https://firefly.cuteleaf.cn/posts/mmp-dev-diary-7/
作者
Yore
发布于
2026-08-14
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
Yore
Hello, I'm Yore.
公告
欢迎来到Yore的博客!本站基于原创作者夏叶的博客网站模版创作。
分类
标签
最新动态
站点统计
文章
51
分类
2
标签
124
总字数
94,115
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
EdgeOne Pages
博客版本
Firefly v6.15.0
文章许可
CC BY-NC-SA 4.0