Reputation: 61
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
Upvotes: 0
Views: 66
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>
Upvotes: 0