检查 coordinates/places openlayers 中的多边形内部
Check coordinates/places inside polygons in openlayers
我有一些代码可以检查多边形内部的位置或坐标。问题是它可能有 10000 个或更多的地方,这会导致性能问题并且地图变慢。请在下面找到我的代码:
places.forEach(p => {
this.isInsidePolygons(p.latitude, p.longitude)
})
isInsidePolygons(latitude: number, longitude: number): boolean {
let isInsidePolygon = false;
var coordinate = OlHelper.transformToEPSG3857([Number(longitude), Number(latitude)]);
var shapes = this.getShapes();
for (let i = 0; i < shapes.length; i++) {
let features = shapes[i].getSource().getFeatures();
if (!features || features.length == 0) continue;
for (let j = 0; j < features.length; j++) {
var geometry = features[j].getGeometry();
isInsidePolygon = geometry.intersectsCoordinate(coordinate);
if (isInsidePolygon) break;
}
if (isInsidePolygon) break;
}
return isInsidePolygon;
}
getShapes(): ol.layer.Vector[] {
var shapes = [];
this.MapControl.getLayers().forEach((layer) => {
if (layer instanceof ol.layer.Vector) shapes.push(layer);
});
return shapes;
}
是否可以一次检查 openlayers 中的所有位置都在多边形内,而不是对每个位置进行循环?
let features = shapes[i].getSource().getFeatures();
if (!features || features.length == 0) continue;
for (let j = 0; j < features.length; j++) {
var geometry = features[j].getGeometry();
isInsidePolygon = geometry.intersectsCoordinate(coordinate);
if (isInsidePolygon) break;
}
可以替换为
isInsidePolygon = (shapes[i].getSource().getFeaturesAtCoordinate(coordinate).length > 0);
代码更少,但效率可能不会更高
要针对更多地点测试形状,您需要为您的地点创建矢量源。使用形状的范围来获取地点的候选名单,并且仅针对形状几何体
测试这些地点
let placesFeatures = [];
places.forEach((p) => {
placesFeatures.push(new Feature({
geometry: new Point(fromLonLat[p.longitude, p.latitude]))
id: [p.latitude, p.longitude].toString,
isInsidePolygon: false
}))
})
let placesSource = new VectorSource({features: placesFeatures});
for (let i = 0; i < shapes.length; i++) {
let features = shapes[i].getSource().getFeatures();
if (!features || features.length == 0) continue;
for (let j = 0; j < features.length; j++) {
var geometry = features[j].getGeometry();
let extent = features[j].getGeometry().getExtent();
let candidates = placesSource.getFeaturesInExtent(geometry.getExtent());
if (!candidates || candidates.length == 0) continue;
for (let k = 0; k < candidates.length; k++) {
isInsidePolygon = geometry.intersectsCoordinate(candidates[k].getGeometry().getCoordinates());
if (isInsidePolygon) {
candidates[k].set('isInsidePolygon', true);
}
})
}
}
然后您可以从源中的地点特征中获取结果
isInsidePolygons(latitude: number, longitude: number): boolean {
return placesSource.getFeatureById([latitude, longitude].toString()).get('isInsidePolygon');
}
您可以使用 turf.js, specifically the function pointsWithinPolygon。
从一个 multi-polygon 或一个多边形和一个点列表开始,函数它 returns 多边形内的所有点,但复杂度与点数成线性关系。
如果我们使用 turf.js 你必须转换 GeoJSON 中的特征。
let format = new ol.format.GeoJSON();
let pointsInsidePolygon = turf.pointsWithinPolygon(
format.writeFeatureObject(points),
format.writeFeatureObject(polygon)
);
然后阅读 GeoJson 功能
let features = format.readFeatures(pointsInsidePolygon);
但是如果你现在只想在多边形内部或外部有一些点,但不知道你可以玩哪一个多边形的范围
我有一些代码可以检查多边形内部的位置或坐标。问题是它可能有 10000 个或更多的地方,这会导致性能问题并且地图变慢。请在下面找到我的代码:
places.forEach(p => {
this.isInsidePolygons(p.latitude, p.longitude)
})
isInsidePolygons(latitude: number, longitude: number): boolean {
let isInsidePolygon = false;
var coordinate = OlHelper.transformToEPSG3857([Number(longitude), Number(latitude)]);
var shapes = this.getShapes();
for (let i = 0; i < shapes.length; i++) {
let features = shapes[i].getSource().getFeatures();
if (!features || features.length == 0) continue;
for (let j = 0; j < features.length; j++) {
var geometry = features[j].getGeometry();
isInsidePolygon = geometry.intersectsCoordinate(coordinate);
if (isInsidePolygon) break;
}
if (isInsidePolygon) break;
}
return isInsidePolygon;
}
getShapes(): ol.layer.Vector[] {
var shapes = [];
this.MapControl.getLayers().forEach((layer) => {
if (layer instanceof ol.layer.Vector) shapes.push(layer);
});
return shapes;
}
是否可以一次检查 openlayers 中的所有位置都在多边形内,而不是对每个位置进行循环?
let features = shapes[i].getSource().getFeatures();
if (!features || features.length == 0) continue;
for (let j = 0; j < features.length; j++) {
var geometry = features[j].getGeometry();
isInsidePolygon = geometry.intersectsCoordinate(coordinate);
if (isInsidePolygon) break;
}
可以替换为
isInsidePolygon = (shapes[i].getSource().getFeaturesAtCoordinate(coordinate).length > 0);
代码更少,但效率可能不会更高
要针对更多地点测试形状,您需要为您的地点创建矢量源。使用形状的范围来获取地点的候选名单,并且仅针对形状几何体
测试这些地点 let placesFeatures = [];
places.forEach((p) => {
placesFeatures.push(new Feature({
geometry: new Point(fromLonLat[p.longitude, p.latitude]))
id: [p.latitude, p.longitude].toString,
isInsidePolygon: false
}))
})
let placesSource = new VectorSource({features: placesFeatures});
for (let i = 0; i < shapes.length; i++) {
let features = shapes[i].getSource().getFeatures();
if (!features || features.length == 0) continue;
for (let j = 0; j < features.length; j++) {
var geometry = features[j].getGeometry();
let extent = features[j].getGeometry().getExtent();
let candidates = placesSource.getFeaturesInExtent(geometry.getExtent());
if (!candidates || candidates.length == 0) continue;
for (let k = 0; k < candidates.length; k++) {
isInsidePolygon = geometry.intersectsCoordinate(candidates[k].getGeometry().getCoordinates());
if (isInsidePolygon) {
candidates[k].set('isInsidePolygon', true);
}
})
}
}
然后您可以从源中的地点特征中获取结果
isInsidePolygons(latitude: number, longitude: number): boolean {
return placesSource.getFeatureById([latitude, longitude].toString()).get('isInsidePolygon');
}
您可以使用 turf.js, specifically the function pointsWithinPolygon。 从一个 multi-polygon 或一个多边形和一个点列表开始,函数它 returns 多边形内的所有点,但复杂度与点数成线性关系。 如果我们使用 turf.js 你必须转换 GeoJSON 中的特征。
let format = new ol.format.GeoJSON();
let pointsInsidePolygon = turf.pointsWithinPolygon(
format.writeFeatureObject(points),
format.writeFeatureObject(polygon)
);
然后阅读 GeoJson 功能
let features = format.readFeatures(pointsInsidePolygon);
但是如果你现在只想在多边形内部或外部有一些点,但不知道你可以玩哪一个多边形的范围