在几个功能上分享很多要点的最佳方式?
Best way to share out many points on a few features?
我有 5000 多个 LatLng 点,对于每个点,我想找出它们属于哪个特征(区域)。这些特征来自 a kmz layer by Philippe Ivaldi,转换为 GeoJSON。
目前,我正在双 for
循环中使用 turfjs 执行此操作。不出所料,计算会使浏览器冻结十分钟,这不是很方便。
这是我的代码:
function countCeaByLayer(geoJsonLayer){
jQuery.getJSON('http://localhost/server/retrieveData.php', function(data){
var turfPoints = [];
for(var i = 0; i < data.length; i++){
turfPoints.push(turf.point([data[i].longitudeWGS84, data[i].latitudeWGS84]));
}
var features = geoJsonLayer.toGeoJSON().features;
for(var i = 0; i < features.length; i++){
var turfPointsNew = [];
for(var j = 0; j < turfPoints.length; j++){
var isInside = turf.inside(turfPoints[j], features[i]);
if(!isInside) turfPointsNew.push(turfPoints[j]);
}
turfPoints = turfPointsNew;
}
console.log("done");
});
}
如何避免冻结浏览器?
- 让它异步?
- 在服务器上使用
node
和 turfjs
进行计算?
- 或在具有
node
和 leaflet-headless
的服务器上部署 leafletjs
?
...或者我应该处理它?
谢谢!
要优化您的代码,您应该这样做。
遍历点。
对于每个点,当您遍历多边形以了解该点是否在其中一个内部时,首先获取多边形 Bounds 并查看该点是否在边界内。
如果没有,您可以跳过下一步并转到下一个多边形。
如果它在边界内,请直接检查它是否在多边形本身内。
如果是这种情况,请中断在多边形上迭代的循环并切换到下一个点。
例如,可以是:
points.forEach(function(point) {
polygons.some(function(polygon) {
if (polygon.getBounds().contains(point)) { // or other method if you are not playing with Leaflet features
if (turf.isInside(polygon, point) { // for example, not sure this method actually exists but you get the concept
// point is within the polygon, do tuff
return true; // break the some loop
}
}
});
});
我自己开发了一些同样基于 turf 的东西,我 运行 它在客户端(我的循环是用 .some
制作的,而不是经典的 for
循环,所以它甚至可以在性能方面走得更远)而且我从未经历过冻结。
从我的角度来看,5000 个点对于浏览器来说是花生,但是如果你的多边形真的很复杂(几十万个顶点),这可能会减慢当然是向下的过程。
Br,
文森特
如果 Stranded Kid 的回答对你来说太过分了,
geoJsonLayer.eachLayer(function(layer){
var within = turf.within(turf.featureCollection(turfPoints),turf.featureCollection([layer.toGeoJSON()]));
console.dir(within);
});
并确保您的坐标是浮点数而不是字符串,因为这就是导致我速度变慢的原因。
我有 5000 多个 LatLng 点,对于每个点,我想找出它们属于哪个特征(区域)。这些特征来自 a kmz layer by Philippe Ivaldi,转换为 GeoJSON。
目前,我正在双 for
循环中使用 turfjs 执行此操作。不出所料,计算会使浏览器冻结十分钟,这不是很方便。
这是我的代码:
function countCeaByLayer(geoJsonLayer){
jQuery.getJSON('http://localhost/server/retrieveData.php', function(data){
var turfPoints = [];
for(var i = 0; i < data.length; i++){
turfPoints.push(turf.point([data[i].longitudeWGS84, data[i].latitudeWGS84]));
}
var features = geoJsonLayer.toGeoJSON().features;
for(var i = 0; i < features.length; i++){
var turfPointsNew = [];
for(var j = 0; j < turfPoints.length; j++){
var isInside = turf.inside(turfPoints[j], features[i]);
if(!isInside) turfPointsNew.push(turfPoints[j]);
}
turfPoints = turfPointsNew;
}
console.log("done");
});
}
如何避免冻结浏览器?
- 让它异步?
- 在服务器上使用
node
和turfjs
进行计算? - 或在具有
node
和leaflet-headless
的服务器上部署leafletjs
?
...或者我应该处理它?
谢谢!
要优化您的代码,您应该这样做。
遍历点。
对于每个点,当您遍历多边形以了解该点是否在其中一个内部时,首先获取多边形 Bounds 并查看该点是否在边界内。 如果没有,您可以跳过下一步并转到下一个多边形。
如果它在边界内,请直接检查它是否在多边形本身内。
如果是这种情况,请中断在多边形上迭代的循环并切换到下一个点。
例如,可以是:
points.forEach(function(point) {
polygons.some(function(polygon) {
if (polygon.getBounds().contains(point)) { // or other method if you are not playing with Leaflet features
if (turf.isInside(polygon, point) { // for example, not sure this method actually exists but you get the concept
// point is within the polygon, do tuff
return true; // break the some loop
}
}
});
});
我自己开发了一些同样基于 turf 的东西,我 运行 它在客户端(我的循环是用 .some
制作的,而不是经典的 for
循环,所以它甚至可以在性能方面走得更远)而且我从未经历过冻结。
从我的角度来看,5000 个点对于浏览器来说是花生,但是如果你的多边形真的很复杂(几十万个顶点),这可能会减慢当然是向下的过程。
Br, 文森特
如果 Stranded Kid 的回答对你来说太过分了,
geoJsonLayer.eachLayer(function(layer){
var within = turf.within(turf.featureCollection(turfPoints),turf.featureCollection([layer.toGeoJSON()]));
console.dir(within);
});
并确保您的坐标是浮点数而不是字符串,因为这就是导致我速度变慢的原因。