1. 编译proj高版本时,会发现proj.lib库是静态库,如果不配置环境变量,会出现以下错误:
1)报错
2)gdal库中的OGRCreateCoordinateTransformation方法,创建对象失败
解决方法:
找到proj.db文件,需要设置用户变量。
2. 使用gdal时候,需要设置环境变量,必须指定到data文件夹所在路径;
3. 从gdal2.0升级到gdal3.0在使用上的变化;
1)API变化
- SRS_WKT_WGS84宏定义被替换为SRS_WKT_WGS84_LAT_LONG;
- 空间参考类添加函数
OSRSetPROJSearchPaths(),
OSRExportToWktEx(),
OSRGetName(),
OSRIsSameEx(),
OSRGetCRSInfoListFromDatabase(),
OSRGetAreaOfUse(),
OSRGetAxisMappingStrategy(),
OSRSetAxisMappingStrategy(),
OSRGetDataAxisToSRSAxisMapping();
- 坐标转换类添加函数
OCTCoordinateTransformationOptionsSetOperation(),
OCTCoordinateTransformationOptionsSetAreaOfInterest(),
OCTDestroyCoordinateTransformationOptions(),
OCTNewCoordinateTransformationEx(),
OCTTransform4D();
- 移除函数
OSRFixupOrdering(),
OSRFixup(),
OSRStripCTParms(),
OCTProj4Normalize(),
OCTCleanupProjMutex(),
OPTGetProjectionMethods(),
OPTGetParameterList(),
OPTGetParameterInfo()
2)空间参考定义
空间参考定义由于GDAL3.0以后的版本依赖的PROJ库必须是6.0+的版本,而且是必须依赖,不像以前的版本proj库可以动态加载,在编译GDAL是不需要PROJ库也可以,但是3.0以后的版本就不行了,编译GDAL的时候必须要有PROJ6.0以上的版本才可以。
这样就会引入一个问题,由于PROJ6里面需要proj.db数据库的支持,这样的话,在GDAL库使用的话也需要proj.db的支持,否则定义空间参考时会报错。proj.db文件默认会在proj.dll所在目录的proj文件夹中找,也可以通过函数OSRSetPROJSearchPaths()来设置proj.db的所在目录。
空间参考定义部分,基本上没有发生大的变化,如果通过SRS_WKT_WGS84宏来定义WGS84椭球的话,需要改为SRS_WKT_WGS84_LAT_LONG宏来进行定义。
3)坐标转换
坐标转换时空间参考的定义必须使用函数SetAxisMappingStrategy来设置坐标轴对应策略,否则坐标转换会失败。下面两份代码分别是之前的版本和3.0以后的版本进行坐标转换的写法。
/=====================================gdal2.0++版本=====================================/
#include "PCSTransform.h"
#include <ogr_spatialref.h>
GDALAllRegister();
OGRRegisterAll();
OGRSpatialReference mOGRSourceSRS;
OGRSpatialReference mOGRTargetSRS;
OGRErr err1 = mOGRSourceSRS.importFromEPSG(sourceESPG);
OGRErr err2 = mOGRTargetSRS.importFromEPSG(targetESPG);
GRCoordinateTransformation *pOGRCT = OGRCreateCoordinateTransformation(&mOGRSourceSRS, &mOGRTargetSRS);
double x = 经度;
double y = 纬度;
double z = 高度;
if (pOGRCT == NULL || !pOGRCT->Transform(1, &x, &y, &z))
{
std::cout << "Transformation failed" << std::endl;
}
/=====================================gdal3.0++版本=====================================/
#include "PCSTransform.h"
#include <ogr_spatialref.h>
GDALAllRegister();
OGRRegisterAll();
OGRSpatialReference mOGRSourceSRS;
OGRSpatialReference mOGRTargetSRS;
OGRErr err1 = mOGRSourceSRS.importFromEPSG(sourceESPG);
OGRErr err2 = mOGRTargetSRS.importFromEPSG(targetESPG);
mOGRSourceSRS.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);//gdal3.0开始需要添加这个
mOGRTargetSRS.SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);//gdal3.0开始需要添加这个
GRCoordinateTransformation *pOGRCT = OGRCreateCoordinateTransformation(&mOGRSourceSRS, &mOGRTargetSRS);
double x = 经度;
double y = 纬度;
double z = 高度;
if (pOGRCT == NULL || !pOGRCT->Transform(1, &x, &y, &z))
{
std::cout << "Transformation failed" << std::endl;
}
4. shp另存为geojson - new line delimited 格式文件
必须使用gdal2.4以上版本
GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GeoJSONSeq");
// 将shp文件转化为json - Newline Delimited文件输出
void parseShpfile2GeojsonFile(char *inFileName, char *outFileName) {
GDALAllRegister();// 注册驱动
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");// 支持中文路径
CPLSetConfigOption("SHAPE_ENCODING", "");// 属性表字段支持中文
GDALDataset *poSrcDS = (GDALDataset *)GDALOpenEx(inFileName, GDAL_OF_VECTOR, NULL, NULL, NULL);// 打开文件,读取数据
// 判断是否读取成功
if (poSrcDS == NULL)
{
std::cout << "未能成功读取!" << std::endl;
return;
}
// json驱动
// gdal必须要用大于等于2.4的版本
GDALDriver* poDriver = GetGDALDriverManager()->GetDriverByName("GeoJSONSeq");
// 复制shp文件到指定输出的json文件
GDALDataset* poDstDS = poDriver->CreateCopy(outFileName, poSrcDS, FALSE, NULL, NULL, NULL);
//int count = GetGDALDriverManager()->GetDriverCount();
//for (size_t i = 0; i < count; i++)
//{
// std::string s = GetGDALDriverManager()->GetDriver(i)->GetDescription();
// std::cout << s << std::endl;
//}
//释放内存
if (poDstDS != NULL)
GDALClose((GDALDatasetH)poDstDS);
GDALClose((GDALDatasetH)poSrcDS);
}