Bagikan melalui


Tutorial: Merutekan kendaraan listrik dengan menggunakan Notebooks (Python)

Azure Maps adalah portofolio API layanan geospasial yang terintegrasi ke Azure, memungkinkan pengembang membuat aplikasi yang sadar lokasi untuk berbagai skenario seperti IoT, mobilitas, dan pelacakan aset.

REST API Azure Maps mendukung bahasa seperti Python dan R untuk analisis data geospasial dan pembelajaran mesin, menawarkan API perutean yang kuat untuk menghitung rute berdasarkan kondisi seperti jenis kendaraan atau area yang dapat dijangkau.

Tutorial ini memandu pengguna melalui perutean kendaraan listrik menggunakan API Azure Maps bersama dengan Jupyter Notebooks di VISUAL Code dan Python untuk menemukan stasiun pengisian daya terdekat ketika baterai rendah.

Dalam tutorial ini, Anda akan:

  • Buat dan jalankan Jupyter Notebook di Visual Studio Code.
  • Panggil REST API Azure Maps dengan Python.
  • Cari jarak yang dapat dijangkau berdasarkan model konsumsi kendaraan listrik.
  • Cari stasiun pengisian kendaraan listrik dalam jangkauan yang dapat dijangkau, atau isochrone.
  • Render batas jarak yang dapat dijangkau dan stasiun pengisian daya pada peta.
  • Temukan dan visualisasikan rute ke stasiun pengisian kendaraan listrik terdekat berdasarkan waktu berkendara.

Prasyarat

Catatan

Untuk informasi selengkapnya tentang autentikasi di Azure Maps, lihat mengelola autentikasi di Azure Maps.

Memasang paket tingkat proyek

Proyek Perutean EV dan Rentang yang Dapat Dijangkau memiliki dependensi pada pustaka python aiohttp dan IPython . Anda dapat menginstalnya di terminal Visual Studio menggunakan pip:

pip install aiohttp
pip install ipython

Buka Jupyter Notebook di Visual Studio Code

Unduh lalu buka Notebook yang digunakan dalam tutorial ini:

  1. Buka file EVrouting.ipynb di repositori AzureMapsJupyterSamples di GitHub.

  2. Pilih tombol Unduh file mentah di sudut kanan atas layar untuk menyimpan file secara lokal.

    Cuplikan layar memperlihatkan cara mengunduh file Notebook bernama EVrouting.ipynb dari repositori GitHub.

  3. Buka Notebook yang diunduh di Visual Studio Code dengan mengklik kanan file lalu pilih Buka dengan > Visual Studio Code, atau melalui File Explorer Visual Studio Code.

Memuat modul dan kerangka kerja yang diperlukan

Setelah kode ditambahkan, Anda dapat menjalankan sel menggunakan ikon Jalankan di sebelah kiri sel dan output ditampilkan di bawah sel kode.

Jalankan skrip berikut untuk memuat semua modul dan kerangka kerja yang diperlukan.

import time
import aiohttp
import urllib.parse
from IPython.display import Image, display

Cuplikan layar memperlihatkan cara mengunduh sel pertama di Notebook yang berisi pernyataan impor yang diperlukan dengan tombol jalankan disorot.

Meminta batas jarak yang dapat dijangkau

Perusahaan pengiriman paket mengoperasikan armada yang mencakup beberapa kendaraan listrik. Kendaraan ini perlu diisi ulang pada siang hari tanpa kembali ke gudang. Ketika sisa biaya turun di bawah satu jam, pencarian dilakukan untuk menemukan stasiun pengisian daya dalam rentang yang dapat dijangkau. Informasi batas untuk rentang stasiun pengisian daya ini kemudian diperoleh.

Yang diminta adalah eko untuk menyeimbangkan routeType ekonomi dan kecepatan. Skrip berikut memanggil Get Route Range API dari layanan perutean Azure Maps, menggunakan parameter yang terkait dengan model konsumsi kendaraan. Skrip kemudian mengurai respons untuk membuat objek poligon dalam format GeoJSON, mewakili rentang maksimum mobil yang dapat dijangkau.

subscriptionKey = "Your Azure Maps key"
currentLocation = [34.028115,-118.5184279]
session = aiohttp.ClientSession()

# Parameters for the vehicle consumption model 
travelMode = "car"
vehicleEngineType = "electric"
currentChargeInkWh=45
maxChargeInkWh=80
timeBudgetInSec=550
routeType="eco"
constantSpeedConsumptionInkWhPerHundredkm="50,8.2:130,21.3"

# Get boundaries for the electric vehicle's reachable range.
routeRangeResponse = await (await session.get("https://atlas.microsoft.com/route/range/json?subscription-key={}&api-version=1.0&query={}&travelMode={}&vehicleEngineType={}&currentChargeInkWh={}&maxChargeInkWh={}&timeBudgetInSec={}&routeType={}&constantSpeedConsumptionInkWhPerHundredkm={}"
                                              .format(subscriptionKey,str(currentLocation[0])+","+str(currentLocation[1]),travelMode, vehicleEngineType, currentChargeInkWh, maxChargeInkWh, timeBudgetInSec, routeType, constantSpeedConsumptionInkWhPerHundredkm))).json()

polyBounds = routeRangeResponse["reachableRange"]["boundary"]

for i in range(len(polyBounds)):
    coordList = list(polyBounds[i].values())
    coordList[0], coordList[1] = coordList[1], coordList[0]
    polyBounds[i] = coordList

polyBounds.pop()
polyBounds.append(polyBounds[0])

boundsData = {
               "geometry": {
                 "type": "Polygon",
                 "coordinates": 
                   [
                      polyBounds
                   ]
                }
             }

Mencari stasiun pengisian kendaraan listrik dalam jarak yang dapat dijangkau

Setelah menentukan rentang kendaraan listrik yang dapat dijangkau (isochrone), Anda dapat mencari stasiun pengisian daya di dalam area tersebut.

Skrip berikut menggunakan Azure Maps Post Search Inside Geometry API untuk menemukan stasiun pengisian daya dalam rentang maksimum kendaraan yang dapat dijangkau. Kemudian menguraikan respons ke dalam array lokasi yang dapat dijangkau.

# Search for electric vehicle stations within reachable range.
searchPolyResponse = await (await session.post(url = "https://atlas.microsoft.com/search/geometry/json?subscription-key={}&api-version=1.0&query=electric vehicle station&idxSet=POI&limit=50".format(subscriptionKey), json = boundsData)).json() 

reachableLocations = []
for loc in range(len(searchPolyResponse["results"])):
                location = list(searchPolyResponse["results"][loc]["position"].values())
                location[0], location[1] = location[1], location[0]
                reachableLocations.append(location)

Merender stasiun pengisian daya dan jarak yang dapat dijangkau di peta

Panggil layanan Azure Maps Get Map Image untuk merender titik pengisian daya dan batas maksimum yang dapat dijangkau pada gambar peta statis dengan menjalankan skrip berikut:

# Get boundaries for the bounding box.
def getBounds(polyBounds):
    maxLon = max(map(lambda x: x[0], polyBounds))
    minLon = min(map(lambda x: x[0], polyBounds))

    maxLat = max(map(lambda x: x[1], polyBounds))
    minLat = min(map(lambda x: x[1], polyBounds))
    
    # Buffer the bounding box by 10 percent to account for the pixel size of pins at the ends of the route.
    lonBuffer = (maxLon-minLon)*0.1
    minLon -= lonBuffer
    maxLon += lonBuffer

    latBuffer = (maxLat-minLat)*0.1
    minLat -= latBuffer
    maxLat += latBuffer
    
    return [minLon, maxLon, minLat, maxLat]

minLon, maxLon, minLat, maxLat = getBounds(polyBounds)
polyBoundsFormatted = ('|'.join(map(str, polyBounds))).replace('[','').replace(']','').replace(',','')
reachableLocationsFormatted = ('|'.join(map(str, reachableLocations))).replace('[','').replace(']','').replace(',','')

path = "lcff3333|lw3|la0.80|fa0.35||{}".format(polyBoundsFormatted)
pins = "custom|an15 53||{}||https://raw.githubusercontent.com/Azure-Samples/AzureMapsCodeSamples/e3a684e7423075129a0857c63011e7cfdda213b7/Static/images/icons/ev_pin.png".format(reachableLocationsFormatted)

encodedPins = urllib.parse.quote(pins, safe='')

# Render the range and electric vehicle charging points on the map.
staticMapResponse =  await session.get("https://atlas.microsoft.com/map/static/png?api-version=2022-08-01&subscription-key={}&pins={}&path={}&bbox={}&zoom=12".format(subscriptionKey,encodedPins,path,str(minLon)+", "+str(minLat)+", "+str(maxLon)+", "+str(maxLat)))

poiRangeMap = await staticMapResponse.content.read()

display(Image(poiRangeMap))

Cuplikan layar yang memperlihatkan rentang lokasi.

Menemukan stasiun pengisian daya yang optimal

Pertama, identifikasi semua stasiun pengisian daya potensial dalam jangkauan kendaraan yang dapat dijangkau. Selanjutnya, tentukan stasiun mana yang dapat diakses dalam waktu sesingkat mungkin.

Skrip berikut memanggil API Perutean Matriks Azure Maps. Ini mengembalikan lokasi kendaraan, waktu tempuh, dan jarak ke setiap stasiun pengisian daya. Skrip berikutnya mengurai respons ini untuk mengidentifikasi stasiun pengisian daya terdekat yang dapat dicapai dalam jumlah waktu paling sedikit.

locationData = {
            "origins": {
              "type": "MultiPoint",
              "coordinates": [[currentLocation[1],currentLocation[0]]]
            },
            "destinations": {
              "type": "MultiPoint",
              "coordinates": reachableLocations
            }
         }

# Get the travel time and distance to each specified charging station.
searchPolyRes = await (await session.post(url = "https://atlas.microsoft.com/route/matrix/json?subscription-key={}&api-version=1.0&routeType=shortest&waitForResults=true".format(subscriptionKey), json = locationData)).json()

distances = []
for dist in range(len(reachableLocations)):
    distances.append(searchPolyRes["matrix"][0][dist]["response"]["routeSummary"]["travelTimeInSeconds"])

minDistLoc = []
minDistIndex = distances.index(min(distances))
minDistLoc.extend([reachableLocations[minDistIndex][1], reachableLocations[minDistIndex][0]])
closestChargeLoc = ",".join(str(i) for i in minDistLoc)

Menghitung rute ke stasiun pengisian daya terdekat

Setelah menemukan stasiun pengisian daya terdekat, gunakan GET Route Directions API untuk mendapatkan petunjuk arah terperinci dari lokasi kendaraan saat ini. Jalankan skrip di sel berikutnya untuk menghasilkan dan mengurai objek GeoJSON yang mewakili rute.

# Get the route from the electric vehicle's current location to the closest charging station. 
routeResponse = await (await session.get("https://atlas.microsoft.com/route/directions/json?subscription-key={}&api-version=1.0&query={}:{}".format(subscriptionKey, str(currentLocation[0])+","+str(currentLocation[1]), closestChargeLoc))).json()

route = []
for loc in range(len(routeResponse["routes"][0]["legs"][0]["points"])):
                location = list(routeResponse["routes"][0]["legs"][0]["points"][loc].values())
                location[0], location[1] = location[1], location[0]
                route.append(location)

routeData = {
         "type": "LineString",
         "coordinates": route
     }

Memvisualisasikan rute

Untuk memvisualisasikan rute, gunakan Get Map Image API untuk merendernya di peta.

destination = route[-1]

#destination[1], destination[0] = destination[0], destination[1]

routeFormatted = ('|'.join(map(str, route))).replace('[','').replace(']','').replace(',','')
path = "lc0f6dd9|lw6||{}".format(routeFormatted)
pins = "default|codb1818||{} {}|{} {}".format(str(currentLocation[1]),str(currentLocation[0]),destination[0],destination[1])


# Get boundaries for the bounding box.
minLon, maxLon = (float(destination[0]),currentLocation[1]) if float(destination[0])<currentLocation[1] else (currentLocation[1], float(destination[0]))
minLat, maxLat = (float(destination[1]),currentLocation[0]) if float(destination[1])<currentLocation[0] else (currentLocation[0], float(destination[1]))

# Buffer the bounding box by 10 percent to account for the pixel size of pins at the ends of the route.
lonBuffer = (maxLon-minLon)*0.1
minLon -= lonBuffer
maxLon += lonBuffer

latBuffer = (maxLat-minLat)*0.1
minLat -= latBuffer
maxLat += latBuffer

# Render the route on the map.
staticMapResponse = await session.get("https://atlas.microsoft.com/map/static/png?api-version=2022-08-01&subscription-key={}&&path={}&pins={}&bbox={}&zoom=16".format(subscriptionKey,path,pins,str(minLon)+", "+str(minLat)+", "+str(maxLon)+", "+str(maxLat)))

staticMapImage = await staticMapResponse.content.read()

await session.close()
display(Image(staticMapImage))

Cuplikan layar yang memperlihatkan peta yang memperlihatkan rute.

Dalam tutorial ini, Anda mempelajari cara memanggil REST API Azure Maps secara langsung dan memvisualisasikan data Azure Maps dengan menggunakan Python.

Untuk informasi selengkapnya tentang API Azure Maps yang digunakan dalam tutorial ini, lihat:

Untuk mengetahui daftar lengkap REST API Azure Maps, lihat REST API Azure Maps.

Langkah berikutnya