Exploring The QGIS Expression Engine, Part 8: Expression Controlled Styles

A screenshot directly from QGIS

 

 While it can be confusing for some (web)mappers, but not all GIS projects use EPSG:4326 or EPSG:3857(900913). This is due to the existence of other coordinate reference systems, some of them more suited for use in a local (city/state/country) focused project.

I recently came across a question in the Israeli QGIS Facebook group asking how can the user show the coordinates (he did not specify, so let's assume we're talking about map center) in Input's screen. This is possible if you a "dashboard" layer to display the coordinates at the corner of the map (or the center if you really don't want to se what you are doing). 

Pseudo dashboards in QGIS are a (relatively) recent idea which was thought of by Tim Sutton from Kartoza, you can check out his video about creating a dashboard below or check out the example dashboard he added to QGIS Hub.

 

This post is mostly written for novice users who need just a small bit from the dashboard and rather read and not rummage through the project or watch the video.  So let's get started with a new project.

Since we wanted to test showing the map's center coordinates in the project CRS we'll start by creating a project, and because we want to show those coordinates in Input, let's try creating the new project with the QGIS Mergin plugin and name it testDashboard.




You should now have a project with an OpenStreetMap background and a survey layer for point collection.


What we should do now is focus around the area we are going to use in our project, I'm going to focus further and include all of Israel in my designated area.

I'll create a new polygon layer, preferably in the same GeoPackage the survey layer is in.
The new layer doesn't really need any attributes, and it will host only feature.
If you plan on using the same GeoPackage, make sure you add a new layer and don't overwrite the entire file.
Now I'm not sure why, but the dashboard layer only works when its CRS is EPSG:4326, but since it only has one geometry and QGIS support on the fly reprojection, we shouldn't really care.





We now draw a large polygon around the entire area we expect our field survey will use, you can just cover the entire world if you don't want to fill restricted. You shouldn't fill obligated to make the polygon look good or have straight angles, we're not going to be looking at it for long.



Save your edits and let's move on to the layer styling panel, where we'll make the layer show the center map coordinates at the bottom left corner of our canvas.

You can switch the the symbol type to No Symbol and move on to the labeling tab of the layer styling panel.
We'll first create a label that reports the coordinates of the map center using a simple expression.
What the following expression does is take the coordinates of the map center (which is a variable that returns a point geometry, you don't have to find it every time you pan or zoom the map) and builds a string that displays its X and Y.

    'X: '+ to_string(round(x(@map_extent_center),2))+'\n'+
  'Y: '+ to_string(round(y(@map_extent_center),2))



I also recommend adding a background so you can see the text, you should probably set it so the text is readable based on your basemap. Just switch over to the Background tab in the labeling section of the layer styling panel.
You should probably use a fixed size for the background and play around with it until you get something you're happy with.


 

Now let's move on to setting the position of our label, so we can finally see where it is.
Switching to the position tab we are going to set our Mode to Offset from point, and now let's set the position with an expression.
You can play around with the points to figure which corner of the map works for you, I like the coordinates at the bottom right so I use the second point (indices in the expression engine start at 1), and for some reason we have to transform it to EPSG:4326, I don't know why, but this method simply doesn't work with other CRSs.

The expression is :
    transform(
        point_n(@map_extent,2), -- extract just one point from the bounds
        @map_crs,'EPSG:4326' - transform from whatever CRS you use
    )




We should also set the offset X and Y, you can do this manually but it will probably look different on a different size screen (i.e. mobile) so we can use an expression that will return the offsets in Meters, so change the offset type to Meters at Scale.
The expression for the offsets uses the map width and height and returns a percentage of them, you can play with the numbers to set to different positions but the basic expression is this:

to_string(@map_extent_width *-0.2)+','
+to_string(@map_extent_height *-0.2)


 

It should offset the label by 20% from the bottom right corner of the screen.


My project now looks like this in QGIS:


 

And like this in Input:


You can use similar methods to further style your projects look and feel or use more elaborate expressions to determine the position and size of the label so it would look different in mobile.

The image at the start of the post is just an example of what you can do with the @map_extent variable to have your own custom canvas style.

You can find the Mergin project I used to test these tricks (with the expressions inside), here.

You can check out the posts in this series and learn more about the QGIS expression  engine, and if you have your own cool uses for expression I'd love to hear about them in the comments.

Exploring The QGIS Expression Engine, Part 1: Getting Values From JSON & HSTORE

Exploring The QGIS Expression Engine, Part 2: What's Missing From Select By Location 

Exploring The QGIS Expression Engine, Part 3: Writing Custom Expression Functions

Exploring The QGIS Expression Engine, Part 4: Selecting By Attributes And Location With One Expression

Exploring The QGIS Expression Engine, Part 5: Fun With Arrays

Exploring The QGIS Expression Engine, Part 6: Creating And Using Variables

Exploring The QGIS Expression Engine, Part 7: Cross-Layer Relationships 

Comments