如何判断坐标是否在Geoapify Isoline API返回的等时线范围内?
解决方案:判断工作地点是否在等时线范围内
核心思路:自定义点-in-多边形算法实现
由于Geoapify Geometry API不支持点与多边形的包含关系判断,直接基于经典射线法实现自定义逻辑是最可行的方案,具体落地步骤如下:
1. 编写点-in-多边形判断函数
基于射线法实现工具函数,输入等时线多边形坐标数组和工作地点经纬度,返回布尔值表示是否在范围内:
function pointInPolygon(point, polygon) { let x = point.lng, y = point.lat; let inside = false; for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) { let xi = polygon[i][0], yi = polygon[i][1]; let xj = polygon[j][0], yj = polygon[j][1]; const intersect = ((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi); if (intersect) inside = !inside; } return inside; }
注:该函数适配Geoapify返回的[lng, lat]格式坐标数组。
2. 批量判断并更新标记样式与搜索结果
获取等时线多边形数据后,遍历所有工作地点标记点,完成范围判断并同步更新样式和列表:
// 假设isolinePolygon为Geoapify返回的等时线坐标数组 // jobMarkers为Leaflet标记点数组 jobMarkers.forEach(marker => { const jobPoint = marker.getLatLng(); const isInside = pointInPolygon({ lng: jobPoint.lng, lat: jobPoint.lat }, isolinePolygon); // 用hue-rotate滤镜切换标记颜色 marker.getElement().style.filter = isInside ? 'hue-rotate(0deg)' : 'hue-rotate(180deg)'; // 同步隐藏/显示搜索结果中的范围外地点 const jobListItem = document.querySelector(`[data-job-id="${marker.options.jobId}"]`); if (jobListItem) { jobListItem.style.display = isInside ? 'block' : 'none'; } });
3. 实现手动添加/排除标记的交互
为标记点绑定点击事件,支持用户手动切换地点的包含状态:
jobMarkers.forEach(marker => { marker.on('click', () => { // 切换自定义的包含状态 marker.options.isInside = !marker.options.isInside; // 更新标记颜色 marker.getElement().style.filter = marker.options.isInside ? 'hue-rotate(0deg)' : 'hue-rotate(180deg)'; // 更新搜索结果显示状态 const jobListItem = document.querySelector(`[data-job-id="${marker.options.jobId}"]`); if (jobListItem) { jobListItem.style.display = marker.options.isInside ? 'block' : 'none'; } }); });
关键注意事项
- 确保等时线多边形是闭合状态(首尾坐标一致),若API返回未闭合,需手动将首坐标追加到数组末尾。
- 处理多环多边形:如果等时线包含多个独立区域,需对每个子多边形分别判断,只要点在任意一个子多边形内,即判定为在范围内。
内容的提问来源于stack exchange,提问作者PeterV
相关产品推荐
相关产品推荐

