WIN10 VS2019下编译GDAL3.0+PROJ6+SQLite
2019-07-04 10:38
531 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_42141589/article/details/94357199
编译和安装 测试程序
WIN10 VS2019下编译GDAL3.0+PROJ6+SQLite
准备
- GDAL3.0编译要求PROJ6投影库,而PROJ6又要求SQLite3环境,所以在编译GDAL之前我们需要先编译好SQLite和PROJ6.
下载
- 下载库
GDAL官方下载地址为https://gdal.org/download.html,我下载的版本是gdal-3.0.0
;PROJ6的官方下载地址为https://proj.org/download.html,我现在的版本为6.1.0
版本;SQLite3的官方下载地址为https://www.sqlite.org/download.html,下载Source Code下的sqlite-amalgamation-3280000.zip
,和Precompiled Binaries for Windows下的sqlite-dll-win32-x86-3280000.zip
sqlite-tools-win32-x86-3280000.zip
为了方便编译,我将下载的三个文件分别解压在F盘的根目录GDAL、PROJ、SQLite文件夹内,以备后用。 - 工具下载
cmake官方下载地址为https://cmake.org/download/,下载cmake-3.15.0-rc3-win64-x64.msi
文件直接载windows上安装,之后添加环境变量,以便在cmd命令行中使用。详细方法 - 懒人包
我编译好的版本静态库debug版、静态库release版、动态库debug版、动态库release版。
编译和安装
1. 静态编译SQLite库
可以按照文章的步骤进行编译。我在此重复一遍。
- 解压
将下载好的两个文件sqlite-amalgamation-3280000.zip
、和sqlite-dll-win32-x86-3280000.zip
解压到SQLite文件夹内,如下所示:
F:. ├─sqlite-amalgamation-3280000 │ shell.c │ sqlite3.c │ sqlite3.h │ sqlite3ext.h │ └─sqlite-dll-win64-x64-3280000 sqlite3.def sqlite3.dll
- 创建静态库工程
- 在SQLite目录下创建一个新工程
- 选好工程创建位置之后,将
sqlite3.c
、sqlite3.h
、sqlite3ext.h
、sqlite3.def
四个文件添加到工程中,如下图所示: - C/C++ --> 预处理器 --> 预处理器定义:设置预定义处理
_USRDLL
SQLITE_ENABLE_RTREE
SQLITE_ENABLE_COLUMN_METADATA
SQLITE_ENABLE_FTS5
SQLITE_ENABLE_UNLOCK_NOTIFY
- 设置模块定义文件,链接器 --> 输入 --> 模块定义文件:
sqlite3.def
- 修改模块定义文件:在最后追加sqlite3_unlock_notify
- 配置类型改为静态库lib
- 最后生成解决方案(需要生成debug版时,选择debug,这里一release版为例),在
F:\SQLite\SQLite3\x64\Release
文件夹可以看到SQLite3.lib静态库和SQLite3.exe(debug版在F:\SQLite\SQLite3\x64\Release
文件夹中)。
在SQLite目录中分别创建include
和lib
和bin
文件夹,将刚才生成的.lib文件放入lib
文件夹中,将sqlite3.h
、sqlite3ext.h
放入include
中,将sqlite-tools-win32-x86-3280000.zip
中的sqlite3.exe放在bin
文件夹中以备后用。
2. 编译PROJ6
- 解压
将下载好的proj-6.1.0
解压到PROJ文件夹内。 - 编译PROJ6
- 进入库文件夹中,在源码目录中创建
build
文件夹,打开cmake - 点击Configure,编译64位,vs2019
- 会出现一些错误,如图
- 这时找到
Name
为EXE_SQLITE3
、SQLITE3_INCLUDE_DIR
和SQLITE3_LIBRARY
三个属性,可以看到现在它们的Value
值都为NOTFOUND的状态,我们将SQLite3.exe
、include
和SQLite3.lib
的路径分别赋给它们。
并设置文件生成目录,我设置的是c:/OSGeo4W。
- 重新点击Configure,提示Configuring done。点击Generate,这时可以看到
build
文件夹里有PROJ4.sln。打开x64 Native Tools Command Prompt for VS 2019
(一般在开始菜单安装VS2019的文件夹里就能看到),进入build文件夹, - 然后输入命令
msbuild ALL_BUILD.vcxproj /p:Configuration="Release" msbuild INSTALL.vcxproj /p:Configuration="Release"
- 开启编译(编译debug版是将引号里面的Release改为Debug)。
- 这时可以在设置的文件生成目录中找到生成的文件
bin
中有各种*.exe
文件、include
中放有头文件、lib
中是静态库文件、share
放有一些数据文件。到此PROJ编译完成。
3. 编译GDAL
- 解压
将下载好的GDAL3.0.0
解压到GDAL
文件夹内。 - 编译GDAL
首先简单了解一下nmake.opt
文件中变量的意义(链接):
项目 | Value |
---|---|
MSVC_VER | 编译器版本 |
WIN64 | 是否编译64位版本 |
GDAL_HOME | 生成文件的目录 |
DLLBUILD | 是否动态编译 |
进入库文件夹中,找到
nmake.opt文件,用VS2019打开。
- 第41行左右,找到
MSVC_VER=
设置为1921
(VS2019版本应该为1920及以上,视自己编译器而定)。 - 第57行左右找到
GDAL_HOME =
将生成文件的路径设置成你想要的位置,我这里设置成"F:\warmerda_release"
。 - 第194行左右找到
WIN64=YES
,如果生成64位版本取消注释本行。 - 第218行左右找到
DLLBUILD=
设置为1
启动动态编译、0
为静态编译。我这里进行静态编译设置DLLBUILD=0
。 - 第238行左右,找到
PROJ_INCLUDE
PROJ_LIBRARY
,分别设置成你刚才生成PROJ时的include
和lib
文件夹(其中PROJ_INCLUDE
的-I
后为地址),并将.lib的名称改对。 - 第509行左右,找到
SQLITE_INC
SQLITE_LIB
,路径设置同上。
至此设置完成,保存文件。
打开x64 Native Tools Command Prompt for VS 2019
进入库文件夹,输入命令:
nmake /f makefile.vc nmake /f makefile.vc devinstall
debug版输入
nmake /f makefile.vc DEBUG=1 nmake /f makefile.vc devinstall
进行编译和安装,完毕后可以在生成文件夹找到5个文件夹
完成!
测试程序
下面几个程序来源于网络,可以作为测试程序验证库是否可用。
库的引用设置可以参考博客
#include "gdal_priv.h" #include<iostream> using namespace std; int main() { const char* pszFile; GDALAllRegister(); pszFile = "F://2.jpg"; GDALDataset *poDataset = (GDALDataset*)GDALOpen(pszFile, GA_ReadOnly); GDALRasterBand *poBand = poDataset->GetRasterBand(1); int xsize = poBand->GetXSize(); int ysize = poBand->GetYSize(); cout << xsize << endl; cout << ysize << endl; return 0; }
上述程序输出加载图片的行列数,具体数值由你加载的图片决定:
#include <iostream> #include <iomanip> #include "gdal_priv.h" using std::cout; /* @brief 计算图像行列号在给定坐标系下对应的地理坐标 @param x 行号 @param y 列号 @param coords 返回的地理坐标 @param transform 变换的六参数 */ void toGeoCoord(int x, int y, double* coords, double* transform) { coords[0] = transform[0] + x * transform[1] + y * transform[2]; coords[1] = transform[3] + x * transform[4] + y * transform[5]; } /* @brief 读取数据并输出元数据信息 @param fileName 数据文件路径 @return 数据读取失败返回1,读取成功返回0 */ int readGeoRaster(const char* fileName) { GDALAllRegister(); // 注册所有支持的数据格式驱动 GDALDataset* dataset = static_cast<GDALDataset*>(GDALOpen(fileName, GA_ReadOnly)); // 以只读模式打开给定的数据文件 if (!dataset) { cout << "影像读取失败:(" << fileName << ")!" << '\n'; return EXIT_FAILURE; } int nSizeX = dataset->GetRasterXSize(); // 影像的宽度(像元数目) int nSizeY = dataset->GetRasterYSize(); // 影像的高度(像元数目) int nBandCount = dataset->GetRasterCount(); // 影像波段数 cout << "图像大小:(" << nSizeX << ", " << nSizeY << ")\n"; cout << "波段数:" << nBandCount << "\n"; double adfGeoTransform[6]; // 存储图像的六参数信息 dataset->GetGeoTransform(adfGeoTransform); // 获取数据的六参数信息 double adfULCoord[2]; // 图像左上角坐标 double adfLRCoord[2]; // 图像右下角坐标 // 获取左上角和右下角的地理坐标 toGeoCoord(0, 0, adfULCoord, adfGeoTransform); toGeoCoord(nSizeX - 1, nSizeY - 1, adfLRCoord, adfGeoTransform); cout << std::fixed; // 对于double类型的数据可以使其正常输入,阻止默认的科学计数法输出, cout << "左上角坐标:(" << adfULCoord[0] << ", " << adfULCoord[1] << ")\n"; cout << "右下角坐标:(" << adfLRCoord[0] << ", " << adfLRCoord[1] << ")\n"; const char* pszProj = dataset->GetProjectionRef(); // 获得WKT形式的投影信息 cout << "投影信息:" << pszProj << '\n'; GDALClose(dataset); // 关闭数据集 return EXIT_SUCCESS; } int main() { const char* pszFileName = R"(E:\1_MASK.tif)"; return readGeoRaster(pszFileName); }
上述程序的结果为:
有可能提示ERROR:找不到pro.db。解决方法是设置一个环境变量PROJ_LIB,将其路径设定到你share文件夹下proj文件夹中,因为在那里面有pro.db文件。
#include "gdal_priv.h" #include "cpl_conv.h" //for CPLMalloc() // int main() int main(int argc, char* argv[]) { //注册文件格式 GDALAllRegister(); const char* pszFile = "F:\\2.jpg";//"C:\\Test.img"; //1.jpg // const char* pszFile = argv[1]; GDALDataset *poDataset; //使用只读方式打开图像 poDataset = (GDALDataset*) GDALOpen( pszFile,GA_ReadOnly ); if( poDataset == NULL ) { printf( "File: %s不能打开!\n",pszFile); return 0; } //输出图像的格式信息 printf( "Driver:%s/%s\n", poDataset->GetDriver()->GetDescription(), poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME) ); //输出图像的大小和波段个数 printf( "Size is%dx%dx%d\n", poDataset->GetRasterXSize(),poDataset->GetRasterYSize(), poDataset->GetRasterCount()); //输出图像的投影信息 if( poDataset->GetProjectionRef() != NULL ) printf( "Projectionis `%s'\n", poDataset->GetProjectionRef() ); //输出图像的坐标和分辨率信息 double adfGeoTransform[6]; if( poDataset->GetGeoTransform( adfGeoTransform) == CE_None ) { printf( "Origin =(%.6f,%.6f)\n", adfGeoTransform[0], adfGeoTransform[3]); printf( "PixelSize = (%.6f,%.6f)\n", adfGeoTransform[1], adfGeoTransform[5]); } GDALRasterBand *poBand; int nBlockXSize, nBlockYSize; int bGotMin, bGotMax; double adfMinMax[2]; //读取第一个波段 poBand = poDataset->GetRasterBand( 1 ); //获取图像的块大小并输出 poBand->GetBlockSize(&nBlockXSize, &nBlockYSize ); printf( "Block=%dx%dType=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize, GDALGetDataTypeName(poBand->GetRasterDataType()), GDALGetColorInterpretationName( poBand->GetColorInterpretation())); //获取该波段的最大值最小值,如果获取失败,则进行统计 adfMinMax[0] = poBand->GetMinimum( &bGotMin); adfMinMax[1] = poBand->GetMaximum( &bGotMax); if( ! (bGotMin&& bGotMax) ) GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax); printf( "Min=%.3fd,Max=%.3f\n", adfMinMax[0], adfMinMax[1] ); //输出图像的金字塔信息 if( poBand->GetOverviewCount() > 0 ) printf( "Band has%d overviews.\n", poBand->GetOverviewCount() ); //输出图像的颜色表信息 if( poBand->GetColorTable() != NULL) printf( "Band hasa color table with %d entries.\n", poBand->GetColorTable()->GetColorEntryCount() ); float *pafScanline; int nXSize = poBand->GetXSize(); //读取图像的第一行数据 pafScanline = (float*) CPLMalloc(sizeof(float)*nXSize); poBand->RasterIO(GF_Read, 0, 0, nXSize,1, pafScanline, nXSize,1, GDT_Float32, 0, 0 ); CPLFree(pafScanline); //关闭文件 GDALClose((GDALDatasetH)poDataset); }
上述程序的输出结果为(具体信息由加载图片决定)
#include "ogrsf_frmts.h" int main() { GDALAllRegister(); GDALDataset* poDS; poDS = (GDALDataset*)GDALOpenEx("F:\\point.shp", GDAL_OF_VECTOR, NULL, NULL, NULL); if (poDS == NULL) { printf("Open failed.\n"); exit(1); } OGRLayer* poLayer; poLayer = poDS->GetLayerByName("point"); //中间读取Feature、FeatureDefn和Geometry等接口没有任何变化 //关闭数据 GDALClose(poDS); }
上述程序不报
Open failed,基本就为成功。
相关文章推荐
- vs2015编译gdal出错:error LNK2019: unresolved external symbol _vsnwprintf_s referenced in function String
- Win10 64位 VS2017下GDAL2.21编译之添加HDF5库编译C#版
- 编译GDAL在win10适用VS2015(64位)
- OSG教程::GDAL编译 win10 VS2015 WIN32与X64 的 debug与release编译(终极修正)
- win7 vs2015 X64环境下编译gdal-2.0.1+geos-3.5.0+proj-4.9.2
- GDAL编译 win10 VS2015 WIN32与X64 的 debug与release编译(终极修正)
- QCA+OPENSSL QT5.7.1 VS2015 WIN10 编译
- CMake + VS2013 Win7x64下编译opencv3.0
- Win10下离线安装.Net3.5,使VS支持编译.Net3.5的Dll
- VS编译SQLite
- tensorflow62 win10 vs2015 编译 tensorflow-gpu1.2.0 on python3.6.1
- Win7系统下利用VS2013编译GDAL(32位和64位)
- win10 vs2015 jsoncpp编译 支持xp系统
- VS 2012 编译64位的GDAL
- VS2013配置编译Caffe-Win10_X64
- tensorflow52 win10 vs2015 编译 tensorflow1.2.0-rc0(支持GPU)
- cocos2dx3.0 添加第三方库,VS编译环境和Android编译环境添加方法
- Win10 下Cmake编译配置 Opencv3.1 + Cuda7.5 + VS2013
- win10系统下vs2015+opencv3.4.3+cmake编译opencv-contrib3.4.3
- win10下使用CMake编译OpenCV2.4(配置VS2015之前)