Labels on features - ajax call - javascript

I am using leaflet 0.7 and want to add a static label using the leaflet.label plugin.
I get the data with a ajax call. I am not sure where to put my onEachFeature function to populate the labels. I am relatively new to javascript and think i got a bit confused on this one.
This code works as long as I use layer.bindLabel('static label'). But I cannot populate it with data from my ajax call.
I know the layer is created before the ajax call and thus not have access to the data. How can I arrange the code to populate the Label with data from my ajax call?
Any help is greatly appreciated
var pointlayer= new L.GeoJSON(null, {
pointToLayer: function (feature, latlng) {
return L.marker(latlng, {icon: sandicon});
},
onEachFeature: function (feature, layer) {
layer.bindLabel(feature.properties.id, //Dynamic label
{noHide:true,direction:'auto'});
},
onEachFeature: function (feature, layer) {
layer.bindPopup('Test' + feature.properties.id);
}
}).addTo(map);
$.ajax({
url: "url",
dataType: 'jsonp',
cache: false,
jsonpCallback: 'getPoint',
success: handlePoint,
});
function handlePoint(data) {
pointlayer.addData(data);
};

You have to bind your label to the marker created in pointToLayer
EDIT: this was not the error
I am not sure where you went wrong but I left a working example here:
https://github.com/yafred/ajax-geojson-and-labels (source)
https://yafred.github.io/ajax-geojson-and-labels/ (web)
Note: L.GeoJSON is for leaflet 1.0, L.GeoJson is for leaflet 0.7

Related

Leaflet - openPopup() not showing with geoJSON

I am trying to bind popups to markers on a geoJSON layer. To do this, I am using the onEachFeature function:
var onEachFeature = function(feature, layer) {
layer.bindPopup("hello",
{closeButton:false,
autoClose: false,
closeOnClick: false,
className: "popup-custom"}).openPopup();
}
This does not result in a popup showing. The popup is created but I need to click on the marker to display it.
What am I missing to make the popup visible without clicking on the marker?
I am not using the pointToLayer function because I am also filtering the features with the filter fuction and using request to customise the popups and the markers (the popup binding is actually in a callback function).
You get a geojsonlayer as result and then you can open the popup for each layer:
var geojsonLayer = L.geoJSON(data, {
onEachFeature : onEachFeature
}).addTo(map);
geojsonLayer.eachLayer(function(layer){
layer.openPopup();
});
Thank you #Falke-Design, I got it to work. I had tried this but it did not work :
var geojsonLayer = L.geoJSON(data, {
onEachFeature : onEachFeature
});
geojsonLayer.eachLayer(function(layer){
layer.openPopup();
});
geojsonLayer.addTo(map);
Could you explain why this did not work?

Fill Leaflet popup on click when acctually needed

I have a map with a lot of markers and a complex popup content, generated by a function called popupcontent(), which takes a lot of time to compute when it is done for all markers on the map with the oneachfeature function.
Is there a way to trigger a function in a popup only when it is actually opened instead of generating all the popups in the beginning? This would speed up loading time a lot.
This is my code so far (I am using the markerclusterer extension):
var geojson1 = L.geoJson(bigJson,{
onEachFeature: function (feature, layer) {
layer.bindPopup(popupcontent(feature,layer));
}
})
.addLayer(tiles);
var markers = L.markerClusterGroup({
spiderfyOnMaxZoom: true,
showCoverageOnHover: true,
zoomToBoundsOnClick: true,
disableClusteringAtZoom: 10,
removeOutsideVisibleBounds:true
});
var geoJsonLayer = L.geoJson(bigJson, {
});
markers.addLayer(geojson1);
map.addLayer(markers);
map.fitBounds(markers.getBounds());
Demo: http://stefang.cepheus.uberspace.de/farmshops/
I think what you're looking for is something like so (if your layer is an interactive layer):
onEachFeature: function (feature, layer) {
layer.once("click", ()=>{
layer.bindPopup(popupcontent(feature,layer)).openPopup();
});
}
Use "once" instead of "on" so it only gets binded once when the layer is clicked.

Styling individual markers in markercluster

I am trying to style individual markers, or clusters of size 1, based on some feature property.
var markers = L.markerClusterGroup();
function onEachFeature(feature, layer) {
if (feature.properties.EncounterType && feature.properties.Year) {
layer.bindPopup(feature.properties.EncounterType + " in " +
feature.properties.Year);
}
}
function style(feature) {
switch (feature.properties.EncounterType) {
case 'Shooting':
return {
color: "ff0000"
};
case 'Sighting':
return {
color: "0000ff"
};
case 'Hunting':
return {
color: "ff0000"
};
}
}
var geoJsonLayer = L.geoJSON(storer, {
onEachFeature: onEachFeature
}, {
style: style
});
markers.addLayer(geoJsonLayer);
map.addLayer(markers);
The onEachFeature function successfully creates the popups. However, the style function does not change the color of the clusters of size 1. I've tried using the iconCreateFunction when initializing the markerclustergroup, however, that did not work either.
Your style option is separated in a 3rd argument of your call to L.geoJSON factory, whereas it should have been placed within the 2nd argument, alongside onEachFeature option.
var geoJsonLayer = L.geoJSON(storer, {
onEachFeature: onEachFeature,
style: style
});
But that is probably not the only reason for your issue.
style option will apply to vector shapes (polylines, polygons, etc.), i.e. to non-point data. It may also apply to Circle Markers, which can be used for Point type geometries, but you have to explicitly create them (typically through the pointToLayer option).
Those non-point data cannot be handled by Leaflet.markercluster.
Therefore if you see "clusters of size 1" (I guess you mean markers), they come from unstyled Point type geometries in your storer GeoJSON data.
This is a normal marker:
It is a PNG image that cannot be styled.
If you want to customize the appearance of your Point geometries, use custom icons, a plugin that provide such custom icons, or Circle Markers which you can modify the colour easily (including through the style option).
For example, if you were to choose that last option, you could do something like:
var geoJsonLayer = L.geoJSON(storer, {
pointToLayer: function (geoJsonPoint, latlng) {
return L.circleMarker(latlng);
},
onEachFeature: onEachFeature,
style: style
});

Return name of geoJSON leaflet layer with click

I have a leaflet map with multiple geoJSON layers:
var site1 = new L.geoJSON(site1_geojson, {
onEachFeature: onEachFeature,
pointToLayer: function (feature, latlng) {
return L.circleMarker(latlng, style);
}
}).addTo(map);
I would like the onEachFeature function to return the name (e.g. "site1") of the layer clicked on. Something like:
var nameOfLayer;
function onEachFeature(feature, layer) {
layer.on('click', function(e) {
nameOfLayer = ????
});
}
I've tried assigning feature and layer to nameOfLayer, but from what I can gather those look like just the point clicked on, not the geoJSON layer itself.
Is this possible to do with leaflet and JavaScript?
If you want a constant string:
var site1 = L.geoJSON(site1_geojson, {
pointToLayer: function (feature, latlng) {
return L.circleMarker(latlng, style);
}
}).addTo(map).bindPopup('Site 1');
If you want a popup specific to each layer / feature, and this specific content is reachable in each Feature properties, you can refer to Combining geojson and json for leaftlet and Leaflet omnivore + clustering markers + filtering marker cluster group

How to fit the map out of the layer bounds?

I have a leaflet map, i added a point layer to it that returns from ajax call, i want to fit the map a little bit away from its bounds so that i can see the country it lies in it,how can this be done?
$.ajax({
type:"POST",
url:"CustomerID_geojson.php",
data:"OrdersID="+ Cust ,
dataType: 'json',
success: function (response)
{
geojsonLayer = L.geoJson(
response,
{
pointToLayer: function(feature, latlng)
{
var redMarker = L.AwesomeMarkers.icon({
icon: 'user',
markerColor: 'purple',
prefix: 'fa',
iconColor: 'white'
});
return L.marker(latlng, {icon:redMarker});
},
onEachFeature: function (feature, layer)
{
layer.bindTooltip('<label class="CustToolTip">Customer: ' + feature.properties.nick_name_) + '</label>';
}
}).addTo(mymap);
mymap.fitBounds(geojsonLayer.getBounds());
}
})
Cannot be done. A point is infinitesimally small and has zero area, so the bounding box of one point feature has zero area. Zooming to the maximum zoom level is the expected behaviour in this case.
You might want to use an alternative approach. e.g. create a L.Circle with the center in the marker, giving it a radius in meters, add it to the map so you can get its bounds, remove it from the map, then zoom to those bounds.

Categories