Proper syntax for a pydeck PathLayer from a shapely geometry

Question:

I see the example of a PathLayer and it shows the input data is a list of lists within a regular pandas df, as opposed to a geopandas df.

Let’s say I’m coming from a GeoPandas df (let’s say called consline) that has a shapely MULTILINESTRING geometry column. What’s the proper/best syntax to use that? I tried different combinations between calling it a PathLayer and a GeoJsonLayer with using the get_path parameter and nothing seemed to work except for doing json.loads(consline.geometry.to_json())['features'][0]['geometry']['coordinates']

The consline can be loaded as

consline=gpd.read_file("https://github.com/deanm0000/SOexamples/raw/main/consline.gpkg")

For instance, this doesn’t work:

mylayers=[
    pdk.Layer(
        'PathLayer',
        data=consline,
        get_path="geometry",
        pickable=True,
        get_fill_color=[0,255,0],
        width_scale=20,
        width_min_pixels=2,   
    )
]
view_state = pdk.ViewState(
    longitude=-98.99,
    latitude=31.79,
    zoom=5,
    min_zoom=1,
    max_zoom=15)
r = pdk.Deck(layers=mylayers, initial_view_state=view_state, map_style='light')
r.to_html("example.html")

but this does:

mylayers=[
    pdk.Layer(
    'PathLayer',
    data=json.loads(consline.geometry.to_json())['features'][0]['geometry']['coordinates'],
    get_path="-",
    pickable=True,
    get_fill_color=[0,255,0],
    width_scale=20,
    width_min_pixels=2,
)
]
view_state = pdk.ViewState(
    longitude=-98.99,
    latitude=31.79,
    zoom=5,
    min_zoom=1,
    max_zoom=15)
r = pdk.Deck(layers=mylayers, initial_view_state=view_state, map_style='light')
r.to_html("example.html")

I can’t imagine having shapely convert it to json and then python to convert it to a dict and then have pydeck convert it back to json for deck.gl is the best way to do this but I can’t get it to work any other way.

Asked By: Dean MacGregor

||

Answers:

You can set data to an object having the shape described for the deck.gl PathLayer.

Using shapely, you can merge the MULTILINESTRING to a LINESTRING.
Then pass along its coordinates.

With default get_path option set to d => d.path

import shapely as shp

consline_geoseries = consline.geometry.iloc[0]
consline_linestring = shp.ops.linemerge(consline_geoseries)
data = [{'path': list(consline_linestring.coords)}]

mylayers=[
    pdk.Layer(
        'PathLayer',
        data=data,
        pickable=True,
        get_fill_color=[0,255,0],
        width_scale=20,
        width_min_pixels=2,   
    )
]

With default get_path set to -

import shapely as shp

consline_multilinestring = consline.geometry.iloc[0]
consline_linestring = shp.ops.linemerge(consline_multilinestring)
data = [list(consline_linestring.coords)]

mylayers=[
    pdk.Layer(
        'PathLayer',
        data=data,
        get_path='-',
        pickable=True,
        get_fill_color=[0,255,0],
        width_scale=20,
        width_min_pixels=2,   
    )
]

If you don’t want to use shapely, you can pass the MULTILINESTRING as a data list of LINESTRING.

consline_multilinestring = consline.geometry[0]
mylayers=[
    pdk.Layer(
        'PathLayer',
        data=[list(geom.coords) for geom in consline_multilinestring.geoms],
        get_path="-",
        pickable=True,
        get_fill_color=[0,255,0],
        width_scale=20,
        width_min_pixels=2,   
    )
]
Answered By: Oluwafemi Sule
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.