-5

Upon checking a polygon object's validity using Objects.polygon.valid, it thrown a GEOS_NOTICE: Self-intersection error.

I know this can be fixed by using the ST_MakeValid method of PostGIS.
I'm using Django 1.11 with GEOS support and can't find its equivalent in Django docs.

Is there any equivalent function for ST_MakeValid in Django?

randomuser
  • 1,201
  • 2
  • 10
  • 19

1 Answers1

10

Django version >= 1.10:

Exists the database method: MakeValid

Django version < 1.10:

You can create a custom database function by extending GeoFunc class which by itself extends the Func() class:

from django.contrib.gis.db.models.functions import GeoFunc

class MakeValid(GeoFunc):
    function='ST_MakeValid'

The MakeValid(field_name) applies the ST_MakeValid to the field with field_name.


Usage:

YourModel.objects.get(id=an_id).update(the_geom=MakeValid('the_geom'))

The following is an equivalent query using F() expression to execute the update:

YourModel.objects.get(id=an_id)
                 .update(the_geom=GeoFunc(
                     F('the_geom'), 
                     function='ST_MakeValid'
                 ))

Note: the_geom represents your geometry field (point, polygon, etc.)

John Moutafis
  • 22,254
  • 11
  • 68
  • 112
  • One more doubt in using this function: when I do `new_polygon_obj = MakeValid()`, it doesn't return a new multi-polygon object. What am I missing? – randomuser Aug 11 '17 at 13:56
  • Are you actually writing as you shown here? If that is the case you are using it wrong and you should use it as I suggest in my answer @ajaysingh – John Moutafis Aug 11 '17 at 14:30
  • I can't do this `YourModel.objects.get(id=an_id).update(the_geom=MakeValid('the_geom'))` as I already have the object in my code. I just need to update the polygon object with something like `YourModel.polygon = MakeValid(YourModel.polygon)` and save it later. Why can't I do it? Thanks in advance. – randomuser Aug 14 '17 at 07:43
  • Because Django does not work that way @ajaysingh. Try this: `YourModel.objects.get(id=an_id).update(polygon=MakeValid('polygon'))` and you should be able to update your polygon with the valid one! Careful of the names!! – John Moutafis Aug 14 '17 at 08:34
  • Actually, I need to save/update my `YourModel` later. Can you please help me to extract geom object from `MakeValid(YourModel.polygon)` which I need? – randomuser Aug 14 '17 at 12:19
  • 2
    @ajaysingh I do believe that this is getting out of scope of this question. You can make a different question on SO on that matter. If my answer solved your initial problem, consider accepting it. – John Moutafis Aug 14 '17 at 12:21
  • 14
    @ajaysingh please don't ping people so they can help you on other questions like this. It's pretty bad form for Stack. – Patrice Aug 22 '17 at 16:32
  • 1
    @Patrice yes, I should have thoroughly checked documentation before posting. Will not repeat it. Thanks. – randomuser Aug 22 '17 at 19:20