Python Create Dictionary with Shapely Points from Linestring coordinates

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}

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

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>}
....
• 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)]} Mar 18 '21 at 19:36
• I have used your code to solve my problem, thank you very much Mar 18 '21 at 21:48

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>}
• 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) Mar 18 '21 at 10:52
• Look New in my answer
– gene
Mar 18 '21 at 18:06
• Ah, I had missed that. Thanks for the nice answer @gene! Mar 19 '21 at 10:55

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,
dict_points[key] = point

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

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>]}