/* Copyright (c) 2019 Jean-Marc VIGLINO, released under the CeCILL-B license (French BSD license) (http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt). */ import ol_source_Vector from 'ol/source/Vector.js' import {tile as ol_loadingstrategy_tile} from 'ol/loadingstrategy.js' import {createXYZ as ol_tilegrid_createXYZ} from 'ol/tilegrid.js' import ol_format_GeoJSON from 'ol/format/GeoJSON.js' import ol_ext_Ajax from '../util/Ajax.js' /** A vector source to load WFS at a tile zoom level * @constructor * @fires tileloadstart * @fires tileloadend * @fires tileloaderror * @fires overload * @extends {ol.source.Vector} * @param {Object} options * @param {string} options.typeName WFS type name parameter * @param {string} [options.version=1.1.0] WFS version to use. Can be either 1.0.0, 1.1.0 or 2.0.0. * @param {string} [options.outputFormat=application/json] WFS outputFormat parameter * @param {number} [options.tileZoom=14] zoom to load the tiles * @param {number} [options.maxFeatures] maximum features returned in the WFS * @param {number} [options.featureLimit=Infinity] maximum features in the source before refresh, default Infinity * @param {boolean} [options.pagination] experimental enable pagination, default no pagination */ var ol_source_TileWFS = class olsourceTileWFS extends ol_source_Vector { constructor(options) { options = options || {} if (!options.featureLimit) options.featureLimit = Infinity // Tile loading strategy var zoom = options.tileZoom || 14 var sourceOpt = { strategy: ol_loadingstrategy_tile(ol_tilegrid_createXYZ({ minZoom: zoom, maxZoom: zoom, tileSize: 512 })) } // Loading params var format = new ol_format_GeoJSON() var url = new URL(options.url) // Get non standard options (apikey) var search = url.search.replace(/^\?/,'').split('&') url = url.origin + url.pathname var std = /^service$|^request$|^version$|^typename$|^outputFormat$|^maxFeatures$|^bbox$|^srsname$/i; search.forEach(function(s) { var name = s.split('=')[0] if (!std.test(name)) { url += (/\?/.test(url) ? '&' : '?') + s; } }) // Query url url = url + (/\?/.test(url) ? '&' : '?') + 'service=WFS' + '&request=GetFeature' + '&version=' + (options.version || '1.1.0') + '&typename=' + (options.typeName || '') + '&outputFormat=' + (options.outputFormat || 'application/json'); if (options.maxFeatures) { url += '&maxFeatures=' + options.maxFeatures + '&count=' + options.maxFeatures } var loader = { loading: 0, loaded: 0 } // Loading fn sourceOpt.loader = function (extent, resolution, projection) { if (loader.loading === loader.loaded) { loader.loading = loader.loaded = 0 if (this.getFeatures().length > options.maxFeatures) { this.clear() this.refresh() } } loader.loading++ this.dispatchEvent({ type: 'tileloadstart', loading: loader.loading, loaded: loader.loaded }) this._loadTile(this._url, extent, projection, format, loader) } super(sourceOpt) this._url = url this.set('pagination', options.pagination) } /** * */ _loadTile(url, extent, projection, format, loader) { var req = url + '&srsname=' + projection.getCode() + '&bbox=' + extent.join(',') + ',' + projection.getCode() if (this.get('pagination') && !/&startIndex/.test(url)) { req += '&startIndex=0' } ol_ext_Ajax.get({ url: req, success: function (response) { loader.loaded++ if (response.error) { this.dispatchEvent({ type: 'tileloaderror', error: response, loading: loader.loading, loaded: loader.loaded }) } else { // Load features var features = format.readFeatures(response, { featureProjection: projection }) if (features.length > 0) { this.addFeatures(features) } // Next page? let pos = response.numberReturned || 0 if (/&startIndex/.test(url)) { pos += parseInt(url.replace(/.*&startIndex=(\d*).*/, '$1')) url = url.replace(/&startIndex=(\d*)/, '') } // Still something to load ? if (pos < response.totalFeatures) { if (!this.get('pagination')) { this.dispatchEvent({ type: 'overload', total: response.totalFeatures, returned: response.numberReturned }) this.dispatchEvent({ type: 'tileloadend', loading: loader.loading, loaded: loader.loaded }) } else { url += '&startIndex=' + pos loader.loaded-- this._loadTile(url, extent, projection, format, loader) } } else { this.dispatchEvent({ type: 'tileloadend', loading: loader.loading, loaded: loader.loaded }) } } }.bind(this), error: function (e) { loader.loaded++ this.dispatchEvent({ type: 'tileloaderror', error: e, loading: loader.loading, loaded: loader.loaded }) }.bind(this) }) } } export default ol_source_TileWFS