diff --git a/public/config/config.json.sample b/public/config/config.json.sample index f812252eaa1bf46307917f32352c910d81154600..833d915f9808fd56e90d9d0d8fc35a3b216446a2 100644 --- a/public/config/config.json.sample +++ b/public/config/config.json.sample @@ -24,6 +24,7 @@ "center": [47.0, 1.0], "zoom": 4 }, + "MAP_PREVIEW_CENTER" : [46.56397874834413, 3.3283550153590995], "GEOCODER_PROVIDERS" : { "ADDOK": "addok", "NOMINATIM": "nominatim", diff --git a/src/services/map-service.js b/src/services/map-service.js index 153ae2eec3dd49aab6bb10121e566da9a8a48cb4..df2592d9b805c618ec6a3af7e1b1e320f9de5eb0 100644 --- a/src/services/map-service.js +++ b/src/services/map-service.js @@ -55,6 +55,7 @@ const mapService = { zoom, zoomControl = true, interactions = { doubleClickZoom: false, mouseWheelZoom: false, dragPan: true }, + controls, } = options; if (el.innerHTML) { @@ -64,7 +65,7 @@ const mapService = { const mapOptions = { layers: [], target: el, - controls: [ + controls: controls ? controls : [ new Attribution(), new ScaleLine({ units: 'metric', @@ -575,12 +576,16 @@ const mapService = { return { html, feature_type, featureId }; }, + zoom(zoomlevel) { + this.map.getView().setZoom(zoomlevel); + }, + zoomTo(location, zoomlevel, lon, lat) { if (lon && lat) { location = [+lon, +lat]; } this.map.getView().setCenter(transform(location, 'EPSG:4326', 'EPSG:3857')); - this.map.getView().setZoom(zoomlevel); + this.zoom(zoomlevel); }, addOverlay(loc) { diff --git a/src/store/modules/map.store.js b/src/store/modules/map.store.js index 3ae7994329dc93751cd400d5c39892bf842b2850..bdfccddc6bcbdf5ba38215d48fd48aa05d626f97 100644 --- a/src/store/modules/map.store.js +++ b/src/store/modules/map.store.js @@ -104,13 +104,13 @@ const map = { }); }, - INITIATE_MAP({ commit, rootState }, el) { //todo: since this function is not anymore called in different components, it would better to move it in project_details.vue - const mapDefaultViewCenter = [46, 2]; // defaultMapView.center; - const mapDefaultViewZoom = 5; // defaultMapView.zoom; - mapService.createMap(el, { - mapDefaultViewCenter: mapDefaultViewCenter, - mapDefaultViewZoom: mapDefaultViewZoom, - maxZoom: rootState.projects.project.map_max_zoom_level, + INITIATE_MAP({ commit, rootState }, options) { + mapService.createMap(options.el, { + mapDefaultViewZoom: options.zoom || 5, + mapDefaultViewCenter: options.center || [46, 2], + maxZoom: options.maxZoom || rootState.projects.project.map_max_zoom_level, + controls: options.controls, + zoomControl: options.zoomControl, }); const map = { ...mapService.getMap() }; commit('SET_MAP', map); diff --git a/src/views/Project/ProjectDetail.vue b/src/views/Project/ProjectDetail.vue index d80e7176209a025da8f4e6c0a16115861ac11540..7550c848881daca746dcabde48537aef3a7ce119 100644 --- a/src/views/Project/ProjectDetail.vue +++ b/src/views/Project/ProjectDetail.vue @@ -409,7 +409,7 @@ export default { async initMap() { if (this.project && this.permissions.can_view_project) { - await this.INITIATE_MAP(this.$refs.map); + await this.INITIATE_MAP({ el: this.$refs.map }); this.checkForOfflineFeature(); const project_id = this.$route.params.slug.split('-')[0]; const mvtUrl = `${this.API_BASE_URL}features.mvt`; diff --git a/src/views/Project/ProjectEdit.vue b/src/views/Project/ProjectEdit.vue index 005ab046c106090122969ae854ba5ecff680628b..2b609241431e59ad77ad6b823bd550116545a3a7 100644 --- a/src/views/Project/ProjectEdit.vue +++ b/src/views/Project/ProjectEdit.vue @@ -169,7 +169,7 @@ </div> <div class="two fields"> - <div class="fields grouped"> + <div class="fields grouped checkboxes"> <div class="field"> <div class="ui checkbox"> <input @@ -225,16 +225,29 @@ <div class="field required"> <label>Niveau de zoom maximum de la carte</label> - <div class="range-container"> - <input - v-model="form.map_max_zoom_level" - type="range" - min="0" - max="22" - step="1" - ><output class="range-output-bubble">{{ - form.map_max_zoom_level - }}</output> + <div class="map-maxzoom-selector"> + <div class="range-container"> + <input + v-model="form.map_max_zoom_level" + type="range" + min="0" + max="22" + step="1" + @input="zoomMap" + ><output class="range-output-bubble">{{ + scalesTable[form.map_max_zoom_level] + }}</output> + </div> + <div class="map-preview"> + <label>Aperçu :</label> + <div + id="map" + ref="map" + /> + <div class="no-preview"> + pas de fond de carte disponible à cette échelle + </div> + </div> </div> </div> </div> @@ -259,10 +272,11 @@ <script> import axios from '@/axios-client.js'; import Dropdown from '@/components/Dropdown.vue'; +import mapService from '@/services/map-service'; import TextareaMarkdown from 'textarea-markdown'; -import { mapState } from 'vuex'; +import { mapActions, mapState } from 'vuex'; export default { name: 'ProjectEdit', @@ -311,6 +325,31 @@ export default { fast_edition_mode: false, }, thumbnailFileSrc: '', + scalesTable: [ + '1:500 Mio', + '1:250 Mio', + '1:150 Mio', + '1:70 Mio', + '1:35 Mio', + '1:15 Mio', + '1:10 Mio', + '1:4 Mio', + '1:2 Mio', + '1:1 Mio', + '1:500 000', + '1:250 000', + '1:150 000', + '1:70 000', + '1:35 000', + '1:15 000', + '1:8 000', + '1:4 000', + '1:2 000', + '1:1 000', + '1:500', + '1:250', + '1:150', + ] }; }, @@ -366,11 +405,12 @@ export default { } } }, - - created() { + + mounted() { this.definePageType(); if (this.action === 'create') { this.thumbnailFileSrc = require('@/assets/img/default.png'); + this.initPreviewMap(); } else if (this.action === 'edit' || this.action === 'create_from') { if (!this.project) { this.$store.dispatch('projects/GET_PROJECT', this.$route.params.slug) @@ -383,14 +423,14 @@ export default { this.fillProjectForm(); } } - }, - - mounted() { let textarea = document.querySelector('textarea'); new TextareaMarkdown(textarea); }, methods: { + ...mapActions('map', [ + 'INITIATE_MAP' + ]), definePageType() { if (this.$router.history.current.name === 'project_create') { this.action = 'create'; @@ -648,12 +688,30 @@ export default { }; } } + this.initPreviewMap(); + }, + + initPreviewMap () { + const map = mapService.getMap(); + if (map) mapService.destroyMap(); + this.INITIATE_MAP({ + el: this.$refs.map, + zoom: this.project ? this.project.map_max_zoom_level : 22, + center: this.$store.state.configuration.MAP_PREVIEW_CENTER, + maxZoom: 22, + controls: [], + zoomControl: false, + }); }, + + zoomMap() { + mapService.zoom(this.form.map_max_zoom_level); + } }, }; </script> -<style media="screen"> +<style media="screen" lang="less"> #form-input-file-logo { margin-left: auto; margin-right: auto; @@ -673,4 +731,52 @@ textarea { border: 1px solid rgba(34, 36, 38, .15); padding: .78571429em 1em; } + +.checkboxes { + padding-left: .5em; +} + +.map-maxzoom-selector { + display: flex; + flex-wrap: wrap; + justify-content: space-between; + + input, output { + height: fit-content; + } + output { + white-space: nowrap; + min-width: auto; + } + + .range-container { + margin-bottom: 2rem; + } + .map-preview { + margin-top: -1rem; + display: flex; + position: relative; + label { + white-space: nowrap; + font-size: .95em; + margin-right: 1rem; + } + #map { + min-height: 80px; + height: 80px; + width: 150px; + max-width: 150px; + z-index: 1; + } + + .no-preview { + position: absolute; + top: 25%; + left: 25%; + text-align: center; + font-size: .75em; + color: #656565; + } + } +} </style> \ No newline at end of file