Megosztás a következőn keresztül:


Oktatóanyag: Elektromos járművek irányítása az Azure Notebooks (Python) használatával

Az Azure Térképek olyan térinformatikai szolgáltatás API-k portfóliója, amelyek natív módon integrálva vannak az Azure-ba. Ezek az API-k lehetővé teszik, hogy a fejlesztők, a nagyvállalatok és az ISV-k helyérzékeny alkalmazásokat, IoT-, mobilitási, logisztikai és eszközkövetési megoldásokat fejlesszenek ki.

Az Azure Térképek REST API-kat olyan nyelvekről lehet meghívni, mint a Python és az R, hogy lehetővé tegyék a térinformatikai adatok elemzését és a gépi tanulási forgatókönyveket. Az Azure Térképek számos olyan útválasztási API-t kínál, amelyekkel a felhasználók több adatpont közötti útvonalakat számíthatnak ki. A számítások különböző feltételeken alapulnak, például járműtípuson vagy elérhető területen.

Ebben az oktatóanyagban segítséget nyújt egy olyan vezetőnek, akinek az elektromos jármű akkumulátora alacsony. A vezetőnek meg kell találnia a legközelebbi lehetséges töltőállomást a jármű helyére.

Az oktatóanyag során az alábbi lépéseket fogja végrehajtani:

  • Jupyter Notebook-fájl létrehozása és futtatása a felhőbeli Azure Notebooksban .
  • Azure Térképek REST API-k meghívása Pythonban.
  • Keressen egy elérhető tartományt az elektromos jármű fogyasztási modellje alapján.
  • Keressen elektromos jármű töltőállomásokat az elérhető tartományon belül, vagy isochrone.
  • Térképen ábrázolja az elérhető tartományhatárt és a töltőállomásokat.
  • Keresse meg és vizualizálja a legközelebbi elektromos jármű töltőállomására vezető útvonalat a meghajtóidő alapján.

Előfeltételek

Megjegyzés:

Az Azure Térképek-hitelesítéssel kapcsolatos további információkért lásd az Azure Térképek hitelesítésének kezelését.

Azure Notebooks-projekt létrehozása

Az oktatóanyag követéséhez létre kell hoznia egy Azure Notebooks-projektet, és le kell töltenie és le kell futtatnia a Jupyter Notebook-fájlt. A Jupyter Notebook-fájl Python-kódot tartalmaz, amely implementálja a forgatókönyvet ebben az oktatóanyagban. Azure Notebooks-projekt létrehozásához és a Jupyter Notebook-dokumentum feltöltéséhez hajtsa végre a következő lépéseket:

  1. Nyissa meg az Azure Notebookst , és jelentkezzen be. További információ : Rövid útmutató: Bejelentkezés és felhasználói azonosító beállítása.

  2. A nyilvános profillap tetején válassza a Saját projektek lehetőséget.

    The My Projects button

  3. A Saját projektek lapon válassza az Új projekt lehetőséget.

    The New Project button

  4. Az Új projekt létrehozása panelen adjon meg egy projektnevet és egy projektazonosítót.

    The Create New Project pane

  5. Válassza a Létrehozás lehetőséget.

  6. A projekt létrehozása után töltse le ezt a Jupyter Notebook-dokumentumfájlt az Azure Térképek Jupyter Notebook-adattárból.

  7. A Saját projektek lapon található projektek listájában válassza ki a projektet, majd válassza a Feltöltés lehetőséget a Jupyter Notebook-dokumentumfájl feltöltéséhez.

    upload Jupyter Notebook

  8. Töltse fel a fájlt a számítógépről, majd válassza a Kész lehetőséget.

  9. A feltöltés sikeres befejezése után a fájl megjelenik a projektoldalon. Kattintson duplán a fájlra jupyter notebookként való megnyitásához.

Próbálja megérteni a Jupyter Notebook-fájlban implementált funkciókat. Futtassa a kódot a Jupyter Notebook fájlban, egyszerre egy cellával. A kódot az egyes cellákban a Jupyter Notebook alkalmazás tetején található Futtatás gombra kattintva futtathatja.

The Run button

Projektszintű csomagok telepítése

Ha a kódot a Jupyter Notebookban szeretné futtatni, telepítse a csomagokat a projekt szintjén az alábbi lépésekkel:

  1. Töltse le a requirements.txt fájlt az Azure Térképek Jupyter Notebook-adattárból, majd töltse fel a projektbe.

  2. A projekt irányítópultján válassza a Project Gépház lehetőséget.

  3. A Project Gépház panelen válassza a Környezet lapot, majd a Hozzáadás lehetőséget.

  4. A Környezetbeállítási lépések területen tegye a következőket: a. Az első legördülő listában válassza a Requirements.txt lehetőséget.
    b. A második legördülő listában válassza ki a requirements.txt fájlt.
    c. A harmadik legördülő listában válassza a Python 3.6-os verzióját verzióként.

  5. Válassza a Mentés lehetőséget.

    Install packages

A szükséges modulok és keretrendszerek betöltése

Az összes szükséges modul és keretrendszer betöltéséhez futtassa a következő szkriptet.

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

Az elérhető tartomány határának kérése

A csomagkézbesítési vállalatnak van néhány elektromos járműve a flottájában. A nap folyamán az elektromos járműveket fel kell tölteni anélkül, hogy vissza kellene térnie a raktárba. Minden alkalommal, amikor a fennmaradó díj egy óránál kevesebbre csökken, olyan töltőállomásokat keres, amelyek egy elérhető tartományon belül vannak. Lényegében akkor keres egy töltőállomást, ha az akkumulátor töltöttségi szint alacsony. És a töltőállomások tartományára vonatkozó határinformációkat is megkapja.

Mivel a vállalat a gazdaságosság és a sebesség egyensúlyát igénylő útvonalakat részesíti előnyben, a kért routeType öko. Az alábbi szkript meghívja az Azure Térképek útválasztási szolgáltatás útvonaltartomány-API-jának lekérését. Paramétereket használ a jármű fogyasztási modelljéhez. A szkript ezután elemzi a választ, hogy létrehozzon egy geojson formátumú sokszögobjektumot, amely az autó maximális elérhető tartományát jelöli.

Az elektromos jármű elérhető tartományának határainak meghatározásához futtassa a szkriptet a következő cellában:

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
                   ]
                }
             }

Elektromos járművek töltőállomásainak keresése az elérhető tartományon belül

Miután meghatározta az elektromos jármű elérhető tartományát (isochrone), az adott tartományon belül kereshet töltőállomásokat.

A következő szkript meghívja az Azure Térképek Post Search Inside Geometry API-t. Elektromos járművek töltőállomásait keresi, az autó maximálisan elérhető tartományán belül. Ezután a szkript elemzi az elérhető helyek tömbjének válaszát.

Az elérhető tartományon belüli elektromos járművek töltőállomásainak kereséséhez futtassa a következő szkriptet:

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

Töltse fel az elérhető tartományt és a töltőpontokat

Hasznos, ha térképen ábrázolja a töltőállomásokat és az elektromos jármű maximálisan elérhető tartományának határát. Kövesse az Adatregisztrációs adatbázis létrehozása című cikkben ismertetett lépéseket a határadatok és a töltőállomások adatai geojson objektumként való feltöltéséhez az Azure Storage-fiókba, majd regisztrálja őket az Azure Térképek-fiókjában. Ügyeljen arra, hogy jegyezze fel az egyedi azonosító (udid) értékét, szüksége lesz rá. Így udid hivatkozhat a forráskódból az Azure Storage-fiókba feltöltött geojson-objektumokra.

A töltőállomások és az elérhető tartomány megjelenítése térképen

Miután feltöltötte az adatokat az Azure Storage-fiókba, hívja meg az Azure Térképek Térkép képének lekérése szolgáltatást. Ez a szolgáltatás a következő szkript futtatásával jeleníti meg a töltési pontokat és a maximálisan elérhető határt a statikus térképképen:

# 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

Az optimális töltőállomás megkeresése

Először is meg kell határoznia az összes lehetséges töltőállomást az elérhető tartományon belül. Ezután tudni szeretné, hogy ezek közül melyik érhető el minimális idő alatt.

Az alábbi szkript meghívja az Azure Térképek Matrix Routing API-t. Visszaadja a jármű megadott helyét, az utazási időt és az egyes töltőállomások távolságát. A következő cellában lévő szkript elemzi a választ, hogy megkeresse a legközelebbi elérhető töltőállomást az idő függvényében.

A legközelebbi elérhető töltőállomás megkereséséhez futtassa a szkriptet a következő cellában:

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)

A legközelebbi töltőállomásra vezető útvonal kiszámítása

Most, hogy megtalálta a legközelebbi töltőállomást, meghívhatja a Get Route Directions API-t , hogy részletes útvonalat kérjen az elektromos jármű aktuális helyétől a töltőállomásig.

Ha le szeretné tölteni az útvonalat a töltőállomásra, és elemezni szeretné a választ, hogy létrehozzon egy geojson objektumot, amely az útvonalat jelöli, futtassa a szkriptet a következő cellában:

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

Az útvonal megjelenítése

Az útvonal megjelenítéséhez kövesse az Adatregisztrációs adatbázis létrehozása című cikkben ismertetett lépéseket az útvonaladatok geojson objektumként való feltöltéséhez az Azure Storage-fiókba, majd regisztrálja azokat az Azure-Térképek-fiókjában. Ügyeljen arra, hogy jegyezze fel az egyedi azonosító (udid) értékét, szüksége lesz rá. Így udid hivatkozhat a forráskódból az Azure Storage-fiókba feltöltött geojson-objektumokra. Ezután hívja meg a renderelési szolgáltatást, a Get Map Image API-t, hogy megjelenítse az útvonalat a térképen, és megjelenítse azt.

A térképen megjelenített útvonal képének lekéréséhez futtassa a következő szkriptet:

# 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

Ebben az oktatóanyagban megtanulta, hogyan hívhatja meg közvetlenül az Azure Térképek REST API-kat, és hogyan jelenítheti meg az Azure Térképek-adatokat a Python használatával.

Az oktatóanyagban használt Azure Térképek API-k megismeréséhez lásd:

Az erőforrások eltávolítása

Nincsenek olyan erőforrások, amelyek karbantartást igényelnek.

További lépések

További információ az Azure Notebooksról: