Q: how to add "fade in" transition effect for Mapbox circle layer - mapbox

I'm loading points from Geojson in batches and would like to add "fadeIn" effect or animation when the points first appear in Mapbox.
this.map.addLayer({
id: 'points',
type: 'circle',
paint: {
'circle-radius-transition': {duration: 300},
'circle-color': '#F98200',
'circle-stroke-color': '#D23B00',
'circle-stroke-opacity': 0.5,
},
source: 'points',
})
I tried circle-radius-transition but it does not seem to help.

You are on the right track with the paint properties. I think what you need is the circle-opacity-transition.
Follow these steps:
Add the points with 'circle-opacity': 0 as default opacity value
Set the 'circle-opacity-transition' as you wish
After the map is loaded change the layers 'circle-opacity' to 1 and your layer will be faded in.
map.addLayer({
"id": "point",
"source": "point",
"type": "circle",
"paint": {
"circle-radius": 20,
// here we define defaut opacity is zero
"circle-opacity": 0,
"circle-opacity-transition": {duration: 2000},
"circle-color": 'red'
}
});
You can check out this solution here: codepen

Joel's answer was perfect but the timeout has to be places inside the map load function else the circle layer will not be loaded if the map takes more time to load
Checkout the below code snippet
mapboxgl.accessToken = 'pk.eyJ1Ijoiam9lbHN0dWVkbGUiLCJhIjoiY2ltbmI1OWNpMDAxNnV1bWFtMnpqYWJndyJ9.uDWVjgzU7EVS63OuVWSRuQ';
var map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/mapbox/streets-v9', //stylesheet location
center: [7.445683, 46.945966], // starting position
zoom: 9 // starting zoom
});
// the data we'll add as 'points'
var data = {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {
"timestamp": "0",
"location-name": "Bern"
},
"geometry": {
"type": "Point",
"coordinates": [7.445683, 46.945966]
}
}]
}
// so if the map loads do the following
map.on('load', function() {
// add the data source with the information for the point
map.addSource('point', {
"type": "geojson",
"data": data
});
map.addLayer({
"id": "point",
"source": "point",
"type": "circle",
"paint": {
"circle-radius": 20,
// here we define defaut opacity is zero
"circle-opacity": 0,
"circle-opacity-transition": {
duration: 1500
},
"circle-color": 'red'
}
});
//Timeout shoud be within the map load function
setTimeout(function() {
map.setPaintProperty('point', 'circle-opacity', 1);
}, 1);
});
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title></title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.36.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.36.0/mapbox-gl.css' rel='stylesheet' />
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<div id='map'></div>
</body>
</html>

Unfortuntely the property-transition won't work in some cases, for example, when you want to toggle a layer on hover.
At least, in my case it does not work. This is my code, the elements pop like there's nothing.
map.addLayer({
'id': 'places-details',
'type': 'symbol',
'source': 'places',
'layout': {
'icon-image': '{icon}',
'text-field': '{data}',
'icon-size': .8,
'text-anchor': 'center',
},
'paint': {
'text-color': '#ffffff',
'icon-opacity': [
'case',
['boolean', ['feature-state', 'hover'], false],
1, 0
],
'text-opacity': [
'case',
['boolean', ['feature-state', 'hover'], false],
1, 0
],
"text-opacity-transition": {
"duration": 3000,
"delay": 0
},
"icon-opacity-transition": {
"duration": 300,
"delay": 0
}
},
});

Related

How can I add icons to a map while using the function L.geoJSN on Leaflet?

I know I can add icons on Leaflet using the following logic:
const geojson = {
"name": "interseccao_circulo",
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
},
"geometry": {
"type": "MultiPoint",
"coordinates": [
[
-46.62831244066412,
-23.551014464955063
]
]
}
},
{
"type": "Feature",
"properties": {
},
"geometry": {
"type": "MultiPoint",
"coordinates": [
[
-46.63242614612176,
-23.55277865770234
]
]
}
}
]
}
var mymap = L.map('mapdiv', {
center:[-23.552778, -46.632426],
zoom:16,
maxZoom:20,
zoomControl:false,
attributionControl:false
});
var lyrOSRHOT = L.tileLayer.provider('OpenStreetMap.HOT');
mymap.addLayer(lyrOSRHOT);
var icons = new L.Icon({
iconUrl: "https://i.imgur.com/ZcGeIVz.png",
iconSize: [40, 40],
});
let lat = geojson.features[0].geometry.coordinates[0][1]
let lng = geojson.features[0].geometry.coordinates[0][0]
let lat2 = geojson.features[1].geometry.coordinates[0][1]
let lng2 = geojson.features[1].geometry.coordinates[0][0]
L.marker([lat, lng], {icon: icons}).addTo(mymap);
L.marker([lat2, lng2], {icon: icons}).addTo(mymap);
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet-src.min.js" integrity="sha512-XQr+/1RXvYozXiwrumwtu3lqQmVwZ8nkLUrC/mc3HBHw4Imh++RXjwtLQFuOz3i65j9CSfKt50x6w/uUY2ovOQ==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-providers/1.12.0/leaflet-providers.min.js" integrity="sha512-LixflAm9c0/qONbz9F1Ept+QJ6QBpb7wUlPuyv1EHloTVgwSK8j3yMV3elnElGQcv7Y5QTFlF/FqyeE/N4LnKQ==" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="anonymous" />
<div id="mapdiv" style="height:100vh; width: 100vw"></div>
However, I'd like to make it work when I draw the points using the L.geoJSON function. Something like the following:
const geojson = {
"name": "interseccao_circulo",
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
},
"geometry": {
"type": "MultiPoint",
"coordinates": [
[
-46.62831244066412,
-23.551014464955063
]
]
}
},
{
"type": "Feature",
"properties": {
},
"geometry": {
"type": "MultiPoint",
"coordinates": [
[
-46.63242614612176,
-23.55277865770234
]
]
}
}
]
}
var mymap = L.map('mapdiv', {
center:[-23.552778, -46.632426],
zoom:16,
maxZoom:20,
zoomControl:false,
attributionControl:false
});
var lyrOSRHOT = L.tileLayer.provider('OpenStreetMap.HOT');
mymap.addLayer(lyrOSRHOT);
var icons = new L.Icon({
iconUrl: "https://i.imgur.com/ZcGeIVz.png",
iconSize: [40, 40],
});
L.geoJSON(geojson, {icon: icons} ).addTo(mymap);
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet-src.min.js" integrity="sha512-XQr+/1RXvYozXiwrumwtu3lqQmVwZ8nkLUrC/mc3HBHw4Imh++RXjwtLQFuOz3i65j9CSfKt50x6w/uUY2ovOQ==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-providers/1.12.0/leaflet-providers.min.js" integrity="sha512-LixflAm9c0/qONbz9F1Ept+QJ6QBpb7wUlPuyv1EHloTVgwSK8j3yMV3elnElGQcv7Y5QTFlF/FqyeE/N4LnKQ==" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="anonymous" />
<div id="mapdiv" style="height:100vh; width: 100vw"></div>
I've tried running it with L.geoJSON(geojson, {icon: icons} ).addTo(mymap), but it doesn't seem to recognize {icon: icons} as the function L.marker does (it's plotting the default Leaflet marker instead)... Is there any way I can draw icons with the function L.geoJSON when I use LeafLet?
I ended up finding the solution to this problem using the pointToLayer object instead of trying to use the icon object inside L.geoJSON. As it's written on the Leaflet geoJSON documentation, the accepted options inside it are only: style, pointToLayer, onEachFeature and filter. The icon option is not accepted inside the Leaflet geoJSON function and it should be used inside the pointToLayer object instead... The solution is the following:
const geojson = {
"name": "interseccao_circulo",
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
},
"geometry": {
"type": "MultiPoint",
"coordinates": [
[
-46.62831244066412,
-23.551014464955063
]
]
}
},
{
"type": "Feature",
"properties": {
},
"geometry": {
"type": "MultiPoint",
"coordinates": [
[
-46.63242614612176,
-23.55277865770234
]
]
}
}
]
}
var mymap = L.map('mapdiv', {
center:[-23.552778, -46.632426],
zoom:16,
maxZoom:20,
zoomControl:false,
attributionControl:false
});
var lyrOSRHOT = L.tileLayer.provider('OpenStreetMap.HOT');
mymap.addLayer(lyrOSRHOT);
L.geoJSON(geojson, {
pointToLayer: function (feature, latlng) {
const icons = new L.Icon({
iconUrl: "https://i.imgur.com/ZcGeIVz.png",
iconSize: [40, 40],
});
return L.marker(latlng, {icon: icons});
}
}).addTo(mymap);
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet-src.min.js" integrity="sha512-XQr+/1RXvYozXiwrumwtu3lqQmVwZ8nkLUrC/mc3HBHw4Imh++RXjwtLQFuOz3i65j9CSfKt50x6w/uUY2ovOQ==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-providers/1.12.0/leaflet-providers.min.js" integrity="sha512-LixflAm9c0/qONbz9F1Ept+QJ6QBpb7wUlPuyv1EHloTVgwSK8j3yMV3elnElGQcv7Y5QTFlF/FqyeE/N4LnKQ==" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="anonymous" />
<div id="mapdiv" style="height:100vh; width: 100vw"></div>

Hover effect for Countries

SO I am new to Mapbox but I am trying to make countries change color on hover. I have seen the hover tutorial on the Docs for states but I am having difficulty finding the right type, data, and source for countries. I have the Mapbox Countries v1 already added to the map from studio. When I try to run this code I get either that it can't find source:"country_boundaries" or "country-boundaries". I know it's something simple but appreciate the help. Thanks.
var hoveredStateId = null;
map.on('load', function () {
==>>map.addSource('states', {
==>>'type': 'geojson',
==>>'data': 'https://docs.mapbox.com/mapbox-gl-js/assets/us_states.geojson'
});
map.addLayer({
'id': 'state-fills',
==>>'type': 'fill',
==>>'source': 'states',
'layout': {},
'paint': {
'fill-color': '#627BC1',
'fill-opacity': [
'case',
['boolean', ['feature-state', 'hover'], false],
1,
0.5
]
}
});
map.addLayer({
'id': 'state-borders',
==>>'type': 'line',
==>>'source': 'states',
'layout': {},
'paint': {
'line-color': '#627BC1',
'line-width': 2
}
});
Below you will find a complete example I've put together from findings at https://docs.mapbox.com/ and other places on the internet.
Please note that this uses Mapbox example token and http://geojson.xyz/ directly, you should download the data and host it yourself if used in an production environment.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Display a map on a webpage</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<link href="https://api.mapbox.com/mapbox-gl-js/v2.6.1/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v2.6.1/mapbox-gl.js"></script>
<style>
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
</style>
</head>
<body>
<div id="map"></div>
<script>
mapboxgl.accessToken = 'pk.eyJ1Ijoid2l0dHJ1cCIsImEiOiJjbDc1NnFpaWIwYzZqM3VudGptdjUzNWZ1In0.R5FpTsM0CeaxLhq8i8Qmyg';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: [-74.5, 40], // starting position [lng, lat]
zoom: 0.31741259330687854
});
map.on('load', function () {
map.addSource('cbs', { // country-boundaries-simplified
'type': 'geojson',
'data': 'https://d2ad6b4ur7yvpq.cloudfront.net/naturalearth-3.3.0/ne_50m_admin_0_countries.geojson'
});
map.addLayer({
"id": "cf", // country-fills
"type": "fill",
"source": "cbs",
"layout": {},
"paint": {
"fill-color": "#627BC1",
"fill-opacity": 0.5
}
});
map.addLayer({
"id": "cb", // country borders
"type": "line",
"source": "cbs",
"layout": {},
"paint": {
"line-color": "#627BC1",
"line-width": 2
}
});
map.addLayer({
"id": "cfh", // country-fills-hover",
"type": "fill",
"source": "cbs",
"layout": {},
"paint": {
"fill-color": "#FFFFFF",
"fill-opacity": 1
},
"filter": ["==", "name", ""]
});
// When the user moves their mouse over the page, we look for features
// at the mouse position (e.point) and within the states layer (states-fill).
// If a feature is found, then we'll update the filter in the state-fills-hover
// layer to only show that state, thus making a hover effect.
map.on("mousemove", function(e) {
var features = map.queryRenderedFeatures(e.point, { layers: ["cf"] });
if (features.length) {
map.getCanvas().style.cursor = 'pointer';
map.setFilter("cfh", ["==", "name", features[0].properties.name]);
} else {
map.setFilter("cfh", ["==", "name", ""]);
map.getCanvas().style.cursor = '';
}
});
// Reset the state-fills-hover layer's filter when the mouse leaves the map
map.on("mouseout", function() {
map.getCanvas().style.cursor = 'auto';
map.setFilter("cfh", ["==", "name", ""]);
});
map.on("click", function(e) {
var features = map.queryRenderedFeatures(e.point, { layers: ["cf"] });
if (features.length) {
console.log(e, features[0].properties.name);
}
});
});
</script>
</body>
</html>

GeoJSON MultiPoint not showing on map

var feature = {
"type": "feature",
"properties": {
"style": {
"color": "#004070",
"weight": 4,
"opacity": 1
}
},
"geometry": {
"type": "MultiPoint",
"coordinates": [[
[0.25, 51.47],
[0.26, 51.47],
[0.27, 51.47]
]]
}
};
var geojsonLayer = new L.GeoJSON(feature);
map.addLayer(geojsonLayer);
I am trying to show the above three points on my map. Why are the markers not appearing?
Make sure your GeoJSON data is compliant as per the spec. You have online linting tools available, e.g. http://geojsonlint.com/ and http://geojson.io/
In your case:
"Feature" type must be capitalized.
"coordinates" for a "MultiPoint" geometry type must be an array of positions / coordinates. But you have an array of array of coordinates. (one extra level)
Once these 2 mistakes are corrected, everything works:
var map = L.map('map');
var feature = {
"type": "Feature",
"properties": {
"style": {
"color": "#004070",
"weight": 4,
"opacity": 1
}
},
"geometry": {
"type": "MultiPoint",
"coordinates": [
[0.25, 51.47],
[0.26, 51.47],
[0.27, 51.47]
]
}
};
var geojsonLayer = new L.GeoJSON(feature);
map.addLayer(geojsonLayer).fitBounds(geojsonLayer.getBounds());
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet#1.3.1/dist/leaflet-src.js" integrity="sha512-IkGU/uDhB9u9F8k+2OsA6XXoowIhOuQL1NTgNZHY1nkURnqEGlDZq3GsfmdJdKFe1k1zOc6YU2K7qY+hF9AodA==" crossorigin=""></script>
<div id="map" style="height: 180px"></div>

Issue with nested functions eachlayer and onEach feature of leaflet with geoson objects

I am practicing Leaflet to create maps.
In order to find the min value of a set of features I wish to browse the layers of a group layer with the function "eachLayer" then browse the features with the function "onEachFeature".
I think I have a problem with the scope of the variables.
My code is:
<!DOCTYPE html>
<html>
<head>
<title>Layers Control Tutorial - Leaflet</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin=""/>
<script src="https://unpkg.com/leaflet#1.3.1/dist/leaflet.js" integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw==" crossorigin=""></script>
<style>
html, body { height: 100%;margin: 0; }
#map { width: 100%; height: 100%;}
</style>
<!-- jQuery - indispensable pour utiliser les fichiers geojson -->
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<!-- Fichier(s) contenant les couches -->
<!-- <script src="troncons.geojson" type="text/javascript"></script> -->
</head>
<body>
<div id='map'></div>
<button id="button1">Station variable1</button>
<button id="button2">Station variable2</button>
<button id="button3">Troncons variable3</button>
<script>
// define the layers groups:
var stationsWait = L.layerGroup();
var GroupLayerTroncons = L.layerGroup();
// Load some stations
var Vincennes = L.circle([48.8473,2.43318], { color: 'red',fillColor: '#f03',fillOpacity: 0.5, radius: 750 }).bindPopup("Choisissez une variable").addTo(stationsWait);
var Nation = L.circle([48.8487,2.39626], { color: 'red',fillColor: '#f03', fillOpacity: 0.5,radius: 750 }).bindPopup("Choisissez une variable").addTo(stationsWait);
// Load some sections of the RERA:
var sections_RERA = {
"type": "FeatureCollection",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "id": 1 , "flow": 500 }, "geometry": { "type": "LineString", "coordinates": [ [ 2.22241227492659, 48.897131251501115 ], [ 2.237644924286148, 48.892430179977538 ] ] } },
{ "type": "Feature", "properties": { "id": 2 , "flow": 400 }, "geometry": { "type": "LineString", "coordinates": [ [ 2.237796534409823, 48.892431145089262 ], [ 2.277988160372222, 48.88068267218889 ], [ 2.291233854345376, 48.87646267502052 ], [ 2.295956684874181, 48.874690897366008 ] ] } },
{ "type": "Feature", "properties": { "id": 3 , "flow": 300 }, "geometry": { "type": "LineString", "coordinates": [ [ 2.295958036238904, 48.874590924832241 ], [ 2.308533488711002, 48.874964167617904 ], [ 2.315348461217771, 48.875403260408021 ], [ 2.329165082403959, 48.873581863436044 ], [ 2.330553508046893, 48.871690011018686 ], [ 2.330553508046893, 48.871690011018686 ] ] } },
{ "type": "Feature", "properties": { "id": 4 , "flow": 200}, "geometry": { "type": "LineString", "coordinates": [ [ 2.330554792932899, 48.871590037832199 ], [ 2.34106115320042, 48.867749099632711 ], [ 2.344584312147049, 48.864769023056539 ], [ 2.347801519250009, 48.861987132117697 ] ] } },
{ "type": "Feature", "properties": { "id": 5 , "flow": 100 }, "geometry": { "type": "LineString", "coordinates": [ [ 2.347801519250009, 48.861987132117697 ], [ 2.349954033166742, 48.859499314657278 ], [ 2.357872312519592, 48.856342662783582 ], [ 2.373020720593452, 48.844025242488712 ] ] } },
{ "type": "Feature", "properties": { "id": 6 , "flow": 500}, "geometry": { "type": "LineString", "coordinates": [ [ 2.373020720593452, 48.844025242488712 ], [ 2.375307175290527, 48.842837414357263 ], [ 2.378035989383918, 48.842651667917124 ], [ 2.379696184575886, 48.843160200223871 ], [ 2.384654536154551, 48.846585203162263 ], [ 2.38585340994371, 48.847691165562274 ], [ 2.390073858038943, 48.849512428852194 ], [ 2.397050398888572, 48.848847918381693 ] ] } },
{ "type": "Feature", "properties": { "id": 7, "flow": 250 }, "geometry": { "type": "LineString", "coordinates": [ [ 2.397050398888572, 48.848847918381693 ], [ 2.40254859872989, 48.844976207608681 ], [ 2.417864326491966, 48.843551984219573 ], [ 2.423292942257146, 48.845777878447315 ], [ 2.428427826130349, 48.847202264244189 ], [ 2.434335613031259, 48.847230342470212 ] ] } }
]
}
var sections_others = [{
"type": "Feature",
"properties": {
"id": 12,
"name": "Autres-Autres",
"flow": 500,
"popupContent": "Texte à changer",
"popupContent2": "Text de la nouvelle variable"
},
"geometry": {
"type": "LineString",
"coordinates": [ [2.373068996549787 , 48.844124177694574],[2.373068176412221 , 48.844124882353711]]
}
}
]
function onEachFeature(feature, layer) {
if (feature.properties && feature.properties.popupContent) {
layer.bindPopup(feature.properties.popupContent);
}
//console.log ( "The id of the feature is " + feature.properties.id)
}
function style (feature){// paramétrage de la symbologie de la couche "arrondissement"
//return { color: "#046380", weight: 1, fillColor: '#4BB5C1', fillOpacity: .5 };
}
L.geoJson(sections_RERA, { onEachFeature: onEachFeature, style: style }).addTo(GroupLayerTroncons);
sections_RERA.id = 10;
console.log(sections_RERA.id )
// Load sections of an other dummy lines:
function style2 (feature){// paramétrage de la symbologie de la couche "arrondissement"
return { color: "red", weight: 5, fillColor: '#4BB5C1', fillOpacity: .5 };
}
L.geoJson(sections_others, { onEachFeature: onEachFeature, style: style2 }).addTo(GroupLayerTroncons);
sections_others.id = 11;
console.log(sections_others.id )
// Load the map
var mbAttr = 'Map data © OpenStreetMap contributors, ' +
'CC-BY-SA, ' +
'Imagery © Mapbox',
mbUrl = 'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw';
var grayscale = L.tileLayer(mbUrl, {id: 'mapbox.light', attribution: mbAttr}),
streets = L.tileLayer(mbUrl, {id: 'mapbox.streets', attribution: mbAttr});
var map = L.map('map', {
center: [48.8666, 2.333],
zoom: 13,
layers: [streets, GroupLayerTroncons, stationsWait]
});
var baseLayers = {"Grayscale": grayscale,"Streets": streets};
var overlays = { "Waiting Times": stationsWait,"Troncons" : GroupLayerTroncons};
L.control.layers(baseLayers, overlays).addTo(map);
//Objectif: Find the min value in a group layer according a given property
function onEachFeature2(feature, layer) {
if (feature.properties && feature.properties.flow) {
console.log ( "The value of the feature property is " + feature.properties.flow); // later we use the OneProperty variable
}
}
// Body of the GetMin function
function GetMin(GroupLayer, OneProperty){
GroupLayer.eachLayer(function (OneLayer) {
L.geoJson(OneLayer, { // it's work whith sections_RERA instead of OneLayer
onEachFeature: onEachFeature2
// onEachFeature : function onEachFeature3 (feature, layer) { console.log( feature.properties.flow); layer.bindPopup("feature.properties.flow"); }
})
console.log ( "theoretically we change layer----");
})};
// Call of the function
var OneProperty = "Flow";
GetMin(GroupLayerTroncons, OneProperty);
</script>
</body>
</html>
The web console return:
Error: Invalid GeoJSON object.
But, it works when I replace the local variable "OneLayer" by the global variables "sections_RERA" or "sections_others". (line 135)
"OneLayer" and "sections_RERA", is it the same type of object?
Leaflet's L.geoJSON factory takes a raw GeoJSON data object (like your sections_RERA variable) as first parameter, not a Leaflet already built layer (like the child layers of your GroupLayerTroncons variable that are looped through in your GetMin function).
It is unclear what you are trying to achieve. If you just want to read the original GeoJSON data from your layers, do so directly in your eachLayer callback. The properties are available on each layer as layer.feature.properties:
var groupLayer = L.layerGroup();
// Nesting a Leaflet GeoJSON Layer Group into groupLayer Layer Group.
var geoJsonGroupLayer = L.geoJSON(geoJsonRawData, options).addTo(groupLayer);
groupLayer.eachLayer(inspectLayer);
function inspectLayer(layer) {
if (layer.feature && layer.feature.properties) {
// layer is a non-group, built from GeoJSON data.
// inspect the layer...
} else if (layer instanceof L.LayerGroup) {
// layer is a nested Layer Group.
// Recursive call to inspectLayer function.
layer.eachLayer(inspectLayer);
}
}

highlighting polyline features in mapbox-gl.js

I am trying to use the following code to highlight features under the mouse pointer.
The difference between my geojson data and the geojson data used in the linked example is that the example is made up of polygons whereas my geojson is made up of polylines. I have tried to modify the code accordingly in order that lines are highlighted however it does not work.
My geojson is accessible here:
http://iskandarblue.github.io/mapbox/data/prototype2.geojson
Any advice on what needs to be changed?
Example:
https://www.mapbox.com/mapbox-gl-js/example/hover-styles/
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>HTML markers from geoJSON url</title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.15.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.15.0/mapbox-gl.css' rel='stylesheet'/>
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<div id='map'></div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoiaXNrYW5kYXJibHVlIiwiYSI6ImNpbHIxMXA3ejAwNWl2Zmx5aXl2MzRhbG4ifQ.qsQjbbm1A71QzVg8OcR7rQ';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v8',
center: [37.625224, 55.744537,],
zoom: 13
});
map.on('style.load', function () {
map.addSource("streets", {
"type": "geojson",
"data": "http://iskandarblue.github.io/mapbox/data/prototype2.geojson"
});
map.addLayer({
"id": "m_streets",
"type": "line",
"source": "streets",
"interactive": true,
"layout": {},
"paint": {
"line-color": "#627BC1",
"line-width": 2.5
}
});
map.addLayer({
"id": "route-hover",
"type": "line",
"source": "streets",
"layout": {},
"paint": {
"line-color": "#627BC1",
"line-width": 2.5
},
"filter": ["==", "rd_name", ""]
});
// When the user moves their mouse over the page, we look for features
// at the mouse position (e.point) and within the states layer (states-fill).
// If a feature is found, then we'll update the filter in the route-hover
// layer to only show that state, thus making a hover effect.
map.on("mousemove", function(e) {
map.featuresAt(e.point, {
radius: 5,
layer: ["m_streets"]
}, function (err, features) {
if (!err && features.length) {
map.setFilter("route-hover", ["==", "rd_name", features[0].properties.rd_name]);
} else {
map.setFilter("route-hover", ["==", "rd_name", ""]);
}
});
});
});
//.addTo(map);
</script>
</body>
</html>
The route-hover layer just needs to be styled differently right? Here's a live example of your code above with a slight adjustment: https://jsbin.com/loxoquwiye/