Sunday, January 15, 2023

Tracing Driving Route Between 2 Places

I am upgrading my post Display Map with Markers and Polygons with Folium and PyQt6.

Python-folium-openrouteservice is a powerful tool for tracing driving routes on a map. Using this library, it is possible to trace a route from BGC Circle to QC Memorial Circle in just a few lines of code. Geographiclib library is also needed in this demo program.

The first step in this process is to install the necessary libraries. This can be done by running the following command in your terminal: pip install folium openrouteservice.

Next, we will need to set up our API key for the openrouteservice. This can be obtained by creating an account at https://openrouteservice.org/signup/. Once you have your key, you can use it to authenticate your requests.

With the client set up, we can now use the directions function to trace a route from BGC Circle to QC Memorial Circle. The coordinates for these locations are 14.554729, 121.024445 and 14.656915, 121.063143 respectively.

The geometry variable now contains the details of the route, including the geometry, distance, and estimated time of arrival. We can use this information to plot the route on a map using the folium library.

The above code will create an interactive map with the traced route displayed in red. This map can be saved as an HTML file or displayed directly in a Jupyter notebook but in this program, I used pyqt5.

With just a few lines of code, we have been able to trace a driving route from BGC Circle to QC Memorial Circle using Python-folium-openrouteservice. This powerful library makes it easy to work with maps and location data in Python, and can be used for a wide range of applications.

The screenshot:


pls note that in order to display the 2 places on the screen correctly, I have to compute for the midpoints between the the gps coordinates.

There is no changes on the pyqt5 code.

The whole code:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import sys
import io
import folium 
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QApplication, QPushButton
from PyQt5.QtWebEngineWidgets import QWebEngineView # pip install PyQtWebEngine
import openrouteservice
from openrouteservice import convert
import json
from geographiclib.geodesic import Geodesic
x=0
y=0
class Window(QMainWindow):

    def __init__(self):
        super(Window, self).__init__()      
         
        self.initUI()

    def initUI(self):
        global x,y
        self.pb1 = QPushButton('Update', self)
        self.pb1.setGeometry(540, 530, 100, 30)       
        self.pb1.clicked.connect(self.onClick_pb2)        
        A = (14.552474,121.044269) #Point A (lat, lon)
        B = (14.651489,121.049309) #Point B (lat, lon)
        s = 10 #Distance (m)

        #Define the ellipsoid
        geod = Geodesic.WGS84

        #Solve the Inverse problem
        inv = geod.Inverse(A[0],A[1],B[0],B[1])
        azi1 = inv['azi1']
        print('Initial Azimuth from A to B = ' + str(azi1))

        #Solve the Direct problem
        dir = geod.Direct(A[0],A[1],azi1,s)
        x = dir['lat2']
        y = dir['lon2']
        C = (dir['lat2'],dir['lon2'])
        print('C = ' + str(C))        
        
        coords = ((121.044269,14.552474),(121.049309,14.651489))
        m = folium.Map(location=[x,y],zoom_start=11, control_scale=True,tiles="cartodbpositron")

        folium.Marker(
          location=list(coords[0][::-1]),
          popup="BGC Burgos Circle",
          icon=folium.Icon(color="green"),
        ).add_to(m)

        folium.Marker(
         location=list(coords[1][::-1]),
         popup="QC Memorial Circle",
         icon=folium.Icon(color="red"),
        ).add_to(m)
    


        # save map data to data object
        data = io.BytesIO()
        m.save(data, close_file=False)

        self.webView = QWebEngineView(self)
        self.webView.setHtml(data.getvalue().decode())
        self.webView.setGeometry(20,20, 620,480)
        self.setGeometry(25, 45, 650, 570)
        self.setWindowTitle('Post 28')
        self.show()
        
    def onClick_pb2(self):
        global x,y
        client = openrouteservice.Client(key='5b3ce35978511111101cf624899b5471d2a5c4b948519c250dcbd7a96') #api key

        coords = ((121.044269,14.552474),(121.049309,14.651489))
        res = client.directions(coords)
        geometry = client.directions(coords)['routes'][0]['geometry']
        decoded = convert.decode_polyline(geometry)

        distance_txt = "<h4> <b>Distance :&nbsp" + "<strong>"+str(round(res['routes'][0]['summary']['distance']/1000,1))+" Km </strong>" +"</h4></b>"
        duration_txt = "<h4> <b>Duration :&nbsp" + "<strong>"+str(round(res['routes'][0]['summary']['duration']/60,1))+" Mins. </strong>" +"</h4></b>"

        m = folium.Map(location=[x,y],zoom_start=11, control_scale=True,tiles="cartodbpositron")
        folium.GeoJson(decoded).add_child(folium.Popup(distance_txt+duration_txt,max_width=300)).add_to(m)

        folium.Marker(
          location=list(coords[0][::-1]),
          popup="BGC Burgos Circle",
          icon=folium.Icon(color="green"),
        ).add_to(m)

        folium.Marker(
         location=list(coords[1][::-1]),
         popup="QC Memorial Circle",
         icon=folium.Icon(color="red"),
        ).add_to(m)


        data = io.BytesIO()
        m.save(data, close_file=False)
        
        self.webView.setHtml(data.getvalue().decode())                    

def main():

    app = QApplication(sys.argv)
    ex = Window()
    ex.show()
    sys.exit(app.exec())


if __name__ == '__main__':
    main()

No comments:

Post a Comment