diff --git a/package.json b/package.json index 3e59989c8975a3211f294b94343c58eee650a539..6af8471dbb3eec623357c86dc789ad9e18359800 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,14 @@ "lint": "vue-cli-service lint" }, "dependencies": { + "@mapbox/vector-tile": "^1.3.1", "@turf/flip": "^6.5.0", "axios": "^0.21.1", "core-js": "^3.6.5", "leaflet": "^1.5.1", "leaflet-draw": "^1.0.4", + "leaflet.vectorgrid": "^1.3.0", + "pbf": "^3.2.1", "register-service-worker": "^1.7.1", "sortablejs": "^1.14.0", "vue": "^2.6.11", diff --git a/src/assets/js/map-util.js b/src/assets/js/map-util.js index 89acc5e36ddc956b36bb996065b2988299592335..3f63f5e64f04e5cb88e778a6a73fde5fd732421d 100644 --- a/src/assets/js/map-util.js +++ b/src/assets/js/map-util.js @@ -1,7 +1,11 @@ +/* eslint-disable no-mixed-spaces-and-tabs */ +/* eslint-disable no-unused-vars */ +/* eslint-disable no-undef */ import L from "leaflet" import "leaflet/dist/leaflet.css"; import flip from '@turf/flip' import axios from "axios" +import "leaflet.vectorgrid"; axios.defaults.headers.common['X-CSRFToken'] = (name => { var re = new RegExp(name + "=([^;]+)"); @@ -9,10 +13,29 @@ axios.defaults.headers.common['X-CSRFToken'] = (name => { return (value != null) ? unescape(value[1]) : null; })('csrftoken'); +import { FillSymbolizer, PointSymbolizer, LineSymbolizer } from "@/assets/js/vector_tile_fix.js"; let map; let dictLayersToLeaflet = {}; - +var layerMVT; +let statusList=[ + { + name: "Brouillon", + value: "draft", + }, + { + name: "Publié", + value: "published", + }, + { + name: "Archivé", + value: "archived", + }, + { + name: "En attente de publication", + value: "pending", + }, +]; L.TileLayer.BetterWMS = L.TileLayer.WMS.extend({ onAdd: function (map) { @@ -274,13 +297,91 @@ const mapUtil = { // Redraw the layers this.addLayers(layers); }, + // eslint-disable-next-line no-unused-vars + addVectorTileLayer: function (project_slug,featureTypes,form_filters) { + let project_id=project_slug.split('-')[0]; + layerMVT = L.vectorGrid.protobuf("/api/features.mvt/?tile={z}/{x}/{y}&project_id="+project_id, { // + vectorTileLayerStyles: { + "default": function(properties, zoom) { + // console.log(properties); + + let featureType=featureTypes.find((x)=>x.slug.split('-')[0]===''+properties.feature_type_id); + let color=featureType.color; + if(featureType.colors_style && featureType.colors_style.custom_field_name){ + let currentValue=properties[featureType.colors_style.custom_field_name]; + let colorValue=featureType.colors_style.colors[currentValue]; + if(colorValue) { + color=colorValue; + } - addFeatures: function (features, filter) { + } + console.log(featureType); + let hiddenStyle=({ + radius: 0, + fillOpacity: 0.5, + weight: 0, + fill: false, + color: featureType.color, + }) + // Filtre sur le feature type + if (form_filters && form_filters.type.selected) { + if(featureType.title !== form_filters.type.selected){ + return hiddenStyle; + } + } + // Filtre sur le statut + if (form_filters && form_filters.status.selected.value) { + if(properties.status !== form_filters.status.selected.value){ + return hiddenStyle; + } + } + // Filtre sur le titre + if (form_filters && form_filters.title) { + if(!properties.title.toLowerCase().includes(form_filters.title.toLowerCase())){ + return hiddenStyle; + } + } + return ({ + radius: 4, + fillOpacity: 0.5, + weight: 3, + fill: true, + color: color, + }); + + }, + }, + // subdomains: "0123", + // key: 'abcdefghi01234567890', + interactive:true, + maxNativeZoom: 14, + getFeatureId: function(f) { + return f.properties.id; + } + }); + let self=this; + layerMVT.on('click', function(e) { // The .on method attaches an event handler + console.log(e); + const popupContent = self._createContentPopup(e.layer,featureTypes,project_slug); + L.popup() + .setContent(popupContent) + .setLatLng(e.latlng) + .openOn(map) + }); + layerMVT.addTo(map); + window.layerMVT=layerMVT; + }, + + addFeatures: function (features, filter,addToMap=true,featureTypes) { let featureGroup = new L.FeatureGroup(); features.forEach((feature) => { - + + let featureType=featureTypes.find((x)=>x.slug.split('-')[0]===''+feature.properties.feature_type_id); + if(feature.properties.feature_type != undefined){ + featureType=featureTypes.find((x)=>x.slug===''+feature.properties.feature_type); + } let filters = []; - + if (filter) { const typeCheck = filter.featureType && feature.properties.feature_type.slug === filter.featureType; const statusCheck = filter.featureStatus && feature.properties.status.value === filter.featureStatus; @@ -293,10 +394,13 @@ const mapUtil = { const geomJSON = flip(feature.geometry); const popupContent = this._createContentPopup(feature); - + let color=feature.properties.color; + if(color==undefined){ + color=featureType.color; + } if (geomJSON.type === 'Point') { L.circleMarker(geomJSON.coordinates, { - color: feature.properties.color, + color: color, radius: 4, fillOpacity: 0.5, weight: 3, @@ -305,14 +409,14 @@ const mapUtil = { .addTo(featureGroup); } else if (geomJSON.type === 'LineString') { L.polyline(geomJSON.coordinates, { - color: feature.properties.color, + color: color, weight: 3, }) .bindPopup(popupContent) .addTo(featureGroup); } else if (geomJSON.type === 'Polygon') { L.polygon(geomJSON.coordinates, { - color: feature.properties.color, + color: color, weight: 3, fillOpacity: 0.5, }) @@ -321,15 +425,39 @@ const mapUtil = { } } }); - map.addLayer(featureGroup); + if(addToMap){ + map.addLayer(featureGroup); + } + return featureGroup; }, - addMapEventListener: function (eventName, callback) { map.on(eventName, callback); }, - _createContentPopup: function (feature) { + _createContentPopup: function (feature,featureTypes,project_slug) { + const formatDate = (current_datetime)=>{ + let formatted_date = current_datetime.getFullYear() + "-" + ("0" + (current_datetime.getMonth() + 1)).slice(-2) + "-" + ("0" + current_datetime.getDate()).slice(-2) + " " + + ("0" + current_datetime.getHours()).slice(-2) + ":" + ("0" + current_datetime.getMinutes()).slice(-2); + return formatted_date; + } + let feature_type; + let status=feature.properties.status; + let date_maj=feature.properties.updated_on; + let feature_type_url=feature.properties.feature_type_url; + let feature_url=feature.properties.feature_url; + if(featureTypes){ // => VectorTile + feature_type=featureTypes.find((x)=>x.slug.split('-')[0]===''+feature.properties.feature_type_id); + status=statusList.find((x)=>x.value==feature.properties.status).name; + date_maj=formatDate(new Date(feature.properties.updated_on)); + feature_type_url='/geocontrib/projet/'+project_slug+'/type_signalement/'+feature_type.slug+'/'; + feature_url=feature_type_url+'signalement/'+feature.properties.feature_id+'/'; + //status=feature.properties.status; + }else{ + feature_type=feature.properties.feature_type; + status=feature.properties.status.label; + } + let author = ""; if (feature.properties.creator) { author = feature.properties.creator.full_name @@ -341,16 +469,16 @@ const mapUtil = { return ` <h4> - <a href="${feature.properties.feature_url}">${feature.properties.title}</a> + <a href="${feature_url}">${feature.properties.title}</a> </h4> <div> - Statut : ${feature.properties.status.label} + Statut : ${status} </div> <div> - Type : <a href="${feature.properties.feature_type_url}"> ${feature.properties.feature_type.title} </a> + Type : <a href="${feature_type_url}"> ${feature_type.title} </a> </div> <div> - Dernière mise à jour : ${feature.properties.updated_on} + Dernière mise à jour : ${date_maj} </div> ${author} `; diff --git a/src/assets/js/vector_tile_fix.js b/src/assets/js/vector_tile_fix.js new file mode 100644 index 0000000000000000000000000000000000000000..5bad33736f8a492d54f4b7595ece4f639a3f8bcf --- /dev/null +++ b/src/assets/js/vector_tile_fix.js @@ -0,0 +1,210 @@ +/* eslint-disable no-unused-vars */ +import L from "leaflet" +export var Symbolizer = L.Class.extend({ + // ðŸ‚method initialize(feature: GeoJSON, pxPerExtent: Number) + // Initializes a new Line Symbolizer given a GeoJSON feature and the + // pixel-to-coordinate-units ratio. Internal use only. + + // ðŸ‚method render(renderer, style) + // Renders this symbolizer in the given tiled renderer, with the given + // `L.Path` options. Internal use only. + render: function(renderer, style) { + this._renderer = renderer; + this.options = style; + renderer._initPath(this); + renderer._updateStyle(this); + }, + + // ðŸ‚method render(renderer, style) + // Updates the `L.Path` options used to style this symbolizer, and re-renders it. + // Internal use only. + updateStyle: function(renderer, style) { + this.options = style; + renderer._updateStyle(this); + }, + + _getPixelBounds: function() { + var parts = this._parts; + var bounds = L.bounds([]); + for (var i = 0; i < parts.length; i++) { + var part = parts[i]; + for (var j = 0; j < part.length; j++) { + bounds.extend(part[j]); + } + } + + var w = this._clickTolerance(), + p = new L.Point(w, w); + + bounds.min._subtract(p); + bounds.max._add(p); + + return bounds; + }, + _clickTolerance: L.Path.prototype._clickTolerance, +}) + +export var PolyBase = { + _makeFeatureParts: function(feat, pxPerExtent) { + var rings = feat.geometry; + var coord; + + this._parts = []; + for (var i = 0; i < rings.length; i++) { + var ring = rings[i]; + var part = []; + for (var j = 0; j < ring.length; j++) { + coord = ring[j]; + // Protobuf vector tiles return {x: , y:} + // Geojson-vt returns [,] + part.push(L.point(coord).scaleBy(pxPerExtent)); + } + this._parts.push(part); + } + }, + + makeInteractive: function() { + this._pxBounds = this._getPixelBounds(); + } +} +export var LineSymbolizer = L.Polyline.extend({ + includes: [Symbolizer.prototype, PolyBase], + + initialize: function(feature, pxPerExtent) { + this.properties = feature.properties; + this._makeFeatureParts(feature, pxPerExtent); + }, + + render: function(renderer, style) { + style.fill = false; + Symbolizer.prototype.render.call(this, renderer, style); + this._updatePath(); + }, + + updateStyle: function(renderer, style) { + style.fill = false; + Symbolizer.prototype.updateStyle.call(this, renderer, style); + }, +}) +export var FillSymbolizer = L.Polygon.extend({ + includes: [Symbolizer.prototype, PolyBase], + + initialize: function(feature, pxPerExtent) { + this.properties = feature.properties; + this._makeFeatureParts(feature, pxPerExtent); + }, + + render: function(renderer, style) { + Symbolizer.prototype.render.call(this, renderer, style); + this._updatePath(); + } +}) +export var PointSymbolizer = L.CircleMarker.extend({ + includes: Symbolizer.prototype, + + statics: { + iconCache: {} + }, + + initialize: function(feature, pxPerExtent) { + this.properties = feature.properties; + this._makeFeatureParts(feature, pxPerExtent); + }, + + render: function(renderer, style) { + Symbolizer.prototype.render.call(this, renderer, style); + this._radius = style.radius || L.CircleMarker.prototype.options.radius; + this._updatePath(); + }, + + _makeFeatureParts: function(feat, pxPerExtent) { + var coord = feat.geometry[0]; + if (typeof coord[0] === 'object' && 'x' in coord[0]) { + // Protobuf vector tiles return [{x: , y:}] + this._point = L.point(coord[0]).scaleBy(pxPerExtent); + this._empty = L.Util.falseFn; + } else { + // Geojson-vt returns [,] + this._point = L.point(coord).scaleBy(pxPerExtent); + this._empty = L.Util.falseFn; + } + }, + + makeInteractive: function() { + this._updateBounds(); + }, + + updateStyle: function(renderer, style) { + this._radius = style.radius || this._radius; + this._updateBounds(); + return Symbolizer.prototype.updateStyle.call(this, renderer, style); + }, + + _updateBounds: function() { + var icon = this.options.icon + if (icon) { + var size = L.point(icon.options.iconSize), + anchor = icon.options.iconAnchor || + size && size.divideBy(2, true), + p = this._point.subtract(anchor); + this._pxBounds = new L.Bounds(p, p.add(icon.options.iconSize)); + } else { + L.CircleMarker.prototype._updateBounds.call(this); + } + }, + + _updatePath: function() { + if (this.options.icon) { + this._renderer._updateIcon(this) + } else { + L.CircleMarker.prototype._updatePath.call(this); + } + }, + + _getImage: function () { + if (this.options.icon) { + var url = this.options.icon.options.iconUrl, + img = PointSymbolizer.iconCache[url]; + if (!img) { + var icon = this.options.icon; + img = PointSymbolizer.iconCache[url] = icon.createIcon(); + } + return img; + } else { + return null; + } + + }, + + _containsPoint: function(p) { + var icon = this.options.icon; + if (icon) { + return this._pxBounds.contains(p); + } else { + return L.CircleMarker.prototype._containsPoint.call(this, p); + } + } +}); + +L.VectorGrid.prototype._createLayer=function(feat, pxPerExtent, layerStyle) { + var layer; + switch (feat.type) { + case 1: + layer = new PointSymbolizer(feat, pxPerExtent); + // [YB 2019-10-23: prevent leaflet from treating these canvas points as real markers] + layer.getLatLng = null; + break; + case 2: + layer = new LineSymbolizer(feat, pxPerExtent); + break; + case 3: + layer = new FillSymbolizer(feat, pxPerExtent); + break; + } + + if (this.options.interactive) { + layer.addEventParent(this); + } + + return layer; + } \ No newline at end of file diff --git a/src/components/feature_type/FeatureTypeCustomForm.vue b/src/components/feature_type/FeatureTypeCustomForm.vue index 1fbe0d0b6c496325494db4bcaea8adf525e93fda..19e82015335a96fe05ec0bfdd7c5653c2bca796b 100644 --- a/src/components/feature_type/FeatureTypeCustomForm.vue +++ b/src/components/feature_type/FeatureTypeCustomForm.vue @@ -128,7 +128,7 @@ export default { Dropdown, }, - props: ["customForm"], + props: ["customForm", "selectedColorStyle"], data() { return { @@ -251,6 +251,7 @@ export default { } return false; }, + fillCustomFormData(customFormData) { for (let el in customFormData) { if (el && this.form[el] && customFormData[el]) { @@ -280,6 +281,9 @@ export default { options: this.form.options.value, }; this.$store.commit("feature_type/UPDATE_CUSTOM_FORM", data); + if (this.customForm.name === this.selectedColorStyle ) { + this.$emit("update", this.form.options.value); + } }, trimWhiteSpace(string) { diff --git a/src/views/feature/Feature_detail.vue b/src/views/feature/Feature_detail.vue index 20b2efdd4c21bf2338c90236bd85e92138ba4685..e69a936c8d90a3c5275f39d7502d6898329e4388 100644 --- a/src/views/feature/Feature_detail.vue +++ b/src/views/feature/Feature_detail.vue @@ -617,7 +617,7 @@ export default { const feature = response.data; if (feature) { const currentFeature = [feature]; - const featureGroup = mapUtil.addFeatures(currentFeature); + const featureGroup = mapUtil.addFeatures(currentFeature,{},true,this.$store.state.feature_type.feature_types); mapUtil .getMap() .fitBounds(featureGroup.getBounds(), { padding: [25, 25] }); diff --git a/src/views/feature/Feature_edit.vue b/src/views/feature/Feature_edit.vue index c00a15ce94c46530d1097ead7f1d01137d919399..15e572e03493e85d5ff4cd61f31d8448f437357c 100644 --- a/src/views/feature/Feature_edit.vue +++ b/src/views/feature/Feature_edit.vue @@ -917,7 +917,12 @@ export default { mapDefaultViewZoom, }); const currentFeatureId = this.$route.params.slug_signal; - + setTimeout( + function () { + mapUtil.addVectorTileLayer(this.$route.params.slug,this.$store.state.feature_type.feature_types); + }.bind(this), + 1000 + ); const url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.$route.params.slug}/feature/?feature_type__slug=${this.$route.params.slug_type_signal}&output=geojson`; axios .get(url) @@ -928,7 +933,7 @@ export default { const allFeaturesExceptCurrent = features.filter( (feat) => feat.id !== currentFeatureId ); - mapUtil.addFeatures(allFeaturesExceptCurrent); + mapUtil.addFeatures(allFeaturesExceptCurrent,{},false,this.$store.state.feature_type.feature_types); if (this.currentRouteName === "editer-signalement") { const currentFeature = features.filter( (feat) => feat.id === currentFeatureId diff --git a/src/views/feature/Feature_list.vue b/src/views/feature/Feature_list.vue index bb7fe27cf44a42808b4d8ed0f7c56f451d5d615d..f136b2be8f3cc49456b218c48ce68c8600b3bb3c 100644 --- a/src/views/feature/Feature_list.vue +++ b/src/views/feature/Feature_list.vue @@ -329,14 +329,27 @@ export default { if (this.featureGroup) { const features = this.filteredFeatures; this.featureGroup.clearLayers(); - this.featureGroup = mapUtil.addFeatures(features, {}); - mapUtil - .getMap() - .fitBounds(this.featureGroup.getBounds(), { padding: [25, 25] }); + this.featureGroup = mapUtil.addFeatures(features, {},false,this.$store.state.feature_type.feature_types); + mapUtil.getMap().invalidateSize(); + mapUtil.getMap()._onResize();// force refresh for vector tiles + + if(this.featureGroup.getLayers().length>0){ + mapUtil + .getMap() + .fitBounds(this.featureGroup.getBounds(), { padding: [25, 25] }); + } + else{ + mapUtil + .getMap() + .zoomOut(1); + } + + } }, initMap() { + console.log(this) this.zoom = this.$route.query.zoom || ""; this.lat = this.$route.query.lat || ""; this.lng = this.$route.query.lng || ""; @@ -360,26 +373,28 @@ export default { }); // --------- End sidebar events ---------- - const url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.$route.params.slug}/feature/?output=geojson`; - this.$store.commit( - "DISPLAY_LOADER", - "Récupération des signalements en cours..." - ); - axios - .get(url) - .then((response) => { - if (response.status === 200 && response.data.features.length > 0) { - this.loadFeatures(response.data.features); - } - this.$store.commit("DISCARD_LOADER"); - }) - .catch((error) => { - this.$store.commit("DISCARD_LOADER"); - throw error; - }); + const url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.$route.params.slug}/feature/?output=geojson`; + this.$store.commit( + "DISPLAY_LOADER", + "Récupération des signalements en cours..." + ); + axios + .get(url) + .then((response) => { + if (response.status === 200 && response.data.features.length > 0) { + this.loadFeatures(response.data.features); + } + this.$store.commit("DISCARD_LOADER"); + }) + .catch((error) => { + this.$store.commit("DISCARD_LOADER"); + throw error; + }); + setTimeout( function () { + mapUtil.addVectorTileLayer(this.$route.params.slug,this.$store.state.feature_type.feature_types,this.form); mapUtil.addGeocoders(this.$store.state.configuration); }.bind(this), 1000 @@ -396,7 +411,7 @@ export default { featureType, featureStatus, featureTitle, - }); + },false,this.$store.state.feature_type.feature_types); // Fit the map to bound only if no initial zoom and center are defined if ( (this.lat === "" || this.lng === "" || this.zoom === "") && diff --git a/src/views/feature_type/Feature_type_edit.vue b/src/views/feature_type/Feature_type_edit.vue index 26f0cba55c1d5986fd9996113c244c9fdcefb809..4478db72b1bd4153a0395cf63200a70d6c920942 100644 --- a/src/views/feature_type/Feature_type_edit.vue +++ b/src/views/feature_type/Feature_type_edit.vue @@ -98,17 +98,18 @@ </div> <div class="colors_selection" id="id_colors_selection" hidden> <div - v-for="(value, key, index) in form.colors_style.value.colors" + v-for="(value, key, index) in this.form.colors_style.value.colors" :key="'colors_style-' + index" - class="color-input" > - <label>{{ key }}</label - ><input - :name="key" - type="color" - :value="value" - @input="setColorStyles" - /> + <div v-if="key" class="color-input"> + <label>{{ key }}</label + ><input + :name="key" + type="color" + :value="value" + @input="setColorStyles" + /> + </div> </div> </div> </div> @@ -117,10 +118,12 @@ <div id="formsets"> <FeatureTypeCustomForm - v-for="form in customForms" - :key="form.dataKey" - :dataKey="form.dataKey" - :customForm="form" + v-for="customForm in customForms" + :key="customForm.dataKey" + :dataKey="customForm.dataKey" + :customForm="customForm" + :selectedColorStyle="form.colors_style.value.custom_field_name" + v-on:update="updateColorsStyle($event)" ref="customForms" /> </div> @@ -268,23 +271,34 @@ export default { }, selected_colors_style: { get() { - const value = this.form.colors_style.value.custom_field_name; - const customField = this.customForms.find((el) => el.name === value); + const name = this.form.colors_style.value.custom_field_name; + const customField = this.customForms.find((el) => el.name === name); return customField && customField.length !== 0 ? customField.label - : value; + : name; }, set(newValue) { - console.log(newValue); - const newColorsStyle = { - colors: newValue.options.reduce((obj, key) => { - obj[key] = "#000000"; - return obj; - }, {}), - custom_field_name: newValue.value, - }; - this.form.colors_style.value = newColorsStyle; - this.updateStore(); + + //* update only if different than custom_form + if (newValue.value !== this.form.colors_style.value.custom_field_name) { + //* get back values from original feature_type + if ( + newValue.value === this.feature_type.colors_style.custom_field_name + ) { + this.form.colors_style.value = this.feature_type.colors_style; + } else { + const newColorsStyle = { + colors: newValue.options.reduce((obj, key) => { + obj[key] = "#000000"; + return obj; + }, {}), + }; + this.form.colors_style.value = newColorsStyle; + this.updateStore(); + } + } + this.form.colors_style.value.custom_field_name = newValue.value; + this.form = { ...this.form }; //! force reactivity to update custom_field_name }, }, }, @@ -362,17 +376,6 @@ export default { } }, - updateColorsStyleInput(newValue) { - const newColorsStyle = { - colors: newValue.options.reduce((obj, key) => { - obj[key] = "#000000"; - return obj; - }, {}), - custom_field_name: newValue.value, - }; - this.form.colors_style.value = newColorsStyle; - }, - updateStore() { this.$store.commit("feature_type/UPDATE_FORM", { color: this.form.color, diff --git a/src/views/project/Project_detail.vue b/src/views/project/Project_detail.vue index d4a8636f340ea9e0a3189a21f33be644403afac6..a0c54f08b882dfd604a93aa729bffa98aa3a3fbb 100644 --- a/src/views/project/Project_detail.vue +++ b/src/views/project/Project_detail.vue @@ -642,46 +642,52 @@ export default { setTimeout(() => (this.infoMessage = ""), 3000); }); }, + initMap(){ + if (this.project && this.permissions.can_view_project) { + this.$store.dispatch("map/INITIATE_MAP"); + const url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.$route.params.slug}/feature/?output=geojson`; + let self = this; + this.checkForOfflineFeature(); + mapUtil.addVectorTileLayer(this.$route.params.slug,this.$store.state.feature_type.feature_types); + axios + .get(url) + .then((response) => { + let features = response.data.features; + self.arraysOffline.forEach(x=>x.geojson.properties.color="red"); + features=response.data.features.concat(self.arraysOffline.map(x=>x.geojson)); + const featureGroup = mapUtil.addFeatures(features,{},false,this.$store.state.feature_type.feature_types); + + if (featureGroup && featureGroup.getLayers().length > 0) { + mapUtil + .getMap() + .fitBounds(featureGroup.getBounds(), { padding: [25, 25] }); + this.$store.commit("map/SET_GEOJSON_FEATURES", features); + } else { + this.$store.commit("map/SET_GEOJSON_FEATURES", []); + } + }) + .catch((error) => { + throw error; + }); + + } + }, }, created() { - this.$store.dispatch("GET_PROJECT_INFO", this.slug); + + if (this.user) { projectAPI .getProjectSubscription({ projectSlug: this.$route.params.slug }) .then((data) => (this.is_suscriber = data.is_suscriber)); } }, + mounted() { - if (this.project && this.permissions.can_view_project) { - this.$store.dispatch("map/INITIATE_MAP"); - const url = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.$route.params.slug}/feature/?output=geojson`; - let self = this; - this.checkForOfflineFeature(); - axios - .get(url) - .then((response) => { - let features = response.data.features; - self.arraysOffline.forEach(x=>x.geojson.properties.color="red"); - features=response.data.features.concat(self.arraysOffline.map(x=>x.geojson)); - const featureGroup = mapUtil.addFeatures(features); - if (featureGroup && featureGroup.getLayers().length > 0) { - mapUtil - .getMap() - .fitBounds(featureGroup.getBounds(), { padding: [25, 25] }); - this.$store.commit("map/SET_GEOJSON_FEATURES", features); - } else { - this.$store.commit("map/SET_GEOJSON_FEATURES", []); - } - }) - .catch((error) => { - throw error; - }); - - - } - + let self=this; + this.$store.dispatch("GET_PROJECT_INFO", this.slug).then(setTimeout(self.initMap,1000)); if (this.message) { this.tempMessage = this.message; document