Rework the way Map is initialized

This commit is contained in:
Lucas Verney 2018-11-07 22:25:31 +01:00
parent 944b9842cb
commit 22c68454ec
5 changed files with 68 additions and 29 deletions

View File

@ -91,7 +91,10 @@ export default {
return this.$store.state.location.gpx.length > 0; return this.$store.state.location.gpx.length > 0;
}, },
isMapLoaded() { 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() { unsentReportsLength() {
return this.$store.state.unsentReports.length; return this.$store.state.unsentReports.length;

View File

@ -78,7 +78,10 @@ export default {
}, },
olCenter() { olCenter() {
// Compute center in OL coordinates system // Compute center in OL coordinates system
if (this.center.every(item => item !== null)) {
return fromLonLat([this.center[1], this.center[0]]); return fromLonLat([this.center[1], this.center[0]]);
}
return this.center;
}, },
olPolyline() { olPolyline() {
// Compute the polyline in OL coordinates system // Compute the polyline in OL coordinates system
@ -135,10 +138,10 @@ export default {
attribution: $t('map.attribution'), attribution: $t('map.attribution'),
hasUserAutorotateMap: this.$store.state.settings.shouldAutorotateMap, hasUserAutorotateMap: this.$store.state.settings.shouldAutorotateMap,
isProgrammaticMove: true, isProgrammaticMove: true,
isRecenterButtonShown: false,
map: null, map: null,
maxZoom: constants.MAX_ZOOM, maxZoom: constants.MAX_ZOOM,
minZoom: constants.MIN_ZOOM, minZoom: constants.MIN_ZOOM,
isRecenterButtonShown: false,
// Variables for easy access to map feature and layers // Variables for easy access to map feature and layers
accuracyFeature: null, accuracyFeature: null,
reportsMarkersFeatures: {}, reportsMarkersFeatures: {},
@ -217,16 +220,16 @@ export default {
}, },
onMoveEnd() { onMoveEnd() {
const view = this.map.getView(); const view = this.map.getView();
if (this.onMapCenterUpdate) { if (this.onMapCenterManualUpdate && !this.isProgrammaticMove) {
const mapCenterLonLat = toLonLat(view.getCenter()); 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 // Show recenter button and call the callback if zoom is updated manually
const zoom = view.getZoom(); const zoom = view.getZoom();
if (zoom !== this.zoom) { if (zoom !== this.zoom) {
this.showRecenterButton(); this.showRecenterButton();
if (this.onMapZoomUpdate) { if (this.onMapZoomManualUpdate) {
this.onMapZoomUpdate(zoom); this.onMapZoomManualUpdate(zoom);
} }
} }
}, },
@ -236,7 +239,7 @@ export default {
this.hideRecenterButton(); this.hideRecenterButton();
const view = this.map.getView(); const view = this.map.getView();
view.setCenter(this.olCenter); view.setCenter(this.olPosition);
if (this.isInAutorotateMap) { if (this.isInAutorotateMap) {
view.setRotation(-this.headingInRadiansFromNorth); view.setRotation(-this.headingInRadiansFromNorth);
} else { } else {
@ -309,6 +312,9 @@ export default {
} }
}, },
showRecenterButton() { showRecenterButton() {
if (!this.hasGeolocationTracking) {
return;
}
if (!this.isRecenterButtonShown) { if (!this.isRecenterButtonShown) {
this.isRecenterButtonShown = true; this.isRecenterButtonShown = true;
} }
@ -442,11 +448,12 @@ export default {
type: Array, type: Array,
required: true, required: true,
}, },
hasGeolocationTracking: Boolean,
heading: Number, // in degrees, clockwise wrt north heading: Number, // in degrees, clockwise wrt north
markers: Array, markers: Array,
onPress: Function, onPress: Function,
onMapCenterUpdate: Function, onMapCenterManualUpdate: Function,
onMapZoomUpdate: Function, onMapZoomManualUpdate: Function,
polyline: Array, polyline: Array,
positionLatLng: Array, positionLatLng: Array,
reportLatLng: Array, reportLatLng: Array,
@ -499,7 +506,7 @@ export default {
} }
const view = this.map.getView(); const view = this.map.getView();
if (!this.isRecenterButtonShown) { if (!this.isRecenterButtonShown && newOlCenter.every(item => item !== null)) {
// Eventually display closest report // Eventually display closest report
const isReportDetailsAlreadyShown = this.$store.state.reportDetails.id; const isReportDetailsAlreadyShown = this.$store.state.reportDetails.id;
const isReportDetailsOpenedByUser = this.$store.state.reportDetails.userAsked; const isReportDetailsOpenedByUser = this.$store.state.reportDetails.userAsked;
@ -536,6 +543,9 @@ export default {
view.setRotation(0); view.setRotation(0);
} }
view.setZoom(this.zoom); view.setZoom(this.zoom);
// Show recenter button
this.showRecenterButton();
} }
}, },
olPolyline(newOlPolyline) { olPolyline(newOlPolyline) {
@ -559,6 +569,11 @@ export default {
); );
this.accuracyFeature.getStyle().getImage().setRadius(this.radiusFromAccuracy); this.accuracyFeature.getStyle().getImage().setRadius(this.radiusFromAccuracy);
} }
// Update view center
if (!this.isRecenterButtonShown) {
this.map.getView().setCenter(newOlPosition);
}
}, },
reportDetailsID(newID, oldID) { reportDetailsID(newID, oldID) {
[oldID, newID].forEach((id) => { [oldID, newID].forEach((id) => {

View File

@ -58,13 +58,11 @@ export default {
methods: { methods: {
onManualLocationPicker(value) { onManualLocationPicker(value) {
this.isActive = false; this.isActive = false;
this.$router.push({ this.$store.dispatch('setCurrentMapZoom', {
name: 'SharedMap',
params: {
lat: value.latlng.lat,
lng: value.latlng.lng,
zoom: DEFAULT_ZOOM, zoom: DEFAULT_ZOOM,
}, });
this.$store.dispatch('setCurrentMapCenter', {
center: [value.latlng.lat, value.latlng.lng],
}); });
}, },
}, },

View File

@ -37,9 +37,12 @@ export const EARTH_RADIUS = 6378137; // in meters
export const KEEP_REPORTS_METERS_AROUND = 10000; // in meters export const KEEP_REPORTS_METERS_AROUND = 10000; // in meters
export const DEFAULT_ZOOM = 17; export const DEFAULT_ZOOM = 17;
export const MIN_ZOOM = 10; export const MIN_ZOOM = 6;
export const MAX_ZOOM = 18; 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 ACCURACY_DISPLAY_THRESHOLD = 100; // in meters
export const POSITION_MARKER_RADIUS = 10; // in pixels export const POSITION_MARKER_RADIUS = 10; // in pixels

View File

@ -6,10 +6,11 @@
<Map <Map
:accuracy="currentLocation.hdop" :accuracy="currentLocation.hdop"
:center="mapCenter" :center="mapCenter"
:hasGeolocationTracking="!hasCenterProvidedByRoute && hasGeolocationTracking"
:heading="currentLocation.heading" :heading="currentLocation.heading"
:markers="reportsMarkers" :markers="reportsMarkers"
:onMapCenterUpdate="onMapCenterUpdate" :onMapCenterManualUpdate="onMapCenterManualUpdate"
:onMapZoomUpdate="onMapZoomUpdate" :onMapZoomManualUpdate="onMapZoomManualUpdate"
:onPress="showReportDialog" :onPress="showReportDialog"
:polyline="positionHistory" :polyline="positionHistory"
:positionLatLng="currentLatLng" :positionLatLng="currentLatLng"
@ -29,7 +30,7 @@
@click.native.stop="() => showReportDialog()" @click.native.stop="() => showReportDialog()"
role="button" role="button"
:aria-label="$t('buttons.reportProblem')" :aria-label="$t('buttons.reportProblem')"
v-if="!hasCenterProvidedByRoute" v-if="!hasCenterProvidedByRoute && hasGeolocationTracking"
> >
<v-icon>report_problem</v-icon> <v-icon>report_problem</v-icon>
</v-btn> </v-btn>
@ -61,6 +62,10 @@ import AppLogo from '@/assets/logo.svg';
function handlePositionError(error) { function handlePositionError(error) {
store.dispatch('setLocationError', { error: error.code }); 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) { function setPosition(position) {
@ -100,7 +105,7 @@ export default {
currentSpeed() { currentSpeed() {
if ( if (
this.hasCenterProvidedByRoute this.hasCenterProvidedByRoute
|| !this.currentLocation || !this.hasGeolocationTracking
) { ) {
return null; return null;
} }
@ -124,6 +129,9 @@ export default {
hasCenterProvidedByRoute() { hasCenterProvidedByRoute() {
return this.$route.params.lat && this.$route.params.lng; return this.$route.params.lat && this.$route.params.lng;
}, },
hasGeolocationTracking() {
return Object.keys(this.currentLocation).length > 0;
},
mapCenter() { mapCenter() {
if (this.hasCenterProvidedByRoute) { if (this.hasCenterProvidedByRoute) {
return [ return [
@ -131,13 +139,25 @@ export default {
parseFloat(this.$route.params.lng), 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() { 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 ( return (
this.$route.params.zoom this.hasGeolocationTracking
? parseInt(this.$route.params.zoom, 10) ? constants.DEFAULT_ZOOM
: constants.DEFAULT_ZOOM : constants.MAP_ZOOM_WITHOUT_GEOLOCATION
); );
}, },
positionHistory() { positionHistory() {
@ -215,7 +235,7 @@ export default {
} }
this.$store.dispatch('setLocationWatcherId', { id: watchID }); this.$store.dispatch('setLocationWatcherId', { id: watchID });
}, },
onMapCenterUpdate(center) { onMapCenterManualUpdate(center) {
// Update reports by default // Update reports by default
let distanceFromPreviousPoint = constants.UPDATE_REPORTS_DISTANCE_THRESHOLD + 1; let distanceFromPreviousPoint = constants.UPDATE_REPORTS_DISTANCE_THRESHOLD + 1;
@ -242,7 +262,7 @@ export default {
this.$store.dispatch('setCurrentMapCenter', { center }); this.$store.dispatch('setCurrentMapCenter', { center });
}, },
onMapZoomUpdate(zoom) { onMapZoomManualUpdate(zoom) {
this.$store.dispatch('setCurrentMapZoom', { zoom }); this.$store.dispatch('setCurrentMapZoom', { zoom });
}, },
removeNotification() { removeNotification() {