gdal 删除矢量文件feature的方法(C++)

gdal 删除矢量文件feature的方法(C++)

GIS中经常会需要对矢量文件进行处理(增删改查),使用gdal能很方便的完成这些操作。对于删除矢量文件中不满足要求的feature,我一直用的是deletefeature()的方法,在qgis里打开显示是正确删除的,一直以为没有问题,但是今天把写好的算法集成给其他同事的时候,他在arcmap里打开矢量文件后发现目标feature没有被删除。然而同一个文件在qgis里打开后,显示目标feature确实是被删除了,amazing!!!。查找了一下原因,原来DeleteFeature()方法只是标记为删除(Marked delete),最后需要使用ExecuteSQL再执行一下。具体过程如下:

1、只用DeleteFeature()方法

原始矢量数据
在这里插入图片描述
任务需求:删除面积小于50的feature

	
#include<iostream>
#include<ogrsf_frmts.h>

int main()
{
	//矢量文件
	const char *m_input_vector="seaice.shp";

	GDALAllRegister();
	//支持中文路径
	CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
	
	//打开数据
	GDALDataset *in_poDS;
	in_poDS = (GDALDataset*)GDALOpenEx(m_input_vector, GDAL_OF_UPDATE, NULL, NULL, NULL);
	if (in_poDS == NULL)
	{
		std::cout << "open failed!" << std::endl;
	}

	OGRLayer *in_poLayer;
	GIntBig feature_nums;
	
	//获取图层
	in_poLayer = in_poDS->GetLayer(0);
	//获取feature个数
	feature_nums = in_poLayer->GetFeatureCount();
	std::cout << feature_nums << std::endl;
	//筛选出面积小于50的feature(注意:无论是使用空间或者属性过滤之后,必须使用getnextfeature()来获取feature,不能用getfeature(id)来获取feature。)
	in_poLayer->SetAttributeFilter("Area < 50");
	feature_nums = in_poLayer->GetFeatureCount();
	std::cout << feature_nums << std::endl;
	
	OGRFeature *po_feat = in_poLayer->GetNextFeature();
	while (po_feat)
	{
		in_poLayer->DeleteFeature(po_feat->GetFID());
		po_feat = in_poLayer->GetNextFeature();
	}
	GDALClose(in_poDS);
	return 0;
}

qgis打开发现只有两个feature了
在这里插入图片描述
arcmap打开发现还是原来的feature
在这里插入图片描述
在代码中遍历执行过上述删除操作的矢量文件

#include<iostream>
#include<ogrsf_frmts.h>

int main()
{
	const char *m_input_vector="seaice.shp";

	GDALAllRegister();
	CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");

	GDALDataset *in_poDS;
	in_poDS = (GDALDataset*)GDALOpenEx(m_input_vector, GDAL_OF_UPDATE, NULL, NULL, NULL);
	if (in_poDS == NULL)
	{
		std::cout << "open failed!" << std::endl;
	}

	OGRLayer *in_poLayer;
	GIntBig feature_nums;

	in_poLayer = in_poDS->GetLayer(0);
	feature_nums = in_poLayer->GetFeatureCount();
	std::cout << feature_nums << std::endl;
	
	for (int i = 0; i < feature_nums; i++)
	{
		OGRFeature *po_feat = in_poLayer->GetFeature(i);	
	}
	return 0;
}

在这里插入图片描述
可以看到执行删除后的矢量文件的feature数量还是10,被删除的feature只是提示marked delete,而没有真正删除feature。

2、彻底删除feature()

需要在关闭数据前更新一下数据集

	
#include<iostream>
#include<ogrsf_frmts.h>

int main()
{
	//矢量文件
	const char *m_input_vector="seaice.shp";

	GDALAllRegister();
	//支持中文路径
	CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
	
	//打开数据
	GDALDataset *in_poDS;
	in_poDS = (GDALDataset*)GDALOpenEx(m_input_vector, GDAL_OF_UPDATE, NULL, NULL, NULL);
	if (in_poDS == NULL)
	{
		std::cout << "open failed!" << std::endl;
	}

	OGRLayer *in_poLayer;
	GIntBig feature_nums;
	//获取图层
	in_poLayer = in_poDS->GetLayer(0);
	//获取feature个数
	feature_nums = in_poLayer->GetFeatureCount();
	std::cout << feature_nums << std::endl;
	//筛选出面积小于50的feature(注意:无论是使用空间或者属性过滤之后,必须使用getnextfeature()来获取feature,不能用getfeature(id)来获取feature。)
	in_poLayer->SetAttributeFilter("Area < 50");
	feature_nums = in_poLayer->GetFeatureCount();
	std::cout << feature_nums << std::endl;
	
	OGRFeature *po_feat = in_poLayer->GetNextFeature();
	while (po_feat)
	{
		in_poLayer->DeleteFeature(po_feat->GetFID());
		po_feat = in_poLayer->GetNextFeature();
	}
	std::string sql;
	sql = "REPACK " + std::string(in_poLayer->GetName());
	in_poDS->ExecuteSQL(sql.data(), NULL, NULL);
	GDALClose(in_poDS);
	return 0;
}

在arcgis中打开处理后的矢量文件,可以看到面积小于50的feature被彻底删除了。
在这里插入图片描述

参考

1、https://stackoverflow.com/questions/34950627/how-to-delete-feature-from-shapefile-using-gdal-c
2、https://www.cnblogs.com/bobird/articles/3224908.html

版权声明:本文为u014311125原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u014311125/article/details/90767809

智能推荐

k8s部署elasticsearch集群

百度营销大学     环境准备 我们使用的k8s和ceph环境见: https://blog.51cto.com/leejia/2495558 https://blog.51cto.com/leejia/2499684 ECK简介 Elastic Cloud on Kubernetes,这是一款基于 Kubernetes Operator 模式的新型编排产品,用户可使用该产品在...

saas-export项目-AdminLTE介绍与入门

AdminLTE介绍 (1)AdminLTE是什么? AdminLTE是一款建立在bootstrap和jquery之上的开源的模板主题工具 (2)AdminLTE有什么特点? 提供一系列响应的、可重复使用的组件, 并内置了多个模板页面 自适应多种屏幕分辨率,兼容PC和移动端 快速的创建一个响应式的Html5网站 AdminLTE 不但美观, 而且可以免去写很大CSS与JS的工作量 AdminLTE...

MyBatis中ResultMap结果集映射

用于解决属性名和字段名不一致的情况: resultMap 元素是 MyBatis 中最重要最强大的元素。...

编写一个shell

编写shell的过程: 1.从标准输入中读入一个字符串。 2.解析字符串 3.创建一个子进程的执行程序。 4.子进程程序替换。 5.父进程等待子进程退出。...

WEB自动化测试中Xpath定位方法

前言: Xpath是在XML文档中查找信息的一种语言,使用路径表达式来选取XML文档中的节点或节点集,由于XML与HTML结构类似(前者用于传输数据,后者用于显示数据),所以Xpath也常用于查找HTML文档中的节点或节点集。 一  路径表达式: 路径以“/”开始     表示找到满足该绝对路径的元素; 路径以//”开始  ...

猜你喜欢

力扣困难难度 第4题 寻找两个正序数组的中位数

先看一眼题 我的思路: 设置下标i,j分别用于遍历两个数组,初始值均为0,直到找到两个数组中从小到大的第第length/2个数为止结束循环,length为两个数组长度之和。 ·每次比较nums[i]nums[j],如果前者小则i++,否则j++ ·循环结束时,如果count已经达到length/2,则说明已经找到了中位数,[注意:此时有可能正好其中一个数组遍历完了!所以...

[国家集训队]小Z的袜子(莫队)

[国家集训队]小Z的袜子 题目描述 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿。终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命…… 具体来说,小Z把这NN只袜子从1到NN编号,然后从编号LL到RR(LL 尽管小Z并不在意两只袜子是不是完整的一双,甚至不在意两只袜子是否一左一右,他却很在意袜子的颜色,毕竟穿两只不同...

服务器配置(五) 服务器使用tomcat配置https全过程

一.了解服务器配置https协议 HTTPS,是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。 配置HTTPS就需要证书,证书通过权威的CA机构付费获得的证书才能被互联网承认,我们将其放在服务器上面,配置好后,就可以进行https通信了。 通过https访问的网站,在地址前可以看到安全两个字,点击可以查...

SQL语言——基本概念、操作数据库、表、表记录、数据库备份与恢复、外键约束

SQL语言 1.基本概念 1.1 SQL SQL–Structured Query Language, 结构化查询语言,是关系型数据库通用的操作语言。 是一种非过程性语言。 由美国国家标准局(ANSI)与国际标准化组织(ISO)制定SQL标准。各大数据库厂商都对其做了实现。所以我们只要学会了SQL语言,就可以操作各大关系型数据库了。 为加强SQL的语言能力,各厂商增强了过程性语言的特征...

.net core3.1 dapper使用(Oracle链接字符串)

历经的艰辛就不多说了(.net 新手 不喜勿喷 欢迎指点) 废话不多说了,直接上正题: 1.首先建一个类来管理数据库连接 public class DbFactory : IDbFactory { readonly IOptions _options; public DbFactory(IOptions options) { _options = options; } public DbConne...