1

I would like to create an array of a line's z-values to use as part of another expression. The z-values should be in the same order as the vertices, I would like to be able to use it as an input for min(), max() functions etc.

I have looked through the geometry and array expressions in the field calculator but I haven't found anything that works. I had an idea to count the number of points (nump_points($geometry)), and loop through the geometry pulling out z values at individual vertices but there's no loop function in the field calculator.

0

2 Answers 2

3

You can easily add a new function to get array of z-values from line vertices.

  1. Open Function Editor tab in Field Calculator (or Expression) window. Create a new function by clicking plus icon. Enter a file name, e.g. z_array_from_line.
  2. Copy/Paste the script. Then, click Save and Load Functions (or related button) to register the function. It's added 'Custom' group.

    from qgis.core import *
    from qgis.gui import *
    
    @qgsfunction(args=0, group='Custom')
    def get_z_array_from_line_vertices(value1, feature, parent):
        z_array = [p.z() for p in feature.geometry().vertices()]
        return z_array
    
  3. Now, you can use get_z_array_from_line_vertices() function in expressions.

The function gives you z-values in the same order as the vertices.

EDIT: But max() function in Expression is expecting set of values like max(1,2,3), not list or array like max([1,2,3]). If you need maximum value you can add python max() which excepts list to the definition of the function or save as a new one.

from qgis.core import *
from qgis.gui import *

@qgsfunction(args=0, group='Custom')
def max_z_value_from_line_vertices(value, feature, parent):
    z_array = [p.x() for p in feature.geometry().vertices()]
    return max(z_array)
2
  • Thanks. However when I try to use max() on the array it doesn't return anything, I think it's because max() is expecting a list or a set but not an array. How do I convert the array to a list? Commented Jul 25, 2019 at 12:31
  • You're right. But max() is expecting set of values like max(1,2,3), not list or array like max([1,2,3]). If you need maximum value you can add max to the new function. I edited the answer. Commented Jul 25, 2019 at 12:45
2

When you want a loop function, the closest option is usually one of the Aggregate functions.

Use the array_agg function, which "Returns an array of aggregated values from a field or expression." To get an array of Z values, use:

 array_agg( z( $geometry))

Your Answer

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

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