Skip to content
Snippets Groups Projects
SidebarLayers.vue 7.31 KiB
Newer Older
  <div
    v-if="isOnline"
    :class="['sidebar-container', { expanded }]"
  >
    <div
      class="layers-icon"
      @click="toggleSidebar()"
      <!-- // ! svg point d'interrogation pas accepté par linter -->
      <!-- <?xml version="1.0" encoding="iso-8859-1"?> -->
      <svg
        id="Capa_1"
        version="1.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>
Timothee P's avatar
Timothee P committed
            <!-- eslint-disable max-len -->
            <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"
            />
Timothee P's avatar
Timothee P committed
            <!--eslint-enable-->
          </g>
        </g>
      </svg>
    </div>

    <div class="basemaps-title">
      <h4>
        Fonds cartographiques
      </h4>
    </div>
    <LayerSelector
      v-for="basemap in baseMaps"
      :key="`list-${basemap.id}`"
      :basemap="basemap"
      :base-maps="baseMaps"
      :active-basemap="activeBasemap"
      @addLayers="addLayers"
      @setActiveBasemap="setActiveBasemap"
    />
import { mapState } from 'vuex';

import LayerSelector from '@/components/Map/LayerSelector.vue';
DESPRES Damien's avatar
DESPRES Damien committed
import mapService from '@/services/map-service';
  name: 'SidebarLayers',
  components: {
Florent Lavelle's avatar
Florent Lavelle committed
      sortable: null
    ...mapState([
      'isOnline',
    ]),
    ...mapState('map', [
      'availableLayers'
    ]),
  },

  mounted() {
    this.baseMaps = this.$store.state.map.basemaps;
Florent Lavelle's avatar
Florent Lavelle committed
    const 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;
      }
    }

    if (this.baseMaps.length > 0) {
      this.baseMaps[0].active = true;
      this.activeBasemap = this.baseMaps[0];
      this.addLayers(this.baseMaps[0]);
    } else {
DESPRES Damien's avatar
DESPRES Damien committed
      mapService.addLayers(
        this.$store.state.configuration.DEFAULT_BASE_MAP_SERVICE,
        this.$store.state.configuration.DEFAULT_BASE_MAP_OPTIONS,
        this.$store.state.configuration.DEFAULT_BASE_MAP_SCHEMA_TYPE
    toggleSidebar(value) {
      this.expanded = value !== undefined ? value : !this.expanded;
    },

    // 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: {
Florent Lavelle's avatar
Florent Lavelle committed
        for (const basemapServer of basemapFromServer) {
          const idLayersServer = basemapServer.layers.map((b) => b.id).sort();
Florent Lavelle's avatar
Florent Lavelle committed
            for (const basemapLocalstorage of basemapFromLocalstorage) {
              if (basemapServer.id === basemapLocalstorage.id) {
Florent Lavelle's avatar
Florent Lavelle committed
                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;
                }
        // 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]
        );
      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;
      });
DESPRES Damien's avatar
DESPRES Damien committed
      mapService.removeLayers();
      // 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
DESPRES Damien's avatar
DESPRES Damien committed
      mapService.addLayers(baseMap.layers.slice().reverse(), null, null, null,);

    setActiveBasemap(basemap) {
      this.activeBasemap = basemap;
    }