2019-05-07 00:05:01 +00:00
|
|
|
<template>
|
2019-05-19 18:24:56 +00:00
|
|
|
<v-container fluid fill-height class="pa-0 p-page p-page-places">
|
2019-05-08 02:37:45 +00:00
|
|
|
<l-map :zoom="zoom" :center="center" :bounds="bounds" :options="options">
|
|
|
|
<l-control position="bottomright">
|
|
|
|
<v-toolbar dense floating color="grey lighten-4" v-on:dblclick.stop v-on:click.stop>
|
|
|
|
<v-btn icon v-on:click="currentPosition()">
|
|
|
|
<v-icon>my_location</v-icon>
|
|
|
|
</v-btn>
|
|
|
|
<v-spacer></v-spacer>
|
|
|
|
<v-text-field class="pt-3 pr-3"
|
|
|
|
single-line
|
|
|
|
label="Search"
|
|
|
|
prepend-inner-icon="search"
|
|
|
|
clearable
|
|
|
|
color="blue-grey"
|
|
|
|
@click:clear="clearQuery"
|
|
|
|
v-model="query.q"
|
|
|
|
@keyup.enter.native="formChange"
|
|
|
|
></v-text-field>
|
|
|
|
</v-toolbar>
|
|
|
|
</l-control>
|
2019-05-07 00:05:01 +00:00
|
|
|
<l-tile-layer :url="url" :attribution="attribution"></l-tile-layer>
|
2019-05-08 02:37:45 +00:00
|
|
|
<l-marker v-for="photo in photos" v-bind:data="photo"
|
|
|
|
v-bind:key="photo.index" :lat-lng="photo.location" :icon="photo.icon"
|
|
|
|
:options="photo.options" @click="openPhoto(photo.index)"></l-marker>
|
2019-06-09 02:37:02 +00:00
|
|
|
<l-marker v-if="position" :lat-lng="position" :z-index-offset="100"></l-marker>
|
2019-05-07 00:05:01 +00:00
|
|
|
</l-map>
|
|
|
|
</v-container>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
2019-05-08 02:37:45 +00:00
|
|
|
import * as L from "leaflet";
|
|
|
|
import Photo from "model/photo";
|
|
|
|
|
2019-05-07 00:05:01 +00:00
|
|
|
export default {
|
2019-05-21 15:59:12 +00:00
|
|
|
name: 'p-page-places',
|
2019-05-07 00:05:01 +00:00
|
|
|
data() {
|
2019-05-08 02:37:45 +00:00
|
|
|
const query = this.$route.query;
|
|
|
|
const q = query['q'] ? query['q'] : '';
|
2019-05-16 00:22:38 +00:00
|
|
|
const lat = query['lat'] ? query['lat'] : '';
|
|
|
|
const long = query['long'] ? query['long'] : '';
|
|
|
|
const dist = query['dist'] ? query['dist'] : 20;
|
2019-05-08 02:37:45 +00:00
|
|
|
|
2019-05-07 00:05:01 +00:00
|
|
|
return {
|
2019-05-08 02:37:45 +00:00
|
|
|
zoom: 15,
|
|
|
|
position: null,
|
2019-05-15 12:37:31 +00:00
|
|
|
center: L.latLng(0, 0),
|
2019-05-07 15:02:15 +00:00
|
|
|
url: 'https://{s}.tile.osm.org/{z}/{x}/{y}.png',
|
2019-05-07 00:05:01 +00:00
|
|
|
attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
|
2019-05-08 02:37:45 +00:00
|
|
|
options: {
|
|
|
|
icon: {
|
2019-05-15 12:37:31 +00:00
|
|
|
iconSize: [50, 50]
|
|
|
|
},
|
|
|
|
minZoom: 3,
|
2019-05-08 02:37:45 +00:00
|
|
|
},
|
|
|
|
photos: [],
|
|
|
|
results: [],
|
|
|
|
query: {
|
|
|
|
q: q,
|
2019-05-16 00:22:38 +00:00
|
|
|
lat: lat,
|
|
|
|
long: long,
|
|
|
|
dist: dist,
|
2019-05-08 02:37:45 +00:00
|
|
|
},
|
|
|
|
offset: 0,
|
2019-05-15 12:37:31 +00:00
|
|
|
pageSize: 101,
|
2019-05-08 02:37:45 +00:00
|
|
|
lastQuery: {},
|
|
|
|
bounds: null,
|
|
|
|
minLat: null,
|
|
|
|
maxLat: null,
|
|
|
|
minLong: null,
|
|
|
|
maxLong: null,
|
2019-05-07 00:05:01 +00:00
|
|
|
}
|
|
|
|
},
|
2019-05-08 02:37:45 +00:00
|
|
|
methods: {
|
|
|
|
openPhoto(index) {
|
2019-05-19 18:13:19 +00:00
|
|
|
this.$viewer.show(this.results, index)
|
2019-05-08 02:37:45 +00:00
|
|
|
},
|
2019-05-16 00:22:38 +00:00
|
|
|
currentPositionSuccess(position) {
|
|
|
|
this.query.lat = position.coords.latitude;
|
|
|
|
this.query.long = position.coords.longitude;
|
|
|
|
this.query.q = "";
|
2019-05-28 22:28:16 +00:00
|
|
|
this.search();
|
2019-05-16 00:22:38 +00:00
|
|
|
},
|
|
|
|
currentPositionError(error) {
|
|
|
|
this.$alert.warning(error.message);
|
|
|
|
},
|
2019-05-08 02:37:45 +00:00
|
|
|
currentPosition() {
|
|
|
|
if ("geolocation" in navigator) {
|
|
|
|
this.$alert.success('Finding your position...');
|
2019-05-16 00:22:38 +00:00
|
|
|
navigator.geolocation.getCurrentPosition(this.currentPositionSuccess, this.currentPositionError);
|
2019-05-08 02:37:45 +00:00
|
|
|
} else {
|
|
|
|
this.$alert.warning('Geolocation is not available');
|
|
|
|
}
|
|
|
|
},
|
|
|
|
formChange() {
|
2019-05-28 22:28:16 +00:00
|
|
|
this.query.lat = "";
|
|
|
|
this.query.long = "";
|
|
|
|
this.search();
|
2019-05-08 02:37:45 +00:00
|
|
|
},
|
|
|
|
clearQuery() {
|
2019-05-16 00:22:38 +00:00
|
|
|
this.query.q = "";
|
2019-05-28 22:28:16 +00:00
|
|
|
this.query.lat = "";
|
|
|
|
this.query.long = "";
|
|
|
|
this.search();
|
2019-05-08 02:37:45 +00:00
|
|
|
},
|
|
|
|
resetBoundingBox() {
|
|
|
|
this.minLat = null;
|
|
|
|
this.maxLat = null;
|
|
|
|
this.minLong = null;
|
|
|
|
this.maxLong = null;
|
|
|
|
},
|
|
|
|
fitBoundingBox(lat, long) {
|
2019-05-15 12:37:31 +00:00
|
|
|
if (this.maxLat === null || lat > this.maxLat) {
|
2019-05-08 02:37:45 +00:00
|
|
|
this.maxLat = lat;
|
|
|
|
}
|
|
|
|
|
2019-05-15 12:37:31 +00:00
|
|
|
if (this.minLat === null || lat < this.minLat) {
|
2019-05-08 02:37:45 +00:00
|
|
|
this.minLat = lat;
|
|
|
|
}
|
|
|
|
|
2019-05-15 12:37:31 +00:00
|
|
|
if (this.maxLong === null || long > this.maxLong) {
|
2019-05-08 02:37:45 +00:00
|
|
|
this.maxLong = long;
|
|
|
|
}
|
|
|
|
|
2019-05-15 12:37:31 +00:00
|
|
|
if (this.minLong === null || long < this.minLong) {
|
2019-05-08 02:37:45 +00:00
|
|
|
this.minLong = long;
|
|
|
|
}
|
|
|
|
},
|
2019-05-08 05:54:53 +00:00
|
|
|
updateMap(results) {
|
2019-05-08 02:37:45 +00:00
|
|
|
const photos = [];
|
|
|
|
|
|
|
|
this.resetBoundingBox();
|
|
|
|
|
2019-05-08 05:54:53 +00:00
|
|
|
for (let i = 0, len = results.length; i < len; i++) {
|
|
|
|
let result = results[i];
|
2019-05-08 02:37:45 +00:00
|
|
|
|
|
|
|
if (!result.hasLocation()) continue;
|
|
|
|
|
|
|
|
this.fitBoundingBox(result.PhotoLat, result.PhotoLong);
|
|
|
|
|
|
|
|
photos.push({
|
|
|
|
id: result.getId(),
|
|
|
|
index: i,
|
|
|
|
options: {
|
|
|
|
title: result.getTitle(),
|
|
|
|
clickable: true,
|
|
|
|
},
|
|
|
|
icon: L.icon({
|
2019-05-13 16:01:50 +00:00
|
|
|
iconUrl: result.getThumbnailUrl('tile_50'),
|
|
|
|
iconRetinaUrl: result.getThumbnailUrl('tile_100'),
|
2019-05-08 02:37:45 +00:00
|
|
|
iconSize: [50, 50],
|
2019-05-08 04:47:30 +00:00
|
|
|
className: 'leaflet-marker-photo',
|
2019-05-08 02:37:45 +00:00
|
|
|
}),
|
|
|
|
location: L.latLng(result.PhotoLat, result.PhotoLong),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-05-08 05:54:53 +00:00
|
|
|
if (photos.length === 0) {
|
|
|
|
this.$alert.warning('No locations found');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.results = results;
|
|
|
|
this.photos = photos;
|
2019-05-08 02:37:45 +00:00
|
|
|
|
2019-06-09 02:37:02 +00:00
|
|
|
this.$nextTick(() => {
|
|
|
|
this.center = photos[0].location;
|
|
|
|
this.bounds = [[this.maxLat, this.minLong], [this.minLat, this.maxLong]];
|
|
|
|
});
|
2019-05-08 02:37:45 +00:00
|
|
|
|
2019-05-15 12:37:31 +00:00
|
|
|
if (photos.length > 100) {
|
|
|
|
this.$alert.info('More than 100 photos found');
|
|
|
|
} else {
|
|
|
|
this.$alert.info(photos.length + ' photos found');
|
|
|
|
}
|
2019-05-08 02:37:45 +00:00
|
|
|
},
|
2019-05-30 00:02:47 +00:00
|
|
|
updateQuery() {
|
2019-11-07 17:06:50 +00:00
|
|
|
this.$router.replace({query: this.query}).catch(err => {});
|
2019-05-08 02:37:45 +00:00
|
|
|
|
2019-05-30 00:02:47 +00:00
|
|
|
if(this.query.lat && this.query.long) {
|
|
|
|
this.position = L.latLng(this.query.lat, this.query.long);
|
|
|
|
this.center = L.latLng(this.query.lat, this.query.long);
|
|
|
|
} else {
|
|
|
|
this.position = null;
|
|
|
|
}
|
|
|
|
},
|
2019-05-28 22:28:16 +00:00
|
|
|
search() {
|
2019-05-08 02:37:45 +00:00
|
|
|
// Don't query the same data more than once
|
|
|
|
if (JSON.stringify(this.lastQuery) === JSON.stringify(this.query)) return;
|
|
|
|
|
|
|
|
Object.assign(this.lastQuery, this.query);
|
|
|
|
|
|
|
|
this.offset = 0;
|
|
|
|
|
2019-05-30 00:02:47 +00:00
|
|
|
this.updateQuery();
|
|
|
|
|
2019-11-07 17:06:50 +00:00
|
|
|
this.$router.replace({query: this.query}).catch(err => {});
|
2019-05-08 02:37:45 +00:00
|
|
|
|
|
|
|
const params = {
|
|
|
|
count: this.pageSize,
|
|
|
|
offset: this.offset,
|
2019-05-15 12:37:31 +00:00
|
|
|
location: 1,
|
2019-05-08 02:37:45 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Object.assign(params, this.query);
|
|
|
|
|
|
|
|
Photo.search(params).then(response => {
|
|
|
|
if (!response.models.length) {
|
|
|
|
this.$alert.warning('No photos found');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-05-08 05:54:53 +00:00
|
|
|
this.updateMap(response.models);
|
2019-05-08 02:37:45 +00:00
|
|
|
});
|
|
|
|
},
|
|
|
|
},
|
|
|
|
created() {
|
2019-05-28 22:28:16 +00:00
|
|
|
this.search();
|
2019-05-08 02:37:45 +00:00
|
|
|
},
|
2019-05-07 00:05:01 +00:00
|
|
|
};
|
|
|
|
</script>
|
2019-05-08 02:37:45 +00:00
|
|
|
|