从Python GDAL/OGR Cookbook 1.0 documentation开始,我在字符串格式中插入一个“in memory”geojson,在loop_zonal_stats中插入一个gdal“in memory”栅格作为input_zone_polygon,然后我从zonal_stats()中为每个特征接收一个int值。该值由FID存储在字典中。
原始代码:
def loop_zonal_stats(input_zone_polygon, input_value_raster):
shp = ogr.Open(input_zone_polygon)
lyr = shp.GetLayer()
featList = range(lyr.GetFeatureCount())
statDict = {}
for FID in featList:
feat = lyr.GetFeature(FID)
maxValue = zonal_stats(feat, input_zone_polygon, input_value_raster)
statDict[FID] = int(maxValue)
return statDict
print statDict
{0: 5, 1: 5, 2: 5, 3: 5, ...}
目标是添加一个名为Densitykm2的字段,并使用从zonal_stats()直接在geojson“in memory”中获取的值填充它。这个更新过的geojson将是该方法的返回。
所以这是修改后的代码:
def loop_zonal_stats(input_zone_polygon, input_value_raster):
shp = ogr.Open(input_zone_polygon)
lyr = shp.GetLayer()
featList = range(lyr.GetFeatureCount())
maxFldDef = ogr.FieldDefn('Densitykm2', ogr.OFTInteger)
lyr.CreateField(maxFldDef)
for FID in featList:
feat = lyr.GetFeature(FID)
maxValue = zonal_stats(feat, input_zone_polygon, input_value_raster)
feat.SetField('Densitykm2', int(maxValue))
lyr.SetFeature(feat)
return input_zone_polygon
然而,我尝试过收到两种错误:
也许还有另一种可能性,将“内存中”geojson与原始代码的返回字典合并到Add字段并填充它。也许用geojson lib?
- 更新 -
这是一个解决方案,我代码:
def loop_zonal_stats(input_zone_polygon, input_value_raster):
# Load Polygon
shp = ogr.Open(input_zone_polygon)
lyr = shp.GetLayer()
# Density field Definition
maxFldDef = ogr.FieldDefn('Densitykm2', ogr.OFTInteger)
# Create Temporary memory layer
outdriver = ogr.GetDriverByName('MEMORY')
source = outdriver.CreateDataSource('memData')
outdriver = outdriver.Open('MEM', 1)
# Copy of Polygon layer
source.CopyLayer(lyr, 'temp', ['OVERWRITE=YES'])
# Load temp Temporary memory layer
memlyr = source.GetLayer()
# Density Field creation
memlyr.CreateField(maxFldDef)
# List of ID to enumerate on
featList = range(lyr.GetFeatureCount())
print "Number of Wetlands in process = {0}".format(len(featList))
# input SpatialReference
inSpatialRef = osr.SpatialReference()
inSpatialRef.ImportFromEPSG(2959)
# input SpatialReference
outSpatialRef = osr.SpatialReference()
outSpatialRef.ImportFromEPSG(4326)
# create the CoordinateTransformation
coordTrans = osr.CoordinateTransformation(inSpatialRef, outSpatialRef)
# Empty list to be filled with Geojon Feature Objet = []
GeojonFeatObj = []
# Loop over features
for FID in featList:
FeatIn = lyr.GetFeature(FID)
# Get feature of Polygon
featOut = memlyr.GetFeature(FID)
# get ZonalStats
maxValue = zonal_stats(FeatIn, input_zone_polygon, input_value_raster)
# Add density to feature
featOut.SetField('Densitykm2', maxValue)
print "Wetlands features proceed FID = {0} / {1}".format(FID, len(featList))
# write the feature to the layer
memlyr.SetFeature(featOut)
# Get geometry
geom = featOut.GetGeometryRef()
# Transform geometry (UTM18N ---> WGS84)
geom.Transform(coordTrans)
# update feature geometry
featOut.SetGeometry(geom)
# Export the feature to a feature geojson
GeojonFeatObj.append(featOut.ExportToJson())
return GeojonFeatObj
请注意,您需要: - 为要素对象列表构建FeatureCollection - 添加crs作为前缀 - 清理ORG字符串混乱
fc = geojson.FeatureCollection(tupple)
outputGeojson = geojson.dumps(fc)
#outputGeojson.replace(,'') }, {"geometry":
prefix = '{"crs": {"type": "link", "properties": {"href": "http://spatialreference.org/ref/epsg/4326/", "type": "proj4"}}, '
output = prefix+outputGeojson[1:]
output = output.replace('\\', '').replace('}"]', '}]').replace('["{', '[{').replace('", "{"geometry":', ', {"geometry":')
亚历