This document discusses advanced atlas map production techniques in QGIS, including:
- Using data defined overrides to customize atlas outputs
- Creating atlases from memory layers or CSV files
- Adding dynamic page items like system and atlas variables to labels
- Filtering atlas features to only include those covered by relevant background maps
- Calculating or labeling adjacent atlas tile references by writing custom functions or rule-based styling
The document provides code examples and discusses pros and cons of different approaches.
24. How to filter atlas
features where there is
no relevant
background map
25. • You need to have a single layer showing extents of coverage for all layers
in your atlas list.
• For LandMark layers you should have a coverage grid layer per epoch. If
you are using other layers such as aerial imagery, plotting sheets or
DTMs you might have to generate extent polygons yourself (gdaltindex
maybe?).
• Once you have coverages for all of your layers:
• dissolve and merge each one so that you have a single feature on
each layer.
• Create an attribute containing the layer name.
• Merge all the layers together so you have a single layer with one
feature per layer, with an attribute identifying which layer it relates to.
26. Now you can alter the query used to create a virtual layer to:
select s.*, l.* from landmark_layers l
inner join merged_grids g
on l.grid_name = g.name
cross join sites s
where INTERSECTS(s.geometry, g.geometry)
So before we do the cross join between our list of layers and our
site feature we’re joining the coverage layer to the list based on
the layer name attribute.
Then we only add features to the virtual layer where the site
boundary intersects with the relevant feature on the
merged_grids layer.
Note: This query could be simplified if you permanantly joined
landmark_layers to merged_grids.
27. How to show adjacent
tile references on
composer
28. At least 3 approaches:
• Calculate adjacent values for all tiles and populate as new columns
on layer. http://gis.stackexchange.com/questions/214300/how-to-determine-neighbouring-tile-ids-in-
qgis/215179#215179
• Calculate values on the fly using label expressions and function.
• Don’t calculate anything, just style it
29. Calculate on the fly
1. Add a label and click Insert an
expression
2. On the Function Editor
tab create a new function
called getAdjacentTileID
and paste code from next
slide
30. @qgsfunction(args="auto", group='Custom')
def getAdjacentTileID(geomAtlas, gridLayerName, gridLayerAttr, tilePos, feature, parent):
gridLayer = QgsMapLayerRegistry.instance().mapLayersByName(gridLayerName)[0]
if geomAtlas is None:
return 0
if gridLayer is None:
raise Exception("Layer not found: " + gridLayerName)
rect = geomAtlas.boundingBox()
gridSize = rect.xMaximum() - rect.xMinimum()
if (tilePos.upper() not in ['N', 'S', 'E', 'W', 'NE', 'NW', 'SE', 'SW']):
raise Exception("Invalid Tile Position: " + tilePos)
atlasCentroid = geomAtlas.centroid().asPoint()
atlasX = atlasCentroid.x()
atlasY = atlasCentroid.y()
if tilePos.upper() in ['N', 'NE', 'NW']:
adjY = atlasY + gridSize
elif tilePos.upper() in ['S', 'SE', 'SW']:
adjY = atlasY - gridSize
else :
adjY = atlasY
if tilePos.upper() in ['NE', 'E', 'SE']:
adjX = atlasX + gridSize
elif tilePos.upper() in ['NW', 'W', 'SW']:
adjX = atlasX - gridSize
else :
adjX = atlasX
adjGeom = QgsGeometry.fromPoint(QgsPoint(adjX,adjY))
for f in gridLayer.getFeatures():
if f.geometry().intersects(adjGeom):
return f[gridLayerAttr]
return ' '
31. 3. On the expression tab enter:
getAdjacentTileID(@atlas_geometry, ‘Grid’, ‘id’, ‘N’)
Where Grid is the name of the atlas layer, id is the attribute to use
for the label and N is the adjacent grid position. Create labels for
values as needed (valid options are N, E, S, W, NE, NW, SE, SW)
● Will only work on square grids
but could be modified for other
shapes.
● Provides flexibility to place
labels anywhere or use values
within other labels
● Means values are calculated
every time atlas is run vs
calculating once and storing
with data (downside)
32. Styling
● Rule based styling for atlas layer, shades out all but current atlas feature
● Rule based labeling labels all BUT the atlas feature
33. Ensure map frame is square and set margin around feature
to 10%
● No calculations needed
and no changes to any
data.
● QGIS styling and labelling
options give lots of
flexibility but more limiting
than calculating label
values