@eeacms/volto-arcgis-block 0.1.30 → 0.1.31
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
CHANGED
|
@@ -4,8 +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.31](https://github.com/eea/volto-arcgis-block/compare/0.1.30...0.1.31)
|
|
8
|
+
|
|
9
|
+
- First commit [`#97`](https://github.com/eea/volto-arcgis-block/pull/97)
|
|
10
|
+
- REFACT: Delete comments [`a7a9296`](https://github.com/eea/volto-arcgis-block/commit/a7a929647749280ccf92d97ea17a3d743f1cfa20)
|
|
11
|
+
- FIX: Watch event on Time Extent for props and services. TimeSlider disabled if no time dimension [`2af7f50`](https://github.com/eea/volto-arcgis-block/commit/2af7f50d2ae1d5e033606d690bab0dffaa83b79e)
|
|
12
|
+
|
|
7
13
|
#### [0.1.30](https://github.com/eea/volto-arcgis-block/compare/0.1.29...0.1.30)
|
|
8
14
|
|
|
15
|
+
> 10 February 2022
|
|
16
|
+
|
|
17
|
+
- Develop [`#99`](https://github.com/eea/volto-arcgis-block/pull/99)
|
|
9
18
|
- Bugs n improvements [`#98`](https://github.com/eea/volto-arcgis-block/pull/98)
|
|
10
19
|
- ESLint fix [`4b23a15`](https://github.com/eea/volto-arcgis-block/commit/4b23a15d924a671ded144b453d5864884394a277)
|
|
11
20
|
- Download functionality [`457fddd`](https://github.com/eea/volto-arcgis-block/commit/457fdddac4082d9706458d0a9421e64fca1e6ab6)
|
package/package.json
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React, { createRef } from 'react';
|
|
2
2
|
import { loadModules } from 'esri-loader';
|
|
3
3
|
var TimeSlider;
|
|
4
|
+
var TimeExtent;
|
|
5
|
+
var timeDict = {};
|
|
4
6
|
|
|
5
7
|
class TimesliderWidget extends React.Component {
|
|
6
8
|
/**
|
|
@@ -19,15 +21,175 @@ class TimesliderWidget extends React.Component {
|
|
|
19
21
|
};
|
|
20
22
|
this.map = this.props.map;
|
|
21
23
|
this.layer = this.props.layer;
|
|
24
|
+
if (this.layer.type === 'feature') {
|
|
25
|
+
this.layerName = this.layer.id; //FEATURE
|
|
26
|
+
} else if (this.layer.type === 'wms') {
|
|
27
|
+
this.layerName = this.layer.sublayers.items[0].name;
|
|
28
|
+
} else if (this.layer.type === 'wmts') {
|
|
29
|
+
this.layerName = this.layer.activeLayer.id; //WMTS
|
|
30
|
+
}
|
|
22
31
|
this.drag = {};
|
|
23
32
|
}
|
|
24
33
|
|
|
25
34
|
loader() {
|
|
26
|
-
return loadModules(['esri/widgets/TimeSlider']).then(
|
|
27
|
-
[
|
|
28
|
-
|
|
35
|
+
return loadModules(['esri/widgets/TimeSlider', 'esri/TimeExtent']).then(
|
|
36
|
+
([_TimeSlider, _TimeExtent]) => {
|
|
37
|
+
[TimeSlider] = [_TimeSlider];
|
|
38
|
+
[TimeExtent] = [_TimeExtent];
|
|
39
|
+
},
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
xmlToJson(xml) {
|
|
44
|
+
// Create the return object
|
|
45
|
+
var obj = {};
|
|
46
|
+
|
|
47
|
+
if (xml.nodeType === 1) {
|
|
48
|
+
// element
|
|
49
|
+
// do attributes
|
|
50
|
+
if (xml.attributes.length > 0) {
|
|
51
|
+
obj['@attributes'] = {};
|
|
52
|
+
for (var j = 0; j < xml.attributes.length; j++) {
|
|
53
|
+
var attribute = xml.attributes.item(j);
|
|
54
|
+
obj['@attributes'][attribute.nodeName] = attribute.nodeValue;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
} else if (xml.nodeType === 3) {
|
|
58
|
+
// text
|
|
59
|
+
obj = xml.nodeValue;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// do children
|
|
63
|
+
if (xml.hasChildNodes()) {
|
|
64
|
+
for (var i = 0; i < xml.childNodes.length; i++) {
|
|
65
|
+
var item = xml.childNodes.item(i);
|
|
66
|
+
var nodeName = item.nodeName;
|
|
67
|
+
if (typeof obj[nodeName] == 'undefined') {
|
|
68
|
+
obj[nodeName] = this.xmlToJson(item);
|
|
69
|
+
} else {
|
|
70
|
+
if (typeof obj[nodeName].push == 'undefined') {
|
|
71
|
+
var old = obj[nodeName];
|
|
72
|
+
obj[nodeName] = [];
|
|
73
|
+
obj[nodeName].push(old);
|
|
74
|
+
}
|
|
75
|
+
obj[nodeName].push(this.xmlToJson(item));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return obj;
|
|
29
80
|
}
|
|
30
81
|
|
|
82
|
+
getTime(esriLayer, layerName) {
|
|
83
|
+
let getCapabilitiesUrl = '';
|
|
84
|
+
|
|
85
|
+
if (esriLayer.type === 'wms') {
|
|
86
|
+
// WMS
|
|
87
|
+
getCapabilitiesUrl =
|
|
88
|
+
esriLayer.url + '?request=GetCapabilities&service=WMS';
|
|
89
|
+
return fetch(getCapabilitiesUrl)
|
|
90
|
+
.then((response) => response.text())
|
|
91
|
+
.then((str) => new window.DOMParser().parseFromString(str, 'text/xml'))
|
|
92
|
+
.then((data) => {
|
|
93
|
+
let cap = this.xmlToJson(data);
|
|
94
|
+
let layers = cap.WMS_Capabilities.Capability.Layer.Layer;
|
|
95
|
+
|
|
96
|
+
let layerMetadata = {};
|
|
97
|
+
if (Array.isArray(layers)) {
|
|
98
|
+
layerMetadata = layers.filter(
|
|
99
|
+
(l) => l['Name']['#text'] === layerName,
|
|
100
|
+
)[0];
|
|
101
|
+
} else {
|
|
102
|
+
layerMetadata = layers;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
if (layerMetadata.hasOwnProperty('Dimension')) {
|
|
106
|
+
const timeString = layerMetadata.Dimension['#text'];
|
|
107
|
+
return this.parserTimeDimensionWMS(timeString);
|
|
108
|
+
} else {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
} else if (esriLayer.type === 'wmts') {
|
|
113
|
+
// WMTS
|
|
114
|
+
getCapabilitiesUrl =
|
|
115
|
+
esriLayer.url + '?request=GetCapabilities&service=WMTS';
|
|
116
|
+
|
|
117
|
+
return fetch(getCapabilitiesUrl)
|
|
118
|
+
.then((response) => response.text())
|
|
119
|
+
.then((str) => new window.DOMParser().parseFromString(str, 'text/xml'))
|
|
120
|
+
.then((data) => {
|
|
121
|
+
let cap = this.xmlToJson(data);
|
|
122
|
+
let layers = cap.Capabilities.Contents.Layer;
|
|
123
|
+
let layerMetadata = {};
|
|
124
|
+
|
|
125
|
+
if (Array.isArray(layers)) {
|
|
126
|
+
layerMetadata = layers.filter(
|
|
127
|
+
(l) => l['ows:Identifier']['#text'] === layerName,
|
|
128
|
+
)[0];
|
|
129
|
+
} else {
|
|
130
|
+
layerMetadata = layers;
|
|
131
|
+
}
|
|
132
|
+
if (layerMetadata.hasOwnProperty('Dimension')) {
|
|
133
|
+
return this.parserTimeDimensionWMTileS(
|
|
134
|
+
layerMetadata.Dimension.Value,
|
|
135
|
+
);
|
|
136
|
+
} else {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
} // getTime
|
|
142
|
+
|
|
143
|
+
parserTimeDimensionWMS(timeString) {
|
|
144
|
+
if (timeString.includes('/P')) {
|
|
145
|
+
const [startDate, endDate, period] = timeString
|
|
146
|
+
.replace(/\s/g, '')
|
|
147
|
+
.split('/');
|
|
148
|
+
return {
|
|
149
|
+
start: startDate,
|
|
150
|
+
end: endDate,
|
|
151
|
+
period: period,
|
|
152
|
+
};
|
|
153
|
+
} else if (timeString.includes(',')) {
|
|
154
|
+
const datesArray = timeString.replace(/\s/g, '').split(',');
|
|
155
|
+
return { array: datesArray.map((e) => e) };
|
|
156
|
+
}
|
|
157
|
+
} // parserTimeDimensionWMS
|
|
158
|
+
|
|
159
|
+
parserTimeDimensionWMTileS(timeString) {
|
|
160
|
+
// [ TO CHECK ] cambiar timeString por un nombre de variable mas entendible
|
|
161
|
+
if (timeString.includes('/P')) {
|
|
162
|
+
const [startDate, endDate, period] = timeString
|
|
163
|
+
.replace(/\s/g, '')
|
|
164
|
+
.split('/');
|
|
165
|
+
return {
|
|
166
|
+
start: startDate,
|
|
167
|
+
end: endDate,
|
|
168
|
+
period: period,
|
|
169
|
+
};
|
|
170
|
+
} else if (Array.isArray(timeString)) {
|
|
171
|
+
const datesArray = timeString.map((e) => e['#text'].replace(/\s/g, ''));
|
|
172
|
+
return { array: datesArray };
|
|
173
|
+
}
|
|
174
|
+
} // parserTimeDimensionWMTS
|
|
175
|
+
|
|
176
|
+
parserPeriod(iso8601Duration) {
|
|
177
|
+
var iso8601DurationRegex = /(-)?P(?:([.,\d]+)Y)?(?:([.,\d]+)M)?(?:([.,\d]+)W)?(?:([.,\d]+)D)?T?(?:([.,\d]+)H)?(?:([.,\d]+)M)?(?:([.,\d]+)S)?/;
|
|
178
|
+
|
|
179
|
+
var matches = iso8601Duration.match(iso8601DurationRegex);
|
|
180
|
+
|
|
181
|
+
return {
|
|
182
|
+
sign: matches[1] === undefined ? '+' : '-',
|
|
183
|
+
years: parseInt(matches[2] === undefined ? 0 : matches[2]),
|
|
184
|
+
months: parseInt(matches[3] === undefined ? 0 : matches[3]),
|
|
185
|
+
weeks: parseInt(matches[4] === undefined ? 0 : matches[4]),
|
|
186
|
+
days: parseInt(matches[5] === undefined ? 0 : matches[5]),
|
|
187
|
+
hours: parseInt(matches[6] === undefined ? 0 : matches[6]),
|
|
188
|
+
minutes: parseInt(matches[7] === undefined ? 0 : matches[7]),
|
|
189
|
+
seconds: parseFloat(matches[8] === undefined ? 0 : matches[8]),
|
|
190
|
+
};
|
|
191
|
+
} // parserPeriod
|
|
192
|
+
|
|
31
193
|
/**
|
|
32
194
|
* This method is executed after the rener method is executed
|
|
33
195
|
*/
|
|
@@ -48,32 +210,99 @@ class TimesliderWidget extends React.Component {
|
|
|
48
210
|
this.props.view.ui.add(this.container.current, 'bottom-right');
|
|
49
211
|
this.container.current.style.display = 'block';
|
|
50
212
|
|
|
51
|
-
this.props.view
|
|
52
|
-
this.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
213
|
+
this.props.view
|
|
214
|
+
.whenLayerView(this.layer, this.TimesliderWidget)
|
|
215
|
+
.then((lv) => {
|
|
216
|
+
if (this.layer.type === 'feature') {
|
|
217
|
+
this.TimesliderWidget.fullTimeExtent = this.layer.timeInfo.fullTimeExtent;
|
|
218
|
+
this.TimesliderWidget.stops = {
|
|
219
|
+
interval: this.layer.timeInfo.interval,
|
|
220
|
+
};
|
|
221
|
+
this.TimesliderWidget.watch('timeExtent', (timeExtent) => {
|
|
222
|
+
if (!this.container.current ? true : false) {
|
|
223
|
+
this.TimesliderWidget.stop();
|
|
224
|
+
}
|
|
225
|
+
let start = new Date(timeExtent.start).getTime();
|
|
226
|
+
let end = new Date(timeExtent.end).getTime();
|
|
227
|
+
this.props.time.elem.setAttribute('time-start', start);
|
|
228
|
+
this.props.time.elem.setAttribute('time-end', end);
|
|
229
|
+
if (this.props.download) {
|
|
230
|
+
this.props.time.dataset.setAttribute('time-start', start);
|
|
231
|
+
this.props.time.dataset.setAttribute('time-end', end);
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
} else {
|
|
235
|
+
this.getTime(this.layer, this.layerName).then((v) => {
|
|
236
|
+
// Capabilities have time enabled
|
|
237
|
+
if (v !== false) {
|
|
238
|
+
// Start-End-Period
|
|
239
|
+
if (v.hasOwnProperty('period')) {
|
|
240
|
+
this.TimesliderWidget.fullTimeExtent = new TimeExtent({
|
|
241
|
+
start: new Date(v.start),
|
|
242
|
+
end: new Date(v.end),
|
|
243
|
+
});
|
|
62
244
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
245
|
+
const period = this.parserPeriod(v.period);
|
|
246
|
+
|
|
247
|
+
this.TimesliderWidget.stops = {
|
|
248
|
+
interval: {
|
|
249
|
+
value:
|
|
250
|
+
period.years * 365 * 24 * 60 +
|
|
251
|
+
period.months * 31 * 24 * 60 +
|
|
252
|
+
period.weeks * 7 * 24 * 60 +
|
|
253
|
+
period.days * 24 * 60 +
|
|
254
|
+
period.hours * 60 +
|
|
255
|
+
period.minutes +
|
|
256
|
+
period.seconds / 60,
|
|
257
|
+
unit: 'minutes',
|
|
258
|
+
},
|
|
259
|
+
};
|
|
260
|
+
} else if (v.hasOwnProperty('array')) {
|
|
261
|
+
// Dates array
|
|
262
|
+
this.TimesliderWidget.fullTimeExtent = new TimeExtent({
|
|
263
|
+
start: new Date(v.array[0]),
|
|
264
|
+
end: new Date(v.array[v.array.length - 1]),
|
|
265
|
+
});
|
|
266
|
+
this.TimesliderWidget.stops = {
|
|
267
|
+
dates: v.array.map((e) => new Date(e)),
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
if (this.layer.type === 'wmts') {
|
|
271
|
+
this.layer.customParameters = {};
|
|
272
|
+
const time = v.array.map((d) => new Date(d));
|
|
273
|
+
|
|
274
|
+
for (let i in time) {
|
|
275
|
+
timeDict[time[i]] = v.array[i];
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
this.TimesliderWidget.watch('timeExtent', (timeExtent) => {
|
|
280
|
+
if (!this.container.current ? true : false) {
|
|
281
|
+
this.TimesliderWidget.stop();
|
|
282
|
+
}
|
|
283
|
+
let start = new Date(timeExtent.start).getTime();
|
|
284
|
+
let end = new Date(timeExtent.end).getTime();
|
|
285
|
+
this.props.time.elem.setAttribute('time-start', start);
|
|
286
|
+
this.props.time.elem.setAttribute('time-end', end);
|
|
287
|
+
if (this.props.download) {
|
|
288
|
+
this.props.time.dataset.setAttribute('time-start', start);
|
|
289
|
+
this.props.time.dataset.setAttribute('time-end', end);
|
|
290
|
+
}
|
|
291
|
+
if (this.layer.type === 'wmts') {
|
|
292
|
+
this.layer.customParameters = {};
|
|
293
|
+
this.layer.customParameters['TIME'] =
|
|
294
|
+
timeDict[this.TimesliderWidget.timeExtent.end];
|
|
295
|
+
this.layer.refresh();
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
} // if there is dimension time
|
|
299
|
+
else {
|
|
300
|
+
this.TimesliderWidget.disabled = true;
|
|
301
|
+
}
|
|
302
|
+
}); // GetTime
|
|
303
|
+
} // is feature or WMS/WMTS
|
|
304
|
+
});
|
|
305
|
+
} //componentDidMount
|
|
77
306
|
|
|
78
307
|
/**
|
|
79
308
|
* Needed to get the desired drag-and-drop behavior
|