ol-ext
Version:
A set of cool extensions for OpenLayers (ol) in node modules structure
161 lines (151 loc) • 5.61 kB
JavaScript
/* 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