<jupyter_start><jupyter_text>digitraffic.fi API-datan käsittelyä pythonillaLiikenneviraston tieliikenteen mittauspisteiden dataa on vapaasti saatavilla verkossa.Tässä koodiesimerkissä luemme tätä dataa ja muokkaamme siitä GeoJSON-formaatin mukaisen mittauspisteluettelon, joka voidaan tulostaa kartan yhteydessä (openstreetmap). Anturidataa on tarjolla hyvinkin paljon, mutta käytämme siitä vain ilman lämpötiloja.<jupyter_code>from io import BytesIO
import gzip
from urllib.request import Request, urlopen

# apurutiini joka ilmoittaa www-palvelimelle, että voimme vastaanottaa gzip-pakattua dataa (Reqeust)
# jos data tulee tässä muodossa (response), niin käytämme moduulia gzip sen purkamiseen
def ReadDataURL( url ):
    req = Request( url )
    req.add_header( 'Accept-encoding', 'gzip' )
    response = urlopen( req )
    if response.info().get('Content-Encoding') == 'gzip':
        buffer = BytesIO( response.read() )
        with gzip.GzipFile( fileobj=buffer ) as MemoryFile:
            # gzip-pakattu data palautetaan purettuna:
            return MemoryFile.read()
    else:
        # "tavallinen" data palautetaan sellaisenaan:
        return response.read()
    
import json

# metadata sisältää asemien sijaintitiedot ja nimet
metaRaw = ReadDataURL( 'https://tie.digitraffic.fi/api/v1/metadata/weather-stations?lastUpdated=false' )

# verkosta tuleva data on JSON-formaatissa.
# muutetaan se Pythonin dictionary rakenteeksi:
metaData = json.loads( metaRaw.decode('utf-8') )

# yhden aseman tiedot tulostettuna
print( json.dumps( metaData['features'][0], indent=2 ) )
# otetaan talteen kunkin aseman tunnisteella sen koordinaatit ja nimi
STATIONS = dict()
for station in metaData['features']:
    # tämä 'geometry'  ja 'properties' rakenne on sama kuin GeoJSON-formaatissa:
    STATIONS[ station['id'] ] = { 'geometry'  : station['geometry'], 
                                  'properties': {'name' : station['properties']['name'] }
                                }
    
STATIONS
# ajankohtainen anturidata kaikilta asemilta löytyy tästä URL:sta:
weatherRaw = ReadDataURL('https://tie.digitraffic.fi/api/v1/data/weather-data?lastUpdated=false')
weatherData = json.loads( weatherRaw.decode('utf-8') )

print( json.dumps( weatherData['weatherStations'][0], indent=2) ) # testitulostus yhdestä asemasta
# poimitaan jokaiselta asemalta talteen "ILMA" anturin arvo
for station in weatherData['weatherStations']:
    for sensor in station['sensorValues']:
        if sensor['name'] == 'ILMA':
            # STATIONS-rakenne on aiemmin jo luotu asemien tiedoista
            # tässä lisäämme yhden 'properties' kentän lämpötilaa varten:
            STATIONS[sensor['roadStationId']]['properties']['Temperature'] = sensor['sensorValue']

# kaikki kerätty data
STATIONS            
# luodaan dictionary, joka sisältää asemien tiedot GeoJSON-formaatissa
# https://en.wikipedia.org/wiki/GeoJSON
GEO = dict()
GEO['type'] = 'FeatureCollection'
GEO['features'] = list() # tässä listassa on kaikki "pisteet" eli mittausasemat

for station in STATIONS.keys():
    # aiemmin kerätty data on jo oikeassa muodossa GeoJSON:n kannalta,
    # joten tyyppitiedon lisäämisen jälkeen
    # talletamme vain kunkin aseman 'features' listaan
    ITEM = STATIONS[station]
    ITEM['type'] = 'Feature'
    GEO['features'].append( ITEM )
   
GEO
# jupyter notebookin lisäosien avulla tehdään tekstikenttä (label)
# ja kartta (map)
from ipyleaflet import Map, GeoJSON
import ipywidgets as ipyw
label = ipyw.Label(layout=ipyw.Layout(width='100%'))
label.value = u'0.0'

# kartan päälle luodaan GeoJSON pisteitä, jotka vastaavat edellä kerättyjä sääasemia
layer = GeoJSON( data = GEO )

# kun karttapistettä klikataan, niin tulostetaan tekstikenttään GeoJSON properties -tietoihin 
# talletettuna oleva lämpötila ja aseman nimi
def click_handler(event=None,id=None,properties=None):
    label.value = str( properties.get('Temperature') ) +' ℃ : ' + properties.get('name')

layer.on_click(click_handler)

# luodaan kartta keskitettynä Tampereelle
map = Map( zoom=7, center=[61.4978,23.7610])

# liitetään kartan päälle sääasemien pisteet
map.add_layer( layer )

# näytetään tekstikenttä ja kartta tässä notebook:ssa
ipyw.VBox( [label,map] )<jupyter_output>Widget Javascript not detected.  It may not be installed or enabled properly.
StarcoderdataJupyterStructuredCleanDedup