基于GDAL库读写shp文件的C++代码

因为项目需要,学习了解了GDAL读取shp文件的方式,贴出代码以供参考

我自己封装的包含shp读写操作的类,并不完整,留下了一些接口,有兴趣或者有需要的可以自己补充完整

头文件SHP_RW.h

#pragma once

#include <gdal.h>
#include <gdal_priv.h>
#include <ogrsf_frmts.h>
#include <fstream>
#include <iostream>

using namespace std;

typedef struct XYZInfo
{
	double x;
	double y;
	double z;
}XYZInfo;


class SHP_RW
{
public:
	SHP_RW();
	~SHP_RW();

	OGRGeometry *poGeometry;
	OGRLayer *poLayer;

	int Get_Point(XYZInfo& coordinate);
	int Get_LineString(vector<XYZInfo>& vecXYZ);
	int Get_Polygon(vector<XYZInfo>& OuterRing, vector<vector<XYZInfo>>& InteriorRing);
	int Get_MultiPoint(vector<XYZInfo> Points);
	int Get_MultiLineString(vector<vector<XYZInfo>> Lines);
	int Get_MultiPolygon(vector<vector<XYZInfo>>& OuterRingVec, vector<vector<vector<XYZInfo>>>& InteriorRingVec);
	int Get_GeometryCollection();

	// 设置点要素
	// 结构体传参
	int Set_Point(XYZInfo point, map<string, string> fieldvalue = map<string, string>())
	{	return Set_Point(point.x, point.y, point.z, fieldvalue);	}
	// x + y (+z)
	int Set_Point(int x, int y, int z = 0)	{return Set_Point(x, y, z, map<string, string>());}
	// x + y + 属性
	int Set_Point(int x, int y, map<string, string> fieldvalue) { return Set_Point(x, y, 0, fieldvalue);}
	// x + y + z + 属性
	int Set_Point(int x, int y, int z, map<string, string> fieldvalue);


	//设置线要素
	// 结构体传参
	int Set_LineString(vector<XYZInfo> Line, map<string, string> fieldvalue = map<string, string>());
	// x + y (+z)
	int Set_LineString(vector<double> vecX, vector<double> vecY, vector<double> vecZ = vector<double> ())
	{	
		return Set_LineString(vecX, vecY, vecZ, map<string, string>());
	}
	// x + y + 属性
	int Set_LineString(vector<double> vecX, vector<double> vecY, map<string, string> fieldvalue) 
	{
		return Set_LineString(vecX, vecY, vector<double>(), fieldvalue);
	}
	// x + y + z + 属性
	int Set_LineString(vector<double> vecX,
					vector<double> vecY,
					vector<double> vecZ,
					map<string, string> fieldvalue);


	// 设置多边形要素
	//结构体传参
	//1. 外环 + 属性
	int Set_Polygon(vector<XYZInfo> OutRingVec,
		map<string, string> fieldvalue)
	{
			return Set_Polygon(OutRingVec, vector<vector<XYZInfo>>(), fieldvalue);
	}

	//2. 外环(+ 内环 (+ 属性))
	int Set_Polygon(vector<XYZInfo> OutRingVec,
		vector<vector<XYZInfo>> InteriorRingVec = vector<vector<XYZInfo>>(),
		map<string, string> fieldvalue = map<string, string>());

	int Set_MultiPoint();
	int Set_MultiLineString();
	int Set_MultiPolygon();
	int Set_GeometryCollection();

    //定义属性字段
	int SetFieldDefn(vector<string> fieldname, vector<OGRFieldType> fieldtype, vector<int> fieldwidth);

private:

};

.cpp文件 SHP_RW.cpp

#include "include/SHP_RW.h"


SHP_RW::SHP_RW()
{
}

SHP_RW::~SHP_RW()
{
}

int SHP_RW::Get_Point(XYZInfo& coordinate)
{
	OGRPoint *poPoint = (OGRPoint *)poGeometry;		//将几何结构转换成点类型
	coordinate.x = poPoint->getX();
	coordinate.y = poPoint->getY();
	coordinate.z = poPoint->getZ();
	return 0;
}

int SHP_RW::Get_LineString(vector<XYZInfo>& vecXYZ)
{
	OGRLineString* pLineGeo = (OGRLineString*)poGeometry;	//将几何结构转换成线类型
	int pointnums = pLineGeo->getNumPoints();
	XYZInfo tmpxyz;
	for (int i = 0; i < pointnums; i++)
	{
		tmpxyz.x = pLineGeo->getX(i);
		tmpxyz.y = pLineGeo->getY(i);
		tmpxyz.z = pLineGeo->getZ(i);
		vecXYZ.push_back(tmpxyz);
	}
	return 0;
}

//参数1是外环数据,是一个坐标名到坐标值vec的map,参数2是内环数据,比参数1多了一层编号映射
int SHP_RW::Get_Polygon(vector<XYZInfo>& OuterRing, vector<vector<XYZInfo>>& InteriorRing)
{
	OGRPolygon *poPolygon = (OGRPolygon *)poGeometry;	//将几何结构转换成多边形类型
	OGRLinearRing *pOGRLinearRing = poPolygon->getExteriorRing();
	//获取外环数据
	XYZInfo outring;
	for (int i = 0; i < pOGRLinearRing->getNumPoints(); i++)
	{
		outring.x = pOGRLinearRing->getX(i);
		outring.y = pOGRLinearRing->getY(i);
		outring.z = pOGRLinearRing->getZ(i);
		OuterRing.push_back(outring);
	}

	//获取内环数据(一个外环包含若干个内环)
	for (int i = 0; i < poPolygon->getNumInteriorRings(); i++)
	{
		vector<XYZInfo> Ringvec;
		pOGRLinearRing = poPolygon->getInteriorRing(i);
		for (int j = 0; j < pOGRLinearRing->getNumPoints(); j++)
		{
			XYZInfo intrring;
			intrring.x = pOGRLinearRing->getX(j);
			intrring.y = pOGRLinearRing->getY(j);
			intrring.z = pOGRLinearRing->getZ(j);
			Ringvec.push_back(intrring);
		}
		InteriorRing.push_back(Ringvec);
	}
	return 0;
}

//点集合
int SHP_RW::Get_MultiPoint(vector<XYZInfo> Points)
{
	OGRMultiPoint *poMultiPoint = (OGRMultiPoint *)poGeometry;		//将几何结构转换成点集合类型
	for (int i = 0; i < poMultiPoint->getNumGeometries(); i++)
	{
		OGRGeometry * geometry = poMultiPoint->getGeometryRef(i);	//根据下标获取点集合中的几何(点)结构
		OGRPoint *poPoint = (OGRPoint *)geometry;		//转换成点类型
		XYZInfo point;
		point.x = poPoint->getX();
		point.y = poPoint->getY();
		point.z = poPoint->getZ();
		Points.push_back(point);
	}
	return 0;
}

//线集合
int SHP_RW::Get_MultiLineString(vector<vector<XYZInfo>> Lines)
{
	OGRMultiLineString* poMultiLine = (OGRMultiLineString *)poGeometry;		//将几何结构转换成线集合类型
	for (int i = 0; i < poMultiLine->getNumGeometries(); i++)
	{
		vector<XYZInfo> Line;
		OGRGeometry * currtGeometry = poMultiLine->getGeometryRef(i);		//根据下标获取对应独立几何(线)结构
		OGRLineString* poLine = (OGRLineString*)currtGeometry;		//转换成线类型
		for (int j = 0; j < poLine->getNumPoints(); j++)
		{
			XYZInfo point;
			point.x = poLine->getX(j);
			point.y = poLine->getY(j);
			point.z = poLine->getZ(j);
			Line.push_back(point);
		}
		Lines.push_back(Line);
	}
	return 0;
}

//多边形集合
int SHP_RW::Get_MultiPolygon(vector<vector<XYZInfo>>& OuterRingVec, vector<vector<vector<XYZInfo>>>& InteriorRingVec)
{
	OGRMultiPolygon *MultiPolygon = (OGRMultiPolygon *)poGeometry;		//将几何结构转换成多边形集合类型
	int NumMPolygon = MultiPolygon->getNumGeometries();
	for (int k = 0; k < NumMPolygon; k++)
	{
		OGRGeometry * FirstGeometry = MultiPolygon->getGeometryRef(k);		//根据下标获取对应独立几何(多边形)结构
		OGRPolygon*poPolygon = (OGRPolygon *)FirstGeometry;			//转换成多边形类型
		OGRLinearRing *pOGRLinearRing = poPolygon->getExteriorRing();
		vector<XYZInfo> OuterRing;
		vector<vector<XYZInfo>> InnerRing;
		for (int i = 0; i < pOGRLinearRing->getNumPoints(); i++)
		{
			XYZInfo tmpinfo;
			tmpinfo.x = pOGRLinearRing->getX(i);
			tmpinfo.y = pOGRLinearRing->getY(i);
			tmpinfo.z = pOGRLinearRing->getZ(i);
			OuterRing.push_back(tmpinfo);
		}
		OuterRingVec.push_back(OuterRing);
		//获取内环数据(一个外环包含若干个内环)
		for (int i = 0; i < poPolygon->getNumInteriorRings(); i++)
		{
			vector<XYZInfo> InteriorRing;
			
			pOGRLinearRing = poPolygon->getInteriorRing(i);
			for (int j = 0; j < pOGRLinearRing->getNumPoints(); j++)
			{
				XYZInfo tmpinfo;
				tmpinfo.x = pOGRLinearRing->getX(i);
				tmpinfo.y = pOGRLinearRing->getY(i);
				tmpinfo.z = pOGRLinearRing->getZ(i);
				InteriorRing.push_back(tmpinfo);
			}
			InnerRing.push_back(InteriorRing);
		}
		InteriorRingVec.push_back(InnerRing);
	}

	return 0;
}

int SHP_RW::Get_GeometryCollection()
{
	return 0;
}


/* *************** 文件写入操作 ********************* */
int SHP_RW::Set_Point(int x, int y, int z, map<string, string> fieldvalue)
{
	OGRFeature *poFeature;
	if (poLayer == NULL)
		return -1;
	poFeature = OGRFeature::CreateFeature(poLayer->GetLayerDefn());
	// 根据提供的字段值map对相应字段赋值
	for (auto field : fieldvalue)
	{
		poFeature->SetField(field.first.c_str(), field.second.c_str());
	}
	OGRPoint point;
	point.setX(x);
	point.setY(y);
	point.setZ(z);
	poFeature->SetGeometry((OGRGeometry *)(&point));
	if (poLayer->CreateFeature(poFeature) != OGRERR_NONE)
	{
		printf("Failed to create feature in shapefile.\n");
		return -1;
	}
	OGRFeature::DestroyFeature(poFeature);

	return 0;
}

//线元素	结构体传参
int SHP_RW::Set_LineString(vector<XYZInfo> Line, map<string, string> fieldvalue)
{
	OGRFeature *poFeature;
	if (poLayer == NULL)
		return -1;
	poFeature = OGRFeature::CreateFeature(poLayer->GetLayerDefn());
	// 根据提供的字段值map对相应字段赋值
	for (auto field : fieldvalue)
	{
		poFeature->SetField(field.first.c_str(), field.second.c_str());
	}

	OGRLineString pLine;

	for (int i = 0; i < Line.size(); i++)
		pLine.addPoint(Line[i].x, Line[i].y, Line[i].z);

	poFeature->SetGeometry((OGRGeometry *)(&pLine));
	if (poLayer->CreateFeature(poFeature) != OGRERR_NONE)
	{
		printf("Failed to create feature in shapefile.\n");
		return -1;
	}


	OGRFeature::DestroyFeature(poFeature);

	return 0;
}

//线元素	参数分别为线要素上的点的x、y、z坐标的vector (z坐标可以没有)
int SHP_RW::Set_LineString(vector<double> vecX, vector<double> vecY, vector<double> vecZ, map<string, string> fieldvalue)
{
	OGRFeature *poFeature;
	if (poLayer == NULL)
		return -1;
	poFeature = OGRFeature::CreateFeature(poLayer->GetLayerDefn());
	// 根据提供的字段值map对相应字段赋值
	for (auto field: fieldvalue)
	{
		poFeature->SetField(field.first.c_str(), field.second.c_str());
	}

	OGRLineString pLine;
	if (vecX.size() == vecY.size())
	{
		if(vecY.size() == vecZ.size())
			for (int i = 0; i < vecX.size(); i++)
				pLine.addPoint(vecX[i], vecY[i], vecZ[i]);
		else if(vecZ.size() == 0)	//z坐标为空
			for (int i = 0; i < vecX.size(); i++)
				pLine.addPoint(vecX[i], vecY[i], 0);

		poFeature->SetGeometry((OGRGeometry *)(&pLine));
		if (poLayer->CreateFeature(poFeature) != OGRERR_NONE)
		{
			printf("Failed to create feature in shapefile.\n");
			return -1;
		}
	}
	else
		return -1;

	OGRFeature::DestroyFeature(poFeature);

	return 0;
}


// 多边形图层(可以无内环)
int SHP_RW::Set_Polygon(vector<XYZInfo> OuterRing,
						vector<vector<XYZInfo>> InteriorRingVec,
						map<string, string> fieldvalue)
{
	try
	{
		OGRFeature *poFeature;
		if (poLayer == NULL)
			return -1;
		poFeature = OGRFeature::CreateFeature(poLayer->GetLayerDefn());

		// 根据提供的字段值map对相应字段赋值
		for (auto field : fieldvalue)
		{
			poFeature->SetField(field.first.c_str(), field.second.c_str());
		}

		//polygon
		OGRPolygon polygon;
		// 外环
		OGRLinearRing ringOut;
		for (int i = 0; i < OuterRing.size(); i++)
		{
			ringOut.addPoint(OuterRing[i].x, OuterRing[i].y, OuterRing[i].z);
		}
		//结束点应和起始点相同,保证多边形闭合
		ringOut.closeRings();
		polygon.addRing(&ringOut);

		// 内环
		for (int i = 0; i < InteriorRingVec.size(); i++)
		{
			OGRLinearRing ringIn;
			for (int j = 0; j < InteriorRingVec[i].size(); j++)
			{
				ringIn.addPoint(InteriorRingVec[i][j].x, InteriorRingVec[i][j].y, InteriorRingVec[i][j].z);
			}
			ringIn.closeRings();
			polygon.addRing(&ringIn);
		}

		poFeature->SetGeometry((OGRGeometry *)(&polygon));
		if (poLayer->CreateFeature(poFeature) != OGRERR_NONE)
		{
			printf("Failed to create feature in shapefile.\n");
			return -1;
		}

		OGRFeature::DestroyFeature(poFeature);

		return 0;
	}
	catch (std::exception&e)
	{
		//LogInfo(FormatLogStr("E", "ImageShp-> " + string(e.what()) + "!"));
		return -1;
	}
}


int SHP_RW::Set_MultiPoint()
{
	return 0;
}

int SHP_RW::Set_MultiLineString()
{
	return 0;
}

int SHP_RW::Set_MultiPolygon()
{
	return 0;
}

int SHP_RW::Set_GeometryCollection()
{
	return 0;
}

//创建属性字段
int SHP_RW::SetFieldDefn(vector<string> fieldname, vector<OGRFieldType> fieldtype, vector<int> fieldwidth)
{
	for (int i = 0; i < fieldname.size(); i++)
	{
		OGRFieldDefn Field(fieldname[i].c_str(), fieldtype[i]);	//创建字段 字段+字段类型
		Field.SetWidth(fieldwidth[i]);		//设置字段宽度,实际操作需要根据不同字段设置不同长度
		poLayer->CreateField(&Field);
	}
	return 0;
}
/* *************** 文件写入操作 ********************* */

读写shp的示例代码

#include <iostream>
#include <gdal.h>
#include <gdal_priv.h>
#include <ogrsf_frmts.h>
#include "SHP_RW.h"
#include <streambuf>
#include <fstream>
#include <ctype.h>
#include <math.h>
#include <iomanip>

using namespace std;

//读shp文件
int shpread(const char* file_path_name)
{
	CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");	// 支持中文路径
	CPLSetConfigOption("SHAPE_ENCODING", "");			//属性表支持中文字段


	GDALAllRegister();

	GDALDataset *poDS = (GDALDataset*)GDALOpenEx(file_path_name, GDAL_OF_VECTOR, NULL, NULL, NULL);
	if (poDS == NULL)
	{
		printf("Open failed.\n");
		exit(1);
	}
	cout << "Open successfully!" << endl;

	
	//获取图层数量
	cout << "<--------获取图层数量-------->" << endl;
	int LayerCount = poDS->GetLayerCount();
	cout << "图层数量: " << LayerCount << endl;

	//获取shp图层
	cout << "<--------获取shp图层-------->" << endl;
	OGRLayer  *poLayer = poDS->GetLayer(0);  //	 根据序号获取相应shp图层,这里表示第一层
	//OGRLayer  *poLayer = poDS->GetLayerByName("point");		//根据名称获取相应图层

	//获取当前图层的属性表结构
	cout << "<--------获取当前图层的属性表结构-------->" << endl;
	OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn();

	//重置要素读取顺序
	cout << "<--------重置要素读取顺序-------->" << endl;
	poLayer->ResetReading();	// ResetReading() 函数功能为把要素读取顺序重置为从第一个开始

	//设置要素指针
	cout << "<--------设置要素指针-------->" << endl;
	OGRFeature *poFeature;		//用于获取图层上的要素

    //创建文件存放数据
        string shpname = string(file_path_name).substr(string(file_path_name).find_last_of("/") + 1);
	shpname = shpname.substr(0, shpname.find_last_of(".")) + "_";
	string attrfile = "D:/output/" + shpname + "attrfile_shp.txt";			// 属性文件
	string datafile = "D:/output/" + shpname + "datafile_shp.txt";			// 数据文件
	cout << attrfile << ' ' << datafile << endl;
	fstream tmpfile(attrfile, ios::out);
	fstream tmpdatafile(datafile, ios::out);

	
	int num = 0;		//用于标记第几个要素

	while ((poFeature = poLayer->GetNextFeature()) != NULL)
	{
		cout << "图层属性->" << endl;

		for (int iField = 0; iField < poFDefn->GetFieldCount(); iField++)
		{
			OGRFieldDefn *poFieldDefn = poFDefn->GetFieldDefn(iField);

			cout << poFieldDefn->GetNameRef() << ": ";		// 属性表字段名
			switch (poFieldDefn->GetType())			// 不同数据类型按不同方式,根据字段号获取相应字段的数据
			{
			case OFTInteger:
				printf("%d,", poFeature->GetFieldAsInteger(iField));
				tmpfile << poFeature->GetFieldAsInteger(iField) << "\t";		// 写入文件
				break;
			case OFTInteger64:
				printf(CPL_FRMT_GIB ",", poFeature->GetFieldAsInteger64(iField));
				tmpfile << poFeature->GetFieldAsInteger64(iField) << "\t";		// 写入文件
				break;
			case OFTReal:
				printf("%.3f,", poFeature->GetFieldAsDouble(iField));
				tmpfile << poFeature->GetFieldAsDouble(iField) << "\t";		// 写入文件
				break;
			case OFTString:
				printf("%s,", poFeature->GetFieldAsString(iField));
				tmpfile << poFeature->GetFieldAsString(iField) << "\t";		// 写入文件
				break;
			default:
				printf("%s,", poFeature->GetFieldAsString(iField));
				tmpfile << poFeature->GetFieldAsString(iField) << "\t";		// 写入文件
				break;
			}
			/*printf("\n");*/
		}
		tmpfile << endl;


		OGRGeometry *poGeometry = poFeature->GetGeometryRef();
		//判断当前要素的几何类型,是否为点图层,利用 getGeometryType() 函数获取要素类型
		SHP_RW geo;
		geo.poGeometry = poGeometry;

		if (poGeometry != NULL)	
		{	
			auto GeometryType = wkbFlatten(poGeometry->getGeometryType());	// getGeometryType() 返回的类型可能会有2.5D类型,通过宏 wkbFlatten 转换为2D类型
				if (GeometryType == wkbPoint)		// 1
				{
					//cout << "点图层要素" << endl;
					XYZInfo Point;
					geo.Get_Point(Point);
					//printf("X= %.3f, Y= %.3f, Z= %.3f\n", staX, staY, staZ);
					tmpdatafile << Point.x << "\t" << Point.y << "\t" << Point.z << endl;		// 写入文件
				}
				else if (GeometryType == wkbLineString)		// 2
				{
					vector<XYZInfo> Line;
					tmpdatafile << "<----- 第" + to_string(1 + num++) + "个要素(线) ---->" << endl;
					geo.Get_LineString(Line);
					for (int i = 0; i < Line.size(); i++)
						//printf("X= %.3f, Y= %.3f, Z= %.3f\n", vecX[i], vecY[i], vecZ[i]);
						tmpdatafile << Line[i].x << "\t" << Line[i].y << "\t" << Line[i].z << endl;		// 写入文件
				}
				else if (GeometryType == wkbPolygon)		// 3
				{
					//cout << "多边形图层要素" << endl;
					vector<XYZInfo> OuterRing;
					vector<vector<XYZInfo>> InteriorRing;
					geo.Get_Polygon(OuterRing, InteriorRing);

					// 将数据写入文件
					tmpdatafile << "<----- 第" + to_string(1 + num++) + "个要素(多边形) ---->" << endl;
					tmpdatafile << "外环数据" << endl;
					//cout << "数据个数:" << OuterRing.size() << endl;
					for (int j = 0; j < OuterRing.size(); j++)
					{
						tmpdatafile << OuterRing[j].x << "\t" << OuterRing[j].y << "\t" << OuterRing[j].z << endl;		// 写入文件
					}

					tmpdatafile << "内环数据" << endl;
					for (int i = 0; i < InteriorRing.size(); i++)
					{
						for (int k = 0; k < InteriorRing[i].size(); k++)
							tmpdatafile << InteriorRing[i][k].x << "\t" << InteriorRing[i][k].y << "\t" << InteriorRing[i][k].z << endl;		// 写入文件
						tmpdatafile << endl;
					}
				}
				else if (GeometryType == wkbMultiPoint)		// 4
				{
					//cout << "点集合图层要素" << endl;
					vector<XYZInfo> Points;
					geo.Get_MultiPoint(Points);

					//将文件写入文件
					tmpdatafile << "<----- 第" + to_string(1 + num++) + "个要素(点集合) ---->" << endl;
					for (int i = 0; i < Points.size(); i++)
					{
						tmpdatafile << Points[i].x << "\t" << Points[i].y << "\t" << Points[i].z << endl;		// 写入文件
					}
				}
				else if (GeometryType == wkbMultiLineString)	// 5
				{
					//cout << "线集合图层要素" << endl;
					vector<vector<XYZInfo>> Lines;
					geo.Get_MultiLineString(Lines);
					//将文件写入文件
					tmpdatafile << "<----- 第" + to_string(1 + num++) + "个要素(线集合) ---->" << endl;
					for (int i = 0; i < Lines.size(); i++)
					{
						tmpdatafile << "线" + to_string(1 + i) << endl;
						for (int j = 0; j < Lines[i].size(); j++)
						{
							tmpdatafile << Lines[i][j].x << "\t" << Lines[i][j].y << "\t" << Lines[i][j].z << endl;		// 写入文件
						}
					}
				}
				else if (GeometryType == wkbMultiPolygon)		// 6
				{
					//cout << "多边形集合图层要素" << endl;
					//获取数据
					vector<vector<XYZInfo>> OuterRingVec;
					vector<vector<vector<XYZInfo>>> InteriorRingVec;
					geo.Get_MultiPolygon(OuterRingVec, InteriorRingVec);

					// 将数据写入文件
					OGRMultiPolygon *MultiPolygon = (OGRMultiPolygon *)poGeometry;
					int NumMPolygon = MultiPolygon->getNumGeometries();
					vector<XYZInfo> xyz;
					tmpdatafile << "<----- 第" + to_string(1 + num++) + "个要素(多边形集合) ---->" << endl;
					for (int k = 0; k < OuterRingVec.size(); k++)
					{
						tmpdatafile << "外环" + to_string(k) << endl;
						for (int j = 0; j < OuterRingVec[k].size(); j++)
						{
							tmpdatafile << OuterRingVec[k][j].x << "\t" << OuterRingVec[k][j].y << "\t" << OuterRingVec[k][j].z << endl;		// 写入文件
						}

						for (int i = 0; i < InteriorRingVec[k].size(); i++)
						{
							tmpdatafile << "内环" + to_string(i+1) << endl;
							for (int j = 0; j < InteriorRingVec[k][i].size(); j++)
								tmpdatafile << InteriorRingVec[k][i][j].x << "\t" << InteriorRingVec[k][i][j].y << "\t" << InteriorRingVec[k][i][j].z << endl;		// 写入文件
						}
						tmpdatafile << endl;
					}
				}
			else if (GeometryType == wkbGeometryCollection)		// 7
			{
				cout << "几何体集合图层要素" << endl;
			}
			else if (GeometryType == wkbNone)
			{
				cout << "该数据只有属性表" << endl;
			}

		}
		else
		{
			printf("no  geometry\n");
		}
		OGRFeature::DestroyFeature(poFeature);
	}
	tmpfile.close();

	GDALClose(poDS);
	return 0;

}


// 写shp文件
int shpwrite(const char* file_path_name)
{
	CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");	// 支持中文路径
	CPLSetConfigOption("SHAPE_ENCODING", "");			//属性表支持中文字段

	//注册所有驱动
	OGRRegisterAll();
	const char *pszDriverName = "ESRI Shapefile";
	GDALDriver *poDriver;
	poDriver = GetGDALDriverManager()->GetDriverByName(pszDriverName);
	if (poDriver == NULL)
	{
		printf("%s driver not available.\n", pszDriverName);
		return 0;
	}

	//创建数据源
	GDALDataset *poDS;
	poDS = poDriver->Create(file_path_name, 0, 0, 0, GDT_Unknown, NULL); //创建shp文件
	if (poDS == NULL)
	{
		printf("Creation of output file failed.\n");
		return 0;
	}


	OGRLayer *poLayer;
	SHP_RW write_shp;
	//OGRwkbGeometryType layertype;
	//layertype = wkbPolygon;
	string layertype = "多边形";
	vector<string> fieldname = { "ID", "NAME", "VALUE" };
	vector<OGRFieldType> fieldtype = { OFTInteger, OFTString, OFTReal };
	vector<int> fieldwidth = { 32, 32, 32 };

	if (layertype == "点")
	{
		// 创建图层,这里没有指定空间参考,如果需要的话,需要在这里进行指定
		poLayer = poDS->CreateLayer("point_out", NULL, wkbPoint, NULL);
		write_shp.poLayer = poLayer;
		write_shp.SetFieldDefn(fieldname, fieldtype, fieldwidth);
		map<string, string> testpoint = { {"ID", "1"}, {"NAME", "FFF"},{"VALUE", "1"} };	// 属性值
		write_shp.Set_Point(100,30, 0, testpoint);	
		//write_shp.Set_Point(100, 30);		// 没有z坐标或属性值可以不传入
	}
	else if (layertype == "线")
	{
		poLayer = poDS->CreateLayer("string_out", NULL, wkbLineString, NULL);
		write_shp.poLayer = poLayer;
		write_shp.SetFieldDefn(fieldname, fieldtype, fieldwidth);
		//vector<double> xvec = { 100, 30 }, yvec = { 101, 30 }, zvec;	//线上的点的x、y、z坐标的集合, 根据需求自己进行赋值
		vector<XYZInfo> Line = { {100, 30},{101, 30} };
		map<string, string> testline = { {"ID", "2"}, {"NAME", "FFF"},{"VALUE", "2"} };	// 属性值
		write_shp.Set_LineString(Line, testline);
		//write_shp.Set_LineString(xvec, yvec);		// 没有z坐标或属性值可以不传入

	}
	else if (layertype == "多边形")
	{
		poLayer = poDS->CreateLayer("polygon_out", NULL, wkbPolygon, NULL);
		write_shp.poLayer = poLayer;
		write_shp.SetFieldDefn(fieldname, fieldtype, fieldwidth);
		vector<XYZInfo> OuterRing;
		vector<vector<XYZInfo>> InteriorRing;
		map<string, string> testpolygon = { {"ID", "3"}, {"NAME", "FFF"},{"VALUE", "3"} };	// 属性值
		write_shp.Set_Polygon(OuterRing, InteriorRing, testpolygon);
		//write_shp.Set_Polygon(OuterRing); // 内环和属性值没有的话可以不传入
	}
	else if (layertype == "点集合")
	{

	}
	else if (layertype == "线集合")
	{

	}
	else if (layertype == "多边形集合")
	{

	}


	GDALClose(poDS);

	return 0;
}


int main()
{
    shpread("D:/originshp/tmppath/0806.shp");
    system("pause");

    return 0;
}
发布了85 篇原创文章 · 获赞 61 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/Leo_csdn_/article/details/99737706
今日推荐