Leaflet: Using HTTP POST for WMS service??

Created on 6 Jun 2017  路  4Comments  路  Source: Leaflet/Leaflet

Hello!

We've been using leaflet version 0.7.7, and the WMS service we use doesn't use the traditional HTTP Get method but rather uses POST. We had this shim to help with this

  var TileLayerSoils = L.TileLayer.WMS.extend({
    options: {
      sld_body: ''
    },
    createTile: function _loadTile(tile, tilePoint) {
      tile._layer = this;
      tile.onload = this._tileOnLoad;
      tile.onerror = this._tileOnError;
      this._adjustTilePoint(tilePoint);
      const xhr = new XMLHttpRequest();
      const splitUrl = this.getTileUrl(tilePoint).split('?');
      xhr.open('POST', splitUrl[0]);
      xhr.responseType = 'blob';
      xhr.onload = function xhrLoadCallback() { tile.src = window.URL.createObjectURL(this.response); };
      xhr.send(splitUrl[1]);
      this.fire('tileloadstart', {
        tile: tile,
        url: tile.src
      });
    },
    getTileUrl: function getTileUrl(tilePoint) {
      const map = this._map;
      const tileSize = this.options.tileSize;
      const nwPoint = tilePoint.multiplyBy(tileSize);
      const sePoint = nwPoint.add([tileSize, tileSize]);
      const nw = this._crs.project(map.unproject(nwPoint, tilePoint.z));
      const se = this._crs.project(map.unproject(sePoint, tilePoint.z));
      const bbox = this._wmsVersion >= 1.3 && this._crs === L.CRS.EPSG4326 ?
        [se.y, nw.x, nw.y, se.x].join(',') :
        [nw.x, se.y, se.x, nw.y].join(',');
      let url = L.Util.template(this._url, {s: this._getSubdomain(tilePoint)});
      const params = [];
      for (const key in this.wmsParams) {
        if (Object.prototype.hasOwnProperty.call(this.wmsParams, key)) {
          params.push(key.toUpperCase() + '=' + this.wmsParams[key]);
        }
      }
      url = url + ((!url || url.indexOf('?') === -1) ? '?' : '&') + params.join('&');
      return url + '&BBOX=' + bbox + '&SLD_BODY=' + this.options.sld_body;
    },
  });

Now after updating to the latest the loadtile method has been deprecated and I can't seem to figure out what method to attach this shim to. After I successfully add a way to use HTTP Post shim for a WMS service ill submit a pr as I think it can be useful.

Most helpful comment

https://anitagraser.com/2010/06/09/getmap-from-geoserver-using-http-post/

Usually, I use CQL filter statements to dynamically filter features in a Geoserver WMS. These CQL filters can be added easily to the URL and Geoserver responds accordingly. There鈥檚 just one problem: There is a size limit for URLs and (very!) long filter statements won鈥檛 fit in. This makes it necessary to switch from HTTP GET to POST

All 4 comments

Had a stroke of genius/luck right after posting this. For those who are wondering you must manipulate the createTile function in order to achieve the desired results.

Hi!

As I understand it, this is more a question of how to use Leaflet than an actual issue?

If this is something that is useful to more people (I don't know how common WMS which requires POST instead of GET is), I suggest publishing a plugin for this. It is not likely to be included in Leaflet itself, since it's after all covering a niche use case with a non-standard service.

I'll close this for now, but feel free to add more information if you think this should be reopened.

@kunalbhatt Could you please suggest a plugin to implement POST, the idea is to pass the tilelayer options to the body of the request, instead of using the leaflet default tileLayer method that uses query params

https://anitagraser.com/2010/06/09/getmap-from-geoserver-using-http-post/

Usually, I use CQL filter statements to dynamically filter features in a Geoserver WMS. These CQL filters can be added easily to the URL and Geoserver responds accordingly. There鈥檚 just one problem: There is a size limit for URLs and (very!) long filter statements won鈥檛 fit in. This makes it necessary to switch from HTTP GET to POST

Was this page helpful?
0 / 5 - 0 ratings