I'm trying to make curved labels based on map projection. As in these examples, I would like labels for point layers to follow parallels. Is that possible in QGIS 3?
It is possible. The way I know how to do it is in a roundabout way that requires using geometry generator and expressions. In the following screenshot example, you can see it in action. What I did:
Created a project and load a basemap just for visualization
Created two layers with EPSG:4326 CRS (the line layer for visualization with a few vertices all Y coordinates at the same 45° value, the point layer to contain a point with its label). This could be any geographic coordinates system if you want your labels to align with parallels
Set the labels up and went to the placement tab
Checked the geometry generator box, set it to Polyline/Multiline and changed general settings placement mode to Curved
In the geometry generator textbox, entered this expression:
make_line( make_point( $x - 2,$y), make_point( $x - 1.5,$y), make_point( $x - 1,$y), make_point( $x - 0.5,$y), make_point( $x,$y), make_point( $x + 0.5,$y), make_point( $x + 1,$y), make_point( $x + 1.5,$y), make_point( $x + 2, $y) )
Now you can change your project CRS to a system that will show parallels as curves and the labels on the point layer should align with them. The label in my example looks linear but it is curved. It should be parallel to the red line. Of course only the vertices on lines are reprojected on the fly so if you want a finer curve, you need to add more vertices.
Maybe there's a better way, but this will work. Basically, I created a line just like the red one, but as the virtual geometry that the label is supposed to be based on. In the example, the final project CRS is EPSG:6622, which is a Lambert conical system.
You can add a function to QGIS that will rotate your labels along parallels, as described in the answer to this question: Parameters of the coordinate system for calculating the rotation of labels along latitude lines
The solution to your question in fact needs two steps:
- Create a grid that shows parallels correctly in any projection as curved lines, not rectangular ones (depending on projection of map canvas) - see first screenshot.
- Apply a curved label on that parallels, following the curved shapes of the parallels.
Proceed as follows (steps 1-2 create the grid, step 3 the curved label):
Create the parallels:
Menu Vector > Research Tools > Create grid, grid type = Line, Grid CRS = EPSG:4326 (this is important to get real parallels). Define the desired spacing (in degrees), e.g. 1 [degree].
Densifiy the grid - use
Menu Processing > Toolbox > Densify by intervaland define a fraction of the spacing from above, e.g. 0.0001 (should be several powers of ten smaller then the spacing, like here: 1000 times). Alternatively, use
Densify by count.
Label the desified lines (parallel grid) created in step 2. In the label settings, go to Placement tab and set the mode to
You can now freely change the projection the map canvas appears in by changing the Project CRS (not the layer CRS): the label will always follow the curved parallels.
See here how to create parallel grids:
Project CRS (map canvas) in
EPSG:7794: creating a line grid in
EPSG:4326 creates straight lines, but the grid is not rectangular (it would be so with project CRS/map canvas in
EPSG:4326). If you created a grid in the same CRS as the project CRS (here:
EPSG:7794), the grid would be rectangular:
Comparision between both variants from above - quite a difference. See here for why that is so: