Newer
Older
Sébastien DA ROCHA
committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<template>
<div :class="['sidebar-container', { expanded }]">
<!-- <div class="sidebar-layers"></div> -->
<div @click="expanded = !expanded" class="layers-icon">
<!-- // ! svg point d'interrogation pas accepté par linter -->
<!-- <?xml version="1.0" encoding="iso-8859-1"?> -->
<svg
version="1.1"
id="Capa_1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
x="0px"
y="0px"
viewBox="0 0 491.203 491.203"
style="enable-background: new 0 0 491.203 491.203"
xml:space="preserve"
>
<g>
<g>
<path
d="M487.298,326.733l-62.304-37.128l62.304-37.128c2.421-1.443,3.904-4.054,3.904-6.872s-1.483-5.429-3.904-6.872
l-62.304-37.128l62.304-37.128c3.795-2.262,5.038-7.172,2.776-10.968c-0.68-1.142-1.635-2.096-2.776-2.776l-237.6-141.6
c-2.524-1.504-5.669-1.504-8.192,0l-237.6,141.6c-3.795,2.262-5.038,7.172-2.776,10.968c0.68,1.142,1.635,2.096,2.776,2.776
l62.304,37.128L3.905,238.733c-3.795,2.262-5.038,7.172-2.776,10.968c0.68,1.142,1.635,2.096,2.776,2.776l62.304,37.128
L3.905,326.733c-3.795,2.262-5.038,7.172-2.776,10.968c0.68,1.142,1.635,2.096,2.776,2.776l237.6,141.6
c2.526,1.494,5.666,1.494,8.192,0l237.6-141.6c3.795-2.262,5.038-7.172,2.776-10.968
C489.393,328.368,488.439,327.414,487.298,326.733z M23.625,157.605L245.601,25.317l221.976,132.288L245.601,289.893
L23.625,157.605z M23.625,245.605l58.208-34.68l159.672,95.2c2.524,1.504,5.668,1.504,8.192,0l159.672-95.2l58.208,34.68
L245.601,377.893L23.625,245.605z M245.601,465.893L23.625,333.605l58.208-34.68l159.672,95.2c2.524,1.504,5.668,1.504,8.192,0
l159.672-95.2l58.208,34.68L245.601,465.893z"
/>
</g>
</g>
</svg>
</div>
<div class="basemaps-title">
<h4>
Fonds cartographiques
<!-- <span data-tooltip="Il est possible pour chaque fond cartographique de modifier l'ordre des couches"
data-position="bottom left">
<i class="question circle outline icon"></i>
</span> -->
</h4>
</div>
<div
v-for="basemap in baseMaps"
:key="`list-${basemap.id}`"
class="basemaps-items ui accordion styled"
>
<div
:class="{ active: isActive(basemap) }"
class="basemap-item title"
@click="activateGroup(basemap)"
>
{{ basemap.title }}
</div>
<div :id="`queryable-layers-selector-${basemap.id}`" v-if="isQueryable(basemap)">
<b>Couche requêtable</b>
<Dropdown
@update:selection="onQueryLayerChange($event)"
:options="getQueryableLayers(basemap)"
:selected="selectedQueryLayer"
:search="true"
/>
</div>
<div
:class="{ active: isActive(basemap) }"
class="content"
:id="`list-${basemap.id}`"
:data-basemap-index="basemap.id"
Sébastien DA ROCHA
committed
<div
v-for="(layer, index) in basemap.layers"
:key="basemap.id + '-' + layer.id + '-' + index"
class="layer-item transition visible item list-group-item" :data-id="layer.id"
Sébastien DA ROCHA
committed
>
<p class="layer-handle-sort">
<i class="th icon"></i>{{ layer.title }}
Sébastien DA ROCHA
committed
</p>
<label>Opacité <span>(%)</span></label>
<div class="range-container">
<!-- // todo : rendre réactif les valeurs et connectés avec store/Map -->
<input
@change="updateOpacity($event, layer)"
Sébastien DA ROCHA
committed
type="range"
min="0"
max="1"
:value="layer.opacity"
step="0.01"
/><output class="range-output-bubble">{{
getOpacity(layer.opacity)
}}</output>
Sébastien DA ROCHA
committed
</div>
<div class="ui divider"></div>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapUtil } from "@/assets/js/map-util.js";
import Dropdown from "@/components/Dropdown.vue";
Sébastien DA ROCHA
committed
export default {
name: "SidebarLayers",
Sébastien DA ROCHA
committed
data() {
return {
Sébastien DA ROCHA
committed
expanded: false,
};
},
methods: {
Sébastien DA ROCHA
committed
},
activateGroup(basemap) {
this.baseMaps.forEach((basemap) => (basemap.active = false));
basemap.active = true;
basemap.title += " "; //weird!! Force refresh
Sébastien DA ROCHA
committed
this.addLayers(basemap);
let mapOptions = localStorage.getItem('geocontrib-map-options') || {};
mapOptions = mapOptions.length ? JSON.parse(mapOptions) : {};
let project=this.$route.params.slug;
mapOptions[project] = {
...mapOptions[project],
'current-basemap-index': basemap.id
};
localStorage.setItem('geocontrib-map-options', JSON.stringify(mapOptions));
Sébastien DA ROCHA
committed
},
updateOpacity(event, layer) {
console.log(event.target.value, layer);
Sébastien DA ROCHA
committed
mapUtil.updateOpacity(layer.id, event.target.value);
layer.opacity = event.target.value;
Sébastien DA ROCHA
committed
},
getOpacity(opacity) {
return Math.round(parseFloat(opacity) * 100);
Sébastien DA ROCHA
committed
},
onQueryLayerChange(layer){
console.log(layer);
this.selectedQueryLayer=layer.name;
},
isQueryable(baseMap){
let queryableLayer=baseMap.layers.filter(l => l.queryable === true);
return queryableLayer.length>0;
},
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
onlayerMove(event){
console.log(event)
// Get the names of the current layers in order.
const currentLayersNamesInOrder = Array.from(document.getElementsByClassName('layer-item transition visible')).map(el => el.children[0].innerText);
// Create an array to put the layers in order.
let movedLayers = [];
for (const layerName of currentLayersNamesInOrder) {
movedLayers.push(this.activeBasemap.layers.filter(el => el.title === layerName)[0]);
}
// Remove existing layers undefined
movedLayers = movedLayers.filter(function(x) {
return x !== undefined;
});
const eventOrder = new CustomEvent('change-layers-order', {
detail: {
layers: movedLayers
}
})
document.dispatchEvent(eventOrder);
// Save the basemaps options into the localstorage
console.log(this.baseMaps)
this.setLocalstorageMapOptions(this.baseMaps)
},
setLocalstorageMapOptions(basemaps) {
let mapOptions = localStorage.getItem('geocontrib-map-options') || {};
mapOptions = mapOptions.length ? JSON.parse(mapOptions) : {};
let project=this.$route.params.slug;
mapOptions[project] = {
...mapOptions[project],
'basemaps': basemaps
};
localStorage.setItem('geocontrib-map-options', JSON.stringify(mapOptions));
},
initSortable(){
this.baseMaps.forEach((basemap) => {
new Sortable(document.getElementById(`list-${basemap.id}`), {
animation: 150,
handle: '.layer-handle-sort', // The element that is active to drag
ghostClass: 'blue-background-class',
dragClass: 'white-opacity-background-class',
onEnd: this.onlayerMove.bind(this)
});
});
},
// Check if there are changes in the basemaps settings. Changes are detected if:
// - one basemap has been added or deleted
// - one layer has been added or deleted to a basemap
areChangesInBasemaps(basemapFromServer, basemapFromLocalstorage={}) {
let isSameBasemaps = false;
let isSameLayers = true;
let isSameTitles = true;
// Compare the length and the id values of the basemaps
const idBasemapsServer = basemapFromServer.map(b => b.id).sort();
const idBasemapsLocalstorage = basemapFromLocalstorage.length ? basemapFromLocalstorage.map(b => b.id).sort() : {};
isSameBasemaps = (idBasemapsServer.length === idBasemapsLocalstorage.length
&& idBasemapsServer.every((value, index) => value === idBasemapsLocalstorage[index]))
// For each basemap, compare the length and id values of the layers
outer_block: {
for(let basemapServer of basemapFromServer) {
let idLayersServer = basemapServer.layers.map(b => b.id).sort();
if (basemapFromLocalstorage.length){
for (let basemapLocalstorage of basemapFromLocalstorage) {
if (basemapServer.id === basemapLocalstorage.id) {
let idLayersLocalstorage = basemapLocalstorage.layers.map(b => b.id).sort();
isSameLayers = (idLayersServer.length === idLayersLocalstorage.length
&& idLayersServer.every((value, index) => value === idLayersLocalstorage[index]));
if (!isSameLayers) {
break outer_block;
}
}
}
}
}
// Compare basemaps titles
const titlesBasemapsServer = basemapFromServer.map(b => b.title).sort();
const titlesBasemapsLocalstorage = basemapFromLocalstorage.length ? basemapFromLocalstorage.map(b => b.title).sort() : {};
isSameTitles = titlesBasemapsServer.every((title, index) => title === titlesBasemapsLocalstorage[index]);
if (!isSameTitles) {
break outer_block;
}
}
return !(isSameBasemaps && isSameLayers && isSameTitles);
},
getQueryableLayers(baseMap){
let queryableLayer=baseMap.layers.filter(l => l.queryable === true);
return queryableLayer.map(x=>{
return {
name:x.title,
value:x
}
});
},
baseMap.layers.forEach((layer) => {
var layerOptions = this.layers.find((l) => l.id === layer.id);
console.log(layerOptions);
layer = Object.assign(layer, layerOptions);
layer.options.basemapId = baseMap.id;
});
Sébastien DA ROCHA
committed
mapUtil.removeLayers(mapUtil.getMap());
// Reverse is done because the first layer in order has to be added in the map in last.
// Slice is done because reverse() changes the original array, so we make a copy first
mapUtil.addLayers(baseMap.layers.slice().reverse(), null, null);
Sébastien DA ROCHA
committed
},
mounted() {
this.baseMaps = this.$store.state.map.basemaps;
let project=this.$route.params.slug;
const mapOptions = JSON.parse(localStorage.getItem('geocontrib-map-options')) || {};
if (mapOptions
&& mapOptions[project]) {
// If already in the storage, we need to check if the admin did some
// modification in the basemaps on the server side. The rule is: if one layer has been added
// or deleted in the server, then we reset the localstorage.
const baseMapsFromLocalstorage = mapOptions[project]['basemaps'];
const areChanges = this.areChangesInBasemaps(this.baseMaps, baseMapsFromLocalstorage);
if (areChanges) {
mapOptions[project] = {
'map-options': this.baseMaps,
'current-basemap-index': 0,
};
localStorage.setItem('geocontrib-map-options', JSON.stringify(mapOptions));
} else {
this.baseMaps = baseMapsFromLocalstorage;
}
}
this.layers = this.$store.state.map.layers;
if (this.baseMaps.length > 0) {
this.baseMaps[0].active = true;
this.activeBasemap=this.baseMaps[0];
Sébastien DA ROCHA
committed
this.addLayers(this.baseMaps[0]);
} else {
mapUtil.addLayers(
null,
this.$store.state.configuration.DEFAULT_BASE_MAP.SERVICE,
this.$store.state.configuration.DEFAULT_BASE_MAP.OPTIONS
);
Sébastien DA ROCHA
committed
}
setTimeout(this.initSortable.bind(this),1000)
Sébastien DA ROCHA
committed
};
</script>
<style>
@import "../../assets/styles/sidebar-layers.css";
.queryable-layers-dropdown {
margin-bottom: 1em;
}
.queryable-layers-dropdown > label {
font-weight: bold;
}
</style>