|
|
@@ -57,23 +57,20 @@ declare module 'vue/types/vue' {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+const METROPOLE_BOUNDS = new L.LatLngBounds([51.03, -5.78], [41.2, 9.70])
|
|
|
+
|
|
|
export default Vue.extend({
|
|
|
props: {
|
|
|
structures: {
|
|
|
type: Array as () => Array<Structure>,
|
|
|
required: false,
|
|
|
default: () => []
|
|
|
- },
|
|
|
- zoomAtStart: {
|
|
|
- type: Boolean,
|
|
|
- required: false,
|
|
|
- default: false
|
|
|
}
|
|
|
},
|
|
|
data () {
|
|
|
return {
|
|
|
map: null,
|
|
|
- defaultBounds: new L.LatLngBounds([51.03, -5.78], [41.2, 9.70]),
|
|
|
+ defaultBounds: METROPOLE_BOUNDS,
|
|
|
shortcuts: [
|
|
|
{ src: '/images/metropole.png', alt: 'Metropole', bounds: [[51.03, -5.78], [41.2, 9.70]] },
|
|
|
{ src: '/images/guadeloupe.png', alt: 'Guadeloupe', bounds: [[16.62, -62.03], [15.74, -60.97]] },
|
|
|
@@ -82,7 +79,9 @@ export default Vue.extend({
|
|
|
{ src: '/images/la_reunion.png', alt: 'La Réunion', bounds: [[-20.65, 54.92], [-21.65, 56.15]] },
|
|
|
{ src: '/images/guyane.png', alt: 'Guyane', bounds: [[6.24, -54.62], [1.87, -50.59]] }
|
|
|
],
|
|
|
- zoomRequired: this.zoomAtStart
|
|
|
+ zoomRequired: false,
|
|
|
+ nextZoomIsDefault: false,
|
|
|
+ firstPopulate: true
|
|
|
}
|
|
|
},
|
|
|
watch: {
|
|
|
@@ -90,13 +89,12 @@ export default Vue.extend({
|
|
|
if (oldVal !== newVal) {
|
|
|
this.populateMarkers()
|
|
|
}
|
|
|
-
|
|
|
if (this.zoomRequired) {
|
|
|
- this._applyZoom()
|
|
|
+ this.fitBoundsToMarkers()
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
- mounted () {
|
|
|
+ async mounted () {
|
|
|
const defaultCenter: L.LatLngTuple = [46.71, 1.94]
|
|
|
const defaultZoom: number = 5.5
|
|
|
const layerSource: string = 'http://{s}.tile.osm.org/{z}/{x}/{y}.png'
|
|
|
@@ -108,14 +106,14 @@ export default Vue.extend({
|
|
|
this.map.setView(defaultCenter, defaultZoom)
|
|
|
L.tileLayer(layerSource, { attribution }).addTo(this.map)
|
|
|
|
|
|
- this.populateMarkers()
|
|
|
+ await this.populateMarkers()
|
|
|
|
|
|
this.map.on('zoomend moveend', () => {
|
|
|
this.$emit('boundsUpdated', this.map.getBounds())
|
|
|
})
|
|
|
|
|
|
if (this.zoomRequired) {
|
|
|
- this._applyZoom()
|
|
|
+ this.fitBoundsToMarkers()
|
|
|
}
|
|
|
},
|
|
|
beforeDestroy (): void {
|
|
|
@@ -124,7 +122,7 @@ export default Vue.extend({
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
- populateMarkers (): void {
|
|
|
+ populateMarkers () {
|
|
|
// remove any existant marker layers
|
|
|
this.map.eachLayer((layer: L.Layer) => {
|
|
|
if (layer instanceof L.MarkerClusterGroup) {
|
|
|
@@ -142,17 +140,30 @@ export default Vue.extend({
|
|
|
clusters.addLayer(marker)
|
|
|
}
|
|
|
this.map.addLayer(clusters)
|
|
|
+
|
|
|
+ if (this.firstPopulate) {
|
|
|
+ if (this.structures.length > 0) { // map is considered as mounted only when the first results are diplayed on it
|
|
|
+ this.$emit('mounted')
|
|
|
+ this.firstPopulate = false
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.$emit('populated')
|
|
|
+ }
|
|
|
},
|
|
|
setMapBounds (bounds: L.LatLngBoundsExpression, padding: [number, number] = [0, 0]): void {
|
|
|
this.map.fitBounds(bounds, { padding }) // << without this, the new bounds may not be properly set when the current view overlaps the new bounds.
|
|
|
},
|
|
|
resetBounds (): void {
|
|
|
- this.setMapBounds(this.defaultBounds)
|
|
|
+ this.setMapBounds(
|
|
|
+ this.defaultBounds,
|
|
|
+ (this.defaultBounds === METROPOLE_BOUNDS ? [0, 0] : [80, 80]) as [number, number]
|
|
|
+ )
|
|
|
},
|
|
|
- zoomOnResults (): void {
|
|
|
+ fitNextResults (setAsDefault = false) {
|
|
|
this.zoomRequired = true
|
|
|
+ this.nextZoomIsDefault = setAsDefault
|
|
|
},
|
|
|
- _fitBoundsToMarkers (): boolean {
|
|
|
+ fitBoundsToMarkers (): boolean {
|
|
|
const coords: L.LatLngBoundsLiteral = this.structures.filter(
|
|
|
(s: Structure) => {
|
|
|
return (
|
|
|
@@ -167,15 +178,13 @@ export default Vue.extend({
|
|
|
if (!(coords.length > 0)) {
|
|
|
return false
|
|
|
}
|
|
|
+
|
|
|
this.setMapBounds(coords, [80, 80])
|
|
|
- return true
|
|
|
- },
|
|
|
- _applyZoom (): void {
|
|
|
- const zoomed = this._fitBoundsToMarkers()
|
|
|
- if (!zoomed) {
|
|
|
- this.setMapBounds(this.defaultBounds)
|
|
|
+
|
|
|
+ if (this.nextZoomIsDefault) {
|
|
|
+ this.defaultBounds = coords
|
|
|
}
|
|
|
- this.zoomRequired = false
|
|
|
+ return true
|
|
|
}
|
|
|
}
|
|
|
})
|