/* Copyright (c) 2018 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_geom_Polygon from 'ol/geom/Polygon.js' import ol_Feature from 'ol/Feature.js' import ol_source_Vector from 'ol/source/Vector.js' import {ol_coordinate_toDFCI} from '../geom/DFCI.js' import {transformExtent as ol_proj_transformExtent} from 'ol/proj.js' import {register as ol_proj_proj4_register} from 'ol/proj/proj4.js'; import proj4 from 'proj4'; /** DFCI source: a source to display the French DFCI grid on a map * @see http://ccffpeynier.free.fr/Files/dfci.pdf * @constructor ol_source_DFCI * @extends {ol/source/Vector} * @param {any} options Vector source options * @param {Array} resolutions a list of resolution to change the drawing level, default [1000,100,20] */ var ol_source_DFCI = class olsourceDFCI extends ol_source_Vector { constructor(options) { options = options || {} options.loader = function(extent, resolution, projection) { return this._calcGrid(extent, resolution, projection) } options.strategy = function (extent, resolution) { if (this.resolution && this.resolution != resolution) { this.clear() this.refresh() } return [extent] } super(options) this._bbox = [[0, 1600000], [11 * 100000, 1600000 + 10 * 100000]] this.set('resolutions', options.resolutions || [1000, 100, 20]) // Add Lambert IIe proj if (!proj4.defs["EPSG:27572"]) proj4.defs("EPSG:27572", "+proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 +x_0=600000 +y_0=2200000 +a=6378249.2 +b=6356515 +towgs84=-168,-60,320,0,0,0,0 +pm=paris +units=m +no_defs") ol_proj_proj4_register(proj4) } /** Cacluate grid according extent/resolution */ _calcGrid(extent, resolution, projection) { // Show step 0 var f, ext, res = this.get('resolutions') if (resolution > (res[0] || 1000)) { if (this.resolution != resolution) { if (!this._features0) { ext = [this._bbox[0][0], this._bbox[0][1], this._bbox[1][0], this._bbox[1][1]] this._features0 = this._getFeatures(0, ext, projection) } this.addFeatures(this._features0) } } else if (resolution > (res[1] || 100)) { this.clear() ext = ol_proj_transformExtent(extent, projection, 'EPSG:27572') f = this._getFeatures(1, ext, projection) this.addFeatures(f) } else if (resolution > (res[2] || 0)) { this.clear() ext = ol_proj_transformExtent(extent, projection, 'EPSG:27572') f = this._getFeatures(2, ext, projection) this.addFeatures(f) } else { this.clear() ext = ol_proj_transformExtent(extent, projection, 'EPSG:27572') f = this._getFeatures(3, ext, projection) this.addFeatures(f) } // reset load this.resolution = resolution } /** * Get middle point * @private */ _midPt(p1, p2) { return [(p1[0] + p2[0]) / 2, (p1[1] + p2[1]) / 2] } /** * Get feature with geom * @private */ _trFeature(geom, id, level, projection) { var g = new ol_geom_Polygon([geom]) var f = new ol_Feature(g.transform('EPSG:27572', projection)) f.set('id', id) f.set('level', level) return f } /** Get features * */ _getFeatures(level, extent, projection) { var features = [] var i var step = 100000 if (level > 0) step /= 5 if (level > 1) step /= 10 var p0 = [ Math.max(this._bbox[0][0], Math.floor(extent[0] / step) * step), Math.max(this._bbox[0][1], Math.floor(extent[1] / step) * step) ] var p1 = [ Math.min(this._bbox[1][0] + 99999, Math.floor(extent[2] / step) * step), Math.min(this._bbox[1][1] + 99999, Math.floor(extent[3] / step) * step) ] for (var x = p0[0]; x <= p1[0]; x += step) { for (var y = p0[1]; y <= p1[1]; y += step) { var p, geom = [[x, y], [x + step, y], [x + step, y + step], [x, y + step], [x, y]] if (level > 2) { var m = this._midPt(geom[0], geom[2]) // .5 var g = [] for (i = 0; i < geom.length; i++) { g.push(this._midPt(geom[i], m)) } features.push(this._trFeature(g, ol_coordinate_toDFCI([x, y], 2) + '.5', level, projection)) // .1 > .4 for (i = 0; i < 4; i++) { g = [] g.push(geom[i]) g.push(this._midPt(geom[i], geom[(i + 1) % 4])) g.push(this._midPt(m, g[1])) g.push(this._midPt(m, geom[i])) p = this._midPt(geom[i], geom[(i + 3) % 4]) g.push(this._midPt(m, p)) g.push(p) g.push(geom[i]) features.push(this._trFeature(g, ol_coordinate_toDFCI([x, y], 2) + '.' + (4 - i), level, projection)) } } else { features.push(this._trFeature(geom, ol_coordinate_toDFCI([x, y], level), level, projection)) } } } return features } } export default ol_source_DFCI