求助:如何拆分JavaScript中含首尾重复坐标的多边形坐标数组
拆分混合多边形坐标数组并绘制多个Google Maps多边形
核心拆分逻辑
每个合法多边形的首尾坐标完全一致,我们可以通过遍历坐标数组,逐个收集坐标点,当遇到与当前多边形起始点匹配的坐标时,完成一个多边形的收集,再启动下一个多边形的收集流程。
拆分函数实现
function splitPolygons(coords) { const polygons = []; if (coords.length === 0) return polygons; let currentPolygon = [coords[0]]; for (let i = 1; i < coords.length; i++) { const currentCoord = coords[i]; const startCoord = currentPolygon[0]; // 用精度阈值判断首尾坐标是否匹配,避免浮点运算误差 const isClosingPoint = Math.abs(currentCoord.lat - startCoord.lat) < 1e-8 && Math.abs(currentCoord.lng - startCoord.lng) < 1e-8; if (isClosingPoint) { currentPolygon.push(currentCoord); polygons.push(currentPolygon); currentPolygon = []; // 跳转至下一个多边形的起始点 if (i + 1 < coords.length) { currentPolygon.push(coords[i + 1]); i++; } } else { currentPolygon.push(currentCoord); } } // 处理未闭合的残留多边形(可选逻辑) if (currentPolygon.length > 0) { const start = currentPolygon[0]; currentPolygon.push({ lat: start.lat, lng: start.lng }); polygons.push(currentPolygon); } return polygons; }
修改原代码实现多多边形绘制
替换原有代码为以下逻辑,拆分坐标后逐个创建并绘制多边形:
var data = []; @foreach ($coordinates as $item) data.push({ lat: {{ $item['lat'] }}, lng: {{ $item['lng'] }} }); @endforeach // 拆分得到独立的多边形路径数组 const polygonPaths = splitPolygons(data); // 统一初始化边界对象,避免频繁视野跳动 const bounds = new google.maps.LatLngBounds(); // 遍历绘制每个多边形 polygonPaths.forEach(path => { const polygon = new google.maps.Polygon({ path: path, geodesic: true, strokeColor: '#FF0000', fillColor: '#FF0000', strokeWeight: 3, strokeOpacity: 0.8, fillOpacity: 0.3 }); polygon.setMap(map); // 扩展地图边界 path.forEach(coord => { bounds.extend(new google.maps.LatLng(coord.lat, coord.lng)); }); }); // 最后统一适配所有多边形的视野 map.fitBounds(bounds);
注意事项
- 浮点精度问题:如果坐标是高精度浮点数,必须用阈值(如
1e-8)判断经纬度是否相等,不能直接用===,避免因浮点运算误差导致拆分失败。 - 残留多边形处理:如果原始数组末尾存在未闭合的坐标组,函数会自动补全首尾坐标,你可以根据实际需求删除这部分逻辑。
- 边界优化:统一收集所有多边形的边界后再调用
fitBounds,比逐个调用更高效,能避免地图视野频繁跳动。
内容的提问来源于stack exchange,提问作者MarcinC
相关产品推荐
相关产品推荐

