I'm trying to select only one layer using a select.
This is my first time with leaflet and I use this great guide: https://maptimeboston.github.io/leaflet-intro/
Now I have on my map the part of "markerclusters" and the last one "heatmap" and I want to choose only one layer or the other or both.. I've been looking for examples but I don't know how to apply them.
(The select right now is ornamental as you can see.)
And here's the image of my map:
Image
here is my code, thanks in advance!
<html>
<head>
<title>MAPA PRUEBA</title>
<link rel="stylesheet" href="leaflet.css"/>
<link rel="stylesheet" href="MarkerCluster.css"/>
<script src="leaflet.js"></script>
<script src="leaflet.markercluster.js"></script>
<script src="leaflet.heat.js"></script>
<script src="jquery-2.1.1.min.js"></script>
<style>
#map{ height: 100% }
</style>
</head>
<body>
<div id="panel" style = "top-left:10px; background-color:#D3D3D3;">
<label>Tipo de mapa</label>
<select id="estilo" onchange="Bordeaux()">
<option value="points" >PUNTOS</option>
<option value="heat">MAPA DE CALOR</option>
</select>
<div id="map"></div>
<script>
// initialize the map
var map = L.map('map').setView([40.46, -3.74], 4);
// load a tile layer
L.tileLayer('http://192.168.0.103/osm/{z}/{x}/{y}.png',
{
attribution: 'Tiles by MAPC, Data by MassGIS',
maxZoom: 17,
minZoom: 1
}).addTo(map);
// load GeoJSON from an external file
$.getJSON("rodents.geojson",function(data){
var ratIcon = L.icon({
iconUrl: 'images/marker-icon.png'});
var rodents = L.geoJson(data,{
pointToLayer: function(feature,latlng){
var marker = L.marker(latlng,{icon: ratIcon});
marker.bindPopup(feature.properties.Location);
return marker;}
});
var clusters = L.markerClusterGroup();
clusters.addLayer(rodents);
map.addLayer(clusters);
});
// HEAT LAYER
$.getJSON("rodents.geojson",function(data){
var locations = data.features.map(function(rat) {
// the heatmap plugin wants an array of each location
var location = rat.geometry.coordinates.reverse();
location.push(1.9);
return location;
});
var heat = L.heatLayer(locations, { radius: 50 });
map.addLayer(heat);
});
</script>
</body>
</html>
change the clusters and heat variable to global. And add only one of both layers to the map.
var clusters, heat;
$.getJSON("rodents.geojson",function(data){
// ...
clusters = L.markerClusterGroup();
clusters.addLayer(rodents);
map.addLayer(clusters);
});
// HEAT LAYER
$.getJSON("rodents.geojson",function(data){
//...
heat = L.heatLayer(locations, { radius: 50 });
});
Then add / remove the layers in your onchange function from the select:
<select id="estilo" onchange="changeFnc(this)">
<option value="points" >PUNTOS</option>
<option value="heat">MAPA DE CALOR</option>
</select>
function changeFnc(obj){
var value = obj.value;
if(value == "points"){
if(map.hasLayer(clusters)){
map.removeLayer(clusters);
}
map.addLayer(points);
}else{
if(map.hasLayer(points)){
map.removeLayer(points);
}
map.addLayer(clusters);
}
}
PS: This code is not tested but should work
Related
I have the following code and I want to add different text in each of the icons. Example for the location "Quebec" it should be entered "08h00" for "Beaupre" .. "15h00" etc..
<html>
<head>
<script src="https://api.mqcdn.com/sdk/mapquest-js/v1.3.2/mapquest.js"></script>
<link type="text/css" rel="stylesheet" href="https://api.mqcdn.com/sdk/mapquest-js/v1.3.2/mapquest.css"/>
<script type="text/javascript">
window.onload = function() {
L.mapquest.key = '';
// Geocode three locations, then call the createMap callback
L.mapquest.geocoding().geocode(['Quebec,Qc', 'Beaupre,Qc', 'Montmagny,Qc'], createMap);
function createMap(error, response) {
// Initialize the Map
var map = L.mapquest.map('map', {
layers: L.mapquest.tileLayer('map'),
center: [0, 0],
zoom: 12
});
// Generate the feature group containing markers from the geocoded locations
var featureGroup = generateMarkersFeatureGroup(response);
// Add markers to the map and zoom to the features
featureGroup.addTo(map);
map.fitBounds(featureGroup.getBounds());
}
function generateMarkersFeatureGroup(response) {
var group = [];
for (var i = 0; i < response.results.length; i++) {
var location = response.results[i].locations[0];
var locationLatLng = location.latLng;
// Create a marker for each location
var marker = L.marker(locationLatLng, {icon: L.mapquest.icons.flag()})
.bindPopup(location.adminArea5 + ', ' + location.adminArea3);
group.push(marker);
}
return L.featureGroup(group);
}
}
</script>
</head>
<body style="border: 0; margin: 0;">
<div id="map" style="width: 100%; height: 530px;"></div>
</body>
</html>
Could anyone help me please ?
Thanks.
Try setting the symbol for the flag like icon: L.mapquest.icons.flag({symbol:"08h00"})
More details here: https://developer.mapquest.com/documentation/mapquest-js/v1.3/l-mapquest-icons/
I have written a Svelte component that displays a map using Leaflet. The following code of the component works.
I'm just wondering if this is the way to do it, or if there is a "more correct" or "smarter" way? Especially in view of the await import('leaflet'); in loadMap() and the way the CSS is loaded from the CDN in onMount()...
<script>
import { onMount } from 'svelte';
let map;
onMount(() => {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'https://unpkg.com/leaflet#1.6.0/dist/leaflet.css';
link.onload = () => loadMap();
document.head.appendChild(link);
return () => {
map.remove();
link.parentNode.removeChild(link);
};
});
async function loadMap() {
await import('leaflet');
map = L.map('map').setView([49, 12], 13);
L.tileLayer('https://a.tile.openstreetmap.org/{z}/{x}/{y}.png ', {
attribution:
'Map data © OpenStreetMap contributors, CC-BY-SA',
maxZoom: 18,
}).addTo(map);
}
</script>
<style>
#map {
height: 480px;
}
</style>
<div id="map" />
You could use <svelte:head> to load the css and javascript: According to the docs:
This element makes it possible to insert elements into document.head. During server-side rendering, head content is exposed separately to the main html content.
So the head component would look like this:
<svelte:head>
<link
rel="stylesheet"
href="https://unpkg.com/leaflet#1.6.0/dist/leaflet.css"
integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
crossorigin="" />
<script
src="https://unpkg.com/leaflet#1.6.0/dist/leaflet.js"
integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew=="
crossorigin="">
</script>
</svelte:head>
Here is a full REPL to play around.
What am I doing wrong? The intent is to have a few (say 6) leafletjs panes, each containing many markers and polylines, so the panes can be hidden independently. Here is a simplified program showing just two lines and markers in jsfiddle. The problem is, the polylines all get grouped in the same SVG and all get hidden together. Each pane in the example should show one polyline and one marker.
I don't want to remove the polylines from the map to hide them, then recreating them would not perform well.
If needed, the polylines could be drawn using D3 on top of the leaflet map but I was hoping it could all be done in leaflet.
Thanks!
JS:
'use strict';
document.addEventListener("DOMContentLoaded", function(event) {
var map = L.map('map').setView([30.5, -0.09], 2);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
var pane1 = map.createPane('pane1');
var pane2 = map.createPane('pane2');
function hide(pane) {
pane.style.display = 'none';
}
function show(pane) {
pane.style.display = '';
}
let icon = new L.Icon.Default();
function dr(pane, latlng){
L.polyline([[45.421, -75.697], latlng], {
weight: 2,
pane: pane
}).addTo(map);
L.marker(latlng, {
icon: icon,
pane: pane
}).addTo(map);
}
// define two locations with lines from Ottawa
dr(pane1, [ 42.3732216, -72.5198537 ]);
dr(pane2, [ 35.9606384, -83.9207392 ]);
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function loop(){
for( var i = 0; i<100; i++){
hide(pane1);
show(pane2);
await sleep(1000);
hide(pane2);
show(pane1);
await sleep(1000);
}
}
loop();});
HTML:
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.5.1/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin=""/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.6.0/leaflet-src.js" integrity="sha256-wc8X54qvAHZGQY6nFv24TKlc3wtO0bgAfqj8AutTIu0=" crossorigin="anonymous"></script>
<style>
html, body {
height: 100%;
margin: 0;
}
#map {
width: 900px;
height: 500px;
}
</style>
</head>
<body>
<div id='map'></div>
</body>
</html>
<script src="c.js"></script>
I am trying to use draw plugin from here http://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html#l-draw
and tried using it locally as shown below
<html>
<head>
<title>A Leaflet map!</title>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css"/>
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.2/leaflet.draw.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/0.4.2/leaflet.draw.js"></script>
<style>
#map{ height: 100% }
</style>
</head>
<body>
<div id="map"></div>
<script>
var map = L.map('map').setView([51.505, -0.09], 13);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
var drawControl = new L.Control.Draw({
draw : {
position : 'topleft',
polygon : true,
polyline : false,
rectangle : true,
circle : false
},
edit : false
});
map.addControl(drawControl);
</script>
</body>
</html>
I am getting the drawing control and map but the polygon draw is not shown up after drawing is completed not sure how to do it
Please help in getting the polygon drawn on the map as shown in this demo
http://leaflet.github.io/Leaflet.draw/docs/examples/full.html
You must create a feature group and add the layers when they are created ...
var drawnItems = L.featureGroup().addTo(map);
map.on(L.Draw.Event.CREATED, function (event) {
var layer = event.layer;
drawnItems.addLayer(layer);
});
see the source of http://leaflet.github.io/Leaflet.draw/docs/examples/full.html
I have read helpful answered given By #ghybs Page: “update properties of geojson to use it with leaflet”
but I am stuck to make it wok using a bootstrap popup window too collect data from user and hold it on feature.properties later I will collect multiple data from multiple marker, polygon polyline convert to geojson.
I can collect data form popup but data is showing same for every marker I am creating. feature.properties should different for each markers.
pelase review my code :
var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
osmAttrib = '© OpenStreetMap contributors',
osm = L.tileLayer(osmUrl, {
maxZoom: 18,
attribution: osmAttrib
});
map = L.map('map', {
layers: [osm],
center: [31.9500, 35.9333],
zoom: 15
});
var editableLayers = L.geoJson().addTo(map);
map.addControl(new L.Control.Draw({
edit: {
featureGroup: editableLayers
}
}));
map.on('draw:created', function (e) {
var layer = e.layer,
feature = layer.feature = layer.feature || {};
feature.type = feature.type || "Feature";
var props = feature.properties = feature.properties || {};
//layer.feature = {properties: {}}; // No need to convert to GeoJSON.
//var props = layer.feature.properties;
props.action = null;
editableLayers.addLayer(layer);
addPopup(layer);
});
function addPopup(layer) {
var content = document.getElementById('action');
layer.feature.properties.action = content;
/* content.addEventListener("keyup", function () {
layer.feature.properties.action = content;
});*/
/* layer.on("popupopen", function () {
content.value = layer.feature.properties.desc;
content.focus();
});
layer.bindPopup(content).openPopup();*/
layer.on('click', function() {
$('#action').val(layer.feature.properties.action);
//content.value = layer.feature.properties.action;
$('#attributes').modal({'show' : true, backdrop:'static', keyboard:false});
$('#action').val(layer.feature.properties.action);
});
}
document.getElementById("convert").addEventListener("click", function () {
console.log(JSON.stringify(editableLayers.toGeoJSON(), null, 2));
});
#map {
height: 500px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script type="text/javascript" src="https://unpkg.com/leaflet#0.7.7/dist/leaflet-src.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet#0.7.7/dist/leaflet.css" type="text/css">
<link rel="stylesheet" href="https://cdn.rawgit.com/Leaflet/Leaflet.draw/v0.3.0/dist/leaflet.draw.css" type="text/css">
<!--js-->
<script type="text/javascript" src="https://cdn.rawgit.com/Leaflet/Leaflet.draw/v0.3.0/dist/leaflet.draw-src.js"></script>
<body>
<div id="map"></div>
<button id="convert">
Get all features to GeoJSON string
</button>
<div class="modal" id="attributes">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Attribute Data</h4>
</div>
<div class="modal-body">
<div class="content-scroll5">
<div class="col-xs-2">
<label for="ex1">ACTION</label>
<input class="form-control" name="action" id="actin" type="text">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">OK</button>
</div>
</div>
</div>
</div>