Accessing data using the Download Service

Download Service is way to get the Open Data from FMI to be used by your applications. The guidelines for the INSPIRE directive give a couple of technological options for implementing a Download Service. FMI has chosen to provide the data using the OGC Web Feature Service interface with separate download links for binary data files.

OGC Web Feature Service (WFS) is a generic interface standard for providing access to geospatial objects, or objects with some kind of location or covered geospatial area. These objects can contain any information, and the internal structure of the objects is not limited by the specification. A WFS service is like a generic object database with a standardized query language. These geospatial objects are called "features".

Typically WFS services return the requested data encoded as XML language called Geography Markup Language (GML), which is another OGC and ISO standard. The service has to able to return the structure description of each of the provided feature types in XML Schema language (the DescribeFeatureType operation). This operation can be used to get the expected structure information for the WFS service data responses before making the actual GetFeature request for retrieving the data.

The latest version of the WFS standard is 2.0, which is also the version required by the INSPIRE directive technical guidance. Consequently the FMI's WFS service also only implements this version of the WFS specification.

The WFS 2.0 defines the following operations:

  • GetCapabilities return service metadata,
  • DescribeFeatureType returns XML Schema description for the requestes feature types,
  • GetPropertyValue returns only the values of selected properties of the requested features,
  • GetFeature returns a list of features based on the given query,
  • LockFeature lock a set of features protecting them from changes (optional),
  • GetFeatureWithLock same as GetFeature but also lock the returned features (optional).

Additionally the WFS service may implement changing the feature collection data (the Transaction operation) and managing stored queries, which are named and parametrized queries to be used with GetFeature operation.

The current version on FMI's Open Data WFS service uses the stored queries extensively to enable users to select the features, areas and times they require as easily as possible. See FMI Open data WFS Service for more detailed information about the available stored queries and their request parameters. For more info on the data models (feature types) used by FMI's Open Data WFS service see page About the Observations & Measurements data model, and if the XML based WFS interface seems a bit too much, and you just want to get your hands on the to the FMI's weather timeseries data, go directly to WFS timeseries page including usage examples for client library (MetOLib).

WFS provides collections of features

The WFS operation actually returning the data is called GetFeature. It always returns a collection of features, typically encoded as an XML document.

Some features are relatively simple:

<ms:greenland_elevation_contour>
  <gml:boundedBy>
    <gml:Envelope srsName="EPSG:32661">
      <gml:lowerCorner>-327189.501776 -456661.863393</gml:lowerCorner>
      <gml:upperCorner>-327164.993574 -456636.649888</gml:upperCorner>
    </gml:Envelope>
  </gml:boundedBy>
  <ms:msGeometry>
    <gml:LineString srsName="EPSG:32661">
      <gml:posList srsDimension="2">-327164.993574 -456638.840870
-327189.501776 -456636.649888
-327183.636846 -456661.863393
-327168.660334 -456653.526955
-327164.993574 -456638.840870
      </gml:posList>
    </gml:LineString>
  </ms:msGeometry>
  <ms:Label>1000 m</ms:Label>
  <ms:Elevation>1000.000000</ms:Elevation>
</ms:greenland_elevation_contour>

Some may be more complicated containing inner objects and deep structure:

<omso:PointTimeSeriesObservation gml:id="fct-1">
  <!-- Reference to HIRLAM forecast model 2011-01-18 09:00 UTC run
    metadata record (at FMI catalog service)-->
  <om:metadata xlink:href="http://catalog.fmi.fi/model/hirlam?run=2011-01-18T09:00:00Z&format=gml"/>

  <om:phenomenonTime>
    <gml:TimePeriod gml:id="time-1">
      <!-- Forecast spans this time period -->
      <gml:beginPosition>2011-01-18T12:00:00Z</gml:beginPosition>
      <gml:endPosition>2011-01-18T18:00:00Z</gml:endPosition>
    </gml:TimePeriod>
  </om:phenomenonTime>

  <om:resultTime>
    <gml:TimeInstant gml:id="time-2">
      <!-- This data became available at 09:45 UTC -->
      <gml:timePosition>2011-01-18T09:45:00Z</gml:timePosition>
    </gml:TimeInstant>
  </om:resultTime>

  <om:validTime>
    <gml:TimePeriod gml:id="time-3">
      <!-- This data should only be used for estimating the expected weather conditions
        within this time period. After this a more recent model run
        data should be used instead. -->
      <gml:beginPosition>2011-01-18T09:00:00Z</gml:beginPosition>
      <gml:endPosition>2011-01-18T16:00:00Z</gml:endPosition>
    </gml:TimePeriod>
  </om:validTime>

  <om:procedure xlink:href="../../../static/process/Inspire-Hirlam74-process.xml"/>

  <!-- Analysis time = nominal time for the forecast model run analysis phase.
      Different model runs are separated from each other by using
      different analysis times.
  -->
  <om:parameter>
    <om:NamedValue>
      <om:name xlink:href="http://inspire.ec.europa.eu/codeList/ProcessParameterValue/value\
/numericalModel/analysisTime"/>
      <om:value>
        <gml:TimeInstant gml:id="at-1">
          <gml:timePosition>2012-01-18T09:00:00Z</gml:timePosition>
        </gml:TimeInstant>
      </om:value>
    </om:NamedValue>
  </om:parameter>

  <!-- Must be a reference by schema definition, no embedding allowed here, so make it dynamic: -->
  <om:observedProperty xlink:href="/observable-property-composite?\
params=air-temp-1h-max,atmospheric-pressure-1h-avg,wind-speed-1h-avg,\
wind-direction-1h-avg"/>

  <!-- Put the FOI embedded here, because this changes with every request with point forecast -->
  <om:featureOfInterest>
    <sams:SF_SpatialSamplingFeature gml:id="uuid-4329293474dfgdf">
      <sam:sampledFeature xlink:href="../../../static/foisurfaceWeatherTargetArea_Finland_epsg4258.xml"/>
      <sams:shape>
        <gml:Point gml:id="id-1" srsName="http://www.opengis.net/def/crs/EPSG/0/4258"\
srsDimension="2">
          <gml:pos>60.17522 24.94458</gml:pos>
        </gml:Point>
      </sams:shape>
    </sams:SF_SpatialSamplingFeature>
  </om:featureOfInterest>

  <om:result>
    <gmlcov:MultiPointCoverage gml:id="mpcv1">
      <gml:domainSet>
        <gmlcov:SimpleMultiPoint gml:id="mp1" srsName="http://xml.fmi.fi/gml/crs/epoch-time.xml"\
srsDimension="1">
          <gmlcov:positions>
            <!--
              epoch times
              2011-01-18T12:00:00Z
              2011-01-18T13:00:00Z
              2011-01-18T14:00:00Z
              2011-01-18T15:00:00Z
              2011-01-18T16:00:00Z
              2011-01-18T17:00:00Z
              2011-01-18T18:00:00Z
            -->
            1295352000
            1295355600
            1295359200
            1295362800
            1295366400
            1295370000
            1295373600
          </gmlcov:positions>
        </gmlcov:SimpleMultiPoint>
      </gml:domainSet>
      <gml:rangeSet>
        <gml:DataBlock>
          <gml:rangeParameters/>
          <!-- the measurement values that correspond to the (temporal) grid points -->
          <gml:doubleOrNilReasonTupleList>
            1.1 1003.5 2.6 232.0
            1.0 1004.1 3.0 232.0
            1.1 1010.6 2.8 221.0
            1.0 1045.7 1.7 244.0
            1.0 1045.0 1.3 217.0
            1.0 1023.4 1.2 217.0
            1.0 1033.1 1.7 210.0
          </gml:doubleOrNilReasonTupleList>
        </gml:DataBlock>
      </gml:rangeSet>
      <gml:coverageFunction>
        <gml:CoverageMappingRule>
          <gml:ruleDefinition>Linear</gml:ruleDefinition>
        </gml:CoverageMappingRule>
      </gml:coverageFunction>

      <!-- Definition of the values given in the rangeSet -->
      <gmlcov:rangeType>
        <swe:DataRecord>
          <swe:field
            name="airTemperature"
            xlink:href="/observable-property?air-temp-1h-max"/>
          <swe:field
            name="atmosphericPressure"
            xlink:href="/observable-property?atmospheric-pressure-1h-avg"/>
          <swe:field
            name="windSpeed"
            xlink:href="/observable-property?wind-speed-1h-max"/>
          <swe:field
            name="windDirection"
            xlink:href="/observable-property?wind-direction-1h-avg"/>
        </swe:DataRecord>
      </gmlcov:rangeType>
    </gmlcov:MultiPointCoverage>
  </om:result>
</omso:PointTimeSeriesObservation>

 

In any case the GML encoded WFS response is wrapped in a wfs:FeatureCollection element:

<?xml version="1.0" encoding="UTF-8"?>
<wfs:FeatureCollection
  timeStamp="2012-04-03T22:56:09"
  numberMatched="15"
  numberReturned="1"
  xmlns:wfs="http://www.opengis.net/wfs/2.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  xmlns:om="http://www.opengis.net/om/2.0"
  xmlns:omso="http://inspire.ec.europa.eu/schemas/omso/2.9"
  xmlns:gml="http://www.opengis.net/gml/3.2"
  xmlns:swe="http://www.opengis.net/swe/2.0"
  xmlns:gmlcov="http://www.opengis.net/gmlcov/1.0"
  xmlns:sam="http://www.opengis.net/sampling/2.0"
  xmlns:sams="http://www.opengis.net/samplingSpatial/2.0"
  xsi:schemaLocation="http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd
http://www.opengis.net/gmlcov/1.0
http://schemas.opengis.net/gmlcov/1.0/gmlcovAll.xsd
http://www.opengis.net/sampling/2.0
http://schemas.opengis.net/sampling/2.0/samplingFeature.xsd
http://www.opengis.net/samplingSpatial/2.0
http://schemas.opengis.net/samplingSpatial/2.0/spatialSamplingFeature.xsd
http://www.opengis.net/swe/2.0
http://schemas.opengis.net/sweCommon/2.0/swe.xsd
http://inspire.ec.europa.eu/schemas/omso/2.9
http://inspire.ec.europa.eu/draftschemas/omso/2.9/SpecialisedObservations.xsd">

  <wfs:boundedBy>
    <!-- 2D Envelope for point forecast data (ETRS89 2D)  -->
    <gml:Envelope srsName="http://www.opengis.net/def/crs/EPSG/0/4258" srsDimension="2">
      <gml:lowerCorner>60.17522 24.94458</gml:lowerCorner>
      <gml:upperCorner>60.17522 24.94458</gml:upperCorner>
    </gml:Envelope>
  </wfs:boundedBy>

  <wfs:member>
     ....
     [the first response feature here]
     ....
  </wfs:member>

  <wfs:member>
     ....
     [the second response feature here]
     ....
  </wfs:member>

   [etc]

</wfs:featureCollection>