tru*_*one 5 python django geodjango shapely geopandas
我正在操作 GIS 数据并将geopandas其存储在各种Django模型中。 在引擎盖下geopandas使用,而没有。 shapelyDjango
这是一些代码:
import geopandas as gpd
from django.contrib.gis.db import models
class MyModel(models.Model):
geometry = models.PolygonField()
name = models.CharField(max_length=255, null=False, unique=True)
some_property = models.IntegerField()
gdf = gpd.read_file("some_data.geojson")
# ...do some stuff w/ gdf...
for data in gdf.to_dict("records"):
name = data.pop("name")
MyModel.objects.create_or_update(
name=name,
defaults=data,
)
Run Code Online (Sandbox Code Playgroud)
上面的代码将会失败,并出现以下错误:
类型错误:无法使用类型值设置 MyModel SpatialProxy (POLYGON):<class 'shapely.geometry.polygon.Polygon'>
除非我添加一些讨厌的代码,例如:
from django.contrib.gis.geos import fromstr, Polygon
data["geometry"] = Polygon(fromstr(str(data["geometry"])))
Run Code Online (Sandbox Code Playgroud)
有没有办法避免这种情况并直接映射 from shapelyto Django?
编辑:
以下是一些值:
>> data["geometry"]
<shapely.geometry.polygon.Polygon object at 0x7fb374f41908>
>> str(data["geometry"])
'POLYGON ((-4.337076919429241 53.41842814531255, -4.336698521348041 53.4182242737367, ....))'
>> fromstr(str(data["geometry"]))
<Polygon object at 0x7fb3733d158e>
Run Code Online (Sandbox Code Playgroud)
您的解决方案似乎并不像您想象的那么糟糕。
由于您的data['geometry']字段返回WKT字符串表示形式 ( 'POLYGON ((-4.337076919429241 53.41842814531255, ... ))),您可以避免该fromstr步骤并将其直接传递给 GEOSGeometry:
from django.contrib.gis.geos import GEOSGeometry
polygon = GEOSGeometry('POLYGON ((-4.337076919429241 53.41842814531255, ... ))')
Run Code Online (Sandbox Code Playgroud)
您还可以添加一些错误处理,不再担心您的解决方案崩溃:):
for data in gdf.to_dict("records"):
name = data.pop("name")
geometry_str = data.pop('geometry')
try:
geometry = GEOSGeometry(geometry_str)
except (TypeError, ValueError) as exc:
# If the geometry_str is not a valid WKT, EWKT or HEXEWKB string
# or is None then either continue, break or do something else.
# I will go with continue here.
continue
if geometry.geom_type != 'Polygon':
# If the created geometry is not a Polygon don't pass it on MyModel
continue
MyModel.objects.update_or_create(
name=name, geometry=geometry,
defaults=data,
)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3754 次 |
| 最近记录: |