|
|
@@ -25,19 +25,10 @@
|
|
|
|
|
|
<script lang="ts">
|
|
|
import 'leaflet/dist/leaflet.css'
|
|
|
-import {
|
|
|
- Layer,
|
|
|
- LatLngBounds,
|
|
|
- LatLngBoundsExpression, LatLngBoundsLiteral,
|
|
|
- LatLngTuple,
|
|
|
- MapOptions,
|
|
|
- Map
|
|
|
-} from 'leaflet'
|
|
|
import Vue from 'vue'
|
|
|
|
|
|
let L: any
|
|
|
-if (typeof window !== 'undefined') {
|
|
|
- // only require leaflet on client-side
|
|
|
+if (process.client) { // only require leaflet on client-side
|
|
|
L = require('leaflet')
|
|
|
}
|
|
|
|
|
|
@@ -45,8 +36,9 @@ declare module 'vue/types/vue' {
|
|
|
interface Vue {
|
|
|
structures: Array<Structure>,
|
|
|
zoomRequired: boolean,
|
|
|
- map: Map,
|
|
|
- defaultBounds: LatLngBounds
|
|
|
+ map: any,
|
|
|
+ defaultBounds: L.LatLngBounds,
|
|
|
+ shortcuts: Array<{src: string, alt: string, bounds: number[][] }>
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -58,12 +50,10 @@ export default Vue.extend({
|
|
|
default: () => []
|
|
|
}
|
|
|
},
|
|
|
- data (): object {
|
|
|
- const options: MapOptions = { scrollWheelZoom: false, zoomSnap: 0.25 }
|
|
|
-
|
|
|
+ data () {
|
|
|
return {
|
|
|
- map: L.map('map', options),
|
|
|
- defaultBounds: new LatLngBounds([51.03, -5.78], [41.2, 9.70]),
|
|
|
+ map: null,
|
|
|
+ defaultBounds: new L.LatLngBounds([51.03, -5.78], [41.2, 9.70]),
|
|
|
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]] },
|
|
|
@@ -87,12 +77,15 @@ export default Vue.extend({
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
- mounted (): void {
|
|
|
- const defaultCenter: LatLngTuple = [46.71, 1.94]
|
|
|
+ mounted () {
|
|
|
+ const defaultCenter: L.LatLngTuple = [46.71, 1.94]
|
|
|
const defaultZoom: number = 5.75
|
|
|
const layerSource: string = 'http://{s}.tile.osm.org/{z}/{x}/{y}.png'
|
|
|
const attribution: string = '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
|
|
|
|
|
|
+ const options: L.MapOptions = { scrollWheelZoom: false, zoomSnap: 0.25 }
|
|
|
+
|
|
|
+ this.map = L.map('map', options)
|
|
|
this.map.setView(defaultCenter, defaultZoom)
|
|
|
L.tileLayer(layerSource, { attribution }).addTo(this.map)
|
|
|
|
|
|
@@ -110,7 +103,7 @@ export default Vue.extend({
|
|
|
methods: {
|
|
|
populateMarkers (): void {
|
|
|
// remove any existant marker layers
|
|
|
- this.map.eachLayer((layer: Layer) => {
|
|
|
+ this.map.eachLayer((layer: L.Layer) => {
|
|
|
if (layer instanceof L.MarkerClusterGroup) {
|
|
|
this.map.removeLayer(layer)
|
|
|
}
|
|
|
@@ -127,7 +120,7 @@ export default Vue.extend({
|
|
|
}
|
|
|
this.map.addLayer(clusters)
|
|
|
},
|
|
|
- setMapBounds (bounds: LatLngBoundsExpression): void {
|
|
|
+ setMapBounds (bounds: L.LatLngBoundsExpression): void {
|
|
|
this.map.fitBounds(bounds) // << without this, the new bounds may not be properly set when the current view overlaps the new bounds.
|
|
|
},
|
|
|
resetBounds (): void {
|
|
|
@@ -137,15 +130,15 @@ export default Vue.extend({
|
|
|
this.zoomRequired = true
|
|
|
},
|
|
|
_fitBoundsToMarkers (): void {
|
|
|
- const coords: LatLngBoundsLiteral = this.structures.filter(
|
|
|
- (s) => {
|
|
|
+ const coords: L.LatLngBoundsLiteral = this.structures.filter(
|
|
|
+ (s: Structure) => {
|
|
|
return (
|
|
|
s.latitude && typeof s.latitude !== 'undefined' &&
|
|
|
s.longitude && typeof s.latitude !== 'undefined'
|
|
|
)
|
|
|
}
|
|
|
).map(
|
|
|
- (s) => { return [s.latitude as number, s.longitude as number] as LatLngTuple }
|
|
|
+ (s: Structure) => { return [s.latitude as number, s.longitude as number] as L.LatLngTuple }
|
|
|
)
|
|
|
|
|
|
if (!coords) {
|