leaflet.js refresh map onclick - javascript

I am using Leaflet to visualize map. Everything worked fine, until I added a checkbox to switch the data for the map.
I wrote it like this for the view:
<input type="checkbox" name="switch" class="switch-checkbox"onclick="change();" checked>
For the function in js :
function change()
{
var map = L.map('map').setView([37.8, -96], 4);
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
if (document.querySelector('.onoffswitch-checkbox').checked) {
data = statesData;
L.geoJson(statesData).addTo(map);
} else {
L.geoJson(statesDataTwo).addTo(map);
}
Then I got an error that the map is already initialized. I tried to add map.remove(); before adding the new map. Like suggested here. But map is undefined. What is the way to do that? Thanks

Why are you adding new map? You probably have it already in global variable map, which is initialized on load. Work with this and change only layers on change/click. Something like this:
var map = L.map('map').setView([37.8, -96], 4);
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 18
}).addTo(map);
var geojsonLayers = {
'states': L.geoJson(statesData),
'statesTwo': L.geoJson(statesDataTwo)
};
function change()
{
if (document.querySelector('.onoffswitch-checkbox').checked) {
map.addLayer(geojsonLayers.states);
if (map.hasLayer(geojsonLayers.statesTwo)) {
map.removeLayer(geojsonLayers.statesTwo);
}
} else {
map.addLayer(geojsonLayers.statesTwo);
if (map.hasLayer(geojsonLayers.states)) {
map.removeLayer(geojsonLayers.states);
}
}
}

Related

Display Shapefile with leaflet and layer control

Hello
I try to implement a leaflet pluging, for display a local hosted shapefile. The display of the shapefile work, but i want to add a layer control (for togle shapefile layer).
the plugin link : https://github.com/calvinmetcalf/shapefile-js
the demo link :http://leaflet.calvinmetcalf.com/#3/32.69/10.55
I want to implement the layer control on demo page
<script>
var m = L.map('map').setView([0, 0 ], 10);
var watercolor =
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: 'Map tiles by <a href="http://stamen.com">Stamen
Design</a>, <a href="http://creativecommons.org/licenses/by/3.0">CC BY
3.0</a> — Map data © OpenStreetMap contributors, CC-BY-SA'
}).addTo(m);
var shpfile = new L.Shapefile('Fr_adm.zip', {
onEachFeature: function(feature, layer) {
if (feature.properties) {
layer.bindPopup(Object.keys(feature.properties).map(function(k) {
return k + ": " + feature.properties[k];
}).join("<br />"), {
maxHeight: 200
});
}
}
});
shpfile.addTo(m);
shpfile.once("data:loaded", function() {
console.log("finished loaded shapefile");
});
// initialize stylable leaflet control widget
var control = L.control.UniForm(null, overlayMaps, {
collapsed: false,
position: 'topright'
}
);
// add control widget to map and html dom.
control.addTo(m);
</script>
The shapefile Fr_adm.zip is displayed, but no layer control.
Thank for your help.
Your problem is that overlayMaps is not defined. Open your console and you should see an error stating this.
Looking at the documentation for L.control.UniForm maps (an extension of leaflet), we can see:
/ **
* standard leaflet code.
** /
// initialize stylable leaflet control widget
var control = L.control.UniForm(null, overlayMaps, {
collapsed: false,
position: 'topright'
}
);
What is overlayMaps in this? To answer we need to take a look at the documentation for standard leaflet code. overlayMaps is a list of key, object pairs:
... we’ll create two objects. One will contain our base layers and
one will contain our overlays. These are just simple objects with
key/value pairs. The key sets the text for the layer in the control
(e.g. “Streets”), while the corresponding value is a reference to the
layer (e.g. streets).
var baseMaps = {
"Grayscale": grayscale,
"Streets": streets
};
var overlayMaps = {
"Cities": cities
};
Consequently, overlayMaps in your example should look like:
var overlayMaps = {"Name To Display":shpfile }
Once defined you should be able to create your layer control as normal.
i see a mistake in the code, no overlayer value. So i try with this :
<script type="text/javascript" charset="UTF-8">
//----------------
var watercolor = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
});
var geo = L.geoJson({features:[]},{onEachFeature:function popUp(f,l){
var out = [];
if (f.properties){
for(var key in f.properties){
out.push(key+": "+f.properties[key]);
}
l.bindPopup(out.join("<br />"));
}
}});
var m = L.map('map', {
center: [10, -1],
zoom: 6,
layers: [watercolor, geo ]
});
//}}).addTo(m);
var base = 'Fr_admin.zip';
shp(base).then(function(data){
geo.addData(data);
});
var baseMaps = {
"BaseLayer": watercolor
};
var overlays = {
"shapefile": geo
};
L.control.layers(baseMaps,overlays).addTo(m);
</script>
It 's work, i can chose to display the shapefile or not.
But dont return all segmentation like here :http://leaflet.calvinmetcalf.com/#3/32.69/10.55
thank you

Preserving Google map zoom to kml layer on checkbox click

I'm attempting to add multiple kml layers to a map that can be turned on and off with check boxes. I got that part working (yay!). When I click on a layer to turn it on, it zooms in (this is fine), but when I unclick to turn the layer off, it zooms back out to my map extent. How do I get it to preserve the zoom of the last loaded layer? Code below.
<script>
var map;
var watershedLayer = new google.maps.KmlLayer ({
url: 'http://mvihes.bc.ca/mapping/watersheds.kmz'
});
var ere1949Layer = new google.maps.KmlLayer ({
url: 'http://mvihes.bc.ca/mapping/ere1949.kmz'
});
function initialize() {
var parksville= new google.maps.LatLng(49.316786, -124.308768);
var mapOptions = {
zoom: 9,
center: parksville
};
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
check();
}
function check()
{
if(document.getElementById('watersheds').checked)
{watershedLayer.setMap(map);}
else
{watershedLayer.setMap(null);}
if(document.getElementById('ere1949').checked)
{ere1949Layer.setMap(map);}
else
{ere1949Layer.setMap(null);}
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
I tried using the preserveViewport function but it just stopped the layer from zooming in, which is not what I wanted. I'm new to javaScript so possibly I'm missing something obvious...any help would be appreciated!
jsfiddle
Set the map-property of a selected layer only when it's not set yet:
function check()
{
if(document.getElementById('watersheds').checked)
{if(!watershedLayer.getMap())watershedLayer.setMap(map);}
else
{watershedLayer.setMap(null);}
if(document.getElementById('ere1949').checked)
{if(!ere1949Layer.getMap())ere1949Layer.setMap(map);}
else
{ere1949Layer.setMap(null);}
}
http://jsfiddle.net/jhagmq7L/16/
You can also attach max and min zoom levels to the map, something to consider the over all map zoom when loading kml layers.
// sets the min and max zoom levels of the map
var opt = { minZoom: 6, maxZoom: 18 };
map.setOptions(opt);

How can I style Mapbox markers being pulled in directly from Mapbox?

I am new to Mapbox, so please bear with me.
I have uploaded my geoJson to my Mapbox map and am now editing it via javascript, creating the map by calling the following function.
$scope.initMap = function() {
var map = L.mapbox.map('map', 'example.hk78fg64');
};
The map works fine, but I want to style the default markers. How can I style these markers being pulled in from Mapbox directly? All examples for styling them have the markers being created on the spot inside the geoJson function (view the expression below)
L.geoJson(geoJson, {
pointToLayer: L.mapbox.marker.style,
});
See the L.mapbox.map documentation:
$scope.initMap = function() {
var map = L.mapbox.map('map', 'example.hk78fg64', { featureLayer: {
pointToLayer: L.mapbox.marker.style }
});
};

How to auto-update a marker on a leaflet map, with meteor

For a school project we are having this idea of making a geospatial tag-game. You log in on our app, your location is shown on the map, and whenever you get close to another player, you tag that person. (Like children's tag but with meteor)
The issue we are having, we seem not able to auto-update our marker on the leaflet map. There's an marker showing it's just not updating.
We tried using Player.update in a time but it doesn't work.
Any suggestions?
The code
if (Meteor.isClient) {
var userLatitude;
var userLongitude;
var map;
Template.map.rendered = function () {
// Setup map
map = new L.map('map', {
dragging: false,
zoomControl: false,
scrollWheelZoom: false,
doubleClickZoom: false,
boxZoom: false,
touchZoom: false
});
map.setView([52.35873, 4.908228], 17);
//map.setView([51.9074877, 4.4550772], 17);
L.tileLayer('http://{s}.tile.cloudmade.com/9950b9eba41d491090533c541f170f3e/997#2x/256/{z}/{x}/{y}.png', {
maxZoom: 17
}).addTo(map);
// If user has location then place marker on map
if (userLatitude && userLongitude) {
var marker = L.marker([userLatitude, userLongitude]).addTo(map);
}
var playersList = players.find().fetch();
playersList.forEach(function(players) {
// Change position of all markers
var marker = L.marker([players.latitude, players.longitude], options={"id" : 666}).addTo(map);
});
};
// If the collection of players changes (location or amount of players)
Meteor.autorun(function() {
var playersList = players.find().fetch();
playersList.forEach(function(players) {
// Change position of all markers
var marker = L.marker([players.latitude, players.longitude]).addTo(map);
});
});
}
if (Meteor.isServer) {
Meteor.startup(function () {
// code to run on server at startup
});
}
/*
Template.hello.events({
'click input' : function () {
// template data, if any, is available in 'this'
if (typeof console !== 'undefined')
console.log("You pressed the button");
}
});
*/
/*
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
userLatitude = 52.35873;
userLongitude = 4.908228;
players.insert({
name: "Martijn",
latitude: userLatitude,
longitude: userLongitude
});
});
}
*/
You need to clear the existing markers, otherwise they remain on the map. The easiest / most efficient way to do this is to attach the markers to a LayerGroup when you're creating them. Then, when you want to update, clear all the markers, and then add them again.
Add layer group declaration at the top, so you have
var map, markers;
After initialising the map,
markers = new L.LayerGroup().addTo(map);
Change this line:
var marker = L.marker([userLatitude, userLongitude]).addTo(map);
to:
var marker = L.marker([userLatitude, userLongitude]).addTo(markers);
in your autorun, before the forEach,
markers.clearLayers();
then in your foreach,
var marker = L.marker([players.latitude, players.longitude]).addTo(markers);

Leaflet: Add a link to the markers

Pretty simple question: How can I make the map markers in Leaflet clickable and route the user to an other page? Every marker has its own page.
I've tried the following without success; somehow all the markers point to the same page, which is the last assigned URI.
var markers = [
{ coords: [51.505, -0.09], uri: '/some-page' },
...
];
for(x in markers)
{
L.marker(markers[x].coords).on('click', function() {
window.location = markers[x].uri;
}).addTo(map);
}
This issue is really driving me nuts.
Okay, I finally came to a solution; when a marker is added to the map it gets assigned an ID called "_leaflet_id". This can be fetched through the target object, and also set to a custom value after it has been added to the map.
So the final solution is simply:
var x = markers.length;
while(x--)
{
L.marker(markers[x].coords).on('click', function(e) {
window.location = markers[e.target._leaflet_id].uri;
}).addTo(map)._leaflet_id = x;
}
(I replaced the for-in loop with a reversed while loop)
You could also use a popup which can display HTML
marker.bindPopup(htmlString);
i found a similar code which may help you. here is jsfiddle link http://jsfiddle.net/farhatabbas/qeJ78/
$(document).ready(function () {
init_map();
add_marker();
});
var map;
function init_map() {
map = L.map('map').setView([37.8, -96], 4);
L.tileLayer('http://{s}.tile.cloudmade.com/{key}/22677/256/{z}/{x}/{y}.png', {
attribution: 'Map data © 2011 OpenStreetMap contributors, Imagery © 2012 CloudMade',
key: 'BC9A493B41014CAABB98F0471D759707'
}).addTo(map);
}
function add_marker() {
var points = [
["P1", 43.059908, -89.442229, "http://www.url_address_01.com/"],
["P2", 43.058618, -89.442032, "http://www.url_address_02.com/"],
["P3", 43.058618, -86.441726, "http://www.url_address_03.com/"]
];
var marker = [];
var i;
for (i = 0; i < points.length; i++) {
marker[i] = new L.Marker([points[i][1], points[i][2]], {
win_url: points[i][3]
});
marker[i].addTo(map);
marker[i].on('click', onClick);
};
}
function onClick(e) {
console.log(this.options.win_url);
window.open(this.options.win_url);
}

Categories