0

You will find my code below.

I have a map with category filters. The map initialize and display correctly but when I use the filter (and the filterMarkers function), the markers change but when I zoom or use the map, the whole "layer" position stays kind of "fixed" and markers position are wrong.

Do I do something wrong? Do I need to reinit the map on category change? Also I'm working with a class system, I'm probably missing something.

Thank you in advance!

import { createComponent } from '../utils/alpine'
import L from 'leaflet'

export default createComponent(({ $persist, $defaults }) => ({

    map: null,
    data: null,

    setup () {

        this.map = L.map('map').setView([42.284095, 9.108869], 9)

        L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}{r}.png', {
            attribution: 'données © OpenStreetMap/ODbL - rendu OSM France',
            minZoom: 1,
            maxZoom: 20
        }).addTo(this.map)

        const request = new XMLHttpRequest()
        
        request.open('GET', '/api/markers/map-1')
        request.responseType = 'json'
        request.send()
        request.onload = function() {
            this.data = request.response
            this.addAllLayers()
        }.bind(this)

    },

    addSelectedLayer (category) {
        const autoLayer = L.geoJson(this.data, {
            filter: function (feature, layer) {
                return feature.properties.ca === category
            },
            pointToLayer: function (feature, latlng) {

                const title = feature.properties.ti
                const link = feature.properties.li
                const image = feature.properties.im
                const description = feature.properties.de
                const category = feature.properties.ca

                const categoryIcon = {
                    cat1: {color: 'bg-brown', size: 'w-[16px] h-[16px]', icon: 'i-[castle]'},
                    cat2: {color: 'bg-valid', size: 'w-[17px] h-[17px]', icon: 'i-[hiking]'},
                    cat3: {color: 'bg-orange', size: 'w-[16px] h-[16px]', icon: 'i-[eating]'},
                    cat4: {color: 'bg-danube', size: 'w-[18px] h-[18px]', icon: 'i-[swimming]'},
                    cat5: {color: 'bg-yellow-dark', size: 'w-[19px] h-[19px]', icon: 'i-[leasure]'},
                };

                const categoryIconHtml = '<span class="' + categoryIcon[category].color + ' w-8 h-8 rounded-full block relative"><i class="' + categoryIcon[category].size + ' ' + categoryIcon[category].icon + ' text-white absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2"></i><span class="' + categoryIcon[category].color + ' block absolute -bottom-1 left-1/2 -translate-x-1/2 -translate-y-[1px] rotate-45 h-2 w-2"></span></span>'

                let popupContent = ''
                popupContent = '<div class="flex bg-white rounded-xl overflow-hidden w-[600px]"><div class="w-1/2 h-48 relative"><img class="absolute inset-0 h-full w-full object-cover" src="' + image + '" /></div><div class="w-1/2 p-4"><span class="text-base font-semibold">' + title + '</span><span class="block mt-1 text-base">' + description + '</span><span>' + link + '</span></div></div>'

                return L.marker(latlng, {
                    category: category,
                    title: title,
                    icon: L.divIcon({ html: categoryIconHtml, iconSize: [24,36], iconAnchor: [12,36] })
                }).bindPopup(popupContent)
      
            }
        })
        autoLayer.addTo(this.map)
    },

    addAllLayers () {
        this.clearLayers()
        for (let i = 1; i < 6; i++) {
            this.addSelectedLayer('cat' + i)
        }
    },

    clearLayers () {
        this.map.eachLayer(function (layer) {
            if (typeof layer._url === 'undefined') {
                this.map.removeLayer(layer)
            }
        }.bind(this))
    },

    filterMarkers(category) {
        if (category === 'all') {
            this.addAllLayers()
        } else {
            this.clearLayers()
            this.addSelectedLayer(category)
        }
    },

}))
3
  • How do you handle the moveend and the zoomend events? I can't see that in your code. If you don't have them, you would have to add them, and reinitialize the markers (remove the old markers, show new markers, etc) within those events. Commented Jan 5, 2023 at 19:04
  • Hmm not sure I need them? I was using this code from another project but I reorganized it in a class and I think I'm missing something. Commented Jan 5, 2023 at 19:36
  • Seems problem disappeared when I removed the zoom animation this.map = L.map('map', {zoomControl: true,zoom:1,zoomAnimation:false,fadeAnimation:true,markerZoomAnimation:true}).setView([42.284095, 9.108869], 9) Commented Jan 5, 2023 at 21:07

0