Tutorial: Merutekan kendaraan listrik dengan menggunakan Notebooks (Python)

Azure Maps adalah portofolio API layanan geospasial yang terintegrasi ke Azure. API ini memungkinkan pengembang, perusahaan, dan ISV untuk mengembangkan aplikasi berbasis lokasi, IoT, mobilitas, logistik, dan solusi pelacakan aset.

REST API Azure Maps dapat dipanggil dari bahasa seperti Python dan R untuk mengaktifkan analisis data geospasial dan skenario pembelajaran mesin. Azure Maps menawarkan serangkaian API perutean yang kuat yang memungkinkan pengguna menghitung rute di antara beberapa poin data. Perhitungan tersebut didasarkan pada berbagai kondisi, seperti jenis kendaraan atau area yang dapat dijangkau.

Dalam tutorial ini, Anda berjalan membantu pengemudi yang baterai kendaraan listriknya rendah. Pengemudi perlu menemukan stasiun pengisian terdekat dari lokasi kendaraan.

Dalam tutorial ini, Anda akan:

  • Buat dan jalankan file Buku Catatan Jupyter di Notebooks di cloud.
  • Panggil REST API Azure Maps dengan Python.
  • Cari jarak yang dapat dijangkau berdasarkan model konsumsi kendaraan listrik.
  • Cari stasiun pengisian kendaraan listrik dalam jarak 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.

Membuat proyek Notebooks

Untuk mengikuti tutorial ini, Anda perlu membuat proyek Notebooks dan mengunduh serta menjalankan file Buku Catatan Jupyter. File Buku Catatan Jupyter berisi kode Python, yang menerapkan skenario dalam tutorial ini. Untuk membuat proyek Notebooks dan mengunggah dokumen Buku Catatan Jupyter ke dalamnya, lakukan langkah-langkah berikut:

  1. Buka Notebooks dan masuk. Untuk informasi selengkapnya, lihat Mulai Cepat: Masuk dan atur ID pengguna.

  2. Di bagian atas halaman profil publik Anda, pilih Proyek Saya.

    The My Projects button

  3. Pada halaman Proyek Saya, pilih Proyek Baru.

    The New Project button

  4. Di panel Buat Proyek Baru, masukkan nama proyek dan ID proyek.

    The Create New Project pane

  5. Pilih Buat.

  6. Setelah proyek Anda dibuat, unduh file dokumen Buku Catatan Jupyter ini dari repositori Buku Catatan Jupyter Azure Maps.

  7. Dalam daftar proyek pada halaman Proyek Saya, pilih proyek Anda, lalu pilih Unggah untuk mengunggah file dokumen Buku Catatan Jupyter.

    upload Jupyter Notebook

  8. Unggah file dari komputer Anda, lalu pilih Selesai.

  9. Setelah pengunggahan selesai dengan sukses, file Anda ditampilkan di halaman proyek. Klik dua kali pada file untuk membukanya sebagai Buku Catatan Jupyter.

Coba untuk memahami fungsionalitas yang diterapkan dalam file Buku Catatan Jupyter. Jalankan kode, dalam file Buku Catatan Jupyter, satu sel pada satu waktu. Anda dapat menjalankan kode di setiap sel dengan memilih tombol Jalankan di bagian atas aplikasi Buku Catatan Jupyter.

The Run button

Memasang paket tingkat proyek

Untuk menjalankan kode di Buku Catatan Jupyter, pasang paket di tingkat proyek dengan melakukan langkah-langkah berikut:

  1. Unduh file requirements.txt dari repositori Buku Catatan Jupyter Azure Maps, lalu unggah ke proyek Anda.

  2. Di dasbor proyek, pilih Pengaturan Proyek.

  3. Di panel Pengaturan Proyek, pilih tab Lingkungan, lalu pilih Tambahkan.

  4. Di bagian Langkah-Langkah Penyiapan Lingkungan, lakukan hal berikut: a. Di daftar turun pertama, pilih Requirements.txt.
    b. Di daftar turun kedua, pilih file requirements.txt Anda.
    c. Di daftar turun ketiga, pilih Python Versi 3.6 sebagai versi Anda.

  5. Pilih Simpan.

    Install packages

Memuat modul dan kerangka kerja yang diperlukan

Untuk memuat semua modul dan kerangka kerja yang diperlukan, jalankan skrip berikut.

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

Meminta batas jarak yang dapat dijangkau

Sebuah perusahaan pengiriman paket memiliki beberapa kendaraan listrik dalam armadanya. Pada siang hari, kendaraan listrik perlu diisi ulang tanpa harus kembali ke gudang. Setiap kali sisa daya turun menjadi kurang dari satu jam, Anda mencari sebuah stasiun pengisian daya yang berada dalam jarak yang dapat dijangkau. Pada dasarnya, Anda mencari stasiun pengisian daya saat daya baterai hampir habis. Dan, Anda mendapatkan informasi batas untuk jarak stasiun pengisian daya tersebut.

Karena perusahaan lebih suka menggunakan rute yang membutuhkan keseimbangan antara ekonomi dan kecepatan, routeType yang diminta adalah eco. Skrip berikut memanggil Dapatkan API Jarak Rute dari layanan perutean Azure Maps. Skrip menggunakan parameter untuk model konsumsi kendaraan. Skrip kemudian mengurai respons untuk membuat objek poligon dengan format geojson, yang mewakili jarak maksimum yang dapat dijangkau mobil.

Untuk menentukan batas jarak jangkauan kendaraan listrik, jalankan skrip di sel berikut:

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 Anda menentukan jarak yang dapat dijangkau (isochrone) untuk kendaraan listrik, Anda dapat mencari stasiun pengisian daya dalam jarak tersebut.

Skrip berikut memanggil Azure Maps API Pencarian Pos Dalam Geometri. API mencari stasiun pengisian daya untuk kendaraan listrik, dalam batas jarak maksimum mobil yang dapat dijangkau. Kemudian, skrip mengurai respons ke berbagai lokasi yang dapat dijangkau.

Untuk mencari stasiun pengisian daya kendaraan listrik dalam jarak yang dapat dijangkau, jalankan skrip berikut:

# 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)

Unggah rentang yang dapat dijangkau dan titik pengisian daya

Sangat membantu untuk memvisualisasikan stasiun pengisian daya dan batas untuk rentang maksimum kendaraan listrik yang dapat dijangkau di peta. Ikuti langkah-langkah yang diuraikan dalam artikel Cara membuat registri data untuk mengunggah data batas dan menagih data stasiun sebagai objek geojson ke akun penyimpanan Azure Anda lalu mendaftarkannya di akun Azure Peta Anda. Pastikan untuk membuat catatan nilai pengidentifikasi unik (udid), Anda akan membutuhkannya. adalah udid cara Anda mereferensikan objek geojson yang Anda unggah ke akun penyimpanan Azure dari kode sumber Anda.

Merender stasiun pengisian daya dan jarak yang dapat dijangkau di peta

Setelah Anda mengunggah data ke akun penyimpanan Azure, panggil layanan Azure Peta Get Map Image. Layanan ini digunakan untuk merender titik pengisian daya dan batas maksimum yang dapat dicapai pada gambar peta statik 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)

path = "lcff3333|lw3|la0.80|fa0.35||udid-{}".format(rangeUdid)
pins = "custom|an15 53||udid-{}||https://raw.githubusercontent.com/Azure-Samples/AzureMapsCodeSamples/master/AzureMapsCodeSamples/Common/images/icons/ev_pin.png".format(poiUdid)

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))

A map showing the location range

Menemukan stasiun pengisian daya yang optimal

Pertama, Anda perlu menentukan semua stasiun pengisian daya potensial dalam jarak yang dapat dijangkau. Kemudian, Anda perlu mengetahui mana dari stasiun pengisian daya yang dapat dicapai dalam waktu minimum.

Skrip berikut memanggil API Perutean Matriks Azure Maps. Skrip menampilkan lokasi kendaraan yang ditentukan, waktu tempuh, dan jarak ke setiap stasiun pengisian daya. Skrip di sel berikutnya menguraikan respons untuk menemukan stasiun pengisian daya terdekat yang dapat dijangkau sehubungan dengan waktu.

Untuk menemukan stasiun pengisian daya terdekat yang dapat dijangkau dalam waktu paling singkat, jalankan skrip di sel berikut:

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

Sekarang setelah Anda menemukan stasiun pengisian daya terdekat, Anda dapat menghubungi API Dapatkan Rute Arah untuk meminta rute mendetail dari lokasi kendaraan listrik saat ini ke stasiun pengisian daya.

Untuk mendapatkan rute ke stasiun pengisian daya dan mengurai respons untuk membuat objek geojson yang mewakili rute, jalankan skrip di sel berikut:

# 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 membantu memvisualisasikan rute, ikuti langkah-langkah yang diuraikan dalam artikel Cara membuat registri data untuk mengunggah data rute sebagai objek geojson ke akun penyimpanan Azure Anda lalu daftarkan di akun Azure Peta Anda. Pastikan untuk membuat catatan nilai pengidentifikasi unik (udid), Anda akan membutuhkannya. adalah udid cara Anda mereferensikan objek geojson yang Anda unggah ke akun penyimpanan Azure dari kode sumber Anda. Kemudian, panggil layanan penyajian, API Dapatkan Gambar Peta, untuk merender rute pada peta, dan memvisualisasikannya.

Untuk mendapatkan gambar untuk rute yang dirender di peta, jalankan skrip berikut:

# Upload the route data to Azure Maps Data service .
routeUploadRequest = await session.post("https://atlas.microsoft.com/mapData?subscription-key={}&api-version=2.0&dataFormat=geojson".format(subscriptionKey), json = routeData)

udidRequestURI = routeUploadRequest.headers["Location"]+"&subscription-key={}".format(subscriptionKey)

while True:
    udidRequest = await (await session.get(udidRequestURI)).json()
    if 'udid' in udidRequest:
        break
    else:
        time.sleep(0.2)

udid = udidRequest["udid"]

destination = route[-1]

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

path = "lc0f6dd9|lw6||udid-{}".format(udid)
pins = "default|codb1818||{} {}|{} {}".format(str(currentLocation[1]),str(currentLocation[0]),destination[1],destination[0])


# Get boundaries for the bounding box.
minLat, maxLat = (float(destination[0]),currentLocation[0]) if float(destination[0])<currentLocation[0] else (currentLocation[0], float(destination[0]))
minLon, maxLon = (float(destination[1]),currentLocation[1]) if float(destination[1])<currentLocation[1] else (currentLocation[1], 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))

A map showing the route

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

Untuk menjelajahi API Azure Maps yang digunakan dalam tutorial ini, lihat:

Membersihkan sumber daya

Tidak ada sumber daya yang memerlukan pembersihan.

Langkah berikutnya

Untuk mempelajari selengkapnya tentang Notebooks, lihat