将png矢量化为shp且每个颜色生成一个面要素
在代码运行前建议先使用arcgis或qgis中的地理配准工具先将图片对齐。
qgis中地理配准过程:点击菜单栏 【栅格】→Freehand Raster Georeferencer,打开图片,选定图片图层后,
先用2p工具选择两点做初步大小和位置的摆放,
然后用缩放、旋转、平移等工具微调,
调整好之后选择export raster将地理配准信息导出
osgeo库的安装:
conda虚拟环境中终端运行
conda install -c conda-forge gdal
将png转为shp且每个颜色生成一个要素代码如下,颜色会写入shp属性表中的color_hex 字段:
from osgeo import gdal, ogr, osr
def add_color_fields(input_png, output_shp, geotransform=None):
try:
# 读取 PNG 颜色数据
ds = gdal.Open(input_png)
if ds is None:
raise Exception(f"无法打开文件: {input_png}")
band_r = ds.GetRasterBand(1)
band_g = ds.GetRasterBand(2)
band_b = ds.GetRasterBand(3)
band_a = ds.GetRasterBand(4) if ds.RasterCount >= 4 else None
# 获取 PNG 文件的地理变换参数和投影信息
geotransform = ds.GetGeoTransform()
projection = ds.GetProjection()
# 创建一个新的波段用于存储 RGB 组合值
driver = gdal.GetDriverByName('MEM')
temp_ds = driver.Create('', ds.RasterXSize, ds.RasterYSize, 1, gdal.GDT_UInt32)
temp_ds.SetGeoTransform(geotransform) # 设置地理变换参数
temp_ds.SetProjection(projection) # 设置投影信息
temp_band = temp_ds.GetRasterBand(1)
r_data = band_r.ReadAsArray()
g_data = band_g.ReadAsArray()
b_data = band_b.ReadAsArray()
# 组合 RGB 值为一个唯一标识
combined_data = (r_data << 16) | (g_data << 8) | b_data
temp_band.WriteArray(combined_data)
# 创建 SHP 文件并定义字段
driver = ogr.GetDriverByName("ESRI Shapefile")
shp_ds = driver.CreateDataSource(output_shp)
if shp_ds is None:
raise Exception(f"无法创建文件: {output_shp}")
# 创建空间参考对象并设置投影信息
srs = osr.SpatialReference()
srs.ImportFromWkt(projection)
layer = shp_ds.CreateLayer("polygons", srs, geom_type=ogr.wkbPolygon)
# 仅添加 color_hex 字段
layer.CreateField(ogr.FieldDefn("color_hex", ogr.OFTInteger))
# 矢量化并写入颜色值
gdal.Polygonize(temp_band, None, layer, 0, [], callback=None)
# 遍历要素填充颜色
layer.ResetReading()
for feat in layer:
geom = feat.GetGeometryRef()
centroid = geom.Centroid()
x, y = int(centroid.GetX()), int(centroid.GetY())
# 提取中心点的组合 RGB 值
combined_value = combined_data[y, x]
# 填充 color_hex 字段
feat.SetField("color_hex", combined_value)
layer.SetFeature(feat)
shp_ds.Destroy()
temp_ds = None # 释放临时数据集
except Exception as e:
print(f"发生错误: {e}")
# 调用示例
add_color_fields("你的png文件路径,注意和配准文件在同一个文件夹中.png",
"你的shp文件存储路径.shp")
以上代码由ai生成,已测可用