How do I get nearby places in leaflet map in json format? - leaflet

var map = L.map('map').setView([27.7172, 85.3240], 13);
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 160,
attribution: '© OpenStreetMap'
}).addTo(map);
var circle = L.circle([27.7172, 85.3240], {
color: 'red',
fillColor: '#f03',
fillOpacity: 0.5,
radius: 500
}).addTo(map);
var popup = L.popup();
function onMapClick(e) {
popup
.setLatLng(e.latlng)
.setContent("You clicked the map at " + e.latlng.toString())
.openOn(map);
}
map.on('click', onMapClick);
var marker = L.marker([27.7172, 85.3240],
{ alt: 'Kathmandu' }).addTo(map) // "Kyiv" is the accessible name of this marker
.bindPopup('Kathmandu Nepal');

Related

Leaflet: How can I add a marker to map only on mouseover another marker?

I have a polygon and two markers. The last marker (var power) I want to start only on mouseover or onclick the first marker (var myIcon). How can I do that? Could you please take a look on this code?
var polygon = new L.Polygon(line, {
color: pastel,
weight: 0.1,
opacity: 0.1,
fillColor: pastel,
fillOpacity: 0.04,
interactive: true
});
polygon.addTo(map)
}
var myIcon = L.divIcon({
className: 'divIcon',
iconSize: new L.Point(35, 15),
iconAnchor:[18, 20],
zIndexOffset: 1000,
html: '<?=$desc1[$i]?>'
});
var marker = L.marker([x1, y1], {icon: myIcon})
.addTo(map)
marker.refPoly = polygon;
marker.on('mouseover', function(e) {
e.target.refPoly.setStyle({
fillOpacity: 0.48
});
});
marker.on('mouseout', function(e) {
e.target.refPoly.setStyle({
fillOpacity: 0.04
});
});
var power = <?php echo json_encode($watt); ?>;
var power = power.reverse();
var myPower = L.divIcon({
className: 'divPower',
iconSize: new L.Point(25, 12),
iconAnchor:[12, 5],
html: power[b]
});
L.marker(pointC, {icon: myPower}).addTo(map)
.bindTooltip(350-b*10 + '°');
You can remove a marker with marker.removeFrom(map) and add it to the map with marker.addTo(map):
var marker = L.marker([x1, y1], {icon: myIcon})
.addTo(map)
marker.refPoly = polygon;
var power = <?php echo json_encode($watt); ?>;
var power = power.reverse();
var myPower = L.divIcon({
className: 'divPower',
iconSize: new L.Point(25, 12),
iconAnchor:[12, 5],
html: power[b]
});
// I removed .addTo(map). Then the marker is not displayed from beginning
var powerMarker = L.marker(pointC, {icon: myPower})
.bindTooltip(350-b*10 + '°');
marker.on('mouseover', function(e) {
e.target.refPoly.setStyle({
fillOpacity: 0.48
});
powerMarker.addTo(map);
});
marker.on('mouseout', function(e) {
e.target.refPoly.setStyle({
fillOpacity: 0.04
});
powerMarker.removeFrom(map);
});
marker.on('click', function(e) {
powerMarker.addTo(map);
});

Leaflet l.layergroup not displaying second layer (features)

I'm trying to make a map of the Rockies that has multiple layers with different geological features. The first layer, with hot springs, works perfectly well--each spring has a corresponding marker and pop-up that displays the spring's name and state.
The problem comes when I try to add a second layer with a different geological feature (canyons and gorges). I have used the code from the "hot springs" layer, but it isn't getting added to the map, even when I select it from the layer control.
I don't think the problem is the geoJSON file. (The points will display properly on the map when I look at the file where it is stored on GitHub, which is the canyonsURL.)
Here is the code for the part that isn't working:
var canyons = new L.LayerGroup();
d3.json(canyonsURL, function(data) {
createFeatures2(data.features);
});
function createFeatures2(canyonsURL) {
function onEachFeature(feature, layer) {
layer.bindPopup(feature.properties.Canyon +
"<hr><p>" + feature.properties.State);
}
function style(feature, layer) {
return {
opacity: 0.5,
radius: 5,
weight: 1,
color: "black",
fillColor: "yellow",
fillOpacity: 0.5
}
}
var canyon = d3.json(canyonsURL, {
pointToLayer: function(_geometry, coordinates) {
return L.circleMarker(coordinates);
},
onEachFeature: onEachFeature,
style: style
}).addTo(canyons);
createMap(canyons)
}
I have tried both with and without the final createMap(canyons). I have tried using identical names for functions (instead of adding the 2) to the end.
I'm sure it's right in front of my eyes and I just can't see it. The same code (obviously pointing to a different URL and with slightly different styling) is working fine for the hot springs. What did I mess up on?
EDIT: This is going to get long; sorry. Here is the createMap function:
function createMap() {
var satellite = L.tileLayer("https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}", {
attribution: "Map data © Openelevationmap contributors, CC-BY-SA, Imagery © Mapbox",
maxZoom: 18,
id: "mapbox.satellite",
accessToken: API_KEY
});
var pirates = L.tileLayer("https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}", {
attribution: "Map data © Openelevationmap contributors, CC-BY-SA, Imagery © Mapbox",
maxZoom: 18,
id: "mapbox.pirates",
accessToken: API_KEY
});
var terrain = L.tileLayer("https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}", {
attribution: "Map data © Openelevationmap contributors, CC-BY-SA, Imagery © Mapbox",
maxZoom: 18,
id: "mapbox.mapbox-terrain-v2",
accessToken: API_KEY
});
var terrain_rgb = L.tileLayer("https://api.mapbox.com/v4/mapbox.terrain-rgb/{z}/{x}/{y}.pngraw?access_token={accessToken}", {
attribution: "Map data © Openelevationmap contributors, CC-BY-SA, Imagery © Mapbox",
maxZoom: 18,
id: "mapbox.mapbox-terrain-rgb",
accessToken: API_KEY
});
// Define a baseMaps object to hold our base layers
var baseMaps = {
// "Elevation Map": elevationmap,
"Satellite": satellite,
"Terrain": terrain,
"Treasure": pirates,
"Shadow": terrain_rgb
};
// Create overlay object to hold our overlay layer
var overlayMaps = {
"Hot Springs": springs,
"Canyons": canyons
};
// Create our map, giving it the satellite and hotSprings layers to display on load
var myMap = L.map("map", {
center: [
44.2643, -109.7879
],
zoom: 5,
layers: [satellite, springs]
});
// Create a layer control
// Pass in our baseMaps and overlayMaps
// Add the layer control to the map
L.control.layers(baseMaps, overlayMaps, {
collapsed: true,
position: 'bottomright'
}).addTo(myMap);
}
Here is the code that I used to (successfully) add the hot springs:
// Create layers for layergroup
var springs = new L.LayerGroup();
d3.json(springsURL, function(data) {
// Once we get a response, send the data.features object to the createFeatures function
createFeatures(data.features);
});
function createFeatures(springsURL) {
// Define a function we want to run once for each feature in the features array
// Give each feature a popup with name and state of spring
function onEachFeature(feature, layer) {
layer.bindPopup(feature.properties.SpringName +
"<hr><p>" + feature.properties.State);
}
function style(feature, layer) {
return {
opacity: 0.5,
radius: 5,
weight: 1,
color: "black",
fillColor: "red",
fillOpacity: 0.5
}
}
var hotSprings = L.geoJSON(springsURL, {
pointToLayer: function(_geometry, coordinates) {
return L.circleMarker(coordinates);
},
onEachFeature: onEachFeature,
style: style
}).addTo(springs);
// Sending our hotSprings layer to the createMap function
createMap(springs);
}
your function createMap(springs); makes no sense. If you add a parameter to the function then you have to read it out. function createMap() { ... } it should be function createMap(layer) { ... }. But that is not necessary for you.
your script should look like this:
var myMap; //the var should init global so you can call it from everywhere
var springs = L.featureGroup(); //Same as L.layerGroup() but with more options.
var canyons = L.featureGroup();
function createMap(){
//...
myMap = L.map("map", { //<-- without "var"
center: [
44.2643, -109.7879
],
zoom: 5,
layers: [satellite, springs, canyons] //<--- Add canyons
});
//...
}
createMap();
var style1 = function style(feature) {
return {
opacity: 0.5,
radius: 5,
weight: 1,
color: "black",
fillColor: "red",
fillOpacity: 0.5
}
}
var style2 = function style(feature) {
return {
opacity: 0.5,
radius: 5,
weight: 1,
color: "yellow",
fillColor: "red",
fillOpacity: 0.5
}
}
function createFeatures(springsURL,stlyecallback, layer) {
// Define a function we want to run once for each feature in the features array
// Give each feature a popup with name and state of spring
function onEachFeature(feature, layer) {
layer.bindPopup(feature.properties.SpringName +
"<hr><p>" + feature.properties.State);
}
var hotSprings = L.geoJSON(springsURL, {
pointToLayer: function(_geometry, coordinates) {
return L.circleMarker(coordinates);
},
onEachFeature: onEachFeature,
style: stlyecallback
}).addTo(layer);
}
d3.json(springsURL, function(data) {
createFeatures(data.features, style1, springs);
});
d3.json(springsURL, function(data) {
createFeatures(data.features, style2, canyons);
});
I hope I have no typo...

How can I center leaflet map in the browser?

I am creating a game map using leaflet and so far everything works fine, except centering the map. I would like the map be vertical centered in the browser.
Is there a way to fix this?
I tried changing L.latLng under //Declare Map Object, but this does not do the trick.
Here's how I have it set up currently:
// Variables
var mapSW = [608, 8026],
mapNE = [7574, 146];
// Declare Map Object
var map = L.map('map', {
center: L.latLng(0, 0),
zoom: 4
});
// Reference the tiles
L.tileLayer('maps/velen/{z}/{x}/{y}.png', {
minZoom: 2,
maxZoom: 5,
continuousWorld: false,
noWrap: true,
crs: L.CRS.Simple,
}).addTo(map);
map.setMaxBounds(new L.LatLngBounds(
map.unproject(mapSW, map.getMaxZoom()),
map.unproject(mapNE, map.getMaxZoom())
));
// Icons
var locat = L.icon({
iconUrl: 'images/locat_marker.png',
iconSize: [24, 30],
iconAnchor: [5, 30],
popupAnchor: [5, 44],
});
var quest_marker_lvl1 = L.icon({
iconUrl: 'images/quest_marker_lvl_0.png',
iconSize: [67, 39],
iconAnchor: [5, 39],
popupAnchor: [0, -39],
});
// Markers and Popups
// LatLng
var refmarker = L.marker([0, 0], {
draggable: true,
}).addTo(map);
refmarker.bindPopup('');
refmarker.on('dragend', function(e) {
refmarker.getPopup().setContent('Clicked ' +
refmarker.getLatLng().toString() + '<br />'
+ 'Pixels ' +map.project(refmarker.getLatLng(),
map.getMaxZoom().toString()))
.openOn(map);
});
// Pixels
// Locations
var popupContent = "Hanged Man's Tree";
var popupOptions =
{
autoClose: false,
closeOnClick: false,
closeButton : false,
'className' : 'locat_marker' // classname for another popup
}
var locat_hanged_mans_tree = L.marker(map.unproject([2172, 1924],
map.getMaxZoom()), {icon: locat})
.bindPopup(popupContent, popupOptions).addTo(map).openPopup();
// Quests lvl 1
var quest_fake_pass = L.marker(map.unproject([2033, 1693],
map.getMaxZoom()), {icon: quest_marker_lvl1})
.bindPopup("Fake Pass");
var quest_thou_shall_not_pass = L.marker(map.unproject([2089, 1717],
map.getMaxZoom()), {icon: quest_marker_lvl1})
.bindPopup("Thou Shall Not Pass");
// Layer Groups
var lg_quests = L.layerGroup([quest_fake_pass,
quest_thou_shall_not_pass]).addTo(map);
var lg_locat = L.layerGroup([locat_hanged_mans_tree]).addTo(map);
var baseLayers = {
};
var overlays = {
"Quests" : lg_quests,
"Locations" : lg_locat
};
// Add layer control
L.control.layers(baseLayers, overlays).addTo(map);

Leaflet.js: click a polygon to remove the the layer and change it to new one

I've been making a Leaflet map for a while and trying to figure out the way to make it so if I click one of the polygon in GeoJSON layer, it will remove the current layer and replace it with another layer.
Likewise, if I click it again, it will remove the new layer and replace it with previous layer.
I've been trying to tinker with different stuff but nothing works. This is one of my recent attempt.
<script type="text/javascript" src="provinces.js"></script>
<script>
var map = L.map('map').setView([-2.5, 119], 5);
L.tileLayer('http://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap © CartoDB',
subdomains: 'abcd',
maxZoom: 19
}).addTo(map);
// get color depending on population density value
function getColor(d) {
return d > 5000 ? '#800026' :
d > 2500 ? '#BD0026' :
d > 1000 ? '#E31A1C' :
d > 500 ? '#FC4E2A' :
'#FFEDA0';
}
function style(feature) {
return {
weight: 2,
opacity: 1,
color: 'white',
dashArray: '',
fillOpacity: 0.7,
fillColor: getColor(feature.properties.kode)
};
}
function highlightFeature(e) {
var layer = e.target;
layer.setStyle({
weight: 5,
color: '#ccc',
dashArray: '',
fillOpacity: 0.7
});
if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
layer.bringToFront();
}
info.update(layer.feature.properties);
}
var geojson;
function resetHighlight(e) {
geojson.resetStyle(e.target);
info.update();
}
function zoomToFeature(e) {
map.fitBounds(e.target.getBounds());
}
function addNewBoundary(e) { // this function doesn't do anything
var newLayerBoundary = new L.geoJson();
newLayerBoundary.addTo(map);
$.ajax({
dataType: "json",
url: "province-details.geojson",
success: function(data) {
$(data.features).each(function(key, data) {
newLayerBoundary.addData(data);
});
}
}).error(function() {});
}
function onEachFeature(feature, layer) {
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
click: clearLayers // with this it just clears the layers before being clicked
});
}
geojson = L.geoJson(provinces, {
style: style,
onEachFeature: onEachFeature
}).addTo(map);
</script>
var layers = [firstLayer,secondLayer]
function switchLayers(){
if(map.haslayer(layers[firstLayer])){
map.addLayer(layers[secondLayer]);
map.removeLayer(layers[firstLayer]);
}else{
if(map.haslayer(layers[secondLayer])){
map.addLayer(layers[firstLayer]);
map.removeLayer(layers[secondLayer]);
}
}

circleMarker click not getting called - OverlappingMarkerSpiderfier-Leaflet

I see that the click event doesn't get called for circleMarker, but does get called for normal Marker. Any help? https://github.com/jawj/OverlappingMarkerSpiderfier-Leaflet/issues/19
http://jsfiddle.net/abarik/crk3jrhp/2/
html
<div id="map"></div>
css
#map {
height: 440px;
}
javascript
map = L.map('map', {
center: [7.2, 40.9],
zoom: 2
});
L.tileLayer('http://{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.png', {
attribution: "Map: Tiles Courtesy of MapQuest (OpenStreetMap, CC-BY-SA)",
subdomains: ["otile1", "otile2", "otile3", "otile4"],
maxZoom: 12,
minZoom: 2
}).addTo(map);
var oms = new OverlappingMarkerSpiderfier(map);
var popup = new L.Popup();
oms.addListener('click', function(marker) {
popup.setContent(marker.__name);
popup.setLatLng(marker.getLatLng());
map.openPopup(popup);
});
var marker1 = new L.Marker([1, 1]);
marker1.__name = 'marker1'
map.addLayer(marker1);
oms.addMarker(marker1);
var marker2 = new L.Marker([1, 1]);
marker2.__name = 'marker2'
map.addLayer(marker2);
oms.addMarker(marker2);
var marker1 = new L.circleMarker([20, 20]);
marker1.__name = 'cirmarker1'
map.addLayer(marker1);
oms.addMarker(marker1);
var marker2 = new L.circleMarker([20, 20]);
marker2.__name = 'cirmarker2'
map.addLayer(marker2);
oms.addMarker(marker2);