@eeacms/volto-arcgis-block 0.1.290 → 0.1.292
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 +11 -0
- package/package.json +1 -1
- package/src/components/MapViewer/AreaWidget.jsx +219 -63
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,17 @@ 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.292](https://github.com/eea/volto-arcgis-block/compare/0.1.291...0.1.292) - 28 June 2024
|
|
8
|
+
|
|
9
|
+
#### :hammer_and_wrench: Others
|
|
10
|
+
|
|
11
|
+
- CLMS-3254 (task): clean console statements. [Unai Bolivar - [`7058e29`](https://github.com/eea/volto-arcgis-block/commit/7058e293a6c546496035875bfda1348e3fb97e45)]
|
|
12
|
+
- CLMS-3254 (task): added CSV to file formats supported span text at the bottom of the area widget [Unai Bolivar - [`96fedac`](https://github.com/eea/volto-arcgis-block/commit/96fedac5bf59edba736d56c75b4c467e8f261416)]
|
|
13
|
+
- CLMS-3254 (feat): Completed CSV file upload [Unai Bolivar - [`b828893`](https://github.com/eea/volto-arcgis-block/commit/b828893edc8b147f779b79ed33935b9ab253bf48)]
|
|
14
|
+
- CLMS-3254 (feat): Checking layer for extent and wkid [Unai Bolivar - [`cf6468a`](https://github.com/eea/volto-arcgis-block/commit/cf6468af5ede54807160be32449e7ecdbcfed819)]
|
|
15
|
+
- CLMS-3254 (feat): CSV file upload renders points on map. [Unai Bolivar - [`abf28d1`](https://github.com/eea/volto-arcgis-block/commit/abf28d1c68580623113a059e15b0dd92a7535118)]
|
|
16
|
+
### [0.1.291](https://github.com/eea/volto-arcgis-block/compare/0.1.290...0.1.291) - 20 June 2024
|
|
17
|
+
|
|
7
18
|
### [0.1.290](https://github.com/eea/volto-arcgis-block/compare/0.1.289...0.1.290) - 19 June 2024
|
|
8
19
|
|
|
9
20
|
### [0.1.289](https://github.com/eea/volto-arcgis-block/compare/0.1.288...0.1.289) - 18 June 2024
|
package/package.json
CHANGED
|
@@ -13,7 +13,8 @@ var Graphic,
|
|
|
13
13
|
request,
|
|
14
14
|
SimpleLineSymbol,
|
|
15
15
|
SimpleFillSymbol,
|
|
16
|
-
SpatialReference
|
|
16
|
+
SpatialReference,
|
|
17
|
+
Polygon;
|
|
17
18
|
|
|
18
19
|
class AreaWidget extends React.Component {
|
|
19
20
|
/**
|
|
@@ -65,6 +66,7 @@ class AreaWidget extends React.Component {
|
|
|
65
66
|
'esri/symbols/SimpleLineSymbol',
|
|
66
67
|
'esri/symbols/SimpleFillSymbol',
|
|
67
68
|
'esri/geometry/SpatialReference',
|
|
69
|
+
'esri/geometry/Polygon',
|
|
68
70
|
]).then(
|
|
69
71
|
([
|
|
70
72
|
_Graphic,
|
|
@@ -79,6 +81,7 @@ class AreaWidget extends React.Component {
|
|
|
79
81
|
_SimpleLineSymbol,
|
|
80
82
|
_SimpleFillSymbol,
|
|
81
83
|
_SpatialReference,
|
|
84
|
+
_Polygon,
|
|
82
85
|
]) => {
|
|
83
86
|
[
|
|
84
87
|
Graphic,
|
|
@@ -93,6 +96,7 @@ class AreaWidget extends React.Component {
|
|
|
93
96
|
SimpleLineSymbol,
|
|
94
97
|
SimpleFillSymbol,
|
|
95
98
|
SpatialReference,
|
|
99
|
+
Polygon,
|
|
96
100
|
] = [
|
|
97
101
|
_Graphic,
|
|
98
102
|
_Extent,
|
|
@@ -106,6 +110,7 @@ class AreaWidget extends React.Component {
|
|
|
106
110
|
_SimpleLineSymbol,
|
|
107
111
|
_SimpleFillSymbol,
|
|
108
112
|
_SpatialReference,
|
|
113
|
+
_Polygon,
|
|
109
114
|
];
|
|
110
115
|
},
|
|
111
116
|
);
|
|
@@ -212,7 +217,7 @@ class AreaWidget extends React.Component {
|
|
|
212
217
|
if (document.querySelector('#download_prepackage').checked) {
|
|
213
218
|
this.setState({
|
|
214
219
|
showInfoPopup: true,
|
|
215
|
-
infoPopupType: '
|
|
220
|
+
infoPopupType: 'prepackage',
|
|
216
221
|
});
|
|
217
222
|
} else {
|
|
218
223
|
this.setState({
|
|
@@ -292,6 +297,7 @@ class AreaWidget extends React.Component {
|
|
|
292
297
|
// FILE UPLOAD HANDLERS
|
|
293
298
|
|
|
294
299
|
// Trigger the file input click
|
|
300
|
+
|
|
295
301
|
handleUploadClick = (event) => {
|
|
296
302
|
event.preventDefault();
|
|
297
303
|
this.fileInput.current.click();
|
|
@@ -299,19 +305,31 @@ class AreaWidget extends React.Component {
|
|
|
299
305
|
|
|
300
306
|
handleFileUpload = (e) => {
|
|
301
307
|
//Get the file name
|
|
308
|
+
|
|
302
309
|
const fileName = e.target.value.toLowerCase();
|
|
303
310
|
|
|
304
311
|
//Get the file size
|
|
312
|
+
|
|
305
313
|
const fileSize = e.target.files[0].size;
|
|
306
314
|
|
|
307
315
|
//Get the file from the form
|
|
316
|
+
|
|
308
317
|
const file = document.getElementById('uploadForm');
|
|
309
318
|
|
|
319
|
+
//Get the file blob
|
|
320
|
+
|
|
321
|
+
const fileBlob = e.target.files[0];
|
|
322
|
+
|
|
323
|
+
//Create a new file reader
|
|
324
|
+
|
|
325
|
+
let reader = new FileReader();
|
|
326
|
+
|
|
310
327
|
//List allowed file extensions
|
|
311
328
|
|
|
312
|
-
let fileExtensions = ['zip', 'geojson'];
|
|
329
|
+
let fileExtensions = ['zip', 'geojson', 'csv'];
|
|
313
330
|
|
|
314
331
|
// Get the file extension
|
|
332
|
+
|
|
315
333
|
let fileExtension = fileName.split('.').pop();
|
|
316
334
|
|
|
317
335
|
//Check if the file format is not supported
|
|
@@ -324,10 +342,13 @@ class AreaWidget extends React.Component {
|
|
|
324
342
|
return;
|
|
325
343
|
}
|
|
326
344
|
|
|
327
|
-
// Check if the file is
|
|
345
|
+
// Check if the file format is geojson or csv and the file size is over the 10mb file size limit
|
|
328
346
|
// or file is a shape file and the file size is over the 2mb file size limit
|
|
329
347
|
|
|
330
|
-
if (
|
|
348
|
+
if (
|
|
349
|
+
fileSize > 10485760 &&
|
|
350
|
+
(fileExtension === 'geojson' || fileExtension === 'csv')
|
|
351
|
+
) {
|
|
331
352
|
this.setState({
|
|
332
353
|
showInfoPopup: true,
|
|
333
354
|
infoPopupType: 'fileLimit',
|
|
@@ -350,14 +371,17 @@ class AreaWidget extends React.Component {
|
|
|
350
371
|
case 'geojson':
|
|
351
372
|
this.generateFeatureCollection(fileName, file, 'geojson');
|
|
352
373
|
break;
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
374
|
+
case 'csv':
|
|
375
|
+
//this.generateFeatureCollection(
|
|
376
|
+
// fileName,
|
|
377
|
+
// file,
|
|
378
|
+
// 'csv',
|
|
379
|
+
//);
|
|
380
|
+
reader.readAsText(fileBlob);
|
|
381
|
+
reader.onload = () => {
|
|
382
|
+
this.handleCsv(reader.result);
|
|
383
|
+
};
|
|
384
|
+
break;
|
|
361
385
|
default:
|
|
362
386
|
break;
|
|
363
387
|
}
|
|
@@ -580,7 +604,7 @@ class AreaWidget extends React.Component {
|
|
|
580
604
|
|
|
581
605
|
//Display CSV on the map
|
|
582
606
|
|
|
583
|
-
handleCsv(data) {
|
|
607
|
+
async handleCsv(data) {
|
|
584
608
|
//Create a CSV layer
|
|
585
609
|
const blob = new Blob([data], {
|
|
586
610
|
type: 'plain/text',
|
|
@@ -594,50 +618,157 @@ class AreaWidget extends React.Component {
|
|
|
594
618
|
title: 'uploadLayer',
|
|
595
619
|
});
|
|
596
620
|
|
|
597
|
-
//
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
//});
|
|
613
|
-
//Check if the file has the correct spatial reference
|
|
614
|
-
if (this.checkWkid(csvLayer?.spatialReference) === false) return;
|
|
615
|
-
|
|
616
|
-
//Check if the file extent is larger than the limit
|
|
617
|
-
//let geometry = new Extent({
|
|
618
|
-
// xmin: data?.features[0]?.geometry.bbox[0],
|
|
619
|
-
// xmax: data?.features[0]?.geometry.bbox[1],
|
|
620
|
-
// ymin: data?.features[0]?.geometry.bbox[2],
|
|
621
|
-
// ymax: data?.features[0]?.geometry.bbox[3],
|
|
622
|
-
// spatialReference: { wkid: 4326 },
|
|
623
|
-
//});
|
|
621
|
+
// Set a simple renderer on the layer
|
|
622
|
+
|
|
623
|
+
csvLayer.renderer = {
|
|
624
|
+
type: 'simple', // autocasts as new SimpleRenderer()
|
|
625
|
+
symbol: {
|
|
626
|
+
type: 'simple-marker', // autocasts as new SimpleMarkerSymbol()
|
|
627
|
+
size: 6,
|
|
628
|
+
color: 'black',
|
|
629
|
+
outline: {
|
|
630
|
+
// autocasts as new SimpleLineSymbol()
|
|
631
|
+
width: 0.5,
|
|
632
|
+
color: 'white',
|
|
633
|
+
},
|
|
634
|
+
},
|
|
635
|
+
};
|
|
624
636
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
//
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
637
|
+
let csvFeatures, csvFeatureCount, csvExtent;
|
|
638
|
+
|
|
639
|
+
//Query the CSV layer
|
|
640
|
+
|
|
641
|
+
try {
|
|
642
|
+
await csvLayer.load();
|
|
643
|
+
const results = await Promise.all([
|
|
644
|
+
csvLayer.queryFeatures(),
|
|
645
|
+
csvLayer.queryFeatureCount(),
|
|
646
|
+
csvLayer.queryExtent(),
|
|
647
|
+
]);
|
|
648
|
+
|
|
649
|
+
csvFeatures = results[0];
|
|
650
|
+
csvFeatureCount = results[1];
|
|
651
|
+
csvExtent = results[2];
|
|
652
|
+
|
|
653
|
+
//Check if the file has the correct spatial reference
|
|
654
|
+
|
|
655
|
+
if (this.checkWkid(csvLayer?.spatialReference) === false) return;
|
|
656
|
+
|
|
657
|
+
//Check if the file extent is larger than the limit
|
|
658
|
+
//If checkExtent() is false, add the layer to the map
|
|
659
|
+
|
|
660
|
+
if (this.checkExtent(csvExtent.extent)) {
|
|
661
|
+
this.setState({
|
|
662
|
+
showInfoPopup: true,
|
|
663
|
+
infoPopupType: 'fullDataset',
|
|
664
|
+
});
|
|
665
|
+
} else {
|
|
666
|
+
//Draw a polygon around of the CSVlayer Features data
|
|
667
|
+
|
|
668
|
+
let allRings = [];
|
|
669
|
+
let currentRing = [];
|
|
670
|
+
let startingPoint = null;
|
|
671
|
+
|
|
672
|
+
for (let i = 0; i < csvFeatureCount; i++) {
|
|
673
|
+
const currentPoint = [
|
|
674
|
+
csvFeatures.features[i].geometry.x,
|
|
675
|
+
csvFeatures.features[i].geometry.y,
|
|
676
|
+
];
|
|
677
|
+
if (!startingPoint) {
|
|
678
|
+
startingPoint = currentPoint;
|
|
679
|
+
currentRing.push(currentPoint);
|
|
680
|
+
} else if (
|
|
681
|
+
startingPoint[0] === currentPoint[0] &&
|
|
682
|
+
startingPoint[1] === currentPoint[1]
|
|
683
|
+
) {
|
|
684
|
+
allRings.push(currentRing);
|
|
685
|
+
currentRing = [];
|
|
686
|
+
startingPoint = null;
|
|
687
|
+
} else {
|
|
688
|
+
currentRing.push(currentPoint);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
if (currentRing.length > 0) {
|
|
693
|
+
allRings.push(currentRing);
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
let idPolygon = new Polygon({
|
|
697
|
+
isSelfIntersecting: false,
|
|
698
|
+
rings: allRings,
|
|
699
|
+
spatialReference: csvExtent.spatialReference,
|
|
700
|
+
//set type as multi polygon
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
//Draw a graphic using the polyId polygon data as the geometry
|
|
704
|
+
|
|
705
|
+
const polygonSymbol = {
|
|
706
|
+
type: 'simple-fill', // autocasts as new SimpleFillSymbol()
|
|
707
|
+
color: [234, 168, 72, 0.8],
|
|
708
|
+
outline: {
|
|
709
|
+
// autocasts as new SimpleLineSymbol()
|
|
710
|
+
color: '#000000',
|
|
711
|
+
width: 0.1,
|
|
712
|
+
},
|
|
713
|
+
};
|
|
714
|
+
|
|
715
|
+
let polygonGraphic = new Graphic({
|
|
716
|
+
geometry: idPolygon,
|
|
717
|
+
symbol: polygonSymbol,
|
|
718
|
+
});
|
|
719
|
+
|
|
720
|
+
//Clear any previously saved file upload data and save the uploaded layer to the component props for reference
|
|
721
|
+
|
|
722
|
+
this.removeFileUploadedLayer();
|
|
723
|
+
this.fileUploadLayer = {
|
|
724
|
+
layers: CSVLayer,
|
|
725
|
+
sourceGraphics: polygonGraphic,
|
|
726
|
+
};
|
|
727
|
+
|
|
728
|
+
//Clean the map before adding the graphic
|
|
729
|
+
|
|
730
|
+
this.removeNutsLayers();
|
|
731
|
+
|
|
732
|
+
//Add the polygon graphic to the map
|
|
733
|
+
|
|
734
|
+
this.props.view.graphics.add(polygonGraphic);
|
|
735
|
+
//this.props.map.add(this.fileUploadLayer);
|
|
736
|
+
|
|
737
|
+
//Refresh the map view
|
|
738
|
+
|
|
739
|
+
this.props.view.goTo(polygonGraphic).catch((error) => {
|
|
740
|
+
//console.error('From handleCsv function', error);
|
|
741
|
+
});
|
|
742
|
+
|
|
743
|
+
//Send the area to the parent component
|
|
744
|
+
|
|
745
|
+
this.props.updateArea({
|
|
746
|
+
origin: { x: csvExtent.extent.xmin, y: csvExtent.extent.ymin },
|
|
747
|
+
end: { x: csvExtent.extent.xmax, y: csvExtent.extent.ymax },
|
|
748
|
+
});
|
|
749
|
+
|
|
750
|
+
//re order the layer in the map
|
|
751
|
+
|
|
752
|
+
let index = this.getHighestIndex();
|
|
753
|
+
this.props.map.reorder(polygonGraphic, index + 1);
|
|
754
|
+
|
|
755
|
+
//Refresh the map view
|
|
756
|
+
|
|
757
|
+
this.setState({
|
|
758
|
+
showInfoPopup: true,
|
|
759
|
+
infoPopupType: 'download',
|
|
760
|
+
});
|
|
761
|
+
|
|
762
|
+
//Save file upload layer to session storage as a tag for adding item to cart action
|
|
763
|
+
|
|
764
|
+
sessionStorage.setItem(
|
|
765
|
+
'fileUploadLayer',
|
|
766
|
+
JSON.stringify(this.fileUploadLayer),
|
|
767
|
+
);
|
|
768
|
+
}
|
|
769
|
+
} catch (error) {
|
|
770
|
+
//console.error('Error: ', error);
|
|
771
|
+
}
|
|
641
772
|
}
|
|
642
773
|
|
|
643
774
|
checkWkid(spatialReference) {
|
|
@@ -851,7 +982,9 @@ class AreaWidget extends React.Component {
|
|
|
851
982
|
'none';
|
|
852
983
|
}
|
|
853
984
|
areaSearch() {
|
|
854
|
-
let searchText = document
|
|
985
|
+
let searchText = document
|
|
986
|
+
.querySelector('#area-searchtext')
|
|
987
|
+
.value.toUpperCase();
|
|
855
988
|
if (searchText.length <= 2) {
|
|
856
989
|
this.loadNutsService('nuts0', [0]);
|
|
857
990
|
this.loadCountriesService('nuts0');
|
|
@@ -872,15 +1005,25 @@ class AreaWidget extends React.Component {
|
|
|
872
1005
|
}
|
|
873
1006
|
let found = false;
|
|
874
1007
|
let count = this.nutsGroupLayer.layers.items.length;
|
|
875
|
-
const queryParams = this.nutsGroupLayer.layers.items[0].createQuery();
|
|
876
|
-
queryParams.where = `(NUTS_ID = '${searchText}')`;
|
|
877
|
-
queryParams.outSpatialReference = this.props.view.spatialReference;
|
|
878
1008
|
document.querySelector('.no-result-message').style.display = 'none';
|
|
879
1009
|
this.nutsGroupLayer.layers.items.forEach((item) => {
|
|
1010
|
+
const queryParams = item.createQuery();
|
|
1011
|
+
if (
|
|
1012
|
+
item.url ===
|
|
1013
|
+
'https://land.discomap.eea.europa.eu/arcgis/rest/services/CLMS_Portal/World_countries_except_EU37/MapServer'
|
|
1014
|
+
) {
|
|
1015
|
+
queryParams.where = `(ISO_2DIGIT = '${searchText}')`;
|
|
1016
|
+
} else {
|
|
1017
|
+
queryParams.where = `(NUTS_ID = '${searchText}')`;
|
|
1018
|
+
}
|
|
1019
|
+
queryParams.outSpatialReference = this.props.view.spatialReference;
|
|
880
1020
|
item.queryFeatures(queryParams).then((response) => {
|
|
881
1021
|
count = count - 1;
|
|
882
1022
|
response.features.forEach((feature) => {
|
|
883
|
-
if (
|
|
1023
|
+
if (
|
|
1024
|
+
feature.attributes.NUTS_ID === searchText ||
|
|
1025
|
+
feature.attributes.ISO_2DIGIT === searchText
|
|
1026
|
+
) {
|
|
884
1027
|
found = true;
|
|
885
1028
|
this.props.updateArea(feature);
|
|
886
1029
|
let symbol = new SimpleFillSymbol(
|
|
@@ -1278,7 +1421,9 @@ class AreaWidget extends React.Component {
|
|
|
1278
1421
|
>
|
|
1279
1422
|
<div className="field">
|
|
1280
1423
|
<label className="file-upload">
|
|
1281
|
-
<span>
|
|
1424
|
+
<span>
|
|
1425
|
+
File formats supported: shp(zip), geojson, CSV
|
|
1426
|
+
</span>
|
|
1282
1427
|
<input
|
|
1283
1428
|
type="file"
|
|
1284
1429
|
name="file"
|
|
@@ -1327,6 +1472,17 @@ class AreaWidget extends React.Component {
|
|
|
1327
1472
|
</div>
|
|
1328
1473
|
</>
|
|
1329
1474
|
)}
|
|
1475
|
+
{this.state.infoPopupType === 'prepackage' && (
|
|
1476
|
+
<>
|
|
1477
|
+
<span className="drawRectanglePopup-icon">
|
|
1478
|
+
<FontAwesomeIcon icon={['fas', 'download']} />
|
|
1479
|
+
</span>
|
|
1480
|
+
<div className="drawRectanglePopup-text">
|
|
1481
|
+
Click on the download icon on “Products and datasets” to
|
|
1482
|
+
continue
|
|
1483
|
+
</div>
|
|
1484
|
+
</>
|
|
1485
|
+
)}
|
|
1330
1486
|
{this.state.infoPopupType === 'fullDataset' && (
|
|
1331
1487
|
<>
|
|
1332
1488
|
<span className="drawRectanglePopup-icon">
|