1

I am trying to insert a polygon into a MongoDB DBMS. The polygon is self intersecting in one point. The polygon is the following:

{
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [{"type": "Feature",
"geometry": {"type": "Polygon", "coordinates": [[
[ -42.03130138154889, -22.89385998377782 ], 
[ -42.03130138154889, -22.89385528258293 ], 
[ -42.03129903095147, -22.89385528258293 ], 
[ -42.031296680354, -22.89385058138791 ], 
[ -42.03129197915909, -22.89384117899809 ], 
[ -42.031296680354, -22.89384588019297 ], 
[ -42.031296680354, -22.89384588019298 ], // Duplicated
[ -42.031296680354, -22.89384588019298 ], // Duplicated
[ -42.03130138154889, -22.89385058138791 ], 
[ -42.0313154851337, -22.89386468497268 ], 
[ -42.03131078393879, -22.89386311790775 ], 
[ -42.03131078393879, -22.89385998377782 ], 
[ -42.0313060827439, -22.89385998377782 ], 
[ -42.03130138154889, -22.89385998377782 ]
]]}}] }

The error I get is:

Loop is not valid: [ 
[ -42.03130138154889, -22.89385998377782 ], 
[ -42.03130138154889, -22.89385528258293 ], 
[ -42.03129903095147, -22.89385528258293 ], 
[ -42.031296680354, -22.89385058138791 ], 
[ -42.03129197915909, -22.89384117899809 ], 
[ -42.031296680354, -22.89384588019297 ], 
[ -42.031296680354, -22.89384588019298 ], 
[ -42.031296680354, -22.89384588019298 ], 
[ -42.03130138154889, -22.89385058138791 ], 
[ -42.0313154851337, -22.89386468497268 ], 
[ -42.03131078393879, -22.89386311790775 ], 
[ -42.03131078393879, -22.89385998377782 ], 
[ -42.0313060827439, -22.89385998377782 ], 
[ -42.03130138154889, -22.89385998377782 ] ] 
Edges 8 and 10 cross. Edge locations in degrees: 
[-42.0313014, -22.8938506]-[-42.0313155, -22.8938647] 
and [-42.0313108, -22.8938631]-[-42.0313108, -22.8938600]', 
details={ 
    }}]. ","path":"/bla"}

So I removed the duplicated points, but closed the loop like this:

import json
from collections import OrderedDict

def remove_duplicated_vertices(feature):
    coords_list = feature["geometry"]["coordinates"]
    coords_tuples = map(tuple, coords_list[0]) # Transform into tuples, they are serializable
    processed_coords = OrderedDict.fromkeys(coords_tuples) # Remove duplicated points
    new_list = list(map(list,processed_coords)) # Transform back into lists
    new_list.append(new_list[0]) # Close the loop
    coords_list[0] = new_list
    return feature

But I get the same error as before. How can I insert this geometry into MongoDB?

Vitaly Olegovitch
  • 3,509
  • 6
  • 33
  • 49
  • 1
    A polygon must not have intersecting edges. Did you draw it in a GIS tool to verify that it doesn't have any? – Thomas Sep 14 '21 at 13:12
  • @Thomas They intersect in a point when I visualize them in QGIS, but I have to be able to programmatically detect polygons like that. I have used several libraries to try to detect intersecting edges, including PyGEOS and bentley_ottmann, but they return that the polygon is not self intersecting. – Vitaly Olegovitch Sep 14 '21 at 13:17
  • 1
    Your polygon is very small, I would say less than one meter. When you round the coordinates to 7 digits after the dot (which gives a precision of around 10 centimeter) then the common libraries detect an self-intersection. Maybe "*somewhere*" your numbers are converted to `single` data type. – Wernfried Domscheit Sep 14 '21 at 14:19

1 Answers1

0

Some geometries can be fixed with PyGEOS. A multipart polygon can emerge as the result of the correction of the geometry.

An example:

import pygeos
pygeos_geometry = pygeos.Geometry("POLYGON((0 0, 1 1, 1 2, 1 1, 0 0))")
result = pygeos.make_valid(pygeos_geometry)
parts = pygeos.get_parts(result)
for part in parts:
  print(part)
Vitaly Olegovitch
  • 3,509
  • 6
  • 33
  • 49