diff --git a/src/App.vue b/src/App.vue index 60b745a..d2e8393 100644 --- a/src/App.vue +++ b/src/App.vue @@ -91,7 +91,10 @@ export default { return this.$store.state.location.gpx.length > 0; }, isMapLoaded() { - return this.$store.state.map.center.every(item => item !== null); + return ( + this.$store.state.map.center.every(item => item !== null) + || this.$store.getters.getLastLocation + ); }, unsentReportsLength() { return this.$store.state.unsentReports.length; diff --git a/src/components/Map.vue b/src/components/Map.vue index 0b8358f..664df9b 100644 --- a/src/components/Map.vue +++ b/src/components/Map.vue @@ -78,7 +78,10 @@ export default { }, olCenter() { // Compute center in OL coordinates system - return fromLonLat([this.center[1], this.center[0]]); + if (this.center.every(item => item !== null)) { + return fromLonLat([this.center[1], this.center[0]]); + } + return this.center; }, olPolyline() { // Compute the polyline in OL coordinates system @@ -135,10 +138,10 @@ export default { attribution: $t('map.attribution'), hasUserAutorotateMap: this.$store.state.settings.shouldAutorotateMap, isProgrammaticMove: true, + isRecenterButtonShown: false, map: null, maxZoom: constants.MAX_ZOOM, minZoom: constants.MIN_ZOOM, - isRecenterButtonShown: false, // Variables for easy access to map feature and layers accuracyFeature: null, reportsMarkersFeatures: {}, @@ -217,16 +220,16 @@ export default { }, onMoveEnd() { const view = this.map.getView(); - if (this.onMapCenterUpdate) { + if (this.onMapCenterManualUpdate && !this.isProgrammaticMove) { const mapCenterLonLat = toLonLat(view.getCenter()); - this.onMapCenterUpdate([mapCenterLonLat[1], mapCenterLonLat[0]]); + this.onMapCenterManualUpdate([mapCenterLonLat[1], mapCenterLonLat[0]]); } // Show recenter button and call the callback if zoom is updated manually const zoom = view.getZoom(); if (zoom !== this.zoom) { this.showRecenterButton(); - if (this.onMapZoomUpdate) { - this.onMapZoomUpdate(zoom); + if (this.onMapZoomManualUpdate) { + this.onMapZoomManualUpdate(zoom); } } }, @@ -236,7 +239,7 @@ export default { this.hideRecenterButton(); const view = this.map.getView(); - view.setCenter(this.olCenter); + view.setCenter(this.olPosition); if (this.isInAutorotateMap) { view.setRotation(-this.headingInRadiansFromNorth); } else { @@ -309,6 +312,9 @@ export default { } }, showRecenterButton() { + if (!this.hasGeolocationTracking) { + return; + } if (!this.isRecenterButtonShown) { this.isRecenterButtonShown = true; } @@ -442,11 +448,12 @@ export default { type: Array, required: true, }, + hasGeolocationTracking: Boolean, heading: Number, // in degrees, clockwise wrt north markers: Array, onPress: Function, - onMapCenterUpdate: Function, - onMapZoomUpdate: Function, + onMapCenterManualUpdate: Function, + onMapZoomManualUpdate: Function, polyline: Array, positionLatLng: Array, reportLatLng: Array, @@ -499,7 +506,7 @@ export default { } const view = this.map.getView(); - if (!this.isRecenterButtonShown) { + if (!this.isRecenterButtonShown && newOlCenter.every(item => item !== null)) { // Eventually display closest report const isReportDetailsAlreadyShown = this.$store.state.reportDetails.id; const isReportDetailsOpenedByUser = this.$store.state.reportDetails.userAsked; @@ -536,6 +543,9 @@ export default { view.setRotation(0); } view.setZoom(this.zoom); + + // Show recenter button + this.showRecenterButton(); } }, olPolyline(newOlPolyline) { @@ -559,6 +569,11 @@ export default { ); this.accuracyFeature.getStyle().getImage().setRadius(this.radiusFromAccuracy); } + + // Update view center + if (!this.isRecenterButtonShown) { + this.map.getView().setCenter(newOlPosition); + } }, reportDetailsID(newID, oldID) { [oldID, newID].forEach((id) => { diff --git a/src/components/SearchModal.vue b/src/components/SearchModal.vue index f115612..8724ba4 100644 --- a/src/components/SearchModal.vue +++ b/src/components/SearchModal.vue @@ -58,13 +58,11 @@ export default { methods: { onManualLocationPicker(value) { this.isActive = false; - this.$router.push({ - name: 'SharedMap', - params: { - lat: value.latlng.lat, - lng: value.latlng.lng, - zoom: DEFAULT_ZOOM, - }, + this.$store.dispatch('setCurrentMapZoom', { + zoom: DEFAULT_ZOOM, + }); + this.$store.dispatch('setCurrentMapCenter', { + center: [value.latlng.lat, value.latlng.lng], }); }, }, diff --git a/src/constants.js b/src/constants.js index 8b48ee2..0d131fa 100644 --- a/src/constants.js +++ b/src/constants.js @@ -37,9 +37,12 @@ export const EARTH_RADIUS = 6378137; // in meters export const KEEP_REPORTS_METERS_AROUND = 10000; // in meters export const DEFAULT_ZOOM = 17; -export const MIN_ZOOM = 10; +export const MIN_ZOOM = 6; export const MAX_ZOOM = 18; +export const MAP_CENTER_WITHOUT_GEOLOCATION = [46.589, 2.944]; +export const MAP_ZOOM_WITHOUT_GEOLOCATION = 6; + export const ACCURACY_DISPLAY_THRESHOLD = 100; // in meters export const POSITION_MARKER_RADIUS = 10; // in pixels diff --git a/src/views/Map.vue b/src/views/Map.vue index 496916e..b293f2d 100644 --- a/src/views/Map.vue +++ b/src/views/Map.vue @@ -6,10 +6,11 @@ report_problem @@ -61,6 +62,10 @@ import AppLogo from '@/assets/logo.svg'; function handlePositionError(error) { store.dispatch('setLocationError', { error: error.code }); + store.dispatch('setCurrentMapZoom', { zoom: constants.MAP_ZOOM_WITHOUT_GEOLOCATION }); + store.dispatch('setCurrentMapCenter', { + center: constants.MAP_CENTER_WITHOUT_GEOLOCATION, + }); } function setPosition(position) { @@ -100,7 +105,7 @@ export default { currentSpeed() { if ( this.hasCenterProvidedByRoute - || !this.currentLocation + || !this.hasGeolocationTracking ) { return null; } @@ -124,6 +129,9 @@ export default { hasCenterProvidedByRoute() { return this.$route.params.lat && this.$route.params.lng; }, + hasGeolocationTracking() { + return Object.keys(this.currentLocation).length > 0; + }, mapCenter() { if (this.hasCenterProvidedByRoute) { return [ @@ -131,13 +139,25 @@ export default { parseFloat(this.$route.params.lng), ]; } - return this.currentLatLng; + if (this.$store.state.map.center.every(item => item !== null)) { + return this.$store.state.map.center; + } + if (!this.hasGeolocationTracking) { + return constants.MAP_CENTER_WITHOUT_GEOLOCATION; + } + return [null, null]; }, mapZoom() { + if (this.$route.params.zoom) { + return parseInt(this.$route.params.zoom, 10); + } + if (this.$store.state.map.zoom) { + return this.$store.state.map.zoom; + } return ( - this.$route.params.zoom - ? parseInt(this.$route.params.zoom, 10) - : constants.DEFAULT_ZOOM + this.hasGeolocationTracking + ? constants.DEFAULT_ZOOM + : constants.MAP_ZOOM_WITHOUT_GEOLOCATION ); }, positionHistory() { @@ -215,7 +235,7 @@ export default { } this.$store.dispatch('setLocationWatcherId', { id: watchID }); }, - onMapCenterUpdate(center) { + onMapCenterManualUpdate(center) { // Update reports by default let distanceFromPreviousPoint = constants.UPDATE_REPORTS_DISTANCE_THRESHOLD + 1; @@ -242,7 +262,7 @@ export default { this.$store.dispatch('setCurrentMapCenter', { center }); }, - onMapZoomUpdate(zoom) { + onMapZoomManualUpdate(zoom) { this.$store.dispatch('setCurrentMapZoom', { zoom }); }, removeNotification() {