使用GDAL/GEOS求面特征的并集
- 2019 年 10 月 10 日
- 筆記
存在这样一个示例的矢量文件,包含了两个重叠的面特征:

一个很常见的需求是求取这个矢量中所有面元素的并集,通过GDAL/GEOS很容易实现这个功能,具体代码如下:
#include <iostream> #include <gdal/ogrsf_frmts.h> using namespace std; bool WritePolygon(string filePath, OGRPolygon *pOgrMerged) { //创建 GDALDriver* driver = GetGDALDriverManager()->GetDriverByName("ESRI Shapefile"); if (!driver) { printf("Get Driver ESRI Shapefile Error!n"); return false; } GDALDataset* dataset = driver->Create(filePath.c_str(), 0, 0, 0, GDT_Unknown, NULL); OGRLayer* poLayer = dataset->CreateLayer("houseType", NULL, wkbPolygon, NULL); //创建特征 { OGRFeature *poFeature = new OGRFeature(poLayer->GetLayerDefn()); poFeature->SetGeometry(pOgrMerged); if (poLayer->CreateFeature(poFeature) != OGRERR_NONE) { printf("Failed to create feature in shapefile.n"); return false; } } //释放 GDALClose(dataset); dataset = nullptr; //GDALDestroyDriverManager(); return true; } int main() { GDALAllRegister(); CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); //支持中文路径 CPLSetConfigOption("SHAPE_ENCODING", ""); //解决中文乱码问题 string filePath = "D:/Work/OSGWork/shpTest/test/src.shp"; GDALDataset *poDS = (GDALDataset*)GDALOpenEx(filePath.c_str(), GDAL_OF_VECTOR, NULL, NULL, NULL); if (!poDS) { printf("无法读取该文件,试检查格式是否正确!"); return 1; } if (poDS->GetLayerCount()<1) { printf("该文件的层数小于1,试检查格式是否正确!"); return 1; } OGRLayer *poLayer = poDS->GetLayer(0); //读取层 poLayer->ResetReading(); std::unique_ptr<OGRPolygon> pOgrMerged(new OGRPolygon()); OGRFeature *poFeature; while ((poFeature = poLayer->GetNextFeature()) != NULL) { // OGRGeometry *pGeo = poFeature->GetGeometryRef(); OGRwkbGeometryType pGeoType = pGeo->getGeometryType(); if (pGeoType == wkbPolygon) { OGRPolygon *pPolygon = (OGRPolygon*)pGeo; if (!pPolygon) { continue; } OGRPolygon* pTemp = static_cast<OGRPolygon*>(pOgrMerged->Union(pPolygon)); if (pTemp) { pOgrMerged.reset(pTemp); } } OGRFeature::DestroyFeature(poFeature); } GDALClose(poDS); poDS = nullptr; if (pOgrMerged && pOgrMerged->IsValid() && pOgrMerged->getExteriorRing()) { string path = "D:/Work/OSGWork/shpTest/test/dst.shp"; WritePolygon(path, pOgrMerged.get()); } return 0; }
在这段代码中,遍历了示例矢量文件中的每个面元素,求取了所有面元素的并集,得到最终一个面元素,并将这个面元素保存成新的矢量文件。这个矢量文件用ArcMap打开显示如下:
