parent
50dfffc0f8
commit
6ad7c560fc
|
@ -20,6 +20,7 @@
|
||||||
"justified-layout": "^4.1.0",
|
"justified-layout": "^4.1.0",
|
||||||
"leaflet": "^1.9.4",
|
"leaflet": "^1.9.4",
|
||||||
"leaflet-edgebuffer": "^1.0.6",
|
"leaflet-edgebuffer": "^1.0.6",
|
||||||
|
"leaflet.heat": "^0.2.0",
|
||||||
"luxon": "^3.3.0",
|
"luxon": "^3.3.0",
|
||||||
"path-posix": "^1.0.0",
|
"path-posix": "^1.0.0",
|
||||||
"photoswipe": "^5.3.8",
|
"photoswipe": "^5.3.8",
|
||||||
|
@ -6728,6 +6729,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/leaflet-edgebuffer/-/leaflet-edgebuffer-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/leaflet-edgebuffer/-/leaflet-edgebuffer-1.0.6.tgz",
|
||||||
"integrity": "sha512-2RZsp3rta0w2zBgC40F7drhYCAPaS0/i6o9MR0gMA0cdp83rLv+1gfqPnF7lnFdqskteGyQX+wzLFVdHrQjb4A=="
|
"integrity": "sha512-2RZsp3rta0w2zBgC40F7drhYCAPaS0/i6o9MR0gMA0cdp83rLv+1gfqPnF7lnFdqskteGyQX+wzLFVdHrQjb4A=="
|
||||||
},
|
},
|
||||||
|
"node_modules/leaflet.heat": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/leaflet.heat/-/leaflet.heat-0.2.0.tgz",
|
||||||
|
"integrity": "sha512-Cd5PbAA/rX3X3XKxfDoUGi9qp78FyhWYurFg3nsfhntcM/MCNK08pRkf4iEenO1KNqwVPKCmkyktjW3UD+h9bQ=="
|
||||||
|
},
|
||||||
"node_modules/leven": {
|
"node_modules/leven": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
|
||||||
|
@ -16655,6 +16661,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/leaflet-edgebuffer/-/leaflet-edgebuffer-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/leaflet-edgebuffer/-/leaflet-edgebuffer-1.0.6.tgz",
|
||||||
"integrity": "sha512-2RZsp3rta0w2zBgC40F7drhYCAPaS0/i6o9MR0gMA0cdp83rLv+1gfqPnF7lnFdqskteGyQX+wzLFVdHrQjb4A=="
|
"integrity": "sha512-2RZsp3rta0w2zBgC40F7drhYCAPaS0/i6o9MR0gMA0cdp83rLv+1gfqPnF7lnFdqskteGyQX+wzLFVdHrQjb4A=="
|
||||||
},
|
},
|
||||||
|
"leaflet.heat": {
|
||||||
|
"version": "0.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/leaflet.heat/-/leaflet.heat-0.2.0.tgz",
|
||||||
|
"integrity": "sha512-Cd5PbAA/rX3X3XKxfDoUGi9qp78FyhWYurFg3nsfhntcM/MCNK08pRkf4iEenO1KNqwVPKCmkyktjW3UD+h9bQ=="
|
||||||
|
},
|
||||||
"leven": {
|
"leven": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
"justified-layout": "^4.1.0",
|
"justified-layout": "^4.1.0",
|
||||||
"leaflet": "^1.9.4",
|
"leaflet": "^1.9.4",
|
||||||
"leaflet-edgebuffer": "^1.0.6",
|
"leaflet-edgebuffer": "^1.0.6",
|
||||||
|
"leaflet.heat": "^0.2.0",
|
||||||
"luxon": "^3.3.0",
|
"luxon": "^3.3.0",
|
||||||
"path-posix": "^1.0.0",
|
"path-posix": "^1.0.0",
|
||||||
"photoswipe": "^5.3.8",
|
"photoswipe": "^5.3.8",
|
||||||
|
|
|
@ -30,6 +30,16 @@
|
||||||
</div>
|
</div>
|
||||||
</LIcon>
|
</LIcon>
|
||||||
</LMarker>
|
</LMarker>
|
||||||
|
<LHeatMap v-if="points.length >= 50"
|
||||||
|
ref="heatMap"
|
||||||
|
:initial-points="points"
|
||||||
|
:options="{
|
||||||
|
// minOpacity: null,
|
||||||
|
// maxZoom: null,
|
||||||
|
radius: 15,
|
||||||
|
blur: 10,
|
||||||
|
gradient: { 0.4: 'blue', 0.65: 'lime', 1: 'red' },
|
||||||
|
}" />
|
||||||
</LMap>
|
</LMap>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -37,6 +47,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { LMap, LTileLayer, LMarker, LPopup, LIcon } from 'vue2-leaflet';
|
import { LMap, LTileLayer, LMarker, LPopup, LIcon } from 'vue2-leaflet';
|
||||||
|
import LHeatMap from './map/LHeatMap.vue';
|
||||||
import { latLngBounds, Icon } from 'leaflet';
|
import { latLngBounds, Icon } from 'leaflet';
|
||||||
import { IPhoto } from '../../types';
|
import { IPhoto } from '../../types';
|
||||||
|
|
||||||
|
@ -73,6 +84,7 @@ Icon.Default.mergeOptions({
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'MapSplitMatter',
|
name: 'MapSplitMatter',
|
||||||
components: {
|
components: {
|
||||||
|
LHeatMap,
|
||||||
LMap,
|
LMap,
|
||||||
LTileLayer,
|
LTileLayer,
|
||||||
LMarker,
|
LMarker,
|
||||||
|
@ -88,6 +100,7 @@ export default defineComponent({
|
||||||
maxBoundsViscosity: 0.9,
|
maxBoundsViscosity: 0.9,
|
||||||
},
|
},
|
||||||
clusters: [] as IMarkerCluster[],
|
clusters: [] as IMarkerCluster[],
|
||||||
|
points: [],
|
||||||
animMarkers: false,
|
animMarkers: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -137,6 +150,7 @@ export default defineComponent({
|
||||||
if (!reinit) {
|
if (!reinit) {
|
||||||
this.setBoundsFromQuery();
|
this.setBoundsFromQuery();
|
||||||
}
|
}
|
||||||
|
await this.fetchPoints();
|
||||||
return await this.fetchClusters();
|
return await this.fetchClusters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,6 +259,34 @@ export default defineComponent({
|
||||||
this.animateMarkers();
|
this.animateMarkers();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async fetchPoints() {
|
||||||
|
const zoom = "18";
|
||||||
|
let minLat = -90;
|
||||||
|
let maxLat = 90;
|
||||||
|
let minLon = -180;
|
||||||
|
let maxLon = 180;
|
||||||
|
|
||||||
|
// Extend bounds by 25% beyond the map
|
||||||
|
const latDiff = Math.abs(maxLat - minLat);
|
||||||
|
const lonDiff = Math.abs(maxLon - minLon);
|
||||||
|
minLat -= latDiff * 0.25;
|
||||||
|
maxLat += latDiff * 0.25;
|
||||||
|
minLon -= lonDiff * 0.25;
|
||||||
|
maxLon += lonDiff * 0.25;
|
||||||
|
|
||||||
|
// Get bounds with expanded margins
|
||||||
|
const bounds = this.boundsToStr({ minLat, maxLat, minLon, maxLon });
|
||||||
|
|
||||||
|
// Make API call
|
||||||
|
const url = API.Q(API.MAP_CLUSTERS(), { bounds, zoom });
|
||||||
|
|
||||||
|
// Params have changed, quit
|
||||||
|
const res = await axios.get(url);
|
||||||
|
this.points = res.data.map((c) => {
|
||||||
|
return [c.center[0], c.center[1], c.count]
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
boundsFromQuery() {
|
boundsFromQuery() {
|
||||||
const bounds = (this.$route.query.b as string).split(',');
|
const bounds = (this.$route.query.b as string).split(',');
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div style="display: none;">
|
||||||
|
<slot v-if="ready" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import 'leaflet.heat/dist/leaflet-heat.js'
|
||||||
|
import { findRealParent, propsBinder } from 'vue2-leaflet'
|
||||||
|
import { DomEvent } from 'leaflet'
|
||||||
|
|
||||||
|
const props = {
|
||||||
|
initialPoints: {
|
||||||
|
type: Array,
|
||||||
|
required: false,
|
||||||
|
default() { return [] },
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
type: Object,
|
||||||
|
default() { return {} },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props,
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
points: null,
|
||||||
|
ready: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
options: {
|
||||||
|
handler(newOptions) {
|
||||||
|
this.mapObject.setOptions(newOptions)
|
||||||
|
},
|
||||||
|
deep: true,
|
||||||
|
},
|
||||||
|
points: {
|
||||||
|
handler(newPoints) {
|
||||||
|
this.mapObject.setLatLngs(newPoints)
|
||||||
|
},
|
||||||
|
deep: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.points = this.initialPoints
|
||||||
|
this.mapObject = L.heatLayer(this.points, this.options)
|
||||||
|
DomEvent.on(this.mapObject, this.$listeners)
|
||||||
|
propsBinder(this, this.mapObject, props)
|
||||||
|
this.ready = true
|
||||||
|
this.parentContainer = findRealParent(this.$parent)
|
||||||
|
this.parentContainer.addLayer(this)
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$emit('ready', this.mapObject)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.parentContainer.removeLayer(this)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
addLayer(layer, alreadyAdded) {
|
||||||
|
if (!alreadyAdded) {
|
||||||
|
this.mapObject.addLayer(layer.mapObject)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeLayer(layer, alreadyRemoved) {
|
||||||
|
if (!alreadyRemoved) {
|
||||||
|
this.mapObject.removeLayer(layer.mapObject)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addLatLng(latlng) {
|
||||||
|
this.mapObject.addLatLng(latlng)
|
||||||
|
},
|
||||||
|
setLatLngs(latlngs) {
|
||||||
|
this.mapObject.setLatLngs(latlngs)
|
||||||
|
},
|
||||||
|
redraw() {
|
||||||
|
this.mapObject.redraw()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
Loading…
Reference in New Issue