@eeacms/volto-arcgis-block 0.1.74 → 0.1.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/Jenkinsfile +4 -3
- package/package.json +1 -1
- package/src/components/MapViewer/BasemapWidget.jsx +34 -2
- package/src/components/MapViewer/InfoWidget.jsx +7 -4
- package/src/components/MapViewer/MenuWidget.jsx +412 -54
- package/src/components/MapViewer/css/ArcgisMap.css +10 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,45 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
|
4
4
|
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
6
|
|
|
7
|
+
### [0.1.76](https://github.com/eea/volto-arcgis-block/compare/0.1.75...0.1.76) - 25 November 2022
|
|
8
|
+
|
|
9
|
+
#### :rocket: New Features
|
|
10
|
+
|
|
11
|
+
- feat: added legends for WMTS and TMS layers [joewdavies - [`cf24e61`](https://github.com/eea/volto-arcgis-block/commit/cf24e6188430724172ced72d0bda116e08845123)]
|
|
12
|
+
- feat: added legends for WMTS and TMS layers [joewdavies - [`2429361`](https://github.com/eea/volto-arcgis-block/commit/2429361bb9cb6d871575dccbb3e1e38a3c13257f)]
|
|
13
|
+
|
|
14
|
+
#### :hammer_and_wrench: Others
|
|
15
|
+
|
|
16
|
+
- specify volto-ci version in jenkinsfile cypress [joewdavies - [`2e3a641`](https://github.com/eea/volto-arcgis-block/commit/2e3a64155c24e94227254ab3ed2a88328f15f8af)]
|
|
17
|
+
- ESlint fix [joewdavies - [`3f086d0`](https://github.com/eea/volto-arcgis-block/commit/3f086d052d26a3dbf186a00403be5d5a56fe44cc)]
|
|
18
|
+
- specify volto-ci version in jenkinsfile [joewdavies - [`a4756a7`](https://github.com/eea/volto-arcgis-block/commit/a4756a72218295a5d3a4dd645823b1c6b5631032)]
|
|
19
|
+
- specify volto-ci version in jenkinsfile [joewdavies - [`667f02c`](https://github.com/eea/volto-arcgis-block/commit/667f02c640a858d33cd092e26b79ee80900f63a0)]
|
|
20
|
+
- specify volto-ci version in jenkinsfile [joewdavies - [`c8434f2`](https://github.com/eea/volto-arcgis-block/commit/c8434f2157ec72506b746d5d214d87ff3a72c3f4)]
|
|
21
|
+
- specify volto-ci version in jenkinsfile [joewdavies - [`482e770`](https://github.com/eea/volto-arcgis-block/commit/482e77029a1569f149c4674362897e972a961f5c)]
|
|
22
|
+
- specify volto-ci version in jenkinsfile [joewdavies - [`a5d7ad7`](https://github.com/eea/volto-arcgis-block/commit/a5d7ad7d7579c295659105623d1c160ad593d6ee)]
|
|
23
|
+
### [0.1.75](https://github.com/eea/volto-arcgis-block/compare/0.1.74...0.1.75) - 22 November 2022
|
|
24
|
+
|
|
25
|
+
#### :rocket: New Features
|
|
26
|
+
|
|
27
|
+
- feat: show zoom in message for snow and ice product when zoom level is below 7 - CLMS-1528 [joewdavies - [`7ac9d04`](https://github.com/eea/volto-arcgis-block/commit/7ac9d04ab96b44b22ea8520e7c8677e286df525e)]
|
|
28
|
+
- feat: show zoom in message for snow and ice product when zoom level is below 7 - CLMS-1528 [joewdavies - [`e803695`](https://github.com/eea/volto-arcgis-block/commit/e803695e46fba76a48186ebdf25c7a74f02e3a08)]
|
|
29
|
+
- feat: show zoom in message for snow and ice product when zoom level is below 7 - CLMS-1528 [joewdavies - [`1734f89`](https://github.com/eea/volto-arcgis-block/commit/1734f89ee8bc16dc1bc18d5d76b3131b044796c5)]
|
|
30
|
+
- feat: show zoom in message for snow and ice product when zoom level is below 7 - CLMS-1528 [joewdavies - [`5f12f70`](https://github.com/eea/volto-arcgis-block/commit/5f12f702061b34421302d6037a87e131c19f3b56)]
|
|
31
|
+
- feat: show zoom in message for snow and ice product when zoom level is below 7 - CLMS-1528 [joewdavies - [`d6e4dea`](https://github.com/eea/volto-arcgis-block/commit/d6e4dea9b5030217ca5faad8c33959e65b9d179b)]
|
|
32
|
+
- feat: load TMS layers JSON asynchronosly [joewdavies - [`a36ac9b`](https://github.com/eea/volto-arcgis-block/commit/a36ac9b99deaa1b5ed344fd869589ea0f053aabb)]
|
|
33
|
+
|
|
34
|
+
#### :hammer_and_wrench: Others
|
|
35
|
+
|
|
36
|
+
- prettier fix [joewdavies - [`3855674`](https://github.com/eea/volto-arcgis-block/commit/3855674ce363b58387dc818bf4a86ce50ff7ee38)]
|
|
37
|
+
- prettier fix [joewdavies - [`a900320`](https://github.com/eea/volto-arcgis-block/commit/a9003201ed25be8636c59ca5e075e98f15086b7d)]
|
|
38
|
+
- prettier fix [joewdavies - [`8b4f2d2`](https://github.com/eea/volto-arcgis-block/commit/8b4f2d24815d96c3be14a2455a6a2af844aa16ba)]
|
|
39
|
+
- prettier fix [joewdavies - [`d578f5a`](https://github.com/eea/volto-arcgis-block/commit/d578f5a6fbc54ed3cf24ae2fe9c439daa3b82961)]
|
|
40
|
+
- add default TMS layer if none specified [joewdavies - [`ffbdc0e`](https://github.com/eea/volto-arcgis-block/commit/ffbdc0e4d1e27d0fd886200a9bba29cc5763698c)]
|
|
41
|
+
- ESLint fix [joewdavies - [`a22c35f`](https://github.com/eea/volto-arcgis-block/commit/a22c35f4568c69b654dc414c61b80257d6932430)]
|
|
42
|
+
- attempt to get TMS layer to work with legend widget [joewdavies - [`4271bdd`](https://github.com/eea/volto-arcgis-block/commit/4271bddff97667c7f1a466b53df568b7cb3a3a14)]
|
|
43
|
+
- remove TMS layer correctly [joewdavies - [`9fb63f1`](https://github.com/eea/volto-arcgis-block/commit/9fb63f1983f82fe9452a9830eff640bc136f7137)]
|
|
44
|
+
- remove superfluous logs [joewdavies - [`9b0717b`](https://github.com/eea/volto-arcgis-block/commit/9b0717bed39113b448e10c9ad4e1fecf2d83bb09)]
|
|
45
|
+
- TMS json progress [joewdavies - [`f24c7c7`](https://github.com/eea/volto-arcgis-block/commit/f24c7c7da483221c15a705bf6972075e1f9bc7a6)]
|
|
7
46
|
### [0.1.74](https://github.com/eea/volto-arcgis-block/compare/0.1.73...0.1.74) - 27 October 2022
|
|
8
47
|
|
|
9
48
|
### [0.1.73](https://github.com/eea/volto-arcgis-block/compare/0.1.72...0.1.73) - 26 October 2022
|
package/Jenkinsfile
CHANGED
|
@@ -6,6 +6,7 @@ pipeline {
|
|
|
6
6
|
NAMESPACE = "@eeacms"
|
|
7
7
|
SONARQUBE_TAGS = "volto.eea.europa.eu,clms.land.copernicus.eu,water.europa.eu-freshwater,clmsdemo.devel6cph.eea.europa.eu"
|
|
8
8
|
DEPENDENCIES = ""
|
|
9
|
+
VOLTO = "15.16.0"
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
stages {
|
|
@@ -76,8 +77,8 @@ pipeline {
|
|
|
76
77
|
node(label: 'docker') {
|
|
77
78
|
script {
|
|
78
79
|
try {
|
|
79
|
-
sh '''docker pull plone/volto-addon-ci'''
|
|
80
|
-
sh '''docker run -i --name="$BUILD_TAG-volto" -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" plone/volto-addon-ci'''
|
|
80
|
+
sh '''docker pull plone/volto-addon-ci:15.x'''
|
|
81
|
+
sh '''docker run -i --name="$BUILD_TAG-volto" -e NAMESPACE="$NAMESPACE" -e VOLTO=$VOLTO -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" plone/volto-addon-ci:15.x'''
|
|
81
82
|
sh '''rm -rf xunit-reports'''
|
|
82
83
|
sh '''mkdir -p xunit-reports'''
|
|
83
84
|
sh '''docker cp $BUILD_TAG-volto:/opt/frontend/my-volto-project/coverage xunit-reports/'''
|
|
@@ -125,7 +126,7 @@ pipeline {
|
|
|
125
126
|
script {
|
|
126
127
|
try {
|
|
127
128
|
sh '''docker pull plone; docker run -d --rm --name="$BUILD_TAG-plone" -e SITE="Plone" -e PROFILES="profile-plone.restapi:blocks" plone fg'''
|
|
128
|
-
sh '''docker pull plone/volto-addon-ci; docker run -i --name="$BUILD_TAG-cypress" --link $BUILD_TAG-plone:plone -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e DEPENDENCIES="$DEPENDENCIES" -e NODE_ENV=test plone/volto-addon-ci cypress'''
|
|
129
|
+
sh '''docker pull plone/volto-addon-ci; docker run -i --name="$BUILD_TAG-cypress" --link $BUILD_TAG-plone:plone -e VOLTO=$VOLTO -e NAMESPACE="$NAMESPACE" -e GIT_NAME=$GIT_NAME -e GIT_BRANCH="$BRANCH_NAME" -e GIT_CHANGE_ID="$CHANGE_ID" -e DEPENDENCIES="$DEPENDENCIES" -e NODE_ENV=test plone/volto-addon-ci cypress'''
|
|
129
130
|
} finally {
|
|
130
131
|
try {
|
|
131
132
|
sh '''rm -rf cypress-reports cypress-results cypress-coverage'''
|
package/package.json
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import React, { createRef } from 'react';
|
|
2
2
|
import { loadModules } from 'esri-loader';
|
|
3
3
|
var BasemapGallery;
|
|
4
|
+
// var Basemap;
|
|
5
|
+
// var WebTileLayer;
|
|
6
|
+
// var LocalBasemapsSource;
|
|
4
7
|
|
|
5
8
|
class BasemapWidget extends React.Component {
|
|
6
9
|
/**
|
|
@@ -20,9 +23,17 @@ class BasemapWidget extends React.Component {
|
|
|
20
23
|
}
|
|
21
24
|
|
|
22
25
|
loader() {
|
|
23
|
-
return loadModules([
|
|
24
|
-
|
|
26
|
+
return loadModules([
|
|
27
|
+
'esri/widgets/BasemapGallery',
|
|
28
|
+
'esri/Basemap',
|
|
29
|
+
'esri/layers/WebTileLayer',
|
|
30
|
+
'esri/widgets/BasemapGallery/support/LocalBasemapsSource',
|
|
31
|
+
]).then(
|
|
32
|
+
([_BasemapGallery, _Basemap, _WebTileLayer, _LocalBasemapsSource]) => {
|
|
25
33
|
BasemapGallery = _BasemapGallery;
|
|
34
|
+
// Basemap = _Basemap;
|
|
35
|
+
// WebTileLayer = _WebTileLayer;
|
|
36
|
+
// LocalBasemapsSource = _LocalBasemapsSource;
|
|
26
37
|
},
|
|
27
38
|
);
|
|
28
39
|
}
|
|
@@ -95,9 +106,30 @@ class BasemapWidget extends React.Component {
|
|
|
95
106
|
async componentDidMount() {
|
|
96
107
|
await this.loader();
|
|
97
108
|
if (!this.container.current) return;
|
|
109
|
+
|
|
110
|
+
// custom basemaps
|
|
111
|
+
// let basemaps = [Basemap.fromId('topo-vector'), Basemap.fromId('hybrid')];
|
|
112
|
+
// basemaps.push(
|
|
113
|
+
// new Basemap({
|
|
114
|
+
// baseLayers: [
|
|
115
|
+
// new WebTileLayer({
|
|
116
|
+
// urlTemplate:
|
|
117
|
+
// 'https://gisco-services.ec.europa.eu/maps/wmts/OSMCartoV4CompositeEN/EPSG3857/{z}/{x}/{y}.png',
|
|
118
|
+
// }),
|
|
119
|
+
// ],
|
|
120
|
+
// title: 'OSM GISCO',
|
|
121
|
+
// id: 'osm-gisco',
|
|
122
|
+
// }),
|
|
123
|
+
// );
|
|
124
|
+
|
|
125
|
+
// let customSource = new LocalBasemapsSource({
|
|
126
|
+
// basemaps,
|
|
127
|
+
// });
|
|
128
|
+
|
|
98
129
|
this.basemapGallery = new BasemapGallery({
|
|
99
130
|
view: this.props.view,
|
|
100
131
|
container: this.container.current.querySelector('.basemap-panel'),
|
|
132
|
+
// source: customSource
|
|
101
133
|
});
|
|
102
134
|
this.props.view.ui.add(this.container.current, 'top-right');
|
|
103
135
|
}
|
|
@@ -297,11 +297,14 @@ class InfoWidget extends React.Component {
|
|
|
297
297
|
break;
|
|
298
298
|
case 'featureLayer':
|
|
299
299
|
if (data.results.length) {
|
|
300
|
-
var
|
|
300
|
+
var graphics = data.results.filter((result) => {
|
|
301
301
|
return result.graphic.layer === layers[index];
|
|
302
|
-
})
|
|
303
|
-
if (
|
|
304
|
-
|
|
302
|
+
});
|
|
303
|
+
if (graphics[0]) {
|
|
304
|
+
let graphic = graphics[0].graphic;
|
|
305
|
+
if (graphic) {
|
|
306
|
+
properties = graphic.attributes;
|
|
307
|
+
}
|
|
305
308
|
}
|
|
306
309
|
}
|
|
307
310
|
this.infoData[index] = {
|
|
@@ -9,7 +9,7 @@ import TimesliderWidget from './TimesliderWidget';
|
|
|
9
9
|
import { Toast } from '@plone/volto/components';
|
|
10
10
|
import { toast } from 'react-toastify';
|
|
11
11
|
import { UniversalLink } from '@plone/volto/components';
|
|
12
|
-
var WMSLayer, WMTSLayer, FeatureLayer;
|
|
12
|
+
var WMSLayer, WMTSLayer, FeatureLayer, BaseTileLayer, esriRequest;
|
|
13
13
|
|
|
14
14
|
const popupSettings = {
|
|
15
15
|
basic: true,
|
|
@@ -412,16 +412,28 @@ class MenuWidget extends React.Component {
|
|
|
412
412
|
this.container = createRef();
|
|
413
413
|
//Initially, we set the state of the component to
|
|
414
414
|
//not be showing the basemap panel
|
|
415
|
-
this.state = { showMapMenu: false };
|
|
415
|
+
this.state = { showMapMenu: false, tms_jsx: null };
|
|
416
416
|
// call the props of the layers list (mapviewer.jsx)
|
|
417
417
|
this.compCfg = this.props.conf;
|
|
418
418
|
this.map = this.props.map;
|
|
419
|
+
this.view = this.props.view;
|
|
419
420
|
this.menuClass =
|
|
420
421
|
'esri-icon-drag-horizontal esri-widget--button esri-widget esri-interactive';
|
|
421
422
|
this.loadFirst = true;
|
|
422
423
|
this.layers = {};
|
|
423
424
|
this.activeLayersJSON = {};
|
|
424
425
|
this.layerGroups = {};
|
|
426
|
+
|
|
427
|
+
// add zoomend listener to map to show/hide zoom in message
|
|
428
|
+
this.view.watch('stationary', (isStationary) => {
|
|
429
|
+
if (isStationary) {
|
|
430
|
+
let node = document.getElementById('snow-and-ice-zoom-message');
|
|
431
|
+
if (node) {
|
|
432
|
+
let zoom = this.view.get('zoom');
|
|
433
|
+
node.style.display = zoom > 6 ? 'none' : 'block';
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
});
|
|
425
437
|
}
|
|
426
438
|
|
|
427
439
|
loader() {
|
|
@@ -429,11 +441,53 @@ class MenuWidget extends React.Component {
|
|
|
429
441
|
'esri/layers/WMSLayer',
|
|
430
442
|
'esri/layers/WMTSLayer',
|
|
431
443
|
'esri/layers/FeatureLayer',
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
444
|
+
'esri/layers/BaseTileLayer',
|
|
445
|
+
'esri/request',
|
|
446
|
+
]).then(
|
|
447
|
+
([
|
|
448
|
+
_WMSLayer,
|
|
449
|
+
_WMTSLayer,
|
|
450
|
+
_FeatureLayer,
|
|
451
|
+
_BaseTileLayer,
|
|
452
|
+
_esriRequest,
|
|
453
|
+
]) => {
|
|
454
|
+
WMSLayer = _WMSLayer;
|
|
455
|
+
WMTSLayer = _WMTSLayer;
|
|
456
|
+
FeatureLayer = _FeatureLayer;
|
|
457
|
+
BaseTileLayer = _BaseTileLayer;
|
|
458
|
+
esriRequest = _esriRequest;
|
|
459
|
+
},
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// get custom TMS layer JSON
|
|
464
|
+
getTMSLayersJSON() {
|
|
465
|
+
let promises = []; // download JSON file calls
|
|
466
|
+
this.compCfg.forEach((component) => {
|
|
467
|
+
component.Products.forEach((product) => {
|
|
468
|
+
product.Datasets.forEach((dataset) => {
|
|
469
|
+
if (dataset.ViewService.endsWith('file')) {
|
|
470
|
+
let promise = fetch(dataset.ViewService, { mode: 'no-cors' })
|
|
471
|
+
.then((response) => {
|
|
472
|
+
if (!response.ok) {
|
|
473
|
+
throw new Error(`HTTP error, status = ${response.status}`);
|
|
474
|
+
}
|
|
475
|
+
return response.json();
|
|
476
|
+
})
|
|
477
|
+
.then((data) => {
|
|
478
|
+
// fill dataset.Layer manually
|
|
479
|
+
dataset.Layer = data.Layers;
|
|
480
|
+
})
|
|
481
|
+
.catch((error) => {
|
|
482
|
+
throw new Error(error);
|
|
483
|
+
});
|
|
484
|
+
promises.push(promise);
|
|
485
|
+
}
|
|
486
|
+
});
|
|
487
|
+
});
|
|
436
488
|
});
|
|
489
|
+
|
|
490
|
+
return Promise.all(promises);
|
|
437
491
|
}
|
|
438
492
|
|
|
439
493
|
/**
|
|
@@ -505,11 +559,12 @@ class MenuWidget extends React.Component {
|
|
|
505
559
|
}
|
|
506
560
|
|
|
507
561
|
/**
|
|
508
|
-
* This method is executed after the
|
|
562
|
+
* This method is executed after the render method is executed
|
|
509
563
|
*/
|
|
510
564
|
async componentDidMount() {
|
|
511
565
|
loadCss();
|
|
512
566
|
await this.loader();
|
|
567
|
+
await this.getTMSLayersJSON();
|
|
513
568
|
this.props.view.ui.add(this.container.current, 'top-left');
|
|
514
569
|
if (this.props.download) {
|
|
515
570
|
document.querySelector('.area-panel input:checked').click();
|
|
@@ -737,15 +792,23 @@ class MenuWidget extends React.Component {
|
|
|
737
792
|
dataset_def.push(idDataset);
|
|
738
793
|
}
|
|
739
794
|
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
795
|
+
// CLMS-1545
|
|
796
|
+
if (
|
|
797
|
+
product.Datasets[i].ViewService !==
|
|
798
|
+
'https://trial.discomap.eea.europa.eu/arcgis/services/CLMS/WorldCountries/MapServer/WmsServer' &&
|
|
799
|
+
product.Datasets[i].ViewService !==
|
|
800
|
+
'https://trial.discomap.eea.europa.eu/arcgis/services/CLMS/WorldCountries/MapServer/WmsServer?'
|
|
801
|
+
) {
|
|
802
|
+
datasets.push(
|
|
803
|
+
this.metodProcessDataset(
|
|
804
|
+
product.Datasets[i],
|
|
805
|
+
index,
|
|
806
|
+
inheritedIndexProduct,
|
|
807
|
+
checkProduct,
|
|
808
|
+
),
|
|
809
|
+
);
|
|
810
|
+
index++;
|
|
811
|
+
}
|
|
749
812
|
}
|
|
750
813
|
|
|
751
814
|
// Empty vector, add the first dataset
|
|
@@ -802,12 +865,38 @@ class MenuWidget extends React.Component {
|
|
|
802
865
|
<legend className="ccl-form-legend">
|
|
803
866
|
{description ? (
|
|
804
867
|
<Popup
|
|
805
|
-
trigger={
|
|
868
|
+
trigger={
|
|
869
|
+
product.ProductId ===
|
|
870
|
+
'8474c3b080fa42cc837f1d2338fcf096' ||
|
|
871
|
+
product.ProductTitle === 'Snow and Ice Parameters' ? (
|
|
872
|
+
<div class="zoom-in-message-container">
|
|
873
|
+
<span>{product.ProductTitle}</span>
|
|
874
|
+
<div
|
|
875
|
+
class="zoom-in-message"
|
|
876
|
+
id="snow-and-ice-zoom-message"
|
|
877
|
+
>
|
|
878
|
+
Zoom in to view on map
|
|
879
|
+
</div>
|
|
880
|
+
</div>
|
|
881
|
+
) : (
|
|
882
|
+
<span>{product.ProductTitle}</span>
|
|
883
|
+
)
|
|
884
|
+
}
|
|
806
885
|
content={description}
|
|
807
886
|
basic
|
|
808
887
|
className="custom"
|
|
809
888
|
style={{ transform: 'translateX(-4rem)' }}
|
|
810
889
|
/>
|
|
890
|
+
) : product.ProductId ===
|
|
891
|
+
'8474c3b080fa42cc837f1d2338fcf096' ||
|
|
892
|
+
product.ProductTitle ===
|
|
893
|
+
'High Resolution Snow and Ice Parameters' ? (
|
|
894
|
+
<div class="zoom-in-message-container">
|
|
895
|
+
<span>{product.ProductTitle}</span>
|
|
896
|
+
<div class="zoom-in-message">
|
|
897
|
+
Zoom in to view on map
|
|
898
|
+
</div>
|
|
899
|
+
</div>
|
|
811
900
|
) : (
|
|
812
901
|
<span>{product.ProductTitle}</span>
|
|
813
902
|
)}
|
|
@@ -860,32 +949,93 @@ class MenuWidget extends React.Component {
|
|
|
860
949
|
? dataset.DatasetDescription.substr(0, 300) + '...'
|
|
861
950
|
: dataset.DatasetDescription;
|
|
862
951
|
|
|
952
|
+
let style = this.props.download
|
|
953
|
+
? { paddingLeft: dataset.HandlingLevel ? '0' : '1rem' }
|
|
954
|
+
: {};
|
|
955
|
+
|
|
863
956
|
if (dataset.HandlingLevel) {
|
|
864
957
|
this.layerGroups[dataset.DatasetId] = [];
|
|
865
958
|
}
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
959
|
+
|
|
960
|
+
// TMS
|
|
961
|
+
if (dataset.ViewService.endsWith('file')) {
|
|
962
|
+
let tmsLayerIndex = 0;
|
|
963
|
+
|
|
964
|
+
dataset.Layer.forEach((layer, sublayerIndex) => {
|
|
965
|
+
if (!layer.LayerId) {
|
|
966
|
+
layer.LayerId = sublayerIndex;
|
|
967
|
+
}
|
|
968
|
+
let inheritedIndexLayer = inheritedIndex + '_' + tmsLayerIndex;
|
|
969
|
+
let checkboxId = layer.LayerId + '_' + inheritedIndexLayer;
|
|
970
|
+
|
|
971
|
+
// add as default
|
|
972
|
+
if (!layer_default.length) {
|
|
973
|
+
layer_default.push(checkboxId);
|
|
974
|
+
}
|
|
975
|
+
// add each sublayer to this.layers
|
|
976
|
+
this.processTMSLayer(layer, checkboxId, dataset);
|
|
977
|
+
|
|
978
|
+
// build TMS DOM nodes for TOC
|
|
979
|
+
layers.push(
|
|
980
|
+
<div
|
|
981
|
+
className="ccl-form-group map-menu-layer"
|
|
982
|
+
id={'layer_' + inheritedIndexLayer}
|
|
983
|
+
key={'a' + tmsLayerIndex}
|
|
984
|
+
data-timeseries={dataset.IsTimeSeries}
|
|
985
|
+
style={style}
|
|
986
|
+
>
|
|
987
|
+
<input
|
|
988
|
+
type="checkbox"
|
|
989
|
+
id={checkboxId}
|
|
990
|
+
parentid={checkIndex}
|
|
991
|
+
layerid={layer.LayerId}
|
|
992
|
+
name="layerCheckbox"
|
|
993
|
+
value="name"
|
|
994
|
+
className="ccl-checkbox ccl-required ccl-form-check-input"
|
|
995
|
+
key={'c' + tmsLayerIndex}
|
|
996
|
+
title={layer.Title}
|
|
997
|
+
onChange={(e) => {
|
|
998
|
+
this.toggleLayer(e.target);
|
|
999
|
+
}}
|
|
1000
|
+
></input>
|
|
1001
|
+
<label
|
|
1002
|
+
className="ccl-form-check-label"
|
|
1003
|
+
htmlFor={layer.LayerId + '_' + inheritedIndexLayer}
|
|
1004
|
+
key={'d' + tmsLayerIndex}
|
|
1005
|
+
>
|
|
1006
|
+
<span>{layer.Title}</span>
|
|
1007
|
+
</label>
|
|
1008
|
+
</div>,
|
|
870
1009
|
);
|
|
1010
|
+
tmsLayerIndex++;
|
|
1011
|
+
});
|
|
1012
|
+
} else {
|
|
1013
|
+
for (var i in dataset.Layer) {
|
|
1014
|
+
if (dataset.Layer[i].Default_active === true) {
|
|
1015
|
+
layer_default.push(
|
|
1016
|
+
dataset.Layer[i].LayerId + '_' + inheritedIndexDataset + '_' + i,
|
|
1017
|
+
);
|
|
1018
|
+
}
|
|
1019
|
+
if (dataset.HandlingLevel) {
|
|
1020
|
+
this.layerGroups[dataset.DatasetId].push(dataset.Layer[i].LayerId);
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
layers.push(
|
|
1024
|
+
this.metodProcessLayer(
|
|
1025
|
+
dataset.Layer[i],
|
|
1026
|
+
index,
|
|
1027
|
+
inheritedIndexDataset,
|
|
1028
|
+
dataset.ViewService,
|
|
1029
|
+
dataset.TimeSeriesService,
|
|
1030
|
+
checkIndex,
|
|
1031
|
+
dataset.IsTimeSeries,
|
|
1032
|
+
dataset.DatasetId,
|
|
1033
|
+
dataset.DatasetTitle,
|
|
1034
|
+
dataset.ProductId,
|
|
1035
|
+
),
|
|
1036
|
+
);
|
|
1037
|
+
index++;
|
|
871
1038
|
}
|
|
872
|
-
if (dataset.HandlingLevel) {
|
|
873
|
-
this.layerGroups[dataset.DatasetId].push(dataset.Layer[i].LayerId);
|
|
874
|
-
}
|
|
875
|
-
layers.push(
|
|
876
|
-
this.metodProcessLayer(
|
|
877
|
-
dataset.Layer[i],
|
|
878
|
-
index,
|
|
879
|
-
inheritedIndexDataset,
|
|
880
|
-
dataset.ViewService,
|
|
881
|
-
dataset.TimeSeriesService,
|
|
882
|
-
checkIndex,
|
|
883
|
-
dataset.IsTimeSeries,
|
|
884
|
-
layer_default,
|
|
885
|
-
dataset.HandlingLevel,
|
|
886
|
-
),
|
|
887
|
-
);
|
|
888
|
-
index++;
|
|
889
1039
|
}
|
|
890
1040
|
|
|
891
1041
|
if (!layer_default.length) {
|
|
@@ -893,9 +1043,6 @@ class MenuWidget extends React.Component {
|
|
|
893
1043
|
dataset.Layer[0].LayerId + '_' + inheritedIndexDataset + '_0',
|
|
894
1044
|
);
|
|
895
1045
|
}
|
|
896
|
-
let style = this.props.download
|
|
897
|
-
? { paddingLeft: dataset.HandlingLevel ? '0' : '1rem' }
|
|
898
|
-
: {};
|
|
899
1046
|
|
|
900
1047
|
return (
|
|
901
1048
|
<div
|
|
@@ -1048,28 +1195,32 @@ class MenuWidget extends React.Component {
|
|
|
1048
1195
|
layer,
|
|
1049
1196
|
layerIndex,
|
|
1050
1197
|
inheritedIndex,
|
|
1051
|
-
|
|
1198
|
+
viewService,
|
|
1052
1199
|
featureInfoUrl,
|
|
1053
1200
|
parentIndex,
|
|
1054
1201
|
isTimeSeries,
|
|
1055
|
-
|
|
1056
|
-
|
|
1202
|
+
DatasetId,
|
|
1203
|
+
DatasetTitle,
|
|
1204
|
+
ProductId,
|
|
1057
1205
|
) {
|
|
1058
1206
|
//For Legend request
|
|
1059
1207
|
const legendRequest =
|
|
1060
1208
|
'request=GetLegendGraphic&version=1.0.0&format=image/png&layer=';
|
|
1061
1209
|
//For each layer
|
|
1062
|
-
|
|
1210
|
+
let inheritedIndexLayer = inheritedIndex + '_' + layerIndex;
|
|
1211
|
+
let style = this.props.download ? { paddingLeft: '4rem' } : {};
|
|
1063
1212
|
//Add sublayers and popup enabled for layers
|
|
1064
1213
|
if (
|
|
1065
1214
|
!this.layers.hasOwnProperty(layer.LayerId + '_' + inheritedIndexLayer)
|
|
1066
1215
|
) {
|
|
1067
|
-
if (
|
|
1068
|
-
|
|
1216
|
+
if (viewService.toLowerCase().includes('wms')) {
|
|
1217
|
+
viewService = viewService.endsWith('?')
|
|
1218
|
+
? viewService
|
|
1219
|
+
: viewService + '?';
|
|
1069
1220
|
this.layers[layer.LayerId + '_' + inheritedIndexLayer] = new WMSLayer({
|
|
1070
|
-
url:
|
|
1221
|
+
url: viewService,
|
|
1071
1222
|
featureInfoFormat: 'text/html',
|
|
1072
|
-
featureInfoUrl:
|
|
1223
|
+
featureInfoUrl: viewService,
|
|
1073
1224
|
//id: layer.LayerId,
|
|
1074
1225
|
title: '',
|
|
1075
1226
|
legendEnabled: true,
|
|
@@ -1083,16 +1234,20 @@ class MenuWidget extends React.Component {
|
|
|
1083
1234
|
legendEnabled: true,
|
|
1084
1235
|
legendUrl: layer.StaticImageLegend
|
|
1085
1236
|
? layer.StaticImageLegend
|
|
1086
|
-
:
|
|
1237
|
+
: viewService + legendRequest + layer.LayerId,
|
|
1087
1238
|
featureInfoUrl: featureInfoUrl,
|
|
1088
1239
|
},
|
|
1089
1240
|
],
|
|
1090
1241
|
isTimeSeries: isTimeSeries,
|
|
1091
1242
|
fields: layer.Fields,
|
|
1243
|
+
DatasetId: DatasetId,
|
|
1244
|
+
DatasetTitle: DatasetTitle,
|
|
1245
|
+
ProductId: ProductId,
|
|
1246
|
+
ViewService: viewService,
|
|
1092
1247
|
});
|
|
1093
|
-
} else if (
|
|
1248
|
+
} else if (viewService.toLowerCase().includes('wmts')) {
|
|
1094
1249
|
this.layers[layer.LayerId + '_' + inheritedIndexLayer] = new WMTSLayer({
|
|
1095
|
-
url:
|
|
1250
|
+
url: viewService.endsWith('?') ? viewService : viewService + '?',
|
|
1096
1251
|
//id: layer.LayerId,
|
|
1097
1252
|
title: '',
|
|
1098
1253
|
_wmtsTitle: layer.Title, // CLMS-1105
|
|
@@ -1103,22 +1258,35 @@ class MenuWidget extends React.Component {
|
|
|
1103
1258
|
},
|
|
1104
1259
|
isTimeSeries: isTimeSeries,
|
|
1105
1260
|
fields: layer.Fields,
|
|
1261
|
+
DatasetId: DatasetId,
|
|
1262
|
+
DatasetTitle: DatasetTitle,
|
|
1263
|
+
ProductId: ProductId,
|
|
1264
|
+
ViewService: viewService,
|
|
1265
|
+
StaticImageLegend: layer.StaticImageLegend,
|
|
1266
|
+
LayerTitle: layer.Title,
|
|
1106
1267
|
});
|
|
1107
1268
|
} else {
|
|
1108
1269
|
this.layers[
|
|
1109
1270
|
layer.LayerId + '_' + inheritedIndexLayer
|
|
1110
1271
|
] = new FeatureLayer({
|
|
1111
|
-
url:
|
|
1272
|
+
url:
|
|
1273
|
+
viewService +
|
|
1274
|
+
(viewService.endsWith('/') ? '' : '/') +
|
|
1275
|
+
layer.LayerId,
|
|
1112
1276
|
id: layer.LayerId,
|
|
1113
1277
|
title: layer.Title,
|
|
1114
1278
|
featureInfoUrl: featureInfoUrl,
|
|
1115
1279
|
popupEnabled: true,
|
|
1116
1280
|
isTimeSeries: isTimeSeries,
|
|
1117
1281
|
fields: layer.Fields,
|
|
1282
|
+
DatasetId: DatasetId,
|
|
1283
|
+
DatasetTitle: DatasetTitle,
|
|
1284
|
+
ProductId: ProductId,
|
|
1285
|
+
ViewService: viewService,
|
|
1118
1286
|
});
|
|
1119
1287
|
}
|
|
1120
1288
|
}
|
|
1121
|
-
|
|
1289
|
+
|
|
1122
1290
|
return (
|
|
1123
1291
|
<div
|
|
1124
1292
|
className="ccl-form-group map-menu-layer"
|
|
@@ -1152,6 +1320,97 @@ class MenuWidget extends React.Component {
|
|
|
1152
1320
|
);
|
|
1153
1321
|
}
|
|
1154
1322
|
|
|
1323
|
+
/**
|
|
1324
|
+
* adds a custom TMS layer to this.layers array
|
|
1325
|
+
* @param {*} checkboxId Is the layers checkbox ID
|
|
1326
|
+
*/
|
|
1327
|
+
processTMSLayer(layer, checkboxId, dataset) {
|
|
1328
|
+
const CustomTileLayer = BaseTileLayer.createSubclass({
|
|
1329
|
+
properties: {
|
|
1330
|
+
urlTemplate: null,
|
|
1331
|
+
tms: false,
|
|
1332
|
+
tint: {
|
|
1333
|
+
value: null,
|
|
1334
|
+
},
|
|
1335
|
+
},
|
|
1336
|
+
|
|
1337
|
+
// generate the tile url for a given level, row and column
|
|
1338
|
+
getTileUrl: function (level, row, col) {
|
|
1339
|
+
// si es cero será el maximo. las filas serán el array invertido
|
|
1340
|
+
// tengo que extrarer de alguna manera la cantidad de filas y columnas que se muestran.
|
|
1341
|
+
|
|
1342
|
+
return this.urlTemplate
|
|
1343
|
+
.replace('{z}', level)
|
|
1344
|
+
.replace('{x}', col)
|
|
1345
|
+
.replace('{y}', row);
|
|
1346
|
+
},
|
|
1347
|
+
|
|
1348
|
+
// This method fetches tiles for the specified level and size.
|
|
1349
|
+
// Override this method to process the data returned from the server.
|
|
1350
|
+
fetchTile: function (level, row, col, options) {
|
|
1351
|
+
// call getTileUrl() method to construct the URL to tiles
|
|
1352
|
+
// for a given level, row and col provided by the LayerView
|
|
1353
|
+
|
|
1354
|
+
// Images pyramid formula
|
|
1355
|
+
if (this.tms) {
|
|
1356
|
+
var rowmax = 1 << level; // LEVEL 1 * (2 ** 1) = 1 * (2) = 2 ; LEVEL 2 * (2 ** 2) = 1 * (4) = 4 ; LEVEL 3 * (2 ** 3) = 1 * (8) = 8 . . .
|
|
1357
|
+
row = rowmax - row - 1; // Invert Y axis
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
const url = this.getTileUrl(level, row, col);
|
|
1361
|
+
|
|
1362
|
+
// request for tiles based on the generated url
|
|
1363
|
+
// the signal option ensures that obsolete requests are aborted
|
|
1364
|
+
return esriRequest(url, {
|
|
1365
|
+
responseType: 'image',
|
|
1366
|
+
signal: options && options.signal,
|
|
1367
|
+
}).then(
|
|
1368
|
+
function (response) {
|
|
1369
|
+
// when esri request resolves successfully
|
|
1370
|
+
// get the image from the response
|
|
1371
|
+
const image = response.data;
|
|
1372
|
+
const width = this.tileInfo.size[0];
|
|
1373
|
+
const height = this.tileInfo.size[0];
|
|
1374
|
+
// create a canvas with 2D rendering context
|
|
1375
|
+
const canvas = document.createElement('canvas');
|
|
1376
|
+
const context = canvas.getContext('2d');
|
|
1377
|
+
//canvas
|
|
1378
|
+
canvas.width = width;
|
|
1379
|
+
canvas.height = height;
|
|
1380
|
+
|
|
1381
|
+
// Draw the blended image onto the canvas.
|
|
1382
|
+
context.drawImage(image, 0, 0, width, height);
|
|
1383
|
+
|
|
1384
|
+
return canvas;
|
|
1385
|
+
}.bind(this),
|
|
1386
|
+
);
|
|
1387
|
+
},
|
|
1388
|
+
});
|
|
1389
|
+
// *******************************************************
|
|
1390
|
+
// end of Custom tile layer class code
|
|
1391
|
+
// *******************************************************
|
|
1392
|
+
this.layers[checkboxId] = new CustomTileLayer({
|
|
1393
|
+
id: checkboxId,
|
|
1394
|
+
tms: true, // True establishes Y axis from the south northwards. False establishes tile origin top left and Y from north southwards (Default False)
|
|
1395
|
+
urlTemplate: layer.LayerUrl,
|
|
1396
|
+
// TMS Service.
|
|
1397
|
+
// 'https://s3-eu-west-1.amazonaws.com/vito-lcv/global/2019/cog-full_l0-colored-full/{z}/{x}/{y}.png',
|
|
1398
|
+
// Google/ESRI/OSM tiling style services
|
|
1399
|
+
// "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
|
|
1400
|
+
// "https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}",
|
|
1401
|
+
// "https://stamen-tiles.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.jpg",
|
|
1402
|
+
spatialReference: {
|
|
1403
|
+
wkid: 3857,
|
|
1404
|
+
},
|
|
1405
|
+
title: layer.Title,
|
|
1406
|
+
LayerTitle: layer.Title,
|
|
1407
|
+
DatasetTitle: dataset.DatasetTitle,
|
|
1408
|
+
ViewService: dataset.ViewService,
|
|
1409
|
+
StaticImageLegend: layer.StaticImageLegend,
|
|
1410
|
+
url: dataset.ViewService,
|
|
1411
|
+
});
|
|
1412
|
+
}
|
|
1413
|
+
|
|
1155
1414
|
/**
|
|
1156
1415
|
* Method to show/hide a layer. Update checkboxes from dataset and products
|
|
1157
1416
|
* @param {*} elem Is the checkbox
|
|
@@ -1195,6 +1454,9 @@ class MenuWidget extends React.Component {
|
|
|
1195
1454
|
} else {
|
|
1196
1455
|
this.deleteCheckedLayer(elem.id);
|
|
1197
1456
|
this.layers[elem.id].opacity = 1;
|
|
1457
|
+
this.layers[elem.id].visible = false;
|
|
1458
|
+
let mapLayer = this.map.findLayerById(elem.id);
|
|
1459
|
+
if (mapLayer) mapLayer.destroy();
|
|
1198
1460
|
this.map.remove(this.layers[elem.id]);
|
|
1199
1461
|
delete this.activeLayersJSON[elem.id];
|
|
1200
1462
|
delete this.visibleLayers[elem.id];
|
|
@@ -1203,10 +1465,105 @@ class MenuWidget extends React.Component {
|
|
|
1203
1465
|
this.updateCheckDataset(parentId);
|
|
1204
1466
|
this.layersReorder();
|
|
1205
1467
|
this.checkInfoWidget();
|
|
1468
|
+
|
|
1469
|
+
// toggle custom legend for WMTS and TMS
|
|
1470
|
+
if (
|
|
1471
|
+
this.layers[elem.id].ViewService.toLowerCase().includes('wmts') ||
|
|
1472
|
+
this.layers[elem.id].ViewService.toLowerCase().endsWith('file')
|
|
1473
|
+
) {
|
|
1474
|
+
this.toggleCustomLegendItem(this.layers[elem.id]);
|
|
1475
|
+
}
|
|
1206
1476
|
// update DOM
|
|
1207
1477
|
this.setState({});
|
|
1208
1478
|
}
|
|
1209
1479
|
|
|
1480
|
+
/**
|
|
1481
|
+
* Hide or show a legend image in the legend widget for a WMTS or a TMS layer
|
|
1482
|
+
*
|
|
1483
|
+
* @param Layer
|
|
1484
|
+
*/
|
|
1485
|
+
toggleCustomLegendItem(layer) {
|
|
1486
|
+
// check for existing legend item
|
|
1487
|
+
let existingItem = document.getElementById(
|
|
1488
|
+
'custom-legend-item-' + layer.id,
|
|
1489
|
+
);
|
|
1490
|
+
|
|
1491
|
+
if (layer.visible) {
|
|
1492
|
+
if (!existingItem) {
|
|
1493
|
+
// create one
|
|
1494
|
+
this.addCustomItemToLegend(layer);
|
|
1495
|
+
} else {
|
|
1496
|
+
// show existing one
|
|
1497
|
+
existingItem.style.display = 'block';
|
|
1498
|
+
}
|
|
1499
|
+
} else {
|
|
1500
|
+
// hide legend item
|
|
1501
|
+
if (existingItem) {
|
|
1502
|
+
existingItem.style.display = 'none';
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
addCustomItemToLegend(layer) {
|
|
1508
|
+
// Find legend widget node
|
|
1509
|
+
const legendDiv = document.querySelectorAll('.esri-widget.esri-legend')[0];
|
|
1510
|
+
let childDiv = legendDiv.firstChild;
|
|
1511
|
+
|
|
1512
|
+
// create legend element
|
|
1513
|
+
let legendItem = this.createStaticLegendImageNode(
|
|
1514
|
+
layer.id,
|
|
1515
|
+
layer.LayerTitle,
|
|
1516
|
+
layer.StaticImageLegend,
|
|
1517
|
+
);
|
|
1518
|
+
|
|
1519
|
+
// append to Legend widet
|
|
1520
|
+
childDiv.appendChild(legendItem);
|
|
1521
|
+
|
|
1522
|
+
// hide no legend message
|
|
1523
|
+
const noLegendMessage = document.querySelectorAll(
|
|
1524
|
+
'.esri-legend__message',
|
|
1525
|
+
)[0];
|
|
1526
|
+
if (noLegendMessage) {
|
|
1527
|
+
noLegendMessage.style.display = 'none';
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
createStaticLegendImageNode(id, title, imageURL) {
|
|
1532
|
+
let node = document.createElement('div');
|
|
1533
|
+
node.classList.add('esri-legend__service');
|
|
1534
|
+
node.id = 'custom-legend-item-' + id;
|
|
1535
|
+
|
|
1536
|
+
// Create node
|
|
1537
|
+
let template = `
|
|
1538
|
+
<div class="esri-legend__layer">
|
|
1539
|
+
<div class="esri-legend__layer-table esri-legend__layer-table--size-ramp" >
|
|
1540
|
+
<div class="esri-legend__layer-caption">
|
|
1541
|
+
${title}
|
|
1542
|
+
</div>
|
|
1543
|
+
<div class="esri-legend__layer-body">
|
|
1544
|
+
<div class="esri-legend__layer-row">
|
|
1545
|
+
<div class="esri-legend__layer-cell esri-legend__layer-cell--symbols" >
|
|
1546
|
+
<div class="esri-legend__symbol">
|
|
1547
|
+
<img crossorigin="anonymous"
|
|
1548
|
+
alt=""
|
|
1549
|
+
src="${imageURL}"
|
|
1550
|
+
style="opacity: 1"
|
|
1551
|
+
/>
|
|
1552
|
+
</div>
|
|
1553
|
+
</div>
|
|
1554
|
+
<div
|
|
1555
|
+
class="esri-legend__layer-cell esri-legend__layer-cell--info"
|
|
1556
|
+
></div>
|
|
1557
|
+
</div>
|
|
1558
|
+
</div>
|
|
1559
|
+
</div>
|
|
1560
|
+
</div>`;
|
|
1561
|
+
|
|
1562
|
+
node.innerHTML = template;
|
|
1563
|
+
|
|
1564
|
+
return node;
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1210
1567
|
/**
|
|
1211
1568
|
* Returns the DOM elements for active layers
|
|
1212
1569
|
* just in the order they were added to map
|
|
@@ -1282,6 +1639,7 @@ class MenuWidget extends React.Component {
|
|
|
1282
1639
|
} else {
|
|
1283
1640
|
datasetChecks = document.querySelectorAll(`[parentid=${id}]`);
|
|
1284
1641
|
}
|
|
1642
|
+
|
|
1285
1643
|
datasetChecks.forEach((element) => {
|
|
1286
1644
|
element.checked = value;
|
|
1287
1645
|
this.toggleDataset(value, element.id, element);
|
|
@@ -1006,3 +1006,13 @@ input[type='range']::-ms-track {
|
|
|
1006
1006
|
background: transparent;
|
|
1007
1007
|
box-shadow: none;
|
|
1008
1008
|
}
|
|
1009
|
+
|
|
1010
|
+
.zoom-in-message {
|
|
1011
|
+
padding: 0.1rem 0.6rem 0.1rem 0.6rem;
|
|
1012
|
+
margin-top: 0.2rem;
|
|
1013
|
+
background: #a0b128;
|
|
1014
|
+
border-radius: 10px;
|
|
1015
|
+
color: white;
|
|
1016
|
+
font-size: 0.875rem;
|
|
1017
|
+
text-align: center;
|
|
1018
|
+
}
|