作为一名编码爱好者,我目前正在按照自己的意愿创建自己的“地理空间”工具。但是从一开始我就已经遇到了问题。 我的工具应该使用GeoPandas提取信息,然后使用OGR / GDAL进行数据编辑,因为我希望它能快速运行。我喜欢分析很多大数据!
带有问题的代码片段应栅格化单个GeoPandas多边形。 我尝试使用此路径来做到这一点。 -使用geopandas WKT多边形从多边形中提取 -使用WKT多边形创建OGR功能 -使用GDAL将其栅格化。
我面临的问题是我只检索了一个由0而不是0和1组成的栅格...
代码显示在下面:
import geopandas as gpd
import ogr, osr
import gdal
import uuid
tf = r'f:test2.shp'
def vector_to_raster(source_layer, output_path, x_size, y_size, options, data_type=gdal.GDT_Byte):
'''
This method should create a raster object by burning the values of a source layer to values.
'''
x_min, x_max, y_min, y_max = source_layer.GetExtent()
print(source_layer.GetExtent())
x_resolution = int((x_max - x_min) / x_size)
y_resolution = int((y_max - y_min) / -y_size)
print(x_resolution, y_resolution)
target_ds = gdal.GetDriverByName(str('GTiff')).Create(output_path, x_resolution, y_resolution, 1, data_type)
spatial_reference = source_layer.GetSpatialRef()
target_ds.SetProjection(spatial_reference.ExportToWkt())
target_ds.SetGeoTransform((x_min, x_size, 0, y_max, 0, -y_size))
gdal.RasterizeLayer(target_ds, [1], source_layer, options=options)
target_ds.FlushCache()
return target_ds
#create geopandas dataframe
gdf = gpd.read_file(tf)
#grab projection from the gdf
projection = gdf.crs['init']
#get geometry from 1 polygon (now just the 1st one)
polygon = gdf.loc[0].geometry
#grab epsg from projection
epsg = int(projection.split(':')[1])
#create geometry
geom = ogr.CreateGeometryFromWkt(polygon.wkt)
#create spatial reference
proj = osr.SpatialReference()
proj.ImportFromEPSG(epsg)
#get driver
rast_ogr_ds = ogr.GetDriverByName('Memory').CreateDataSource('wrk')
#create polylayer with projection
rast_mem_lyr = rast_ogr_ds.CreateLayer('poly', srs=proj)
#create feature
feat = ogr.Feature(rast_mem_lyr.GetLayerDefn())
#set geometry in feature
feat.SetGeometryDirectly(geom)
#add feature to memory layer
rast_mem_lyr.CreateFeature(feat)
#create memory location
tif_output = '/vsimem/' + uuid.uuid4().hex + '.vrt'
#rasterize
lel = vector_to_raster(rast_mem_lyr, tif_output, 0.001, -0.001,['ATTRIBUTE=Shape__Len', 'COMPRESS=LZW', 'TILED=YES', 'NBITS=4'])
# output should consist of 0's and 1's
print(np.unique(lel.ReadAsArray()))
非常感谢能给我一个正确方向的提示的人:-)。
干杯!
答案 0 :(得分:0)
您好,我没有运行您的代码,但是我可以给出一些建议。 目前,您正在根据多边形中的“ Shape__Len”字段进行栅格化,并指定将栅格输出为GDT_Byte(只能包含0到255之间的值),请确保“ Shape__Len”与数据类型匹配,或者在包含0到255之间的整数的多边形中创建一个新字段以进行栅格化,或将输出数据类型更改为GDT_Float32。
或者,如果您只想要1和0,则可以在存在多边形的情况下将值1烧掉:
gdal.RasterizeLayer(target_ds, [1], source_layer,burn_values=[1])
这也是明智的做法,因为您正在为自己创建一些工具,以跟踪/管理NoData值。如果只想显示栅格化的多边形,则可以添加以下步骤:
target_ds = gdal.GetDriverByName(str('GTiff')).Create(output_path, x_resolution, y_resolution, 1, data_type)
spatial_reference = source_layer.GetSpatialRef()
target_ds.SetProjection(spatial_reference.ExportToWkt())
target_ds.SetGeoTransform((x_min, x_size, 0, y_max, 0, -y_size))
NowBand = target_ds.GetRasterBand(1) # ADD
NowBand.SetNoDataValue(0) # ADD NoData Value of your choice (according to your specified data type)
NowBand.Fill(0) # ADD Fill the band with NoData as to only display your rasterized features
gdal.RasterizeLayer(target_ds, [1], source_layer, burn_values=[1]) # if you only want to burn 1 in your values
target_ds.FlushCache()
答案 1 :(得分:0)
我也没有运行代码,但是以防万一有人在寻找答案,我认为您在“ vector_to_raster”函数中犯了错误:
2020-01-24 14:43:47.846445+00:00
x_resolution和y_resolution不应转换为int。 GeoTransform应该采用x_resolution / y_resolution,而不是x_size /(-)y_size。