Thursday 17 October 2019

gdal - Exporting QGIS Atlas using PyQGIS (qgis.core)


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.`



No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...