I'm using Leaflet, leaflet.geo.csv and leaflet-sidebar to build a map. Map works and shows me markers but only 25 of 200. Not the 25 first but randomly among the 200. And it is always the same ones that appear.
I can't show you my csv (sensitive data) but I have checked it many times, clean it and I think it is fine. My console is empty.
This is a sample of my code :
var map = L.map('map');
var affaires = L.geoCsv(null, {
onEachFeature: function (feature, layer) {
var popup = '';
for (var key in feature.properties) {
var title = affaires.getPropertyTitle(key);
popup += '<p class="title">'+title+'</b><p class="info">'+feature.properties[key]+'</p>';
}
layer.on('click', function () {
sidebar.hide();
sidebar.show();
sidebar.setContent(popup);
});
},
pointToLayer: function (feature, latlng) {
return L.marker(latlng, {
icon:L.icon({
iconUrl: 'marker.png',
shadowUrl: 'shadow.png',
iconSize: [25,38],
shadowSize: [41, 41],
shadowAnchor: [13, 21]
})
});
},
firstLineTitles: true,
fieldSeparator: ','
});
$.ajax ({
type:'GET',
dataType:'text',
url:'mydata.csv',
error: function() {
alert('Pas de données');
},
success: function(csv) {
var markers = new L.Marker();
affaires.addData(csv);
map.addLayer(affaires);
map.fitBounds(affaires.getBounds());
console.log(affaires);
}
});
L.tileLayer('http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap © CartoDB | © lamontagne.fr - Julien Jégo',
subdomains: 'abcd',
maxZoom: 19
}).addTo(map);
var sidebar = L.control.sidebar('sidebar', {
closeButton: true,
position: 'left'
});
map.addControl(sidebar); ...
A screenshot of my map :
Any suggestion ?
Thanks
Related
Im using GeoJSON with leaflet to insert markers onto a map, I then have a Ajax request periodically update the icons every 60 seconds with their latest state (they go red or green if the location is up or down)
However it's been noted that the page looked like it had a memory leak, on further investigations we can see that additional markers are added on each refresh, so with 100 markers on the map after an hour we have 6000 markers. Can anyone help me on making the existing markers update based on the new data or remove and re add them?
current code below
Thanks
<script type="text/javascript">
var map = L.map('map').setView([54.0,-3.4], 7);
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
maxZoom: 18,
id: 'mapbox/dark-v10',
accessToken: 'pk.*****'
}).addTo(map);
$(function() {
function update_maps() {
// Update the pins in the amaps
$.get('/monitoring/data/status_map_geo_data/gb/', function(geo_data) {
L.geoJSON(geo_data, {
pointToLayer: function (feature, latlng) {
var zindex = feature.properties.z_index && feature.properties.z_index !== "null";
return L.marker(latlng, {
zIndexOffset: zindex ? 1000 : 0,
icon: L.AwesomeMarkers.icon(
{
icon: feature.properties.icon,
markerColor: feature.properties.color,
prefix: 'fa',
iconColor: 'white',
}
)
}
);
},
onEachFeature: function (feature, layer) {
var layer_text = '<h3>'+feature.properties.popupContent+'</h3>'
layer.bindPopup(layer_text)
}
}).addTo(map);
});
}
$(document).ready(function() {
// load icons on start
update_maps()
});
// refresh page
setInterval(function() {
update_maps()
}, 60 * 1000);
});
</script>
This is a simple solution, L.geoJSON returns a group with the markers, this group can be cleared with .clearLayers().
So change your code to:
var geoJsonGroup = null;
function update_maps() {
// Update the pins in the amaps
$.get('/monitoring/data/status_map_geo_data/gb/', function(geo_data) {
if(geoJsonGroup){
geoJsonGroup.clearLayers();
}
geoJsonGroup = L.geoJSON(geo_data, {
pointToLayer: function (feature, latlng) {
var zindex = feature.properties.z_index && feature.properties.z_index !== "null";
return L.marker(latlng, {
zIndexOffset: zindex ? 1000 : 0,
icon: L.AwesomeMarkers.icon(
{
icon: feature.properties.icon,
markerColor: feature.properties.color,
prefix: 'fa',
iconColor: 'white',
}
)
}
);
},
onEachFeature: function (feature, layer) {
var layer_text = '<h3>'+feature.properties.popupContent+'</h3>'
layer.bindPopup(layer_text)
}
}).addTo(map);
});
}
Alternatives (From #gyhbs) "Many roads lead to Rome":
Call geoJsonGroup.removeFrom(map) instead of geoJsonGroup.clearLayers();
Put the L.geoJSON outside and then call addData instead of creating a new group everytime:
var geoJsonGroup = L.geoJSON(null, {
pointToLayer: function(feature, latlng) {
var zindex = feature.properties.z_index && feature.properties.z_index !== "null";
return L.marker(latlng, {
zIndexOffset: zindex ? 1000 : 0,
icon: L.AwesomeMarkers.icon({
icon: feature.properties.icon,
markerColor: feature.properties.color,
prefix: 'fa',
iconColor: 'white',
})
});
},
onEachFeature: function(feature, layer) {
var layer_text = '<h3>' + feature.properties.popupContent + '</h3>'
layer.bindPopup(layer_text)
}
}).addTo(map);
function update_maps() {
// Update the pins in the amaps
$.get('/monitoring/data/status_map_geo_data/gb/', function(geo_data) {
if (geoJsonGroup) {
geoJsonGroup.clearLayers();
}
geoJsonGroup.addData(geo_data)
});
}
I'm trying to use geolocation to get my current position, which inserts the lat and lon into the centre point of a map. I know that geolocation is asynchronous, so I have to get that value, then call another function for this to pass forward. I am not getting the object mymap created for some reason.
<script>
function foundLocation(pos) {
setMyLocation(pos.coords.latitude, pos.coords.longitude)
};
function noLocation() {
document.getElementById("warning").innerHTML = "Could not find your location";
};
function setMyLocation(myLat, myLon) {
L.marker([ myLat, myLon ], {icon: homeIcon}).bindPopup("You Are Here").addTo(coolPlaces);
var mymap = L.map('mapid', {
center: [ myLat, myLon ],
minZoom: 2,
maxZoom: 18,
zoom: 15,
layers: [mymarkers]
});
};
navigator.geolocation.getCurrentPosition(foundLocation, noLocation);
<snip other JS irrelevant stuff>
</script>
Is there a way I can get those two variables out of the function and create the mymap object? I'm not well versed in JS and its restrictions.
The above code results in no map generated. I have to take mymap outside the geolocation functions for this to happen. The issue is that I don't know how to send myLat and myLon outside to that declaration.
Kudos to #espascarello: All the map functionality inside the success function foundLocation(pos).
Update: The problem is above. Read it. Putting every map function inside foundLocation(pos) worked fine. There's no use for any map function if these two variables are not found.
myLat = 0
myLon = 0
mymap = ""
function foundLocation(pos) {
myLat = pos.coords.latitude;
myLon = pos.coords.longitude;
// setMyLocation(pos.coords.latitude, pos.coords.longitude)
var homeIcon = L.icon({
iconUrl: '/img/house_marker.png',
iconSize: [24, 24],
iconAnchor: [12, 24],
popupAnchor: [0, -24]
});
var mymarkers = L.layerGroup([
L.marker([ myLat, myLon ], {icon: homeIcon}).bindPopup("You Are Here"),
<%= #markers %>
]);
var mymap = L.map('mapid', {
center: [ myLat,myLon ],
minZoom: 2,
maxZoom: 18,
zoom: 15,
layers: [mymarkers]
});
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
attribution: 'Map data © OpenStreetMap Imagery © Mapbox',
id: 'mapbox.streets'
}).addTo(mymap);
L.control.layers(mymarkers).addTo(mymap);
};
function noLocation() {
document.getElementById("warning").innerHTML = "Could not find your location";
};
function setMyLocation(pushLat, pushLon) {
alert("inside setMyLocation");
myLat = pushLat;
myLon = pushLon;
// var mymap = L.map('mapid', {
// center: [ myLat, myLon ],
// minZoom: 2,
// maxZoom: 18,
// zoom: 15,
// layers: [mymarkers]
// });
};
navigator.geolocation.getCurrentPosition(foundLocation, noLocation);
I tried to apply pointTolayer in my Leaflet Map it but it still throws the classic icons. There is an error in the Code.
$.getJSON("https://gist.githubusercontent.com/vassilaros/3791204ca226d5b236b4cd3106ef23cf/raw/PicnicSites.geojson",function(data){
var baseline_person = L.icon({
iconUrl: 'baseline_person.png',
iconSize: [18,18]
});
// add GeoJSON layer to the map once the file is loaded
L.geoJson(data, {
pointTolayer: function(feture, latlng){
return L.marker(latlng,{icon: baseline_person});
}
}).addTo(map);
});
Your L.geoJson should be L.geoJSON and pointTolayer should be pointToLayer respectively.
And then define iconSize and iconAnchor as L.icon params
const customMarker = new L.icon({
iconUrl: "marker.png",
iconSize: [32, 32],
iconAnchor: [10, 41],
});
axios
.get(
"https://gist.githubusercontent.com/vassilaros/3791204ca226d5b236b4cd3106ef23cf/raw/PicnicSites.geojson"
)
.then(response => {
L.geoJSON(response.data, {
pointToLayer: (feature, latlng) => {
return L.marker(latlng, { icon: customMarker });
}
}).addTo(map);
});
Demo
I want to draw a map with few routes drawn on it.
I want to have a dropbox with numbers 1,..,n
when an item in the dropbox is chosen, the corresponding route is highlighted on the map.
I have started using "leaflet".
why doesn't my resetStyle() return the lines to their original style?
here is my code:
document.onload = loadMap();
function loadMap() {
var map = L.map('map').setView([37.8, -96], 4);
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
attribution: 'Map data © OpenStreetMap contributors,CC-BY-SA, Imagery © Mapbox',
maxZoom: 18,
id: 'mapbox.streets',
accessToken: 'pk.eyJ1IjoiZW==========yJ9.3HqHQ4BMRvSPaYe8ToA7YQ'
}).addTo(map);
var marker = L.marker([51.5, -0.09]).addTo(map);
var myLines = [{
"type": "LineString",
"properties": {
"id": "1"
}
"coordinates": [
[-100, 40],
[-105, 45],
[-110, 55]
]
}, {
"type": "LineString",
"properties": {
"id": "2"
}
"coordinates": [
[-105, 40],
[-110, 45],
[-115, 55]
]
}];
var myLayer = L.geoJson().addTo(map);
myLayer.addData(myLines);
geojson = L.geoJson(myLines, {
onEachFeature: onEachFeature
}).addTo(map);
}
function highlightFeature(e) {
var layer = e.target;
layer
layer.setStyle({
weight: 25,
color: '#ff3300',
dashArray: '',
fillOpacity: 0.7
});
if (!L.Browser.ie && !L.Browser.opera) {
layer.bringToFront();
}
}
function resetHighlight(e) {
geojson.resetStyle(e.target);
layer.setStyle({
weight: 5,
color: '#0000ff',
dashArray: '',
fillOpacity: 0.7
});
}
function onEachFeature(feature, layer) {
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
// click: zoomToFeature
});
}
$('select[name="dropdown"]').change(function() {
var item = $(this).val();
alert("call the do something function on option " + item);
//how to make the chosen line highlighted ??
});
The resetStyle method of L.GeoJSON reset the given layer's style back to the style defined when initializing the L.GeoJSON layer:
Resets the given vector layer's style to the original GeoJSON style, useful for resetting style after hover events.
http://leafletjs.com/reference.html#geojson-resetstyle
Code example:
var geojsonLayer = new L.GeoJSON(geojson, {
style: function () {
return {
color: 'red'
}
},
onEachFeature: function (feature, layer) {
layer.on('mouseover', function () {
this.setStyle({
color: 'green'
});
});
layer.on('mouseout', function () {
geojsonLayer.resetStyle(this);
});
}
}).addTo(map);
Working example on Plunker: http://plnkr.co/edit/iriGMBYiFRizeXizMF06?p=preview
Plunker Example:
Leaflet Draw plugin with OSM map
var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
osmAttrib = '© OpenStreetMap contributors',
osm = L.tileLayer(osmUrl, { maxZoom: 18, attribution: osmAttrib });
var map = new L.Map('leaflet', { layers: [osm], center: new L.LatLng(52.105289405897, 5.2629891004852425), zoom: 13 });
console.log('map ready');
var drawnItems = new L.FeatureGroup();
var coords = [new L.latLng(51.2, 4.5), new L.latLng(51.2, 4.6), new L.latLng(51.2, 4.9)];
var poly = new L.Polyline(coords, {
color: 'blue',
opacity: 1,
weight: 5
});
drawnItems.addLayer(poly);
map.addLayer(drawnItems);
var drawControl = new L.Control.Draw({
draw: {
position: 'right',
polygon: {
title: 'Polygon',
allowIntersection: false,
drawError: {
color: '#b00b00',
timeout: 1000
},
shapeOptions: {
color: '#bada55'
},
showArea: true
},
polyline: {
metric: false
},
circle: {
shapeOptions: {
color: '#662d91'
}
}
},
edit: {
featureGroup: drawnItems
}
});
map.addControl(drawControl);
map.on('draw:created', function (e) {
var type = e.layerType,
layer = e.layer;
if (type === 'marker') {
layer.bindPopup('A popup!');
}
drawnItems.addLayer(layer);
console.log('adding layer', layer, drawnItems);
});
I need to catch a created rectangle and ultimately make a file out of it's coordinates, but for now I'm trying to figure out how to catch the event and output the rectangles coordinates to the console.
Forgive me, still stepping into Javascript. Thanks
--Edit--
So I see how to log this event to console, but I don't clearly see how to access the lat/lng info from the event.
map.on('draw:rectangle-created', function (e) {
console.log(e.rectangle-created);
});
Just use the draw:created event and check if type is a rectangle:
map.on('draw:created', function (e) {
var type = e.layerType,
layer = e.layer;
if (type === 'rectangle') {
// It's a rectangle, do stuff
console.log(layer.getLatLngs());
}
drawnItems.addLayer(layer);
console.log('adding layer', layer, drawnItems);
});
You can access the rectangle's coordinates by calling the getLatLngs method. It returns an array of L.LatLng objects:
rectangle.getLatLngs().forEach(function (latlng) {
console.log(latlng.lat); //latitude
console.log(latlng.lng); //longitude
});
http://leafletjs.com/reference.html#latlng