helgasoft / leaflet.dexie

A Leaflet plugin for local persistent storage using library Dexie.js, demo:
https://helgasoft.github.io/leaflet.dexie/index.html
GNU General Public License v2.0
8 stars 3 forks source link

wms? #11

Open barbalex opened 2 years ago

barbalex commented 2 years ago

Does this work with wms? What would have to be changed?

Not sure if I a up to the challenge: But I may tackle this if you point me out the necessary changes.

barbalex commented 2 years ago

After looking deeper into the problem: I think that solving this for wms is at least harder, if not impossible.

The reason: WMS requests a single image for exactly the bbox representing the map view. So every time the map is panned/zoomed a completely new image is requested, which is taylored for this exact zoom level / view extent.

As the number of possible zoom levels and map view extents is huge, it will not be possible to pre-cache the right ones.

While in a tiled map every map tile is pre-cached only once, in WMS the same extent (= tile) would have to be pre-cached for every zoom-level and view extent that contains this tile. So basically the needed storage capacity would quickly soar to unreasonable heights.

It might be possible to pre-cache wms images and later overlay them as an ImageOverlay though. Maybe a 'do-it-yourself' tiled map could be built this way. Not sure if that is a good idea though.

Or even wilder: request wms images for all 256*256 tiles contained in the viewed map and save them as a regular tile layer?

Does any of this make sense?

helgasoft commented 2 years ago

Very good question! WMS is not supported yet, but worth the shot. TileLayer and TileLayer.WMS are both raster, only options are different. Maybe start by duplicating TileLayerOffline.js as TileLayerWMSoffline.js and replace code with:

var TileLayerWMSoffline = L.TileLayer.WMS.extend( {
  options: {
    layers: null,   // required - Comma-separated list of WMS layers to show.
    styles: null,   // Comma-separated list of WMS styles
    format: 'image/jpeg',   // WMS image format (use 'image/png' for layers with transparency)
    transparent: false, // If true, the WMS service will return images with transparency
    version: '1.1.1',   // Version of the WMS service to use
    crs: null,      // Coordinate Reference System to use for the WMS requests, defaults to map CRS.
    uppercase: false,   // If true, WMS request parameter keys will be uppercase
    offUrl: null    // link to PNG file for missing tile in offline mode
  },
  dtable: null,     // database table to get tiles from
  offtest: false,   // for simulating offline response
...
 L.tileLayer.WMSoffline = function (url, options) { return new TileLayerWMSoffline(url, options); };

Then, the call from index.html will be

let baseLayer = L.tileLayer.WMSoffline ('http://ows.mundialis.de/services/service?', {
    layers: 'TOPO-WMS'
});

As far as I know: Regular tiles are standardized. Leaflet will always request tile https://a.tile.openstreetmap.org/14/8366/5751.png for zoom 14 and around certain lat/lng. Our code saves the same tile in IndexedDB with URL-key. When Leaflet later asks for it offline, our code finds it in local storage by URL. WMS tiles are similarly generated on-the-fly by requesting a BBOX. From experiments, it looks like most WMS servers return predefined tiles. They could be stored by URL-key and show offline just like regular tiles. Example - https://ows.mundialis.de/services/service?&service=WMS...&bbox=-13149614.849955443 Other WMS servers however return coded and/or temporary tiles like https://apps.sentinel-hub.com/2a9142fb-03fa-46be-9979-3fd8bfe52679/. They do not have a permanent URL and saving them offline does not make sense.

barbalex commented 2 years ago

Thanks a lot for your valued and helpful input.

I am building an app that should enable offline data collecting, including mapping. My programming background is web dev, not mapping. I transitioned to web dev more than 10 years ago from environmental science where I spent plenty of time mapping nature myself though. So enabling this is interesting to me.

The app has some other challenges too. So I will see how quickly and successfully I can tackle this challenge.