How to fetch hourly observations from GeoJson endpoint?

WOW exposes observation data from various endpoints with different data types. One of them is GeoJson, which is defined as below in GeoJson.org:

GeoJSON is a format for encoding a variety of geographic data structures.

GeoJSON supports the following geometry types: Point, LineString, Polygon, MultiPoint, MultiLineString, and MultiPolygon. Geometric objects with additional properties are Feature objects. Sets of features are contained by FeatureCollection objects.

WOW itself uses GeoJson format on its map from the same endpoint, so you will have the same results in the API response with the data on map. To learn how to connect to WOW API in detail, please refer to our article “How to connect to WOW API?”.

The GeoJson endpoint always shows the data in hourly ranges. It searches for the observations within that hour and shows the latest observations per site within the hour. If a site has multiple observations in that selected hour, only the latest one is returned.

You can also send parameters to filter the data or show additional information. The full list is at GetObservationsAsGeoJson API Reference, so you can tweak your result set however you wish.

Following code is a sample to access public observation data within the last hour.

private static async Task MainAsync()
{
    var observations = await GetLastHourObservationsAsGeoJson("your-api-key");
    foreach (var observation in observations.features)
    {
        Console.WriteLine("Id: " + observation.properties.reportId);
        Console.WriteLine("SiteId: " + observation.properties.msi);
        Console.WriteLine("Report Date: " + observation.properties.reportEndDateTime);
        Console.WriteLine("Temperature: " + observation.properties.primary.dt);
    }
}

private static async Task<dynamic> GetLastHourObservationsAsGeoJson(string subscriptionKey)
{
    using (var httpClient = new HttpClient())
    {
        httpClient.BaseAddress = new Uri("https://mowowprod.azure-api.net");
        httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", subscriptionKey);

        using (var response = await httpClient.GetAsync("/api/observations/geojson"))
        {
            response.EnsureSuccessStatusCode();
            return JObject.Parse(await response.Content.ReadAsStringAsync());
        }
    }
}

Common Usage Scenarios

Below, you will find a few common scenarios and their code samples.

Observations within the current hour:

private static async Task<dynamic> GetObservationsAsGeoJson(string subscriptionKey)
{
    using (var httpClient = new HttpClient())
    {
        httpClient.BaseAddress = new Uri("https://mowowprod.azure-api.net");
        httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", subscriptionKey);

        using (var response = await httpClient.GetAsync("/api/observations/geojson?timePointSlider=25"))
        {
            response.EnsureSuccessStatusCode();
            return JObject.Parse(await response.Content.ReadAsStringAsync());
        }
    }
}

Observations at a specific date and time:

private static async Task<dynamic> GetObservationsAsGeoJson(string subscriptionKey)
{
    using (var httpClient = new HttpClient())
    {
        httpClient.BaseAddress = new Uri("https://mowowprod.azure-api.net");
        httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", subscriptionKey);

        using (var response = await httpClient.GetAsync("/api/observations/geojson?useSlider=false&mapTime=23/04/2016 13:59"))
        {
            response.EnsureSuccessStatusCode();
            return JObject.Parse(await response.Content.ReadAsStringAsync());
        }
    }
}

Observations in a geographical bounding box within the past hour:

private static async Task<dynamic> GetObservationsAsGeoJson(string subscriptionKey)
{
    using (var httpClient = new HttpClient())
    {
        httpClient.BaseAddress = new Uri("https://mowowprod.azure-api.net");
        httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", subscriptionKey);

        using (var response = await httpClient.GetAsync("/api/observations/geojson?northLat=90&westLon=-180&southLat=-90&eastLon=180"))
        {
            response.EnsureSuccessStatusCode();
            return JObject.Parse(await response.Content.ReadAsStringAsync());
        }
    }
}

Only official observations within the past hour:

private static async Task<dynamic> GetObservationsAsGeoJson(string subscriptionKey)
{
    using (var httpClient = new HttpClient())
    {
        httpClient.BaseAddress = new Uri("https://mowowprod.azure-api.net");
        httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", subscriptionKey);

        using (var response = await httpClient.GetAsync("/api/observations/geojson?showOfficialData=on&showWowData=off"))
        {
            response.EnsureSuccessStatusCode();
            return JObject.Parse(await response.Content.ReadAsStringAsync());
        }
    }
}

Only WOW observations within the past hour:

private static async Task<dynamic> GetObservationsAsGeoJson(string subscriptionKey)
{
    using (var httpClient = new HttpClient())
    {
        httpClient.BaseAddress = new Uri("https://mowowprod.azure-api.net");
        httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", subscriptionKey);

        using (var response = await httpClient.GetAsync("/api/observations/geojson?showOfficialData=off&showWowData=on"))
        {
            response.EnsureSuccessStatusCode();
            return JObject.Parse(await response.Content.ReadAsStringAsync());
        }
    }
}

Images submitted today:

private static async Task<dynamic> GetImagesAsGeoJson(string subscriptionKey)
{
    using (var httpClient = new HttpClient())
    {
        httpClient.BaseAddress = new Uri("https://mowowprod.azure-api.net");
        httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", subscriptionKey);

        using (var response = await httpClient.GetAsync("/api/observations/geojson?useSlider=false&timePointPicker=-1&mapLayer=imageKey"))
        {
            response.EnsureSuccessStatusCode();
            return JObject.Parse(await response.Content.ReadAsStringAsync());
        }
    }
}

Impacts submitted in the last month:

private static async Task<dynamic> GetImpactsAsGeoJson(string subscriptionKey)
{
    using (var httpClient = new HttpClient())
    {
        httpClient.BaseAddress = new Uri("https://mowowprod.azure-api.net");
        httpClient.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", subscriptionKey);

        using (var response = await httpClient.GetAsync("/api/observations/geojson?useSlider=false&timePointPicker=-31&mapLayer=impactv2"))
        {
            response.EnsureSuccessStatusCode();
            return JObject.Parse(await response.Content.ReadAsStringAsync());
        }
    }
}

Observation result set format

{
  "type": "FeatureCollection",
  "crs": {
    "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" },
    "type": "name"
  },
  "features": [ // List of observations
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [ 1.921427, 42.39833 ] // Coordinates of the observation in [ Longitude, Latitude ] format
      },
      "properties": {
        "reportId": "201612187kkbcmsfcoe6pfyyyyb96smacr", // Id of the observation
        "msi": "22678525", // SiteId
        "siteId": "22678525", // SiteId
        "reportStartDateTime": "2016-12-18T20:59:58Z", // Observation start date
        "reportEndDateTime": "2016-12-18T20:59:58Z", // Observation end date (main date)
        "type": "jtwr", // Type of the feature. Check “Feature Type” section for detail.
        "observationType": 1, // Type of the observation
        "softwareType": "meteohub", // Software used to send this observation
        "collectionName": 1, // Collection Name / Id
        "version": 1, // Revision version number. Starts from 1.
        "primary": {
          "dt": -3.6111111111111112, // Air Temperature (Dry Bulb) in Celsius
          "dws": 1.7379511044456706, // Wind Speed in mph (for BOM Knots)
          "dwd": 90.0, // Wind Direction in Degrees
          "drr": 0.0, // Rainfall Rate in mm/hr
          "dra": 0.0, // Rainfall Amount in mm
          "dm": 895.0226127, // Mean Sea Level Pressure in hPa
          "dh": 78.0, // Humidity in Percentage
          "ds": 0.0, // Snow in mm
          "dwc": 0.0, // Present Weather Code
          "dsm": 0.0, // Soil Moisture in Percentage
          "dp": “”, // Photo Id of the observation
          "dpurl": “”, // Photo URL of the observation
          "di": “” // Attached weather impact Id
        },
        "secondary": {
          "dt": 25.5, // Air Temperature (Dry Bulb) in Fahrenheit
          "dws": 1.7379511044456706, // Wind Speed in Knots (for BOM km/h)
          "dwd": 90.0, // Wind Direction in Degrees
          "drr": 0.0, // Rainfall Rate in inches/hr
          "dra": 0.0, // Rainfall Amount in inches
          "dm": 26.43, // Mean Sea Level Pressure in inches of mercury
          "dh": 78.0, // Humidity in Percentage
          "ds": 0.0, // Snow in inches
          "dwc": 0.0, // Present Weather Code
          "dsm": 0.0, // Soil Moisture in Centibar
          "dp": “”, // Photo Id of the observation
          "dpurl": “”, // Photo URL of the observation
          "di": “” // Attached weather impact Id

        },
        "universal": { } // For the impacts
      }
    }
  ]
}