pierrot10
pierrot10

Reputation: 139

How can I refresh the leaflet marker value

Good evening,

I am using Leaflet.js to localize the station which measure the temperature of bud. The app needs to generate an alarm when the temperature is too low. The user can view the temperature shown in markers. The app needs to request a MySQL database to collect the needed records.

On each refreshed, I do not want to reload the map, because the station does not move.

Is there a way to reload only the makers, or to update the value?

Here is how I load my map

    function refreshMap(){
        loadMap();
    }
    
    function loadMap(){
    
        var get_map_center = [];
    
        $.ajax({
            type: "POST",
            url: "https://sub.domain.ch/sql/mysql.php",
            crossDomain: true,
            success: result,
            error: error,
            dataType: "json"
        });
    
        function error(data)
        {
            alert("Error getting datas from DB");
            console.log("Error getting datas from DB");
            console.log(data);
    
            showMap(46.187164,5.997526,null);
        }
    
        function result(data){
            console.info("data:",data);
    
           for(var y=0; y < data.map_center.length; y++)
           {
                get_map_center.push(data.map_center[y]);
           }
    
            
            var allMarkers = [];
            var markers = L.markerClusterGroup({
                showCoverageOnHover: false
            });

            // THIS ADD AN IMAGE IF THE TEMPERATURE ARE NORMAL; LIMITE OR TO LOW
            var nhtml = '<img src="img/property-types/vineyard.png">';
    
            for (var i = 0; i < data.properties.length; i++) 
            {
                allMarkers.push(L.latLng(data.properties[i]['la'], data.properties[i]['lo']));
    
                if((data.properties[i]['b1']>=data.properties[i]['se'] && data.properties[i]['b1'] < data.properties[i]['se']+1) ||
                        (data.properties[i]['b2']>=data.properties[i]['se'] && data.properties[i]['b2'] < data.properties[i]['se']+1) ||
                        (data.properties[i]['b3']>=data.properties[i]['se'] && data.properties[i]['b3'] < data.properties[i]['se']+1) ||
                        (data.properties[i]['b4']>=data.properties[i]['se'] && data.properties[i]['b4'] < data.properties[i]['se']+1)
                    )
                {
                    nhtml = '<img src="img/property-types/vineyard-orange.png">';
                }
    
                if(((data.properties[i]['b1'] < data.properties[i]['se']) && data.properties[i]['b1'] != null) ||
                        ((data.properties[i]['b2'] < data.properties[i]['se']) && data.properties[i]['b2'] != null) ||
                        ((data.properties[i]['b3'] < data.properties[i]['se']) && data.properties[i]['b3'] != null) ||
                        ((data.properties[i]['b4'] < data.properties[i]['se']) && data.properties[i]['b4'] != null)
                    )
                {   
                    nhtml = '<img src="img/property-types/vineyard-red.png">';
                }
                else{
                    nhtml = '<img src="img/property-types/vineyard.png">';
                }
    
    
                var _icon = L.divIcon({
                    //html: '<img src="' + locations[i][7] +'">',
                    html: nhtml,
                    iconSize:     [40, 48],
                    iconAnchor:   [20, 48],
                    popupAnchor:  [0, -48]
                });
    
                var title = data.properties[i]['station'];
                var marker = L.marker(new L.LatLng(data.properties[i]['la'],data.properties[i]['lo']), {
                    title: title,
                    icon: _icon
                });
    
                var str ='';
                if(data.properties[i]['b1'] != null)
                {
                    str = str.concat('<div class="tag price"> ' + data.properties[i]['b1'] + '°C</div>');
                }
                if(data.properties[i]['b2'] != null)
                {
                    str = str.concat('<div class="tag price"> ' + data.properties[i]['b2'] + '°C</div>');
                }
                if(data.properties[i]['b3'] != null)
                {
                    str = str.concat('<div class="tag price"> ' + data.properties[i]['b3'] + '°C</div>');
                }
                if(data.properties[i]['b4'] != null)
                {
                    str = str.concat('<div class="tag price"> ' + data.properties[i]['b4'] + '°C</div>');
                }
    
                marker.bindPopup(
                        '<div class="property">' +
                            '' +
                                '<div class="property-image">' +
    
                                    '<img src="img/stations/station-' + data.properties[i]['id_station'] + '.jpg">' +
                                '</div>' +
                                '<div class="overlay">' +
    
                                    '<div class="info">' +
                                          '<h3>' + data.properties[i]['station'] + '</h3>' +
                                        '<p>' + data.properties[i]['da'] + '</p>' +
                                        // '<figure>' + data.properties[i]['la'] + ' ' + data.properties[i]['lo'] +'</figure>' +
                                        str +
                                        '<p> <a data-field=' + data.properties[i]['id_field'] +'" data-station=' + data.properties[i]['id_station'] +'" href="https://bud.eco-sensors.ch/charts.php?field='+ data.properties[i]['id_field'] +'#st-'+ data.properties[i]['id_station'] +'">Historique</a></p>' +
                              
                                        //'<div class="tag"> ' + data.properties[i]['se'] + '°C</div>' +
                                        
                                      
                                    '</div>' +
                                '</div>' +
                            '' +
                        '</div>',{autoClose: true, closeOnClick: true, closeButton: true}
                );
    
    /*
    *. THOSE VALUES NEEED TO BE UPDATED
    */
    
                 var val = '';
    
                if(!isEmpty(data.properties[i]['b4']))
                {
                    val = data.properties[i]['b4'] +'°C ';
                }
    
                if(!isEmpty(data.properties[i]['b1']))
                {
                    val = val + data.properties[i]['b1'] +'°C ';
                }
    
                if(!isEmpty(data.properties[i]['su']))
                {
                    val = val + data.properties[i]['su'] +'W/m2 ';
                }
    
                if(!isEmpty(data.properties[i]['an']))
                {
                    val = val + data.properties[i]['an'] +'km/h ';
                }
    
                if(!isEmpty(data.properties[i]['sb']))
                {
                    val = val + data.properties[i]['sb'] +'°C (B)';
                }
    
                if(!isEmpty(data.properties[i]['sl']))
                {
                    val = val + data.properties[i]['sl'] +'°C (F)';
                }
                marker.bindTooltip(val, {direction: 'bottom', permanent: true});
                markers.addLayer(marker);
            }
            showMap(get_map_center[0][0],get_map_center[0][1], markers);
    
        } // End result
    }
    
    /*
    * BUILD THE MAP AFTER THE FUNCTION 'result' OF AJAX
    * I need it to make sure that the map is initialized when AJAX finishes loading
    */
    
    function showMap(lat,lng, markers){
    
        var map = L.map('map', {
                //center: [46.187164,5.997526],
                center: [lat,lng],
                zoom: 14,
                scrollWheelZoom: false
            });
    
             
    
            // add an OpenStreetMap tile layer
            L.tileLayer('https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', {
            //subdomains: '0123',
                maxZoom: 20,
                attribution: '<a href="https://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'
            }).addTo(map);
    
            if(markers!=null){
                map.addLayer(markers);  
            }   
    }

Maybe it can done better, but this works fine, except that I need to update the value in the bind tooltips when I make a new MySQL request to get the new value.

I hope I clearly explained my needs ;) Is possible to reload the markers (or the value) without reloading the full map?

Many thanks

Upvotes: 0

Views: 1697

Answers (2)

pierrot10
pierrot10

Reputation: 139

So many thank, that works fine. That's great.

I just add to correct this

map.panTo(get_map_center[0][0],get_map_center[0][1]);

to

map.panTo([get_map_center[0][0],get_map_center[0][1]]);

Finally, the map was not show completely

enter image description here

I had that issue when I worked with leaflet, .... some year ago, and I found in my old code the following, and I added it after panto()

map.panTo([get_map_center[0][0] , get_map_center[0][1]]);
map.invalidateSize();

I did not know, if it would solve the problem. But I tried and the map is now well (and fully) displayed

I look at the doc

map.invalidateSize()
Checks if the map container size changed and updates the map if so — call it after you've changed the map size dynamically, also animating pan by default. If options.pan is false, panning will not occur. If options.debounceMoveend is true, it will delay moveend event so that it doesn't happen often even if the method is called many times in a row.

and it seems to be right choose, isn't?

So many thanks, that helped a lot!!!

Upvotes: 0

Falke Design
Falke Design

Reputation: 11338

  1. Create your map outside (=global), not in a function
var map = L.map('map', {
    //center: [46.187164,5.997526],
    center: [0, 0],
    zoom: 14,
    scrollWheelZoom: false
});

// add an OpenStreetMap tile layer
L.tileLayer('https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', {
    //subdomains: '0123',
    maxZoom: 20,
    attribution: '<a href="https://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'
}).addTo(map);

function loadMap() {
...
  1. Create a featureGroup where you add the markers instead adding them to the map:
var map = ...
// add an OpenStreetMap tile layer
L.tileLayer( ... ).addTo(map); 

var fg = L.featureGroup().addTo(map);

function loadMap() {
...
  1. When loadMap is called, clear the featureGroup and then add the markers to it (then the old markers are removed and the new one are added => refresh Markers)

Instead of showMap:

function result(){ 
 ...

            marker.bindTooltip(val, {direction: 'bottom', permanent: true});
            markers.addLayer(marker);
        }
        showMap(get_map_center[0][0],get_map_center[0][1], markers);

    } // End result
}

us this code:


function result(){ 
 ...

            marker.bindTooltip(val, {direction: 'bottom', permanent: true});
            markers.addLayer(marker);
        }
        fg.clearLayers();
        fg.addLayer(markers);
        map.panTo(get_map_center[0][0],get_map_center[0][1]);
    } // End result
}
  1. When you don't want that the map center is refreshed you can use a flag:

var map = ...
var fg = ...
var centered = false;

...

function result(){
...

        fg.clearLayers();
        fg.addLayer(markers);
        if(!centered){
            centered = true;
            // map is centered only once
            map.panTo(get_map_center[0][0],get_map_center[0][1]);
        }

Summary:

var map = L.map('map', {
    //center: [46.187164,5.997526],
    center: [0, 0],
    zoom: 14,
    scrollWheelZoom: false
});

// add an OpenStreetMap tile layer
L.tileLayer('https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', {
    //subdomains: '0123',
    maxZoom: 20,
    attribution: '<a href="https://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'
}).addTo(map);

var fg = L.featureGroup().addTo(map);
var centered = false;


function refreshMap(){
    loadMap();
}

function loadMap(){

    var get_map_center = [];

    $.ajax({
        type: "POST",
        url: "https://sub.domain.ch/sql/mysql.php",
        crossDomain: true,
        success: result,
        error: error,
        dataType: "json"
    });

    function error(data)
    {
        alert("Error getting datas from DB");
        console.log("Error getting datas from DB");
        console.log(data);

        showMap(46.187164,5.997526,null);
    }

    function result(data){
        console.info("data:",data);

       for(var y=0; y < data.map_center.length; y++)
       {
            get_map_center.push(data.map_center[y]);
       }

        
        var allMarkers = [];
        var markers = L.markerClusterGroup({
            showCoverageOnHover: false
        });
    
        // THIS ADD AN IMAGE IF THE TEMPERATURE ARE NORMAL; LIMITE OR TO LOW
        var nhtml = '<img src="img/property-types/vineyard.png">';

        for (var i = 0; i < data.properties.length; i++) 
        {
            allMarkers.push(L.latLng(data.properties[i]['la'], data.properties[i]['lo']));

            if((data.properties[i]['b1']>=data.properties[i]['se'] && data.properties[i]['b1'] < data.properties[i]['se']+1) ||
                    (data.properties[i]['b2']>=data.properties[i]['se'] && data.properties[i]['b2'] < data.properties[i]['se']+1) ||
                    (data.properties[i]['b3']>=data.properties[i]['se'] && data.properties[i]['b3'] < data.properties[i]['se']+1) ||
                    (data.properties[i]['b4']>=data.properties[i]['se'] && data.properties[i]['b4'] < data.properties[i]['se']+1)
                )
            {
                nhtml = '<img src="img/property-types/vineyard-orange.png">';
            }

            if(((data.properties[i]['b1'] < data.properties[i]['se']) && data.properties[i]['b1'] != null) ||
                    ((data.properties[i]['b2'] < data.properties[i]['se']) && data.properties[i]['b2'] != null) ||
                    ((data.properties[i]['b3'] < data.properties[i]['se']) && data.properties[i]['b3'] != null) ||
                    ((data.properties[i]['b4'] < data.properties[i]['se']) && data.properties[i]['b4'] != null)
                )
            {   
                nhtml = '<img src="img/property-types/vineyard-red.png">';
            }
            else{
                nhtml = '<img src="img/property-types/vineyard.png">';
            }


            var _icon = L.divIcon({
                //html: '<img src="' + locations[i][7] +'">',
                html: nhtml,
                iconSize:     [40, 48],
                iconAnchor:   [20, 48],
                popupAnchor:  [0, -48]
            });

            var title = data.properties[i]['station'];
            var marker = L.marker(new L.LatLng(data.properties[i]['la'],data.properties[i]['lo']), {
                title: title,
                icon: _icon
            });

            var str ='';
            if(data.properties[i]['b1'] != null)
            {
                str = str.concat('<div class="tag price"> ' + data.properties[i]['b1'] + '°C</div>');
            }
            if(data.properties[i]['b2'] != null)
            {
                str = str.concat('<div class="tag price"> ' + data.properties[i]['b2'] + '°C</div>');
            }
            if(data.properties[i]['b3'] != null)
            {
                str = str.concat('<div class="tag price"> ' + data.properties[i]['b3'] + '°C</div>');
            }
            if(data.properties[i]['b4'] != null)
            {
                str = str.concat('<div class="tag price"> ' + data.properties[i]['b4'] + '°C</div>');
            }

            marker.bindPopup(
                    '<div class="property">' +
                        '' +
                            '<div class="property-image">' +

                                '<img src="img/stations/station-' + data.properties[i]['id_station'] + '.jpg">' +
                            '</div>' +
                            '<div class="overlay">' +

                                '<div class="info">' +
                                      '<h3>' + data.properties[i]['station'] + '</h3>' +
                                    '<p>' + data.properties[i]['da'] + '</p>' +
                                    // '<figure>' + data.properties[i]['la'] + ' ' + data.properties[i]['lo'] +'</figure>' +
                                    str +
                                    '<p> <a data-field=' + data.properties[i]['id_field'] +'" data-station=' + data.properties[i]['id_station'] +'" href="https://bud.eco-sensors.ch/charts.php?field='+ data.properties[i]['id_field'] +'#st-'+ data.properties[i]['id_station'] +'">Historique</a></p>' +
                          
                                    //'<div class="tag"> ' + data.properties[i]['se'] + '°C</div>' +
                                    
                                  
                                '</div>' +
                            '</div>' +
                        '' +
                    '</div>',{autoClose: true, closeOnClick: true, closeButton: true}
            );

/*
*. THOSE VALUES NEEED TO BE UPDATED
*/

             var val = '';

            if(!isEmpty(data.properties[i]['b4']))
            {
                val = data.properties[i]['b4'] +'°C ';
            }

            if(!isEmpty(data.properties[i]['b1']))
            {
                val = val + data.properties[i]['b1'] +'°C ';
            }

            if(!isEmpty(data.properties[i]['su']))
            {
                val = val + data.properties[i]['su'] +'W/m2 ';
            }

            if(!isEmpty(data.properties[i]['an']))
            {
                val = val + data.properties[i]['an'] +'km/h ';
            }

            if(!isEmpty(data.properties[i]['sb']))
            {
                val = val + data.properties[i]['sb'] +'°C (B)';
            }

            if(!isEmpty(data.properties[i]['sl']))
            {
                val = val + data.properties[i]['sl'] +'°C (F)';
            }
            marker.bindTooltip(val, {direction: 'bottom', permanent: true});
            markers.addLayer(marker);
        }

        fg.clearLayers();
        fg.addLayer(markers);
        if(!centered){
            centered = true;
            // map is centered only once
            map.panTo(get_map_center[0][0],get_map_center[0][1]);
        }

    } // End result
}

Now you can call loadMap how often you want

Upvotes: 1

Related Questions