1

I'm developing a QGIS plugin in Python that lets you add layers from Web Map Services (WMS) to the canvas.

This feature does not work with certain layers of certain WMS services from QGIS Server.

When I use QGIS native features directly, the layers created are valid, but not when I use the following code, which works for many other WMS layers:

from qgis.core import QgsProject, QgsRasterLayer, QgsCoordinateReferenceSystem

wms_layer_url = "SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&layers=Une+belle+ligne&crs=EPSG:2154&format=image/png&styles=&TRANSPARENT=TRUE&BBOX=576227.8869208727,6450495.220395137,654285.1798996647,6858657.968743979&WIDTH=962&HEIGHT=847&url=https://carto.isogeo.net/qgisserver-test?"
wms_layer_title = "QGIS_Server_Layer"
layer = QgsRasterLayer(wms_layer_url, wms_layer_title)
QgsProject.instance().addMapLayer(layer)

When I run the above code, a layer is added to the layer manager, but the following error message is displayed:

IReadBlock failed at X offset 0, Y offset 0: GDALWMS: Unable to download block 0, 0. URL: HTTP status code: 0, error: (null). Add the HTTP status code to to ignore this error (see http://www.gdal.org/frmt_wms.html).

enter image description here

Going to the link indicated in the message, I realize that there is a tag that could allow me to indicate not to abort the request on receipt of an HTTP status code equal to 0.

Unfortunately, I haven't found it possible to implement this GDAL driver tag in my code with PyQGIS. I really don't want to add extra dependencies to my project to handle such a special case.

Has this problem ever been encountered by someone who has managed to get around it?

2
  • Your URL looks wrong to me - I would expect https://carto.isogeo.net/qgisserver-test? to come at the start not as a parameter called url at the end
    – Ian Turton
    Commented Oct 3, 2023 at 16:11
  • @IanTurton that's a (incorrect) QGIS layer URI not a WMS URL.
    – user2856
    Commented Oct 4, 2023 at 9:34

1 Answer 1

1

You're trying to use WMS query parameters as part of a QGS Datasource URI, you are missing the styles parameter and your layer parameter is incorrect. Instead use something like:

crs=EPSG:4326&format=image/jpeg&layers=Une%20belle%20ligne&styles=&url=https://carto.isogeo.net/qgisserver-test

Note that the URI is url encoded.

Or use QgsDataSourceUri:

from qgis.core import QgsProject
from qgis.core import QgsDataSourceUri
from qgis.core import QgsRasterLayer

wms_layer_title = "QGIS_Server_Layer"
wms_layer_config = dict(

    styles="",
    layers="Une belle ligne",
    crs="EPSG:4326",
    format="image/jpeg",
    url="https://carto.isogeo.net/qgisserver-test"
)

uri = QgsDataSourceUri()
for key, val in wms_layer_config.items():
    uri.setParam(key, val)

layer = QgsRasterLayer(bytes(uri.encodedUri()).decode(), wms_layer_title, "wms")
QgsProject.instance().addMapLayer(layer)

You can see what parameters can form part of the URI by adding a WMS layer manually via the Data Source Manager then opening the layer properties->source tab and viewing the URI that QGIS created.

2
  • Thank you very much for taking the time to answer me. It seems to work. But how can I specify parameters such as TRANSPARENT, BBOX or HEIGHT then ? Commented Oct 4, 2023 at 9:37
  • It seems that your code still works even if I add TRANSPARENT, BBOX, HEIGHT... and other parameters to wms_layer_config. I also realized that it was important to replace the "+" with a " " in the value of the "layers" parameter. Thanks again for your help Commented Oct 4, 2023 at 10:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.