As stated in the linked post MakeValid
is a database function, which means that it can be executed only during querying the database.
It is 1-to-1 similar to the PostGIS
usage of ST_MakeValid
which cannot be executed outside of a table query (cannot exist autonomously).
When you create the np
object, and then you try to do:
np.polygon = MakeValid(np.polygon)
You are essentially trying to apply a database function to an instance of the ‘MyModel’ class which isn’t supposed to work! (as it does not)
What you can do:
-
You can create a query to update a specific table row:
np = MyModel.objects.filter(id=np.id).update(polygon=MakeValid('polygon'))
Note: The object with
id=np.id
‘s polygon, will be updated in the
database permanently with that method. -
You can utilize the
GEOSGeometry.buffer()
:Using
polygon.buffer(0)
can tidy up most of the polygon irregularities (it can even solve some types of “bowtie”/self-intersecting polygons)np.polygon.valid # False np.polygon.buffer(0) # Make valid with buffer(0) np.polygon.valid # True
-
Finally, you can use
Shapely
and create a shapely polygon for your calculations which you can make valid with the same method as above (both Shapely’sbuffer
and GeoDjango’sbuffer
useGEOS
library):from shapely.geometry import Polygon # Initialize the polygon object with one of the following ways: np_polygon = Polygon([np.polygon.coords]) # or np_polygon = Polygon(np.polygon.wkt) np_polygon.is_valid # False np_polygon = np_polygon.buffer(0) # Make valid with buffer(0) np_polygon.is_valid # True
7
solved MakeValid not working for a single model object