1

I have a polygon clipping function in my OpenLayers app which may return me a multipolygon.

Unfortunately, my app does not support multipolygons by design. So I need to convert a multipolygon to single polygons somehow.

The purpose of my function is to delete everything below a specific polygon the user can drag. I'm basically deleting the old version of the polygon and replace this with the result I get from the difference-function from the polygon-clipping library. "Punch-out" function is the better term, I think.

Some pictures to illustrate what I mean:

I have some overlapping polygons (black) and the red one is my "punch-out-tool". The result I want is on the right side (just moved them apart a bit). This works for most cases already.

enter image description here

But the user can move the red polygon everywhere he wants, so this can happen:

enter image description here

In this case, I will get a multipolygon, which is not supported in my application.

My idea is to cut this multipolygon in half, somehow like this:

enter image description here But this is not that easy to do for every case, because I could end up with multiple "holes" in my multipolygon, f. e. top left and bottom right...

My code so far: just for clarification, the first loop in my punch function is to prepare the coordinates for the polygon-clipping library. I'm not sure why, but I need to wrap my coordinates in another array.

The Difference function down below is where I may get my multipolygon. You can see that I just take the first one. The "singlePolygon" term is misleading here because it could be a Multipolygon.

function start(layers: MyLayer[], punchPolygon: Polygon): PunchOutValue[] {
    const punchOutValues: PunchOutValue[] = [];

        for (const layer of layers) {
            if (!layer.objects.items.length) {
                continue;
            }

            const value = punch(layer.objects.items, punchPolygon);

            punchOutValues.push({
                layer: layer,
                newObjects: value.newObjects,
                deleteThisObjects: value.deleteThisObjects,
            });
        }
    
    return punchOutValues;
}

function punch(
    existingObjects: Object[],
    punchPolygon: PolygonClippingMultiPolygon): ImportPunchOutValue {

    const modifiedObjects: ModifiedObject[] = [];
    const deleteThisObjects: Object[] = [];

    const existingObjectCollection: PolygonClippingMultiPolygon = [];

    for (const object of existingObjects) {
        const shape = object.shape;
        if (shape.type === ObjectType.POLYGON) {

            const multiPolygon = [shape.coordinates];
            existingObjectCollection.push(multiPolygon as []);
        }
    }

    //###################################################################################

    const intersectResult = PolygonClippingIntersection(existingObjectCollection, punchPolygon);

    if (intersectResult.length) {
        for (const object of existingObjects) {
            if (object.shape.type !== ObjectType.POLYGON) {
                continue;
            }
            const multiPolygon = [object.shape.coordinates];

            const objectInterSection = PolygonClippingIntersection(multiPolygon as [], punchPolygon);

            if (!objectInterSection.length) {
                continue;
            }

            const result = PolygonClippingDifference(multiPolygon as [], punchPolygon);

            for (const singlePolygon of result) {
                const modifiedObject: ModifiedObject = {
                    shape: {
                        type: ObjectType.POLYGON,
                        coordinates: singlePolygon[0],
                    },
                };
                modifiedObjects.push(modifiedObject);
            }
            deleteThisObjects.push(object);
        }
    }

    return {
        newObjects: modifiedObjects,
        deleteThisObjects: deleteThisObjects,
    };
}
8
  • 3
    The second case could be polygon with a hole, not a multipolygon. Would that be OK?
    – TomazicM
    Jul 9 '21 at 11:53
  • Code added... It would be better if I could get valid polygons without holes, but I think it's better than nothing. It just these holes can confuse the user because they don't know polygons with a hole, they can't draw them, and it could lead to errors in my area calculation function. But maybe I can build on your idea.
    – R. Kut
    Jul 9 '21 at 12:38
  • I would say that the main question is what would user want to achieve when cutting hole in the polygon. I really his/her idea to make two halves? I not, you could simply ignore such case or display warning this it's not allowed.
    – TomazicM
    Jul 9 '21 at 12:55
  • It's not like the user do this on purpose. Basically, he wants to clear this area out with a punch object of his choice. It just that there are a lot of existing polygons in different sizes, he would punch out.
    – R. Kut
    Jul 9 '21 at 13:01
  • 1
    This means you want to have a polygon with a hole. In this case you could use proposed solution of semitransparently coloring the background of it. If you really want to split it like you proposed to, you could use this solution for splitting: gis.stackexchange.com/questions/344068/…
    – TomazicM
    Jul 9 '21 at 14:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.