Update Leaflet GeoJSON layer with data inside bounding box - javascript

I'm using leaflet/JavaScript for the first time and I want to display a map, with a GeoJSON layer which change on every move… To only show points on the area.
This is my code source:
// Function to refresh points to display
function actualiseGeoJSON() {
// Default icon for my points
var defaultIcon = L.icon({
iconUrl: '../images/icones/cabane.png',
iconSize: [16, 16],
iconAnchor: [8, 8],
popupAnchor: [0, -8]
});
// We create each point with its style (from GeoJSON file)
function onEachFeature(feature, layer) {
var popupContent = '' + feature.properties.nom + "";
layer.bindPopup(popupContent);
var cabaneIcon = L.icon({
iconUrl: '../images/icones/' + feature.properties.type + '.png',
iconSize: [16, 16],
iconAnchor: [8, 8],
popupAnchor: [0, -8]
});
layer.setIcon(cabaneIcon);
}
// We download the GeoJSON file (by using ajax plugin)
var GeoJSONlayer = L.geoJson.ajax('../exportations/exportations.php?format=geojson&bbox=' + map.getBounds().toBBoxString() + '',{
onEachFeature: onEachFeature,
pointToLayer: function (feature, latlng) {
return L.marker(latlng, {icon: defaultIcon});
}
}).addTo(map);
}
// We create the map
var map = L.map('map');
L.tileLayer('http://maps.refuges.info/hiking/{z}/{x}/{y}.png', {
attribution: '© Contributeurs d\'OpenStreetMap',
maxZoom: 18
}).addTo(map);
// An empty base layer
var GeoJSONlayer = L.geoJson().addTo(map);
// Used to only show your area
function onLocationFound(e) {
var radius = e.accuracy / 2;
L.marker(e.latlng).addTo(map);
actualiseGeoJSON();
}
function onLocationError(e) {
alert(e.message);
actualiseGeoJSON();
}
function onMove() {
// map.removeLayer(GeoJSONlayer);
actualiseGeoJSON();
}
map.locate({setView: true, maxZoom: 14});
// Datas are modified if
map.on('locationerror', onLocationError);
map.on('locationfound', onLocationFound);
map.on('moveend', onMove);
I have tried to remove the layer in my first function but GeoJSONlayer is not defined
I have tried to remove the layer in onMove() but nothing appears
I have tried to remove the layer in moveend event but I have an syntax error…
If somebody can help me…
Sorry for my bad English, French guy ith french function names

I see you are using the leaflet ajax plugin.
The simplest way to get your map to work is to download all available data right at the start, providing a giant bounding box, and add it to the map just once. This will probably work just fine, unless there's insanely many cabins and stuff to download.
But if you wish to refresh the data regularly, based on the bounding box, you can use the refresh method in the leaflet-ajax plugin:
you can also add an array of urls instead of just one, bear in mind
that "addUrl" adds the new url(s) to the list of current ones, but if
you want to replace them use refresh e.g.:
var geojsonLayer = L.geoJson.ajax("data.json");
geojsonLayer.addUrl("data2.json");//we now have 2 layers
geojsonLayer.refresh();//redownload those two layers
geojsonLayer.refresh(["new1.json","new2.json"]);//add two new layer replacing the current ones
So initially:
var defaultIcon = ...
function onEachFeature(feature, layer) ...
// Do this in the same scope as the actualiseGeoJSON function,
// so it can read the variable
var GeoJSONlayer = L.geoJson.ajax(
'../exportations/exportations.php?format=geojson&bbox='
+ map.getBounds().toBBoxString() + '',{
onEachFeature: onEachFeature,
pointToLayer: function (feature, latlng) {
return L.marker(latlng, {icon: defaultIcon});
}
}).addTo(map);
And then for each update:
function actualiseGeoJSON() {
// GeoJSONLayer refers to the variable declared
// when the layer initially got added
GeoJSONlayer.refresh(
['../exportations/exportations.php?format=geojson&bbox='
+ map.getBounds().toBBoxString() + '']);
}
Alternatively, you could set the layer as a property of the map, instead of as a var:
map.geoJsonLayer = L.geoJson.ajax(...)
And later refer to it as follows:
map.geoJsonLayer.refresh(...)

this leaflet plugin is more suitable for your purpose, manage map events and zoom.
Caching remote requests and much more.
http://labs.easyblog.it/maps/leaflet-layerjson/
var ajaxUrl = "search.php?lat1={minlat}&lat2={maxlat}&lon1={minlon}&lon2={maxlon}";
map.addLayer( new L.LayerJSON({url: ajaxUrl }) );
Extend L.GeoJSON with more features and support ajax or jsonp request. See the source code comments for more documentation.

Related

KML is overlapping map and pop-up is not working

I am working with google maps. I have some lat longs and I display them on map using my use cases. Now I have implemented kml but the kml is loading after the map thus my pop-up is not working. I am attaching code below for the the reference.
var base = L.tileLayer('http://{s}.google.com/vt/lyrs=m&x={x}&y={y}&z={z}',{
maxZoom: 20,
subdomains:['mt0','mt1','mt2','mt3']
});
//=========================
var map = L.map('leafletmap', {
layers: [base],
tap: true,
center: new L.LatLng(30.864111, 72.355499), // alternative of - map.setView([31.582045, 74.329376], 15);
zoom: 7,
});
// Above is just Map
var kmlLayer = new L.KML("/assets/tehsil_punjab.kml",{async:true});
map.addLayer(kmlLayer);
// Here I loaded KML file
unction initialize() {
map.on('enterFullscreen', function () { // detect fullscreen toggling
if (window.console) window.console.log('enterFullscreen');
});
map.on('exitFullscreen', function () {
if (window.console) window.console.log('exitFullscreen');
});
// layerControl = new L.control.layers(baseMaps, overlayMaps).addTo(map);
L.control.scale({ position: "bottomleft", metric: true, imperial: true }).addTo(map);
drawSimpleActivities();
}
// Here I my initializer function
This drawSimpleActivities function is basically drawing polygons on different cities. Here My problem is I want to load my kml first then load this polygons so that my polygons gets on top of kml to work perfectly. I have tried async await and promises But I did not worked for me.I cannot use settimeout as time here is dependent on server.

Leaflet: I want to have a dropdown filter selection box using feature properties as options

I am relatively new with leaftlet and Javascript, but I am making my little advances with a lot of research and patience.
But now, I have this doubt, I had a geojson with state information and a status information. So I need to put one Icon for each of status information and this I have already done, but I also need to have a dropfown filter selection box, with the state information as option, so If a select one State, I can only see the registers of this selection and of course I need to preserve the custom icons for every status.
How can I achieve it using leaflet? Is that possible? I have already achieved the combo selection box with custom options, but I had failed when tried to use this selection as filter in my data.
Here is my code:
var map = L.map('map').setView([-23.589262,-46.619145], 10);
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'Mapas © OpenCycleMap, Dados do Mapa © contribuidores do OpenStreetMap'
}).addTo(map);
function nomeando (feature, layer){
layer.bindPopup(feature.properties.NAME)
}
L.geoJson (PTS_TESTE,{
onEachFeature: nomeando
,
pointToLayer: function(feature, latlng) {
var smallIcon = new L.Icon({
iconSize: [27, 27],
iconAnchor: [13, 27],
popupAnchor: [1, -24],
iconUrl: 'images/torre.jpg'
});
var smallIcon2 = new L.Icon({
iconSize: [27, 27],
iconAnchor: [13, 27],
popupAnchor: [1, -24],
iconUrl: 'images/telefone.jpg'
});
if (feature.properties.STATUS == 'TORRE') {
return L.marker(latlng, {icon: smallIcon});
}
else {return L.marker(latlng, {icon: smallIcon2});}
}}).addTo(map)
var legend = L.control({position: 'topright'});
legend.onAdd = function (map) {
var div = L.DomUtil.create('div', 'info legend');
div.innerHTML = '<select><option>RJ</option><option>SP</option><option>MG</option></select>';
div.firstChild.onmousedown = div.firstChild.ondblclick = L.DomEvent.stopPropagation;
return div;
};
legend.addTo(map);
// This part here, I have tried to change change function to erase my layer first.
$('select').change(function(){
var value = $(this).val();
if (value == "RJ") {
map.removeLayer(PTS_TESTE);}
});

Remove custom geojson markers (loaded with Leaflet) after zoom

I'm adding some points to a map using the code below and they look great. I'm also adding some json polygons without issue.
When a certain zoom level is reached I would like the points and polygons to turn off. Using the map.removeLayer(name of polygon) turns off the polygon perfectly and then zoom back out I use map.addLayer(name of polygon) and they come back (using 'zoomend' and if else statement).
The point features do not react to the removeLayer function like the polygons do. I've also tried to harvestPoints.setOpacity(0) which does not work either. What code should I use to turn these geojson markers "on" and "off" like the polygon features?
function onEachPoint(feature, layer) {
layer.bindPopup(feature.properties.MGNT_AREA.toString());
layer.on('click', function (e) { layer.openPopup(); });
layer.bindLabel(feature.properties.MGNT_AREA.toString(), {
noHide: true,
className: "my-label",
offset: [-2, -25]
}).addTo(map);
};
var areaIcon = {
icon: L.icon({
iconUrl: 'labels/MonitoringIcon.png',
iconAnchor: [20, 24]
})
};
var harvestPoints = new L.GeoJSON.AJAX('labels/dfo_areas_point.json', {
onEachFeature: onEachPoint,
pointToLayer: function (feature, latlng) {
return L.marker(latlng, areaIcon);
}
});
Not sure exactly what is the root cause for your issue, as we are missing how exactly you reference yours points (markers) when you try to remove them from the map.
Normally, there should be no difference between polygons and points (markers) to achieve what you described (removing the layers from the map at certain zoom level, and add them back at other zooms).
Note that setOpacity is a method for L.Markers, whereas you apply it to harvestPoints which is your geoJson layer group.
What may happen is that you add individual points (markers) to your map (last instruction in your onEachPoint function), but try to remove the layer group harvestPoints from map. Because it seems to be never added to the map, nothing happens.
If you want to turn on/off ALL the points in your harvestPoints layer group at the same time, then you would simply add / remove that layer group to / from the map, instead of adding individual markers:
var harvestPoints = L.geoJson.ajax('labels/dfo_areas_point.json', {
onEachFeature: onEachPoint,
pointToLayer: function (feature, latlng) {
// make sure `areaIcon` is an OPTIONS objects
return L.marker(latlng, areaIcon);
}
}).addTo(map); // Adding the entire geoJson layer to the map.
map.on("zoomend", function () {
var newMapZoom = map.getZoom();
if (newMapZoom >= 13) {
map.addLayer(harvestPoints);
} else {
// Removing entire geoJson layer that contains the points.
map.removeLayer(harvestPoints);
}
});
Side note: popups open on click by default, you should not need to add an on click listener for that?
Demo: http://jsfiddle.net/ve2huzxw/62/

Binding drawn shapes/markers with specific toggling layer : Leaflet

I am working with the application Beta_Here which uses leaflet plugins, all libraries are local except for few(css related)
Usage of application live
First View:This application get input from user and set the distance
calculation formula accordingly....
Second View : After entering input e.g 9, second view will be loaded
where we can draw shapes....
Introduction
I have setup the script which will load two imageoverlays(layers) and
we can toggle them from top right and we can draw or measure from
bottom left....
Problem
When we draw shapes or put markers on an image, controls work nearly
perfect but when we toggle the layers, there starts the problem....
all shapes go to the background or (it seems they disappeared)
Main Question
How can we bind the drawings and marker to the specific
layer(imageoverlay) if there is a way as we can see the drawing are
not bind with the images but the map container..... (Pardon me if you
feel i am doing something stupid because i have limited knowledge
about layers so i came up with my question here....
If someone has idea about how to solve this problem, please do help or
any kind of reference will be appreciated... Thanks for your time
Working Script
var map = L.map('map', {
minZoom: 1,
maxZoom: 4,
center: [0, 0],
zoom: 0,
crs: L.CRS.Simple
});
// dimensions of the image
var w = 3200,
h = 1900,
mainurl = 'assets/img/isbimg.jpg';
childurl = 'assets/img/fjmap.png';
// calculate the edges of the image, in coordinate space
var southWest = map.unproject([0, h], map.getMaxZoom() - 1);
var northEast = map.unproject([w, 0], map.getMaxZoom() - 1);
var bounds = new L.LatLngBounds(southWest, northEast);
var featureGroup = L.featureGroup().addTo(map);
var drawControl = new L.Control.Draw({
edit: {
featureGroup: featureGroup
},
draw: {
polygon: true,
polyline: true,
rectangle: true,
circle: true,
marker: true
}
}).addTo(map);
map.on('draw:created', showPolygonArea);
map.on('draw:edited', showPolygonAreaEdited);
// add the image overlay,so that it covers the entire map
L.control.layers({
Main: L.imageOverlay(mainurl, bounds),
Child: L.imageOverlay(childurl, bounds)
}, null, { collapsed: false }).addTo(map);
L.control.nanomeasure({ nanometersPerPixel: 10000 }).addTo(map);
// tell leaflet that the map is exactly as big as the image
map.setMaxBounds(bounds);
L.tileLayer({
attribution: 'SmartMinds',
maxZoom: 18
}).addTo(map);
//polygon area customization
function showPolygonAreaEdited(e) {
e.layers.eachLayer(function (layer) {
showPolygonArea({ layer: layer });
});
}
function showPolygonArea(e) {
var userInputCustom = prompt("Please enter image name : choose between a to f");
featureGroup.addLayer(e.layer);
e.layer.bindPopup("<div style='width:200px;height:200px;background-image: url(assets/img/" + userInputCustom + ".png);background-size: 195px 195px;;background-repeat: no-repeat;'></div>");
e.layer.openPopup();
}
});
I would contain those FeatureGroup and ImageOverlay pairs into L.LayerGroup's. Then you can switch between those groups. Then you can keep track of the currently selected group, and add your features to the featurelayer of that group. I can explain it better with code through comments:
Basic map, nothing special:
var map = L.map('map', {
'center': [0, 0],
'zoom': 1,
'layers': [
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
'attribution': 'Map data © OpenStreetMap contributors'
})
]
});
// Bounds for the map and imageoverlays
var bounds = L.latLngBounds([[40.712216, -74.22655],[40.773941, -74.12544]]);
// Set bounds on the map
map.fitBounds(bounds);
The grouping part:
// New layergroup, note it's not added to the map yet
var layerGroup = new L.LayerGroup(),
imageOverlayUrl = 'https://placeholdit.imgix.net/~text?txtsize=33&txt=Overlay 1&w=294&h=238',
// New imageoverlay added to the layergroup
imageOverlay = new L.ImageOverlay(imageOverlayUrl, bounds).addTo(layerGroup),
// New featuregroup added to the layergroup
featureGroup = new L.FeatureGroup().addTo(layerGroup);
// Second layergroup not added to the map yet
var layerGroup2 = new L.LayerGroup(),
imageOverlayUrl2 = 'https://placeholdit.imgix.net/~text?txtsize=33&txt=Overlay 2&w=294&h=238',
// New imageoverlay added to the second layergroup
imageOverlay2 = new L.imageOverlay(imageOverlayUrl2, bounds).addTo(layerGroup2),
// New featuregroup added to the second layergroup
featureGroup2 = new L.FeatureGroup().addTo(layerGroup2);
Default drawcontrol and layercontrol with both layergroups added as baselayers:
var layerControl = new L.control.layers({
'Group 1': layerGroup,
'Group 2': layerGroup2
}).addTo(map);
var drawControl = new L.Control.Draw().addTo(map);
Here's where the magic happens ;) :
// Variable to hold the selected layergroup's featuregroup.
var currentFeatureGroup;
// Catch the layer change event
map.on('baselayerchange', function (layersControlEvent) {
// Loop over the layers contained in the current group
layersControlEvent.layer.eachLayer(function (layer) {
// If it's the imageoverlay make sure it's in the background
if (layer instanceof L.ImageOverlay) {
layer.bringToBack();
// If not then it's the featuregroup, reference with variable.
} else {
currentFeatureGroup = layer;
}
});
});
// Catch draw created event
map.on('draw:created', function (e) {
// Store created feature into the current featuregroup
currentFeatureGroup.addLayer(e.layer);
});
That's it. Pretty basic just meant as an example but it does what you want it to do. A real implementation would look different, with errorhandling because for instance when you draw and have no baselayer/overlay selected it fail etc. Here's a working example on Plunker to play with: http://plnkr.co/edit/6cGceX?p=preview

HIDE/SHOW Markers

I am developing a website that has a mapping and i am using leaflet. Now im on the part that i will hide /show markers that i made.
below is my code finding the image that i want and use it as a marker
var Icon1 = L.icon({
iconUrl: 'legends/fire.GIF',
iconSize: [170, 120], // size of the icon
iconAnchor: [100, 120], // point of the icon which will correspond to marker's location
popupAnchor: [-7, -80] // point from which the popup should open relative to the iconAnchor
the other one below is my code when putting the mark on the map.
function mark()
{
if (select1.value === "Fire"){
var note = document.getElementById('note');
var datepick = document.getElementById('demo1');
var timepick = document.getElementById('timepick');
map.on('click', function(e){
var marker = new L.Marker(e.latlng,{icon: Icon1});
marker.bindPopup("</a><br><strong>FIRE</strong></br><strong>Date:</strong>"+datepick.value+"</br><strong>Time:</strong>"+timepick.value+"</br><strong>Address:</strong>"+note.value+"<strong><br><strong>Suspect Sketch</strong><br><a href=legends/suspect.jpg rel=lightbox><img src = legends/suspect.jpg height=100 width = 100/>").addTo(map);
marker.on('dragend');
});
This is my code in hiding the marker.
script type="text/javascript">
function closure(marker){
var checkbox = document.getElementById("chbx")
$(chbx).click(function(){
if(map.hasLayer(marker)){
window.alert("I want to hide the marker");
}
window.alert("I want to show the marker");
})
}
</script>
This is just what i wanted.
1.Add A marker on the map
2.Hide/Show the marker in the map
3.Make this happen during run time or when i try it.
I try everything but still nothing happens.
What is the right thing to do to call my hide/show function in checkbox?
Here's a way to do it:
Define a function which takes marker as its argument, and with jQuery create a function to toggle the visibility of the layer:
function closure(marker){
$('#yourcheckbox id').click(function(){
if(map.hasLayer(marker)){
map.removeLayer(marker)
}
else {map.addLayer(marker)}
})
}
Than, inside the click event of the map, add the closure function:
map.on('click', function(e){
marker = new L.Marker(e.latlng).addTo(map);
closure (marker)
})
With .addTo(map) should works.
However, you can use addLayer and removeLayer for add/remove markers:
var marker = new L.Marker(e.latlng,{icon: Icon1});
marker.bindPopup('<div>Hello World</div>');
//add the marker to the map
map.addLayer(marker);
//remove the marker from the map
map.removeLayer(marker);
I assume that you have created the map
In some cases for hiding markers we may use such method, may be.
marker._icon.style.display = 'none';
if (value._popup._isOpen)
{
marker.closePopup();
}
For show markers after hiding.
marker._icon.style.display = '';

Categories