2

The Goal

Generate maps based on communities (701), within districts (50). Overview map next to the main map that shows the district within the region (8). In the main map I only show the district that the community belongs to. The maps will be printed and the zoom needs to be on the district.

The Situation

I have followed How to generate multiple maps where one highlighted attribute changes? to highlight the map.

Used How to filter features in other layers of a QGIS Atlas? to filter out only the district that the community belongs to.

All works perfectly, now I create the Atlas and the maps are created. Problem now is that it zooms on the community, while we want to show the district as a whole with the community moving inside.

Possible workarounds

  1. In the attribute table, add a column with the scale and other columns to define the extents, per district. This would be manually and I have to do it 50 times.

Any idea if it is possible to zoom based on a layer outside the coverage layer, in this case the district layer?

2 Answers 2

3

You just have to add a user-defined extent of your main map. Setting the boundingbox of your district as reference.

In the 'item properties' of your main map click on the right side to open the rule-window and choose edit.

enter image description here

for the 'X min' value add following code (you have to change 'name_of_district_layer' to your layername)

x_min(aggregate(layer:='name_of_district_layer', aggregate:= 'collect', expression:=bounds($geometry), filter:=intersects( @atlas_geometry , $geometry )))

For the other values you do the same, but you have to change x_min by y_min, etc.

4
  • Tried it, got this error "Eval Error: No such aggregate 'collect' ". QGIS 2.18.0
    – Gertenbol
    Jul 17, 2018 at 14:43
  • 1
    Got it with x_min( geometry(get_feature('mli_admbnda_adm2_gov_ocha_itos','Admin2Name',attribute(@atlas_feature,'Admin2Name')))) . Thanks a lot Pieter!
    – Gertenbol
    Jul 17, 2018 at 15:30
  • @Gertenbol, the example is with QGIS 3
    – PieterB
    Jul 17, 2018 at 16:05
  • I have set up the whole thing in QGIS 3 now but your query gives different values back for every atlas item somehow. I have verified that I'm applying it to the district layer.
    – Gertenbol
    Jul 18, 2018 at 12:46
1

enter image description here

To visualize what I think you're asking, I'm using a county layer and a city layer. The city and county layers both have a county code attribute that we can link these with, but a regular join won't bring in the geometry of the county into the city layer for us. After bringing in the county and city layers into QGIS, we can use the QGIS DB Manager to produce the layer we want without generating a new file (unless we want to). The DB Manager is found in the Database menu.

enter image description here

Expand the Virtual Layers, then expand the QGIS layers to see the layers in your QGIS project. Click on the SQL window button to open the query tab as shown.

I will use the id column from the cities layer, the county name, the city name, and use the geometry from the county layer.

SELECT cities.gid, counties.county_nam, cities.corporatio,counties.geometry
FROM cities, counties
WHERE cities.county_cod=counties.county_cod
ORDER BY cities.county_cod,cities.corporatio

The ORDER BY line is optional, but makes it easier for me.

Click the Execute button. The table window will populate the result. When satisfied with the result, check the Load as new layer box. Check the Column with unique values box and use the id column (gid in my case). Check the Geometry column box and select the geometry column form the drop down if necessary.

Add a layer name to the Layer name (prefix) line (I've called mine county_geom here) and then click the Load button. This will add your newly conjured layer to your map. You'll notice a hit in draw performance because it is re-running the query the source layers. If the performance hit is too much, you can save the layer in your prefered format and use that.

As you've probably guessed, the county_geom layer has a county geometry for every city in the associated county. This layer is what we will build the atlas upon. At this point, you're probably seeing where this is going.

In the Layout window, select your new layer as the Coverage layer in the Atlas tab. Next, you'll need to determine a Page name that the city layer can match to. Since in my case the two layers only have the county_code column in common and not the county name I want, I will do a join on the city layer with the county layer to get the county name. And then with that I can use that to only show the city for the page.

For the Atlas page name, I'm using:

"corporatio" || '\n('|| "county_nam" ||' COUNTY)'

And for the Rule-based Symbology on the cities layer, I'm using:

"corporatio" || '\n('|| "counties_county_nam" ||' COUNTY)' =  @atlas_pagename

enter image description here

Then I duplicate the county_geom layer and do the same Rule-based symbology trick on it.

Now as we go through each page of the Atlas, it zooms to the county geometry from the county_geom layer, highlights the city on top of the highlighted county.

I hope this is clear enough and about what you were looking for.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.