1

I have a Geodataframe with Linestring Z geometries as follows:

id_line geometry
1 LINESTRING Z (0 0 0, 5 6 9, 1 2 3, ...)
2 LINESTRING Z (7 8 9, 9 8 7, 1 2 5, ...)

each of the Linestring is made up of n triples of x, y, z coordinates. What I am looking for? Extract each of the triples that make up each line and convert it into Shapely POINT, then save each of these points in a dictionary like that:

{id_line : [points]}
points_by_line = {1 : [POINT Z(0,0,0), POINT Z(5,6,9), POINT Z(1,2,3)], 2 : [POINT Z(7,8,9), POINT Z(9,8,7), POINT Z(1,2,5)]
       

How am I trying to do this?

#Extracting the geometries from the Geodataframe
lines_segments = real_traj['geometry']
# saving the coordinates in a list
line_coords = []
for line in lines_segments:
    coords_line = list(line.coords)
    line_coords.append(coords_line)

Then I am trying to create a function that will extract each of the coordinates and convert them into Shapely Points, but here is where I am stuck

def linestring_to_points(line_coords):
    # creating a list for stock the points of each line
    line_points = []
    for coords in line_coords:
        for point_coord in coords:
            # access accessing the coordinates of each point on the line and creating a point from 
            # each group of coordinates
            line_points.append(geometry.Point(point_coord))
    return {id_line:Point.coords}
3

If the question is only Create Shapely Points from Linestring coordinates then the answer is:

print(line.wkt)
LINESTRING (22.6211173184358 -366.5480446927374, 21.05843575418999 -333.7317318435754, 21.57932960893859 -303.5198882681564, 21.57932960893859 -273.828938547486, 20.53754189944139 -236.8454748603352, 19.49575418994418 -206.1127374301676, 23.66290502793301 -172.775530726257, 25.74648044692742 -138.3965363128492, 27.30916201117323 -107.6637988826815, 25.22558659217881 -76.41016759776535, 27.30916201117323 -44.63564245810054)
for coord in list(line.coords):
    print(Point(coord))
POINT (22.6211173184358 -366.5480446927374)
POINT (21.05843575418999 -333.7317318435754)
POINT (21.57932960893859 -303.5198882681564)
POINT (21.57932960893859 -273.828938547486)
POINT (20.53754189944139 -236.8454748603352)
POINT (19.49575418994418 -206.1127374301676)
POINT (23.66290502793301 -172.775530726257)
POINT (25.74648044692742 -138.3965363128492)
POINT (27.30916201117323 -107.6637988826815)
POINT (25.22558659217881 -76.41016759776535)
POINT (27.30916201117323 -44.63564245810054)

New

I want to bring into the dictionary the identifier of the line id_line to which the point belongs

gdf = gpd.read_file("lines.shp")
for i,line in enumerate(df.geometry):
    for coord in line.coords:
        points = {"id":df.iloc[i].id, "pt":Point(coord)}
        print(points)
{'id': 0, 'pt': <shapely.geometry.point.Point object at 0x115007470>}
{'id': 0, 'pt': <shapely.geometry.point.Point object at 0x1150565f8>}
{'id': 0, 'pt': <shapely.geometry.point.Point object at 0x115007470>}
{'id': 1, 'pt': <shapely.geometry.point.Point object at 0x1150565f8>}
{'id': 1, 'pt': <shapely.geometry.point.Point object at 0x115007470>}
{'id': 1, 'pt': <shapely.geometry.point.Point object at 0x115056048>}
{'id': 1, 'pt': <shapely.geometry.point.Point object at 0x115007470>}
{'id': 2, 'pt': <shapely.geometry.point.Point object at 0x115056048>}
{'id': 2, 'pt': <shapely.geometry.point.Point object at 0x115007470>}
{'id': 2, 'pt': <shapely.geometry.point.Point object at 0x115056048>}
....
2
  • Thanks, in your answer a dictionary is created for each coordinate. What I am looking for is a single dictionary, where the value of the coordinates of each point will be appended to the corresponding key (id_line), like that: {1 : [POINT Z(0,0,0), POINT Z(5,6,9), POINT Z(1,2,3)], 2 : [POINT Z(7,8,9), POINT Z(9,8,7), POINT Z(1,2,5)]} – MigueL Mar 18 at 19:36
  • I have used your code to solve my problem, thank you very much – MigueL Mar 18 at 21:48
2

You can get the coordinate tuples of a LineString via the .coords attribute. To convert the whole sequence of them into a numbered dictionary, you can use a dictionary expression like this:

>>> points = {
>>>     i: Point(coords)
>>>     for i, coords
>>>     in enumerate(line.coords)
>>> }

{0: <shapely.geometry.point.Point at 0x7fe8862f0c10>,
 1: <shapely.geometry.point.Point at 0x7fe886277070>,
 2: <shapely.geometry.point.Point at 0x7fe886277400>,
 3: <shapely.geometry.point.Point at 0x7fe8861ac130>,
 4: <shapely.geometry.point.Point at 0x7fe8861ac0a0>,
 5: <shapely.geometry.point.Point at 0x7fe886d64f70>,
 6: <shapely.geometry.point.Point at 0x7fe886c597c0>,
 7: <shapely.geometry.point.Point at 0x7fe88431dee0>,
 8: <shapely.geometry.point.Point at 0x7fe88431d370>,
 9: <shapely.geometry.point.Point at 0x7fe88431dd30>,
 10: <shapely.geometry.point.Point at 0x7fe88431d970>}
3
  • Thanks, but instead of enumerate the points, I want to bring into the dictionary the identifier of the line id_line to which the point belongs, am trying this but is not working: lines_segments = list(gdf['geometry']) id_traject = list(gdf['id_line']) for line in lines_segments: for coord in line.coords: points = dict(zip(id_traject,Point(coord))) print(points) – MigueL Mar 18 at 10:52
  • Look New in my answer – gene Mar 18 at 18:06
  • Ah, I had missed that. Thanks for the nice answer @gene! – bugmenot123 Mar 19 at 10:55
1

Create a function to append the values to an existing key to a dictionary:

def append_point(dict_points, key, point):
    # Check if key exist in dict_points or not
    if key in dict_points:
        # Key exist in dict_points.
        # Check if type of point of key is list or not
        if not isinstance(dict_points[key], list):
            # If type is not list then make it list
            dict_points[key] = [dict_points[key]]
        # Append the point in list
        dict_points[key].append(point)
    else:
        # As key is not in dict_points,
        # so, add key-point pair
        dict_points[key] = point

        

Use the function in a for loop that will convert the coordinates of the linestrings into Shapely points:

gdf = gpd.read_file("lines.shp")

points = {}
for i,line in enumerate(gdf.geometry):
    for coord in line.coords:
        point = Point(coord)
        append_point(points, gdf.iloc[i].id_line, point)

Output:

{1: [<shapely.geometry.point.Point at 0x1859c65c160>,
  <shapely.geometry.point.Point at 0x1859c65cca0>,
  <shapely.geometry.point.Point at 0x1859c65c640>],
2: [<shapely.geometry.point.Point at 0x18598675400>,
  <shapely.geometry.point.Point at 0x1859c69f460>,
  <shapely.geometry.point.Point at 0x1859c69f3d0>,
  <shapely.geometry.point.Point at 0x1859c69f4c0>],
3: [<shapely.geometry.point.Point at 0x18598675400>,
  <shapely.geometry.point.Point at 0x1859c69f460>,
  <shapely.geometry.point.Point at 0x1859c69f3d0>,
  <shapely.geometry.point.Point at 0x1859c69f4c0>]}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.