Newer
Older
Sébastien DA ROCHA
committed
<template>
<div
v-if="isOnline"
:class="['sidebar-container', { expanded }]"
>
Sébastien DA ROCHA
committed
<!-- // ! svg point d'interrogation pas accepté par linter -->
<!-- <?xml version="1.0" encoding="iso-8859-1"?> -->
<svg
id="Capa_1"
Sébastien DA ROCHA
committed
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>
Sébastien DA ROCHA
committed
<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"
/>
Sébastien DA ROCHA
committed
</g>
</g>
</svg>
</div>
<div class="basemaps-title">
<h4>
Fonds cartographiques
</h4>
</div>
v-for="basemap in baseMaps"
:key="`list-${basemap.id}`"
:basemap="basemap"
:base-maps="baseMaps"

Timothee P
committed
:active="activeBasemap.id === basemap.id"

Timothee P
committed
@activateGroup="activateGroup"
@onlayerMove="onlayerMove"
Sébastien DA ROCHA
committed
</div>
</template>
<script>
import LayerSelector from '@/components/Map/LayerSelector.vue';
Sébastien DA ROCHA
committed
export default {

Timothee P
committed

Timothee P
committed
Sébastien DA ROCHA
committed
data() {
return {
Sébastien DA ROCHA
committed
expanded: false,

Timothee P
committed
projectSlug: this.$route.params.slug
Sébastien DA ROCHA
committed
};
},

Timothee P
committed
computed: {
...mapState([
'isOnline',
]),
...mapState('map', [

Timothee P
committed
'availableLayers',

Timothee P
committed
activeBasemap() {
return this.baseMaps.find((baseMap) => baseMap.active);
},
activeBasemapIndex() {
return this.baseMaps.findIndex((el) => el.id === this.activeBasemap.id);
},
},
mounted() {
this.baseMaps = this.$store.state.map.basemaps;
const mapOptions =
JSON.parse(localStorage.getItem('geocontrib-map-options')) || {};

Timothee P
committed
if (mapOptions && mapOptions[this.projectSlug]) {
// 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.

Timothee P
committed
const baseMapsFromLocalstorage = mapOptions[this.projectSlug]['basemaps'];
const areChanges = this.areChangesInBasemaps(
this.baseMaps,
baseMapsFromLocalstorage
);
if (areChanges) {

Timothee P
committed
mapOptions[this.projectSlug] = {
'current-basemap-index': 0,
};
localStorage.setItem(
'geocontrib-map-options',
JSON.stringify(mapOptions)
);
} else {
this.baseMaps = baseMapsFromLocalstorage;
}
}
if (this.baseMaps.length > 0) {
// if an active layers has been set earlier
if (mapOptions[this.projectSlug] && mapOptions[this.projectSlug]['current-basemap-index']) {
// set the concerned layer with active value
this.baseMaps.find((baseMap) => baseMap.id === mapOptions[this.projectSlug]['current-basemap-index']).active = true;
} else { // set the first basemap as active
this.baseMaps[0].active = true;
}
this.addLayers(this.activeBasemap);
this.$store.state.configuration.DEFAULT_BASE_MAP_SERVICE,

Timothee P
committed
this.$store.state.configuration.DEFAULT_BASE_MAP_OPTIONS,
this.$store.state.configuration.DEFAULT_BASE_MAP_SCHEMA_TYPE

Timothee P
committed
},
Sébastien DA ROCHA
committed
methods: {
toggleSidebar(value) {
this.expanded = value !== undefined ? value : !this.expanded;
},
// Check if there are changes in the basemaps settings. Changes are detected if:

Timothee P
committed
// - one basemap has been added or deleted
// - one layer has been added or deleted to a basemap
areChangesInBasemaps(basemapFromServer, basemapFromLocalstorage) {
// prevent undefined later even if in this case the function is not called anyway
if (!basemapFromLocalstorage) return false;

Timothee P
committed
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.map((b) => b.id).sort() || {};

Timothee P
committed
isSameBasemaps =
idBasemapsServer.length === idBasemapsLocalstorage.length &&
idBasemapsServer.every(
(value, index) => value === idBasemapsLocalstorage[index]
);
// if basemaps changed, return that changed occured to avoid more processing
if (!isSameBasemaps) return true;

Timothee P
committed
outer_block: {
// For each basemap from the server, compare the length and id values of the layers
// Prepare an array of layer ids from the server and sort them
const idLayersServer = basemapServer.layers.map((b) => b.id).sort();
// loop over basemaps from localStorage and check if layers id match the ones from the server
for (const basemapLocalstorage of basemapFromLocalstorage) {
if (basemapServer.id === basemapLocalstorage.id) {
const 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;

Timothee P
committed
// Compare basemaps titles
const titlesBasemapsServer = basemapFromServer
.map((b) => b.title)
.sort();
const titlesBasemapsLocalstorage = basemapFromLocalstorage.map((b) => b.title).sort() || {};

Timothee P
committed
isSameTitles = titlesBasemapsServer.every(
(title, index) => title === titlesBasemapsLocalstorage[index]
);

Timothee P
committed
if (!isSameTitles) {
break outer_block;
}

Timothee P
committed
return !(isSameBasemaps && isSameLayers && isSameTitles);
},
addLayers(baseMap) {
baseMap.layers.forEach((layer) => {
const layerOptions = this.availableLayers.find((l) => l.id === layer.id);
layer = Object.assign(layer, layerOptions);
layer.options.basemapId = baseMap.id;
});
Sébastien DA ROCHA
committed
// 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
mapService.addLayers(baseMap.layers.slice().reverse(), null, null, null,);

Timothee P
committed
activateGroup(basemapId) {
//* to activate a basemap, we need to set the active property to true and set the others to false

Timothee P
committed
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
this.baseMaps = this.baseMaps.map((bm) => {
return { ...bm, active: bm.id === basemapId ? true : false };
});
//* add the basemap that was clicked to the map
this.addLayers(this.baseMaps.find((bm) => bm.id === basemapId));
//* to persist the settings, we set the localStorage mapOptions per project
this.setLocalstorageMapOptions({ 'current-basemap-index': basemapId });
},
onlayerMove() {
// Get the names of the current layers in order.
const currentLayersNamesInOrder = Array.from(
document.getElementsByClassName('layer-item transition visible')
).map((el) => parseInt(el.attributes['data-id'].value));
// Create an array to put the layers in order.
let movedLayers = [];
for (const layerName of currentLayersNamesInOrder) {
movedLayers.push(
this.activeBasemap.layers.find((el) => el.id === layerName)
);
}
// 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);
// report layers order change in the basemaps object before saving them
this.baseMaps[this.activeBasemapIndex].layers = movedLayers;
// Save the basemaps options into the localstorage
this.setLocalstorageMapOptions({ basemaps: this.baseMaps });
},
onOpacityUpdate(data) {
const { layerId, opacity } = data;
// retrieve layer to update opacity
this.baseMaps[this.activeBasemapIndex].layers.find((layer) => layer.id === layerId).opacity = opacity;

Timothee P
committed
// Save the basemaps options into the localstorage
this.setLocalstorageMapOptions({ basemaps: this.baseMaps });
},
setLocalstorageMapOptions(newOptionObj) {
let mapOptions = localStorage.getItem('geocontrib-map-options') || {};
mapOptions = mapOptions.length ? JSON.parse(mapOptions) : {};
mapOptions[this.projectSlug] = {
...mapOptions[this.projectSlug],
...newOptionObj,
};
localStorage.setItem(
'geocontrib-map-options',
JSON.stringify(mapOptions)
);
},
Sébastien DA ROCHA
committed
},
};
</script>