TransWikia.com

How to capture real time weather data of points using OpenWeatherMap

Geographic Information Systems Asked by Zess on May 29, 2021

I want to set points on a map layer with autofilled data in some fields in the attribute table, which already works fine with date/time and username/observer.

Is there also a way to capture real time weather data every time a point is set on the layer? (E.g. temperature, humidity and sight)

I have access to an API Key of OpenWeatherMap.

One Answer

You could use a custom function such as:

from qgis.core import *
from qgis.gui import *
import urllib.request
import urllib
import json

@qgsfunction(args='auto', group='Custom')
def jsonfromurl(url, feature, parent):
    header = {"accept":"application/json"}
    request = urllib.request.Request(url)
    response = urllib.request.urlopen(request)
    response_data = response.read()
    encoding = response.info().get_content_charset('utf-8')
    data = json.loads(response_data.decode(encoding))
    #txt = json.dumps(data) #uncomment this line to receive data as string. also change next line to: return txt
    return data

This function will get a JSON-Response from a given URL.

Open the expression dialog, for example via field calculator, and go to the "Function Editor"-Tab:

enter image description here

Save and load the custom function. Then go back to the regular "Expression"-Tab. Here you can use the new function. Dont forget to insert your personal API-Key.

Here some usage examples:

Get the "main"-content for your current location:

map_get(
jsonfromurl('http://api.openweathermap.org/data/2.5/weather?lat=' ||$y || '&lon=' || $x || '&appid=' || 'yourapikeyhere'),
'main')

enter image description here

Get the temperature for lat=35 and lon=139:

map_get(
map_get(
jsonfromurl('http://api.openweathermap.org/data/2.5/weather?lat=35&lon=139&appid=' || 'yourapikeyhere'),
'main'),
'temp')

enter image description here

Get the wind speed of the current location:

map_get(
map_get(
jsonfromurl('http://api.openweathermap.org/data/2.5/weather?lat=' ||$y || '&lon=' || $x || '&appid=' || 'yourapikeyhere'),
'wind'),
'speed')

enter image description here

If you want to get the current location, make sure your layer is in EPSG:4326 (or use transform(), e.g. map_get(map_get(jsonfromurl('http://api.openweathermap.org/data/2.5/weather?lat=' ||y(transform($geometry,layer_property(@layer,'crs'),'EPSG:4326')) || '&lon=' || x(transform($geometry,layer_property(@layer,'crs'),'EPSG:4326')) || '&appid=' || 'yourapikeyhere'),'wind'),'speed')).

If you need metric units from the response, just add units=metric to the url. For example:

map_get( map_get( jsonfromurl('http://api.openweathermap.org/data/2.5/weather?units=metric&lat=' ||$y || '&lon=' || $x || '&appid=' || 'yourapikeyhere'), 'main'), 'temp')

As you can see, you need to change map_get() and/or the URL depending on what you want to receive. Check out openweathermap API docs for details: https://openweathermap.org/current#geo or look at their example response, e.g.:

{"coord":{"lon":139,"lat":35},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}],"base":"stations","main":{"temp":282.1,"feels_like":281.16,"temp_min":279.82,"temp_max":284.82,"pressure":1013,"humidity":76},"visibility":10000,"wind":{"speed":1.95,"deg":63,"gust":2.92},"clouds":{"all":59},"dt":1617734050,"sys":{"type":3,"id":2019346,"country":"JP","sunrise":1617740571,"sunset":1617786549},"timezone":32400,"id":1851632,"name":"Shuzenji","cod":200}

If you enter this expression as default value in attributes form, it will be the standard-value for your field:

enter image description here

Example result:

enter image description here

Answered by MrXsquared on May 29, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP