本章讲述使用qgis c++ Api加载栅格地图数据并显示。
QgsRasterLayer
代表栅格图层,详见官方文档Represents a raster layer.
A QgsRasterLayer is instantiated by specifying the name of a data provider, such as “gdal” or “wms”, and a url defining the specific data set to connect to.
The raster layer constructor in turn instantiates a QgsRasterDataProvider subclass corresponding to the provider type, and passes it the url. The data provider connects to the data source.
QgsRasterLayer (const QString &uri, const QString &baseName=QString(), const QString &providerType="gdal", const QgsRasterLayer::LayerOptions &options=QgsRasterLayer::LayerOptions())
providerType
用于指定data provider,data provider可以指定的值包括:Provider | 说明 |
---|---|
gdal | GDAL 是读写大量的栅格空间数据格式的广泛应用的开源库 |
wms | 网络地图服务 |
空间数据抽象库(Geospatial Data Abstraction Library,GDAL)由Frank Warmerdam于1998年开始研发,主要用于读取栅格数据的抽象数据模型类库,并采用X/MIT协议发布。GDAL支持绝大多数的GIS栅格数据,并被大多数桌面GIS软件应用,如QGIS、ArcGIS等开源或商业软件都使用GDAL作为读取、写入栅格数据的基础类库。
常见的栅格数据如下表
providerType
为gdal
void MainWindow::addRasterSlot()
{
QString filename = QStringLiteral("maps/SRTM.tif");
QFileInfo ff(filename);
QgsRasterLayer* rlayer = new QgsRasterLayer(filename,ff.baseName(),"gdal");
if(!rlayer->isValid())
{
QMessageBox::critical(this,tr("error"),tr("invalid layer"));
return;
}
QgsProject::instance()->addMapLayer(rlayer);
zoomToFirstLayer();
}
包含多个tiff图层
GPKG:/home/project/data/data.gpkg:layername
void MainWindow::addGpkg1Slot()
{
QString filename = QStringLiteral("maps/two_raster_layers.gpkg");
QFileInfo ff(filename);
QString uri1 = QString("GPKG:%1/%2:layer01").arg(QCoreApplication::applicationDirPath()).arg(filename);
QString uri2 = QString("GPKG:%1/%2:layer02").arg(QCoreApplication::applicationDirPath()).arg(filename);
QgsRasterLayer* rlayer1 = new QgsRasterLayer(uri1,"layer01","gdal");
QgsRasterLayer* rlayer2 = new QgsRasterLayer(uri2,"layer02","gdal");
QgsProject::instance()->addMapLayer(rlayer1);
QgsProject::instance()->addMapLayer(rlayer2);
zoomToFirstLayer();
}
WMS通过HTTP为用户提供地图渲染数据,并且支持返回JPEG、PNG等多种数据格式。OGC为WMS定义了GetCapabilities、GetMap和GetFeatureInfo等常见重要方法。通过GetCapabilities方法可获得WMS服务的基本信息,如服务内容、版本信息等。GetMap方法是WMS的核心,通过它可获得具体地理范围的地图数据。通过GetFeatureInfo方法,可根据地理位置坐标获取该位置详细的要素信息。
WMS—Web地图服务详情文档地址
QgsRasterLayer
的uri参数,其中最重要的是以下四个
https://webst01.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}
QgsDataSourceUri
类的setParam
函数,encodeUri
函数返回最终url
url
需要UrlEncode
转码QgsMapLayer *ll_qgis_base_lib::addWmsLayer(const QString &uri, const QString &baseName)
{
QString urlWithParams;
QString type = QStringLiteral("xyz");
int zMin = 0;
int zMax = 18;
#if 1
QgsDataSourceUri urik;
urik.setParam( QStringLiteral( "url" ), uri );
urik.setParam( QStringLiteral( "type" ), type );
urik.setParam( QStringLiteral( "zmin" ), QString::number( zMin ) );
urik.setParam( QStringLiteral( "zmax" ), QString::number( zMax ) );
urlWithParams = urik.encodedUri();
#else
QString urlEncode = QUrl::toPercentEncoding(url);
urlWithParams = QString("type=xyz&url=%1&zmax=18&zmin=0").arg(urlEncode);
#endif
QgsRasterLayer *rlayer = new QgsRasterLayer(urlWithParams,baseName,"wms");
QgsProject::instance()->addMapLayer(rlayer);
return rlayer;
}
下图显示了前三个流派在zoom=1层级上的瓦片编号结果:
file:///home/t/gis/ld_qgis_demos/bin/maps/gaode20230630//${z}/${y}/${x}.png
-180
90
180
-90
2
top
EPSG:4326
256
256
3
void MainWindow::addGdalOfflineSlot()
{
QString mapPath = QCoreApplication::applicationDirPath()+QStringLiteral("/maps/gaode20230630");
QString tmsPath = mapPath+QStringLiteral("/tms.xml");
QString serverUrl = QStringLiteral("file:///") + mapPath + QStringLiteral("//${z}/${y}/${x}.png");
QString tmsStr = QString(""
"%1 "
""
"-180 90 180 -90 "
"2 top "
" "
"EPSG:4326 256 256 3 "
" ").arg(serverUrl);
QFile file(tmsPath);
if(file.open(QIODevice::ReadWrite))
{
file.write(tmsStr.toStdString().c_str());
file.close();
}
QgsRasterLayer* layer = new QgsRasterLayer(mapPath+QStringLiteral("/tms.xml"),"gaodeoffline","gdal");
QgsProject::instance()->addMapLayer(layer);
zoomToFirstLayer();
}