MakeValid 不适用于单个模型对象

MakeValid not working for a single model object

我正在尝试使用 MakeValid 修复(验证)我的几何字段。
我可以通过单行获取和更新来使其工作:

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

MyModel.objects.filter(id=<id>).update(polygon=MakeValid('polygon'))

但在某些情况下,我必须更新已在函数中实例化的单个模型对象的 polygon(这意味着我已经完成 .filter/.get),这给了我以下错误:

// np is an object of MyModel which has a field 'polygon' which is `MultiPolygon` django model field
np.polygon = MakeValid(np.polygon)
// np.save()
TypeError: Cannot set MyModel SpatialProxy (MULTIPOLYGON) with value of type: <class 'django.contrib.gis.db.models.functions.MakeValid'>

在这里,MakeValid(np.polygon) 没有 return 一个 MultiPolygon 对象。相反,它 return 是一个 django.contrib.gis.db.models.functions.MakeValid 包装器。

我可以从 MakeValid 获取 Geometry 对象吗?

As MakeValid is a database function,表示只能在查询数据库时执行。

它与ST_MakeValidPostGIS用法是一对一的,不能在table查询之外执行(不能独立存在)。

当您创建 np 对象时,然后您尝试做:

np.polygon = MakeValid(np.polygon)

您实质上是在尝试将数据库函数应用到 'MyModel' class 的实例,这不应该起作用! (因为它没有)


你能做什么:

  1. 您可以创建一个查询来更新特定的 table 行:

    np = MyModel.objects.filter(id=np.id).update(polygon=MakeValid('polygon'))
    

    注意:具有id=np.id多边形的对象,将在 使用该方法永久保存数据库。

  2. 您可以利用 GEOSGeometry.buffer():

    使用polygon.buffer(0)可以整理大部分多边形的不规则(甚至可以解决某些类型的"bowtie"/自相交多边形)

    np.polygon.valid          # False
    np.polygon.buffer(0)      # Make valid with buffer(0)
    np.polygon.valid          # True
    
  3. 终于可以使用Shapely and create a shapely polygon for your calculations which you can make valid with the same method as above (both Shapely's buffer and GeoDjango's buffer使用GEOS库了):

    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