Nabih Bawazir
Nabih Bawazir

Reputation: 7255

How to convert linestring to multiple longitude latitude column in geopandas

Here's my one row of input

Name                    geometry
Jalan W.R. Supratman    LINESTRING (95.317339 5.5603499, 95.3169007 5.5602832, 95.3165735 5.5602391, 95.3161729 5.5602097, 95.3161289 5.5601326, 95.3160873 5.5600178)

Here's my expected output

Name                                  Langitude         Longitude
Jalan W.R. Supratman                  95.317339         5.5603499
Jalan W.R. Supratman                  95.3169007        5.5602832
Jalan W.R. Supratman                  95.3165735        5.5602391
Jalan W.R. Supratman                  95.3161729        5.5602097
Jalan W.R. Supratman                  95.3161289        5.5601326
Jalan W.R. Supratman                  95.3160873        5.5600178

Edit:

Here's what I try

def utm_to_latlon(coords, zone_number, zone_letter):
    easting = coords[0]
    northing = coords[1]
    return utm.to_latlon(easting, northing, zone_number, zone_letter)

# Using nested list comprehension
df ["lat_lon_tuple"] = [[utm_to_latlon(xy, 44, "N") for xy in tuple(geom.coords)] for geom in df.geometry]

The error message

<ipython-input-5-4dfd2badb8b4> in <listcomp>(.0)
      5 
      6 # Using nested list comprehension
----> 7 df ["lat_lon_tuple"] = [[utm_to_latlon(xy, 44, "N") for xy in tuple(geom.coords)] for geom in df.geometry]

AttributeError: 'str' object has no attribute 'coords'

Upvotes: 2

Views: 2224

Answers (2)

Stef
Stef

Reputation: 30579

Explode with index and then apply Series:

import pandas as pd
import geopandas as gpd
from shapely.geometry import LineString

df = gpd.GeoDataFrame(
    {'Name': ['Jalan W.R. Supratman', 'Other Street'],
     'geometry': [LineString([(95.317339, 5.5603499), (95.3169007,5.5602832), (95.3165735, 5.5602391), (95.3161729,5.5602097), (95.3161289, 5.5601326), (95.3160873, 5.5600178)]),
                  LineString([(95.0, 6.0), (95.01, 6.01)])]})

print(df.set_index('Name').geometry
        .apply(lambda x: list(x.coords))
        .explode(ignore_index=False)
        .apply(pd.Series)
        .reset_index()
        .rename(columns={0: 'Langitude', 1: 'Longitude'}))

Result:

                   Name  Langitude  Longitude
0  Jalan W.R. Supratman  95.317339   5.560350
1  Jalan W.R. Supratman  95.316901   5.560283
2  Jalan W.R. Supratman  95.316574   5.560239
3  Jalan W.R. Supratman  95.316173   5.560210
4  Jalan W.R. Supratman  95.316129   5.560133
5  Jalan W.R. Supratman  95.316087   5.560018
6          Other Street  95.000000   6.000000
7          Other Street  95.010000   6.010000

Upvotes: 3

Michael Delgado
Michael Delgado

Reputation: 15432

You can convert the coordinates defining the LineString with the coords attribute, then convert this to a shapely.geometry.MultiPoint:

df['geometry'] = df['geometry'].apply(
    lambda x: shapely.geometry.MultiPoint(list(x.coords))
)

Once this is done, you can use df.explode:

In [10]: df.explode(index_parts=False)
Out[10]:
                   geometry
0  POINT (95.31734 5.56035)
0  POINT (95.31690 5.56028)
0  POINT (95.31657 5.56024)
0  POINT (95.31617 5.56021)
0  POINT (95.31613 5.56013)
0  POINT (95.31609 5.56002)

Upvotes: 1

Related Questions