4

Windows 10, PyCharm, QGIS 3.10 installed via osgeo4w (64bit).

I set up a simple QGIS composer layout with a vector layer and a WMS base map on the map layout. The vector layer contains about 10 polygon features and is used as the ‘coverage’ layer for the Atlas generation. The project, vector layer and the WMS base map are all in the same projection CRS: 27700.

I use this python code to export all 10 Atlas images from a standalone script:

import os, sys, glob

# clear output folder of existing export images
files = glob.glob('D:\Tasks_D\QGIS_core_test\exports\*')
for f in files:
    os.remove(f)

#modify environment variables to find qgis and qt plugins during qgis.core import
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = r'C:\OSGeo4W64\apps\Qt5\plugins'
os.environ['PATH'] += r';C:\OSGeo4W64\apps\qgis\bin;C:\OSGeo4W64\apps\Qt5\bin;C:\OSGeo4W64\bin'
os.environ['OSGEO4W_ROOT'] = r'C:\OSGeo4W64'
os.environ['PYTHONPATH'] = r'C:\OSGeo4W64\apps\qgis\python'
os.environ['PYTHONHOME'] = r'C:\OSGeo4W64\apps\Python37'
os.environ['PROJ_LIB'] = r'C:\OSGeo4W64\share\proj'
sys.path.extend([r'C:\OSGeo4W64\apps\qgis\python',r'C:\OSGeo4W64\apps\Python37\lib\site-packages'])
os.environ['OSGEO4W'] = r'C:\OSGeo4W64'

from qgis.core import QgsApplication, QgsProject, QgsLayoutExporter
print("modules imported")

def export_atlas(qgs_project_path, layout_name, output_folder):

    # Open existing project
    project = QgsProject.instance()
    project.read(qgs_project_path)

    print(f'Project in "{project.fileName()} loaded successfully')

    # Open prepared layout that as atlas enabled and set
    layout = project.layoutManager().layoutByName(layout_name)

    # Export atlas
    exporter = QgsLayoutExporter(layout)
    settings = QgsLayoutExporter.ImageExportSettings()
    exporter.exportToImage(layout.atlas(),output_folder, 'tif', settings)

def main():
    # Start a QGIS application without GUI
    qgs = QgsApplication([], False)
    qgs.initQgis()

    project_path = 'D:/Tasks_D/QGIS_core_test/qgis_core_test.qgs'
    output_folder = 'D:/Tasks_D/QGIS_core_test/exports/'
    layout_name = 'qgiscore'

    export_atlas(project_path, layout_name, output_folder)

    # Close the QGIS application
    qgs.exitQgis()

if __name__ == "__main__":
    main()

print("done")

My problem is that the base map doesn’t show, instead each tif has a blank white background (tried a few different wms sources just to check too). The vector coverage layer does show. If I were to export the atlas normally from the QGIS composer GUI, the export image file display correctly.

I also get multiple ‘cannot find proj.db’ errors. Even though I’ve set as a environment variable the folder containing proj.db. Each error appears in the PyCharm console multiple times and include:

proj_create_from_database: Cannot find proj.db
proj_identify: Cannot find proj.db
pj_obj_create: Cannot find proj.db
proj_coordoperation_is_instantiable: Cannot find proj.db
ERROR 1: PROJ: proj_create_from_wkt: Cannot find proj.db
ERROR 1: PROJ: proj_as_wkt: Cannot find proj.db
ERROR 1: PROJ: proj_create_from_name: Cannot find proj.db

How can I get my code running as required? With no errors and basemap WMS layers showing...

UPDATE1: I've been exploring further and found that other shapefile layers added to the map do show in the exports, shapefiles in a different projection (say WGS84) do not show (even though they do show correctly in the QGIS gui). So my code does seem to have trouble reprojecting layers. Still doesn't explain why my EPSG:27700 WMS layers aren't showing...

UPDATE 2: pyqgis isn't recognising any WMS layer as a valid layer. Regardless of the projection, no layer displays on the export image files. To test in python, it errors:

from qgis.core import *

layer = QgsVectorLayer("D:\\Tasks_D\\QGIS_core_test\\shps\\sites.shp", "testlayer_shp", "ogr")
if not layer.isValid():
    print ("Layer is NOT valid!")
else:
    print ("Layer is valid")

url = 'contextualWMSLegend=0&crs=EPSG:27700&dpiMode=7&featureCount=10&format=image/jpeg&layers=Opencast.coal.prospecting.sites&styles&url=https://map.bgs.ac.uk/arcgis/services/GeoIndex_Onshore/boreholes/MapServer/WmsServer'
layer = QgsRasterLayer(url, "testlayer_wms" "wms")
if not layer.isValid():
    print ("Layer is NOT valid!")
else:
    print ("Layer is valid")

The shapefile vector produces a valid layer message but the WMS fails, with error:

ERROR4:`contextualWMSLegend=0&crs=EPSG:27700&dpiMode=7&featureCount=10&format=image/jpeg&layers=Opencast.coal.prospecting.sites&styles&url=https://map.bgs.ac.uk/arcgis/services/GeoIndex_Onshore/boreholes/MapServer/WmsServer' does not exist in the file system, and is not recognized as a supported dataset name.`
  • Taking a stab in the dark, feels like the WMS layer is being reprojected on the fly to match your CRS/atlas CRS and then you have your proj.db file location problem getting in the way of the reprojection. Does your problem persist if you temporarily set the project CRS to match that of the WMS layer? – Houska Dec 17 '19 at 23:40
  • @Houska I'll update my question details but- project CRS, WMS CRSs are both the same (BNG 27700) – Theo F Dec 18 '19 at 8:57
  • hmm. Following breadcrumbs at the cookbook ("in case you create an independent application you need to set paths correctly with QgsApplication.setPrefixPath(), otherwise it will fail to find the database.") and this thread, maybe try setting setPrefixPath()? And try a few dummy CRS operations in your script (from the same cookbook page) to see if they fail too? – Houska Dec 18 '19 at 10:49
  • Beside of setting environnement variable test your wms layer layer.isValid(). Is it valid ? – SIGIS Dec 19 '19 at 11:23
  • @SIGIS where do I use that code? In QGIS? – Theo F Dec 19 '19 at 20:45

Your Answer

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

Browse other questions tagged or ask your own question.