Iceneo
Iceneo

Reputation: 61

TurfJs intersection issue

Hi i am trying to implement map objects (Street Zones) which will if intersect with other street zones, bend them around. I've implemented next logic: when the drawing of zone is finished, i am trying to find all intersections of it with other zones using intersection function from turfjs, then i am uniting all of the intersection with union and using difference with original object

getting Union intersection fn (truncated is used to compensate distance between boundaries)

    const format = new GeoJSON();
    const feaPoly = format.writeFeatureObject(feature) as GeoJSONPolygon;
    
    const intersections = featuresToGetIntersectionsWith
      .filter(existingFea =>
        existingFea.get('type') !== feature.get('type') ||
        existingFea.getId() !== feature.getId())
      .map((existingFea) => {
        const existingFeaturePoly = format.writeFeatureObject(existingFea) as GeoJSONPolygon;
        return intersect(feaPoly, existingFeaturePoly);
      })
      .filter(intersection => intersection);


    if (!intersections.length) { return null; }

    return intersections
      .reduce((prev, curr) => union(truncate(prev), truncate(curr)));
  } 

bendingFunction

        try {
      const format = new GeoJSON();
      const feaPoly = format.writeFeatureObject(feature) as GeoJSONPolygon;
      const unionIntersection = this.getUnionIntersection(feature, featuresToBend);
      if (!unionIntersection) { return; }
      const diff = difference(feaPoly, unionIntersection) as GeoJSONPolygon | GeoJSONMultiPolygon;

      if (!diff) { throw Error('Inner fea'); }
      if (diff.geometry.type === 'MultiPolygon' && !ignoreMultiPolygon) { throw Error('Many shapes'); }
      
      return { difference: diff, intersection: unionIntersection, bendedFeatures: featuresToBend };
        } catch (e) {
            this.handleBendError(objType, e);
            throw Error(e.message);
        }
    }

as you can see the only suitable case for difference result is polygon in my case. Everything works fine when creating first two street zones, the problems start to appear when the third is drawn

Coords of first polygon (blue on the screenshot)

[
    [
        9227079.586445518,
        7361106.72521227
    ],
    [
        9226950.666712714,
        7358240.1570358025
    ],
    [
        9229240.8878484,
        7358528.330556187
    ],
    [
        9227079.586445518,
        7361106.72521227
    ]
]

Coords of second polygon (purple on the screenshot)

[
    [
        9227891.022410812,
        7361228.061431374
    ],
    [
        9227789.82178895,
        7360259.4269078225
    ],
    [
        9229240.8878484,
        7358528.330556187
    ],
    [
        9229230.813561888,
        7358527.062930729
    ],
    [
        9229976.488676753,
        7358452.495419242
    ],
    [
        9227891.022410812,
        7361228.061431374
    ]
]

Coords of intersection of the first(blue) and new polygon (red)

[
    [
        9227440.736314,
        7359644.350225
    ],
    [
        9228159.754835,
        7359818.103274
    ],
    [
        9227491.252183,
        7360615.615209
    ],
    [
        9227440.736314,
        7359644.350225
    ]
]

Coords of intersection of the second (purple) and new polygon (red)

[
    [
        9227789.821789,
        7360259.426908
    ],
    [
        9228159.754835,
        7359818.103274
    ],
    [
        9228476.375107,
        7359894.615543
    ],
    [
        9227821.439394,
        7360562.052554
    ],
    [
        9227789.821789,
        7360259.426908
    ]
]

The result of union of truncated intersection geometries is multipolygon with both intersections presented in it. I need to have only one united polygon. Moreover, because of the truncate difference returns polygon with points left on boundaries of intersections

Red polygon is what i am drawing, salad part of it is what needs to stay after difference result enter image description here

Upvotes: 0

Views: 66

Answers (1)

James Beard
James Beard

Reputation: 340

Firstly, if you are using Turf you should convert your coordinates into longitude, latitude (-180 to 180, -90 to 90).

After that, if what you want is the green polygon - the part of the red polygon that isn't covered by any part of the blue or purple polygons - it can be done with Turf in a few steps.

Briefly, first get the union of the blue and purple polygons. Then get the difference between the red polygon and the union-ed polygon.

const bluePoly = turf.polygon([
  [
    [
      41.76534176121291,
      55.30020075177271
    ],
    [
      41.53667178476189,
      54.93371491220336
    ],
    [
      42.030982332657516,
      54.950231895745446
    ],
    [
      41.76534176121291,
      55.30020075177271
    ]
  ]
]);

const purplePoly = turf.polygon([
  [
    [
      42.23500146948683,
      54.926542661401385
    ],
    [
      41.99537724266625,
      55.33439338563056
    ],
    [
      41.84338701879824,
      54.97293854904663
    ],
    [
      42.23500146948683,
      54.926542661401385
    ]
  ]
]);

const redPoly = turf.polygon([
  [
    [
      41.87898833249693,
      55.25019065857009
    ],
    [
      41.79546217343503,
      55.0475312977143
    ],
    [
      42.056994900991924,
      55.0781134256396
    ],
    [
      41.87898833249693,
      55.25019065857009
    ]
  ]
]);

const blueAndPurplePoly = turf.union(turf.featureCollection([bluePoly, purplePoly]));
const greenPoly = turf.difference(turf.featureCollection([redPoly, blueAndPurplePoly]));

console.log(greenPoly);
<script src="https://cdn.jsdelivr.net/npm/@turf/[email protected]/turf.min.js"></script>

Four polygons

Upvotes: 0

Related Questions