Как точно проверить, перекрывает ли один многоугольник другой, игнорируя границы - PullRequest
0 голосов
/ 24 сентября 2019

У меня есть один вопрос, касающийся топологии и отношений между полигонами в открытых слоях.

Ситуация такова: enter image description here

Использование https://turfjs.org/ I 'Я использую два метода, чтобы проверить, перекрываются ли многоугольники, https://turfjs.org/docs/#booleanOverlap и https://turfjs.org/docs/#booleanWithin, но я получаю какое-то странное взаимодействие.

Как видите, в синем прямоугольнике многоугольник привязан к красному многоугольнику, и это нормально, но проблема в том, что для них многоугольники в желтом прямоугольнике, я получаю true и автоматически перекрывающийся красный стиль .Многоугольники в синем и многоугольники в желтом прямоугольнике привязываются только к границе красного многоугольника.

Итак, мой вопрос таков;Можно ли как-то игнорировать границу ограничительного многоугольника (красный) или я должен найти другой подход.

Пример кода, который я проверяю, перекрывают ли многоугольники:

 vectorLayer.getSource().on(OpenLayersEvents.AddFeature, (evt: any) => {


            let feature = evt.feature;


            // clip area function with return geometry value
            let polygon = clipFieldArea(feature, this.myRestrictionVectorLayer);


            let isFeatureOverlappingFlag = false;
            //red polygons
            if (this.restrictiveLayer.getSource().getFeatures().length > 0) {
                isFeatureOverlappingFlag = arePolygonsOverlapping(feature, this.restrictiveLayer); 
            }

            // checks if features are overlapping then set new style
            feature.getGeometry().setCoordinates(polygon.getCoordinates());
            if (isFeatureOverlappingFlag) {
                feature.setStyle(this.featureOverlappingStyle);
            } else {
                feature.setStyle(this.fieldStyle);
            }....

И здесьis arePolygonsOverlapping () метод, который проверяет топологию

   let geojsonFormat = new GeoJSON();

    let areOverlapping: boolean = false;

    let flagCheck: boolean = false;
    let restrictionFeatures = restrictionLayer.getSource().getFeatures();

    // create GeoJSON object and transform it in WGS84 for intersect method
    let firstGeometryObject = geojsonFormat.writeFeatureObject(feature, { dataProjection: 'EPSG:4326', featureProjection: 'EPSG:3857' });

    for (let featureRestrict of restrictionFeatures) {

        let secondGeometryObject = geojsonFormat.writeFeatureObject(featureRestrict,
            { dataProjection: 'EPSG:4326', featureProjection: 'EPSG:3857' });

        areOverlapping = booleanOverlap(firstGeometryObject as unknown as TurfPolygon, secondGeometryObject as unknown as TurfPolygon);

        if (areOverlapping) {
            flagCheck = true;
            break;
        }
    }
    return flagCheck;

1 Ответ

1 голос
/ 25 сентября 2019

Я протестировал booleanOverlap и, хотя, похоже, он работает с числами из любой проекции, для соответствия спецификации газона было бы целесообразно придерживаться небольших чисел, уменьшая координаты EPSG: 3857 без преобразования впроекция, которая меняет формы многоугольника.Преобразования масштабирования также могут быть проще, чем ссылки в комментариях.

import { getWidth } from 'ol/extent';
import { Projection, addCoordinateTransforms, addProjection, get as getProjection } from 'ol/proj';

....
....


let viewProjection = getProjection('EPSG:3857');
let smallProjection = getProjection('small');

if (!smallProjection) {

    smallProjection = new Projection({
        code: 'small',
        units: 'm'
    });
    addProjection(smallProjection);

    let scale = getWidth(viewProjection.getExtent());

    let smallTransform = function(coordinate) {
        return [coordinate[0] / scale, coordinate[1] / scale];
    }

    let normalTransform = function(coordinate) {
        return [coordinate[0] * scale, coordinate[1] * scale];
    }

    addCoordinateTransforms(viewProjection, smallProjection, smallTransform, normalTransform);

}

let geojsonFormat = new GeoJSON();

let areOverlapping: boolean = false;

let flagCheck: boolean = false;
let restrictionFeatures = restrictionLayer.getSource().getFeatures();

// create GeoJSON object and transform it in WGS84 for intersect method
let firstGeometryObject = geojsonFormat.writeFeatureObject(feature, { dataProjection: smallProjection, featureProjection: viewProjection });

for (let featureRestrict of restrictionFeatures) {

    let secondGeometryObject = geojsonFormat.writeFeatureObject(featureRestrict,
        { dataProjection: smallProjection, featureProjection: viewProjection });

    areOverlapping = booleanOverlap(firstGeometryObject as unknown as TurfPolygon, secondGeometryObject as unknown as TurfPolygon);

    if (areOverlapping) {
        flagCheck = true;
        break;
    }
}
return flagCheck;
...