Openlayers 如何在忽略边界的情况下精确检查一个多边形是否与另一个多边形重叠

Openlayers 如何在忽略边界的情况下精确检查一个多边形是否与另一个多边形重叠,openlayers,openlayers-3,openlayers-5,topology,turfjs,Openlayers,Openlayers 3,Openlayers 5,Topology,Turfjs,我有一个关于openlayers中多边形之间的拓扑和关系的问题 情况是: 我用两种方法来检查多边形是否重叠,但我得到了一些奇怪的交互作用 如您所见,在蓝色矩形中,多边形被捕捉到红色多边形,这是一个很好的行为,但问题是黄色矩形中的多边形对于它们,我得到了真实的效果,并自动重叠红色样式。蓝色矩形中的多边形和黄色矩形中的多边形仅捕捉到红色多边形的边界 所以我的问题是,;是否有可能忽略限制性多边形(红色)的边界,或者我是否应该找到另一种方法 我正在检查多边形是否重叠的代码示例: vectorLaye

我有一个关于openlayers中多边形之间的拓扑和关系的问题

情况是:

我用两种方法来检查多边形是否重叠,但我得到了一些奇怪的交互作用

如您所见,在蓝色矩形中,多边形被捕捉到红色多边形,这是一个很好的行为,但问题是黄色矩形中的多边形对于它们,我得到了真实的效果,并自动重叠红色样式。蓝色矩形中的多边形和黄色矩形中的多边形仅捕捉到红色多边形的边界

所以我的问题是,;是否有可能忽略限制性多边形(红色)的边界,或者我是否应该找到另一种方法

我正在检查多边形是否重叠的代码示例:

 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);
            }....
下面是检查拓扑的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;
更新

我尝试使用Mike提出的解决方案,但我得到了
未捕获的类型错误:ol\u proj\uu WEBPACK\u IMPORTED\u MODULE\u 3\uuuu。default.Projection不是构造函数

尝试创建新投影时。 这里是更新的方法

export function arePolygonsOverlapping(feature: any, restrictionLayer: VectorLayer): boolean {

    let areOverlapping: boolean = false;

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

    //#region "Parameters for scaling down coordinates"
        let viewProjection = Projection.get('EPSG:3857');
        let smallProjection = Projection.get('small');

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

        Projection.addProjection(smallProjection);

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

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

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

        Projection.addCoordinateTransforms(viewProjection, smallProjection, smallTransform as any, normalTransform as any);

    }
    //#endregion "Parameters for scaling down coordinates"


    // 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;
}
以下是我的作品:

import Extent from 'ol/extent';
import Projection from 'ol/proj';

我忘了说我用的是V4.6.2,我已经测试过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;

好吧,我在这件事上采取了不同的态度。而不是“固定”和调整坐标(尽管如此,迈克的回答很好地指出我们应该缩小坐标)

我只是使用了草皮相交的方法,并用附加的面积检查来检查是否有任何相交的特征

这种方法涵盖了我尝试过的大多数案例

let isIntersecting: 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' }) as unknown as TurfPolygon;

for (let featureRestrict of restrictionFeatures) {

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

    // get intersected polgon
    let intersectPolygon = intersect(firstGeometryObject, secondGeometryObject);

    if (intersectPolygon != null) {
        isIntersecting = true;

        // calculate value of intersected area
        let areaValue: number = area(intersectPolygon as unknown as AllGeoJSON);

        // area below 10 meters is considered overlapping
        if (areaValue < 10) {
            isIntersecting = false;
        }
    }

    if (isIntersecting) {
        flagCheck = true;
        break;
    }
}
return flagCheck;
let isIntersecting:boolean=false;
让flagCheck:布尔值=false;
让restrictionFeatures=restrictionLayer.getSource().getFeatures();
//创建GeoJSON对象并在WGS84中为intersect方法进行转换
让firstGeometryObject=geojsonFormat.writeFeatureObject(feature,{dataProjection:'EPSG:4326',featureProjection:'EPSG:3857'})与多边形一样未知;
对于(让限制特性的特性限制){
让secondGeometryObject=geojsonFormat.writeFeatureObject(featureRestrict,
{dataProjection:'EPSG:4326',featureProjection:'EPSG:3857'})与purpolygon一样未知;
//交叉波尔贡
让intersectPolygon=相交(第一个几何体对象,第二个几何体对象);
if(相交多边形!=null){
isIntersecting=true;
//计算相交面积的值
let areaValue:number=面积(与AllGeoJSON一样未知);
//10米以下的区域视为重叠区域
如果(面积值<10){
isIntersecting=假;
}
}
如果(isIntersecting){
flagCheck=true;
打破
}
}
返旗检查;

是否需要更改writeFeatureObject中的投影?一个投影中的重叠部分可能不在另一个投影中。-见@Mike嗨,Mike,谢谢你的回答。我认为我必须这样做,因为Turf库希望数据是标准的WGS84经纬度坐标。这当然是一些Turf函数的问题(特别是当它们使用公差时),而其他函数仅使用提供的数字。如有必要,您可以定义一个虚拟投影,该投影将EPSG:3857坐标减少到足够小的值,以便turf将其视为WGS84,而不会影响形状,就像重新投影一样-请参见@Mike Thanke you。我还考虑了另一种方法,比如说使用JST或以某种方式检测边界是否正确overlapping@MikeMike,用一些代码示例将您的评论输入到答案中以接受它Mike,谢谢您的努力,但我在尝试创建新投影时遇到了错误