Wechat: yu389741| Email: gisdqy@163.com

Shop:https://www.giserdqy.com/shop

GDAL2.x读取shp文件



楼主之前一直用的GDAL 1.x来读取的矢量数据和栅格数据,但是发现转到GDAL 2.x上以后,原来的代码就不能用了T_T,也是折腾了一下午才弄明白,原来2.x和1.x在接口上发生了一些变化,主要是获取layer和销毁数据集接口的变化。这篇博客讲的是用GDAL2.x读取面状shp文件。

由于楼主是做面向对象遥感影像分类的,读的shp文件的属性主要包含了类别名称ClassName和一系列的特征值,所以采用一种自定义的结构体来存储每一条记录。

struct DataSet
{
    string className;
    int FID;
    vector<double> dataValue;   
};

下面开始读shp文件

//读取数据的函数
//输入:lpszPathName--文件路径,isNormalized--数据是否需要归一化,1表示是,0表示否
//读到的数据存储在容器vFeatureData中
vector<DataSet> LoadDataSource(const char * lpszPathName, bool isNormalized)
{
    vector<DataSet> vFeatureData;//存储所有数据
    GDALAllRegister();
    CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");//设置中文路径
    GDALDataset *poDS;
    poDS = (GDALDataset*)GDALOpenEx(lpszPathName, GDAL_OF_VECTOR, NULL, NULL, NULL);
    if (poDS == NULL)
    {
        exit(1);
    }
    OGRLayer  *poLayer;
    poLayer = poDS->GetLayer(0);
    if (poLayer==NULL)
    {
        exit(1);
    }
    //读取几何和属性值

    int iFieldCount;//特征数
    //图层初始化
    poLayer->ResetReading();
    //属性表结构信息
    OGRFeatureDefn *poDeFn = poLayer->GetLayerDefn();
    iFieldCount = poDeFn->GetFieldCount();//特征个数
    for (int iAttr = 0; iAttr < iFieldCount; iAttr++)
    {
        OGRFieldDefn *poFieldDefn = poDeFn->GetFieldDefn(iAttr);
        if (poFieldDefn->GetNameRef() == "Class_name")
        {
            break;
        }
        FeatureName.push_back(poFieldDefn->GetNameRef());//特征名
    }
    OGRFeature *poFeature = NULL;
    while ((poFeature = poLayer->GetNextFeature()) != NULL)
    {
        // 获取要素中的属性表内容      
        DataSet dataSet_temp;//存储当前记录
        dataSet_temp.FID = poFeature->GetFID();
        vector <double> v_temp;
        v_temp.clear();
        for (int iField = 0; iField<iFieldCount; iField++)
        {
            OGRFieldDefn *poFieldDefn = poDeFn->GetFieldDefn(iField);
            const char *str = poFieldDefn->GetNameRef();
            OGRFieldType type = poFieldDefn->GetType();
            switch (type)
            {
            case OFTString:
                dataSet_temp.className = poFeature->GetFieldAsString(iField);
                break;
            default:
                v_temp.push_back(poFeature->GetFieldAsDouble(iField));
                break;
            }
        }

        vFeatureData.push_back(dataSet_temp);
        // 获取要素中的几何体
        OGRGeometry *poGeometry = poFeature->GetGeometryRef();
    }
    if (isNormalized == TRUE)//数据需要做归一化
    {
        //求各个特征最大最小值
        vector<double> min_data;
        vector<double> max_data;
        //为最大最小值赋初值
        for (int i = 0; i < vFeatureData.at(0).dataValue.size(); i++)
        {
            min_data.push_back(vFeatureData.at(0).dataValue.at(i));
            max_data.push_back(vFeatureData.at(1).dataValue.at(i));
        }
        for (int i = 0; i < vFeatureData.size(); i++)
        {
            for (int j = 0; j < vFeatureData.at(0).dataValue.size(); j++)
            {
                if (vFeatureData.at(i).dataValue.at(j) < min_data.at(j))
                    min_data.at(j) = vFeatureData.at(i).dataValue.at(j);
                if (vFeatureData.at(i).dataValue.at(j) > max_data.at(j))
                    max_data.at(j) = vFeatureData.at(i).dataValue.at(j);
            }
        }
        //计算归一化参数

        for (int i = 0; i < min_data.size(); i++)
        {
            a.push_back(1.0 / (max_data.at(i) - min_data.at(i)));
            b.push_back(-a.at(i)*min_data.at(i));
        }
        //释放不要的内存
        max_data.clear();
        vector<double>(max_data).swap(max_data);
        min_data.clear();
        vector<double>(min_data).swap(max_data);
        //数据归一化
        for (int i = 0; i < vFeatureData.size(); i++)
        {
            for (int j = 0; j < vFeatureData.at(0).dataValue.size(); j++)
            {
                vFeatureData.at(i).dataValue.at(j) = (a.at(j)*vFeatureData.at(i).dataValue.at(j) + b.at(j));
            }
        }
    }   
    GDALClose(poDS);
    return vFeatureData;
}

转载自:https://blog.csdn.net/ZMT1849101245/article/details/73188180