1

I'm trying to achieve the exact transformation explained in this post.

Basically, I have a pair of XY coordinates (in EPSG 2154) and by using Folium, I need to :

  1. display those points in a map
  2. draw a line between every origin and its destination
  3. calculate the distance between every origin and its destination

So I tried to modify the code and end up with this one :

CODE :

import pandas as pd
from pyproj import Transformer
import folium

# --- CREATING THE DATAFRAME
df = pd.DataFrame({'name_origin (f)' : ['A', 'A', 'A', 'A', 'A', 'A', 'A'],
                   'x_origin' : [485605.326573992206249, 485605.326573992206249, 
                                 485605.326573992206249, 485605.326573992206249, 
                                 485622.851343188376632, 485622.851343188376632, 
                                 485622.851343188376632],
                   'y_origin' : [6609181.990121294744313, 6609181.990121294744313,
                                 6609181.990121294744313, 6609181.990121294744313,
                                 6609868.775725279003382, 6609868.775725279003382,
                                 6609868.775725279003382],
                    'name_destination' : ['Point 1', 'Point 2', 'Point 3', 'Point 4', 'Point 5', 'Point 6', 'Point 7'],
                    'x_destination': [485625.494795222417451, 485406.249829484208021,
                                     485775.291626620688476, 485782.127203797223046,
                                     485689.846236585523002, 485452.832908925425727,
                                     485872.578190427448135],
                    'y_destination': [6608980.483131179586053, 6609103.971662417054176,
                                     6609113.006477451883256, 6608920.478859589435160,
                                     6610121.606054869480431, 6609983.695990070700645,
                                     6609883.745388342998922]})
    
# --- TRANSFORMING THE XY COORDINATES (EPSG2154) TO LON/LAT
transformer = Transformer.from_crs("epsg:2154", "epsg:4326")
latlong_coordinates_origin = transformer.transform(df.iloc[1,], df.iloc[2,])
latlong_coordinates_destination = transformer.transform(df.iloc[4,], df.iloc[5,])

# --- CREATING A FOLIUM MAP BASED ON THE TRANSFORMED DATAFRAME
m = folium.Map([latlong_coordinates_origin, latlong_coordinates_destination], zoom_start=15)

for _, row in df.iterrows():
    folium.CircleMarker([row['x_origin'], row['y_origin']],
                        radius=15,
                        fill_color="#3db7e4", # divvy color
                       ).add_to(m)

    folium.CircleMarker([row['x_destination'], row['y_destination']],
                        radius=15,
                        fill_color="red", # divvy color
                       ).add_to(m)

    folium.PolyLine([[row['x_origin'], row['y_origin']], 
                     [row['x_destination'], row['y_destination']]]).add_to(m)
m

ERROR :

Unfortunately, I get this error :

TypeError: input must be an array, list, tuple, scalar, or have the __array__ method.

Do you have any propositions?

0

1 Answer 1

5

You can use this script:

import pandas as pd
from pyproj import Transformer
import folium

df = pd.DataFrame({'name_origin (f)' : ['A', 'A', 'A', 'A', 'A', 'A', 'A'],
                   'x_origin' : [485605.326573992206249, 485605.326573992206249, 
                                 485605.326573992206249, 485605.326573992206249, 
                                 485622.851343188376632, 485622.851343188376632, 
                                 485622.851343188376632],
                   'y_origin' : [6609181.990121294744313, 6609181.990121294744313,
                                 6609181.990121294744313, 6609181.990121294744313,
                                 6609868.775725279003382, 6609868.775725279003382,
                                 6609868.775725279003382],
                    'name_destination' : ['Point 1', 'Point 2', 'Point 3', 'Point 4', 'Point 5', 'Point 6', 'Point 7'],
                    'x_destination': [485625.494795222417451, 485406.249829484208021,
                                     485775.291626620688476, 485782.127203797223046,
                                     485689.846236585523002, 485452.832908925425727,
                                     485872.578190427448135],
                    'y_destination': [6608980.483131179586053, 6609103.971662417054176,
                                     6609113.006477451883256, 6608920.478859589435160,
                                     6610121.606054869480431, 6609983.695990070700645,
                                     6609883.745388342998922]})
    
transformer = Transformer.from_crs("epsg:2154", "epsg:4326")
latlong_origin = list(zip(*transformer.transform(df["x_origin"], df["y_origin"])))
latlong_destination = list(zip(*transformer.transform(df["x_destination"], df["y_destination"])))
m = folium.Map(latlong_origin[0], zoom_start=15)

for origin, destination in zip(latlong_origin, latlong_destination):
    folium.CircleMarker([origin[0], origin[1]],
                        radius=15,
                        fill_color="#3db7e4", # divvy color
                       ).add_to(m)

    folium.CircleMarker([destination[0], destination[1]],
                        radius=15,
                        fill_color="red", # divvy color
                       ).add_to(m)

    folium.PolyLine([[origin[0], origin[1]], 
                     [destination[0], destination[1]]]).add_to(m)
m

enter image description here

3
  • Thank you so much @Kadir. This is the exact result I'm looking for. I run the code on Jupyter and it worked ! Is there a way we can add a column to the Dataframe to precise the length of each line ?
    – Timeless.
    Aug 10, 2022 at 17:35
  • Is there also a way to put labels on each marker ? Eventually, the origin/destination's names. This will be amazing if we could do so !
    – Timeless.
    Aug 10, 2022 at 17:55
  • You can add distance column using: import numpy as np; df["distance"] = np.sqrt((df["x_origin"] - df["x_destination"])**2 + (df["y_origin"] - df["y_destination"])**2) Aug 10, 2022 at 18:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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