@@ -39,8 +39,10 @@ async function autoReloadData(store, geoJsonLayer) {
39
39
const { data } = await load ( geoJsonLayer . geoJsonUrl )
40
40
const layerCopy = geoJsonLayer . clone ( )
41
41
layerCopy . geoJsonData = data
42
- await store . dispatch ( 'updateLayer' , {
43
- layer : layerCopy ,
42
+ // we update through the action updateLayers, so that if multiple copies of the same GeoJSON layer are present,
43
+ // they will all be updated with the fresh data
44
+ store . dispatch ( 'updateLayers' , {
45
+ layers : [ layerCopy ] ,
44
46
...dispatcher ,
45
47
} )
46
48
log . debug ( `Data reloaded according to updateDelay for layer ${ geoJsonLayer . id } ` )
@@ -51,11 +53,18 @@ async function autoReloadData(store, geoJsonLayer) {
51
53
} , geoJsonLayer . updateDelay )
52
54
}
53
55
56
+ function clearAutoReload ( layerId ) {
57
+ log . debug ( `Removing auto-reload of data for layer ${ layerId } as it was removed from the map` )
58
+ clearInterval ( intervalsByLayerId [ layerId ] )
59
+ delete intervalsByLayerId [ layerId ]
60
+ }
61
+
54
62
/**
55
63
* @param {GeoAdminGeoJsonLayer } geoJsonLayer
56
64
* @returns {Promise<GeoAdminGeoJsonLayer> }
57
65
*/
58
- async function loadDataAndStyle ( store , geoJsonLayer ) {
66
+ async function loadDataAndStyle ( geoJsonLayer ) {
67
+ log . debug ( `Loading data/style for added GeoJSON layer` , geoJsonLayer )
59
68
const clone = geoJsonLayer . clone ( )
60
69
try {
61
70
const [ { data : style } , { data } ] = await Promise . all ( [
@@ -68,19 +77,13 @@ async function loadDataAndStyle(store, geoJsonLayer) {
68
77
clone . geoJsonData = data
69
78
clone . geoJsonStyle = style
70
79
clone . isLoading = false
71
- await store . dispatch ( 'updateLayer' , {
72
- layer : clone ,
73
- ...dispatcher ,
74
- } )
80
+ return clone
75
81
} catch ( error ) {
76
82
log . error ( `Error while fetching GeoJSON data/style for layer ${ geoJsonLayer ?. id } ` , error )
77
83
clone . isLoading = false
78
84
clone . errorKey = 'loading_error_network_failure'
79
85
clone . hasError = true
80
- await store . dispatch ( 'updateLayer' , {
81
- layer : clone ,
82
- ...dispatcher ,
83
- } )
86
+ return clone
84
87
}
85
88
}
86
89
@@ -92,18 +95,34 @@ async function loadDataAndStyle(store, geoJsonLayer) {
92
95
*/
93
96
export default function loadGeojsonStyleAndData ( store ) {
94
97
store . subscribe ( ( mutation ) => {
95
- const addLayersSubscriber = ( layers ) => {
96
- layers
98
+ const addLayersSubscriber = async ( layers ) => {
99
+ const geoJsonLayers = layers
97
100
. filter ( ( layer ) => layer instanceof GeoAdminGeoJsonLayer )
101
+ // filtering out multiple active layer entries for the same GeoJSON data
102
+ // (only one request to get the data is necessary for all entries)
103
+ . filter (
104
+ ( geoJsonLayer , index , self ) =>
105
+ // checking that the index of the first layer matching our ID is the same index as the layer
106
+ // we are currently looping through, filtering it out otherwise (it's a duplicate)
107
+ self . indexOf ( self . find ( ( layer ) => layer . id === geoJsonLayer . id ) ) === index
108
+ )
109
+
110
+ const updatedLayers = await Promise . all (
111
+ geoJsonLayers
112
+ . filter ( ( layer ) => layer . isLoading )
113
+ . map ( ( layer ) => loadDataAndStyle ( layer ) )
114
+ )
115
+ if ( updatedLayers . length > 0 ) {
116
+ store . dispatch ( 'updateLayers' , { layers : updatedLayers , ...dispatcher } )
117
+ }
118
+
119
+ // after the initial load is done,
120
+ // going through all layers that have an update delay and launching the routine to reload their data
121
+ geoJsonLayers
122
+ . filter ( ( layer ) => layer . updateDelay > 0 )
98
123
. forEach ( ( layer ) => {
99
- if ( layer . isLoading ) {
100
- log . debug ( `Loading data/style for added GeoJSON layer` , layer )
101
- loadDataAndStyle ( store , layer )
102
- }
103
- if ( layer . updateDelay > 0 ) {
104
- log . debug ( 'starting auto-reload of data for layer' , layer )
105
- autoReloadData ( store , layer )
106
- }
124
+ log . debug ( 'starting auto-reload of data for layer' , layer )
125
+ autoReloadData ( store , layer )
107
126
} )
108
127
}
109
128
if ( mutation . type === 'addLayer' ) {
@@ -113,12 +132,19 @@ export default function loadGeojsonStyleAndData(store) {
113
132
addLayersSubscriber ( mutation . payload . layers )
114
133
}
115
134
if ( mutation . type === 'removeLayerWithId' && intervalsByLayerId [ mutation . payload . layerId ] ) {
116
- log . debug (
117
- `Removing auto-reload of data for layer ${ mutation . payload . layerId } as it was removed from the map`
118
- )
119
135
// when a layer is removed, if a matching interval is found, we clear it
120
- clearInterval ( intervalsByLayerId [ mutation . payload . layerId ] )
121
- delete intervalsByLayerId [ mutation . payload . layerId ]
136
+ clearAutoReload ( mutation . payload . layerId )
137
+ }
138
+ if ( mutation . type === 'removeLayerByIndex' ) {
139
+ // As we come after the work has been done,
140
+ // we cannot get the layer ID removed from the store from the mutation's payload.
141
+ // So we instead go through all intervals, and clear any that has no matching layer in the active layers
142
+ Object . keys ( intervalsByLayerId )
143
+ . filter (
144
+ ( layerId ) =>
145
+ ! store . state . layers . activeLayers . some ( ( layer ) => layer . id === layerId )
146
+ )
147
+ . forEach ( ( layerId ) => clearAutoReload ( layerId ) )
122
148
}
123
149
} )
124
150
}
0 commit comments