Let users move the view around
* Let user move the view around, without automatic refocusing. * Add a button to refocus view.
This commit is contained in:
parent
ac518944d1
commit
c15ad9ab56
@ -1,10 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="fill-height fill-width">
|
<div class="fill-height fill-width">
|
||||||
<v-lmap :center="latlng" :zoom="this.zoom" :minZoom="this.minZoom" :maxZoom="this.maxZoom" :options="{ zoomControl: false }" @contextmenu="handleLongPress">
|
<v-lmap :center="latLng" :zoom="this.zoom" :minZoom="this.minZoom" :maxZoom="this.maxZoom" :options="{ zoomControl: false }" @contextmenu="handleLongPress" @moveend="onMoveEnd" @movestart="onMoveStart">
|
||||||
<v-ltilelayer :url="tileServer" :attribution="attribution"></v-ltilelayer>
|
<v-ltilelayer :url="tileServer" :attribution="attribution"></v-ltilelayer>
|
||||||
|
|
||||||
<v-lts v-if="heading" :lat-lng="latlng" :options="markerOptions"></v-lts>
|
<v-lts v-if="heading" :lat-lng="positionLatLng" :options="markerOptions"></v-lts>
|
||||||
<v-lcirclemarker v-else :lat-lng="latlng" :color="markerOptions.color" :fillColor="markerOptions.fillColor" :fillOpacity="1.0" :weight="markerOptions.weight" :radius="markerRadius"></v-lcirclemarker>
|
<v-lcirclemarker v-else :lat-lng="positionLatLng" :color="markerOptions.color" :fillColor="markerOptions.fillColor" :fillOpacity="1.0" :weight="markerOptions.weight" :radius="markerRadius"></v-lcirclemarker>
|
||||||
|
|
||||||
<v-lcircle v-if="shouldDisplayAccuracy" :lat-lng="latlng" :radius="radiusFromAccuracy"></v-lcircle>
|
<v-lcircle v-if="shouldDisplayAccuracy" :lat-lng="latlng" :radius="radiusFromAccuracy"></v-lcircle>
|
||||||
|
|
||||||
@ -41,16 +41,19 @@ export default {
|
|||||||
default: null,
|
default: null,
|
||||||
},
|
},
|
||||||
heading: Number,
|
heading: Number,
|
||||||
lat: Number,
|
latLng: Array,
|
||||||
lng: Number,
|
|
||||||
markers: Array,
|
markers: Array,
|
||||||
onLongPress: Function,
|
onLongPress: Function,
|
||||||
|
onMoveEnd: Function,
|
||||||
|
onMoveStart: Function,
|
||||||
|
positionLatLng: Array,
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
radiusFromAccuracy() {
|
radiusFromAccuracy() {
|
||||||
if (this.accuracy) {
|
if (this.accuracy) {
|
||||||
return this.accuracy / (
|
return this.accuracy / (
|
||||||
(constants.EARTH_RADIUS * 2 * Math.PI * Math.cos(this.lat * (Math.PI / 180))) /
|
(constants.EARTH_RADIUS * 2 * Math.PI * Math.cos(this.latLng[0] *
|
||||||
|
(Math.PI / 180))) /
|
||||||
(2 ** (this.zoom + 8))
|
(2 ** (this.zoom + 8))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -63,9 +66,6 @@ export default {
|
|||||||
this.radiusFromAccuracy > this.markerRadius
|
this.radiusFromAccuracy > this.markerRadius
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
latlng() {
|
|
||||||
return [this.lat, this.lng];
|
|
||||||
},
|
|
||||||
markerOptions() {
|
markerOptions() {
|
||||||
return {
|
return {
|
||||||
fillColor: '#00ff00',
|
fillColor: '#00ff00',
|
||||||
|
@ -1,8 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-container fluid fill-height class="no-padding">
|
<v-container fluid fill-height class="no-padding">
|
||||||
<v-layout row wrap fill-height>
|
<v-layout row wrap fill-height>
|
||||||
<v-flex xs12 fill-height v-if="lat && lng">
|
<v-flex xs12 fill-height v-if="latLng">
|
||||||
<Map :lat="lat" :lng="lng" :heading="heading" :accuracy="accuracy" :markers="reportsMarkers" :onLongPress="showReportDialog"></Map>
|
<Map :latLng="mapLatLng" :positionLatLng="latLng" :heading="heading" :accuracy="accuracy" :markers="reportsMarkers" :onLongPress="showReportDialog" :onMoveEnd="onMapMoveEnd" :onMoveStart="onMapMoveStart"></Map>
|
||||||
|
<v-btn
|
||||||
|
fixed
|
||||||
|
dark
|
||||||
|
fab
|
||||||
|
bottom
|
||||||
|
left
|
||||||
|
color="blue"
|
||||||
|
class="overlayButton"
|
||||||
|
v-if="hasMapMoved"
|
||||||
|
@click.native.stop="recenterMap"
|
||||||
|
>
|
||||||
|
<v-icon>my_location</v-icon>
|
||||||
|
</v-btn>
|
||||||
<v-btn
|
<v-btn
|
||||||
fixed
|
fixed
|
||||||
dark
|
dark
|
||||||
@ -64,15 +77,23 @@ export default {
|
|||||||
latLng: [report.attributes.lat, report.attributes.lng],
|
latLng: [report.attributes.lat, report.attributes.lng],
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
mapLatLng() {
|
||||||
|
if (this.hasMapMoved) {
|
||||||
|
return this.mapMovedLatLng;
|
||||||
|
}
|
||||||
|
return this.latLng;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
accuracy: null,
|
accuracy: null,
|
||||||
|
centering: false,
|
||||||
dialog: false,
|
dialog: false,
|
||||||
error: null,
|
error: null,
|
||||||
|
hasMapMoved: false,
|
||||||
heading: null,
|
heading: null,
|
||||||
lat: null,
|
latLng: null,
|
||||||
lng: null,
|
mapMovedLatLng: null,
|
||||||
noSleep: null,
|
noSleep: null,
|
||||||
reportLat: null,
|
reportLat: null,
|
||||||
reportLng: null,
|
reportLng: null,
|
||||||
@ -119,17 +140,16 @@ export default {
|
|||||||
this.error = `Error ${error.code}: ${error.message}`;
|
this.error = `Error ${error.code}: ${error.message}`;
|
||||||
},
|
},
|
||||||
setPosition(position) {
|
setPosition(position) {
|
||||||
if (this.lat && this.lng) {
|
if (this.latLng) {
|
||||||
const distanceFromPreviousPoint = distance(
|
const distanceFromPreviousPoint = distance(
|
||||||
[this.lat, this.lng],
|
[this.latLng[0], this.latLng[1]],
|
||||||
[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) {
|
||||||
this.$store.dispatch('fetchReports');
|
this.$store.dispatch('fetchReports');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.lat = position.coords.latitude;
|
this.latLng = [position.coords.latitude, position.coords.longitude];
|
||||||
this.lng = position.coords.longitude;
|
|
||||||
this.heading = position.coords.heading ? position.coords.heading : null;
|
this.heading = position.coords.heading ? position.coords.heading : null;
|
||||||
this.accuracy = position.coords.accuracy ? position.coords.accuracy : null;
|
this.accuracy = position.coords.accuracy ? position.coords.accuracy : null;
|
||||||
},
|
},
|
||||||
@ -147,8 +167,8 @@ export default {
|
|||||||
this.reportLat = latlng.lat;
|
this.reportLat = latlng.lat;
|
||||||
this.reportLng = latlng.lng;
|
this.reportLng = latlng.lng;
|
||||||
} else {
|
} else {
|
||||||
this.reportLat = this.lat;
|
this.reportLat = this.latLng[0];
|
||||||
this.reportLng = this.lng;
|
this.reportLng = this.latLng[1];
|
||||||
}
|
}
|
||||||
this.dialog = !this.dialog;
|
this.dialog = !this.dialog;
|
||||||
},
|
},
|
||||||
@ -183,6 +203,23 @@ export default {
|
|||||||
window.addEventListener('touchmove', this.handleFirstUserInteraction, false);
|
window.addEventListener('touchmove', this.handleFirstUserInteraction, false);
|
||||||
window.addEventListener('MSPointerMove', this.handleFirstUserInteraction, false);
|
window.addEventListener('MSPointerMove', this.handleFirstUserInteraction, false);
|
||||||
},
|
},
|
||||||
|
recenterMap() {
|
||||||
|
this.mapMovedLatLng = null;
|
||||||
|
this.centering = true;
|
||||||
|
this.hasMapMoved = false;
|
||||||
|
},
|
||||||
|
onMapMoveStart() {
|
||||||
|
if (!this.centering) {
|
||||||
|
this.hasMapMoved = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onMapMoveEnd(ev) {
|
||||||
|
const latLng = ev.target.getCenter();
|
||||||
|
if (!this.hasMapMoved) {
|
||||||
|
this.mapMovedLatLng = [latLng.lat, latLng.lng];
|
||||||
|
}
|
||||||
|
this.centering = false;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
Reference in New Issue
Block a user