基于经纬度划分运输区域网格及请求数统计的实现方案咨询
无API实现思路:运输区域划分与经纬度归属判断
一、提取全局运输范围(大正方形)
- 从MongoDB的
CitizenRequest集合中批量提取所有PointPath的经纬度数据:- 如果
PointPath是JSON数组(例如[{"lng": 116.3, "lat": 39.9}, ...]),用MongoDB聚合管道展开并计算边界:db.CitizenRequest.aggregate([ {$unwind: "$PointPath"}, {$group: { _id: null, min_lng: {$min: "$PointPath.lng"}, max_lng: {$max: "$PointPath.lng"}, min_lat: {$min: "$PointPath.lat"}, max_lat: {$max: "$PointPath.lat"} }} ]) - 得到四个边界值后,大正方形范围即为:西(min_lng)、东(max_lng)、南(min_lat)、北(max_lat)
- 如果
二、划分小Zone并存储
- 确定小Zone尺寸:
- 自定义每个Zone的经度跨度
Δlng和纬度跨度Δlat(例如0.01度,约对应1公里边长,可按需调整)
- 自定义每个Zone的经度跨度
- 计算Zone行列数量:
- 横向(经度方向)数量:
count_lng = Math.ceil((max_lng - min_lng) / Δlng) - 纵向(纬度方向)数量:
count_lat = Math.ceil((max_lat - min_lat) / Δlat)
- 横向(经度方向)数量:
- 生成Zone数据并存入新集合(如
TransportZone):- 遍历每个行列索引
(row, col),计算当前Zone边界:// 示例Node.js代码 const zone = { zone_id: `${row}-${col}`, // 或用数字ID:row * count_lng + col min_lng: min_lng + col * Δlng, max_lng: min_lng + (col + 1) * Δlng, min_lat: min_lat + row * Δlat, max_lat: min_lat + (row + 1) * Δlat, request_count: 0 // 初始请求数为0 } - 将所有Zone文档插入
TransportZone集合
- 遍历每个行列索引
三、经纬度归属Zone的判断算法
对于任意经纬度点(target_lng, target_lat),按以下步骤计算所属Zone:
- 范围校验:如果
target_lng不在[min_lng, max_lng]或target_lat不在[min_lat, max_lat],则不属于任何运输Zone - 计算行列索引:
- 横向索引:
col = Math.floor((target_lng - min_lng) / Δlng) - 纵向索引:
row = Math.floor((target_lat - min_lat) / Δlat) - 边界修正:若
target_lng === max_lng,则col = count_lng - 1;若target_lat === max_lat,则row = count_lat - 1(避免索引越界)
- 横向索引:
- 匹配Zone ID:根据
(row, col)直接生成对应zone_id,或从TransportZone集合中查询
四、请求数量统计优化
- 批量更新:遍历
CitizenRequest集合,对每个请求的PointPath(取起点则用第一个点,统计全路径则遍历所有点)计算所属Zone ID,然后用MongoDB的updateOne累加请求数:db.TransportZone.updateOne( { zone_id: "0-1" }, { $inc: { request_count: 1 } } ) - 缓存参数:将全局的
min_lng、Δlng等关键参数缓存到内存,避免每次判断都查询数据库,提升效率
内容的提问来源于stack exchange,提问作者TrySoHard
相关产品推荐
相关产品推荐

