#geospatial #geojson #geo #turfjs
#геопространственный #geojson #гео #turfjs
Вопрос:
Это на стороне интерфейса. Я использую turf.js .
Сценарий: Получать все предупреждения и инциденты в пределах 10 км от моего текущего местоположения.
Я получаю прямую трансляцию geojson, которая содержит предупреждения или инциденты с множеством функций, некоторые из которых имеют свои geometry.type='Point' || geometry.type='MultiPolygon' || geometry.type='GeometryCollection'
.
Что я сделал до сих пор:
Создайте область объектов буфера с моими текущими координатами и сравните, произошел ли инцидент рядом со мной (в 10 км).
Если geometry.type=’Point’, я сравниваю, используя turf.inside (point, bufferPolygon), и это работает нормально.
Проблема заключается в том, что это не точка, скажем, мультиполигон или GeometryCollection, в котором есть мультиполигоны.
Единственный другой метод, который я могу использовать для поиска, который принимает polygon в обоих параметрах, — это turf.intersect(polygon, bufferPolygon)
.
Здесь я не получаю geometry.type ='Polygon'
в свой канал, но это MultiPolygon
или GeometryCollection
(имеющий мультиполигоны).
if(feature.geometry.type === 'Point') {
if(turf.inside(feature, bufferPolygon)) {
console.log("inside");
feature.properties.feedType === 'warning' ? warningsNearBy : incidentsNearBy ;
}
} else {
if(feature.geometry.type === 'GeometryCollection') {
$.each(feature.geometry.geometries, function(index, geo) {
if(geo.type === 'MultiPolygon') {
//console.log('MP:', geo.coordinates[0]);
var convertToPolygon = turf.polygon(geo.coordinates[0]);
console.log('convertToPolygon:',convertToPolygon);
//console.log('MP:intersect',turf.intersect(polygon, bufferPolygon));
var isIntersecting = turf.intersect(convertToPolygon, bufferPolygon);
if(isIntersecting) {
feature.properties.feedType === 'warning' ? warningsNearBy : incidentsNearBy ;
}
} else if(geo.type === 'GeometryCollection') {
console.log('GC:', geo);
}
});
} else {
console.log('not geo collection:', feature.geometry.type);
}
}
Кроме того, пытался преобразовать MultiPolygon в полигон, не сработало так хорошо.
Может ли кто-нибудь, пожалуйста, предложить способ сравнения bufferFeature с набором объектов, содержащих point, multipolygon и GeometryCollection?
Ответ №1:
Одна вещь, которую вы могли бы сделать, если вы не возражаете против сравнения буфера с несколькими точками, — это использовать turf.explode()
для полигонов / мультиполигонов. Вот ссылка на документацию.
http://turfjs.org/examples/turf-explode/
Turf explode превратит полигоны или мультиполигоны в набор пространственных объектов, представляющих вершины фигуры. После того, как вы выполнили turf.explode()
работу с полигонами / мультиполигонами, вам нужно будет выполнить итерацию по каждому объекту (точке) в результатах и сравнить его с буфером, используемым turf.inside()
. Вероятно, было бы проще использовать turf.within()
для этой части, но вы можете использовать turf.inside()
вместо этого, если хотите.
Это работает, потому что если одна из точек находится внутри буфера, то по крайней мере некоторая часть многоугольника, которую представляют точки, также находилась бы в области буфера.
Другим способом добиться этого было бы использовать точку вместо буфера для сравнения расстояний. Тогда, если бы у вас была точка, вы могли бы просто использовать turf.distance()
с двумя точками, чтобы увидеть расстояние между ними. Если бы у вас были полигоны / мультиполигоны, вы могли бы turf.explode()
их и сравнить расстояния с вашей исходной точкой.
Что касается коллекций геометрии, я не думаю, что вы сможете работать с коллекциями, использующими turf, если не разделите разные части коллекции геометрии на отдельные коллекции объектов по типу.
Ответ №2:
Кроме того, пытался преобразовать MultiPolygon в полигон, не сработало так хорошо.
Почему это не сработало? Не могли бы вы объяснить это подробнее?
Мультиполигон или полигон — это не что иное, как набор точек. Вы должны иметь возможность преобразовать его в массив точек или массив, содержащий объекты точек.
Вы могли бы сделать это примерно так:
function unpackMultiPolCoords(features) {
var data = [];
featureEach(features, function(feature) {
var coordCollection = feature.geometry.coordinates;
coordCollection.forEach(function(coords) {
coords.forEach(function(coord) {
data.push(coord);
});
});
});
return data;
};
var unpacked = unpackMultiPolCoords(multiPoly);
let toPoints = function(fc) {
let points = [];
fc.forEach((coord) => {
points.push(turf.point(coord));
});
return points;
};
var points = toPoints(unpacked);
Смотрите полный код @ http://codepen.io/bitHugger/pen/mOxwME
Затем вы могли бы сравнить каждую точку с функцией расстояния от turfs до вашего буфера.