Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • geocontrib/geocontrib-frontend
  • ext_matthieu/geocontrib-frontend
  • fnecas/geocontrib-frontend
  • MatthieuE/geocontrib-frontend
4 results
Show changes
...@@ -220,11 +220,32 @@ ...@@ -220,11 +220,32 @@
class="ui tab active map-container" class="ui tab active map-container"
data-tab="map" data-tab="map"
> >
<div
:class="{ active: mapLoading }"
class="ui inverted dimmer"
>
<div class="ui loader" />
</div>
<div <div
id="map" id="map"
ref="map" ref="map"
/> />
<div
id="popup"
class="ol-popup"
>
<a
id="popup-closer"
href="#"
class="ol-popup-closer"
/>
<div
id="popup-content"
/>
</div>
<SidebarLayers v-if="basemaps && map" /> <SidebarLayers v-if="basemaps && map" />
<EditingToolbar v-if="basemaps && map" />
</div> </div>
</div> </div>
...@@ -315,21 +336,21 @@ ...@@ -315,21 +336,21 @@
<script> <script>
import { mapState, mapGetters } from 'vuex'; import { mapState, mapGetters } from 'vuex';
import L from 'leaflet';
import 'leaflet-draw';
import axios from '@/axios-client.js';
import flip from '@turf/flip';
import featureAPI from '@/services/feature-api';
import { mapUtil } from '@/assets/js/map-util.js';
import { allowedStatus2change } from '@/utils';
import FeatureAttachmentForm from '@/components/Feature/FeatureAttachmentForm'; import FeatureAttachmentForm from '@/components/Feature/FeatureAttachmentForm';
import FeatureLinkedForm from '@/components/Feature/FeatureLinkedForm'; import FeatureLinkedForm from '@/components/Feature/FeatureLinkedForm';
import FeatureExtraForm from '@/components/Feature/Edit/FeatureExtraForm'; import FeatureExtraForm from '@/components/Feature/Edit/FeatureExtraForm';
import Dropdown from '@/components/Dropdown.vue'; import Dropdown from '@/components/Dropdown.vue';
import SidebarLayers from '@/components/SidebarLayers'; import SidebarLayers from '@/components/Map/SidebarLayers';
import EditingToolbar from '@/components/Map/EditingToolbar';
import featureAPI from '@/services/feature-api';
import mapService from '@/services/map-service';
import editionService from '@/services/edition-service';
import { allowedStatus2change } from '@/utils';
import axios from '@/axios-client.js';
import { GeoJSON } from 'ol/format';
export default { export default {
name: 'FeatureEdit', name: 'FeatureEdit',
...@@ -339,12 +360,14 @@ export default { ...@@ -339,12 +360,14 @@ export default {
FeatureLinkedForm, FeatureLinkedForm,
Dropdown, Dropdown,
SidebarLayers, SidebarLayers,
EditingToolbar,
FeatureExtraForm, FeatureExtraForm,
}, },
data() { data() {
return { return {
map: null, map: null,
mapLoading: false,
baseUrl: this.$store.state.configuration.BASE_URL, baseUrl: this.$store.state.configuration.BASE_URL,
file: null, file: null,
showGeoRef: false, showGeoRef: false,
...@@ -503,13 +526,6 @@ export default { ...@@ -503,13 +526,6 @@ export default {
this.initMap(); this.initMap();
this.onFeatureTypeLoaded(); this.onFeatureTypeLoaded();
this.initExtraForms(this.feature); this.initExtraForms(this.feature);
setTimeout(
function () {
mapUtil.addGeocoders(this.$store.state.configuration);
}.bind(this),
1000
);
}); });
}, },
...@@ -538,15 +554,23 @@ export default { ...@@ -538,15 +554,23 @@ export default {
this.updateStore(); this.updateStore();
} }
}, },
addPointToCoordinates(coordinates){
let json = {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: coordinates,
},
properties: {},
};
this.updateMap(json);
this.updateGeomField(json.geometry);
this.showGeoPositionBtn = false;
this.erreurGeolocalisationMessage = '';
},
create_point_geoposition() { create_point_geoposition() {
function success(position) { function success(position) {
const latitude = position.coords.latitude; this.addPointToCoordinates([position.coords.longitude, position.coords.latitude]);
const longitude = position.coords.longitude;
var layer = L.circleMarker([latitude, longitude]);
this.add_layer_call_back(layer);
this.map.setView([latitude, longitude]);
} }
function error(err) { function error(err) {
...@@ -596,16 +620,7 @@ export default { ...@@ -596,16 +620,7 @@ export default {
if (response.data.geom.indexOf('POINT') >= 0) { if (response.data.geom.indexOf('POINT') >= 0) {
const regexp = /POINT\s\((.*)\s(.*)\)/; const regexp = /POINT\s\((.*)\s(.*)\)/;
const arr = regexp.exec(response.data.geom); const arr = regexp.exec(response.data.geom);
const json = { this.addPointToCoordinates([parseFloat(arr[1]), parseFloat(arr[2])]);
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [parseFloat(arr[1]), parseFloat(arr[2])],
},
properties: {},
};
this.updateMap(json);
this.updateGeomField(json);
// Set Attachment // Set Attachment
this.addAttachment({ this.addAttachment({
title: 'Localisation', title: 'Localisation',
...@@ -777,175 +792,23 @@ export default { ...@@ -777,175 +792,23 @@ export default {
//* ************* MAP *************** *// //* ************* MAP *************** *//
onFeatureTypeLoaded() { onFeatureTypeLoaded() {
var geomLeaflet = {
point: 'circlemarker',
linestring: 'polyline',
polygon: 'polygon',
};
var geomType = this.feature_type.geom_type; var geomType = this.feature_type.geom_type;
var drawConfig = { editionService.addEditionControls(geomType);
polygon: false, editionService.draw.on('drawend', (evt) => {
marker: false, var feature = evt.feature;
polyline: false, this.updateGeomField(new GeoJSON().writeGeometry(feature.getGeometry(),{ dataProjection:'EPSG:4326',featureProjection:'EPSG:3857' }));
rectangle: false, if (this.feature_type.geomType === 'point') {
circle: false, this.showGeoPositionBtn = false;
circlemarker: false, this.erreurGeolocalisationMessage = '';
}; }
drawConfig[geomLeaflet[geomType]] = true;
L.drawLocal = {
draw: {
toolbar: {
actions: {
title: 'Annuler le dessin',
text: 'Annuler',
},
finish: {
title: 'Terminer le dessin',
text: 'Terminer',
},
undo: {
title: 'Supprimer le dernier point dessiné',
text: 'Supprimer le dernier point',
},
buttons: {
polyline: 'Dessiner une polyligne',
polygon: 'Dessiner un polygone',
rectangle: 'Dessiner un rectangle',
circle: 'Dessiner un cercle',
marker: 'Dessiner une balise',
circlemarker: 'Dessiner un point',
},
},
handlers: {
circle: {
tooltip: {
start: 'Cliquer et glisser pour dessiner le cercle.',
},
radius: 'Rayon',
},
circlemarker: {
tooltip: {
start: 'Cliquer sur la carte pour placer le point.',
},
},
marker: {
tooltip: {
start: 'Cliquer sur la carte pour placer la balise.',
},
},
polygon: {
tooltip: {
start: 'Cliquer pour commencer à dessiner.',
cont: 'Cliquer pour continuer à dessiner.',
end: 'Cliquer sur le premier point pour terminer le dessin.',
},
},
polyline: {
error: '<strong>Error:</strong> shape edges cannot cross!',
tooltip: {
start: 'Cliquer pour commencer à dessiner.',
cont: 'Cliquer pour continuer à dessiner.',
end: 'Cliquer sur le dernier point pour terminer le dessin.',
},
},
rectangle: {
tooltip: {
start: 'Cliquer et glisser pour dessiner le rectangle.',
},
},
simpleshape: {
tooltip: {
end: 'Relâcher la souris pour terminer de dessiner.',
},
},
},
},
edit: {
toolbar: {
actions: {
save: {
title: 'Sauver les modifications',
text: 'Sauver',
},
cancel: {
title:
'Annuler la modification, annule toutes les modifications',
text: 'Annuler',
},
clearAll: {
title: "Effacer l'objet",
text: 'Effacer',
},
},
buttons: {
edit: "Modifier l'objet",
editDisabled: 'Aucun objet à modifier',
remove: "Supprimer l'objet",
removeDisabled: 'Aucun objet à supprimer',
},
},
handlers: {
edit: {
tooltip: {
text: "Faites glisser les marqueurs ou les balises pour modifier l'élément.",
subtext: 'Cliquez sur Annuler pour annuler les modifications..',
},
},
remove: {
tooltip: {
text: 'Cliquez sur un élément pour le supprimer.',
},
},
},
},
};
this.drawnItems = new L.FeatureGroup();
this.map.addLayer(this.drawnItems);
this.drawControlFull = new L.Control.Draw({
position: 'topright',
edit: {
featureGroup: this.drawnItems,
},
draw: drawConfig,
}); });
editionService.modify.on('modifyend', (evt) => {
this.drawControlEditOnly = new L.Control.Draw({ let feature = evt.features.getArray()[0];
position: 'topright', this.updateGeomField(new GeoJSON().writeGeometry(feature.getGeometry(),{ dataProjection:'EPSG:4326',featureProjection:'EPSG:3857' }));
edit: {
featureGroup: this.drawnItems,
},
draw: false,
}); });
//this.changeMobileBtnOrder();
if (this.currentRouteName === 'editer-signalement') {
this.map.addControl(this.drawControlEditOnly);
} else {
this.map.addControl(this.drawControlFull);
}
this.changeMobileBtnOrder();
this.map.on(
'draw:created',
function (e) {
var layer = e.layer;
this.add_layer_call_back(layer);
}.bind(this)
);
//var wellknown;// TODO Remplacer par autre chose
this.map.on(
'draw:edited',
function (e) {
var layers = e.layers;
const self = this;
layers.eachLayer(function (layer) {
self.updateGeomField(layer.toGeoJSON());
});
}.bind(this)
);
this.map.on( this.map.on(
'draw:deleted', 'draw:deleted',
...@@ -962,20 +825,13 @@ export default { ...@@ -962,20 +825,13 @@ export default {
}, },
updateMap(geomFeatureJSON) { updateMap(geomFeatureJSON) {
if (this.drawnItems) { if (editionService.drawSource) {
this.drawnItems.clearLayers(); editionService.drawSource.clear();
} }
var geomType = this.feature_type.geom_type;
if (geomFeatureJSON) { if (geomFeatureJSON) {
var geomJSON = flip(geomFeatureJSON.geometry); let retour = new GeoJSON().readFeature(geomFeatureJSON,{ dataProjection:'EPSG:4326',featureProjection:'EPSG:3857' });
if (geomType === 'point') { editionService.startEditFeature(retour);
L.circleMarker(geomJSON.coordinates).addTo(this.drawnItems);
} else if (geomType === 'linestring') {
L.polyline(geomJSON.coordinates).addTo(this.drawnItems);
} else if (geomType === 'polygon') {
L.polygon(geomJSON.coordinates).addTo(this.drawnItems);
}
this.map.fitBounds(this.drawnItems.getBounds(), { padding: [25, 25] });
} else { } else {
this.map.setView( this.map.setView(
this.$store.state.configuration.DEFAULT_MAP_VIEW.center, this.$store.state.configuration.DEFAULT_MAP_VIEW.center,
...@@ -985,32 +841,24 @@ export default { ...@@ -985,32 +841,24 @@ export default {
}, },
updateGeomField(newGeom) { updateGeomField(newGeom) {
this.form.geom.value = newGeom.geometry; this.form.geom.value = newGeom;
this.updateStore(); this.updateStore();
}, },
initMap() { initMap() {
this.mapLoading = true;
var mapDefaultViewCenter = var mapDefaultViewCenter =
this.$store.state.configuration.DEFAULT_MAP_VIEW.center; this.$store.state.configuration.DEFAULT_MAP_VIEW.center;
var mapDefaultViewZoom = var mapDefaultViewZoom =
this.$store.state.configuration.DEFAULT_MAP_VIEW.zoom; this.$store.state.configuration.DEFAULT_MAP_VIEW.zoom;
// Create the map, then init the layers and features // Create the map, then init the layers and features
this.map = mapUtil.createMap(this.$refs.map, { this.map = mapService.createMap(this.$refs.map, {
mapDefaultViewCenter, mapDefaultViewCenter,
mapDefaultViewZoom, mapDefaultViewZoom,
interactions : { doubleClickZoom :false, mouseWheelZoom:true, dragPan:true }
}); });
const currentFeatureId = this.$route.params.slug_signal; const currentFeatureId = this.$route.params.slug_signal;
setTimeout(() => {
const project_id = this.$route.params.slug.split('-')[0];
const mvtUrl = `${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}features.mvt/?tile={z}/{x}/{y}&project_id=${project_id}`;
mapUtil.addVectorTileLayer(
mvtUrl,
this.$route.params.slug,
this.feature_types
);
}, 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`; 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 axios
.get(url) .get(url)
...@@ -1020,7 +868,7 @@ export default { ...@@ -1020,7 +868,7 @@ export default {
const allFeaturesExceptCurrent = features.filter( const allFeaturesExceptCurrent = features.filter(
(feat) => feat.id !== currentFeatureId (feat) => feat.id !== currentFeatureId
); );
mapUtil.addFeatures( mapService.addFeatures(
allFeaturesExceptCurrent, allFeaturesExceptCurrent,
{}, {},
true, true,
...@@ -1033,30 +881,21 @@ export default { ...@@ -1033,30 +881,21 @@ export default {
this.updateMap(currentFeature); this.updateMap(currentFeature);
} }
} }
this.mapLoading = false;
}) })
.catch((error) => { .catch((error) => {
this.mapLoading = false;
throw error; throw error;
}); });
document.addEventListener('change-layers-order', (event) => { document.addEventListener('change-layers-order', (event) => {
// Reverse is done because the first layer in order has to be added in the map in last. // 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 // Slice is done because reverse() changes the original array, so we make a copy first
mapUtil.updateOrder(event.detail.layers.slice().reverse()); mapService.updateOrder(event.detail.layers.slice().reverse());
}); });
}, },
add_layer_call_back(layer) { // TODO DDS voir adaptations
layer.addTo(this.drawnItems);
this.drawControlFull.remove(this.map);
this.drawControlEditOnly.addTo(this.map);
//var wellknown;// TODO Remplacer par autre chose
this.updateGeomField(layer.toGeoJSON());
if (this.feature_type.geomType === 'point') {
this.showGeoPositionBtn = false;
this.erreurGeolocalisationMessage = '';
}
},
changeMobileBtnOrder() { //* move large toolbar for polygon creation, cutting map in the middle changeMobileBtnOrder() { //* move large toolbar for polygon creation, cutting map in the middle
function changeDisplay() { function changeDisplay() {
const buttons = document.querySelector('.leaflet-draw-actions.leaflet-draw-actions-top.leaflet-draw-actions-bottom'); const buttons = document.querySelector('.leaflet-draw-actions.leaflet-draw-actions-top.leaflet-draw-actions-bottom');
......
...@@ -103,7 +103,10 @@ ...@@ -103,7 +103,10 @@
@change="onGeojsonFileChange" @change="onGeojsonFileChange"
> >
</div> </div>
<div class="field"> <div
v-if="structure.geom_type === 'point'"
class="field"
>
<label <label
class="ui icon button ellipsis" class="ui icon button ellipsis"
for="csv_file" for="csv_file"
...@@ -195,11 +198,15 @@ ...@@ -195,11 +198,15 @@
<option value="GeoJSON"> <option value="GeoJSON">
GeoJSON GeoJSON
</option> </option>
<option value="CSV"> <option
v-if="structure.geom_type === 'point'"
value="CSV"
>
CSV CSV
</option> </option>
</select> </select>
<button <button
:class="{ loading: exportLoading }"
type="button" type="button"
class="ui fluid teal icon button" class="ui fluid teal icon button"
@click="exportFeatures" @click="exportFeatures"
...@@ -394,7 +401,8 @@ export default { ...@@ -394,7 +401,8 @@ export default {
loadingImportFile: false, loadingImportFile: false,
waitMessage: false, waitMessage: false,
reloadingImport: false, reloadingImport: false,
exportFormat: 'GeoJSON' exportFormat: 'GeoJSON',
exportLoading: false
}; };
}, },
...@@ -773,20 +781,26 @@ export default { ...@@ -773,20 +781,26 @@ export default {
}, },
exportFeatures() { exportFeatures() {
this.exportLoading = true;
const url = ` const url = `
${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.slug}/feature-type/${this.$route.params.feature_type_slug}/export/?format_export=${this.exportFormat.toLowerCase()} ${this.$store.state.configuration.VUE_APP_DJANGO_API_BASE}projects/${this.slug}/feature-type/${this.$route.params.feature_type_slug}/export/?format_export=${this.exportFormat.toLowerCase()}
`; `;
featureAPI.getFeaturesBlob(url).then((blob) => { featureAPI.getFeaturesBlob(url)
if (blob) { .then((blob) => {
const link = document.createElement('a'); if (blob) {
link.href = URL.createObjectURL(blob); const link = document.createElement('a');
link.download = `${this.project.title}-${this.structure.title}.${this.exportFormat === 'GeoJSON' ? 'json' : 'csv'}`; link.href = URL.createObjectURL(blob);
link.click(); link.download = `${this.project.title}-${this.structure.title}.${this.exportFormat === 'GeoJSON' ? 'json' : 'csv'}`;
setTimeout(function(){ link.click();
URL.revokeObjectURL(link.href); setTimeout(function(){
}, 1000); URL.revokeObjectURL(link.href);
} }, 1000);
}); }
this.exportLoading = false;
})
.catch(() => {
this.exportLoading = false;
});
}, },
async getLastFeatures(){ async getLastFeatures(){
const response = await const response = await
......
...@@ -151,7 +151,7 @@ ...@@ -151,7 +151,7 @@
class="white save icon" class="white save icon"
aria-hidden="true" aria-hidden="true"
/> />
Créer et importer le(s) signalement(s) du geojson Créer et importer le(s) signalement(s) du {{ geojson ? 'geojson' : 'csv' }}
</button> </button>
</div> </div>
</form> </form>
......
...@@ -25,8 +25,21 @@ ...@@ -25,8 +25,21 @@
ref="map" ref="map"
/> />
<SidebarLayers v-if="basemaps && map" /> <SidebarLayers v-if="basemaps && map" />
<Geocoder />
<div
id="popup"
class="ol-popup"
>
<a
id="popup-closer"
href="#"
class="ol-popup-closer"
/>
<div
id="popup-content"
/>
</div>
</div> </div>
<FeatureListTable <FeatureListTable
v-else v-else
:paginated-features="paginatedFeatures" :paginated-features="paginatedFeatures"
...@@ -38,42 +51,43 @@ ...@@ -38,42 +51,43 @@
@update:page="handlePageChange" @update:page="handlePageChange"
@update:sort="handleSortChange" @update:sort="handleSortChange"
/> />
</div>
<!-- MODAL ALL DELETE FEATURE TYPE -->
<div <!-- MODAL ALL DELETE FEATURE TYPE -->
v-if="isDeleteModalOpen"
class="ui dimmer modals page transition visible active"
style="display: flex !important"
>
<div <div
:class="[ v-if="isDeleteModalOpen"
'ui mini modal subscription', class="ui dimmer modals page transition visible active"
{ 'active visible': isDeleteModalOpen }, style="display: flex !important"
]"
> >
<i <div
class="close icon" :class="[
aria-hidden="true" 'ui mini modal subscription',
@click="isDeleteModalOpen = false" { 'active visible': isDeleteModalOpen },
/> ]"
<div class="ui icon header"> >
<i <i
class="trash alternate icon" class="close icon"
aria-hidden="true" aria-hidden="true"
@click="isDeleteModalOpen = false"
/> />
Êtes-vous sûr de vouloir effacer <div class="ui icon header">
<span v-if="checkedFeatures.length === 1"> un signalement ? </span> <i
<span v-else> ces {{ checkedFeatures.length }} signalements ? </span> class="trash alternate icon"
</div> aria-hidden="true"
<div class="actions"> />
<button Êtes-vous sûr de vouloir effacer
type="button" <span v-if="checkedFeatures.length === 1"> un signalement ? </span>
class="ui red compact fluid button" <span v-else> ces {{ checkedFeatures.length }} signalements ? </span>
@click="deleteAllFeatureSelection" </div>
> <div class="actions">
Confirmer la suppression <button
</button> type="button"
class="ui red compact fluid button"
@click="deleteAllFeatureSelection"
>
Confirmer la suppression
</button>
</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -83,12 +97,12 @@ ...@@ -83,12 +97,12 @@
<script> <script>
import { mapState, mapActions, mapMutations } from 'vuex'; import { mapState, mapActions, mapMutations } from 'vuex';
import { mapUtil } from '@/assets/js/map-util.js'; import mapService from '@/services/map-service';
import Geocoder from '@/components/Map/Geocoder';
import featureAPI from '@/services/feature-api'; import featureAPI from '@/services/feature-api';
import FeaturesListAndMapFilters from '@/components/Project/FeaturesListAndMap/FeaturesListAndMapFilters'; import FeaturesListAndMapFilters from '@/components/Project/FeaturesListAndMap/FeaturesListAndMapFilters';
import SidebarLayers from '@/components/SidebarLayers'; import SidebarLayers from '@/components/Map/SidebarLayers';
import FeatureListTable from '@/components/Project/FeaturesListAndMap/FeatureListTable'; import FeatureListTable from '@/components/Project/FeaturesListAndMap/FeatureListTable';
const initialPagination = { const initialPagination = {
...@@ -104,6 +118,7 @@ export default { ...@@ -104,6 +118,7 @@ export default {
components: { components: {
FeaturesListAndMapFilters, FeaturesListAndMapFilters,
SidebarLayers, SidebarLayers,
Geocoder,
FeatureListTable, FeatureListTable,
}, },
...@@ -163,20 +178,20 @@ export default { ...@@ -163,20 +178,20 @@ export default {
}, },
watch: { watch: {
map(newValue) { /*map(newValue) {
if (newValue && this.paginatedFeatures && this.paginatedFeatures.length) { if (newValue && this.paginatedFeatures && this.paginatedFeatures.length) {
if (this.currentLayer) { if (this.currentLayer) {
this.map.removeLayer(this.currentLayer); this.map.removeLayer(this.currentLayer);
} }
this.currentLayer = mapUtil.addFeatures( this.currentLayer = mapService.addFeatures(
this.paginatedFeatures, this.paginatedFeatures,
{}, {},
true, true,
this.feature_types this.feature_types
); );
} }
}, },*/
paginatedFeatures: { /*paginatedFeatures: {
deep: true, deep: true,
handler(newValue, oldValue) { handler(newValue, oldValue) {
if (newValue && newValue.length && newValue !== oldValue && this.map) { if (newValue && newValue.length && newValue !== oldValue && this.map) {
...@@ -184,7 +199,7 @@ export default { ...@@ -184,7 +199,7 @@ export default {
this.map.removeLayer(this.currentLayer); this.map.removeLayer(this.currentLayer);
this.currentLayer = null; this.currentLayer = null;
} }
this.currentLayer = mapUtil.addFeatures( this.currentLayer = mapService.addFeatures(
newValue, newValue,
{}, {},
true, true,
...@@ -197,7 +212,7 @@ export default { ...@@ -197,7 +212,7 @@ export default {
} }
} }
} }
}, },*/
}, },
mounted() { mounted() {
...@@ -210,7 +225,7 @@ export default { ...@@ -210,7 +225,7 @@ export default {
} else { } else {
this.initMap(); this.initMap();
} }
this.fetchPagedFeatures();
window.addEventListener('mousedown', this.clickOutsideDropdown); window.addEventListener('mousedown', this.clickOutsideDropdown);
}, },
...@@ -322,12 +337,8 @@ export default { ...@@ -322,12 +337,8 @@ export default {
}, },
onFilterChange() { onFilterChange() {
if (mapUtil.getMap()) { if (mapService.getMap() && mapService.mvtLayer) {
mapUtil.getMap().invalidateSize(); mapService.mvtLayer.changed();
mapUtil.getMap()._onResize(); // force refresh for vector tiles
if (window.layerMVT) {
window.layerMVT.redraw();
}
} }
}, },
...@@ -341,44 +352,46 @@ export default { ...@@ -341,44 +352,46 @@ export default {
var mapDefaultViewZoom = var mapDefaultViewZoom =
this.$store.state.configuration.DEFAULT_MAP_VIEW.zoom; this.$store.state.configuration.DEFAULT_MAP_VIEW.zoom;
this.map = mapUtil.createMap(this.$refs.map, { this.map = mapService.createMap(this.$refs.map, {
zoom: this.zoom, zoom: this.zoom,
lat: this.lat, lat: this.lat,
lng: this.lng, lng: this.lng,
mapDefaultViewCenter, mapDefaultViewCenter,
mapDefaultViewZoom, mapDefaultViewZoom,
interactions : { doubleClickZoom :false,mouseWheelZoom:true,dragPan:true }
}); });
this.fetchBboxNfit(); //this.fetchBboxNfit(); cette methode est appelée a nouveau par la suite donc pas utile ici
document.addEventListener('change-layers-order', (event) => { document.addEventListener('change-layers-order', (event) => {
// Reverse is done because the first layer in order has to be added in the map in last. // 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 // Slice is done because reverse() changes the original array, so we make a copy first
mapUtil.updateOrder(event.detail.layers.slice().reverse()); mapService.updateOrder(event.detail.layers.slice().reverse());
}); });
// --------- End sidebar events ---------- // --------- End sidebar events ----------
let self=this;
setTimeout(() => { setTimeout(() => {
const project_id = this.projectSlug.split('-')[0]; const project_id = this.projectSlug.split('-')[0];
const mvtUrl = `${this.API_BASE_URL}features.mvt/?tile={z}/{x}/{y}&project_id=${project_id}`; const mvtUrl = `${this.API_BASE_URL}features.mvt/`;
mapUtil.addVectorTileLayer( mapService.addVectorTileLayer(
mvtUrl, mvtUrl,
this.projectSlug, project_id,
this.feature_types, self.projectSlug,
this.form self.feature_types,
self.form
); );
mapUtil.addGeocoders(this.$store.state.configuration);
}, 1000); }, 1000);
this.fetchPagedFeatures();
}, },
fetchBboxNfit(queryParams) { fetchBboxNfit(queryParams) {
featureAPI featureAPI
.getFeaturesBbox(this.projectSlug, queryParams) .getFeaturesBbox(this.projectSlug, queryParams)
.then((bbox) => { .then((bbox) => {
const map = mapUtil.getMap(); if (bbox) {
if (bbox && map) { mapService.fitBounds(bbox);
map.fitBounds(bbox, { padding: [25, 25] });
} }
}); });
}, },
...@@ -445,8 +458,8 @@ export default { ...@@ -445,8 +458,8 @@ export default {
//* bbox needs to be updated with the same filters //* bbox needs to be updated with the same filters
if (this.paginatedFeatures.length) { if (this.paginatedFeatures.length) {
this.fetchBboxNfit(queryString); this.fetchBboxNfit(queryString);
this.onFilterChange(); //* use paginated event to watch change in filters and modify features on map
} }
this.onFilterChange(); //* use paginated event to watch change in filters and modify features on map
this.$store.commit('DISCARD_LOADER'); this.$store.commit('DISCARD_LOADER');
}); });
}, },
......
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
/> />
</div> </div>
<div class="eight wide column"> <div class="eight wide column map-container">
<div <div
:class="{ active: mapLoading }" :class="{ active: mapLoading }"
class="ui inverted dimmer" class="ui inverted dimmer"
...@@ -70,10 +70,36 @@ ...@@ -70,10 +70,36 @@
Chargement de la carte... Chargement de la carte...
</div> </div>
</div> </div>
<div <div
id="map" id="map"
ref="map" ref="map"
/> />
<div
class="ui button fluid teal"
@click="$router.push({
name: 'liste-signalements',
params: { slug: slug },
})"
>
<i class="ui icon arrow right" />
Voir tous les signalements
</div>
<div
id="popup"
class="ol-popup"
>
<a
id="popup-closer"
href="#"
class="ol-popup-closer"
/>
<div
id="popup-content"
/>
</div>
</div> </div>
</div> </div>
...@@ -118,7 +144,7 @@ ...@@ -118,7 +144,7 @@
</template> </template>
<script> <script>
import { mapUtil } from '@/assets/js/map-util.js'; import mapService from '@/services/map-service';
import { mapGetters, mapState, mapActions, mapMutations } from 'vuex'; import { mapGetters, mapState, mapActions, mapMutations } from 'vuex';
import projectAPI from '@/services/project-api'; import projectAPI from '@/services/project-api';
...@@ -282,10 +308,8 @@ export default { ...@@ -282,10 +308,8 @@ export default {
this.DISCARD_LOADER(); this.DISCARD_LOADER();
this.projectInfoLoading = false; this.projectInfoLoading = false;
setTimeout(() => { setTimeout(() => {
const map = mapUtil.getMap(); let map = mapService.getMap();
if (map) { if (map) mapService.destroyMap();
map.remove();
}
this.initMap(); this.initMap();
}, 1000); }, 1000);
}) })
...@@ -412,10 +436,11 @@ export default { ...@@ -412,10 +436,11 @@ export default {
if (this.project && this.permissions.can_view_project) { if (this.project && this.permissions.can_view_project) {
await this.INITIATE_MAP(this.$refs.map); await this.INITIATE_MAP(this.$refs.map);
this.checkForOfflineFeature(); this.checkForOfflineFeature();
const project_id = this.$route.params.slug.split('-')[0]; let project_id = this.$route.params.slug.split('-')[0];
const mvtUrl = `${this.API_BASE_URL}features.mvt/?tile={z}/{x}/{y}&project_id=${project_id}`; const mvtUrl = `${this.API_BASE_URL}features.mvt/`;
mapUtil.addVectorTileLayer( mapService.addVectorTileLayer(
mvtUrl, mvtUrl,
project_id,
this.$route.params.slug, this.$route.params.slug,
this.feature_types this.feature_types
); );
...@@ -431,7 +456,7 @@ export default { ...@@ -431,7 +456,7 @@ export default {
}) })
.then(() => { .then(() => {
this.featuresLoading = false; this.featuresLoading = false;
mapUtil.addFeatures( mapService.addFeatures(
[...this.features, ...featuresOffline], [...this.features, ...featuresOffline],
{}, {},
true, true,
...@@ -445,7 +470,7 @@ export default { ...@@ -445,7 +470,7 @@ export default {
featureAPI.getFeaturesBbox(this.slug).then((bbox) => { featureAPI.getFeaturesBbox(this.slug).then((bbox) => {
if (bbox) { if (bbox) {
mapUtil.getMap().fitBounds(bbox, { padding: [25, 25] }); mapService.fitBounds(bbox);
} }
}); });
} }
...@@ -454,10 +479,19 @@ export default { ...@@ -454,10 +479,19 @@ export default {
}; };
</script> </script>
<style scoped> <style lang="less" scoped>
.fullwidth { .fullwidth {
width: 100%; width: 100%;
} }
.map-container {
display: flex !important;
flex-direction: column;
.button {
margin-top: 0.5em;
}
}
</style> </style>
...@@ -62,7 +62,10 @@ ...@@ -62,7 +62,10 @@
id="form-members" id="form-members"
class="ui form" class="ui form"
> >
<table class="ui red table"> <table
class="ui red table"
aria-describedby="Table des membres du projet"
>
<thead> <thead>
<tr> <tr>
<th scope="col"> <th scope="col">
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
? require('@/assets/img/default.png') ? require('@/assets/img/default.png')
: DJANGO_BASE_URL + project.thumbnail + refreshId() : DJANGO_BASE_URL + project.thumbnail + refreshId()
" "
alt="Image associé au projet"
> >
</div> </div>
<div class="middle aligned content"> <div class="middle aligned content">
......