@eeacms/volto-arcgis-block 0.1.264 → 0.1.266
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 +25 -0
- package/package.json +3 -3
- package/src/components/MapViewer/AreaWidget.jsx +484 -8
- package/src/components/MapViewer/MapViewer.jsx +1 -1
- package/src/components/MapViewer/MenuWidget.jsx +99 -13
- package/src/components/MapViewer/config.js +1 -0
- package/src/components/MapViewer/css/ArcgisMap.css +17 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,31 @@ 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.266](https://github.com/eea/volto-arcgis-block/compare/0.1.265...0.1.266) - 19 March 2024
|
|
8
|
+
|
|
9
|
+
#### :hammer_and_wrench: Others
|
|
10
|
+
|
|
11
|
+
- CLMS-2383-3050 (chore): added FAQ hyperlink [Unai Bolivar - [`445af32`](https://github.com/eea/volto-arcgis-block/commit/445af32d2a7c4326f3369657378bbe97b1cb4c2f)]
|
|
12
|
+
- CLMS-2383-3050 (chore): fixed lint error 2 [Unai Bolivar - [`93114ff`](https://github.com/eea/volto-arcgis-block/commit/93114ff28cc2ad1414a079e09489a0c732e8d8ff)]
|
|
13
|
+
- CLMS-2383-3050 (chore): fixed lint error [Unai Bolivar - [`0b53f2e`](https://github.com/eea/volto-arcgis-block/commit/0b53f2e4237aa111e667978c2f97459e1ba7c468)]
|
|
14
|
+
- CLMS-2383-3050 (bug): ready for push [Unai Bolivar - [`c452b23`](https://github.com/eea/volto-arcgis-block/commit/c452b234d7be3dff7dfd35cc14d18b8c0df2a215)]
|
|
15
|
+
- CLMS-2383-3050 (feat): implemented new functions for feature generation [Unai Bolivar - [`d31c2b9`](https://github.com/eea/volto-arcgis-block/commit/d31c2b94bb5232fd15631851549eedd6fa7e80be)]
|
|
16
|
+
- CLMS-2383-3050 (feat): implemented cleared rectangle handler when file is uploaded [Unai Bolivar - [`a90a1ff`](https://github.com/eea/volto-arcgis-block/commit/a90a1ff4121c0f4e12740865c1def8e1a8455a8c)]
|
|
17
|
+
- CLMS-2383-3050 (feat): Disabled legends for file uploads [Unai Bolivar - [`c5c3e16`](https://github.com/eea/volto-arcgis-block/commit/c5c3e163230952b1bf1b732b12c51256c07d5a14)]
|
|
18
|
+
- CLMS-2383-3050 (feat): Implemented nuts and countries layer removal when file uploaded and uploaded layer removal when countries or nuts is selected or a new file is uploaded and successfully processed [Unai Bolivar - [`3f47039`](https://github.com/eea/volto-arcgis-block/commit/3f47039d2deb4a0c9a7dc5016b415946d3bd6fb8)]
|
|
19
|
+
- CLMS-2383-3050 (feat): Implemented single polygon and geometry type checks for shp and geojson files [Unai Bolivar - [`06e43b2`](https://github.com/eea/volto-arcgis-block/commit/06e43b2a819124034d94407b2117a1ad6f6cd1fa)]
|
|
20
|
+
- CLMS-2383-3050 (feat): implemented extent bounding box limit, wkid checker, needs more testing. [Unai Bolivar - [`901d893`](https://github.com/eea/volto-arcgis-block/commit/901d8939226a25624e7708081c59283f5cd27bfa)]
|
|
21
|
+
- CLMS-2383-3050 (chore): implemented max file size limit and info button for file upload FAQ page [Unai Bolivar - [`a05d736`](https://github.com/eea/volto-arcgis-block/commit/a05d73609f84813e275351eee952c4dd318614d2)]
|
|
22
|
+
- CLMS-2383-3050 (chore): implemented simple error messages for file upload max size and incorrect format [Unai Bolivar - [`cbed86e`](https://github.com/eea/volto-arcgis-block/commit/cbed86e68dfe1e2fa61c75da743e1cf9a5332e8f)]
|
|
23
|
+
- CLMS-2383-3050 (chore): corrected button styles in upload form [Unai Bolivar - [`5ca6fb1`](https://github.com/eea/volto-arcgis-block/commit/5ca6fb1d946facf2543d034c23fa9806ac6bfa4c)]
|
|
24
|
+
- CLMS-2749 (feat): csv file upload and render on map is working [Unai Bolivar - [`b670eca`](https://github.com/eea/volto-arcgis-block/commit/b670eca70fc8569929d17b9dda9e585a768de1bd)]
|
|
25
|
+
- CLMS-2749 (feat): shape file upload and render on map is working [Unai Bolivar - [`b8a4731`](https://github.com/eea/volto-arcgis-block/commit/b8a473139f4eb5dceb9ec411c3c446570c630881)]
|
|
26
|
+
- CLMS-2749 (feat): geoJSON file upload and render on map is working [Unai Bolivar - [`a87f7f1`](https://github.com/eea/volto-arcgis-block/commit/a87f7f1c0028e9251ffb4e4e196739b48335c87f)]
|
|
27
|
+
- CLMS-2749 (feat): continuation [Unai Bolivar - [`a16254e`](https://github.com/eea/volto-arcgis-block/commit/a16254e661576630a97aed17df27ad346593a1af)]
|
|
28
|
+
- CLMS-2749 (feat): added new library for shp processing and most file operations have been built [Unai Bolivar - [`114902f`](https://github.com/eea/volto-arcgis-block/commit/114902f5636c18784979db8c6dc8fbf11ba86023)]
|
|
29
|
+
- CLMS-2749 (feat): Implementation of file upload in area selection for data viewer [Unai Bolivar - [`bce2e45`](https://github.com/eea/volto-arcgis-block/commit/bce2e458d5cf1cc9d6c39b4824f054343a2d9781)]
|
|
30
|
+
### [0.1.265](https://github.com/eea/volto-arcgis-block/compare/0.1.264...0.1.265) - 13 March 2024
|
|
31
|
+
|
|
7
32
|
### [0.1.264](https://github.com/eea/volto-arcgis-block/compare/0.1.263...0.1.264) - 11 March 2024
|
|
8
33
|
|
|
9
34
|
### [0.1.263](https://github.com/eea/volto-arcgis-block/compare/0.1.262...0.1.263) - 29 February 2024
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eeacms/volto-arcgis-block",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.266",
|
|
4
4
|
"description": "volto-arcgis-block: Volto add-on",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"author": "European Environment Agency: CodeSyntax",
|
|
@@ -70,9 +70,9 @@
|
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@cypress/code-coverage": "^3.9.5",
|
|
72
72
|
"babel-plugin-transform-class-properties": "^6.24.1",
|
|
73
|
+
"dotenv": "^16.3.2",
|
|
73
74
|
"husky": "^8.0.3",
|
|
74
75
|
"lint-staged": "13.1.4",
|
|
75
|
-
"md5": "^2.3.0"
|
|
76
|
-
"dotenv": "^16.3.2"
|
|
76
|
+
"md5": "^2.3.0"
|
|
77
77
|
}
|
|
78
78
|
}
|
|
@@ -4,9 +4,13 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
|
4
4
|
|
|
5
5
|
var Graphic,
|
|
6
6
|
Extent,
|
|
7
|
+
CSVLayer,
|
|
7
8
|
FeatureLayer,
|
|
9
|
+
Field,
|
|
8
10
|
GroupLayer,
|
|
9
11
|
Color,
|
|
12
|
+
//Query,
|
|
13
|
+
request,
|
|
10
14
|
SimpleLineSymbol,
|
|
11
15
|
SimpleFillSymbol;
|
|
12
16
|
|
|
@@ -35,41 +39,65 @@ class AreaWidget extends React.Component {
|
|
|
35
39
|
this.nutsUrl = '';
|
|
36
40
|
this.initFMI = this.initFMI.bind(this);
|
|
37
41
|
this.mapviewer_config = this.props.mapviewer_config;
|
|
42
|
+
this.fileInput = createRef();
|
|
43
|
+
this.handleCsv = this.handleCsv.bind(this);
|
|
44
|
+
this.fileUploadLayer = null;
|
|
45
|
+
this.removeFileUploadedLayer = this.removeFileUploadedLayer.bind(this);
|
|
46
|
+
this.uploadPortal = this.props.urls.uploadPortal;
|
|
47
|
+
this.generateFeatureCollection = this.generateFeatureCollection.bind(this);
|
|
48
|
+
this.addFeatureCollectionToMap = this.addFeatureCollectionToMap.bind(this);
|
|
49
|
+
this.checkFeatureCount = this.checkFeatureCount.bind(this);
|
|
38
50
|
}
|
|
39
51
|
|
|
40
52
|
loader() {
|
|
41
53
|
return loadModules([
|
|
42
54
|
'esri/Graphic',
|
|
43
55
|
'esri/geometry/Extent',
|
|
56
|
+
'esri/layers/CSVLayer',
|
|
44
57
|
'esri/layers/FeatureLayer',
|
|
58
|
+
'esri/layers/support/Field',
|
|
45
59
|
'esri/layers/GroupLayer',
|
|
46
60
|
'esri/Color',
|
|
61
|
+
//'esri/rest/support/Query',
|
|
62
|
+
'esri/request',
|
|
47
63
|
'esri/symbols/SimpleLineSymbol',
|
|
48
64
|
'esri/symbols/SimpleFillSymbol',
|
|
49
65
|
]).then(
|
|
50
66
|
([
|
|
51
67
|
_Graphic,
|
|
52
68
|
_Extent,
|
|
69
|
+
_CSVLayer,
|
|
53
70
|
_FeatureLayer,
|
|
71
|
+
_Field,
|
|
54
72
|
_GroupLayer,
|
|
55
73
|
_Color,
|
|
74
|
+
//_Query,
|
|
75
|
+
_request,
|
|
56
76
|
_SimpleLineSymbol,
|
|
57
77
|
_SimpleFillSymbol,
|
|
58
78
|
]) => {
|
|
59
79
|
[
|
|
60
80
|
Graphic,
|
|
61
81
|
Extent,
|
|
82
|
+
CSVLayer,
|
|
62
83
|
FeatureLayer,
|
|
84
|
+
Field,
|
|
63
85
|
GroupLayer,
|
|
64
86
|
Color,
|
|
87
|
+
//Query,
|
|
88
|
+
request,
|
|
65
89
|
SimpleLineSymbol,
|
|
66
90
|
SimpleFillSymbol,
|
|
67
91
|
] = [
|
|
68
92
|
_Graphic,
|
|
69
93
|
_Extent,
|
|
94
|
+
_CSVLayer,
|
|
70
95
|
_FeatureLayer,
|
|
96
|
+
_Field,
|
|
71
97
|
_GroupLayer,
|
|
72
98
|
_Color,
|
|
99
|
+
//_Query,
|
|
100
|
+
_request,
|
|
73
101
|
_SimpleLineSymbol,
|
|
74
102
|
_SimpleFillSymbol,
|
|
75
103
|
];
|
|
@@ -101,6 +129,7 @@ class AreaWidget extends React.Component {
|
|
|
101
129
|
infoPopupType: 'area',
|
|
102
130
|
});
|
|
103
131
|
this.clearWidget();
|
|
132
|
+
this.removeFileUploadedLayer();
|
|
104
133
|
this.container.current.querySelector(
|
|
105
134
|
'#download_area_select_nuts0',
|
|
106
135
|
).checked = true;
|
|
@@ -183,6 +212,8 @@ class AreaWidget extends React.Component {
|
|
|
183
212
|
//definitionExpression: 'LEVL_CODE=' + level,
|
|
184
213
|
});
|
|
185
214
|
|
|
215
|
+
this.removeFileUploadedLayer();
|
|
216
|
+
|
|
186
217
|
this.nutsGroupLayer.add(layer);
|
|
187
218
|
|
|
188
219
|
let index = this.getHighestIndex();
|
|
@@ -204,6 +235,8 @@ class AreaWidget extends React.Component {
|
|
|
204
235
|
popupEnabled: false,
|
|
205
236
|
});
|
|
206
237
|
|
|
238
|
+
this.removeFileUploadedLayer();
|
|
239
|
+
|
|
207
240
|
this.nutsGroupLayer.add(layer);
|
|
208
241
|
|
|
209
242
|
let index = this.getHighestIndex();
|
|
@@ -211,6 +244,354 @@ class AreaWidget extends React.Component {
|
|
|
211
244
|
this.props.map.reorder(this.nutsGroupLayer, index + 1);
|
|
212
245
|
}
|
|
213
246
|
|
|
247
|
+
// FILE UPLOAD HANDLERS
|
|
248
|
+
|
|
249
|
+
// Trigger the file input click
|
|
250
|
+
handleUploadClick = (event) => {
|
|
251
|
+
event.preventDefault();
|
|
252
|
+
this.fileInput.current.click();
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
handleFileUpload = (e) => {
|
|
256
|
+
//Store the file as Blob
|
|
257
|
+
let fileBlob = e.target.files[0];
|
|
258
|
+
//Get the file name
|
|
259
|
+
const fileName = e.target.value.toLowerCase();
|
|
260
|
+
//console.log('file name: ', fileName);
|
|
261
|
+
|
|
262
|
+
//Get the file from the form
|
|
263
|
+
const file = document.getElementById('uploadForm');
|
|
264
|
+
//console.log('uploaded file from form: ', file);
|
|
265
|
+
|
|
266
|
+
//List allowed file extensions
|
|
267
|
+
let fileExtensions = ['zip', 'geojson', 'csv'];
|
|
268
|
+
|
|
269
|
+
// Get the file extension
|
|
270
|
+
let fileExtension = fileName.split('.').pop();
|
|
271
|
+
|
|
272
|
+
//console.log('file extension: ', fileExtension);
|
|
273
|
+
|
|
274
|
+
//Check if the file format is not supported
|
|
275
|
+
if (fileExtensions.indexOf(fileExtension) === -1) {
|
|
276
|
+
this.setState({
|
|
277
|
+
showInfoPopup: true,
|
|
278
|
+
infoPopupType: 'fileFormat',
|
|
279
|
+
});
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
//Check if the file size is over the 10mb file size limit
|
|
284
|
+
if (
|
|
285
|
+
(file.size > 2000000 && fileExtension === 'zip') ||
|
|
286
|
+
(file.size > 1000000 && fileExtension === 'geojson') ||
|
|
287
|
+
(file.size > 1000000 && fileExtension === 'csv')
|
|
288
|
+
) {
|
|
289
|
+
this.setState({
|
|
290
|
+
showInfoPopup: true,
|
|
291
|
+
infoPopupType: 'fileLimit',
|
|
292
|
+
});
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
//Read the file
|
|
297
|
+
let reader = new FileReader();
|
|
298
|
+
|
|
299
|
+
reader.onload = (event) => {
|
|
300
|
+
switch (fileExtension) {
|
|
301
|
+
// case 'zip':
|
|
302
|
+
// this.handleShp(event.target.result);
|
|
303
|
+
// break;
|
|
304
|
+
// case 'geojson':
|
|
305
|
+
// let parsedData;
|
|
306
|
+
// try {
|
|
307
|
+
// parsedData = JSON.parse(event.target.result);
|
|
308
|
+
// } catch (e) {
|
|
309
|
+
// console.error('Failed to parse JSON', e);
|
|
310
|
+
// return;
|
|
311
|
+
// }
|
|
312
|
+
// this.handleGeoJson(parsedData);
|
|
313
|
+
// break;
|
|
314
|
+
case 'csv':
|
|
315
|
+
this.handleCsv(event.target.result);
|
|
316
|
+
break;
|
|
317
|
+
default:
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
switch (fileExtension) {
|
|
323
|
+
case 'zip':
|
|
324
|
+
this.generateFeatureCollection(fileName, file, 'shapefile');
|
|
325
|
+
//reader.readAsArrayBuffer(file);
|
|
326
|
+
break;
|
|
327
|
+
case 'geojson':
|
|
328
|
+
this.generateFeatureCollection(fileName, file, 'geojson');
|
|
329
|
+
//reader.readAsText(file);
|
|
330
|
+
break;
|
|
331
|
+
case 'csv':
|
|
332
|
+
//this.generateFeatureCollection(
|
|
333
|
+
// fileName,
|
|
334
|
+
// file,
|
|
335
|
+
// 'csv',
|
|
336
|
+
//);
|
|
337
|
+
reader.readAsText(fileBlob);
|
|
338
|
+
break;
|
|
339
|
+
default:
|
|
340
|
+
break;
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
generateFeatureCollection(fileName, file, inputFormat) {
|
|
345
|
+
let name = fileName.split('.');
|
|
346
|
+
|
|
347
|
+
// Chrome adds c:\fakepath to the value - we need to remove it
|
|
348
|
+
name = name[0].replace('c:\\fakepath\\', '');
|
|
349
|
+
|
|
350
|
+
//console.log('from generateFeatureCollection() name: ', name);
|
|
351
|
+
|
|
352
|
+
// define the input params for generate see the rest doc for details
|
|
353
|
+
// https://developers.arcgis.com/rest/users-groups-and-items/generate.htm
|
|
354
|
+
const params = {
|
|
355
|
+
name: name,
|
|
356
|
+
targetSR: this.props.view.spatialReference,
|
|
357
|
+
maxRecordCount: 1000,
|
|
358
|
+
enforceInputFileSizeLimit: true,
|
|
359
|
+
enforceOutputJsonSizeLimit: true,
|
|
360
|
+
};
|
|
361
|
+
// generalize features to 10 meters for better performance
|
|
362
|
+
params.generalize = true;
|
|
363
|
+
params.maxAllowableOffset = 10;
|
|
364
|
+
params.reducePrecision = true;
|
|
365
|
+
params.numberOfDigitsAfterDecimal = 0;
|
|
366
|
+
|
|
367
|
+
const myContent = {
|
|
368
|
+
filetype: inputFormat,
|
|
369
|
+
publishParameters: JSON.stringify(params),
|
|
370
|
+
f: 'json',
|
|
371
|
+
};
|
|
372
|
+
// use the REST generate operation to generate a feature collection from the zipped shapefile
|
|
373
|
+
request(this.uploadPortal + '/sharing/rest/content/features/generate', {
|
|
374
|
+
query: myContent,
|
|
375
|
+
body: file,
|
|
376
|
+
responseType: 'json',
|
|
377
|
+
})
|
|
378
|
+
.then((response) => {
|
|
379
|
+
if (response.data && response.data.featureCollection) {
|
|
380
|
+
//console.log('response data: ', response.data);
|
|
381
|
+
//Check for more than a single feature
|
|
382
|
+
if (this.checkFeatureCount(response.data.featureCollection) === false)
|
|
383
|
+
return;
|
|
384
|
+
//Create a feature layer from the feature collection
|
|
385
|
+
this.addFeatureCollectionToMap(response.data.featureCollection);
|
|
386
|
+
} else {
|
|
387
|
+
//console.error('Unexpected response structure:', response);
|
|
388
|
+
}
|
|
389
|
+
})
|
|
390
|
+
.catch((error) => {
|
|
391
|
+
//console.error('From generateFeatureCollection function', error);
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// add the feature collection to the map and zoom to the feature collection extent
|
|
396
|
+
// if you want to persist the feature collection when you reload browser, you could store the
|
|
397
|
+
// collection in local storage by serializing the layer using featureLayer.toJson()
|
|
398
|
+
// see the 'Feature Collection in Local Storage' sample for an example of how to work with local storage
|
|
399
|
+
addFeatureCollectionToMap(featureCollection) {
|
|
400
|
+
let sourceGraphics = [];
|
|
401
|
+
const layers = featureCollection.layers.map((layer) => {
|
|
402
|
+
const graphics = layer.featureSet.features.map((feature) => {
|
|
403
|
+
return Graphic.fromJSON(feature);
|
|
404
|
+
});
|
|
405
|
+
sourceGraphics = sourceGraphics.concat(graphics);
|
|
406
|
+
const featureLayer = new FeatureLayer({
|
|
407
|
+
objectIdField: 'FID',
|
|
408
|
+
source: graphics,
|
|
409
|
+
legendEnabled: false,
|
|
410
|
+
title: 'uploadLayer',
|
|
411
|
+
fields: layer.layerDefinition.fields.map((field) => {
|
|
412
|
+
return Field.fromJSON(field);
|
|
413
|
+
}),
|
|
414
|
+
});
|
|
415
|
+
return featureLayer;
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
//Check for the correct spatial reference
|
|
419
|
+
//console.log("layer: ", layers);
|
|
420
|
+
if (this.checkWkid(layers[0]?.spatialReference) === false) return;
|
|
421
|
+
|
|
422
|
+
let geometry = new Extent(
|
|
423
|
+
featureCollection.layers[0].layerDefinition.extent,
|
|
424
|
+
);
|
|
425
|
+
|
|
426
|
+
//If checkExtent returns false, add the layer to the map
|
|
427
|
+
if (this.checkExtent(geometry.extent)) {
|
|
428
|
+
this.setState({
|
|
429
|
+
showInfoPopup: true,
|
|
430
|
+
infoPopupType: 'fullDataset',
|
|
431
|
+
});
|
|
432
|
+
} else {
|
|
433
|
+
//Remove old uploaded file and save new one to component props for reference
|
|
434
|
+
this.removeFileUploadedLayer();
|
|
435
|
+
this.fileUploadLayer = { layers: layers, sourceGraphics: sourceGraphics };
|
|
436
|
+
//remove NUTS and COUNTRIES layers from map
|
|
437
|
+
this.removeNutsLayers();
|
|
438
|
+
|
|
439
|
+
//Add uploaded layer to the map and zoom to the extent
|
|
440
|
+
this.props.map.addMany(layers);
|
|
441
|
+
this.props.view.goTo(sourceGraphics).catch((error) => {
|
|
442
|
+
//console.error('From addFeatureCollectionToMap function', error);
|
|
443
|
+
});
|
|
444
|
+
//Send the area to the parent component
|
|
445
|
+
this.props.updateArea({
|
|
446
|
+
origin: { x: geometry.extent.xmin, y: geometry.extent.ymin },
|
|
447
|
+
end: { x: geometry.extent.xmax, y: geometry.extent.ymax },
|
|
448
|
+
});
|
|
449
|
+
//Order the layer in the map
|
|
450
|
+
let index = this.getHighestIndex();
|
|
451
|
+
this.props.map.reorder(this.fileUploadLayer, index + 1);
|
|
452
|
+
this.setState({
|
|
453
|
+
showInfoPopup: true,
|
|
454
|
+
infoPopupType: 'download',
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
//check if the featurecollection has more than one feature
|
|
460
|
+
|
|
461
|
+
checkFeatureCount(layers) {
|
|
462
|
+
//debugger;
|
|
463
|
+
if (layers.layers[0].featureSet.features.length > 1) {
|
|
464
|
+
this.setState({
|
|
465
|
+
showInfoPopup: true,
|
|
466
|
+
infoPopupType: 'singleFeature',
|
|
467
|
+
});
|
|
468
|
+
return false;
|
|
469
|
+
} else {
|
|
470
|
+
return true;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
//Check if the file has a polygon geometry type
|
|
475
|
+
|
|
476
|
+
/* uncomment the code below before pushing to DEMO */
|
|
477
|
+
|
|
478
|
+
//if (data?.features?.geometry?.type !== 'polygon') {
|
|
479
|
+
// this.setState({
|
|
480
|
+
// showInfoPopup: true,
|
|
481
|
+
// infoPopupType: 'singlePolygon',
|
|
482
|
+
// });
|
|
483
|
+
// return;
|
|
484
|
+
//}
|
|
485
|
+
|
|
486
|
+
//Display CSV on the map
|
|
487
|
+
|
|
488
|
+
handleCsv(data) {
|
|
489
|
+
//Create a CSV layer
|
|
490
|
+
const blob = new Blob([data], {
|
|
491
|
+
type: 'plain/text',
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
let url = URL.createObjectURL(blob);
|
|
495
|
+
|
|
496
|
+
const csvLayer = new CSVLayer({
|
|
497
|
+
url,
|
|
498
|
+
legendEnabled: false,
|
|
499
|
+
title: 'uploadLayer',
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
//debugger;
|
|
503
|
+
//Query all features insisde the CSV layer
|
|
504
|
+
|
|
505
|
+
//csvLayer.load().then(function(){
|
|
506
|
+
// let query = new Query({
|
|
507
|
+
// where: "mag > 5",
|
|
508
|
+
// returnGeometry: true
|
|
509
|
+
// });
|
|
510
|
+
//
|
|
511
|
+
// return csvLayer.queryFeatures(query);
|
|
512
|
+
//})
|
|
513
|
+
//.then(function(results){
|
|
514
|
+
// console.log(results);
|
|
515
|
+
//})
|
|
516
|
+
//.catch(function (error) {
|
|
517
|
+
// console.error("From CSV query: ", error);
|
|
518
|
+
//});
|
|
519
|
+
//Check if the file has the correct spatial reference
|
|
520
|
+
if (this.checkWkid(csvLayer?.spatialReference) === false) return;
|
|
521
|
+
|
|
522
|
+
//Check if the file extent is larger than the limit
|
|
523
|
+
//let geometry = new Extent({
|
|
524
|
+
// xmin: data?.features[0]?.geometry.bbox[0],
|
|
525
|
+
// xmax: data?.features[0]?.geometry.bbox[1],
|
|
526
|
+
// ymin: data?.features[0]?.geometry.bbox[2],
|
|
527
|
+
// ymax: data?.features[0]?.geometry.bbox[3],
|
|
528
|
+
// spatialReference: { wkid: 4326 },
|
|
529
|
+
//});
|
|
530
|
+
|
|
531
|
+
//If checkExtent returns false, add the layer to the map
|
|
532
|
+
//if (this.checkExtent(geometry)) {
|
|
533
|
+
// this.setState({
|
|
534
|
+
// showInfoPopup: true,
|
|
535
|
+
// infoPopupType: 'fullDataset',
|
|
536
|
+
// });
|
|
537
|
+
//} else {
|
|
538
|
+
this.removeFileUploadedLayer();
|
|
539
|
+
this.fileUploadLayer = csvLayer;
|
|
540
|
+
this.removeNutsLayers();
|
|
541
|
+
this.props.map.add(this.fileUploadLayer);
|
|
542
|
+
this.setState({
|
|
543
|
+
showInfoPopup: true,
|
|
544
|
+
infoPopupType: 'download',
|
|
545
|
+
});
|
|
546
|
+
//}
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
checkWkid(spatialReference) {
|
|
550
|
+
if (
|
|
551
|
+
spatialReference &&
|
|
552
|
+
spatialReference?.isWGS84 &&
|
|
553
|
+
spatialReference?.wkid === 4326
|
|
554
|
+
) {
|
|
555
|
+
return true;
|
|
556
|
+
} else {
|
|
557
|
+
this.setState({
|
|
558
|
+
showInfoPopup: true,
|
|
559
|
+
infoPopupType: 'incorrectWkid',
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
//Remove the NUTS layers from the map
|
|
565
|
+
|
|
566
|
+
removeNutsLayers() {
|
|
567
|
+
//find all the radio buttons
|
|
568
|
+
let radioButtons = document.querySelectorAll('fieldset.ccl-fieldset');
|
|
569
|
+
|
|
570
|
+
// Isolate the the checked radio button
|
|
571
|
+
let selectedRadioButton = Array.from(radioButtons).find(
|
|
572
|
+
(radioButton) => radioButton.querySelector('input').checked,
|
|
573
|
+
);
|
|
574
|
+
|
|
575
|
+
//Uncheck the selected radio button
|
|
576
|
+
if (selectedRadioButton) {
|
|
577
|
+
selectedRadioButton.querySelector('input').checked = false;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
//Remove the layers in this.nutsGroupLayer from the map
|
|
581
|
+
//this.nutsGroupLayer.removeAll();
|
|
582
|
+
this.clearWidget();
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
//Remove the uploaded layer from the map
|
|
586
|
+
|
|
587
|
+
removeFileUploadedLayer() {
|
|
588
|
+
if (this.fileUploadLayer !== null) {
|
|
589
|
+
this.props.map.removeMany(this.fileUploadLayer.layers);
|
|
590
|
+
//this.props.view.graphics.removeMany(this.fileUploadLayer.sourceGraphics);
|
|
591
|
+
this.fileUploadLayer = null;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
214
595
|
getHighestIndex() {
|
|
215
596
|
let index = 0;
|
|
216
597
|
document.querySelectorAll('.active-layer').forEach((layer) => {
|
|
@@ -396,19 +777,15 @@ class AreaWidget extends React.Component {
|
|
|
396
777
|
)
|
|
397
778
|
) {
|
|
398
779
|
layer = result.graphic;
|
|
780
|
+
return layer;
|
|
781
|
+
} else {
|
|
782
|
+
return false;
|
|
399
783
|
}
|
|
400
|
-
return layer;
|
|
401
784
|
})[0].graphic;
|
|
402
785
|
if (graphic) {
|
|
403
786
|
let geometry = graphic.geometry;
|
|
404
787
|
if (geometry.type === 'polygon') {
|
|
405
|
-
|
|
406
|
-
if ('countries'.includes(graphic.layer.id)) {
|
|
407
|
-
nuts = graphic.attributes.ISO_2DIGIT;
|
|
408
|
-
} else {
|
|
409
|
-
nuts = graphic.attributes.NUTS_ID;
|
|
410
|
-
}
|
|
411
|
-
this.props.updateArea(nuts);
|
|
788
|
+
this.props.updateArea(graphic);
|
|
412
789
|
let symbol = new SimpleFillSymbol(
|
|
413
790
|
'solid',
|
|
414
791
|
new SimpleLineSymbol('solid', new Color([232, 104, 80]), 2),
|
|
@@ -432,6 +809,9 @@ class AreaWidget extends React.Component {
|
|
|
432
809
|
});
|
|
433
810
|
}
|
|
434
811
|
});
|
|
812
|
+
//this.props.view.watch('updating', () => {
|
|
813
|
+
// console.log('graphics: ', this.props.view.graphics);
|
|
814
|
+
//});
|
|
435
815
|
|
|
436
816
|
this.props.download
|
|
437
817
|
? this.container !== null && this.props.view.ui.add(this.container)
|
|
@@ -648,6 +1028,51 @@ class AreaWidget extends React.Component {
|
|
|
648
1028
|
</div>
|
|
649
1029
|
</fieldset>
|
|
650
1030
|
</div>
|
|
1031
|
+
<br />
|
|
1032
|
+
<div className="area-header">
|
|
1033
|
+
Upload a file with your area of interest
|
|
1034
|
+
<a
|
|
1035
|
+
href="https://land.copernicus.eu/en/faq/map-viewer/how-can-i-upload-a-file-with-my-area-of-interest"
|
|
1036
|
+
target="_blank"
|
|
1037
|
+
rel="noopener noreferrer"
|
|
1038
|
+
onClick={(e) => e.stopPropagation()}
|
|
1039
|
+
onKeyDown={(e) => e.stopPropagation()}
|
|
1040
|
+
>
|
|
1041
|
+
<span className="map-menu-icon nuts-menu-icon">
|
|
1042
|
+
<FontAwesomeIcon icon={['fa', 'info-circle']} />
|
|
1043
|
+
</span>
|
|
1044
|
+
</a>
|
|
1045
|
+
</div>
|
|
1046
|
+
<div className="ccl-form">
|
|
1047
|
+
<form
|
|
1048
|
+
enctype="multipart/form-data"
|
|
1049
|
+
method="post"
|
|
1050
|
+
id="uploadForm"
|
|
1051
|
+
>
|
|
1052
|
+
<div className="field">
|
|
1053
|
+
<label className="file-upload">
|
|
1054
|
+
<span>
|
|
1055
|
+
File formats supported: shp(zip), geojson, csv
|
|
1056
|
+
</span>
|
|
1057
|
+
<input
|
|
1058
|
+
type="file"
|
|
1059
|
+
name="file"
|
|
1060
|
+
id="inFile"
|
|
1061
|
+
ref={this.fileInput}
|
|
1062
|
+
style={{ display: 'none' }}
|
|
1063
|
+
onChange={this.handleFileUpload}
|
|
1064
|
+
/>
|
|
1065
|
+
</label>
|
|
1066
|
+
</div>
|
|
1067
|
+
</form>
|
|
1068
|
+
<button
|
|
1069
|
+
className="esri-button"
|
|
1070
|
+
onClick={this.handleUploadClick}
|
|
1071
|
+
type="submit"
|
|
1072
|
+
>
|
|
1073
|
+
Upload File
|
|
1074
|
+
</button>
|
|
1075
|
+
</div>
|
|
651
1076
|
</div>
|
|
652
1077
|
</div>
|
|
653
1078
|
</div>
|
|
@@ -697,6 +1122,57 @@ class AreaWidget extends React.Component {
|
|
|
697
1122
|
</div>
|
|
698
1123
|
</>
|
|
699
1124
|
)}
|
|
1125
|
+
{this.state.infoPopupType === 'fileFormat' && (
|
|
1126
|
+
<>
|
|
1127
|
+
<span className="drawRectanglePopup-icon">
|
|
1128
|
+
<FontAwesomeIcon icon={['fas', 'info-circle']} />
|
|
1129
|
+
</span>
|
|
1130
|
+
<div className="drawRectanglePopup-text">
|
|
1131
|
+
The file format is not correct.
|
|
1132
|
+
</div>
|
|
1133
|
+
</>
|
|
1134
|
+
)}
|
|
1135
|
+
{this.state.infoPopupType === 'fileLimit' && (
|
|
1136
|
+
<>
|
|
1137
|
+
<span className="drawRectanglePopup-icon">
|
|
1138
|
+
<FontAwesomeIcon icon={['fas', 'info-circle']} />
|
|
1139
|
+
</span>
|
|
1140
|
+
<div className="drawRectanglePopup-text">
|
|
1141
|
+
Uploading files larger than 10MB is not allowed.
|
|
1142
|
+
</div>
|
|
1143
|
+
</>
|
|
1144
|
+
)}
|
|
1145
|
+
{this.state.infoPopupType === 'incorrectWkid' && (
|
|
1146
|
+
<>
|
|
1147
|
+
<span className="drawRectanglePopup-icon">
|
|
1148
|
+
<FontAwesomeIcon icon={['fas', 'info-circle']} />
|
|
1149
|
+
</span>
|
|
1150
|
+
<div className="drawRectanglePopup-text">
|
|
1151
|
+
The spatial reference is not correct.
|
|
1152
|
+
</div>
|
|
1153
|
+
</>
|
|
1154
|
+
)}
|
|
1155
|
+
{this.state.infoPopupType === 'singleFeature' && (
|
|
1156
|
+
<>
|
|
1157
|
+
<span className="drawRectanglePopup-icon">
|
|
1158
|
+
<FontAwesomeIcon icon={['fas', 'info-circle']} />
|
|
1159
|
+
</span>
|
|
1160
|
+
<div className="drawRectanglePopup-text">
|
|
1161
|
+
Uploading files with more than a single feature is not
|
|
1162
|
+
allowed.
|
|
1163
|
+
</div>
|
|
1164
|
+
</>
|
|
1165
|
+
)}
|
|
1166
|
+
{this.state.infoPopupType === 'singlePolygon' && (
|
|
1167
|
+
<>
|
|
1168
|
+
<span className="drawRectanglePopup-icon">
|
|
1169
|
+
<FontAwesomeIcon icon={['fas', 'info-circle']} />
|
|
1170
|
+
</span>
|
|
1171
|
+
<div className="drawRectanglePopup-text">
|
|
1172
|
+
Uploaded file is not a polygon geometry type.
|
|
1173
|
+
</div>
|
|
1174
|
+
</>
|
|
1175
|
+
)}
|
|
700
1176
|
</div>
|
|
701
1177
|
</div>
|
|
702
1178
|
</div>
|
|
@@ -346,7 +346,7 @@ class MapViewer extends React.Component {
|
|
|
346
346
|
renderArea() {
|
|
347
347
|
if (this.props.mapviewer_config.Download) return;
|
|
348
348
|
if (this.view) {
|
|
349
|
-
return <CheckLogin reference={this} />;
|
|
349
|
+
return <CheckLogin reference={this} urls={this.cfgUrls} />;
|
|
350
350
|
}
|
|
351
351
|
}
|
|
352
352
|
|
|
@@ -26,6 +26,7 @@ export const AddCartItem = ({
|
|
|
26
26
|
download,
|
|
27
27
|
areaData,
|
|
28
28
|
dataset,
|
|
29
|
+
handleOpenPopup,
|
|
29
30
|
}) => {
|
|
30
31
|
const { addCartItem, isLoggedIn } = useCartState();
|
|
31
32
|
|
|
@@ -48,7 +49,13 @@ export const AddCartItem = ({
|
|
|
48
49
|
} else {
|
|
49
50
|
if (areaData) {
|
|
50
51
|
area.type = 'nuts';
|
|
51
|
-
|
|
52
|
+
if (areaData.geometry.type === 'polygon') {
|
|
53
|
+
if ('countries'.includes(areaData.layer.id)) {
|
|
54
|
+
area.value = areaData.attributes.ISO_2DIGIT;
|
|
55
|
+
} else {
|
|
56
|
+
area.value = areaData.attributes.NUTS_ID;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
52
59
|
} else {
|
|
53
60
|
area = '';
|
|
54
61
|
}
|
|
@@ -67,6 +74,65 @@ export const AddCartItem = ({
|
|
|
67
74
|
}
|
|
68
75
|
});
|
|
69
76
|
};
|
|
77
|
+
const checkExtent = (e) => {
|
|
78
|
+
let intersection = false;
|
|
79
|
+
let areaExtent = null;
|
|
80
|
+
let check = document.querySelector('.area-panel input:checked').value;
|
|
81
|
+
if (check === 'area') {
|
|
82
|
+
areaExtent = new Extent({
|
|
83
|
+
xmin: Math.min(areaData.end.x, areaData.origin.x),
|
|
84
|
+
xmax: Math.max(areaData.end.x, areaData.origin.x),
|
|
85
|
+
ymin: Math.min(areaData.end.y, areaData.origin.y),
|
|
86
|
+
ymax: Math.max(areaData.end.y, areaData.origin.y),
|
|
87
|
+
});
|
|
88
|
+
} else {
|
|
89
|
+
areaExtent = areaData.geometry;
|
|
90
|
+
}
|
|
91
|
+
if (dataset?.DatasetTitle) {
|
|
92
|
+
Object.keys(props.layers).forEach((id) => {
|
|
93
|
+
if (
|
|
94
|
+
props.layers[id]?.DatasetTitle &&
|
|
95
|
+
dataset.DatasetTitle === props.layers[id].DatasetTitle
|
|
96
|
+
) {
|
|
97
|
+
let layerExtent = null;
|
|
98
|
+
if (props.layers[id].fullExtent) {
|
|
99
|
+
layerExtent = new Extent({
|
|
100
|
+
xmin: props.layers[id].fullExtent.xmin,
|
|
101
|
+
ymin: props.layers[id].fullExtent.ymin,
|
|
102
|
+
xmax: props.layers[id].fullExtent.xmax,
|
|
103
|
+
ymax: props.layers[id].fullExtent.ymax,
|
|
104
|
+
});
|
|
105
|
+
} else if (
|
|
106
|
+
props.layers[id].fullExtents &&
|
|
107
|
+
props.layers[id].fullExtents[0]
|
|
108
|
+
) {
|
|
109
|
+
layerExtent = new Extent({
|
|
110
|
+
xmin: props.layers[id].fullExtents[0].xmin,
|
|
111
|
+
ymin: props.layers[id].fullExtents[0].ymin,
|
|
112
|
+
xmax: props.layers[id].fullExtents[0].xmax,
|
|
113
|
+
ymax: props.layers[id].fullExtents[0].ymax,
|
|
114
|
+
});
|
|
115
|
+
} else {
|
|
116
|
+
layerExtent = new Extent({
|
|
117
|
+
xmin: -20037508.342789,
|
|
118
|
+
ymin: -20037508.342789,
|
|
119
|
+
xmax: 20037508.342789,
|
|
120
|
+
ymax: 20037508.342789,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
if (layerExtent.intersects(areaExtent)) {
|
|
124
|
+
intersection = true;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
if (intersection) {
|
|
129
|
+
checkArea();
|
|
130
|
+
} else {
|
|
131
|
+
e.currentTarget.appendChild(document.querySelector('.popup-container'));
|
|
132
|
+
handleOpenPopup();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
};
|
|
70
136
|
|
|
71
137
|
const checkCartData = (cartData, area, dataset) => {
|
|
72
138
|
if (!dataset) {
|
|
@@ -112,7 +178,7 @@ export const AddCartItem = ({
|
|
|
112
178
|
document.querySelector('.drawRectanglePopup-block').style
|
|
113
179
|
.display === 'none'
|
|
114
180
|
) {
|
|
115
|
-
|
|
181
|
+
checkExtent(e);
|
|
116
182
|
}
|
|
117
183
|
}
|
|
118
184
|
}}
|
|
@@ -144,7 +210,7 @@ export const AddCartItem = ({
|
|
|
144
210
|
document.querySelector('#map_area_button').click();
|
|
145
211
|
}
|
|
146
212
|
} else {
|
|
147
|
-
|
|
213
|
+
checkExtent(e);
|
|
148
214
|
}
|
|
149
215
|
}
|
|
150
216
|
}}
|
|
@@ -254,6 +320,7 @@ class MenuWidget extends React.Component {
|
|
|
254
320
|
setNoServiceModal: true,
|
|
255
321
|
TMSLayerObj: null,
|
|
256
322
|
draggedElements: [],
|
|
323
|
+
popup: false,
|
|
257
324
|
};
|
|
258
325
|
this.menuClass =
|
|
259
326
|
'esri-icon-drag-horizontal esri-widget--button esri-widget esri-interactive';
|
|
@@ -269,6 +336,7 @@ class MenuWidget extends React.Component {
|
|
|
269
336
|
this.prepareHotspotLayers = this.prepareHotspotLayers.bind(this);
|
|
270
337
|
this.activeLayersToHotspotData = this.activeLayersToHotspotData.bind(this);
|
|
271
338
|
this.getLimitScale = this.getLimitScale.bind(this);
|
|
339
|
+
this.handleOpenPopup = this.handleOpenPopup.bind(this);
|
|
272
340
|
// add zoomend listener to map to show/hide zoom in message
|
|
273
341
|
this.view.watch('stationary', (isStationary) => {
|
|
274
342
|
let snowAndIceInSessionStorage = sessionStorage.getItem('snowAndIce');
|
|
@@ -1403,6 +1471,7 @@ class MenuWidget extends React.Component {
|
|
|
1403
1471
|
download={this.props.download}
|
|
1404
1472
|
areaData={this.props.area}
|
|
1405
1473
|
dataset={dataset}
|
|
1474
|
+
handleOpenPopup={this.handleOpenPopup}
|
|
1406
1475
|
/>
|
|
1407
1476
|
) : (
|
|
1408
1477
|
<span
|
|
@@ -3062,16 +3131,6 @@ class MenuWidget extends React.Component {
|
|
|
3062
3131
|
}
|
|
3063
3132
|
});
|
|
3064
3133
|
if (layers.length === 0 && document.querySelector('.info-container')) {
|
|
3065
|
-
if (
|
|
3066
|
-
this.props.view.graphics.items.find((a) => {
|
|
3067
|
-
return a.attributes ? a.attributes.id === 'pixel-info' : false;
|
|
3068
|
-
})
|
|
3069
|
-
) {
|
|
3070
|
-
let marker = this.props.view.graphics.items.find((a) => {
|
|
3071
|
-
return a.attributes && a.attributes.id === 'pixel-info';
|
|
3072
|
-
});
|
|
3073
|
-
this.props.view.graphics.remove(marker);
|
|
3074
|
-
}
|
|
3075
3134
|
if (
|
|
3076
3135
|
this.props.mapViewer.activeWidget?.container.current.className ===
|
|
3077
3136
|
'info-container esri-component'
|
|
@@ -3758,6 +3817,23 @@ class MenuWidget extends React.Component {
|
|
|
3758
3817
|
}, 100);
|
|
3759
3818
|
}
|
|
3760
3819
|
}
|
|
3820
|
+
handleOpenPopup = () => {
|
|
3821
|
+
clearTimeout(this.timeout);
|
|
3822
|
+
this.setState({
|
|
3823
|
+
popup: true,
|
|
3824
|
+
});
|
|
3825
|
+
|
|
3826
|
+
this.timeout = setTimeout(() => {
|
|
3827
|
+
this.handleClosePopup();
|
|
3828
|
+
}, 2000);
|
|
3829
|
+
};
|
|
3830
|
+
|
|
3831
|
+
handleClosePopup = () => {
|
|
3832
|
+
this.setState({
|
|
3833
|
+
popup: false,
|
|
3834
|
+
});
|
|
3835
|
+
clearTimeout(this.timeout);
|
|
3836
|
+
};
|
|
3761
3837
|
|
|
3762
3838
|
/**
|
|
3763
3839
|
* This method renders the component
|
|
@@ -3768,6 +3844,15 @@ class MenuWidget extends React.Component {
|
|
|
3768
3844
|
<>
|
|
3769
3845
|
<div ref={this.container} className="map-left-menu-container">
|
|
3770
3846
|
<div className="map-menu tab-container" id="tabcontainer">
|
|
3847
|
+
<Popup
|
|
3848
|
+
type={'info'}
|
|
3849
|
+
open={this.state.popup}
|
|
3850
|
+
position="right center"
|
|
3851
|
+
trigger={<div className="popup-container"></div>}
|
|
3852
|
+
offset={[0, 20]}
|
|
3853
|
+
>
|
|
3854
|
+
{'No data available on the selected area'}
|
|
3855
|
+
</Popup>
|
|
3771
3856
|
<div className="tabs" role="tablist">
|
|
3772
3857
|
<span
|
|
3773
3858
|
className={!this.props.download ? 'tab tab-selected' : 'tab'}
|
|
@@ -3874,6 +3959,7 @@ class MenuWidget extends React.Component {
|
|
|
3874
3959
|
mapViewer={this.props.mapViewer}
|
|
3875
3960
|
download={this.props.download}
|
|
3876
3961
|
areaData={this.props.area}
|
|
3962
|
+
handleOpenPopup={this.handleOpenPopup}
|
|
3877
3963
|
/>
|
|
3878
3964
|
</div>
|
|
3879
3965
|
)}
|
|
@@ -246,6 +246,7 @@ const config = {
|
|
|
246
246
|
'https://gisco-services.ec.europa.eu/maps/wmts/CountriesWorld/EPSG3857/0/0/0.png',
|
|
247
247
|
countriesWorldTemplate:
|
|
248
248
|
'https://gisco-services.ec.europa.eu/maps/tiles/CountriesWorld/EPSG3857/{z}/{x}/{y}.png',
|
|
249
|
+
uploadPortal: 'https://www.arcgis.com',
|
|
249
250
|
},
|
|
250
251
|
};
|
|
251
252
|
export default config;
|
|
@@ -352,6 +352,21 @@ div.esri-popover
|
|
|
352
352
|
label.ccl-form-radio-label span.nuts-menu-icon {
|
|
353
353
|
margin-left: 9rem;
|
|
354
354
|
}
|
|
355
|
+
|
|
356
|
+
.area-container .esri-button {
|
|
357
|
+
border-color: #a0b128;
|
|
358
|
+
margin-left: 0.25rem;
|
|
359
|
+
background-color: #a0b128;
|
|
360
|
+
color: white !important;
|
|
361
|
+
transition: all 0.3s ease-out;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
.area-container .esri-button:hover {
|
|
365
|
+
border-color: #a0b128;
|
|
366
|
+
background-color: white;
|
|
367
|
+
color: #a0b128 !important;
|
|
368
|
+
}
|
|
369
|
+
|
|
355
370
|
/* Left menu */
|
|
356
371
|
.map-menu {
|
|
357
372
|
position: relative;
|
|
@@ -1367,7 +1382,7 @@ input[type='range']::-ms-track {
|
|
|
1367
1382
|
display: flex;
|
|
1368
1383
|
width: 19rem;
|
|
1369
1384
|
height: 60px;
|
|
1370
|
-
justify-content: space-
|
|
1385
|
+
justify-content: space-around;
|
|
1371
1386
|
padding: 0.6rem 0.8rem 0.8rem 0.8rem;
|
|
1372
1387
|
background-color: white;
|
|
1373
1388
|
}
|
|
@@ -1381,6 +1396,7 @@ input[type='range']::-ms-track {
|
|
|
1381
1396
|
}
|
|
1382
1397
|
|
|
1383
1398
|
.drawRectanglePopup-text {
|
|
1399
|
+
flex: auto;
|
|
1384
1400
|
font-family: 'Lato', sans-serif;
|
|
1385
1401
|
font-size: 0.875rem;
|
|
1386
1402
|
}
|