Qt+GDAL開(kāi)發(fā)筆記(二):在windows系統(tǒng)msvc207x64編譯GDAL庫(kù)、搭建開(kāi)發(fā)環(huán)境和基礎(chǔ)Dem
前言
??上一篇使用mingw32版本的gdal,過(guò)程曲折,為更好的更方便搭建環(huán)境,在windows上msvc方式對(duì)于庫(kù)比較友好。
大地坐標(biāo)簡(jiǎn)介
概述
??大地坐標(biāo)(Geodetic coordinate)是大地測(cè)量中以參考橢球面為基準(zhǔn)面的坐標(biāo),地面點(diǎn)P的位置用大地經(jīng)度L、大地緯度B和大地高H表示。
原理
??當(dāng)點(diǎn)在參考橢球面上時(shí),僅用大地經(jīng)度和大地緯度表示。大地經(jīng)度是通過(guò)該點(diǎn)的大地子午面與起始大地子午面(通過(guò)格林尼治天文臺(tái)的子午面)之間的夾角。規(guī)定以起始子午面起算,向東由0°至180°稱(chēng)為東經(jīng);向西由0°至180°稱(chēng)為西經(jīng)。大地緯度是通過(guò)該點(diǎn)的法線(xiàn)與赤道面的夾角,規(guī)定由赤道面起算,由赤道面向北從0°至90°稱(chēng)為北緯;向南從0°到90°稱(chēng)為南緯。大地高是地面點(diǎn)沿法線(xiàn)到參考橢球面的距離。
北京54坐標(biāo)系:BJZ54
??北京54坐標(biāo)系(BJZ54)是指北京54坐標(biāo)系為參心大地坐標(biāo)系,大地上的一點(diǎn)可用經(jīng)度L54、緯度M54和大地高H54定位,它是以克拉索夫斯基橢球?yàn)榛A(chǔ),經(jīng)局部平差后產(chǎn)生的坐標(biāo)系。
長(zhǎng)半軸a = 6378245m
短半軸b = 6356863.0188m
第一偏心率平方e2 = 0.006693421622
扁率α =1/298.3
世界大地坐標(biāo)系統(tǒng):WGS-84
??WGS-84坐標(biāo)系是世界大地坐標(biāo)系統(tǒng),其坐標(biāo)原點(diǎn)在地心,采用WGS-84橢球(1984世界大地坐標(biāo)系)。
??WGS-84坐標(biāo)系是美國(guó)國(guó)防部研制確定的大地坐標(biāo)系,是一種協(xié)議地球坐標(biāo)系。
??WGS-84坐標(biāo)系的定義是:原點(diǎn)是地球的質(zhì)心,空間直角坐標(biāo)系的Z軸指向BIH(1984.0)定義的地極(CTP)方向,即國(guó)際協(xié)議原點(diǎn)CIO,它由IAU和IUGG共同推薦。X軸指向BIH定義的零度子午面和CTP赤道的交點(diǎn),Y軸和Z,X軸構(gòu)成右手坐標(biāo)系。
??WGS-84橢球采用國(guó)際大地測(cè)量與地球物理聯(lián)合會(huì)第17屆大會(huì)測(cè)量常數(shù)推薦值,采用的兩個(gè)常用基本幾何參數(shù):
長(zhǎng)半軸a = 6378137m
短半軸b = 6356752.3142m
第一偏心率平方e2 = 0.00669437999013
扁率 α= 1/298.257223563
國(guó)家大地坐標(biāo)系:CGCS2000
??2000國(guó)家大地坐標(biāo)系,是我國(guó)當(dāng)前最新的國(guó)家大地坐標(biāo)系,英文名稱(chēng)為China Geodetic Coordinate System 2000,英文縮寫(xiě)為CGCS2000。
??2000國(guó)家大地坐標(biāo)系的原點(diǎn)為包括海洋和大氣的整個(gè)地球的質(zhì)量中心;2000國(guó)家大地坐標(biāo)系的Z軸由原點(diǎn)指向歷元2000.0的地球參考極的方向,該歷元的指向由國(guó)際時(shí)間局給定的歷元為1984.0的初始指向推算,定向的時(shí)間演化保證相對(duì)于地殼不產(chǎn)生殘余的全球旋轉(zhuǎn),X軸由原點(diǎn)指向格林尼治參考子午線(xiàn)與地球赤道面(歷元2000.0)的交點(diǎn),Y軸與Z軸、X軸構(gòu)成右手正交坐標(biāo)系。采用廣義相對(duì)論意義下的尺度。
長(zhǎng)半軸a = 6378137m
短半軸b = 6356752.314m
第一偏心率平方e2 = 0.00669438002290
扁率α = 1/298.257222101
GDAL庫(kù)
概述
??GDAL(Geospatial Data Abstraction Library)是一個(gè)在X/MIT許可協(xié)議下的開(kāi)源柵格空間數(shù)據(jù)轉(zhuǎn)換庫(kù)。它利用抽象數(shù)據(jù)模型來(lái)表達(dá)所支持的各種文件格式。它還有一系列命令行工具來(lái)進(jìn)行數(shù)據(jù)轉(zhuǎn)換和處理。 OGR是GDAL項(xiàng)目的一個(gè)分支,提供對(duì)矢量數(shù)據(jù)的支持。 有很多著名的GIS類(lèi)產(chǎn)品都使用了GDAL/OGR庫(kù),包括ESRI的ARCGIS 9.3,Google Earth和跨平臺(tái)的GRASS GIS系統(tǒng)。利用GDAL/OGR庫(kù),可以使基于Linux的地理空間數(shù)據(jù)管理系統(tǒng)提供對(duì)矢量和柵格文件數(shù)據(jù)的支持。
功能特征
GDAL提供對(duì)多種柵格數(shù)據(jù)的支持,包括Arc/Info ASCII Grid(asc),GeoTiff (tiff),Erdas Imagine Images(img),ASCII DEM(dem) 等格式。
GDAL使用抽象數(shù)據(jù)模型(abstract data model)來(lái)解析它所支持的數(shù)據(jù)格式,抽象數(shù)據(jù)模型包括數(shù)據(jù)集(dataset),坐標(biāo)系統(tǒng),仿射地理坐標(biāo)轉(zhuǎn)換(Affine Geo Transform),大地控制點(diǎn)(GCPs),元數(shù)據(jù)(Metadata),柵格波段(Raster Band),顏色表(Color Table),子數(shù)據(jù)集域(Subdatasets Domain),圖像結(jié)構(gòu)域(Image_Structure Domain),XML域(XML:Domains)。
GDALMajorObject類(lèi):帶有元數(shù)據(jù)的對(duì)象。
GDALDdataset類(lèi):通常是從一個(gè)柵格文件中提取的相關(guān)聯(lián)的柵格波段集合和這些波段的元數(shù)據(jù);
GDALDdataset也負(fù)責(zé)所有柵格波段的地理坐標(biāo)轉(zhuǎn)換(georeferencing transform)和坐標(biāo)系定義。
GDALDriver類(lèi):文件格式驅(qū)動(dòng)類(lèi),GDAL會(huì)為每一個(gè)所支持的文件格式創(chuàng)建一個(gè)該類(lèi)的實(shí)體,來(lái)管理該文件格式。
GDALDriverManager類(lèi):文件格式驅(qū)動(dòng)管理類(lèi),用來(lái)管理GDALDriver類(lèi)。
OGR體系結(jié)構(gòu)
Geometry類(lèi):Geometry (包括OGRGeometry等類(lèi))封裝了OpenGIS的矢量數(shù)據(jù)模型,并提供了一些幾何操作,WKB(Well Knows Binary)和WKT(Well Known Text)格式之間的相互轉(zhuǎn)換,以及空間參考系統(tǒng)(投影)。
Spatial Reference類(lèi):OGRSpatialReference封裝了投影和基準(zhǔn)面的定義。
Feature類(lèi):OGRFeature封裝了一個(gè)完整feature的定義,一個(gè)完整的feature包括一個(gè)geometry和geometry的一系列屬性。
Feature Definition類(lèi):OGRFeatureDefn里面封裝了feature的屬性,類(lèi)型、名稱(chēng)及其默認(rèn)的空間參考系統(tǒng)等。一個(gè)OGRFeatureDefn對(duì)象通常與一個(gè)層(layer)對(duì)應(yīng)。
Layer類(lèi):OGRLayer是一個(gè)抽象基類(lèi),表示數(shù)據(jù)源類(lèi)OGRDataSource里面的一層要素(feature)。
Data Source類(lèi):OGRDataSource是一個(gè)抽象基類(lèi),表示含有OGRLayer對(duì)象的一個(gè)文件或一個(gè)數(shù)據(jù)庫(kù)。
Drivers類(lèi):OGRSFDriver對(duì)應(yīng)于每一個(gè)所支持的矢量文件格式。類(lèi)OGRSFDriver由類(lèi)OGRSFDriverRegistrar來(lái)注冊(cè)和管理。
下載地址
??Home:https://gdal.org/download.html
?選擇3.2.1版本
關(guān)于編譯順序
?? 因?yàn)槭紫冗x擇的是之前vs2019編譯成功的版本,但是本次vs2017x64無(wú)解了。
??gdal依賴(lài)proj,proj又依賴(lài)sqlite,所以本篇先sqlite,再proj,最后gdal。
編譯SQLite 3.34.1(windows msvc2017x64版本)
步驟一:下載解壓
??https://www.sqlite.org/download.html
??

步驟二:使用VS2017新建VC++空工程
??

??

步驟三:添加文件到工程
??

??

步驟四:添加宏命令
??

_USRDLL
SQLITE_ENABLE_RTREE
SQLITE_ENABLE_COLUMN_METADATA
SQLITE_ENABLE_FTS5
SQLITE_ENABLE_UNLOCK_NOTIFY
??

步驟六:修改sqlite3.def
sqlite3_unlock_nofity
??

步驟七:修改目標(biāo)
??這里release和debug都要改成配置類(lèi)型“靜態(tài)庫(kù)(.lib)”:
??

步驟八:編譯成功
??編譯:
??

??

??

??

編譯PROJ 6.2.0(windows msvc2017x64版本)
步驟一:下載解壓
??https://proj.org/download.html
??

步驟二:CMake配置,添加sqlite3
??

??(注意:配置的時(shí)候選擇編譯器就要選擇x64的,不要去vs里面再建,有些環(huán)境變量需要CMake帶進(jìn)去)
??沒(méi)有添加SQLIte,則會(huì)報(bào)錯(cuò):
??

??添加:
??

??

??安裝python到系統(tǒng),自己下個(gè)python3.7.3版本,裝到系統(tǒng),然后將python的可執(zhí)行文件添加進(jìn)系統(tǒng)變量:
??

??然后重啟CMake,再繼續(xù):
??

??下個(gè)對(duì)應(yīng)版本的sqlite3.exe:
??


??繼續(xù)配置,配置通過(guò):
??

步驟三:CMake生成工程
??

步驟四:打開(kāi)編譯(使用vs2017打開(kāi))
??

??(PS:若是這里沒(méi)有x64,則是需要在CMakeGui的時(shí)候配置configure選擇x64,在這里新建是會(huì)要報(bào)錯(cuò)的)
步驟五:編譯成功
??

??

編譯GDAL(windows msvc2017x64版本)
步驟一:下載解壓
??之前做osgearth編譯過(guò)Qt5.15的2019x64版本,本次編譯qt5.9.3的2017x64版本。
??

步驟二:修改源碼
??修改目錄下的nmake.opt文件,如下:
??第41行的代碼修改為:
??

!IFNDEF MSVC_VER#MSVC_VER=1800 # VS2013#MSVC_VER=1900 # VS2015MSVC_VER=1910 # vs2017#MSVC_VER=1921 # VS2019!ENDIF
WIN64=1
步驟三:打開(kāi)vs2017命令行編譯
??

??

??找到目錄,并輸入命令:
nmake /f makefile.vc MSVC_VER=1910 WIN64=1 DEBUG=1
??出現(xiàn)錯(cuò)誤:
??

??修改如下(前面鄙夷的時(shí)候,請(qǐng)注意proj的prefix_install路徑配置,來(lái)看install到哪個(gè)位置了):
??

??入坑編譯過(guò)不去解決:
??
??然后繼續(xù)編譯:
nmake /f makefile.vc MSVC_VER=1910 WIN64=1 DEBUG=1
步驟四:編譯
nmake /f makefile.vc MSVC_VER=1910 WIN64=1 DEBUG=1
??
??這是前面配置proj的時(shí)候沒(méi)有去掉多shell32和ole32,然后繼續(xù):
??

??這是沒(méi)有引入sqlite,重新在gdal引入下;
??

??然后繼續(xù),終于編譯成功了,問(wèn)題居多,歷時(shí)兩天了,:
??

??

步驟五:安裝提取
??(這里debug就是代表調(diào)試模式)
nmake /f makefile.vc MSVC_VER=1910 WIN64=1 DEBUG=1 install
??

??

??還得進(jìn)行一次devinstall:
nmake /f makefile.vc MSVC_VER=1910 WIN64=1 DEBUG=1 devinstall
??

??

??

??頭文件終于出來(lái)了。
步驟六:走一遍非調(diào)試模式
??之前以為DEBUG是編譯過(guò)程打印調(diào)試信息,現(xiàn)在看來(lái)就是生成的庫(kù)是不是調(diào)試模式了,我們需要release所以再來(lái)一遍:
nmake /f makefile.vc MSVC_VER=1910 WIN64=1 nmake /f makefile.vc MSVC_VER=1910 WIN64=1 install
nmake /f makefile.vc MSVC_VER=1910 WIN64=1 devinstall
??

步驟七:調(diào)整工程測(cè)試
??對(duì)pri文件進(jìn)行windows庫(kù)的引入,如下圖:
??

模塊化
??

Demo源碼
GDALManager.pri
INCLUDEPATH += $$PWD
DEPENDPATH += $$PWD
HEADERS += \
? ?$$PWD/GDALManager.h
SOURCES += \
? ?$$PWD/GDALManager.cpp
win32 {
? ?# windows Qt5.9.3 msvc2017x64 版本 gdal
? ?INCLUDEPATH += $$PWD/gdal-3.2.1_msvc2017x64/include
? ?LIBS += -L$$PWD/gdal-3.2.1_msvc2017x64/lib
? ?LIBS += -lgdal_i
? ?# 引入也失敗了,當(dāng)前不深
# ? ?# windows Qt5.9.3 mingw32 版本 sqlite3# ? ?INCLUDEPATH += $$PWD/gdal3.2.1_qt593_mingw32/sqlite3/include# ? ?LIBS += -L$$PWD/gdal3.2.1_qt593_mingw32/sqlite3/lib# ? ?LIBS += -lsqlite3# ? ?# windows Qt5.9.3 mingw32 版本 proj6.2.0# ? ?INCLUDEPATH += $$PWD/gdal3.2.1_qt593_mingw32/proj6.2.0/include# ? ?LIBS += -L$$PWD/gdal3.2.1_qt593_mingw32/proj6.2.0/lib# ? ?LIBS += -lproj# ? ?# windows Qt5.9.3 mingw32 版本 gdal3.2.1# ? ?INCLUDEPATH += $$PWD/gdal3.2.1_qt593_mingw32/gdal3.2.1/include# ? ?LIBS += -L$$PWD/gdal3.2.1_qt593_mingw32/gdal3.2.1/lib# ? ?LIBS += -lgdal}else {
? ?DEFINES += LINUX ? ?# GDAL系統(tǒng)安裝的默認(rèn)路徑位/usr/local
? ?# 系統(tǒng)庫(kù),頭文件路徑和庫(kù)文件默認(rèn)已包含
? ?LIBS += -lgdal ? ?# PROJ系統(tǒng)安裝的默認(rèn)路徑位/usr/local
? ?# 系統(tǒng)庫(kù),頭文件路徑和庫(kù)文件默認(rèn)已包含
? ?LIBS += -lproj}
GDALManager.h
#ifndef GDALMANAGER_H#define GDALMANAGER_H#include <QObject>class GDALManager : public QObject{
? ?Q_OBJECTpublic:
? ?explicit GDALManager(QObject *parent = 0);signals:public:
? ?static void testEnv(); ? ? ? ? ? ? ? ? ? ? // v1.0.0 測(cè)試環(huán)境private:};#endif // GDALMANAGER_H
GDALManager.cpp
#include "GDALManager.h"#include "gdal.h"#include <QDebug>#include <QDateTime>//#define LOG qDebug()<<__FILE__<<__LINE__//#define LOG qDebug()<<__FILE__<<__LINE__<<__FUNCTION__//#define LOG qDebug()<<__FILE__<<__LINE__<<QThread()::currentThread()//#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd")#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz")GDALManager::GDALManager(QObject *parent)
? ?: QObject(parent){
? ?// 注冊(cè)所有驅(qū)動(dòng)
? ?GDALAllRegister();}void GDALManager::testEnv(){
? ?QString version = QString(GDALVersionInfo("RELEASE_NAME"));
? ?LOG << version;}
工程模板v1.1.0
??
