how to replace the geoJSON variable - javascript

I have a geo JSON variable as below:
line_01.js
var lines= {
"type":"FeatureCollection",
"features": [
{
"type": "Feature",
"geometry":{"type":"LineString",
"coordinates":[[103.85909,1.2941],[103.85895,1.2940450000000001],[103.85881,1.29399]]},
"properties": {"id":"01","score":10}
},
....//more 100 lines
]};
So when I click a button I need to replace the variable lines with
line_02.js
var lines= {
"type":"FeatureCollection",
"features": [
{
"type": "Feature",
"geometry":{"type":"LineString",
"coordinates":[[103.8436,1.2893],[103.8890,1.2956],[103.8432,1.2874]]},
"properties": {"id":"03","score":09}
},
..../ the rest lines
]};
So my button click function is
$('#update_map').click(function(){
$("#grid_name").html("SINGAPORE");
updatemap();
});
function updatemap(){
if (geojson) {
geojson.remove();
console.log("removed");
}
//here I have to replace the lines variable to the new one
geojson = L.geoJson(lines, {
style: style,
onEachFeature: onEachFeature
}).addTo(map);
}
So which means it will erase the previous line(layer) and replace a new line.is it possible?Any help is appreciated.Thank you.

From the looks of it you want to update the coordinates and properties field when a user clicks a button. If so then you do
function updatemap(){
if (geojson) {
geojson.remove();
console.log("removed");
}
//here I have to replace the lines variable to the new one
if (lines){
// updates lines if necessary
lines["coordinates"] = [New coordinates]
lines["properties"] = {new : score}
}
geojson = L.geoJson(lines, {
style: style,
onEachFeature: onEachFeature
}).addTo(map);
}

Related

Update polygon leaflet realtime

I am trying to display a polygon from an external geojson file, the data loads but does not update the polygon in real time.
The polygon is added but color is not updated after interval when level changes.
Heres is my code:
L.realtime({
url: 'js/areas.json',
crossOrigin: true,
type: 'json'
}, {
interval: 60 * 1000,
onEachFeature: function (feature, latlng) {
var level = feature.properties.level;
if (level == 0) {
var polygon = L.polygon(latlng._latlngs, {
color: '#51F03B',
opacity: 0.3,
fillOpacity: 0.1
}).addTo(map);
} else if (level == 1) {
var polygon = L.polygon(latlng._latlngs, {
color: '#F43B19',
opacity: 0.3,
fillOpacity: 0.1
}).addTo(map);
}
return polygon;
},
updateFeature: function (feature, oldLayer, newLayer) {
var level = feature.properties.level;
if (!oldLayer) {
return;
}
if (level== 0) {
oldLayer.setStyle({color: '#51F03B'});
} else if (level == 1) {
oldLayer.setStyle({color: '#F43B19'});
}
return oldLayer;
}
});
If i don´t return oldLayer, the polygon color changes but don´t remove the previous polygon.
geoJson file:
{
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {
"level": 0,
"id": 1
},
"geometry": {
"type": "Polygon",
"coordinates": [[
[-75.360297, 6.071571],
[-76.005083, 6.063846],
[-76.051694, 6.511708],
[-75.298149, 6.573451]
]]
}
}]
}
I show markers and more in this way but I don't know if being polygons is different.
The way I worked with "real-time" with polygon was cleaning the previous polygon and creating a new one. With that in mind, you will need to keep track of the layers that you have created (like in an array), a method to clear that layer (or clear all layers, there's a leaflet method for that) and a method to set a timeOut to call an update method.
I say "real-time" because currently, I keep asking back-end for an update using a timeOut function.
first, when you received the geojson draw the polygon, add it to your map and call the setTimeout with your update method.
second, you will need a method to remove the old layer, something like this:
const resetPolygonArray = polygonId => {
myPolygon = polygonArray.filter(polygon => {
if (polygon.id != polygonId) {
return myPolygon
} else {
map_machiney.removeLayer(myPolygon.geojson)
}
})
}
even though you can use that array to store the polygon and the marker related to it, like this structure:
polygonArray.push({
id: polygonId,
geojson: geojson,
marker: marker
})

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.

leaflet map, getting specific data of geojson file with button

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

Leaflet: How to style 2000+ points in a GeoJSON object with no style properties?

I have a single GeoJSON FeatureCollection object that contains over 2000 features. In the GeoJSON object, each feature is part of one category like so:
{
"type": "Feature",
"properties": {
"category": "Electrical",
"Name": "Plane No 2"
},
"geometry": {
"type": "Point",
"coordinates": [
94.5703125,
58.722598828043374
]
}
},
{
"type": "Feature",
"properties": {
"category": "Military",
"Name": "Base 1"
},
"geometry": {
"type": "Point",
"coordinates": [
104.4140625,
62.91523303947614
]
}
},
In my actual data, there are a total of about 38 categories (each feature is only assigned to one category).
Is using a JavaScript Switch Statement in my situation a practical solution in order to give each point its own styling? Or, is there a better way?
I am doing something like this in my code:
L.geoJson(mygeoJson, {
onEachFeature: function (feature, layer){
layer.bindPopup(L.Util.template(popupTemplate, feature.properties));
},
pointToLayer: function (feature, latlng){
return L.circleMarker(latlng, gjsonOptions);
},
// 3 of the 38 categories are listed here as an example
style: function(feature){
switch(feature.properties.category){
case 'Electrical': return { color: '#fb8072'};
case 'Military': return { color: '#b3de69'};
case 'Aviation': return { color: '#80b1d3'};
}
}
}).addTo(map);
Demo link here
I think one should add the colors on the clientside, just as he/she did in the code example. adding the colors to each GeoJSON feature will needlessly bloat your transfer. If you really want to add them to your collection you could create some sort of legend property in your collection object like so:
var collection = {
"type": "FeatureCollection",
"properties": {
"legend": {
"Electrical": "#fb8072",
"Military": "#b3de69",
"Aviation": "#80b1d3"
}
}
"features": [...]
}
So that when you create your GeoJSON layer you can add them on the fly:
L.geoJson(collection, {
'style': function (feature) {
return {
'color': collection.properties.legend[feature.properties.category]
}
}
}).addTo(map);
You could instead of storing the legend in the collection object, store it in your code/script somewhere:
var legend = {
"Electrical": "#fb8072",
"Military": "#b3de69",
"Aviation": "#80b1d3"
}
L.geoJson(collection, {
'style': function (feature) {
return {
'color': legend[feature.properties.category]
}
}
}).addTo(map);
Edit after comments:
If you need to set L.Marker icons you should use the pointToLayer function:
L.geoJson(collection, {
'pointToLayer': function (feature, latlng) {
return new L.Marker(latlng, {
'icon': new L.Icon({
'iconUrl': 'icons/' + feature.properties.category + '.png'
...
})
})
}
}).addTo(map);
You're currently using L.CircleMarker which doesn't support the icon option. It's a path which only supports the pathoptions:
http://leafletjs.com/reference.html#path-options
Here's a nice tutorial on creating L.Marker's with custom icons:
http://leafletjs.com/examples/custom-icons.html

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