前言
前面我已经编译过MinGW版本的OSG(3.6.5),osgEarth的编译需要依赖sqlite3、curl 、proj 、geos 、gdal,以及OSG库。这些库也需要用QT自带的MinGW环境进行编译。
环境说明
我系统的QT MinGW目录为:D:\software\Qt5.12.10\Tools\mingw730_64
我创建了目录D:\software\build-deps,用于编译主要的依赖库,在该目录下生效一个env.bat,用于在cmd命令行窗口配置编译的环境,完成依赖库的编译操作,生成的依赖库保存在D:\software\mingw73-deps目录下
@echo off
set MINGW=D:\software\Qt5.12.10\Tools\mingw730_64
set PATH=%MINGW%\bin;%PATH%
cd /d D:\software\build-deps
sqlite3下载及编译
call D:\software\build-deps\env.bat
cd /d D:\software\build-deps
curl -L -o sqlite.zip https://www.sqlite.org/2024/sqlite-amalgamation-3450100.zip
tar -xf sqlite.zip
cd sqlite-amalgamation-3450100
gcc -O2 ^
-DSQLITE_ENABLE_RTREE=1 ^
-DSQLITE_ENABLE_COLUMN_METADATA=1 ^
-DSQLITE_ENABLE_FTS3=1 ^
-DSQLITE_ENABLE_FTS3_PARENTHESIS=1 ^
-DSQLITE_ENABLE_MATH_FUNCTIONS=1 ^
-c sqlite3.c
ar rcs libsqlite3.a sqlite3.o
copy /y libsqlite3.a D:\software\mingw73-deps\lib\
copy /y sqlite3.h D:\software\mingw73-deps\include\
copy /y sqlite3ext.h D:\software\mingw73-deps\include\
curl下载及编译
call D:\software\build-deps\env.bat
curl -L -o curl-8.5.0.tar.gz https://curl.se/download/curl-8.5.0.tar.gz
tar -xf curl-8.5.0.tar.gz
cd curl-8.5.0
mkdir build & cd build
cmake .. -G "MinGW Makefiles" ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_C_COMPILER=D:/software/Qt5.12.10/Tools/mingw730_64/bin/gcc.exe ^
-DCMAKE_CXX_COMPILER=D:/software/Qt5.12.10/Tools/mingw730_64/bin/g++.exe ^
-DCMAKE_INSTALL_PREFIX=D:/software/mingw73-deps ^
-DBUILD_SHARED_LIBS=ON ^
-DCURL_USE_OPENSSL=OFF ^
-DCURL_USE_LIBSSH2=OFF ^
-DCURL_DISABLE_LDAP=ON ^
-DCURL_BROTLI=OFF ^
-DCURL_ZSTD=OFF ^
-DBUILD_TESTING=OFF
mingw32-make -j4
mingw32-make install
PROJ下载及编译
call D:\software\build-deps\env.bat
curl -L -o proj-8.2.1.tar.gz https://download.osgeo.org/proj/proj-8.2.1.tar.gz
tar -xf proj-8.2.1.tar.gz
cd proj-8.2.1
mkdir build & cd build
cmake .. -G "MinGW Makefiles" ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_C_COMPILER=D:/software/Qt5.12.10/Tools/mingw730_64/bin/gcc.exe ^
-DCMAKE_CXX_COMPILER=D:/software/Qt5.12.10/Tools/mingw730_64/bin/g++.exe ^
-DCMAKE_INSTALL_PREFIX=D:/software/mingw73-deps ^
-DBUILD_SHARED_LIBS=ON ^
-DENABLE_TIFF=OFF ^
-DENABLE_CURL=OFF ^
-DBUILD_TESTING=OFF ^
-DBUILD_APPS=OFF ^
-DSQLite3_INCLUDE_DIR=D:/software/mingw73-deps/include ^
-DSQLite3_LIBRARY=D:/software/mingw73-deps/lib/libsqlite3.a
mingw32-make -j4
mingw32-make install
GEOS下载及编译
call D:\software\build-deps\env.bat
curl -L -o geos-3.9.3.tar.bz2 https://download.osgeo.org/geos/geos-3.9.3.tar.bz2
tar -xf geos-3.9.3.tar.bz2
cd geos-3.9.3
mkdir build & cd build
cmake .. -G "MinGW Makefiles" ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_C_COMPILER=D:/software/Qt5.12.10/Tools/mingw730_64/bin/gcc.exe ^
-DCMAKE_CXX_COMPILER=D:/software/Qt5.12.10/Tools/mingw730_64/bin/g++.exe ^
-DCMAKE_INSTALL_PREFIX=D:/software/mingw73-deps ^
-DBUILD_SHARED_LIBS=ON ^
-DBUILD_TESTING=OFF
mingw32-make -j4
mingw32-make install
cd ..\..\..
dir D:\software\mingw73-deps\lib\libgeos*.dll.a
GDAL 3.5.2下载及编译
call D:\software\build-deps\env.bat
cd /d D:\software\build-deps\gdal-3.5.2
rmdir /s /q build
mkdir build & cd build
cmake .. -G "MinGW Makefiles" ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_C_COMPILER=D:/software/Qt5.12.10/Tools/mingw730_64/bin/gcc.exe ^
-DCMAKE_CXX_COMPILER=D:/software/Qt5.12.10/Tools/mingw730_64/bin/g++.exe ^
-DCMAKE_INSTALL_PREFIX=D:/software/mingw73-deps ^
-DBUILD_SHARED_LIBS=ON ^
-DBUILD_TESTING=OFF ^
-DBUILD_PYTHON_BINDINGS=OFF ^
-DBUILD_JAVA_BINDINGS=OFF ^
-DBUILD_CSHARP_BINDINGS=OFF ^
-DGDAL_BUILD_OPTIONAL_DRIVERS=OFF ^
-DOGR_BUILD_OPTIONAL_DRIVERS=OFF ^
-DGDAL_ENABLE_DRIVER_GTIFF=ON ^
-DOGR_ENABLE_DRIVER_GEOJSON=ON ^
-DOGR_ENABLE_DRIVER_SHAPE=ON ^
-DGDAL_USE_CURL=OFF ^
-DGDAL_USE_OPENSSL=OFF ^
-DGDAL_USE_EXPAT=OFF ^
-DGDAL_USE_ICONV=OFF ^
-DGDAL_USE_TIFF=OFF ^
-DGDAL_USE_GEOTIFF=OFF ^
-DGDAL_USE_ZLIB=OFF ^
-DGDAL_USE_SQLITE3=ON ^
-DGDAL_USE_GEOS=ON ^
-DSQLite3_INCLUDE_DIR=D:/software/mingw73-deps/include ^
-DSQLite3_LIBRARY=D:/software/mingw73-deps/lib/libsqlite3.a ^
-DGEOS_INCLUDE_DIR=D:/software/mingw73-deps/include ^
-DGEOS_LIBRARY=D:/software/mingw73-deps/lib/libgeos_c.dll.a ^
-DCMAKE_C_FLAGS="-Wa,-mbig-obj" ^
-DCMAKE_CXX_FLAGS="-Wa,-mbig-obj"
mingw32-make -j4
mingw32-make install
osgEarth 2.10.1下载及编译
call D:\software\build-deps\env.bat
curl -L -o osgearth-2.10.1 https://codeload.github.com/pelicanmapping/osgearth/tar.gz/refs/tags/osgearth-2.10.1
cd osgearth-2.10.1
mkdir build & cd build
cmake .. -G "MinGW Makefiles" ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_C_COMPILER=D:/software/Qt5.12.10/Tools/mingw730_64/bin/gcc.exe ^
-DCMAKE_CXX_COMPILER=D:/software/Qt5.12.10/Tools/mingw730_64/bin/g++.exe ^
-DCMAKE_CXX_FLAGS="-DGEOS_INLINE" ^
-DCMAKE_INSTALL_PREFIX=D:/software/OpenSceneG/osgEarth-2.10.1-mingw ^
-DCMAKE_PREFIX_PATH=D:/software/mingw73-deps ^
-DOSG_DIR=D:/software/OpenSceneG/install-mingw73 ^
-DOPENTHREADS_LIBRARY=D:/software/OpenSceneG/install-mingw73/lib/libOpenThreads.dll.a ^
-DGDAL_INCLUDE_DIR=D:/software/mingw73-deps/include ^
-DGDAL_LIBRARY=D:/software/mingw73-deps/lib/libgdal.dll.a ^
-DGEOS_INCLUDE_DIR=D:/software/mingw73-deps/include ^
-DGEOS_LIBRARY=D:/software/mingw73-deps/lib/libgeos.dll.a ^
-DCURL_INCLUDE_DIR=D:/software/mingw73-deps/include ^
-DCURL_LIBRARY=D:/software/mingw73-deps/lib/libcurl.dll.a ^
-DSQLITE3_INCLUDE_DIR=D:/software/mingw73-deps/include ^
-DSQLITE3_LIBRARY=D:/software/mingw73-deps/lib/libsqlite3.a ^
-DBUILD_OSGEARTH_EXAMPLES=OFF ^
-DBUILD_OSGEARTH_DOCS=OFF
mingw32-make -j4
mingw32-make install
注意,上面参数是关闭openssl的(-DCURL_USE_OPENSSL=OFF),无 SSL 版只支持 http:// 在线图层。
环境配置
以上编译完成之后,需要做下环境配置:
在系统环境变量path中增加两个新增的路径
D:\software\OpenSceneG\osgEarth-2.10.1-mingw\bin;
D:\software\mingw73-deps\bin;
另外添加两个新变量:
| 变量名 | 值 |
|---|---|
GDAL_DATA |
D:\software\mingw73-deps\share\gdal |
PROJ_LIB |
D:\software\mingw73-deps\share\proj |
一个QT示例
#demo.pro文件
QT += core gui widgets opengl
CONFIG += c++14
DEFINES += NOMINMAX
TEMPLATE = app
TARGET = osgearth_demo
OSG_DIR = D:/software/OpenSceneG/install-mingw73
OSGEARTH_DIR = D:/software/OpenSceneG/osgEarth-2.10.1-mingw
INCLUDEPATH += $$OSG_DIR/include $$OSGEARTH_DIR/include
LIBS += -L$$OSGEARTH_DIR/lib -L$$OSG_DIR/lib
# osgEarth 系
LIBS += -losgEarth -losgEarthFeatures -losgEarthSymbology -losgEarthUtil -losgEarthAnnotation
# OSG 系
LIBS += -losgViewer -losgDB -losgUtil -losgGA -losg -lOpenThreads
# 系统库
LIBS += -lopengl32 -lglu32
SOURCES += main.cpp
//main.cpp
// Qt 5.12 + osgEarth 2.10.1 + OSG 3.6.x (MinGW 7.3 x64)
#include <QApplication>
#include <QOpenGLWidget>
#include <QTimer>
#include <QMouseEvent>
#include <QWheelEvent>
#include <osgViewer/Viewer>
#include <osgViewer/GraphicsWindow> // OSG 3.6: GraphicsWindowEmbedded 在这个头里
#include <osgGA/GUIEventAdapter>
#include <osgEarth/Map>
#include <osgEarth/MapNode>
#include <osgEarth/ImageLayer> // 2.x:用通用 ImageLayer,没有 GDALImageLayer
#include <osgEarth/SpatialReference>
#include <osgEarth/GeoData> // GeoPoint 在这里
#include <osgEarth/Viewpoint>
#include <osgEarth/Units> // Angle / Distance / Units
#include <osgEarthUtil/EarthManipulator> // 2.x:在 Util 库里
#include <osgEarthDrivers/gdal/GDALOptions> // GDAL 驱动选项(纯头文件)
static const char* kWorldFile = "D:/software/OSG/osgearth-2.10.1/data/world.tif";
static const char* kBostonFile = "D:/software/OSG/osgearth-2.10.1/data/boston-inset-wgs84.tif";
class EarthWidget : public QOpenGLWidget
{
public:
explicit EarthWidget(QWidget* parent = nullptr) : QOpenGLWidget(parent)
{
setMouseTracking(true);
setFocusPolicy(Qt::StrongFocus);
QTimer* timer = new QTimer(this);
connect(timer, &QTimer::timeout, this,
static_cast<void (QWidget::*)()>(&QWidget::update));
timer->start(33);
}
protected:
void initializeGL() override
{
if (_viewer.valid()) return;
// ---- 1) 组装地图:底图 + 高清切片 ----
osg::ref_ptr<osgEarth::Map> map = new osgEarth::Map();
osgEarth::Drivers::GDALOptions worldOpt;
worldOpt.url() = kWorldFile;
map->addLayer(new osgEarth::ImageLayer("world", worldOpt));
osgEarth::Drivers::GDALOptions bostonOpt;
bostonOpt.url() = kBostonFile;
map->addLayer(new osgEarth::ImageLayer("boston", bostonOpt));
osg::ref_ptr<osgEarth::MapNode> mapNode = new osgEarth::MapNode(map);
// ---- 2) 视图器嵌入 Qt(OSG 3.6 新方法名/新签名) ----
_viewer = new osgViewer::Viewer;
_viewer->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);
_gw = _viewer->setUpViewerAsEmbeddedInWindow(0, 0, width(), height());
osg::ref_ptr<osgEarth::Util::EarthManipulator> manip =
new osgEarth::Util::EarthManipulator();
_viewer->setCameraManipulator(manip.get());
_viewer->setSceneData(mapNode.get());
// 开场视角:全球视角(替代原来的波士顿特写)
osgEarth::Viewpoint vp;
vp.name() = std::string("World");
vp.focalPoint() = osgEarth::GeoPoint(
osgEarth::SpatialReference::get("wgs84"),
-71.06, 42.36, 0.0, osgEarth::ALTMODE_ABSOLUTE);
vp.heading() = osgEarth::Angle(0.0, osgEarth::Units::DEGREES);
vp.pitch() = osgEarth::Angle(-90.0, osgEarth::Units::DEGREES); // -90 = 正对地心俯视
vp.range() = osgEarth::Distance(30000000.0, osgEarth::Units::METERS); // 30000 km,看全球
manip->setViewpoint(vp);
// 顺手把背景色从"OpenGL 默认绿/蓝"改成太空黑(这行加在 realize 之前)
_viewer->getCamera()->setClearColor(osg::Vec4(0.0f, 0.0f, 0.05f, 1.0f));
}
void resizeGL(int w, int h) override
{
if (_gw.valid())
{
_gw->resized(0, 0, w, h);
_gw->getEventQueue()->windowResize(0, 0, w, h);
}
}
void paintGL() override
{
if (_viewer.valid())
_viewer->frame();
}
void mousePressEvent(QMouseEvent* e) override
{
if (_gw.valid())
_gw->getEventQueue()->mouseButtonPress(e->x(), height() - e->y(), osgButton(e));
}
void mouseReleaseEvent(QMouseEvent* e) override
{
if (_gw.valid())
_gw->getEventQueue()->mouseButtonRelease(e->x(), height() - e->y(), osgButton(e));
}
void mouseMoveEvent(QMouseEvent* e) override
{
if (_gw.valid())
_gw->getEventQueue()->mouseMotion(e->x(), height() - e->y());
}
void wheelEvent(QWheelEvent* e) override
{
if (_gw.valid())
_gw->getEventQueue()->mouseScroll(
e->angleDelta().y() > 0 ? osgGA::GUIEventAdapter::SCROLL_UP
: osgGA::GUIEventAdapter::SCROLL_DOWN);
}
private:
static int osgButton(QMouseEvent* e)
{
switch (e->button())
{
case Qt::LeftButton: return osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON;
case Qt::MiddleButton: return osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON;
case Qt::RightButton: return osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON;
default: return 0;
}
}
osg::ref_ptr<osgViewer::Viewer> _viewer;
osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> _gw;
};
int main(int argc, char** argv)
{
// 必须在 QApplication 之前设置
qputenv("GDAL_DATA", "D:/software/mingw73-deps/share/gdal");
qputenv("PROJ_LIB", "D:/software/mingw73-deps/share/proj");
QApplication app(argc, argv);
EarthWidget w;
w.setWindowTitle(QStringLiteral("Qt + osgEarth 2.10.1 (MinGW730_64)"));
w.resize(1280, 720);
w.show();
return app.exec();
}
在initializeGL中,组装了两个世界地图和波士顿地图,地图文件是osgEarth自带的。
static const char* kWorldFile = "D:/software/OSG/osgearth-2.10.1/data/world.tif";
static const char* kBostonFile = "D:/software/OSG/osgearth-2.10.1/data/boston-inset-wgs84.tif";
// ---- 1) 组装地图:底图 + 高清切片 ----
osg::ref_ptr<osgEarth::Map> map = new osgEarth::Map();
osgEarth::Drivers::GDALOptions worldOpt;
worldOpt.url() = kWorldFile;
map->addLayer(new osgEarth::ImageLayer("world", worldOpt));
osgEarth::Drivers::GDALOptions bostonOpt;
bostonOpt.url() = kBostonFile;
map->addLayer(new osgEarth::ImageLayer("boston", bostonOpt));
效果图

