Search code examples
openlayerswmsopenlayers-5

Openlayers - WMS layer: how to get the time dimension from a specific layer


I'm trying to load a WMS-layer. Using the current ISO-8601 Time the layer is showing, but I also want to be able to set different Date/Times.

In order to use Date/Times that are within a certain range I need to retrieve the Time Dimension through e.g. the GetCapabilities for this specific layer and put the retrieved values in an array. And from then on I can use updateParams to set/update the Date/Time.

How can I do that?

E.g:

var WMS_DWD = new ol.layer.Image({
    name: 'Radar D',
    title: "Radar D",
    source: new ol.source.ImageWMS({
        ratio: 1,
        url: 'https://maps.dwd.de/geoserver/ows?service=wms&version=1.3.0&request=GetCapabilities',
        params: {
            'FORMAT': "image/png",
            'VERSION': '1.1.1',
            'LAYERS': 'dwd:RX-Produkt',
             time   : '2019-02-03T15:35:00.000Z',
            "exceptions": 'application/vnd.ogc.se_inimage'
        }
    })
});

When I view the url in the browser the resulting XML has a TAG "".....in this case for the layer "dwd:RX-Produkt".

Within this TAG there are a number of available Date/Times showing. These "Date/Times" I need to put into an array.

I hope you can help me!

EDIT: below an updated code (thx to oicgasser)

WMSlyr = new ol.layer.Tile({
        name: 'myLYR',
        title: "myLYR",
        preload: Infinity,
        source: new ol.source.TileWMS({
            url: 'https://ogcie.iblsoft.com/observations',
            params: {
               'FORMAT': "image/png",
               'VERSION': '1.3.0'
            }
        }),
        urlCapabilities: 'https://ogcie.iblsoft.com/observations?REQUEST=GetCapabilities&SERVICE=WMS&VERSION=1.3.0'
    });

LYR = 'metar';

url = 'https://ogcie.iblsoft.com/observations?REQUEST=GetCapabilities&SERVICE=WMS&VERSION=1.3.0';

window['timeArray'] = [];

var parser = new ol.format.WMSCapabilities();

Time = '2019-02-15T17:00:00.000Z';

fetch(url).then(function (response) {
       return response.text();
    }).then(function (text) {
    var capabilities = parser.read(text);
    var currentProj = map.getView().getProjection().getCode();
    var crs;

    // the parser can only read the list of projections from the WMS 1.3.0 responses.
    // For previous version the current projection wil be used as the default one.
    // If the WMS (< 1.3.0) does not support the default projection the layer will not load.
    if (capabilities.version === '1.3.0'){
        crs = capabilities.Capability.Layer.CRS; // supported EPSG-numbers
    }
    else {
        crs = [currentProj];
    }

    console.log('Projection WMS: ' + crs);

    var layers = capabilities.Capability.Layer.Layer;

    var AllLayerNames = [];

    if (layers.length > 0 && crs.indexOf(currentProj) > -1){
        for (var i = 0; i < layers.length; i += 1){
            if ( _.isArray(layers[i]['Dimension']) && layers[i]['Dimension'].length > 0 ){
                console.log(layers[i].Name);

                AllLayerNames.push(layers[i].Name);

                console.log(layers[i]['Dimension'][0]['values']);
            }
        }
    }


    var LYRnr =  (_.invert(AllLayerNames))[LYR];

    window['timeArray'] = layers[LYRnr]['Dimension'][0]['values'].split(',');

    var formats = capabilities.Capability.Request.GetMap.Format;
    var allformats = [];
    for (var i = 0; i < formats.length; i += 1){
        allformats.push(formats[i]);
    }
    console.log(allformats); // array with all the supported output-formats

    if (window['timeArray'].indexOf(Time.substr(0,16))) { // use part of string because some WMS dimensions use milliseconds and some do not
        WMSlyr.getSource().updateParams({'LAYERS': LYR, 'TIME': Time});
    }
});

Question that remains is:

  • Some WMScapabilities-XML (e.g. 'https://maps.dwd.de/geoserver/wms?version=1.3.0&request=GetCapabilities') show layers deeper than 'normal'. The code shows an error because the Dimension of the layer LYR is not found........How can I search for these layers when I have the name of that layer or even better.....how can I generalize the code above to achieve that?

Solution

  • There is a WMS GetCapabilities parser in Openlayers.

    Here is a code sample on how to achieve that with ol 4.6.5:

    var parser = new ol.format.WMSCapabilities();
    fetch("https://maps.dwd.de/geoserver/ows?service=wms&version=1.3.0&request=GetCapabilities")
      .then(function(response) {
        return response.text();
      })
      .then(function(text) {
        var result = parser.read(text);
        var layers = result.Capability.Layer.Layer;
        console.log(layers);
      })
    });
    

    Then you need to look for the layer you are interested in the array and analyse the Dimension field. Make sure you recursively look in all the child layers since they are nested for the most part.

    Here is a codepen with your WMS GetCapabilities: https://codepen.io/loicgasser/pen/BMdLYX