[GIS] Including WMTS Layer from API in Openlayers2

apiopenlayers-2wmts

I´ve generated a map API from the GBIF data portal. It shows points from the country Mali.

enter image description here

I included the API as a WMTS in Openlayers2, but I dont know how to change the xyz accordingly, so that my data shows up properly in my openlayers2?

The implemented WMTS Layer code looks like this:

    var wmts = new OpenLayers.Layer.WMTS({
    name: "Observations Mali 2000-2010 WMTS Gbif",
    url: "http://api.gbif.org/v1/map/density/tile?x=0&y=0&z=0&type=COUNTRY&key=ML&layer=OBS_2000_2010&palette=yellows_reds",
    layer: "layer_id",
    style: "default",
    matrixSet: "matrix_id",
    isBaseLayer: false

});

map.addLayer(wmts);

And the webbrowser output (the yellow dots) looks like this so far:

enter image description here

Setting xyz as 0 values just give me a yellow point grid in my map.
Hope someone can give me a solution to my problem showing up the Mali data properly.

Best Answer

Why do you want to use WMTS? The GBIF website is based on Leaflet. The built-in tiles layer are not using WMTS grid at all but the OSM default grid.

Normally with both OpenLayers 2 and 3, you just have to change the URL parameters when tiles are base_url/z/x/y.png but the GBIF url do not work the usual way: it requires more changes as the url uses additional parameters.

For OpenLayers 2

Use the code below

var params = ['SP_1900_1910','OBS_1900_1910','OTH_1900_1910','SP_1910_1920',
              'OBS_1910_1920','OTH_1910_1920','SP_1920_1930','OBS_1920_1930',
              'OTH_1920_1930','SP_1930_1940','OBS_1930_1940','OTH_1930_1940',
              'SP_1940_1950','OBS_1940_1950','OTH_1940_1950','SP_1950_1960',
              'OBS_1950_1960','OTH_1950_1960','SP_1960_1970','OBS_1960_1970',
              'OTH_1960_1970','SP_1970_1980','OBS_1970_1980','OTH_1970_1980',
              'SP_1980_1990','OBS_1980_1990','OTH_1980_1990','SP_1990_2000',
              'OBS_1990_2000','OTH_1990_2000','SP_2000_2010','OBS_2000_2010',
              'OTH_2000_2010','SP_2010_2020','OBS_2010_2020','OTH_2010_2020',
              'SP_NO_YEAR','OBS_NO_YEAR','OTH_NO_YEAR','LIVING',
              'FOSSIL','SP_PRE_1900','OBS_PRE_1900','OTH_PRE_1900'];

var countries = ['ML'];

var getMyTileUrl = function getMyTileUrl(options) {
  var options = options;
    return function(bounds) {
      var res = this.map.getResolution();
      var x = Math.round ((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
      var y = Math.round ((this.maxExtent.top - bounds.top) / (res * this.tileSize.h));
      var z = this.map.getZoom();

      var country_params = options.countries.map(function(el) {
        return 'key='+ el;
      })
      var layer_params  options.layers.map(function(el) {
        return 'layer='+ el;
      })

      return this.url + '?' + 'x=' + x + '&y=' + y + '&z=' + z + '&' +
         'type=COUNTRY' + '&' + country_params.join('&') + '&' +
         layer_params.join('&')+ '&palette=yellows_reds';
   }
 }


 var layerGBIF = new OpenLayers.Layer.XYZ("GBIF",
   'http://api.gbif.org/v1/map/density/tile',
   {
     name: 'layer name',
     sphericalMercator: true,
     getURL: getMyTileUrl({layers: params, countries: countries}),
     type: 'png',
     isBaseLayer: false,
     transitionEffect: 'resize',
     buffer: 3
 });

 map.addLayer(layerGBIF);

See a working demo. (Added by editing)

To change parameters in URL, just do in the browser debugger console:

layerGBIF.getURL = getMyTileUrl({layers: ['OTH_1990_2000', 'OTH_2000_2010'], countries: ['ML']});
layerGBIF.redraw();

For OpenLayers 3 (it was my first answer...)

You can use the following. I use some parameters so it's possible to change layers or countries instead of only relying on x, y, z

var params = ['SP_1900_1910','OBS_1900_1910','OTH_1900_1910','SP_1910_1920',
              'OBS_1910_1920','OTH_1910_1920','SP_1920_1930','OBS_1920_1930',
              'OTH_1920_1930','SP_1930_1940','OBS_1930_1940','OTH_1930_1940',
              'SP_1940_1950','OBS_1940_1950','OTH_1940_1950','SP_1950_1960',
              'OBS_1950_1960','OTH_1950_1960','SP_1960_1970','OBS_1960_1970',
              'OTH_1960_1970','SP_1970_1980','OBS_1970_1980','OTH_1970_1980',
              'SP_1980_1990','OBS_1980_1990','OTH_1980_1990','SP_1990_2000',
              'OBS_1990_2000','OTH_1990_2000','SP_2000_2010','OBS_2000_2010',
              'OTH_2000_2010','SP_2010_2020','OBS_2010_2020','OTH_2010_2020',
              'SP_NO_YEAR','OBS_NO_YEAR','OTH_NO_YEAR','LIVING',
              'FOSSIL','SP_PRE_1900','OBS_PRE_1900','OTH_PRE_1900'];

var setTileUrlFunction = function setTileUrlFunction(options) {
  var options = options;
  return function setTileUrlFunction(tileCoord, pixelRatio, projection) {
    if(tileCoord == null) {
      return "";
    }
    var layerParams = options.layers.map(function(el) {
      return 'layer=' + el;
    })
    var layerCountries = options.countries.map(function(el) {
      return 'key=' + el;
    })
    return 'http://api.gbif.org/v1/map/density/tile?' +
       'x=' + tileCoord[1] + '&' +
       'y=' + tileCoord[2] + '&' +
       'z=' + tileCoord[0] + '&' +
       'type=COUNTRY' + '&' +
       layerCountries.join('&') + '&' +
       layerParams.join('&') + '&' +
       'palette=yellows_reds';
  }
}

var layer = new ol.layer.Tile({
  name: 'TMS',
  source: new ol.source.XYZ({
    tileUrlFunction: setTileUrlFunction({layers: params, countries: ['ML']})
  })
})

With this, you can later in the console do something like layer.getSource().setTileUrlFunction(setTileUrlFunction({layers: ['OTH_1990_2000', 'OTH_2000_2010'], countries: ['ML']})) to change your tiles.

Related Question