Upload
shaun-lewis
View
74
Download
0
Embed Size (px)
Citation preview
QGIS Print Composer & Advanced Atlas Production
Data Defined OveridesQGIS’ Secret Superhero?
Creating a basic atlas
Snazzing it up
http://gis.stackexchange.com/questions/152296/how-to-count-points-within-the-current-print-composer-atlas-feature-in-qgis-2-8
Creating an atlas of historic epochs for Land Contamination desk studies.
Memory layer
CSV
Create Atlas Coverage
select s.*, l.* from sites scross join landmark_layers l
Digitise Site
Composer Settings
‘sites|’ || attribute(@atlas_feature, ‘name’)
Dynamic page itemsSystem variables
Dynamic page itemsAtlas variables
More on QGIS Variables
http://nyalldawson.net/2015/12/exploring-variables-in-qgis-2-12-part-1/
Atlas Results
QGIS Print Composer &
Advanced Atlas Production
Follow Up Questions
How to filter atlas features where
there is no relevant background map
• 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.
Now you can alter the query used to create a virtual layer to:
select s.*, l.* from landmark_layers linner join merged_grids gon l.grid_name = g.namecross join sites swhere 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.
How to show adjacent tile
references on composer
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
Calculate on the fly1. 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
@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 + gridSizeelif tilePos.upper() in ['S', 'SE', 'SW']:
adjY = atlasY - gridSizeelse :
adjY = atlasYif tilePos.upper() in ['NE', 'E', 'SE']:
adjX = atlasX + gridSizeelif tilePos.upper() in ['NW', 'W', 'SW']:
adjX = atlasX - gridSizeelse :
adjX = atlasXadjGeom = QgsGeometry.fromPoint(QgsPoint(adjX,adjY))for f in gridLayer.getFeatures():
if f.geometry().intersects(adjGeom):return f[gridLayerAttr]
return ' '
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)
Styling● Rule based styling for atlas layer, shades out all but current atlas
feature
● Rule based labeling labels all BUT the atlas feature
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
Any questions please contact me on [email protected]