Store complete GPX data

Rework the store to keep track of everything useful for building a full
GPX trace.
This commit is contained in:
Lucas Verney 2018-08-02 16:58:08 +02:00
parent 7800621c5f
commit 05cb92d8e3
5 changed files with 43 additions and 44 deletions

View File

@ -112,18 +112,25 @@ export function setCurrentMapZoom({ commit, state }, { zoom }) {
} }
export function setCurrentPosition( export function setCurrentPosition(
{ commit, state }, { commit, getters, state },
{ accuracy = null, heading = null, latLng = null }, { coords, timestamp },
) { ) {
const locationState = state.location; const currentLocation = {
if ( latitude: coords.latitude,
accuracy !== locationState.accuracy || longitude: coords.longitude,
heading !== locationState.heading || hdop: coords.accuracy ? coords.accuracy : null,
locationState.currentLatLng.some((item, index) => item !== latLng[index]) elevation: coords.elevation ? coords.elevation : null,
) { vdop: coords.altitudeAccuracy ? coords.altitudeAccuracy : null,
// Throttle mutations if nothing has changed heading: (
commit(SET_CURRENT_POSITION, { accuracy, heading, latLng }); (coords.heading !== null && !isNaN(coords.heading))
} ? coords.heading
: null
),
speed: coords.speed ? coords.speed : null,
timestamp,
};
commit(SET_CURRENT_POSITION, { currentLocation });
} }
export function setLocationWatcherId({ commit }, { id }) { export function setLocationWatcherId({ commit }, { id }) {

View File

@ -1,5 +1,13 @@
import { REPORT_VOTES_THRESHOLD } from '@/constants'; import { REPORT_VOTES_THRESHOLD } from '@/constants';
export function getLastLocation(state) {
const gpx = state.location.gpx;
if (gpx.length > 0) {
return gpx[gpx.length - 1];
}
return null;
}
export function notDismissedReports(state) { export function notDismissedReports(state) {
return state.reports.filter((item) => { return state.reports.filter((item) => {
if (item.attributes.downvotes === 0) { if (item.attributes.downvotes === 0) {

View File

@ -86,11 +86,8 @@ export const initialState = {
hasGoneThroughIntro: false, hasGoneThroughIntro: false,
isLoading: false, isLoading: false,
location: { location: {
accuracy: null,
currentLatLng: [null, null],
error: null, error: null,
heading: null, // in degrees, clockwise wrt north gpx: [],
positionHistory: [],
watcherID: null, watcherID: null,
}, },
map: { map: {
@ -161,11 +158,8 @@ export const mutations = {
[types.SET_CURRENT_MAP_ZOOM](state, { zoom }) { [types.SET_CURRENT_MAP_ZOOM](state, { zoom }) {
Vue.set(state.map, 'zoom', zoom); Vue.set(state.map, 'zoom', zoom);
}, },
[types.SET_CURRENT_POSITION](state, { accuracy, heading, latLng }) { [types.SET_CURRENT_POSITION](state, { currentLocation }) {
Vue.set(state.location, 'accuracy', accuracy); state.location.gpx.push(currentLocation);
Vue.set(state.location, 'currentLatLng', latLng);
Vue.set(state.location, 'heading', heading);
state.location.positionHistory.push(latLng);
}, },
[types.SET_LOCATION_ERROR](state, { error }) { [types.SET_LOCATION_ERROR](state, { error }) {
Vue.set(state.location, 'error', error); Vue.set(state.location, 'error', error);

View File

@ -38,6 +38,7 @@ export function mockLocation() {
longitude: (Math.random() * (LNG_MAX - LNG_MIN)) + LNG_MIN, longitude: (Math.random() * (LNG_MAX - LNG_MIN)) + LNG_MIN,
heading: null, // 20 * (Math.PI / 180), heading: null, // 20 * (Math.PI / 180),
}, },
timestamp: new Date().getTime(),
}; };
console.log('New mock location: ', newLocation); console.log('New mock location: ', newLocation);
return newLocation; return newLocation;

View File

@ -4,9 +4,9 @@
<ReportCard></ReportCard> <ReportCard></ReportCard>
<v-flex xs12 fill-height v-if="mapCenter"> <v-flex xs12 fill-height v-if="mapCenter">
<Map <Map
:accuracy="accuracy" :accuracy="currentLocation.accuracy"
:center="mapCenter" :center="mapCenter"
:heading="heading" :heading="currentLocation.heading"
:markers="reportsMarkers" :markers="reportsMarkers"
:onMapCenterUpdate="onMapCenterUpdate" :onMapCenterUpdate="onMapCenterUpdate"
:onMapZoomUpdate="onMapZoomUpdate" :onMapZoomUpdate="onMapZoomUpdate"
@ -61,10 +61,10 @@ function handlePositionError(error) {
} }
function setPosition(position) { function setPosition(position) {
const currentLatLng = store.state.location.currentLatLng; const lastLocation = store.getters.getLastLocation;
if (currentLatLng) { if (lastLocation !== null) {
const distanceFromPreviousPoint = distance( const distanceFromPreviousPoint = distance(
[currentLatLng[0], currentLatLng[1]], [lastLocation.latitude, lastLocation.longitude],
[position.coords.latitude, position.coords.longitude], [position.coords.latitude, position.coords.longitude],
); );
if (distanceFromPreviousPoint > constants.UPDATE_REPORTS_DISTANCE_THRESHOLD) { if (distanceFromPreviousPoint > constants.UPDATE_REPORTS_DISTANCE_THRESHOLD) {
@ -73,15 +73,7 @@ function setPosition(position) {
} }
store.dispatch( store.dispatch(
'setCurrentPosition', 'setCurrentPosition',
{ { coords: position.coords, timestamp: position.timestamp },
accuracy: position.coords.accuracy ? position.coords.accuracy : null,
heading: (
(position.coords.heading !== null && !isNaN(position.coords.heading))
? position.coords.heading
: null
),
latLng: [position.coords.latitude, position.coords.longitude],
},
); );
} }
@ -107,16 +99,16 @@ export default {
ReportDialog, ReportDialog,
}, },
computed: { computed: {
accuracy() {
return this.$store.state.location.accuracy;
},
currentLatLng() { currentLatLng() {
const currentLatLng = this.$store.state.location.currentLatLng; const currentLocation = this.$store.getters.getLastLocation;
// Check that this is a correct position // Check that this is a correct position
if (currentLatLng.some(item => item === null)) { if (currentLocation === null) {
return null; return null;
} }
return currentLatLng; return [currentLocation.latitude, currentLocation.longitude];
},
currentLocation() {
return this.$store.getters.getLastLocation;
}, },
error() { error() {
const errorCode = this.$store.state.location.error; const errorCode = this.$store.state.location.error;
@ -136,9 +128,6 @@ export default {
hasCenterProvidedByRoute() { hasCenterProvidedByRoute() {
return this.$route.params.lat && this.$route.params.lng; return this.$route.params.lat && this.$route.params.lng;
}, },
heading() {
return this.$store.state.location.heading;
},
mapCenter() { mapCenter() {
if (this.hasCenterProvidedByRoute) { if (this.hasCenterProvidedByRoute) {
return [this.$route.params.lat, this.$route.params.lng]; return [this.$route.params.lat, this.$route.params.lng];
@ -153,7 +142,7 @@ export default {
); );
}, },
positionHistory() { positionHistory() {
return this.$store.state.location.positionHistory; return this.$store.state.location.gpx.map(item => [item.latitude, item.longitude]);
}, },
reportsMarkers() { reportsMarkers() {
return this.$store.getters.notDismissedReports.map(report => ({ return this.$store.getters.notDismissedReports.map(report => ({