Python Distance Calculation – Draw a Line Between Pairs of Points and Calculate Distance Using Folium

foliumpyprojpython

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?

Best Answer

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