tom colley - qgis print composer & advanced atlas production

Post on 23-Jan-2017

75 Views

Category:

Software

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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 t.colley@npt.gov.uk

top related