From 69fcc81fa695782bda5d75ff05b36e9b59d41f95 Mon Sep 17 00:00:00 2001 From: Francesco Boccacci Date: Tue, 7 Feb 2023 09:28:53 +0100 Subject: [PATCH] Use projection definition provide by server (including projection extent) (#280) * Use crs object provide by server. In case of AddLayer register new Projection if not register on Application * Create a API_BASE_URLS constant to constant.js and add CRS url * Add case of server error request not register crs * add since tags * remove wrong version * add since version * Changes not related to the pull request. Refactoring it other pull request is better * Add missing import module Projections * Export API_BASE_URLS * Changes not related to the pull request. Refactoring it other pull request is better * Change as suggest https://github.com/g3w-suite/g3w-client/pull/280#discussion_r1068079455 * Change as suggest https://github.com/g3w-suite/g3w-client/pull/280#discussion_r1094156489 * Change as https://github.com/g3w-suite/g3w-client/pull/280#discussion_r1094163225 * Add comments as suggest https://github.com/g3w-suite/g3w-client/pull/280#discussion_r1068082252 --------- Co-authored-by: Raruto --- src/app/constant.js | 10 +- src/app/g3w-ol/map/maphelpers.js | 8 +- src/app/g3w-ol/projection/projection.js | 18 +--- src/app/g3w-ol/projection/projections.js | 126 +++++++---------------- src/app/gui/map/mapservice.js | 10 +- src/components/MapAddLayer.vue | 23 +++-- 6 files changed, 78 insertions(+), 117 deletions(-) diff --git a/src/app/constant.js b/src/app/constant.js index 572d66c2e..8a5a88d7e 100644 --- a/src/app/constant.js +++ b/src/app/constant.js @@ -349,6 +349,13 @@ export const ZINDEXES = { } }; +/** + * @since v3.8 + */ +export const API_BASE_URLS = { + CRS: '/crs/' //Example /crs/ +}; + export default { APP_VERSION, DEFAULT_EDITING_CAPABILITIES, @@ -372,5 +379,6 @@ export default { TOC_LAYERS_INIT_STATUS, TOC_THEMES_INIT_STATUS, VIEWPORT, - ZINDEXES + ZINDEXES, + API_BASE_URLS }; \ No newline at end of file diff --git a/src/app/g3w-ol/map/maphelpers.js b/src/app/g3w-ol/map/maphelpers.js index 863d6dbd2..576f12a83 100755 --- a/src/app/g3w-ol/map/maphelpers.js +++ b/src/app/g3w-ol/map/maphelpers.js @@ -1,5 +1,4 @@ -const BaseLayers = require('g3w-ol/layers/bases'); -const Projections = require('g3w-ol/projection/projections'); +const BaseLayers = require('../layers/bases'); const MapHelpers = { createViewer(opts={}){ @@ -26,10 +25,7 @@ const _Viewer = function(opts={}) { view, keyboardEventTarget: document }; - if (opts.id) { - options.target = opts.id; - } - Projections.setApplicationProjections(); + options.target = opts.id; const map = new ol.Map(options); this.map = map; }; diff --git a/src/app/g3w-ol/projection/projection.js b/src/app/g3w-ol/projection/projection.js index 012cffcc7..325467193 100644 --- a/src/app/g3w-ol/projection/projection.js +++ b/src/app/g3w-ol/projection/projection.js @@ -1,25 +1,13 @@ -const GENERIC_GRID_EXTENT = [0,0,8388608,8388608]; -const GRID_EXTENT_3857 = ol.proj.get('EPSG:3857').getExtent(); -const GENERIC_GRID_EXTENT_DEGREE = [-180,-90, 180, 90]; -/** - * BACK COMPATIBILITY < v3.5 - */ -const CUSTOM_PROJECTIONS_EXTENT = { - 'EPSG:3876': [18835101.07,4367049.45,22702879.51,9383109.87], - 'EPSG:32733': GRID_EXTENT_3857, - 'EPSG:25833': [-2465144.8,3638055.41,2885759.28, 9493779.8] -}; - const Projection = function(options={}) { if (!options.crs) return null; - const {epsg, proj4:proj4def, geographic=false, axisinverted=false, extent} = options.crs; // new structure of information crs from server + // structure of information crs from server set on each layer and base layer + const {epsg, proj4:proj4def, geographic=false, axisinverted=false, extent} = options.crs; proj4def && proj4.defs(epsg, proj4def); this._axisOrientation = axisinverted ? 'neu' : 'enu'; const degrees = geographic; ol.proj.Projection.call(this, { code: epsg, - //FOR NOW FORCE TO GET EXTENT - extent: false ? extent : degrees ? GENERIC_GRID_EXTENT_DEGREE: CUSTOM_PROJECTIONS_EXTENT[epsg] || GENERIC_GRID_EXTENT, + extent, axisOrientation: this._axisOrientation, units: degrees ? 'degrees' : 'm' }); diff --git a/src/app/g3w-ol/projection/projections.js b/src/app/g3w-ol/projection/projections.js index 258ec253b..3c79f9004 100644 --- a/src/app/g3w-ol/projection/projections.js +++ b/src/app/g3w-ol/projection/projections.js @@ -1,104 +1,54 @@ -const Projection = require('g3w-ol/projection/projection'); -const ADDEDPROJECTIONS = ['EPSG:4326', 'EPSG:3857']; +import {API_BASE_URLS} from 'constant'; +const Projection = require('./projection'); +const {XHR} = require('core/utils/utils'); +const {normalizeEpsg} = require('core/utils/geo'); const Projections = { + + /** + * @since v3.8 + */ + isRegistered(epsg) { + return ol.proj.get(epsg); + }, + get(crs={}) { - const cachedProjection = ADDEDPROJECTIONS.indexOf(crs.epsg) !== -1 ? ol.proj.get(crs.epsg) : null; + const cachedProjection = this.isRegistered(crs.epsg); if (cachedProjection) return cachedProjection; const projection = new Projection({ crs }); ol.proj.addProjection(projection); - ADDEDPROJECTIONS.push(crs.epsg); + ol.proj.proj4.register(proj4); return projection; }, + /** - * extent get from https://epsg.io/ + * Check and register epsg + * + * @param epsg : "EPSG:" Ex. "EPSG:4326" + * @returns {Promise} + * @since v3.8 */ - setApplicationProjections() { - this.get({ - epsg: "EPSG:3003", - proj4: "+proj=tmerc +lat_0=0 +lon_0=9 +k=0.9996 +x_0=1500000 +y_0=0 +ellps=intl +towgs84=-104.1,-49.1,-9.9,0.971,-2.917,0.714,-11.68 +units=m +no_defs", - axisinverted: false, - geographic: false, - extent: [1290650.93, 4190305.78, 2343702.24, 5261004.57] - }); - - this.get({ - epsg: "EPSG:3004", - proj4: "+proj=tmerc +lat_0=0 +lon_0=15 +k=0.9996 +x_0=2520000 +y_0=0 +ellps=intl +towgs84=-104.1,-49.1,-9.9,0.971,-2.917,0.714,-11.68 +units=m +no_defs", - axisinverted: false, - geographic: false, - extent: [1782205.39, 4190307.02, 2834974.5, 5250474.42] - }); - - this.get({ - epsg: "EPSG:3045", - proj4:"+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs", - axisinverted: true, - geographic: false, - extent: [-2465144.8, 3638055.41, 2885759.28, 9493779.8] - }); - - this.get({ - epsg:"EPSG:6708", - proj4:"+proj=utm +zone=33 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs", - axisinverted: true, - geographic: false, - extent: [-331278.39, 3846440.97, 865258.04, 5256332.65] - }); - - this.get({ - epsg:"EPSG:32632", - proj4:"+proj=utm +zone=32 +datum=WGS84 +units=m +no_defs", - axisinverted: false, - geographic: false, - extent: [166021.44, 0.0, 833978.56, 9329005.18] - }); - - this.get({ - epsg:"EPSG:32633", - proj4:"+proj=utm +zone=33 +ellps=WGS84 +datum=WGS84 +units=m +no_defs", - axisinverted: false, - geographic: false, - extent: [166021.44, 0.0, 833978.56, 9329005.18] - }); - - this.get({ - epsg:"EPSG:32634", - proj4:"+proj=utm +zone=34 +datum=WGS84 +units=m +no_defs", - axisinverted: false, - geographic: false, - extent: [166021.44, 0.0, 833978.56, 9329005.18] - }); - - this.get({ - epsg:"EPSG:25833", - proj4:"+proj=utm +zone=33 +ellps=GRS80 +units=m +no_defs", - axisinverted: false, - geographic: false, - extent: [-2465144.8,3638055.41,2885759.28, 9493779.8] - }); - - this.get({ - epsg:"EPSG:23032", - proj4:"+proj=utm +zone=32 +ellps=intl +units=m +no_defs", - axisinverted: false, - geographic: false, - extent: [-1206117.77, 3859932.9, 2582411.08, 8051813.3] - }); - - this.get({ - epsg:"EPSG:23033", - proj4:"+proj=utm +zone=33 +ellps=intl +units=m +no_defs", - axisinverted: false, - geographic: false, - extent: [-1767202.11, 3859945.89, 2023400.16, 8079073.01] - }); - //REGISTER AT THE END THE CUSTOM PROJECTIONS - ol.proj.proj4.register(proj4) + registerProjection(epsg) { + return new Promise((resolve, reject) => { + let projection = this.isRegistered(epsg); + // check if already register + if (projection) resolve(projection); + else { + XHR.get({url: `${API_BASE_URLS.CRS}${epsg.split(':')[1]}`}) + .then(({result, data}) => { + if (result) { + data.epsg = normalizeEpsg(data.epsg); + projection = this.get(data); + ol.proj.proj4.register(proj4); + resolve(projection); + } + }) + .catch(err => reject(err)) + } + }) } }; - module.exports = Projections; diff --git a/src/app/gui/map/mapservice.js b/src/app/gui/map/mapservice.js index da92866e6..b91b552ba 100644 --- a/src/app/gui/map/mapservice.js +++ b/src/app/gui/map/mapservice.js @@ -89,9 +89,13 @@ function MapService(options={}) { this._mapLayers = []; this._externalMapLayers = []; this._externalLayers = []; - // array where store interactions added from plugin or extenal from application + // array where store interactions added from plugin or external from application this._externalInteractions = []; this.mapBaseLayers = {}; + /** + * Default layers are OL layers that are add to map by default. + * Are used to show selection Features and/or highlight Layer feature + */ this.defaultsLayers = { _style: { highlightLayer: { @@ -1835,6 +1839,10 @@ proto._setUpDefaultLayers = function(){ this.getMap().addLayer(this.defaultsLayers.selectionLayer); }; +/** + * Method to set Default layers (selectionLayer, and highlightLayer) + * always on top of layers stack of map to be always visible + */ proto.moveDefaultLayersOnTop = function(zindex){ this.setZIndexLayer({ layer: this.defaultsLayers.highlightLayer, diff --git a/src/components/MapAddLayer.vue b/src/components/MapAddLayer.vue index 3d80c5653..4e8495289 100644 --- a/src/components/MapAddLayer.vue +++ b/src/components/MapAddLayer.vue @@ -81,6 +81,8 @@ import { Chrome as ChromeComponent } from 'vue-color'; import { EPSG } from 'app/constant'; +const Projections = require('g3w-ol/projection/projections'); + const { createVectorLayerFromFile, createStyleFunctionToVectorLayer } = require('core/utils/geo'); const SUPPORTED_FORMAT = ['zip','geojson', 'GEOJSON', 'kml', 'kmz', 'KMZ', 'KML', 'json', 'gpx', 'gml', 'csv']; @@ -246,11 +248,20 @@ export default { } catch(err){this.setError('add_external_layer');} }, async addLayer() { - if (this.vectorLayer || this.csv.valid){ - this.loading = true; - //Recreate always the vector layer because we can set the right epsg after first load the file - // if we change the epsg of the layer after loaded + if (this.vectorLayer || this.csv.valid) { + const {crs} = this.layer; try { + /** + * waiting to register a epsg choose if all go right + */ + try { + await Projections.registerProjection(crs); + } catch(error) { + this.setError(error); + return; + } + + this.loading = true; this.vectorLayer = await createVectorLayerFromFile(this.layer); this.vectorLayer.setStyle(createStyleFunctionToVectorLayer({ color: this.layer.color, @@ -260,10 +271,10 @@ export default { crs: this.layer.crs, type: this.layer.type, position: this.position - - }); + }); $(this.$refs.modal_addlayer).modal('hide'); this.clearLayer(); + } catch(err){ this.setError('add_external_layer'); }