Search code examples
geopandasshapely

Access Z coordinate in a LINESTRING Z in geopandas?


I have a GeoDataFrame with a LINESTRING Z geometry where Z is my altitude for the lat/long. (There are other columns in the dataframe that I deleted for ease of sharing but are relevant when displaying the resulting track)

    TimeUTC Latitude    Longitude   AGL geometry
    0   2021-06-16 00:34:04+00:00   42.835413   -70.919610  82.2    LINESTRING Z (-70.91961 42.83541 82.20000, -70...

I would like to find the maximum Z value in that linestring but I am unable to find a way to access it or extract the x,y,z values in a way that I can determine the maximum value outside of the linestring.

line.geometry.bounds only returns the x,y min/max.

The best solution I could come up with was to turn all the points into a list of tuples:

points = line.apply(lambda x: [y for y in x['geometry'].coords], axis=1)

And then find the maximum value of the third element:

from operator import itemgetter
max(ft2,key=itemgetter(2))[2]

I hope there is a better solution available.

Thank you.


Solution

  • You can take your lambda function approach and just take it one step further:

    import numpy as np
    line['geometry'].apply(lambda geom: np.max([coord[2] for coord in geom.coords]))
    

    Here's a fully reproducible example from start to finish:

    import shapely
    import numpy as np
    import geopandas as gpd
    
    linestring = shapely.geometry.LineString([[0,0,0],
                                              [1,1,1],
                                              [2,2,2]])
    
    gdf = gpd.GeoDataFrame({'id':[1,2,3],
                            'geometry':[linestring,
                                        linestring,
                                        linestring]})
    
    gdf['max_z'] = (gdf['geometry']
                    .apply(lambda geom: 
                           np.max([coord[2] for coord in geom.coords])))
    
    

    In the example above, I create a new column called "max_z" that stores the maximum Z value for each row.

    Important note

    This solution will only work if you exclusively have LineStrings in your geometries. If, for example, you have MultiLineStrings, you'll have to adapt the function I wrote to take care of that.