GeoJSON MultiPoint not showing on map - leaflet

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>

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>

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);
}
}

JSONP - Using to access data website in conjuction with leaflet

I am having trouble getting jsonp to work for a data serving website. Below is my script that will plot data points on a leaflet map as long as they are in the same domain. I need to take it a step further by using jsonp. I am having trouble understanding jsonp tutorials, especially with understanding how to deal with the response of the json file. This is my first time trying to use this method, and I have not be successful as I still don't fully understand js/html that well. Any help would be great as I think I am just a few lines of code from being able to get this to work properly. Thanks.
<html>
<head>
<meta charset="utf-8"/>
<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>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<style>
#map{ width: 1000px; height: 600px; }
</style>
</head>
<body>
<div id="map"></div>
<script>
var map = L.map('map',{center: [35, -121],zoom: 7});
var myStyle = {"color": "#ff7800", "weight": 5, "opacity": 0.65};
L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer/tile/{z}/{y}/{x}', {attribution: 'Tiles © Esri — Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri'}).addTo(map);
$.getJSON("http://localhost:8000/erdCalCOFIcufes.geojson", function(data) {
L.geoJson(data, {
style: myStyle
}).addTo(map);
})
</script>
</body>
</html>
Note that it is hosted locally as detailed below. The website I need to use is here...
https://coastwatch.pfeg.noaa.gov/erddap/tabledap/erdCalCOFIcufes.geoJson?longitude,latitude,sardine_eggs&cruise=%22201504%22&sardine_eggs%3E=0&.draw=markers&.marker=5%7C5&.color=0x000000&.colorBar=%7C%7C%7C%7C%7C&.bgColor=0xffccccff
Here is what is looks like without a proper jsonp to grab data to plot. Currently, I have been able to grab the data by hosting the scripts in the same domain as the geojson file using the following...
python -m SimpleHTTPServer
This was more for proof of concept and wont fit my needs.
<html>
<head>
<meta charset="utf-8"/>
<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>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<style>
#map{ width: 1000px; height: 600px; }
</style>
</head>
<body>
<div id="map"></div>
<script>
var map = L.map('map',{center: [35, -121],zoom: 7});
var myStyle = {"color": "#ff7800", "weight": 5, "opacity": 0.65};
L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer/tile/{z}/{y}/{x}', {attribution: 'Tiles © Esri — Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri'}).addTo(map);
$.getJSON("http://localhost:8000/erdCalCOFIcufes.geojson", function(data) {
L.geoJson(data, {
style: myStyle
}).addTo(map);
})
</script>
</body>
</html>
The geojson file looks like the following. I cut out a lot of points to make it more digestible.
{
"type": "FeatureCollection",
"propertyNames": ["sardine_eggs"],
"propertyUnits": ["count"],
"features": [
{"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-123.3226, 38.1476] },
"properties": {
"sardine_eggs": 0 }
},
{"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-123.3527, 38.1785] },
"properties": {
"sardine_eggs": 1 }
},
{"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-123.369, 38.238] },
"properties": {
"sardine_eggs": 0 }
},
{"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-117.3725, 32.6873] },
"properties": {
"sardine_eggs": 0 }
},
{"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-117.2973, 32.6538] },
"properties": {
"sardine_eggs": 0 }
}
],
"bbox": [-126.5296, 29.8483, -117.2931, 43.7501]
}

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

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
}
},
});

addingand using marker variable with geoJsonData and markercluster with leaflet.js

I've been searching for hours and hours now, and i'm still stuck. I have a feeling it is something easy/stupid i'm missing.
I am using the example of markercluster from GitHub. I have 2 different markers (simply 2 different colors) that i would like to show which i would defined in the json format.
I have followed guide from leaflet site to define different markers.
I added my variable to the json part, but i can not figure out how to make the map load the different markers. It's either giving me no map or error; or it still uses the default blue marker.
here is my code:
<script type="text/javascript">
var geoJsonData = {
"type": "FeatureCollection",
"features": [
{ "type": "Feature", "id":"1", "properties": { "address": "2","marker": "cmIcon"}, "geometry": { "type": "Point", "coordinates": [175.2209316333,-37.8210922667 ] } },
{ "type": "Feature", "id":"2", "properties": { "address": "151","marker": "otherIcon" }, "geometry": { "type": "Point", "coordinates": [175.2238417833,-37.80975435 ] } },
{ "type": "Feature", "id":"3", "properties": { "address": "21","marker": "cmIcon" }, "geometry": { "type": "Point", "coordinates": [175.2169955667,-37.818193 ] } },
{ "type": "Feature", "id":"4", "properties": { "address": "14","marker": "otherIcon" }, "geometry": { "type": "Point", "coordinates": [175.2240856667,-37.8216963 ] } },
{ "type": "Feature", "id":"5", "properties": { "address": "38B","marker": "cmIcon" }, "geometry": { "type": "Point", "coordinates": [175.2196982333,-37.8188702167 ] } },
{ "type": "Feature", "id":"6", "properties": { "address": "38","marker": "otherIcon" }, "geometry": { "type": "Point", "coordinates": [175.2209942 ,-37.8192782833 ] } }
]
};
var cloudmade = L.tileLayer('http://{s}.tile.cloudmade.com/{key}/997/256/{z}/{x}/{y}.png', {
maxZoom: 18,
attribution: 'Map data © 2011 OpenStreetMap contributors, Imagery © 2011 CloudMade',
key: 'BC9A493B41014CAABB98F0471D759707'
});
var LeafIcon = L.Icon.extend({
options: {
shadowUrl: 'marker/marker-shadow.png',
iconSize: [32, 32],
shadowSize: [36, 20],
iconAnchor: [22, 94],
shadowAnchor: [4, 62],
popupAnchor: [-3, -76]
}
});
var cmIcon = new LeafIcon({iconUrl: 'marker/marker-cm.png'}),
otherIcon = new LeafIcon({iconUrl: 'marker/marker-others.png'});
var map = L.map('map')
.addLayer(cloudmade);
var markers = new L.MarkerClusterGroup();
var geoJsonLayer = L.geoJson(geoJsonData, {
onEachFeature: function (feature, layer) {
layer.bindPopup(feature.properties.address);
}
});
markers.addLayer(geoJsonLayer);
map.addLayer(markers);
map.fitBounds(markers.getBounds());
function onLocationFound(e) {
var radius = e.accuracy / 2;
L.marker(e.latlng).addTo(map)
.bindPopup("Vous etes ici").openPopup();
L.circle(e.latlng, radius).addTo(map);
}
function onLocationError(e) {
alert(e.message);
}
map.on('locationfound', onLocationFound);
map.on('locationerror', onLocationError);
map.locate({setView: true, maxZoom: 16});
</script>
I suspect that i need to tell leaflet to get the marker variable, probably in
var geoJsonLayer = L.geoJson(geoJsonData, {
onEachFeature: function (feature, layer) {
layer.bindPopup(feature.properties.address);
}
});
but i cannot make it work.
i even tried as suggested some where else:
var geoJsonLayer = L.geoJson(geoJsonData, {
onEachFeature: function (feature, layer) {
layer.bindPopup(feature.properties.address),
layer.setIcon(feature.properties.marker);
}
});
i'm still getting an error: Uncaught TypeError: Object cmIcon has no method 'createIcon'
does anybody have an idea on how to do that?
Any help would be greatly appreciated.
Thank you in advance.
You need to tell the MarkerClusterGroup how to create the icon. The marker cluster docs show an example with a DivIcon like this:
var markers = new L.MarkerClusterGroup({
iconCreateFunction: function(cluster) {
return new L.DivIcon({ html: '<b>' + cluster.getChildCount() + '</b>' });
}
});
You can use your custom icon instead like this:
var markers = new L.MarkerClusterGroup({
iconCreateFunction: function(cluster) {
// decide which icon you want to use
return (cluster.getChildCount() > 10) ? cmIcon : otherIcon;
}
});