How to return multiple lines with geopandas given a DataFrame with two lat/long values

Viewed 613

I built a python program that will siphon through my email and retrieve lat/long pairs of worksites that will be relevant for future analysis. At the moment I have the following dataframe returned.

                lat1              long1              lat2              long2
0          29.886283         -97.932083         29.892553         -97.921784
1          29.890503         -97.940304         29.891903         -97.938405
2           30.56325         -97.661213         30.570474         -97.651814
3          29.890692         -97.954414         29.891938         -97.952977
4          29.890564         -97.938196         29.892173         -97.936506
..               ...                ...               ...                ...
63  29.8900381016903  -97.9450610026556  29.8906241085088  -97.9442241534448
64  29.8847283631397  -97.9325702241829  29.8873980640358  -97.9291477254781
65         30.556555         -97.659824         30.569138         -97.650855
66         30.556555         -97.659824         30.569138         -97.650855
67         29.890564         -97.938196         29.892173         -97.936506
[68 rows x 4 columns]

My issue is that I cannot figure out how to turn these points into multi-lines, and ultimately poylgons using the GeoSeries.envelope function. Using the documentation I was able to create GeoDataFrame points with one set of lat/long pairs, like so...


print(df)
gdf = geopandas.GeoDataFrame(
    df, geometry=geopandas.points_from_xy(df.long1, df.lat1)) #df.lat2, df.long2))
print(gdf.head())

world = geopandas.read_file(geopandas.datasets.get_path(('naturalearth_lowres')))
ax = world[world.continent == 'North America'].plot(
    color = 'white', edgecolor = 'black')

gdf.plot(ax = ax, color='green')

plt.show()

That gives the following output:

0  29.886283  -97.932083  29.892553  -97.921784  POINT (-97.93208 29.88628)
1  29.890503  -97.940304  29.891903  -97.938405  POINT (-97.94030 29.89050)
2   30.56325  -97.661213  30.570474  -97.651814  POINT (-97.66121 30.56325)
3  29.890692  -97.954414  29.891938  -97.952977  POINT (-97.95441 29.89069)
4  29.890564  -97.938196  29.892173  -97.936506  POINT (-97.93820 29.89056)

But I can not seem to figure out how to return these values as lines using lat/long pairs.

I was expecting to see a comparable function to "points_from_xy" in the documentation that would generate a Multi-Line GeoDataFrame, but I don't believe any such function exists.

Any words of wisdom and/or links to documentation would be very much appriciated.

1 Answers

There is no pre-built way for your exact transformation, so you have to create your geometry objects yourself. I assume you meant one LineString object per row in in your DataFrame. With little typing, you could create such a column using the powerful apply method.

from shapely.geomtry import LineString
series = df.apply(
    lambda r: LineString([
         (r['long1'], r['lat1']),
         (r['long2'], r['lat2'])
    ]),
    axis=1
)

and with that convert it to a GeoSeries:

In [28]: geopandas.GeoSeries(series)
Out[28]:
0    LINESTRING (29.886 -97.932, 29.893 -97.922)
1    LINESTRING (29.891 -97.940, 29.892 -97.938)
2    LINESTRING (30.563 -97.661, 30.570 -97.652)
3    LINESTRING (29.891 -97.954, 29.892 -97.953)
4    LINESTRING (29.891 -97.938, 29.892 -97.937)
dtype: geometry

If I had the coordinates initially as a plain Python data structure (e.g. a list of tuple), I probably would first prepare a simple list of LineString objects, and only drop that into the (geo)pandas machinery once you specificially need its processing/plotting power.

Related