#include <iostream>
#include <gdal.h>
#include <gdal_priv.h>
#include <ogrsf_frmts.h>
#include "shp_reader_writer.h"
#include <streambuf>
#include <fstream>
#include <ctype.h>
#include <math.h>
#include <iomanip>
#include <QFileDialog>
#include <QApplication>
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, nullptr, nullptr, nullptr);
if (poDS == nullptr)
{
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; //用于标记第几个要素
int feature_index = 0;
while ((poFeature = poLayer->GetNextFeature()) != nullptr)
{
cout <<"\r\n\r\n" <<feature_index++ << " 图层属性---------------->" << endl;
cout << "FieldCount->" << poFDefn->GetFieldCount()<< endl;
for (int iField = 0; iField < poFDefn->GetFieldCount(); iField++)
{
OGRFieldDefn *poFieldDefn = poFDefn->GetFieldDefn(iField);
cout << "field " << iField << " type=" << poFieldDefn->GetType() << "-->";
cout << poFieldDefn->GetNameRef() << ": "; // 属性表字段名
switch (poFieldDefn->GetType()) // 不同数据类型按不同方式,根据字段号获取相应字段的数据
{
case OFTInteger:
//printf("%d,", poFeature->GetFieldAsInteger(iField));
cout << poFeature->GetFieldAsInteger(iField) << "\t"; // 写入文件
break;
case OFTInteger64:
//printf(CPL_FRMT_GIB ",", poFeature->GetFieldAsInteger64(iField));
cout << poFeature->GetFieldAsInteger64(iField) << "\t"; // 写入文件
break;
case OFTReal:
//printf("%.3f,", poFeature->GetFieldAsDouble(iField));
cout << poFeature->GetFieldAsDouble(iField) << "\t"; // 写入文件
break;
case OFTString:
//printf("%s,", poFeature->GetFieldAsString(iField));
cout << poFeature->GetFieldAsString(iField) << "\t"; // 写入文件
break;
default:
//printf("%s,", poFeature->GetFieldAsString(iField));
cout << poFeature->GetFieldAsString(iField) << "\t"; // 写入文件
break;
}
printf("\n");
}
cout << endl;
OGRGeometry *poGeometry = poFeature->GetGeometryRef();
//判断当前要素的几何类型,是否为点图层,利用 getGeometryType() 函数获取要素类型
shp_reader_writer geo;
geo.poGeometry = poGeometry;
if (poGeometry != nullptr)
{
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);
cout << Point.x << "\t" << Point.y << "\t" << Point.z << endl; // 写入文件
}
else if (GeometryType == wkbLineString) // 2
{
vector<XYZInfo> Line;
cout << "<----- 第" + 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]);
cout << 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);
// 将数据写入文件
cout << "<----- 第" + to_string(1 + num++) + "个要素(多边形) ---->" << endl;
cout << "外环数据" << endl;
//cout << "数据个数:" << OuterRing.size() << endl;
for (int j = 0; j < OuterRing.size(); j++)
{
cout << OuterRing[j].x << "\t" << OuterRing[j].y << "\t" << OuterRing[j].z << endl; // 写入文件
}
cout << "内环数据" << endl;
for (int i = 0; i < InteriorRing.size(); i++)
{
for (int k = 0; k < InteriorRing[i].size(); k++)
cout << InteriorRing[i][k].x << "\t" << InteriorRing[i][k].y << "\t" << InteriorRing[i][k].z << endl; // 写入文件
cout << endl;
}
}
else if (GeometryType == wkbMultiPoint) // 4
{
//cout << "点集合图层要素" << endl;
vector<XYZInfo> Points;
geo.Get_MultiPoint(Points);
//将文件写入文件
cout << "<----- 第" + to_string(1 + num++) + "个要素(点集合) ---->" << endl;
for (int i = 0; i < Points.size(); i++)
{
cout << 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);
//将文件写入文件
cout << "<----- 第" + to_string(1 + num++) + "个要素(线集合) ---->" << endl;
for (int i = 0; i < Lines.size(); i++)
{
cout << "线" + to_string(1 + i) << endl;
for (int j = 0; j < Lines[i].size(); j++)
{
cout << 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;
cout << "<----- 第" + to_string(1 + num++) + "个要素