小工具—修改.shp文件,删除指定属性的要素(gdal, boost库)

main.cpp:

#include <iostream>

#include "shp_Parser.h"

int main()
{
	SHP_Parser shpParser;
	shpParser.ReadShapeFile();
	return 0;
}

shp_Parser.h:

#ifndef SHP_PARSER_H
#define SHP_PARSER_H

#include <vector>
#include <fstream>
#include <iostream>
#include "gdal_priv.h"

typedef struct ini_file
{
	std::string input_path;
	std::string output_path;

	std::string link_attr;
}INI_FILE;

class SHP_Parser
{
public:
	void ReadShapeFile();
	void dealRTable(GDALDriver *poDriver);
	void dealNTable(GDALDriver *poDriver);
	void dealCTable(GDALDriver *poDriver);
	void dealR_LNameTable(GDALDriver *poDriver);

private:
	bool ReadIni(const char* _path);
	int deleteLinkID(char *_pDst, const char *_pSrc);

	INI_FILE m_iniFile;
	char **m_pRID;
	int m_filed_0b01_count;
	std::ofstream fout;

};

#endif

shp_Parser.cpp:

#include "shp_Parser.h"

#include <vector>
#include <algorithm>
#include "boost\algorithm\string.hpp"
#include "boost\property_tree\ptree.hpp"
#include "boost\property_tree\ini_parser.hpp"

#include "ogrsf_frmts.h"
#include "gdal.h"
#include "gdal_priv.h"
using namespace std;

// 支持删除的最多的link数,预分配内存
#define DELETE_LINK_NUM_MAX		5000

//// 删除的link的属性类型
//#define ROAD_KIND_ATTR			"080a"


void SHP_Parser::ReadShapeFile()
{
	//使属性表字段支持中文
	CPLSetConfigOption("SHAPE_ENCODING", "");
	GDALAllRegister();
	CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
	//创建ESRI shp文件
	char *pszDriverName = "ESRI Shapefile";
	GDALDriver *poDriver = NULL;
	poDriver = GetGDALDriverManager()->GetDriverByName(pszDriverName);
	if (poDriver == NULL)
	{
		cout << pszDriverName << "驱动不可用!" << endl;
		return;
	}

	// R表和R_LNname表中删除要素,N表和C表是修改要素属性
	//ReadIni("config.ini");
	ReadIni("F:\\lipeng\\tempProj\\delete466163\\Release\\config.ini");
	dealRTable(poDriver);
	dealNTable(poDriver);
	dealCTable(poDriver);
	dealR_LNameTable(poDriver);

	system("pause");
}

void SHP_Parser::dealRTable(GDALDriver *poDriver)
{
#if 1
	string pRshanghaiShp = m_iniFile.input_path + "\\Rshanghai.shp";
	string pNewRshanghaiShp = m_iniFile.output_path + "\\Rshanghai.shp";
	string RLogFile = m_iniFile.output_path + "\\Rlog.csv";
#endif

	//------------------------------------------------------------------------------------------------------------------------------------------
	// 修改Rshanghai.shp表
	fout.open(RLogFile, ios::out);
	GDALDataset *pDataSet_RShanghaiSimplify = (GDALDataset*)GDALOpenEx(pRshanghaiShp.c_str(), GDAL_OF_VECTOR, NULL, NULL, NULL); //RShanghai抽稀shp文件
	cout << "正在创建新的Rshanghai.shp文件:" << pNewRshanghaiShp << "...";
	GDALDataset *pNewDataSet_RShanghaiSimplify = poDriver->CreateCopy(pNewRshanghaiShp.c_str(), pDataSet_RShanghaiSimplify, 0, 0, 0, NULL);
	if (pDataSet_RShanghaiSimplify == NULL || pNewDataSet_RShanghaiSimplify == NULL)
	{
		cout << "数据集打开失败!" << endl;
		return;
	}
	cout << endl << pNewRshanghaiShp << "创建完成" << endl << "正在处理" << pNewRshanghaiShp << "...";


	OGRLayer *poLayer, *poNewLayer = NULL;
	poLayer = pDataSet_RShanghaiSimplify->GetLayer(0); // 都只有一个图层 
	poNewLayer = pNewDataSet_RShanghaiSimplify->GetLayer(0);

	OGRFeature *poFeature;
	poLayer->ResetReading();

	int field_count = 0, iFID = 0;
	m_filed_0b01_count = 0; //R表中类型为0b01的记录条数
	int ifield = 0;
	double dfield = 0.0;
	const char *strOneField = NULL;
	const char *strSecField = NULL;
	vector<GIntBig> vecDelID;
	GIntBig RFeatureCount = poLayer->GetFeatureCount(); // 得到要素个数

	m_pRID = new char*[DELETE_LINK_NUM_MAX];	// 需要删除的link的ID
	for (int i = 0; i < DELETE_LINK_NUM_MAX; ++i)	// 分配内存
	{
		m_pRID[i] = new char[13];
		memset(m_pRID[i], 0, 13);
	}

	fout << "delete Rshanghai.shp "<<m_iniFile.link_attr.c_str()<<":" << endl;
	fout << "MapID,ID,Kind,SnodeID,EnodeID" << endl;
	while ((poFeature = poLayer->GetNextFeature()) != NULL)
	{
		iFID = poFeature->GetFID();
		strOneField = poFeature->GetFieldAsString(0);	// MapID
		strSecField = poFeature->GetFieldAsString(3);	// Kind
		//if ((strcmp(strOneField, "466163") == 0) && (strcmp(strSecField, "0b01") == 0)) // MapID=466163 && Kind=0b01
		if ((strcmp(strOneField, "466163") == 0) && (strcmp(strSecField, m_iniFile.link_attr.c_str()) == 0)) // MapID=466163 && Kind=0b01
		{
			memcpy(m_pRID[m_filed_0b01_count], poFeature->GetFieldAsString(1), 13);
			++m_filed_0b01_count;
			vecDelID.push_back(poFeature->GetFID());
			fout << poFeature->GetFieldAsString(0) << "," << poFeature->GetFieldAsString(1) << "," << poFeature->GetFieldAsString(3)
				<< "," << poFeature->GetFieldAsString(9) << "," << poFeature->GetFieldAsString(10) << endl;
		}

		//int fieldcount = poFDefn->GetFieldCount();
		//cout<<"Field count is : %d\n"<<poFDefn->GetFieldCount()<<endl;  
		//for (field_count = 0; field_count < poFDefn->GetFieldCount(); field_count++)
		//{
		//	OGRFieldDefn * poFieldDefn = poFDefn->GetFieldDefn(field_count);
		//	if (poFieldDefn->GetType() == OFTInteger)
		//	{
		//		ifield = poFeature->GetFieldAsInteger(field_count);
		//		//              printf("%d ", poFeature->GetFieldAsInteger(iField));  
		//	}
		//	else if (poFieldDefn->GetType() == OFTReal)
		//	{
		//		dfield = poFeature->GetFieldAsDouble(field_count);
		//		//              printf("%3f ", poFeature->GetFieldAsDouble(iField));  
		//	}
		//	else if (poFieldDefn->GetType() == OFTString)
		//	{
		//		strfield = poFeature->GetFieldAsString(field_count);
		//		//              printf("%s ", poFeature->GetFieldAsString(iField));  
		//	}
		//	//          else  
		//	//              printf("%s", poFeature->GetFieldAsString(iField));  
		//}
		//以上操作与gdal官网一样  
		//get Geometry获取polygon的信息  
		// 		OGRGeometry *poGeometry;
		// 		poGeometry = poFeature->GetGeometryRef();
		// 		double x, y; double area;
		// 		if (poGeometry != NULL && wkbFlatten(poGeometry->getGeometryType()) == wkbPolygon)
		// 		{
		// 			OGRPolygon *poPolygon = (OGRPolygon *)poGeometry;
		// 			area = poPolygon->get_Area();
		// 			OGRPoint point;
		// 			OGRLinearRing *pOGRLinearRing = poPolygon->getExteriorRing();
		// 			pOGRLinearRing->getPoint(0, &point);//得到第一个点的坐标  
		// 			x = point.getX();
		// 			y = point.getY();
		// 			//          printf("%.6f, %.6f\n", poPoint->getX(), poPoint->getY());  
		// 		}
		// 		else
		// 			//          printf("no point geometry\n");  

		OGRFeature::DestroyFeature(poFeature);
	}
	for_each(vecDelID.begin(), vecDelID.end(), [&poNewLayer](GIntBig _id)
	{
		poNewLayer->DeleteFeature(_id);
	});

	GDALClose(pDataSet_RShanghaiSimplify);
	GDALClose(pNewDataSet_RShanghaiSimplify);
	fout << "delete total: " << m_filed_0b01_count << endl;
	fout.close();
	cout << endl << pNewRshanghaiShp<< "处理完成" << endl << endl;

}

void SHP_Parser::dealNTable(GDALDriver *poDriver)
{
#if 1
	string pNshanghaiShp = m_iniFile.input_path + "\\Nshanghai.shp";
	string pNewNshanghaiShp = m_iniFile.output_path + "\\Nshanghai.shp";
	string NLogFile = m_iniFile.output_path + "\\Nlog.csv";
#endif

	//------------------------------------------------------------------------------------------------------------------------------
	// 修改NShanghai.shp表
	fout.open(NLogFile, ios::out);
	GDALDataset *pDataSet_NShanghai = (GDALDataset*)GDALOpenEx(pNshanghaiShp.c_str(), GDAL_OF_VECTOR, NULL, NULL, NULL); //NShanghai的shp文件
	cout << "正在创建新的Nshanghai.shp文件:" << pNewNshanghaiShp << "...";
	GDALDataset *pNewDataSet_NShanghai = poDriver->CreateCopy(pNewNshanghaiShp.c_str(), pDataSet_NShanghai, 0, 0, 0, NULL);
	if (pDataSet_NShanghai == NULL || pNewDataSet_NShanghai == NULL)
	{
		cout << "数据集打开失败!" << endl;
		return;
	}
	cout << endl << pNewNshanghaiShp << "创建完成" << endl << "正在处理" << pNewNshanghaiShp << "...";

	char ch[254] = { '\0' };
	int flag = 0, deleteCount = 0;
	vector<GIntBig> vecDelID;
	const char *strOneField = NULL;
	const char *strSecField = NULL;
	OGRLayer *poNewLayer = NULL;
	OGRFeature *poFeature = NULL;
	poNewLayer = pNewDataSet_NShanghai->GetLayer(0);
	poNewLayer->ResetReading();
	fout << "delete Nshanghai.shp:" << endl;
	fout << "MapID,ID,Kind,Corss_LID,Node_LID" << endl;
	while ((poFeature = poNewLayer->GetNextFeature()) != NULL)
	{
		flag = 0;
		strOneField = poFeature->GetFieldAsString(6);	// Cross_LID 需要检测的字段
		strSecField = poFeature->GetFieldAsString(12);	// Node_LID 需要检测的字段
		if (deleteLinkID(ch, strOneField) != 0)
		{
			flag = 1;
			poFeature->SetField(6, ch);
			poNewLayer->SetFeature(poFeature);

		}

		memset(ch, 0, 254);
		if (deleteLinkID(ch, strSecField) != 0)
		{
			flag = 1;
			poFeature->SetField(12, ch);
			poNewLayer->SetFeature(poFeature);
		}
		if (flag == 1)
		{
			++deleteCount;
			vecDelID.push_back(poFeature->GetFID());
			fout << poFeature->GetFieldAsString(0) << "," << poFeature->GetFieldAsString(1) << "," << poFeature->GetFieldAsString(3)
				<< "," << poFeature->GetFieldAsString(6) << "," << poFeature->GetFieldAsString(12) << endl;
		}
		OGRFeature::DestroyFeature(poFeature);
	}

	GDALClose(pDataSet_NShanghai);
	GDALClose(pNewDataSet_NShanghai);
	fout << "delete total:" << deleteCount << endl;
	fout.close();
	cout << endl << pNewNshanghaiShp << "处理完成" << endl << endl;
}

void SHP_Parser::dealCTable(GDALDriver *poDriver)
{
	string pCshanghaiShp = m_iniFile.input_path + "\\Cshanghai.shp";
	string pNewCshanghaiShp = m_iniFile.output_path + "\\Cshanghai.shp";
	string CLogFile = m_iniFile.output_path + "\\Clog.csv";

	//------------------------------------------------------------------------------------------------------------------------------
	// 修改CShanghai.shp表
	fout.open(CLogFile, ios::out);
	GDALDataset *pDataSet_CShanghai = (GDALDataset*)GDALOpenEx(pCshanghaiShp.c_str(), GDAL_OF_VECTOR, NULL, NULL, NULL); //NShanghai的shp文件
	cout << "正在创建新的Cshanghai.shp文件:" << pNewCshanghaiShp << "...";
	GDALDataset *pNewDataSet_CShanghai = poDriver->CreateCopy(pNewCshanghaiShp.c_str(), pDataSet_CShanghai, 0, 0, 0, NULL);
	if (pDataSet_CShanghai == NULL || pNewDataSet_CShanghai == NULL)
	{
		cout << "数据集打开失败!" << endl;
		return;
	}
	cout << endl << pNewCshanghaiShp << "创建完成" << endl << "正在处理" << pNewCshanghaiShp << "...";

	char ch[254] = { '\0' };
	int flag = 0, deleteCount = 0;
	vector<GIntBig> vecDelID;
	const char *strOneField = NULL;
	const char *strSecField = NULL;
	OGRLayer *poNewLayer = NULL;
	OGRFeature *poFeature = NULL;
	char inLinkID[14] = { '\0' }, outLinkID[14] = { '\0' };
	poNewLayer = pNewDataSet_CShanghai->GetLayer(0);
	poNewLayer->ResetReading();
	fout << "delete Cshanghai.shp:" << endl;
	fout << "MapID,ID,inLinkID,outLinkID" << endl;
	while ((poFeature = poNewLayer->GetNextFeature()) != NULL)
	{
		flag = 0;
		strOneField = poFeature->GetFieldAsString(3);	// inLinkID 需要检测的字段
		memcpy(inLinkID, strOneField, 13);
		strSecField = poFeature->GetFieldAsString(4);	// outLinkID 需要检测的字段
		memcpy(outLinkID, strSecField, 13);
		if (deleteLinkID(ch, strOneField) != 0)
		{
			flag = 1;
			poFeature->SetField(3, ch);
			poNewLayer->SetFeature(poFeature);

		}

		memset(ch, 0, 254);
		if (deleteLinkID(ch, strSecField) != 0)
		{
			flag = 1;
			poFeature->SetField(4, ch);
			poNewLayer->SetFeature(poFeature);
		}
		if (flag == 1)
		{
			++deleteCount;
			vecDelID.push_back(poFeature->GetFID());
			fout << poFeature->GetFieldAsString(0) << "," << poFeature->GetFieldAsString(2) << "," << inLinkID
				<< "," << outLinkID << endl;
		}
		OGRFeature::DestroyFeature(poFeature);
		memset(inLinkID, '\0', 14);
		memset(outLinkID, '\0', 14);

	}

	GDALClose(pDataSet_CShanghai);
	GDALClose(pNewDataSet_CShanghai);
	fout << "delete total:" << deleteCount << endl;
	fout.close();
	cout << endl << pNewCshanghaiShp << "处理完成" << endl << endl;

}

void SHP_Parser::dealR_LNameTable(GDALDriver *poDriver)
{
	string pR_LNameshanghaiShp = m_iniFile.input_path + "\\R_LNameshanghai.shp";
	string pNewR_LNameshanghaiShp = m_iniFile.output_path + "\\R_LNameshanghai.shp";
	string R_LNameLogFile = m_iniFile.output_path + "\\R_LNamelog.csv";

	//------------------------------------------------------------------------------------------------------------------------------
	// 修改CShanghai.shp表
	fout.open(R_LNameLogFile, ios::out);
	GDALDataset *pDataSet_R_LNameShanghai = (GDALDataset*)GDALOpenEx(pR_LNameshanghaiShp.c_str(), GDAL_OF_VECTOR | GDAL_OF_UPDATE, NULL, NULL, NULL); //NShanghai的shp文件
	cout << "正在创建新的R_LNameshanghai.dbf文件:" << pNewR_LNameshanghaiShp << "...";
	
	//GDALDataset *pNewDataSet_R_LNameShanghai = poDriver->CreateCopy(pNewR_LNameshanghaiShp, pDataSet_R_LNameShanghai, 0, 0, 0, NULL);
	CPLCopyFile(pNewR_LNameshanghaiShp.c_str(), pR_LNameshanghaiShp.c_str());
	GDALDataset *pNewDataSet_R_LNameShanghai = (GDALDataset*)GDALOpenEx(pNewR_LNameshanghaiShp.c_str(), GDAL_OF_VECTOR | GDAL_OF_UPDATE, NULL, NULL, NULL); //NShanghai的shp文件
	if (pDataSet_R_LNameShanghai == NULL || pNewDataSet_R_LNameShanghai == NULL)
	{
		cout << "数据集打开失败!" << endl;
		return;
	}
	cout <<endl<< pNewR_LNameshanghaiShp << "创建完成" << endl << "正在处理" << pNewR_LNameshanghaiShp << "...";

	char ch[254] = { '\0' };
	int deleteCount = 0;
	vector<GIntBig> vecDelID;
	const char *strOneField = NULL;
	OGRLayer *poNewLayer = NULL;
	OGRFeature *poFeature = NULL;
	poNewLayer = pNewDataSet_R_LNameShanghai->GetLayer(0);
	poNewLayer->ResetReading();
	fout << "delete R_Nameshanghai.dbf:" << endl;
	fout << "MapID,ID" << endl;
	while ((poFeature = poNewLayer->GetNextFeature()) != NULL)
	{
		strOneField = poFeature->GetFieldAsString(1);	// ID 需要检测的字段
		memset(ch, 0, 254);
		if (deleteLinkID(ch, strOneField) != 0)
		{
			++deleteCount;
			vecDelID.push_back(poFeature->GetFID());
			fout << poFeature->GetFieldAsString(0) << "," << poFeature->GetFieldAsString(1) << endl;
// 			poFeature->SetField(1, ch);	// 删掉该要素,不需要这些代码
// 			poNewLayer->SetFeature(poFeature);
		}
		OGRFeature::DestroyFeature(poFeature);
	}

	for_each(vecDelID.begin(), vecDelID.end(), [&poNewLayer](GIntBig _id)
	{
		poNewLayer->DeleteFeature(_id);
	});
	GDALClose(pDataSet_R_LNameShanghai);
	GDALClose(pNewDataSet_R_LNameShanghai);
	fout << "delete total:" << deleteCount << endl;
	fout.close();
	cout << endl << pNewR_LNameshanghaiShp << "处理完成" << endl << endl;
}

// 读取配置文件
bool SHP_Parser::ReadIni(const char* _path)
{
	if (NULL == _path)
	{
		return false;
	}

	boost::property_tree::ptree pt;
	boost::property_tree::ini_parser::read_ini(_path, pt);
	
	m_iniFile.input_path = pt.get<string>("PATH.INPUT_PATH");
	m_iniFile.output_path = pt.get<string>("PATH.OUTPUT_PATH");
	m_iniFile.link_attr = pt.get<string>("LINK_ATTR.DELETE_ATTR_LINK");

	return true;

}
// 修改属性字符串,输入原属性字符串_pSrc, 返回修改之后的字符串_pDst,
int SHP_Parser::deleteLinkID(char *_pDst, const char *_pSrc)
{
	if (_pDst == NULL || _pSrc == NULL)
		return 0;

	string str_line = _pSrc;
	vector<string> vecLinkID, tempVecLinkID;
	boost::algorithm::split(vecLinkID, str_line, boost::is_any_of("|"));
	for (size_t i = 0; i < vecLinkID.size(); ++i)
	{
		size_t j = 0;
		for (; j < m_filed_0b01_count; ++j)
		{
			if (strcmp(m_pRID[j], vecLinkID[i].c_str()) == 0)
			{
				break;
			}
		}

		if (j == m_filed_0b01_count)

		{
			tempVecLinkID.push_back(vecLinkID[i]);
		}
	}

	if (tempVecLinkID.size() == vecLinkID.size())
	{
		return 0;
	}
	else if (tempVecLinkID.size() == 0 && vecLinkID.size() != 0)
	{
		strcpy(_pDst, "");
	}
	else if (tempVecLinkID.size() == 1)
	{
		strcpy(_pDst, tempVecLinkID[0].c_str());
	}
	else
	{
		strcpy(_pDst, tempVecLinkID[0].c_str());
		for (size_t i = 1; i < tempVecLinkID.size(); ++i)
		{
			strcat(_pDst, "|");
			strcat(_pDst, tempVecLinkID[i].c_str());
		}
	}
	return 1;
}

配置文件config.ini:

            
转载自:https://blog.csdn.net/lp310018931/article/details/78968721

You may also like...