From 4ff645cc43b5a5a48b754c207690653e115c7409 Mon Sep 17 00:00:00 2001 From: "Phyks (Lucas Verney)" Date: Mon, 15 Oct 2018 09:11:41 +0200 Subject: [PATCH] Filter reports returned by the API based on map center Only keep reports which are around the map center in the data returned by the server. Filtering is done client-side for privacy reasons. --- src/constants.js | 3 +++ src/store/actions.js | 17 ++++++++++++++-- src/store/getters.js | 11 ----------- src/store/mutations.js | 10 ---------- src/views/Map.vue | 44 ++++++++++++++++++++++++------------------ 5 files changed, 43 insertions(+), 42 deletions(-) diff --git a/src/constants.js b/src/constants.js index 936cba7..c8af23c 100644 --- a/src/constants.js +++ b/src/constants.js @@ -89,6 +89,9 @@ export const REPORT_DOWNVOTES_THRESHOLD = 1; export const EARTH_RADIUS = 6378137; // in meters +// Keep reports only in a given radius around map center. +export const KEEP_REPORTS_METERS_AROUND = 10000; // in meters + export const DEFAULT_ZOOM = 17; export const MIN_ZOOM = 10; export const MAX_ZOOM = 18; diff --git a/src/store/actions.js b/src/store/actions.js index 0e42c00..32189ef 100644 --- a/src/store/actions.js +++ b/src/store/actions.js @@ -1,5 +1,6 @@ import * as api from '@/api'; import * as constants from '@/constants'; +import { distance } from '@/tools'; import i18n from '@/i18n'; import { @@ -22,11 +23,23 @@ import { STORE_REPORTS, } from './mutations-types'; -export function fetchReports({ commit }) { +export function fetchReports({ commit, state }) { commit(IS_LOADING); return api.getActiveReports() .then((reports) => { - commit(STORE_REPORTS, { reports }); + // Filter reports which are too far + const reportsToCommit = reports.filter( + (report) => { + if (report.attributes.downvotes >= constants.REPORT_DOWNVOTES_THRESHOLD) { + return false; + } + return distance( + [report.attributes.lat, report.attributes.lng], + state.map.center, + ) < 10000; + }, + ); + commit(STORE_REPORTS, { reports: reportsToCommit }); commit(IS_DONE_LOADING); }) .catch((exc) => { diff --git a/src/store/getters.js b/src/store/getters.js index 89131bb..310d153 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -1,5 +1,3 @@ -import { REPORT_DOWNVOTES_THRESHOLD } from '@/constants'; - export function getLastLocation(state) { const { gpx } = state.location; if (gpx.length > 0) { @@ -7,12 +5,3 @@ export function getLastLocation(state) { } return null; } - -export function notDismissedReports(state) { - return state.reports.filter((item) => { - if (item.attributes.downvotes >= REPORT_DOWNVOTES_THRESHOLD) { - return false; - } - return true; - }); -} diff --git a/src/store/mutations.js b/src/store/mutations.js index 73ac3ae..6ae21d7 100644 --- a/src/store/mutations.js +++ b/src/store/mutations.js @@ -171,16 +171,6 @@ export const mutations = { }, [types.SET_CURRENT_POSITION](state, { currentLocation }) { state.location.gpx.push(currentLocation); - if ( - !state.lastReportFetchingLocation - || !state.lastReportFetchingLocation[0] - || !state.lastReportFetchingLocation[1] - ) { - state.lastReportFetchingLocation = [ - currentLocation.latitude, - currentLocation.longitude, - ]; - } }, [types.SET_LAST_REPORT_FETCHING_LOCATION](state, { locationLatLng }) { state.lastReportFetchingLocation = locationLatLng; diff --git a/src/views/Map.vue b/src/views/Map.vue index c183b2b..12fd8d6 100644 --- a/src/views/Map.vue +++ b/src/views/Map.vue @@ -64,23 +64,6 @@ function handlePositionError(error) { } function setPosition(position) { - const lastFetchingLocation = store.state.lastReportFetchingLocation; - if ( - lastFetchingLocation - && lastFetchingLocation[0] !== null - && lastFetchingLocation[1] !== null - ) { - const distanceFromPreviousPoint = distance( - [lastFetchingLocation[0], lastFetchingLocation[1]], - [position.coords.latitude, position.coords.longitude], - ); - if (distanceFromPreviousPoint > constants.UPDATE_REPORTS_DISTANCE_THRESHOLD) { - store.dispatch('setLastReportFetchingLocation', { - locationLatLng: [position.coords.latitude, position.coords.longitude], - }); - store.dispatch('fetchReports'); - } - } store.dispatch( 'setCurrentPosition', { coords: position.coords, timestamp: position.timestamp }, @@ -158,7 +141,7 @@ export default { return this.$store.state.location.gpx.map(item => [item.latitude, item.longitude]); }, reportsMarkers() { - return this.$store.getters.notDismissedReports.map(report => ({ + return this.$store.state.reports.map(report => ({ id: report.id, type: report.attributes.type, latLng: [report.attributes.lat, report.attributes.lng], @@ -230,6 +213,30 @@ export default { this.$store.dispatch('setLocationWatcherId', { id: watchID }); }, onMapCenterUpdate(center) { + // Update reports by default + let distanceFromPreviousPoint = constants.UPDATE_REPORTS_DISTANCE_THRESHOLD + 1; + + // If last fetching location is known, only update reports if not too close + const lastFetchingLocation = this.$store.state.lastReportFetchingLocation; + if ( + lastFetchingLocation + && lastFetchingLocation[0] !== null + && lastFetchingLocation[1] !== null + ) { + distanceFromPreviousPoint = distance( + [lastFetchingLocation[0], lastFetchingLocation[1]], + [center[0], center[1]], + ); + } + + // If necessary, refetch reports + if (distanceFromPreviousPoint > constants.UPDATE_REPORTS_DISTANCE_THRESHOLD) { + store.dispatch('setLastReportFetchingLocation', { + locationLatLng: center, + }); + store.dispatch('fetchReports').catch(() => {}); + } + this.$store.dispatch('setCurrentMapCenter', { center }); }, onMapZoomUpdate(zoom) { @@ -314,7 +321,6 @@ export default { this.$store.dispatch('markHasVibratedOnce'); } } - this.$store.dispatch('fetchReports').catch(() => {}); }, };