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

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

247
247
2022-08-30 / 0 评论 / 87 阅读 / 正在检测是否收录...

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

头文件shprw.h


#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文件 shprw.cpp

#include "shprw.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;
}
/* *************** 文件写入操作 ********************* */

读写示例

#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("1.shp");
    system("pause");
 
    return 0;
}
0

评论 (0)

取消