I am trying to build a plugin to load a print composer from file, generate an atlas and export to image. So far I have been successful in loading the template and exporting it to image.
I have been unable to add any of the layers in the legend (which are also in the toc) to the exported map, which results in a blank map and none of the field expressions working.
# Get layers in the legend and append, must be a cleaner way to do this?
layers = self.iface.legendInterface().layers()
layerStringList = []
for layer in layers:
layerID = layer.id()
layerStringList.append(layerID)
# Add layer to map render
myMapRenderer = QgsMapRenderer()
myMapRenderer.setLayerSet(layerStringList)
myMapRenderer.setProjectionsEnabled(False)
# Load template
myComposition = QgsComposition(myMapRenderer)
myFile = os.path.join(os.path.dirname(__file__), 'MMR_Template.qpt')
myTemplateFile = file(myFile, 'rt')
myTemplateContent = myTemplateFile.read()
myTemplateFile.close()
myDocument = QDomDocument()
myDocument.setContent(myTemplateContent)
myComposition.loadFromTemplate(myDocument)
# Save image
myImagePath = os.path.join(os.path.dirname(__file__), 'come_on.png')
myImage = myComposition.printPageAsRaster(0)
myImage.save(myImagePath)
Here is a snippet from the loaded template which should setup the atlas:
I am also unsure of the best way to add all the layer in the toc to the instance of QgsMapRenderer().
Thanks
Answer
If anyone is interested here is the code I ended up with. This will turn on/off specific layers in the table of contents (from a list of layers), load a selected composer template from file, generate an atlas and export the map. Finally, returning the table of contents to its original state.
def sort_toc(self):
# Turn on/off layers as required by search type
legend = self.iface.legendInterface()
layers = legend.layers()
wanted_layers = metal_wanted
global turn_on, turn_off, atlas_desktop
turn_off = []
turn_on = []
all_layers = []
for layer in layers:
layername = layer.name()
all_layers.append(layername)
layerid = layer.id()
if layername == "desktop_search":
atlas_desktop = layer
if layername in wanted_layers and legend.isLayerVisible(layer) is False:
turn_off.append(layer)
legend.setLayerVisible(layer, True)
if layername not in wanted_layers and legend.isLayerVisible(layer) is True:
turn_on.append(layer)
legend.setLayerVisible(layer, False)
else:
pass
# Checks for required layers missing from map file
for layer in wanted_layers:
missing = []
if layer not in all_layers:
missing.append(layer)
else:
pass
if not missing:
pass
else:
QMessageBox.warning(self.iface.mainWindow(), "Missing layers", "Required layers are missing from your map file. Details: %s" % (str(missing)))
return atlas_desktop
def quick_export(self, ref, stype, scale):
# Add all layers in map canvas to render
myMapRenderer = self.iface.mapCanvas().mapRenderer()
# Load template from file
myComposition = QgsComposition(myMapRenderer)
myFile = os.path.join(os.path.dirname(__file__), 'MMR_Template.qpt')
myTemplateFile = file(myFile, 'rt')
myTemplateContent = myTemplateFile.read()
myTemplateFile.close()
myDocument = QDomDocument()
myDocument.setContent(myTemplateContent)
myComposition.loadFromTemplate(myDocument)
# Get map composition and define scale
myAtlasMap = myComposition.getComposerMapById(0)
myAtlasMap.setNewScale(int(scale))
# Setup Atlas
myAtlas = QgsAtlasComposition(myComposition)
myAtlas.setCoverageLayer(atlas_desktop) # Atlas run from desktop_search
myAtlas.setComposerMap(myAtlasMap)
myAtlas.setFixedScale(True)
myAtlas.fixedScale()
myAtlas.setHideCoverage(False)
myAtlas.setFilterFeatures(True)
myAtlas.setFeatureFilter("reference = '%s'" % (str(ref)))
myAtlas.setFilterFeatures(True)
# Generate atlas
myAtlas.beginRender()
for i in range(0, myAtlas.numFeatures()):
myAtlas.prepareForFeature( i )
jobs = r"\\MSUKSERVER\BusinessMan Docs\Jobs"
job_fol = os.path.join(jobs, str(ref))
output_jpeg = os.path.join(job_fol, ref + "_BMS_plan.jpg")
myImage = myComposition.printPageAsRaster(0)
myImage.save(output_jpeg)
myAtlas.endRender()
def return_toc(self):
# Revert layers back to pre-script state (on/off)
legend = self.iface.legendInterface()
for wanted in turn_on:
legend.setLayerVisible(wanted, True)
for unwanted in turn_off:
legend.setLayerVisible(unwanted, False)
No comments:
Post a Comment