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?
Or a labeling style like this: Or like this in world map spherical projection:
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?
Or a labeling style like this: Or like this in world map spherical projection:
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:
Red - the solution you're looking for: densified grid in EPSG:4326
(parallels); black - for comparision only: rectangular grid in the project CRS, EPSG:3003
:
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 interval
and 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
.
Like this, the densified grid will show correctly in any projection of the map canvas (project CRS) - here in EPSG:3035
/ETRS89-extended / LAEA Europe:
Label the desified lines (parallel grid) created in step 2. In the label settings, go to Placement tab and set the mode to Curved
.
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:
The densified grid from above appears (correctly) as curved lines:
Comparision between both variants from above - quite a difference. See here for why that is so: