leaflet map, getting specific data of geojson file with button - javascript

I'm triying to display on my map specific value ( data.geojson) of my geojson file with buttons. (for exemple to plot a map with only value "domaine":"violences ")
I am loocking for a way to rely my data ("domaine":"violences" or other)with a buttons on my map ?
Thanks so much in advance for your time.
my js:
<script type="text/javascript">
var map = L.map('map');
var terrainTiles = L.tileLayer('http://stamen-tiles-{s}.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}.{ext}', {
attribution: 'Map tiles by Stamen Design, CC BY 3.0 — Map data © OpenStreetMap',
subdomains: 'abcd',
minZoom: 0,
maxZoom: 20,
ext: 'png'
});
terrainTiles.addTo(map);
map.setView([46.5160000, 6.6328200], 10);
L.control.locate(location).addTo(map);
function addDataToMap(data, map) {
var dataLayer = L.geoJson(data, {
onEachFeature: function(feature, layer) {
var popupText = "<b>" + feature.properties.nom
+ "<br>"
+ "<small>" + feature.properties.localite
+ "<br>Rue: " + feature.properties.rue + + feature.properties.num
+ "<br>Téléphone: " + feature.properties.tel
+ "<br><a href= '" + feature.properties.url + "'>Internet</a>";
layer.bindPopup(popupText); }
});
dataLayer.addTo(map);
}
$.getJSON("data.geojson", function(data) { addDataToMap(data, map); });
</script>
</body>
</html>
the data.geojson
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [ 6.1200622,46.2106091 ]
},
"properties": {
"nom":"Centre d'entraînement aux méthodes d'éducation active - Genève",
"rue":"Route des Franchises",
"num":"11",
"npa":1203,
"localite":"Genève",
"canton":"GE",
"tel":"022 940 17 57",
"url":"www.formation-cemea.ch",
"domaine":"formation "
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [ 6.1243056,46.2120426 ]
},
"properties": {
"nom":"VIRES",
"rue":"Rue Ernest-Pictet ",
"num":"10",
"npa":1203,
"localite":"Genève",
"canton":"GE",
"tel":"022 328 44 33",
"url":"www.vires.ch",
"domaine":"violences "
}
}

As for toggling ON / OFF your categories, you could use Leaflet Layers Control L.control.layers.
As for grouping your features by category ("domaine" in your case), see the post I linked in my comment: Leaflet: How to toggle GeoJSON feature properties from a single collection?
You could even slightly simplify it by directly using Layer Groups L.layerGroup instead of using intermediate arrays.
var categories = {},
category;
var layersControl = L.control.layers(null, null).addTo(map);
function addDataToMap(data, map) {
L.geoJson(data, {
onEachFeature: function(feature, layer) {
category = feature.properties.domaine;
// Initialize the category layer group if not already set.
if (typeof categories[category] === "undefined") {
categories[category] = L.layerGroup().addTo(map);
layersControl.addOverlay(categories[category], category);
}
categories[category].addLayer(layer);
}
});
//dataLayer.addTo(map); // no longer add the GeoJSON layer group to the map.
}
$.getJSON("data.geojson", function(data) {
addDataToMap(data, map);
});
Demo: https://plnkr.co/edit/H6E6q0vKwb3RPOZBWs27?p=preview

Related

Leaflet.js - Create layers and add markers depending on geojson category data?

I have a .js file with coordinates for internships:
var internships = [{
"features": [
{"type":"Feature","properties":{"category":"entretient","Name":"green"},"geometry":{"type":"Point","coordinates":[50.807149, 3.162994]}},
{"type":"Feature","properties":{"category":"securité","Name":"blue"},"geometry":{"type":"Point","coordinates":[50.334421, 3.290146]}},
{"type":"Feature","properties":{"category":"secretaria","Name":"red"},"geometry":{"type":"Point","coordinates":[50.744787, 2.256216]}}
]
}];
I've found this bit of code allowing me to create layers depending on a property and here what my JS looks like:
$.getScript("CoordinatesPdC.js");
function mapLoad() {
var sécuritéLayer = new L.LayerGroup();
var secrétariatLayer = new L.LayerGroup();
var entretientLayer = new L.LayerGroup();
var map = L.map('map').setView([50.2910, 2.7775], 8);
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: 'Map data © OpenStreetMap contributors, ' +
'CC-BY-SA, '
}).addTo(map);
var marker = L.marker([50.2910, 2.7775]).addTo(map);
var entretientLayer = L.geoJson(internships, {
filter: function (feature, layer) {
return (feature.properties.category === "entretient");
}
}).addTo(map);
var sécuritéLayer = L.geoJson(internships, {
filter: function (feature, layer) {
return (feature.properties.category === "sécurité");
}
}).addTo(map);
var secrétariatLayer = L.geoJson(internships, {
filter: function (feature, layer) {
return (feature.properties.category === "secrétariat");
}
}).addTo(map);
}
window.onload = mapLoad;
But now I have to create the markes assigned to these layers, how can I achieve that?
Your markers are already assigned to each later. In your example, you create a layer (with all of its markers) and immediately add it to the map using .addTo(map); Here's the code responsible for it.
var sécurité = L.geoJson(internships, {
filter: function (feature, layer) {
return (feature.properties.category === "sécurité");
}
}).addTo(map);
Now, you probably want to only display a certain layer based on user input. If so, I suggest adding the related layer to the map on a click event. Then when the event is triggered a layer is added. Here's the code for doing that. sécurité.addTo(map)
A layer is removed using map.removeLayer(sécurité);
Below is a working example based on your initial code. (I did write it in jQuery as my vanilla JavaScript could be better) You can also view it on jsFiddle here.
I left some comments in the code to explain what each part does. I hope that helps you with your understanding.
var internships = [{
"features": [{
"type": "Feature",
"properties": {
"category": "entretient",
"Name": "green"
},
"geometry": {
"type": "Point",
"coordinates": [3.162994, 50.807149]
}
},
{
"type": "Feature",
"properties": {
"category": "securité",
"Name": "blue"
},
"geometry": {
"type": "Point",
"coordinates": [3.290146, 50.334421]
}
},
{
"type": "Feature",
"properties": {
"category": "secretaria",
"Name": "red"
},
"geometry": {
"type": "Point",
"coordinates": [2.256216, 50.744787]
}
}
]
}];
$(document).ready(function() {
// Create an object to keep track of active layers and each layer with its markers
const layers = {
active: [],
entretientLayer: new L.LayerGroup(),
sécuritéLayer: new L.LayerGroup(),
secrétariatLayer: new L.LayerGroup(),
};
// create the map
var map = L.map('map').setView([50.8010, 3.1675], 6,5);
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: 'Map data © OpenStreetMap contributors, ' +
'CC-BY-SA, '
}).addTo(map);
// based on the category assign a marker to the layer
layers.entretientLayer = L.geoJson(internships, {
filter: function(feature, layer) {
return (feature.properties.category === "entretient");
}
})
layers.sécuritéLayer = L.geoJson(internships, {
filter: function(feature, layer) {
return (feature.properties.category === "securité");
}
})
layers.secrétariatLayer = L.geoJson(internships, {
filter: function(feature, layer) {
return (feature.properties.category === "secretaria");
}
})
// register click event
$('button').on('click', function(e) {
const layerName = e.target.name;
// if a layer is already active, remove it from the map and the active array
if (layers.active.includes(layerName)) {
layers.active = layers.active.filter(layer => layer !== layerName);
map.removeLayer(layers[layerName]);
} else {
// add the layer to the map and to the active array
layers.active.push(layerName);
layers[layerName].addTo(map);
}
});
});
#map {
height: 140px;
width: 100%;
}
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.3/leaflet.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!--<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.3/leaflet.js"></script> -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.3.3/leaflet-src.js"></script>
<div class="button-group">
<button name="entretientLayer">entretient</button>
<button name="sécuritéLayer">sécurité</button>
<button name="secrétariatLayer">secrétariat</button>
</div>
<p></p>
<div id="map"></div>
UPDATE: updated leaflet.js to version 1.3.3.
The difference with the update is that each layer needs to be initialised using the new key word. Code is updated to reflect the change.

Loading GeoJSON into Mapbox

When I use GeoJSON inside the HTML it works, but when I try to load externally it doesn't.
My HTML file and GeoJSON file are in the same folder in site.
I try to open picture popups with markers.
Thanks a lot!
L.mapbox.accessToken = 'lalalalala';
var southWest = L.latLng(40.875557, 29.235992),
northEast = L.latLng(41.277226, 28.749847),
bounds = L.latLngBounds(southWest, northEast);
var map = L.mapbox.map('map', 'mapbox.light', {
maxBounds: bounds,
maxZoom: 19,
minZoom: 11
});
var myLayer = L.mapbox.featureLayer()
.loadURL('http://terkedilmisarabalar.mudurlugu.org/geojson/terkedilmisarabalar.geojson')
.on('ready', function() {
myLayer.eachLayer(function(layer) {
map.fitBounds(myLayer.getBounds());
layer.bindPopup(layer.features.properties.name);
});
})
.addTo(map);
myLayer.setGeoJSON(geojson);
myLayer.on('onclick', function(e) {
e.layer.openPopup();
});
myLayer.on('onrelease', function(e) {
e.layer.closePopup();
});
Here is an example GeoJSON file:
{
type: 'FeatureCollection',
features: [
{
"type": "Feature",
"properties": {
"name": "Acıbadem Cd. No:117",
"description": "<img src=\"https://lh3.googleusercontent.com/DkEl65k9kZAtvPdf9HuE22aIAJKUKBDtiL0m5vZBRqn9nVsgcQIQYdi03gt5yhOKcrEvTQpctu_xnLVfhzzt6Tr3fGtsxuIJSqPrf7R9p-0faSL-YRxTzyn44B8KVB8\" height=\"200\" width=\"auto\" /><br><br>",
"gx_media_links": "https://lh6.googleusercontent.com/fmIjm4ynkTWSkmzcOfoMCoVgnm6h9pQ8KINgHqhjx-ZNQMrT05NqsZo2Lv5d6FwFFakmqOzl_ruRKvu34jbC96U3nKaxlu0sul6W4qXU1ily4PNbLCQTsR2BGKOxervb"
},
"geometry": {
"coordinates": [
29.045881,
41.005992,
0
],
"type": "Point"
}
}

Add infowindow and custom icon to Google map using Geojson

I have this simple Google map in a Web2py application.
I would like to apply something like a switch for choosing the feature icon and also setting an infoWindow from json text.
Someone knows how I can do it?
var map;
function initMap() {
map = new google.maps.Map(document.getElementById("events_map"), {
center: {lat: 45.070309, lng: 7.686580999999933},
zoom: 13,
mapTypeControl: false
});
var largeInfowindow = new google.maps.InfoWindow();
google.maps.event.addListener(map, 'idle', function() {
var ne = map.getBounds().getNorthEast();
var north = ne.lat();
var east = ne.lng();
var sw = map.getBounds().getSouthWest();
var south = sw.lat();
var west = sw.lng();
var queryString = '?east=' + east + '&west=' + west + '&south=' + south + '&north=' + north + '&zoom=8'
map.data.loadGeoJson('{{=URL('f_ajax', 'get_locations_g')}}' + queryString);
});
}
json data has a category field that can have 1, 2, 3, or 4 as value.
So with a switch I would like to set the icon in this way:
var icon;
switch (feature.properties.category) {
case '1':
icon = greenIcon;
break;
case '2':
icon = bluIcon;
break;
case '3':
icon = redIcon;
break;
case '4':
icon = blackIcon;
break;
}
But I don't know how.
For the infowindow, can I use this function and how for displaying the json field 'description'?
Thanks.
function populateInfoWindow(marker, infowindow) {
// Check to make sure the infowindow is not already opened on this marker.
if (infowindow.marker != marker) {
infowindow.marker = marker;
infowindow.setContent("<div><a href='" + marker.link + "'>" + marker.title + '</a></div>');
infowindow.open(map, marker);
// Make sure the marker property is cleared if the infowindow is closed.
infowindow.addListener('closeclick', function() {
infowindow.marker = null;
});
}
}
For the icon you have to use the setStyle-function.
A object with the icons should be the easiest approach here
map.data.setStyle(function(feature) {
return {
icon:({1:greenIcon,
2:redIcon,
3:blueIcon,
4:blackIcon})[feature.getProperty('category')]
};
});
The function for the InfoWindow may not be used, because there is no marker available in the click-handler, you have to set the options of the InfoWindow based on the clicked feature
map.data.addListener('click', function(event) {
largeInfowindow.setOptions({
map : map,
position: event.feature.getGeometry().get(),
content : '<strong>'+event.feature.getProperty('description')+'</strong>'
})
});
Demo:
function initMap() {
var greenIcon = 'http://maps.gstatic.com/mapfiles/markers2/icon_green.png',
redIcon = 'http://maps.gstatic.com/mapfiles/markers2/marker.png',
blueIcon = 'http://maps.gstatic.com/mapfiles/markers2/boost-marker-mapview.png',
blackIcon = 'http://maps.gstatic.com/mapfiles/markers2/drag_cross_67_16.png',
map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: {lat:52.41, lng: 9.74}
}),
largeInfowindow = new google.maps.InfoWindow({pixelOffset:new google.maps.Size(0,-30)});
map.data.setStyle(function(feature) {
return {
icon:({1:greenIcon,
2:redIcon,
3:blueIcon,
4:blackIcon})[feature.getProperty('category')]
};
});
map.data.addListener('click', function(event) {
largeInfowindow.setOptions({
map : map,
position: event.feature.getGeometry().get(),
content : '<strong>'+event.feature.getProperty('description')+'</strong>'
})
});
map.data.addGeoJson(json);
}
var json={
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {category:1,description:'Berlin'},
"geometry": {
"type": "Point",
"coordinates": [
13.392333984375,
52.53627304145948
]
}
},
{
"type": "Feature",
"properties": {category:2,description:'Hamburg'},
"geometry": {
"type": "Point",
"coordinates": [
10.008544921875,
53.57293832648609
]
}
},
{
"type": "Feature",
"properties": {category:3,description:'Cologne'},
"geometry": {
"type": "Point",
"coordinates": [
6.954345703125,
50.951506094481545
]
}
}
]
};
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
<script async defer
src="https://maps.googleapis.com/maps/api/js?callback=initMap"></script>
<div id="map"></div>

Leaflet markers on localstorage, how to get marker lat lng and exclude from storage?

I created a function that on click places a marker on map, and save it to localstorage. Inside the marker popup, its displayed the marker position, and a delete button.
How I can make that delete button get actual marker position, compare to the ones stored in localstorage, and if find an equal value, delete it from local storage?
Using this:
for ( var i = 0, len = localStorage.length; i < len; ++i ) {
console.log( localStorage.getItem( localStorage.key( i ) ) );
}
I get the what's in localstorage, I noticed that the markers are saved with a "\", any way to improve this code?
["{\"lat\":1780,\"lng\":456}","{\"lat\":1280,\"lng\":904}","{\"lat\":1000,\"lng\":-132}","{\"lat\":216,\"lng\":300}"]
The code:
function onMapClick(e) {
var geojsonFeature = {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [e.latlng.lat, e.latlng.lng]
}
}
var marker;
L.geoJson(geojsonFeature, {
pointToLayer: function(feature, latlng){
marker = L.marker(e.latlng, {
title: "Resource Location",
alt: "Resource Location",
riseOnHover: true,
draggable: false,
icon: totem
}).bindPopup("<span>X: " + e.latlng.lng + ", Y: " + e.latlng.lat + "</span><br><a href='#' id='marker-delete-button'>Delete marker</a>");
marker.on("popupopen", onPopupOpen);
marker.on("dragend", function (ev) {
var chagedPos = ev.target.getLatLng();
this.bindPopup(chagedPos.toString()).openPopup();
});
// Begin store markers in local storage
storeMarker(e.latlng);
// End store markers in local storage
return marker;
}
}).addTo(map);
}
function onPopupOpen() {
var tempMarker = this;
$("#marker-delete-button:visible").click(function () {
map.removeLayer(tempMarker);
localStorage.removeItem("markers");
});
}
/// Load markers
function loadMarkers(){
var markers = localStorage.getItem("markers");
if(!markers) return;
markers = JSON.parse(markers);
markers.forEach(function(entry) {
latlng = JSON.parse(entry);
var geojsonFeature = {
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [latlng.lat, latlng.lng]
}
}
var marker;
L.geoJson(geojsonFeature, {
pointToLayer: function(feature){
marker = L.marker(latlng, {
title: "Resource Location",
alt: "Resource Location",
riseOnHover: true,
draggable: true,
icon: totem
}).bindPopup("<span>X: " + latlng.lng + ", Y: " + latlng.lat + "</span><br><a href='#' id='marker-delete-button'>Delete marker</a>");
marker.on("popupopen", onPopupOpen);
return marker;
}
}).addTo(map);
});
}
/// Store markers
function storeMarker(marker){
var markers = localStorage.getItem("markers");
if(!markers) {
markers = new Array();
console.log(marker);
markers.push(JSON.stringify(marker));
}
else
{
markers = JSON.parse(markers);
markers.push(JSON.stringify(marker));
}
console.log(JSON.stringify(markers));
localStorage.setItem('markers', JSON.stringify(markers));
}
map.on('click', onMapClick);
loadMarkers();
You seem to be confused about what locaStorage is/does, it stores data as key:value pairs, so what you have there is basically a list of stuff where you have:
key: \"lat\":1780,
value: \"lng\":456
As for deleting geoJSON features, a possibility is to use is the function onEachFeature() that can bind a function to geoJSON features before they are added to the map, so perhaps you can use that to bind a delete function when the delete button of the popup is clicked but while it can remove the layer from the map, it will not wipe the data from localStorage as leaflet as no way of referencing the data there.
Another possibility is to add unique id's to your points when creating them so you can reference them more easily when you want to remove them from database.

Openlayers 3 : popup by geojson file

How do you put GeoJSON attribute information in a popup with OpenLayers 3
I need to display the informations included in my geojson file into the popup. Here is my method but it gives me undefined.
My GeoJson file:
{ "type": "FeatureCollection", "features": [{ "type": "Feature", "properties": { "name": "Caen - Campus 3 "}, "geometry": { "type": "Point", "coordinates": [-0.353538,49.148791] } }, { "type": "Feature", "properties": { "name": "Caen "}, "geometry": { "type": "Point", "coordinates": [-0.369770,49.184403] } }
Here is my method
var element = document.getElementById('popup');
var popup = new ol.Overlay({
element: element
});
map.addOverlay(popup)
map.on('click', function(evt){
var feature = map.forEachFeatureAtPixel(evt.pixel,
function(feature, layer) {
return feature;
});
if ( feature ) {
var geometry = feature.getGeometry();
var coord = geometry.getCoordinates();
var nom = feature.getProperties();
//var nam = nom.type;
popup.setPosition(coord);
$(element).popover({
'placement': 'top',
'html': true,
'content': '<p>'+feature.get('name')+'</p>'
});
$(element).popover('show');
} else {
$(element).popover('destroy');
}
});
I create the popup when I click on it displays me 'undefined'. I think that don't use the good method to put the 'name' object included on the GeoJson file: feature.get('name')
I think that I don't uses the best method. Thank for your help.

Categories

Resources