OGR中空间叠加函数Union

本文介绍如何利用OGR库中的Union函数实现地理信息系统中两个图层的合并操作,并详细解析了函数参数的意义及使用方法。同时提供了具体的代码实例,展示了如何设置参数以达到期望的合并效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

    在OGRLayer的对象中调用Union函数了。先看一下Union函数的原型:

Union(OGRLayer *pLayerMethod, OGRLayer *pLayerResult, char **papszOptions=NULL, GDALProgressFunc pfnProgress=NULL, void *pProgressArg=NULL),根据OGR提供的解释来看,前三个参数是比较重要的:

    pLayerMethod:要跟当前图层做Union的那个图层,如果我要对layer1、layer2做Union操作,通过layer1对象调用Union函数,那么layer2就是pLayerMethod,不能为空。

    pLayerResult:很明显,存储Union结果的图层,也不能为空。这里可以是用ArcGIS创建好的没有要素的图层,也可以是在程序中用OGR创建的新图层,个人倾向与在程序  中用代码创建一个,简单的代码就能实现。

    papszOptions:这个二维指针中有其实包括了四个参数——SKIP_FAILURES=YES/NO、PROMOTE_TO_MULTI=YES/NO、INPUT_PREFIX=string、METHOD_PREFIX=string。当SKIP_FAILURES=YES的时候,如果某个要素的合并出现错误,则会跳过该要素继续后续要素的合并。PROMOTE_TO_MULTI=YES时,可以将单空间对象转换为多空间对象,如将Polygons转换为MultiPolygons, LineStrings转换为MultiLineStrings。INPUT_PREFIX=string,输入图层的属性字段在结果图层中的前置标记。METHOD_PREFIX=string,操作图层的属性字段在结果图层中的前置标记。还是拿layer1和layer2来举例,layer1、layer2合并后的结果图层中包含有layer1和layer2的所有属性字段,那么如果我们设置INPUT_PREFIX=1,METHOD_PREFIX=2,那么在结果图层的字段中,来自layer1的所有字段将在字段名称前加上前缀"1",来自layer2的将加前缀"2"。

    后面的两个参数没做尝试。

   下面看一个具体的代码示例

  

	char *filePath = "D:\\CeShi_Data\\CESHI_NEW";
	char *layerName1 = "layer1";
	char *layerName2 = "layer2";
	OGRLayer *pLayer1 = NULL;
	OGRLayer *pLayer2 = NULL;
	OGRDataSource *pODS = NULL;

	OGRRegisterAll();
	pODS = OGRSFDriverRegistrar::Open(filePath,TRUE);

	//读取取要进行Union的两个图层
	pLayer1 = pODS->GetLayerByName(layerName1);
	pLayer2 = pODS->GetLayerByName(layerName2);
	//创建结果图层
	OGRLayer *pResultLayer = NULL;
	pResultLayer = pODS->CreateLayer("result",pLayer2->GetSpatialRef(),wkbMultiPolygon,NULL);
	//配置Union函数中的第三个参数
	char **p = new char *[4];
	p[0] = "SKIP_FAILURES=YES";
	p[1] = "PROMOTE_TO_MULTI=YES";
	p[2] = "INPUT_PREFIX=1";
	p[3] = "METHOD_PREFIX=2";
	pLayer2->Union(pLayer1,pResultLayer,p,NULL,NULL);  

	//将对pResultLayer的编辑写入文件,如果不加这句,result文件中将没有记录
	pResultLayer->SyncToDisk();
	OGRDataSource::DestroyDataSource(pODS);

如下图:

layer1

layer2:

结果图层result:

如果layer1、layer2中的属性字段相同,如示例中,在结果图层中想保存一份属性字段,则在创建结果图层的时给结果图层创建同layer1一样的属性字段集即可,在代码中做如下修改:

	//创建结果图层
	OGRLayer *pResultLayer = NULL;
	pResultLayer = pODS->CreateLayer("result",pLayer2->GetSpatialRef(),wkbMultiPolygon,NULL);
	//为结果图层创建跟输入图层layer1相同的属性字段
	OGRFeatureDefn *pOGRFeatureDefn = pLayer1->GetLayerDefn();
	for (int i = 0 ; i < pOGRFeatureDefn->GetFieldCount(); i++)
		pResultLayer->CreateField( pOGRFeatureDefn->GetFieldDefn(i));
	pLayer2->Union(pLayer1,pResultLayer,p,NULL,NULL);  

生成的结果图层的属性表如下:

    以上便是Union的一些简单用法,其他几个函数也基本相同,不妥之处,请批评指正!

转载于:https://www.cnblogs.com/abella/p/9473121.html

# -*- coding: utf-8 -*- import os import sys from osgeo import gdal, ogr, osr import chardet # 强制设置全局中文编码环境 gdal.SetConfigOption('GDAL_FILENAME_IS_UTF8', 'YES') gdal.SetConfigOption('SHAPE_ENCODING', '') # 不预设编码,通过代码精确控制 def detect_file_encoding(filepath): """精确检测文件编码""" with open(filepath, 'rb') as f: rawdata = f.read(10000) # 读取前10000字节用于检测 return chardet.detect(rawdata)['encoding'] def get_reference_geometry(reference_shp): """获取参考矢量文件的合并几何体(完整实现)""" try: # 检测源文件编码 file_encoding = detect_file_encoding(reference_shp) or 'GB18030' # 设置临时编码环境 original_encoding = gdal.GetConfigOption('SHAPE_ENCODING') gdal.SetConfigOption('SHAPE_ENCODING', file_encoding) ref_ds = ogr.Open(reference_shp) if ref_ds is None: raise RuntimeError(f"无法打开参考矢量文件:{reference_shp}") ref_layer = ref_ds.GetLayer() ref_srs = ref_layer.GetSpatialRef() union_geom = ogr.Geometry(ogr.wkbMultiPolygon) for feature in ref_layer: geom = feature.GetGeometryRef() if geom is not None: union_geom.AddGeometry(geom.Clone()) result_geom = union_geom.UnionCascaded() return result_geom, ref_srs, file_encoding finally: if 'ref_ds' in locals(): ref_ds = None gdal.SetConfigOption('SHAPE_ENCODING', original_encoding) def convert_encoding(text, source_encoding, target_encoding='GB18030'): """精确编码转换函数""" if text is None: return "" if isinstance(text, bytes): try: return text.decode(source_encoding).encode(target_encoding).decode(target_encoding) except: try: return text.decode('GB18030') except: return text.decode(errors='ignore') if isinstance(text, str): try: return text.encode(source_encoding).decode(target_encoding) except: return text ret
最新发布
03-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值