我将从Trimble导入一些OSM数据到PostGIS数据库中,以将其作为Django应用程序的一部分进行处理.这对于点和线效果很好,但是我在多边形上挣扎.
导入工作正常:
shp2pgsql -d -I aeroway_polygon_polygon.shp aeroway_polygon | psql
Django InspectDB以一种明智的方式解释数据:
./manage.py inspectdb > models.py
models.py内容:
class AerowayPolygon(models.Model):
gid = models.AutoField(primary_key=True)
id = models.FloatField(blank=True, null=True)
osm_id = models.DecimalField(max_digits=65535, decimal_places=65535, blank=True, null=True)
z_order = models.FloatField(blank=True, null=True)
aeroway = models.CharField(max_length=80, blank=True, null=True)
name = models.CharField(max_length=80, blank=True, null=True)
name_en = models.CharField(db_column='name:en', max_length=80, blank=True, null=True) # Field renamed to remove unsuitable characters.
operator = models.CharField(max_length=80, blank=True, null=True)
ref = models.CharField(max_length=80, blank=True, null=True)
faa = models.CharField(max_length=80, blank=True, null=True)
iata = models.CharField(max_length=80, blank=True, null=True)
icao = models.CharField(max_length=80, blank=True, null=True)
website = models.CharField(max_length=80, blank=True, null=True)
contact_we = models.CharField(db_column='contact:we', max_length=80, blank=True, null=True) # Field renamed to remove unsuitable characters.
phone = models.CharField(max_length=80, blank=True, null=True)
contact_ph = models.CharField(db_column='contact:ph', max_length=80, blank=True, null=True) # Field renamed to remove unsuitable characters.
ele = models.CharField(max_length=80, blank=True, null=True)
tower_type = models.CharField(db_column='tower:type', max_length=80, blank=True, null=True) # Field renamed to remove unsuitable characters.
geom = models.MultiPolygonField(srid=0, dim=4, blank=True, null=True)
class Meta:
managed = False
db_table = 'aeroway_polygon'
从数据库访问对象的任何尝试都会导致GEOS抱怨LinearRing.
>>> from data.models import AerowayPolygon
>>> AerowayPolygon.objects.all()[0]
GEOS_ERROR: IllegalArgumentException: Points of LinearRing do not form a closed linestring
错误没有错,这些点不会关闭LineString.但是我感到困惑,因为我认为类型应该是MultiPolygon,因此应该可以正常工作.是什么赋予了?
通过手动尝试从PostGIS中获取几何图形,我进行了更深入的研究.
作为一个众所周知的二进制十六进制字符串,我会得到相同的行为:
>>> from django.contrib.gis.geos import GEOSGeometry
>>> wkb ='01shp2pgsql -d -I aeroway_polygon_polygon.shp aeroway_polygon | psql
0C00100000001030000C0020000008E0000000064931E4F47DDBF4020B11AB5BC49400000000000000000FFFFFFFFFFFFEFFF006493B23347DDBF442075F9B7BC494 ... 003C9368871FDDBF4020B193B4BC49400000000000000000FFFFFFFFFFFFEFFF'
>>> GEOSGeometry(wkb)
GEOS_ERROR: IllegalArgumentException: Points of LinearRing do not form a closed linestring
解决方法:
MultiPolygon的每个多边形仍应形成闭合的线串.您的数据可能格式错误或已损坏.
您可以尝试使用ST_MakeValid解决此问题.
UPDATE aeroway_polygon
SET geom = ST_Multi(ST_CollectionExtract(ST_Makevalid(geom), 3))
WHERE ST_IsValid(geom) = false;
请注意,我没有测试此查询,但找到了here on gis.stackexchange.