Get weather data using Weather API
thank you for your hard work.
This is Matsuyama from the System Development Office.
This time, I would like to create a weather checking application using the “Weather API”.
Previously, I thought it was necessary to purchase weather information from the Japan Meteorological Agency, but
now it seems that there is also an API that can be used for free, so I will use this.
By the way, the Japan Meteorological Agency also seems to be distributing weather data for free, but
since it is basically meteorological data (rain, wind, temperature, etc.), it seems different from weather data.
(Past weather information was distributed)
requirements
① Use Rakuten Rapid API's Open Weather Map
② Reuse HTTP communication based on the one created previously
③ Obtain weather data for nearby cities from GPS location information
④ Display latitude, longitude, city name, and weather icons on the screen Display
* Created with Unity 2019.4.11f1
Rakuten Rapid API
Rakuten Rapid API is a service that allows you to use and develop APIs for various functions.
Although you need to register for an account, there are many features that can be used for free, so you can try out various things.
Rakuten Rapid API
Open Weather Map
Get weather data using the Open Weather Map found in the Rakuten Rapid API.
Open Weather Map
There are several APIs, but if you want to get the current weather, you can use the Current Weather Data API.
You can test it on the browser, so it's a good idea to try it out while adjusting the parameters.
Please note that it will be counted in the number of calls even in the test. (Free for 500 times a month)
The following information is required as API request information.
・Request header (fixed)
request.AddHeader("x-rapidapi-host", "community-open-weather-map.p.rapidapi.com"); // Host address request.AddHeader("x-rapidapi-key", "xxxxxxxxxxxxxxxxx"); // API key issued for each account
・Request parameter
q: City ID (*required)
There seems to be no problem even if there are no other optional parameters.
You can obtain
your city ID here You can get weather data for registered cities.
HTTP communication
In accordance with the above requirements, we will proceed with implementation based on the processes created in the past.
Click here for past articles
Copy the sources from Scripts/Utility and Scripts/Api
・ApiBase.cs
・CoroutineHandler.cs
・SigletonMonoBehaviour.cs
・Network.cs
・ApiSample.csAbout
this area
Add/adjust functionality to support OpenWeatherMap.
1. Corresponds to GET Method
To support GET Method, request parameters passed in JSON are converted into a string by connecting them to the URL.
Although it is quite tentative, it is implemented in the following form.
private string convGetParam(string json) { string jsonTrim = json.Trim('{', '}'); jsonTrim = jsonTrim.Replace("\"", ""); string[] jsonArry = jsonTrim.Split(', '); string retStr = "?"; bool isFirst = true; foreach (var data in jsonArry) { if (!data.Contains(":")) break; if (!isFirst) { retStr += "&"; } else { isFirst = false; } string[] paramAry = data.Split(':'); retStr += paramAry[0] + "=" + paramAry[1]; } return retStr; }
2. Set request headers
Here, as mentioned above, set the host address and API key.
*Values are displayed on the OpenWeatherMap screen
3. Define HTTP request and response parameters
Create a class for acquiring weather data under Script/Api.
This time it was created using WeatherApi.cs.
■ Request
The request is only the city name.
[Serializable] public struct Request { public string q; }
■Response
The response is a bit long, but it will be expanded like this.
Actually, all you need is the Weather structure, but I made it possible to get it just in case.
[Serializable] public struct Coord { public float lon; public float lat; } [Serializable] public struct Weather { public int id; public string main; public string description; public string icon; } [Serializable] public struct Main { public float temp ; public float fells_like; public float temp_min; public float temp_max; public int pressure; public int humidity; } [Serializable] public struct Wind { public float speed; public int deg; } [Serializable] public struct Rain { // public float 1h ; // 1h cannot be used as an element name } [Serializable] public struct Clouds { public int all; } [Serializable] public struct Sys { public int type; public int id; public string country; public int sunrise; public int sunset; } [Serializable] public struct Response { public Coord coord; public List<Weather> weather; // public string base; // base cannot be used as an element name public Main main; public int visibility; public Wind wind; public Rain rain; public Clouds clouds; public int dt; public Sys sys; public int timezone; public int id; public string name; public int cod; }
*There are some names that cannot be used and have been commented out, but this time we will not worry about them as the information will not be used ^^;
For now, I think the communication related preparations are OK.
Using GPS
We will also write the necessary code for GPS, referring to what we have created in the past.
Click here for past articles
The required GPS processing this time is:
Input.location.Start(); Input.compass.enabled = true;
Do this first,
Input.location.lastData.longitude; // Longitude Input.location.lastData.latitude; // Latitude
Just get the latitude and longitude using lastData.
* Strictly speaking, we will also determine whether GPS can be used.
Input.location.isEnabledByUser; // Is the use of GPS allowed? Input.location.status; // Can be used if in Running state
Also, don't forget to fill in Location Usage Description in ProjectSettings.
weather data
As mentioned above, in order to obtain weather data, it is necessary to specify a registered city, so
for verification purposes, we extracted one city data from 47 prefectures and selected
the nearest one from the latitude and longitude obtained by GPS. Implement it in the flow of acquiring weather data for a city.
First, create the city data.
As city data, prefecture name, city name, city name (for API), latitude, and longitude are defined in the following structure.
private struct Data { public string prefecture; // Prefecture name public string city; // City name public string name; // City name passed to the API public double lon; // Longitude public double lat; // Latitude }
Convert it into data like this.
static private List<Data> datas = new List<Data> { new Data { prefecture = "Hokkaido", city = "Sapporo City", name = "sapporo", lon = 141.346939, lat = 43.064171 }, new Data { prefecture = "Aomori Prefecture", city = "Aomori City", name = "aomori", lon = 140.740005, lat = 40.82444 }, new Data { prefecture = "Iwate Prefecture", city = "Morioka City", name = "morioka", lon = 141.152496, lat = 39.703609 }, new Data { prefecture = "Miyagi Prefecture", city = "Sendai City", name = "sendai", lon = 140.871933, lat = 38.26889 }, new Data { prefecture = "Akita Prefecture", city = "Akita City", name = "akita" , lon = 140.116669, lat = 39.716671 }, new Data { prefecture = "Yamagata Prefecture", city = "Yamagata City", name = "yamagata", lon = 139.821671, lat = 38.721668 }, new Data { prefecture = "Fukushima Prefecture ", city = "Fukushima City", name = "fukushima", lon = 140.383331, lat = 37.400002 }, // // omitted // new Data { prefecture = "Kagoshima Prefecture", city = "Kagoshima City", name = "kagoshima", lon = 130.558136, lat = 31.560181 }, new Data { prefecture = "Okinawa Prefecture", city = "Naha City", name = "naha", lon = 127.681107, lat = 26.2125 } };
Next, search for the nearest city data based on your current location (latitude and longitude).
Would it be good to have a function like this?
static public Info NearbyCity(double lon, double lat) { Info info = new Info(); float dist = 9999f; foreach(Data dat in datas) { double z = (dat.lat - lat) * Lat2Km; // -z is south double x = (dat.lon - lon) * Lat2Km; // +x is east Vector3 v = new Vector3((float)x, 0, (float)z); if(v.magnitude < dist) { dist = v.magnitude; info.city = dat.prefecture + dat.city; info.name = dat.name; } } return info; }
The returned value structure will be the prefecture/city name for display and the city name for API.
public struct Info { public string city; public string name; }
Display latitude, longitude, city name, and weather icons on the screen
Configure the screen in Unity.
Roughly this image
All that's left to do is display the information obtained using GPS and API, and here's the finished product.
You can check information such as weather ID and weather icons here.
Weather data details
summary
It's a bit of a rush, but I think it's a sample that roughly displays the weather.
Acquisition of weather data itself can be implemented with a single API, but linking (data conversion) between registered cities and current locations may be a bit of a hassle.
This time as well, I will upload the sample project to GitHub.
I hope this will be of some help to you.
Unity sample
Rakuten Rapid Api has other functions, so I would like to use it another time.
lastly
I have opened the system development service site "SEKARAKU Lab" to which I belong.
Beyond is a one-stop service for everything from server design and construction to operation, so if you have any trouble with server-side development, please feel free to contact us.
SEKARAKU Lab: [https://sekarakulab.beyondjapan.com/](https://sekarakulab.beyondjapan.com/)
Well, that's all for now.