import { mapGetters } from 'vuex'
const shouldEnableClustering = (zoomLevel) => false //zoomLevel <= 14 //Enabling clustering at certain zoom level improves performance
export default {
computed: {
...mapGetters({
clientZones: 'zones/clientZones',
}),
},
watch: {
/**
* Client zones can be available in any map
* (Visible by default only if Zones module)
*/
clientZones: {
handler() {
//console.log('watch::zones-dataset-change::drawLegacyZones')
this.waitForMapRef(() => this.drawClientZones())
},
deep: true,
immediate: true,
},
moveendTimestamp() {
//Update markers if user pans the map only if non-clustering
if (!shouldEnableClustering(this.zoomLevel)) {
//console.log('watch::map-pan::drawLegacyZones')
this.drawClientZones()
}
},
zoomLevel() {
//console.log('watch::zoomLevel::drawLegacyZones')
this.drawClientZones()
},
mapOptions: {
handler(newValue, oldValue) {
if (newValue.zonesMarkersToggle !== oldValue.zonesMarkersToggle) {
//console.log('watch::toggle::drawLegacyZones')
this.drawClientZones()
}
},
deep: true,
},
},
methods: {
/**
* @function drawClientZones
* @description Draws client zones on the map based on the current bounds. Clustering is enabled at certain zoom levels. If non-clustering, zones are filtered out if outside viewport.
*/
drawClientZones() {
const self = this
if (this.clientZones.length === 0 || !this.getMap()) {
return
}
if (this.isZonesMap) {
return //Skip Generic zones if zones module (To avoid duplicated zones)
}
let enableClustering = shouldEnableClustering(this.zoomLevel)
let clusteringOptions = {}
if (enableClustering) {
clusteringOptions = {
clusterOptions: {
singleMarkerMode: true,
iconCreateFunction: function (cluster) {
return getClusterIcon(cluster)
},
},
}
function getClusterIcon(cluster) {
let size = 21
size = cluster.getChildCount() > 99 ? 16 : size
size = cluster.getChildCount() > 999 ? 12 : size
return L.divIcon({
className: 'cluster_marker',
html: `<div class="marker__content">
<div>
<img class="marker_icon alert_marker_icon"
src="./lib/realtimeMap/assets/picto_pins/Pin.svg">
<div class="alert_marker_icon_inner marker_icon_cluster_text" style="font-size:${size}px;">
${cluster.getChildCount()}
</div>
</img>
</div>`,
})
}
}
let visible = this.mapOptions.zonesMarkersToggle
let data = []
if (self.zoomLevel < 6) {
visible = false //Do not render if zoom distance above 50km
} else {
if (enableClustering) {
data = this.clientZones // Do not filter by bounds if clustering
} else {
// Function to filter the clientZones based on the bounds of a map instance (current viewport)
const getFilteredZones = () => {
let map = this.getMap()
let mapBounds = map.getBounds()
return this.clientZones.filter((item) =>
mapBounds.contains(L.latLng(item.lat, item.lng))
)
}
data = getFilteredZones()
}
}
/*console.log('drawClientZones', {
visible,
enableClustering,
dataLen: data.length,
})*/
this.$refs.map &&
this.$refs.map.drawGeometries &&
this.$refs.map.drawGeometries({
visible,
...clusteringOptions,
layer: 'clientZones',
data: data,
recreateLayerGroup: true,
generate(item, { map }) {
if (enableClustering) {
return L.marker([item.lat, item.lng]) //Dummy marker
}
let color = item.categoryColor || 'green'
let pathOptions = {
weight: 2,
color: '#014470',
fill: true,
fillOpacity: 0.8,
fillColor: color,
}
let geometry =
item.type === 'P'
? L.polygon(item.polygon, {
...pathOptions,
})
: L.circle([item.lat, item.lng], {
...pathOptions,
radius: item.radius,
})
let accessPointGeometry = L.marker(
[item.access_lat, item.access_lng],
{
icon: L.divIcon({
className: 'zone_marker__access_point_icon',
html: `<svg xmlns="http: //www. W3. Org/2000/svg" width="18.385" height="18.385" viewbox="0 0 18.385 18.385" > <g class="a" transform="translate(9.192) rotate(45)" : fill="var(--color-dark-blue)" > <rect class="b" style="stroke: none" stroke="none" width="13" height="13" rx="2" /> <rect class="c" style="fill: none" fill="none" x="0.5" y="0.5" width="12" height="12" rx="1.5" /> </g> </svg>`,
}),
}
)
let textGeometry = new L.marker([item.lat, item.lng], {
opacity: 1,
icon: L.divIcon({
html: `<div>
<img
src="/img/zones/${item.categoryImageName}"
title="${item.name}"
/>
${
self.zoomLevel > 16
? `<div><span>${item.name}</span></div>`
: ''
}
</div>
`,
iconAnchor: [16, 2],
className: 'zone_marker__text_icon',
}),
})
let layers = [geometry]
if (self.zoomLevel > 14) {
layers.push(textGeometry, accessPointGeometry)
}
return layers
},
})
},
},
}
Source