当前位置:   article > 正文

Qgis二次开发-加载高德在线地图失败报错Raster layer Cannot instantiate the ‘wms‘ data provider_qgis 二次开发 加载在线地图

qgis 二次开发 加载在线地图

1.加载在线的高德地图

以下是在线高德地图地址。

http://webrd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8

以下是代码示例:

  1. #include <QApplication>
  2. #include <QMainWindow>
  3. #include "qgisinterface.h"
  4. #include "qgsproviderregistry.h"
  5. #include "qgsrasterlayer.h"
  6. #include "qgsproject.h"
  7. #include "qgsmapcanvas.h"
  8. int main(int argc, char *argv[])
  9. {
  10. // 初始化QGIS
  11. QgsApplication app(argc, argv, true);
  12. app.initQgis();
  13. // 创建主窗口
  14. QMainWindow mainWindow;
  15. mainWindow.setWindowTitle("QGIS with Amap");
  16. // 创建地图Canvas
  17. QgsMapCanvas* mapCanvas = new QgsMapCanvas(&mainWindow);
  18. mapCanvas->setCanvasColor(Qt::white);
  19. mapCanvas->setVisible(true);
  20. mapCanvas->setFrameStyle(0);
  21. mainWindow.setCentralWidget(mapCanvas);
  22. // 创建栅格图层
  23. QgsRasterLayer* amapLayer = new QgsRasterLayer("http://webrd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8", "Amap", "wms");
  24. if (amapLayer->isValid())
  25. {
  26. QgsProject::instance()->addMapLayer(amapLayer);
  27. QgsRectangle extent = amapLayer->extent();
  28. mapCanvas->setExtent(extent);
  29. }
  30. else
  31. {
  32. QMessageBox::critical(&mainWindow, "Error", "Could not load Amap layer.");
  33. return -1;
  34. }
  35. // 设置地图范围和投影
  36. QgsCoordinateReferenceSystem crs("EPSG:3857");
  37. mapCanvas->setDestinationCrs(crs);
  38. mapCanvas->enableAntiAliasing(true);
  39. // 显示主窗口
  40. mainWindow.show();
  41. // 执行QGIS事件循环
  42. return app.exec();
  43. }

结果运行结果无效并报错:

Raster layer Cannot instantiate the 'wms' data provider

大概的意思就是说不能初始化wms的东西,就是wms的相关驱动没有加载好。

解决办法:

1.设置路径

  1. //设置前缀路径
  2. QgsApplication app(argc, argv, true);
  3. app.setPrefixPath("E:/OSGeo4W/apps/qgis-ltr-dev", true);
  4. app.initQgis();

2.将驱动文件拷贝到运行目录下

不需要设置setPrefixPath()。

将E:/OSGeo4W/apps/qgis-ltr-dev/plugins目录拷贝到生成程序的运行目录下,因为程序启动起来加载的是本地的plugins下的插件。

注意不要拷贝错了,我下载的目录下有两个qgis目录,你使用的哪个路径下的库来编译的程序,就拷贝哪个路径下的plugins目录,否则有可能导致程序起不来。

2.如果url填入不能进行正常加载

提供一个编码url的类

  1. #ifndef QGSXYZCONNECTION_H
  2. #define QGSXYZCONNECTION_H
  3. #include <QStringList>
  4. struct QgsXyzConnection
  5. {
  6. QString name;
  7. QString url;
  8. int zMin = -1;
  9. int zMax = -1;
  10. // Authentication configuration id
  11. QString authCfg;
  12. // HTTP Basic username
  13. QString username;
  14. // HTTP Basic password
  15. QString password;
  16. // Referer
  17. QString referer;
  18. // tile pixel ratio (0 = unknown (not scaled), 1.0 = 256x256, 2.0 = 512x512)
  19. double tilePixelRatio = 0;
  20. bool hidden = false;
  21. QString encodedUri() const;
  22. };
  23. //! Utility class for handling list of connections to XYZ tile layers
  24. class QgsXyzConnectionUtils
  25. {
  26. public:
  27. //! Returns list of existing connections, unless the hidden ones
  28. static QStringList connectionList();
  29. //! Returns last used connection
  30. static QString selectedConnection();
  31. //! Saves name of the last used connection
  32. static void setSelectedConnection( const QString &connName );
  33. //! Returns connection details
  34. static QgsXyzConnection connection( const QString &name );
  35. //! Removes a connection from the list
  36. static void deleteConnection( const QString &name );
  37. //! Adds a new connection to the list
  38. static void addConnection( const QgsXyzConnection &conn );
  39. };
  40. #endif // QGSXYZCONNECTION_H
  41. #include <qgslogger.h>
  42. #include "qgsxyzconnection.h"
  43. #include <qgsdatasourceuri.h>
  44. #include <qgssettings.h>
  45. QString QgsXyzConnection::encodedUri() const
  46. {
  47. QgsDataSourceUri uri;
  48. uri.setParam( QStringLiteral( "type" ), QStringLiteral( "xyz" ) );
  49. uri.setParam( QStringLiteral( "url" ), url );
  50. if ( zMin != -1 )
  51. uri.setParam( QStringLiteral( "zmin" ), QString::number( zMin ) );
  52. if ( zMax != -1 )
  53. uri.setParam( QStringLiteral( "zmax" ), QString::number( zMax ) );
  54. if ( ! authCfg.isEmpty() )
  55. uri.setAuthConfigId( authCfg );
  56. if ( ! username.isEmpty() )
  57. uri.setUsername( username );
  58. if ( ! password.isEmpty() )
  59. uri.setPassword( password );
  60. if ( ! referer.isEmpty() )
  61. uri.setParam( QStringLiteral( "referer" ), referer );
  62. if ( tilePixelRatio != 0 )
  63. uri.setParam( QStringLiteral( "tilePixelRatio" ), QString::number( tilePixelRatio ) );
  64. return uri.encodedUri();
  65. }
  66. QStringList QgsXyzConnectionUtils::connectionList()
  67. {
  68. QgsSettings settings;
  69. QStringList connList;
  70. settings.beginGroup( QStringLiteral( "qgis/connections-xyz" ) );
  71. connList = settings.childGroups();
  72. const QStringList global = settings.globalChildGroups();
  73. settings.endGroup();
  74. for ( const auto &s : global )
  75. {
  76. settings.beginGroup( "qgis/connections-xyz/" + s );
  77. bool isHidden = settings.value( QStringLiteral( "hidden" ), false ).toBool();
  78. settings.endGroup();
  79. if ( isHidden )
  80. {
  81. connList.removeOne( s );
  82. }
  83. }
  84. return connList;
  85. }
  86. QString QgsXyzConnectionUtils::selectedConnection()
  87. {
  88. QgsSettings settings;
  89. return settings.value( QStringLiteral( "qgis/connections-xyz/selected" ) ).toString();
  90. }
  91. void QgsXyzConnectionUtils::setSelectedConnection( const QString &name )
  92. {
  93. QgsSettings settings;
  94. return settings.setValue( QStringLiteral( "qgis/connections-xyz/selected" ), name );
  95. }
  96. QgsXyzConnection QgsXyzConnectionUtils::connection( const QString &name )
  97. {
  98. QgsSettings settings;
  99. settings.beginGroup( "qgis/connections-xyz/" + name );
  100. QgsXyzConnection conn;
  101. conn.name = name;
  102. conn.url = settings.value( QStringLiteral( "url" ) ).toString();
  103. conn.zMin = settings.value( QStringLiteral( "zmin" ), -1 ).toInt();
  104. conn.zMax = settings.value( QStringLiteral( "zmax" ), -1 ).toInt();
  105. conn.authCfg = settings.value( QStringLiteral( "authcfg" ) ).toString();
  106. conn.username = settings.value( QStringLiteral( "username" ) ).toString();
  107. conn.password = settings.value( QStringLiteral( "password" ) ).toString();
  108. conn.referer = settings.value( QStringLiteral( "referer" ) ).toString();
  109. conn.tilePixelRatio = settings.value( QStringLiteral( "tilePixelRatio" ), 0 ).toDouble();
  110. conn.hidden = settings.value( QStringLiteral( "hidden" ) ).toBool();
  111. return conn;
  112. }
  113. void QgsXyzConnectionUtils::deleteConnection( const QString &name )
  114. {
  115. QgsSettings settings;
  116. settings.remove( "qgis/connections-xyz/" + name );
  117. settings.beginGroup( QStringLiteral( "qgis/connections-xyz" ) );
  118. QStringList global = settings.globalChildGroups();
  119. if ( global.contains( name ) )
  120. {
  121. QgsSettings settings;
  122. settings.beginGroup( "qgis/connections-xyz/" + name );
  123. settings.setValue( QStringLiteral( "hidden" ), true );
  124. }
  125. }
  126. void QgsXyzConnectionUtils::addConnection( const QgsXyzConnection &conn )
  127. {
  128. QgsSettings settings;
  129. bool addHiddenProperty = false;
  130. settings.beginGroup( QStringLiteral( "qgis/connections-xyz" ) );
  131. QStringList global = settings.globalChildGroups();
  132. if ( global.contains( conn.name ) )
  133. {
  134. addHiddenProperty = true;
  135. }
  136. settings.endGroup();
  137. settings.beginGroup( "qgis/connections-xyz/" + conn.name );
  138. settings.setValue( QStringLiteral( "url" ), conn.url );
  139. settings.setValue( QStringLiteral( "zmin" ), conn.zMin );
  140. settings.setValue( QStringLiteral( "zmax" ), conn.zMax );
  141. settings.setValue( QStringLiteral( "authcfg" ), conn.authCfg );
  142. settings.setValue( QStringLiteral( "username" ), conn.username );
  143. settings.setValue( QStringLiteral( "password" ), conn.password );
  144. settings.setValue( QStringLiteral( "referer" ), conn.referer );
  145. settings.setValue( QStringLiteral( "tilePixelRatio" ), conn.tilePixelRatio );
  146. if ( addHiddenProperty )
  147. {
  148. settings.setValue( QStringLiteral( "hidden" ), false );
  149. }
  150. }

使用:

  1. QgsXyzConnection xyz;
  2. xyz.url = QStringLiteral("http://webrd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8");
  3. xyz.zMin = 0;
  4. xyz.zMax = 18;
  5. xyz.tilePixelRatio = 1.0;
  6. QgsXyzConnectionUtils::addConnection(xyz);
  7. QString url2 = xyz.encodedUri();
  8. qDebug() << "url2 = " << url2;
  9. QgsRasterLayer *layer = addRasterLayerPrivate(url2, QStringLiteral("ocr0"), QStringLiteral("wms"));

3.加载不了的看这里

看了评论有一些同学加载失败,以下是我整理的一个完整例子,加载失败最大的原因,我认为就是Qgis的相关运行库、驱动库没有拷贝完整。我把运行路径也截图了,可以照着参考。

加载高德地图成功效果图

自定义WQgsMapCanvas类

  1. #pragma once
  2. #include <qgsmapcanvas.h>
  3. #include <qgsrasterlayer.h>
  4. #include <QMouseEvent>
  5. #include <QPaintEvent>
  6. #include <qgspoint.h>
  7. #include <qgsmaptoolpan.h>
  8. #include <qgsrubberband.h>
  9. #include <qgsgeometry.h>
  10. #include <QDebug>
  11. #include <QList>
  12. #include <QWheelEvent>
  13. class WQgsMapCanvas : public QgsMapCanvas
  14. {
  15. Q_OBJECT
  16. public:
  17. WQgsMapCanvas(const QString &url,QWidget *parent = nullptr);
  18. ~WQgsMapCanvas();
  19. private:
  20. QgsRasterLayer *addRasterLayer(const QString &rasterFile, const QString &baseName);
  21. QgsRasterLayer *addRasterLayerPrivate(const QString &uri, const QString &name, const QString &providerKey);
  22. public:
  23. bool isExistRect = false;
  24. QRectF qRectf;
  25. protected:
  26. //void wheelEvent(QWheelEvent*event);
  27. private:
  28. QgsRasterLayer *m_layer = nullptr; //图层
  29. };
  30. #include "WQgsMapCanvas.h"
  31. #include <qgsmapcanvas.h>
  32. #include <qgsmaptoolidentify.h>
  33. #include <qgsmaptool.h>
  34. #include <qgssymbollayer.h>
  35. #include <qgsannotationmarkeritem.h>
  36. #include <qgsannotationlayer.h>
  37. #include <qgsmarkersymbollayer.h>
  38. #include <qgssinglesymbolrenderer.h>
  39. #include <qgsrubberband.h>
  40. #include <qgsannotationpointtextitem.h>
  41. #include <qgsmapcanvasannotationitem.h>
  42. #include <qgstextannotation.h>
  43. #include <QTextDocument>
  44. #include "QgsMapToolSelectItem.h"
  45. #include <QRegularExpression>
  46. #include "qgsxyzconnection.h"
  47. #include <qglobal.h>
  48. QgsRasterLayer *WQgsMapCanvas::addRasterLayer(const QString &rasterFile, const QString &baseName)
  49. {
  50. return addRasterLayerPrivate(rasterFile, baseName, QString());
  51. }
  52. QgsRasterLayer *WQgsMapCanvas::addRasterLayerPrivate(const QString &uri, const QString &name, const QString &providerKey)
  53. {
  54. QString shortName = name;
  55. QRegularExpression reRasterFile(QStringLiteral("^/vsi(.+/)*([^ ]+)( .+)?$"), QRegularExpression::CaseInsensitiveOption);
  56. QRegularExpressionMatch matchRasterFile = reRasterFile.match(name);
  57. if (matchRasterFile.hasMatch())
  58. {
  59. if (!matchRasterFile.captured(2).isEmpty())
  60. {
  61. shortName = matchRasterFile.captured(2);
  62. }
  63. }
  64. QgsSettings settings;
  65. QString baseName = settings.value(QStringLiteral("qgis/formatLayerName"), false).toBool() ? QgsMapLayer::formatLayerName(shortName) : shortName;
  66. //QgsDebugMsgLevel("Creating new raster layer using " + uri
  67. // + " with baseName of " + baseName, 2);
  68. QgsRasterLayer *layer = nullptr;
  69. // XXX ya know QgsRasterLayer can snip out the basename on its own;
  70. // XXX why do we have to pass it in for it?
  71. // ET : we may not be getting "normal" files here, so we still need the baseName argument
  72. if (!providerKey.isEmpty() && uri.endsWith(QLatin1String(".adf"), Qt::CaseInsensitive))
  73. {
  74. QFileInfo fileInfo(uri);
  75. QString dirName = fileInfo.path();
  76. layer = new QgsRasterLayer(dirName, QFileInfo(dirName).completeBaseName(), QStringLiteral("gdal"));
  77. }
  78. else if (providerKey.isEmpty())
  79. layer = new QgsRasterLayer(uri, baseName); // fi.completeBaseName());
  80. else
  81. layer = new QgsRasterLayer(uri, baseName, providerKey);
  82. QString title;
  83. bool ok = false;
  84. if (!layer->isValid())
  85. {
  86. QgsError error = layer->error();
  87. title = "Invalid Layer";
  88. qDebug() << error.message(QgsErrorMessage::Text);
  89. }
  90. if (layer)
  91. layer->loadDefaultMetadata(ok);
  92. return layer;
  93. }
  94. QList<QgsMapLayer *> g_layers;
  95. QList<QgsMapLayer *> g_tempLayer;
  96. bool g_is3857crs = false;
  97. WQgsMapCanvas::WQgsMapCanvas(const QString &url,QWidget *parent /*= nullptr*/)
  98. : QgsMapCanvas(parent)
  99. {
  100. setCanvasColor(QColor(255, 255, 255));
  101. QgsRasterLayer *layer = nullptr;
  102. if (url.contains("http"))
  103. {
  104. QgsXyzConnection xyz;
  105. xyz.url = url;
  106. xyz.zMin = 0;
  107. xyz.zMax = 18;
  108. xyz.tilePixelRatio = 1.0;
  109. QgsXyzConnectionUtils::addConnection(xyz);
  110. QString url2 = xyz.encodedUri();
  111. layer = addRasterLayerPrivate(url2, "OSM", "wms");
  112. if (!layer->isValid())
  113. {
  114. QgsError error = layer->error();
  115. qDebug() << error.message(QgsErrorMessage::Text);
  116. }
  117. }
  118. else
  119. {
  120. layer = new QgsRasterLayer(url); // fi.completeBaseName());
  121. }
  122. if (!layer->isValid())
  123. {
  124. QgsError error = layer->error();
  125. qDebug() << error.message(QgsErrorMessage::Text);
  126. }
  127. QgsCoordinateReferenceSystem crs = layer->crs();
  128. if (crs.authid().contains("3857"))
  129. {
  130. g_is3857crs = true;
  131. }
  132. qDebug() << "crs = " << crs.authid();
  133. this->setDestinationCrs(crs);
  134. g_layers.append(layer);
  135. g_tempLayer.append(layer);
  136. setExtent(layer->extent());
  137. enableAntiAliasing(true);
  138. setLayers(g_layers);
  139. this->zoomToFullExtent();
  140. refresh();
  141. }
  142. WQgsMapCanvas::~WQgsMapCanvas()
  143. {
  144. }

调用:

  1. m_canvas = new WQgsMapCanvas("http://webrd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=8");
  2. setCentralWidget(m_canvas);

运行路径截图

 剩下的就是qgis运行的动态库了

查看完整的配置: 目录3

https://sunnnnnn666.blog.csdn.net/article/details/131816730

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/235914
推荐阅读
相关标签
  

闽ICP备14008679号