Menu
  • Hem
  • Dokument
  • Om Mig
Geosupportsystem

Väder i QGIS?

Posted on 2017-08-10

SMHI har mängder av öppna API för att komma åt data av olika slag. I detta inlägg tittar jag närmare på prognosdata och om det är möjligt att bygga in stöd för detta i QGIS på något sätt.
SMHI släpper väldigt mycket data under licensen Creative Commons 4.0 BY, och på http://opendata.smhi.se/apidocs/metfcst så finns mer information om de olika tjänsterna.
Jag är intresserad av prognosdata på valfri geografisk plats i Sverige, så då använder jag ”pmp3g v2”, som du kan läsa mera om på http://opendata.smhi.se/apidocs/metfcst/parameters.html.
I korthet så ger man ett kommando:
GET /api/category/{category}/version/{version}/geotype/point/lon/{longitude}/lat/{latitude}/data.json
Vilket returnerar en mängd data för den angivna punkten. Man kan prova i en vanlig webbläsare också med (exempelvis):
https://opendata-download-metfcst.smhi.se/api/category/pmp3g/version/2/geotype/point/lon/14.97/lat/57.67/data.json
Ovanstående hämtar och visar prognosdata för Eksjö i JSON format.
Det är en ganska stor mängd data organiserad i en ”tidsserie” där det närmaste dygnet anges timme för timme, för att övergå till tre timmars intervall och senare sex och tolv timmar, i upp till tio dygn framåt. Data uppdateras regelbundet, så oavsett när man begär dessa data så skall de vara så aktuella de kan vara.
I tidsserien så finns det runt 20 parametrar för varje tidpunkt där temperatur, vind, relativ fuktighet, regnmängd, etc. För att läsa dessa data och lyfta ut sådant man kan vara intresserad av så behövs någon form av ”tolk”.
Eftersom QGIS helst hanterar data med Python så behövs det ett Python bibliotek som förstår JSON.

lat = 57.67
lon = 14.97
url = 'https://opendata-download-metfcst.smhi.se/api/category/pmp3g/version/2/geotype/point/lon/%s/lat/%s/data.json' % (lon, lat)
import urllib3
import json
http = urllib3.PoolManager()
response = http.request('GET', url)
result = json.loads(response.data.decode('utf-8'))
print(result['timeSeries'][0]['parameters'][11])

Ovanstående skriver ut temperaturdata för den första tidsserien, det vill säga ”nu” på följande sätt:

{'unit': 'Cel', 'name': 't', 'levelType': 'hl', 'level': 2, 'values': [15.9]}

Så det är lika enkelt att enbart skriva ut temperaturen genom att lägga till [’values’][0] i kommandot, såhär:

print(result['timeSeries'][0]['parameters'][11]['values'][0])

Då finns det en metod för att hämta aktuell temperatur för en bestämd plats. Vilket gör det ganska enkelt att skapa en QGIS process som hämtar temperaturen för en angiven position.
Skärmbild_2017-08-04_10-42-07.png
När ovanstående körs så får man fylla i latitud och longitud, medan funktionen returnerar temperaturen just nu. Den här funktionen är ganska oanvändbar för sig själv då det inte finns någon metod för att fånga upp resultatet. Om man i stället gör det till en ren Pythonfunktion, så kan man baka in det i en pythonprocess som tar ett punktlager som indata, och går igenom alla punkterna samt lägger till temperatur i ett nytt attribut för alla dessa. En sådan funktion skulle kunna se ut såhär:

##Get Temp=name
##Punktlager=vector
from PyQt4.QtCore import QVariant
from qgis.core import QgsVectorLayer, QgsField
def getTemp(lat,lon):
 url ='https://opendata-download-metfcst.smhi.se/api/category/pmp3g/version/2/geotype/point/lon/%s/lat/%s/data.json' % (round(lon,5), round(lat,5))
 import urllib3
 import simplejson
 http = urllib3.PoolManager()
 r = http.request('GET', url)
 result = simplejson.loads(r.data.decode('utf-8'))
 temperatur=result['timeSeries'][0]['parameters'][11]['values'][0]
 return(temperatur)
lager = processing.getObjectFromUri(Punktlager)
lager.startEditing()
if (lager.isValid()):
 progress.setText('Lager OK')
else:
 progress.setText('Felaktigt lager')
namn = 'temp'
attribut = [attr.name() for attr in lager.pendingFields()]
try:
 if not namn in attribut:
  res = lager.dataProvider().addAttributes( [ QgsField(namn, QVariant.Double) ] )
  lager.updateFields()
except:
 progress.setText('Attribut temp finns redan, skriver över!')
for punkt in lager.getFeatures():
 geometri = punkt.geometry()
 lat = geometri.asPoint().y()
 lon = geometri.asPoint().x()
 temperatur = getTemp(lat, lon)
 punkt['temp'] = temperatur
 lager.updateFeature(punkt)
 progress.setText('Lat: %s Long: %s Temp: %s C' % (lat, lon, temperatur))
lager.commitChanges()

När jag kör detta skript som process så får jag först välja ett vektorlager, som måste vara oprojicerat med decimala lat/long koordinater, och det bör vara ett punktlager för att det skall fungera.
Skärmbild_2017-08-04_13-16-09.png
Skriptet kontrollerar om det finns ett ”temp” attribut, och lägger till det om så inte är fallet. Till detta attribut hämtas och skrivs aktuell temperatur från SMHI tjänsten.
Du kan själv anpassa skriptet och välja en annan ”timeSeries” för att få exempelvis prognos för i morgon, men även hämta andra värden än temperaturen.
På så sätt skulle man kunna använda QGIS för att skapa en helt egen prognoskarta med symboler och text. Exempelvis att sätta upp på friluftsanläggningen, arbetet, eller liknande, med egen layout och logotyp. Glöm bara inte att ange CC-BY SMHI som källa!
(Exempel på väderkarta i QGIS med prognos för om 24 timmar, från skapande tillfället):
Skärmbild från 2017-08-04 17-15-17.png
[Jag gjorde även en hastig YouTube film om hur kartan ovan är gjord.] https://www.youtube.com/watch?v=0MlgtpuONt4&t=302s

0 thoughts on “Väder i QGIS?”

  1. Johan T skriver:
    2017-08-13 kl. 15:12

    Tackar! Detta skall bli intressant att prova när tid finns.

    Svara

Lämna ett svar Avbryt svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *

Translate with Google

GBR In English
GER Auf Deutch
FRA En Français
ESP En Español
Swedish is a hard language for a machine to translate. Nuance and detail will likely be lost.
     

Bok om QGIS på Svenska

Bok

Beställ Boken/E-bok genom att klicka på bilden (även förhandsgranskning).

Senaste kommentarer

  • klakar om Laga hål i höjddata
  • Per Ekström om Laga hål i höjddata
  • Sur om Mera verktyg i QGIS
  • Anton om ”Mobile *.Geodatabase”
  • Fredrik Ekberg om Ingen är oskyldig

Arkiv

Prenumerera på Geosupportsystem

Skriv in namn och epost för att prenumerera på meddelanden från denna blogg.
Loading

geosupport

TrueNAS bygge. @fractaldesignna Define R5 är rikt TrueNAS bygge. @fractaldesignna Define R5 är riktigt trevlig att bygga i, och den sväljer väldigt mycket disk. Här skall virtualiseras både PostGis, WebODM och Geonode så småningom.
Då har jag lite att bläddra i ett tag framöver. Då har jag lite att bläddra i ett tag framöver.
YouTube video to frames. Processed in OpenDroneMap YouTube video to frames. Processed in OpenDroneMap and visualized in QGIS 3.17.
Ladda mer...

Meta

  • Logga in
  • Flöde för inlägg
  • Flöde för kommentarer
  • WordPress.org
©2021 Geosupportsystem | WordPress Theme by Superbthemes.com