4

I am trying to add a XYZ Open Street Map tile into my QGIS project, using PyQGIS. I am currently trying to use PyCharm to start with, to see if my script is running correctly. I have looked through various other questions but none have worked successfully so far. I have also tried to add the link with %7Bz%7D/%7Bx%7D/%7By%7D instead of {z}/{x}/{y} but still no luck. The code works perfectly inside the QGIS Python Console but does not seem to run in PyCharm. My code is:

# Add Base Map
urlWithParams = 'type=xyz&url=https://tile.openstreetmap.org/{z}/{x}/{y}.png&zmax=19&zmin=0&crs=EPSG3857'
rlayer2 = QgsRasterLayer(urlWithParams, 'OpenStreetMap', 'wms')

rlayer2.isValid()
QgsProject.instance().addMapLayer(rlayer2)
print(QgsProject.instance().mapLayers())

But when I run the script, an error occurs as my other raster and vector layer is added, but the OpenStreetMap layer becomes invalid and is not added to my exported map, even though it tells me in the script that rlayer2.isValid (as can be seen below).

{'OpenStreetMap_9b914e8c_7637_411a_beea_397b7f36f2c8': <QgsRasterLayer: 'OpenStreetMap' (Invalid)>}

Wetransfer link - [1]: https://we.tl/t-RiNdhUOHrc

5
  • I have edited the question so that it contains a link to my full script through a wetransfer link.
    – LiamHems
    Jan 15 at 14:13
  • Maybe some firewall/blocking? Does this work: import urllib.request;req = urllib.request.Request("https://tile.openstreetmap.org/14/9975/8501.png", headers={'User-Agent':'Mozilla'});response = urllib.request.urlopen(req);print("request threw no error"). Jan 15 at 18:05
  • I guess the problem isn't about the project not adding OSM layer. It is added to the project. The problem might be crs. Jan 16 at 13:56
  • @bugmenot123 I have replaced the code I used above to your script and it comes back in the console, 'request threw no error' but it is not added to the exported map nor printed in the console when I ask to print map layers in project. Is there another step/code that I would have to write, to add it to the QgsProject.instance?
    – LiamHems
    Jan 16 at 15:22
  • @KadirŞahbaz I use the same code within a script in the QGIS python console and the base map is printed in that exported map. Both has the same crs - EPSG3857, so I am not too sure??
    – LiamHems
    Jan 16 at 15:24
6
+50

As you stated, OSM layer is added to the project. I found a solution (it worked for my toy data) after some trial and error. Since I don't have your data, I cannot guarantee that it will work for you.

  • Add project.setCrs(vlayer.crs()) after project = ... (line 179)

  • You can remove these lines:

    201 canvas = QgsMapCanvas()
    202 root = QgsProject.instance().layerTreeRoot()
    203 bridge = QgsLayerTreeMapCanvasBridge(root, canvas)
    

    and

    301 canvas = QgsMapCanvas()
    
  • Then try different scales for map and map2.

    208 map.setScale(30000000) # I used 50000000 for my map shown in the image 
    ...
    303 map2.setScale(100000000) # I used 100000000
    

enter image description here

7
  • Thank you for your help. I have added the piece of code you suggested after line 179 but only rlayer and vlayer is still added and not the base map. It still prints out the OpenStreetMap layer is 'invalid' whilst I print map layers (line 86). Have you got any more ideas?
    – LiamHems
    Jan 17 at 15:17
  • It works on my computer. I don't know. Also try to remove some lines I mentioned in the answer. Jan 17 at 18:42
  • I've truncated many parts of your code and added a toy data. If you share (if not restricted), I can try to find a solution using your code and data. Meanwhile, I use VS Code in Ubuntu. Jan 17 at 18:48
  • Is there a way I can message you/send the script to your privately? I have removed the lines but still no successful unfortunately, so I think if I share my script with you, then that probably would be the best method! Thank you very much for your help so far.
    – LiamHems
    Jan 17 at 20:49
  • I have sent you an email back now Kadir.
    – LiamHems
    Jan 18 at 15:42
2

You need to add the URL without urlencoding of the parameters that QGIS is supposed to update:

urlWithParams = 'type=xyz&url=https://tile.openstreetmap.org/{z}/{x}/{y}.png&zmax=19&zmin=0&crs=EPSG3857'
9
  • Unfortunately I have tried that and it still prints invalid layer for some reason... Is it meant to be {z}/{x}/{z} or should the last {z} be a {y}? I have tried this also and still no luck.
    – LiamHems
    Jan 11 at 13:37
  • 1
    That was a typo, thanks. Sorry, I don't know what else is wrong. Jan 11 at 13:42
  • No worries, thanks anyway!
    – LiamHems
    Jan 11 at 13:43
  • It works fine for me though. rlayer2.isValid() returns True and I can add the layer just fine with QgsProject.instance().addMapLayer(rlayer2). Jan 11 at 17:49
  • 1
    It works within the QGIS python console for me, just struggling to get it working in PyCharm/in a python script outside of QGIS.
    – LiamHems
    Jan 13 at 10:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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