6. 加载栅格(raster)图层

前言

本章讲述使用qgis c++ Api加载栅格地图数据并显示。

加载栅格(raster)图层

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说明
gdalGDAL 是读写大量的栅格空间数据格式的广泛应用的开源库
wms网络地图服务

gdal

空间数据抽象库(Geospatial Data Abstraction Library,GDAL)由Frank Warmerdam于1998年开始研发,主要用于读取栅格数据的抽象数据模型类库,并采用X/MIT协议发布。GDAL支持绝大多数的GIS栅格数据,并被大多数桌面GIS软件应用,如QGIS、ArcGIS等开源或商业软件都使用GDAL作为读取、写入栅格数据的基础类库。

常见的栅格数据如下表
在这里插入图片描述

GeoTiff

  • 是常用的栅格数据存储格式
QGis导入tif

在这里插入图片描述
在这里插入图片描述

代码添加
  • 构造函数参数uri为文件路径,providerTypegdal
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<QgsRasterLayer*>();
}

在这里插入图片描述
在这里插入图片描述

GeoPackage

包含多个tiff图层

QGis导入

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代码导入
  • 注意: uri格式为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<QgsRasterLayer*>();
}

在这里插入图片描述
在这里插入图片描述

wms

WMS通过HTTP为用户提供地图渲染数据,并且支持返回JPEG、PNG等多种数据格式。OGC为WMS定义了GetCapabilities、GetMap和GetFeatureInfo等常见重要方法。通过GetCapabilities方法可获得WMS服务的基本信息,如服务内容、版本信息等。GetMap方法是WMS的核心,通过它可获得具体地理范围的地图数据。通过GetFeatureInfo方法,可根据地理位置坐标获取该位置详细的要素信息。

WMS—Web地图服务详情文档地址

在线高德影像地图

QGis添加在线高德影像
  • 输入Name和Url
    在这里插入图片描述
    在这里插入图片描述
  • 注意: 这里没有选择WMS/WMTS,而是选择了XYZ
代码添加
  • 需要构建QgsRasterLayer的uri参数,其中最重要的是以下四个
    • url: wms的服务器地址https://webst01.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}
    • type: 类型 xyz,mbtiles,wmst和其他,对于高德选择xyz,其他参数待查
    • zmin/zmax: 缩放等级
  • 构建url参数有两种方法:
    • 使用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;
}

在这里插入图片描述
在这里插入图片描述

离线高德影像地图

瓦片原理
  • 瓦片就是一堆图片,怎么对这堆图片进行编号,是目前主流互联网地图商分歧最大的地方。总结起来分为四个流派:
    • 谷歌XYZ:Z表示缩放层级,Z=zoom;XY的原点在左上角,X从左向右,Y从上向下。
    • TMS:开源产品的标准,Z的定义与谷歌相同;XY的原点在左下角,X从左向右,Y从下向上。
    • QuadTree:微软Bing地图使用的编码规范,Z的定义与谷歌相同,同一层级的瓦片不用XY两个维度表示,而只用一个整数表示,该整数服从四叉树编码规则
    • 百度XYZ:Z从1开始,在最高级就把地图分为四块瓦片;XY的原点在经度为0纬度位0的位置,X从左向右,Y从下向上。

下图显示了前三个流派在zoom=1层级上的瓦片编号结果:
在这里插入图片描述

服务描述XML文件
  • 通过创建本地服务描述XML文件访问服务,详情见链接
<GDAL_WMS>
    <Service name="TMS"> 
	<ServerUrl>file:///home/t/gis/ld_qgis_demos/bin/maps/gaode20230630//${z}/${y}/${x}.png</ServerUrl>
    </Service>
    <DataWindow>
        <UpperLeftX>-180</UpperLeftX>
        <UpperLeftY>90</UpperLeftY>
        <LowerRightX>180</LowerRightX>
        <LowerRightY>-90</LowerRightY>
        <TileLevel>2</TileLevel>
        <YOrigin>top</YOrigin>
    </DataWindow>
    <Projection>EPSG:4326</Projection>
    <BlockSizeX>256</BlockSizeX>
    <BlockSizeY>256</BlockSizeY>
    <BandsCount>3</BandsCount>
    <Cache />
</GDAL_WMS>
  • ServerUrl:描述本地瓦片地址路径
    在这里插入图片描述
QGis导入离线地图
  • 选择tms.xml
    在这里插入图片描述
    在这里插入图片描述
代码导入
  • 重点是构建正确的xml文件
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("<GDAL_WMS>"
                     "<Service name=TMS><ServerUrl>%1</ServerUrl></Service>"
                     "<DataWindow>"
                     "<UpperLeftX>-180</UpperLeftX><UpperLeftY>90</UpperLeftY><LowerRightX>180</LowerRightX><LowerRightY>-90</LowerRightY>"
                     "<TileLevel>2</TileLevel><YOrigin>top</YOrigin>"
                     "</DataWindow>"
                     "<Projection>EPSG:4326</Projection><BlockSizeX>256</BlockSizeX><BlockSizeY>256</BlockSizeY><BandsCount>3</BandsCount><Cache />"
                             "</GDAL_WMS>").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<QgsRasterLayer*>();
}

在这里插入图片描述
在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雷动软件工作室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值