3

I have used 2 geojson object for polygon. It's too large that I can't post it here. Now I am using TurfJs to make the union of this polygon geojson and plotting it on the map. But it's not working properly.

I think little bit points in the middle of it is a little bit different. So is there any way to ignore this points in the middle in turfjs union?

See images bellow for better understanding.

Polygon 1 : enter image description here

Polygon 2 :

enter image description here

Now merged polygon for bellow code:

polygons = {
          "type": "FeatureCollection",
          "features": [poly1, poly2]
        };

enter image description here

Now main UNION result:

union = turf.union(poly1,poly2);

enter image description here

So in this, i want to ignore points that are in middle of boundary I know that, there may be points that are not accurate on intersection boundary of both polygon but can I ignore points that are nearer or having little bit of differencr to ignore middle points?

Or is there is any alternative to do union of polygon that ignore few nearer distraction of point and remove middle points?

Mayur Patel
  • 1,741
  • 15
  • 32

3 Answers3

2

You can try running the resulting polygon through turf.buffer(result, 0, 'kilometers') (turf-buffer docs). If your result is invalid geojson then using a buffer of 0 should cleanse the geometry (remove the points/lines in the middle).

It is hard to say what will work for sure without seeing the actual GeoJSON of the result. Is there any way you can upload it to pastebin or something?

Update - Turf buffer did not work in this case. The only solution that I could get to work was doing this on the result of turf.union(p1, p2).

result.geometry.coordinates = [result.geometry.coordinates[0]]

You want to be careful with this solution as it removes everthing from the polygon other than the external ring.

To understand why/how this works, you will want to make sure you understand how the coordinates for geojson polygons work. From the geojson.org geojson polygon specification

For type "Polygon", the "coordinates" member must be an array of LinearRing coordinate arrays. For Polygons with multiple rings, the first must be the external ring and any others must be internal rings or holes.

The external ring is essentially the outline of your polygon. Any internal rings are usually represented as holes. In your case, the internal rings were actually lines.

When looking at the coordinates for a geojson polygon, you will notice that all coordinates are contained within an outer array. Here is an example of a geojson polygon with only a single (external) ring.

{"type": "Feature", "properties": {}, "geometry": {"type": "Polygon", "coordinates": **[ [ [1, 1], [1, 2], [1, 3], [1, 1] ] ]**

Notice that the first coordinate and last coordinate of a ringe must always be the same. That ensure that we get a closed shape (ie: polygon).

Now here is an example with an external ring, and an internal ring

{"type": "Feature", "properties": {}, "geometry": {"type": "Polygon", "coordinates": **[ [ [1, 1], [1, 2], [1, 3], [1, 1] ], [ [1, 2], [1, 3], [1, 1] ] ]**

Now if we apply the suggested solution to the above example, we would get the same coordinates as the first example because we are grabbing only the first set of coordinates from the polygon, which will always be the external ring. Any subsequent elements in the coordinates array will represent internal rings (which is what the lines were, even though they are technically not valid internal rings).

{"type": "Feature", "properties": {}, "geometry": {"type": "Polygon", "coordinates": **[ [ [1, 1], [1, 2], [1, 3], [1, 1] ] ]**

As you can see, we are removing all internal rings from the polygon. That is the reason that you must be careful with how you use this. If you ever have valid internal rings, it will actually get rid of those.

I think that the reason this happens is because your polygons (p1 and p2) share a border.

Dylan Hamilton
  • 662
  • 4
  • 14
  • Thanks i will try this. – Mayur Patel Mar 02 '17 at 13:00
  • When I use 0.01 my result JSON size is increasing in larger number? Why is it? And what exactly this turf.buffer do? – Mayur Patel Mar 02 '17 at 13:53
  • Turf buffer can be used for a lot of things. To oversimplify it, you could say it is used to expand or make things bigger. Using 0 can also sometimes be used to cleanse geometries, but that did not work in the case of your data. Can you also upload the two original polygons to pastebin? – Dylan Hamilton Mar 02 '17 at 14:00
  • Here is [Poly1](http://pastebin.com/7xFDZxm8) and [Poly2](http://pastebin.com/WaecNu3S) – Mayur Patel Mar 02 '17 at 14:11
  • Alright, so this isn't probably the best way since it could have undesired effects if you aren't careful but here is something that works. Once you do turf.merge, you need to do this on the result. `result.geometry.coordinates = [result.geometry.coordinates[0]]` – Dylan Hamilton Mar 02 '17 at 14:31
  • Means after turf.buffer(result, 0, 'kilometers'). Can you make the edit in your answer. Do i need to make first turf.buffer(result, 0, 'kilometers') and then result.geometry.coordinates = [result.geometry.coordinates[0]] – Mayur Patel Mar 02 '17 at 14:38
  • I went ahead and updated the answer. You do not need to use turf.buffer. I thought it might work, but it did not in this case. – Dylan Hamilton Mar 02 '17 at 14:41
  • Wow, this did trick. But if I use turf.buffer(result, 0.007, 'kilometers') also map is showing proper but JSON size is increasing. Can you tell me which is better and What exactly updated answer do? – Mayur Patel Mar 02 '17 at 14:47
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/137070/discussion-between-dylan-hamilton-and-mayur-patel). – Dylan Hamilton Mar 02 '17 at 15:30
0

Faced the same problem: After trying to buffer a small positive amount and the same negative amount, the lines disappears. But this made the polygon having more points than the original so I did this workaround:

inner = [YOUR FEATURE COLLECTION]
var areas = []
for (var i = 0; i < inner.geometry.coordinates.length; i++) {
    let item = inner.geometry.coordinates[i]
    if (item.length > 10) areas.push(item)
}
inner = turf.polygon(areas)

As you can see I am removing the "non complex" polygons (assuming that a polygon with less than 10 points is not a real area)

0

This happens because the coordinates of both polygons are not 100% the same, creating a small gap when merging them together.

When faced with this problem, I had to use turf's distance method to check every vertex of the polygons, and if there was a small difference between them, I'd make them the same.

The implementation method may vary on the map library you are using, but it should go something like this:

layers.forEach(layer => {
    layers.forEach(innerLayer => {
        if (layer === innerLayer) return;
    
        // Here you would check if the vertexes are close to each other, using distance.

        // If the vertexes are close, you would make them equal and update the layer.
    })
})

Only after making the vertex of the polygons the same, you would merge them with the union method.

Since the implementation is pretty unique and depends on the project, I won't waste both our time with actual code, but I believe that with the insights above, you should be good to go.

Arthur Serafim
  • 393
  • 2
  • 7
  • Hey, still not sure how to do the distance from two polygon and make it equal. Can you post your code (even if is not the same that I need it)? – Rodrigo Gauzmanf Oct 13 '22 at 15:50
  • I haven't touched maps for like, 2 years, but you should just do a regular value change. layer.coordinate = innerLayer.coordinate or something – Arthur Serafim Oct 14 '22 at 17:40