0

(I have since found a solution and added it as an answer)

I am currently creating my first Plugin for QGIS using the 'Plugin Builder'Plugin, QtDesigner and Python. At this point it's just supposed to create a raster layer from WMS for the extent of a chosen layer and a 1km zone around it.

The wms_url I get via the print command works both in the QGIS WMS menu and the browser (example), the layer created using it in the next line isn't valid however and I can't figure out why.

  1. Imports etc: (The last 3 lines are from the top answer of this question as it seems to be the same issue, it didn't solve anything for me though.)
from os import system
from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication
from qgis.PyQt.QtGui import *
from qgis.PyQt.QtWidgets import QAction, QFileDialog
from qgis.core import *
import processing
from .resources import *
from .flight_planner_dialog import UASFlightPlannerDialog
import os.path
qgis_prefix="C:\\Program Files\\QGIS 3.26.3\\apps\\qgis"
QgsApplication.setPrefixPath(qgis_prefix, True) 
QgsApplication.initQgis()

(I skipped some stuff generated by the Plugin Builder (and I think QtDesigner) here)

  1. Context for the variables in the WMS URL (shouldn't be the issue, but just in case):
flightpath = self.dlg.mMapLayerComboBox.currentLayer()
destCrs = QgsCoordinateReferenceSystem(25832)
flightpathCrs = QgsCoordinateReferenceSystem(flightpath.crs())
ext = flightpath.extent()
if destCrs != flightpathCrs:
         tform = QgsCoordinateTransform(flightpathCrs, destCrs, QgsProject.instance())
         ext = tform.transform(ext)
bboxwest = round(ext.xMinimum())-1000
bboxsouth = round(ext.yMinimum())-1000
bboxeast = round(ext.xMaximum())+1000
bboxnorth = round(ext.yMaximum())+1000
height = bboxnorth-bboxsouth
width = bboxeast-bboxwest
  1. The part that doesn't work:
wms_url = 'url=https://uas-betrieb.de/geoservices/dipul/wms?service=WMS&version=1.3.0&request=GetMap&layers=dipul:wohngrundstuecke&bbox='+str(bboxwest)+','+str(bboxsouth)+','+str(bboxeast)+','+str(bboxnorth)+'&width='+str(width)+'&height='+str(height)+'&srs=EPSG:25832&transparent=true&format=image/png&styles='
print (wms_url)
rgeozones = QgsRasterLayer(wms_url, 'rgeozones', 'wms')
print(rgeozones.isValid())
11
  • I can't find the question just now, but yesterday there was a similar question (with a WFS, I believe) and the solution was to remove url= from the beginning of the wms_url string.
    – Matt
    Commented Nov 10, 2022 at 17:49
  • May not affect you for this WMS but note that bbox for WMS is in minx,miny,maxx,maxy order where x is the first listed axis in the CRS and y the second, it isn't always west,south,east,north
    – nmtoken
    Commented Nov 10, 2022 at 17:51
  • also note the values for transparent are TRUE or FALSE i.e. case sensitive, the default value is false, so transparent=true may give a non-transparent image
    – nmtoken
    Commented Nov 10, 2022 at 17:53
  • for WMS version 1.3.0 you should use CRS not SRS to define the coordinate reference system
    – nmtoken
    Commented Nov 10, 2022 at 17:56
  • @Matt thanks for the suggestion, but removing the url= just adds a error message for me. Translated to english it would be something like: "Property request failed: The protocol "" is unknown" From what I could find online, url= is for some reason needed for WMS, but not for WFS. @nmtoken thank you as well, I applied your suggestions, however it didn't solve the problem.
    – JannisM
    Commented Nov 11, 2022 at 8:51

1 Answer 1

1

The URL needs a slightly different syntax in Python than in both the web browser and the WMS menu in QGIS. There were two seperate issues:

  1. @nmtoken was indeed right, the dipul: breaks it, but only in Python.
  2. In my actual Code I request about a dozen layers, not just one. I omitted this detail in the question because I thought it was irrelevant and just reduced readability. While in the web browser and the menu you can simply seperate them with a comma &layers=layername1,layername2,layername3&styles&, in python you have to call each one seperately &layers=layername1&layers=layername2&layers=layername3&styles&styles&styles&. There also has to be the same amount of styles& as layers=layername&.

So the relevant bit now looks like this:
Note that the URL produced by this code doesn't work in web browsers/the WMS menu.

wms_url = 'url=https://uas-betrieb.de/geoservices/dipul/wms?service=WMS&version=1.3.0&request=GetMap&layers=flugplaetze&styles&layers=flughaefen&styles&layers=kontrollzonen&styles&layers=flugbeschraenkungsgebiete&styles&layers=bundesautobahnen&styles&layers=bundesstrassen&styles&layers=bahnanlagen&styles&layers=binnenwasserstrassen&styles&layers=seewasserstrassen&styles&layers=schifffahrtsanlagen&styles&layers=wohngrundstuecke&styles&layers=freibaeder&styles&layers=industrieanlagen&styles&layers=kraftwerke&styles&layers=umspannwerke&styles&layers=stromleitungen&styles&layers=windkraftanlagen&styles&layers=justizvollzugsanstalten&styles&layers=militaerische_anlagen&styles&layers=labore&styles&layers=verfassungsorgane&styles&layers=oberste_behoerden&styles&layers=diplomatische_vertretungen&styles&layers=internationale_organisationen&styles&layers=polizei&styles&layers=sicherheitsbehoerden&styles&layers=krankenhaeuser&styles&layers=nationalparks&styles&layers=naturschutzgebiete&styles&layers=ffh-gebiete&styles&layers=vogelschutzgebiete&styles&bbox='+str(xMin)+','+str(yMin)+','+str(xMax)+','+str(yMax)+'&width='+str(width)+'&height='+str(height)+'&crs=EPSG:3857&transparent=TRUE&format=image/png&'
print(wms_url)
rgeozones = QgsRasterLayer(wms_url, 'rgeozones', 'wms')
rgeozones.setExtent(QgsRectangle(xMin,yMin,xMax,yMax))

The .setExtent() is needed because QGIS doesn't seem to care about my bounding box. It basically just crops the image.
I also changed the CRS to one that matches the GetCapabilities, however it still also works with EPSG: 25832.

Even before these changes I didn't get any actual error messages, it just didn't do anything. However with print (rgeozones.error().message()) I was able to find out, why the layer wasn't valid. I couldn't find a fix for this online, so I hope this post may help someone. It turned out to be because of the second issue. Error message:

WMS provider: Cannot calculate extent 
Raster layer: Provider is not valid (provider: wms, URI: <the uri of the wms request>)

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.