Reputation: 139
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
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
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
Reputation: 11338
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() {
...
var map = ...
// add an OpenStreetMap tile layer
L.tileLayer( ... ).addTo(map);
var fg = L.featureGroup().addTo(map);
function loadMap() {
...
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
}
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