I am wondering if there is a way to display coordinates for each vertex of a polygon by only using expressions, without creating a new layer. So this question is basically inspired by Displaying vertex coordinates of a polygon on a map in QGIS and enhancing it.
I thought about creating an array containing all vertices as geometry. So I have created this expression:
array_foreach( -- Go throuth every element of the following array
string_to_array(geom_to_wkt(nodes_to_points($geometry)),','), -- Create the array of WKT information splitted by comma [ 'MultiPoint ((0.2974026 51.8987013)', '(0.00909091 51.50... ]
make_point( -- Create a point geometry for every array content
to_real(if(
length(regexp_substr( -- Only create X coordinate if
regexp_substr(@element,'\\d.*\\d.[0-9]'),'([^ ]+)'))>0, -- everything between the Brackets of 'MultiPoint ((0.2974026 51.8987013)' before the whitespace '0.2974026' is not empty like ''
to_real(regexp_substr(regexp_substr(@element,'\\d.*\\d.[0-9]'),'([^ ]+)')), -- Extract the X coordinate of 'MultiPoint ((0.2974026 51.8987013)' --> 0.2974026
NULL -- If invalid coordinate use NULL, maybe replace with 0
)),
to_real(if(
length(regexp_substr( -- Only create Y coordinate if
regexp_substr(@element,'\\d.*\\d.[0-9]'),'(?<=\\s).*'))>0, -- everything between the Brackets of 'MultiPoint ((0.2974026 51.8987013)' after the whitespace '51.8987013' is not empty like ''
to_real(regexp_substr(regexp_substr(@element,'\\d.*\\d.[0-9]'),'(?<=\\s).*')), -- Extract the Y coordinate of 'MultiPoint ((0.2974026 51.8987013)' --> 51.8987013
NULL -- If invalid coordinate use NULL, maybe replace with 0
))
)
)
Which returns an array like [ <geometry: Point>, <geometry: Point>, <geometry: Point>, <geometry: Point>, ... ]
, which represents all the vertex of the polygon. One can easily extract X and Y coordinates out of it by adding x()
or y()
in front of make_point()
, or by just adding another array_foreach()
like array_foreach(*expression above*,x(@element))
.
How could I use such an array to label every vertex with its coordinates? I thought of extracting them from the array, but cant iterate over it. Would this be possible? Or something similar? I am kind of stuck now...
2 Answers 2
There is a way to display the coordinates... though not as a label.
One can add style with geometry generator
to extract the vertices, then add a font marker
style that will be overridden to display the vertices coordinates..
- add the vertices
Add a style of type geometry generator
, geometry type point
computed with the expression nodes_to_points( $geometry)
- Style it as a
Font Marker
- Instruct to display the coordinates
Scroll down and click the box to the right of character(s)
to edit the data-defined override. Enter the following expression
round(x( geometry_n( $geometry, @geometry_part_num )),4) || ' - ' || round(y( geometry_n( $geometry, @geometry_part_num )),4)
Let's break it down a bit:
geometry_n( $geometry, @geometry_part_num ))
--> get the nth
geometry from the one being rendered. From step 1, the geometry being rendered is an array of point (each vertices). Because we use @geometry_part_num
, it is applied on every part (= on every vertex).
x(..)
and y(...)
-> the x/y coordinates of the point
round(..)
--> let's not display 18 decimals :-)
|| ' - ' ||
--> Concatenate the X and Y coordinates, separate them with a -
-
3Bravo, works perfectly! I would add for future readers that at 3.16.1 I did not initially see the "... epsilon besides character(s).." Instead, I saw the default button (not sure what to call it!). However, clicking on that default button and selecting Edit... brought up the Expression String Builder window, into which the expression can be written. At that point the default button displays the epsilon symbol, as circled in the answer.Stu Smith– Stu Smith2020年12月04日 19:46:25 +00:00Commented Dec 4, 2020 at 19:46
-
Great @JGH However confusing that in QGIS, vertices are refered to differently depending on context: normally, they are called vertices. In the expression
nodes_to_points
they are refered to as nodes, whereasgeometry_part_num
names them geometry part - good to remember!Babel– Babel2020年12月04日 20:46:03 +00:00Commented Dec 4, 2020 at 20:46 -
@babel Indeed! Though the
geometry_part
is more generic as it could refer to polygons or else (like a generated multiple ring buffer)JGH– JGH2020年12月04日 20:55:04 +00:00Commented Dec 4, 2020 at 20:55 -
OK, so indeed geometry_part is not exclusively for vertices. Still, there is another name: in the expression
point_n(geometry,index)
vertices are refered to as points.Babel– Babel2020年12月04日 21:11:32 +00:00Commented Dec 4, 2020 at 21:11 -
Now thats one clever trick! And works with lines as well :)MrXsquared– MrXsquared2020年12月04日 22:31:35 +00:00Commented Dec 4, 2020 at 22:31
There is still something to copy from OpenJUMP (and improve). In OpenJUMP vertex XY is available as a decoration. Unfortunately the font or the numbers is tiny and there is no user interface for changing it.
EDIT
I was reading the question too fast and used wrong decorations first.
Explore related questions
See similar questions with these tags.
nodes_to_points($geometry)
) but can't have vertex coordinates.