使用 pydeck 的 PathLayer(或 TripLayer)从 GeoDataFrame 绘制 LINESTRING Z

Plot LINESTRING Z from GeoDataFrame using pydeck's PathLayer (or TripLayer)

我有一个包含 LINESTRING Z 几何的地理数据框:

TimeUTC Latitude Longitude AGL geometry
0 2021-06-16 00:34:04+00:00 42.8354 -70.9196 82.2 LINESTRING Z (42.83541343273769 -70.91961015378617 82.2, 42.83541343273769 -70.91961015378617 82.2)
1 2021-06-14 13:32:18+00:00 42.8467 -70.8192 66.3 LINESTRING Z (42.84674080836037 -70.81919357049679 66.3, 42.84674080836037 -70.81919357049679 66.3)
2 2021-06-18 23:56:05+00:00 43.0788 -70.7541 0.9 LINESTRING Z (43.07882882269921 -70.75414567194126 0.9, 43.07884601143309 -70.75416286067514 0, 43.07885174101104 -70.75416286067514 0, 43.07884028185512 -70.75415713109717 0, 43.07884601143309 -70.75414567194126 0, 43.07884601143309 -70.75414567194126 0)

我可以使用 pydeck 的 ScatterplotLayer 使用原始数据绘制组件点 (不是地理)数据框,但我还需要绘制完整、平滑的轨迹。

我试过这个:

        layers = [ 
pdk.Layer(
    type = "PathLayer",
    data=tracks,
    get_path="geometry",
    width_scale=20,
    width_min_pixels=5,
    get_width=5,
    get_color=[180, 0, 200, 140],
    pickable=True,
    ),
]
view_state = pdk.ViewState(
    latitude=gdf_polygon.centroid.x,
    longitude=gdf_polygon.centroid.y,
    zoom=6,
    min_zoom=5,
    max_zoom=15,
    pitch=40.5,
    bearing=-27.36)

r = pdk.Deck(layers=[layers], initial_view_state=view_state)
return(r)

默默地失败了。尽我所能,我找不到一种方法来转换 LINESTRING Z(如果需要的话我可以不用 Z 组件)到一个对象 pydeck 会接受。

我找到了一种从 GeoPandas 中提取所需信息并使其在 pydeck 中工作的方法。您只需要 apply 一个从 shapely 几何图形中提取坐标的函数作为列表。这是一个完全可重现的例子:

import shapely
import numpy as np
import pandas as pd
import pydeck as pdk
import geopandas as gpd


linestring_a = shapely.geometry.LineString([[0,1,2],
                                            [3,4,5],
                                            [6,7,8]])

linestring_b = shapely.geometry.LineString([[7,15,1],
                                            [8,14,2],
                                            [9,13,3]])

multilinestring = shapely.geometry.MultiLineString([[[10,11,2],
                                                     [13,14,5],
                                                     [16,17,8]],
                                                    [[19,10,11],
                                                     [12,15,4],
                                                     [10,13,0]]])



gdf = gpd.GeoDataFrame({'id':[1,2,3],
                        'geometry':[linestring_a,
                                    linestring_b,
                                    multilinestring],
                        'color_hex':['#ed1c24',
                                     '#faa61a',
                                     '#ffe800']})

# Function that transforms a hex string into an RGB tuple.
def hex_to_rgb(h):
    h = h.lstrip("#")
    return tuple(int(h[i : i + 2], 16) for i in (0, 2, 4))

# Applying the HEX-to-RGB function above
gdf['color_rgb'] = gdf['color_hex'].apply(hex_to_rgb)

# Function that extracts the 2d list of coordinates from an input geometry
def my_geom_coord_extractor(input_geom):
    if (input_geom is None) or (input_geom is np.nan):
        return []
    else:
        if input_geom.type[:len('multi')].lower() == 'multi':
            full_coord_list = []
            for geom_part in input_geom.geoms:
                geom_part_2d_coords = [[coord[0],coord[1]] for coord in list(geom_part.coords)]
                full_coord_list.append(geom_part_2d_coords)
        else:
            full_coord_list = [[coord[0],coord[1]] for coord in list(input_geom.coords)]
        return full_coord_list

# Applying the coordinate list extractor to the dataframe
gdf['coord_list'] = gdf['geometry'].apply(my_geom_coord_extractor)

gdf_polygon = gdf.unary_union.convex_hull 

# Establishing the default view for the pydeck output
view_state = pdk.ViewState(latitude=gdf_polygon.centroid.coords[0][1], 
                           longitude=gdf_polygon.centroid.coords[0][0], 
                           zoom=4)

# Creating the pydeck layer
layer = pdk.Layer(
    type="PathLayer",
    data=gdf,
    pickable=True,
    get_color='color_rgb',
    width_scale=20,
    width_min_pixels=2,
    get_path="coord_list",
    get_width=5,
)

# Finalizing the pydeck output
r = pdk.Deck(layers=[layer], initial_view_state=view_state, tooltip={"text": "{id}"})
r.to_html("path_layer.html")

这是它产生的输出:

重要警告

pydeck 似乎无法处理 MultiLineString 几何图形。请注意,在上面的示例中,我的原始数据框有 3 个几何图形,但在屏幕截图中只绘制了 2 条线。