I want to edit polygon which i have added using map.addLayer() on mapbox.
the code:
map.addLayer({
'id': 'maine'+id,
'type': 'fill',
'source': {
'type': 'geojson',
'data': {
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': coords
}
}
},
'layout': {},
'paint': {
'fill-color': '#088',
'fill-opacity': 0.8
}
});
Mapbox GL Drawing Library is used to draw/edit the shapes.
You have added the polygon as a map layer. Editing the layer in drawing mode directly seems not possible. Here is a possible way
You need to hide the layer first.
Get the Polygon data from layer source
Init the drawing mode and add a new polygon to drawing manager with the polygon data
Once the editing finished, update the layer source with the edited polygon data from drawing manager
Remove the polygon from the drawing manager
Show the updated layer
You need to use the add method to draw an existing shape.
draw.add({
'id': 'polygon-3355',
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'Polygon',
'coordinates': [[[-67.13734351262877, 45.137451890638886],
[-66.96466, 44.8097],
[-68.03252, 44.3252],
[-69.06, 43.98],
[-70.11617, 43.68405],
[-70.64573401557249, 43.090083319667144],
[-70.75102474636725, 43.08003225358635],
[-70.79761105007827, 43.21973948828747],
[-70.98176001655037, 43.36789581966826],
[-70.94416541205806, 43.46633942318431],
[-71.08482, 45.3052400000002],
[-70.6600225491012, 45.46022288673396],
[-70.30495378282376, 45.914794623389355],
[-70.00014034695016, 46.69317088478567],
[-69.23708614772835, 47.44777598732787],
[-68.90478084987546, 47.184794623394396],
[-68.23430497910454, 47.35462921812177],
[-67.79035274928509, 47.066248887716995],
[-67.79141211614706, 45.702585354182816],
[-67.13734351262877, 45.137451890638886]]]
}
});
Library Link:
https://github.com/mapbox/mapbox-gl-draw
API Methods Reference:
https://github.com/mapbox/mapbox-gl-draw/blob/master/docs/API.md
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title>Show drawn polygon area</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.50.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.css' rel='stylesheet' />
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<style>
.calculation-box {
height: 75px;
width: 150px;
position: absolute;
bottom: 40px;
left: 10px;
background-color: rgba(255, 255, 255, .9);
padding: 15px;
text-align: center;
}
p {
font-family: 'Open Sans';
margin: 0;
font-size: 13px;
}
</style>
<script src='https://api.tiles.mapbox.com/mapbox.js/plugins/turf/v3.0.11/turf.min.js'></script>
<script src='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.0.9/mapbox-gl-draw.js'></script>
<link rel='stylesheet' href='https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.0.9/mapbox-gl-draw.css' type='text/css'/>
<div id='map'></div>
<div class='calculation-box'>
<p>Draw a polygon using the draw tools.</p>
<div id='calculated-area'></div>
</div>
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoiZWRlbnJheWdhcmRuZXIiLCJhIjoiRlZRVlhqOCJ9.tDrWaeNRbMCtXAovQLYuzA';
/* eslint-disable */
var map = new mapboxgl.Map({
container: 'map', // container id
style: 'mapbox://styles/mapbox/streets-v8',
center: [-70.11617, 43.68405],
zoom: 5
});
var draw = new MapboxDraw({
displayControlsDefault: false,
controls: {
polygon: true,
trash: true
}
});
map.addControl(draw);
map.on('draw.create', updateArea);
map.on('draw.delete', updateArea);
map.on('draw.update', updateArea);
draw.add({
'id': 'polygon-3355',
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'Polygon',
'coordinates': [[[-67.13734351262877, 45.137451890638886],
[-66.96466, 44.8097],
[-68.03252, 44.3252],
[-69.06, 43.98],
[-70.11617, 43.68405],
[-70.64573401557249, 43.090083319667144],
[-70.75102474636725, 43.08003225358635],
[-70.79761105007827, 43.21973948828747],
[-70.98176001655037, 43.36789581966826],
[-70.94416541205806, 43.46633942318431],
[-71.08482, 45.3052400000002],
[-70.6600225491012, 45.46022288673396],
[-70.30495378282376, 45.914794623389355],
[-70.00014034695016, 46.69317088478567],
[-69.23708614772835, 47.44777598732787],
[-68.90478084987546, 47.184794623394396],
[-68.23430497910454, 47.35462921812177],
[-67.79035274928509, 47.066248887716995],
[-67.79141211614706, 45.702585354182816],
[-67.13734351262877, 45.137451890638886]]]
}
});
function updateArea(e) {
var data = draw.getAll();
var answer = document.getElementById('calculated-area');
if (data.features.length > 0) {
var area = turf.area(data);
// restrict to area to 2 decimal points
var rounded_area = Math.round(area*100)/100;
answer.innerHTML = '<p><strong>' + rounded_area + '</strong></p><p>square meters</p>';
} else {
answer.innerHTML = '';
if (e.type !== 'draw.delete') alert("Use the draw tools to draw a polygon!");
}
}
</script>
</body>
</html>
Related
This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
Closed 12 months ago.
Here I cannot change the long and lat values in the constructor in the setcurrentposition function. When I call this in this function, it returns undefined. How can I change the values in the constructor within that function? When I want to set lan long values in the constructor in my showPosition method, this method does not show the constructor. How can I set this? When I press this to console it comes undefined
const geojson = {
'type': 'FeatureCollection',
'features': [{
'type': 'Feature',
'properties': {
'message': 'Foo',
'iconSize': [60, 60]
},
'geometry': {
'type': 'Point',
'coordinates': [-66.324462, -16.024695]
}
},
{
'type': 'Feature',
'properties': {
'message': 'Bar',
'iconSize': [50, 50]
},
'geometry': {
'type': 'Point',
'coordinates': [-61.21582, -15.971891]
}
},
{
'type': 'Feature',
'properties': {
'message': 'Baz',
'iconSize': [40, 40]
},
'geometry': {
'type': 'Point',
'coordinates': [-63.292236, -18.281518]
}
}
]
};
class MapboxClass {
constructor({
token = token,
long = long,
lat = lat,
mapCanvas = mapCanvas,
mapStyle = mapStyle,
geojson = geojson,
} = {}) {
this.mapCanvas = mapCanvas
this.token = token;
this.long = long;
this.lat = lat;
this.geojson = geojson
this.mapStyle = mapStyle
}
currentLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(this.setCurrentPosition, this.showError)
}
}
setCurrentPosition(position) {
this.lat = position.coords.latitude;
this.long = position.coords.longitude;
}
showError(error) {
switch (error.code) {
case error.PERMISSION_DENIED:
x.innerHTML = "User denied the request for Geolocation."
break;
case error.POSITION_UNAVAILABLE:
x.innerHTML = "Location information is unavailable."
break;
case error.TIMEOUT:
x.innerHTML = "The request to get user location timed out."
break;
case error.UNKNOWN_ERROR:
x.innerHTML = "An unknown error occurred."
break;
}
}
// Method
createMap() {
mapboxgl.accessToken = this.token
const mapCanvas = new mapboxgl.Map({
container: 'map',
style: this.mapStyle,
center: [27.144623192174567, 38.428404055417225],
zoom: 6
});
this.mapCanvas = mapCanvas
}
addMarkersToMap() {
for (const marker of this.geojson.features) {
// Create a DOM element for each marker.
const el = document.createElement('div');
const width = marker.properties.iconSize[0];
const height = marker.properties.iconSize[1];
el.className = 'marker';
el.style.backgroundImage = `url(https://placekitten.com/g/${width}/${height}/)`;
el.style.width = `${width}px`;
el.style.height = `${height}px`;
el.style.backgroundSize = 'cover';
el.style.backgroundPosition = 'center';
// Add markers to the map.
new mapboxgl.Marker(el)
.setLngLat(marker.geometry.coordinates)
.addTo(this.mapCanvas);
el.addEventListener('click', () => {
window.alert(marker.properties.message);
});
}
}
}
const mapp = new MapboxClass({
token: "pk.eyJ1IjoiemdubXVzdGFmYSIsImEiOiJja2ZmZzF1ZzgwZWhxMnlvM2V4cWh0c3ZrIn0.5U4S5f2PwICD0MainYx_OQ",
mapStyle: 'mapbox://styles/mapbox/streets-v11',
mapCanvas: '',
lat: 'x',
long: 'x',
geojson: {
'features': [{
'type': 'Feature',
'properties': {
'message': 'Foo',
'iconSize': [60, 60]
},
'geometry': {
'type': 'Point',
'coordinates': [27.13652687626378, 38.41263764981549]
}
},
{
'type': 'Feature',
'properties': {
'message': 'Bar',
'iconSize': [50, 50]
},
'geometry': {
'type': 'Point',
'coordinates': [27.13652687626378, 39.41263764981549]
}
},
{
'type': 'Feature',
'properties': {
'message': 'Baz',
'iconSize': [40, 40]
},
'geometry': {
'type': 'Point',
'coordinates': [29.13652687626378, 38.41263764981549]
}
}
]
}
});
mapp.createMap();
mapp.addMarkersToMap();
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
.marker {
display: block;
border: none;
border-radius: 50%;
cursor: pointer;
padding: 0;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Add custom icons with Markers</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<link href="https://api.mapbox.com/mapbox-gl-js/v2.7.0/mapbox-gl.css" rel="stylesheet">
<script src="https://api.mapbox.com/mapbox-gl-js/v2.7.0/mapbox-gl.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<style>
.marker {
display: block;
border: none;
border-radius: 50%;
cursor: pointer;
padding: 0;
}
</style>
<div id="map"></div>
<div id="demo"></div>
</body>
</html>
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I'm working on this Mapbox map, and shows features using geojson/FeatureCollection (basically something like this).
If you zoom all the way out, the map will show multiple world copies (which I want), but it will also show each feature on ALL world copies (don't want this!). What should I do so that the mapbox only displays the features on ONE of the world copies?
The example linked above also has the same issue (as you can see in the image below).
Sample code showcasing the issue
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Add multiple geometries from one GeoJSON source</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<script src="https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.12.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.eyJ1Ijoic2h1YmhhbW1laHJhIiwiYSI6ImNqempxZWNqeDBicnMzbnFpaTZ6amVmYjQifQ.US2y0mYyWtRABvxzfpBWrw';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/outdoors-v11',
center: [-121.403732, 40.492392],
zoom: 10
});
map.on('load', function () {
map.addSource('national-park', {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': [
{
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': [
[
[-121.353637, 40.584978],
[-121.284551, 40.584758],
[-121.275349, 40.541646],
[-121.246768, 40.541017],
[-121.251343, 40.423383],
[-121.32687, 40.423768],
[-121.360619, 40.43479],
[-121.363694, 40.409124],
[-121.439713, 40.409197],
[-121.439711, 40.423791],
[-121.572133, 40.423548],
[-121.577415, 40.550766],
[-121.539486, 40.558107],
[-121.520284, 40.572459],
[-121.487219, 40.550822],
[-121.446951, 40.56319],
[-121.370644, 40.563267],
[-121.353637, 40.584978]
]
]
}
},
{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [-121.415061, 40.506229]
}
},
{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [-121.505184, 40.488084]
}
},
{
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [-121.354465, 40.488737]
}
}
]
}
});
map.addLayer({
'id': 'park-boundary',
'type': 'fill',
'source': 'national-park',
'paint': {
'fill-color': '#888888',
'fill-opacity': 0.4
},
'filter': ['==', '$type', 'Polygon']
});
map.addLayer({
'id': 'park-volcanoes',
'type': 'circle',
'source': 'national-park',
'paint': {
'circle-radius': 6,
'circle-color': '#B42222'
},
'filter': ['==', '$type', 'Point']
});
});
</script>
</body>
</html>
I don't think this is possible. Geographically, what you're asking for doesn't really make sense. Your point has the same location as the map tile underneath it, so to have the basemap display but not your point, on the basis of the user having effectively rotated the map is...weird.
Your best workaround would be to use a Marker rather than a symbol layer. Each Marker is a single DOM element so only ever displayed once.
my problem is that I have some markers that needs to toggle when I click on the button, How can I add the id and the visiblity property to these markers ? I tried adding the id directly to the markers but that didn't work and also I don't know how to add the "visibility" to the markers geojson (only for the mapboxmarker the other one is just for some testig there)
Here is the code and the js fiddle link https://jsfiddle.net/foyb96zq/
HTML
<script src="https://api.mapbox.com/mapbox-gl-js/v1.11.0/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.11.0/mapbox-gl.css" rel="stylesheet" />
<script src="https://kit.fontawesome.com/7134867017.js" crossorigin="anonymous"></script>
<div id="menu">
</div>
<div id="map"></div>
CSS
body { margin: 0; padding: 0; }
#map { position: absolute; top: 0; bottom: 0; width: 100%; }
.marker {
background-image: url('https://f.hubspotusercontent20.net/hubfs/6957522/mapbox-icon.png');
background-size: cover;
width: 50px;
height: 50px;
cursor: pointer;
}
#menu {
background: #773dbd;
position: absolute;
z-index: 1;
top: 50px;
right: 10px;
margin-bottom: 5%;
border-radius: 3px;
width: 120px;
border: 1px solid rgba(0, 0, 0, 0.4);
font-family: 'Open Sans', sans-serif;
}
#menu a {
font-size: 13px;
color: #ffffff;
display: block;
margin: 0;
padding: 0;
padding: 10px;
text-decoration: none;
border-bottom: 1px solid rgba(0, 0, 0, 0.25);
text-align: center;
}
#menu a:last-child {
border: none;
}
#menu a:hover {
background-color: #966acc;
color: #ffffff;
}
#menu a.active {
background-color: #773dbd;
color: #ffffff;
}
#menu a.active:hover {
background: #966acc;
}
.clicked {
text-align: right !important;
}
.clicked::before {
content:"\f058";
font-family: "Font Awesome 5 Free";
font-style: normal;
font-weight: normal;
text-decoration: inherit;
/*--adjust as necessary--*/
color: #ffffff;
font-size: 18px;
padding-right: 0.5em;
position: absolute;
top:9px;
left:10px;
}
JS
mapboxgl.accessToken = 'pk.eyJ1IjoiYW5kcnJlIiwiYSI6ImNrYndjMm0yZzBjMHIyeW1zN3EyNWY4ODcifQ.G4ThulNR7Vi_u6zrdJ5V1w';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/andrre/ckbwd976y10g91iqmo7s17jcz',
center: [-41.014594, 38.320168],
zoom: 3
});
var geojson = {
type: 'FeatureCollection',
features: [{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [
-73.985148,
40.732454
]
},
properties: {
title: 'New York',
description: 'undefined'
}
},
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [
-0.128754,
51.507662
]
},
properties: {
title: 'London',
description: 'undefined'
}
},
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [
2.352028,
48.857033
]
},
properties: {
title: 'Paris',
description: 'undefined'
}
}
]};
//
geojson.features.forEach(function(marker) {
// create a HTML element for each feature
var el = document.createElement('div');
el.className = 'marker';
new mapboxgl.Marker(el)
.setLngLat(marker.geometry.coordinates)
.setPopup(new mapboxgl.Popup({ offset: 25 }) // add popups
.setHTML('<h3>' + marker.properties.title + '</h3><p>' + marker.properties.description + '</p>'))
.addTo(map);
// make a marker for each feature and add to the map
new mapboxgl.Marker(el)
.setLngLat(marker.geometry.coordinates)
.addTo(map);
});
//code for toogle
//
// enumerate ids of the layers
var toggleableLayerIds = ['contours', 'museums'];
// set up the corresponding toggle button for each layer
for (var i = 0; i < toggleableLayerIds.length; i++) {
var id = toggleableLayerIds[i];
var link = document.createElement('a');
link.href = '#';
link.className = 'active';
link.textContent = id;
link.onclick = function(e) {
var clickedLayer = this.textContent;
e.preventDefault();
e.stopPropagation();
var visibility = map.getLayoutProperty(clickedLayer, 'visibility');
// toggle layer visibility by changing the layout object's visibility property
if (visibility === 'visible') {
map.setLayoutProperty(clickedLayer, 'visibility', 'none');
this.className = '';
} else {
this.className = 'active';
map.setLayoutProperty(clickedLayer, 'visibility', 'visible');
}
};
var layers = document.getElementById('menu');
layers.appendChild(link);
}
You need to add the markers as new feature layers, not just add them one-by-one in a for loop. The above code is erroring as you have not added any layers, and mapbox doesn't know how it is mean to group your markers.
See the docs here for info.
I found a way of doing it, here is the code if anyone wants to use it, this needs to be placed instead of geojson
map.on('load', function() {
// Add an image to use as a custom marker
map.loadImage(
'https://docs.mapbox.com/mapbox-gl-js/assets/custom_marker.png',
function(error, image) {
if (error) throw error;
map.addImage('custom-marker', image);
// Add a GeoJSON source with 2 points
map.addSource('points', {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': [
{
// feature for Mapbox DC
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [
-77.03238901390978,
38.913188059745586
]
},
'properties': {
'title': 'New York',
'description':'undefined'
}
},
{
// feature for Mapbox SF
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [-122.414, 37.776]
},
'properties': {
'title': 'Mapbox SF',
'description': 'description sf'
}
}
]
}
});
// Add a symbol layer
map.addLayer({
'id': 'points',
'type': 'symbol',
'source': 'points',
'layout': {
'icon-image': 'custom-marker',
// get the title name from the source's "title" property
}
});
}
);
});
map.on('click', 'points', function(e) {
var coordinates = e.features[0].geometry.coordinates.slice();
var description = e.features[0].properties.description;
var title = e.features[0].properties.title;
// Ensure that if the map is zoomed out such that multiple
// copies of the feature are visible, the popup appears
// over the copy being pointed to.
while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
}
new mapboxgl.Popup()
.setLngLat(coordinates)
.setHTML('<h3>' + title + '</h3><p>' + description + '</p>')
.addTo(map);
});
//code for toogle
//
// enumerate ids of the layers
var toggleableLayerIds = ['points', 'museums'];
// set up the corresponding toggle button for each layer
for (var i = 0; i < toggleableLayerIds.length; i++) {
var id = toggleableLayerIds[i];
var link = document.createElement('a');
link.href = '#';
link.className = 'active';
link.textContent = id;
link.onclick = function(e) {
var clickedLayer = this.textContent;
e.preventDefault();
e.stopPropagation();
var visibility = map.getLayoutProperty(clickedLayer, 'visibility');
// toggle layer visibility by changing the layout object's visibility property
if (visibility === 'visible') {
map.setLayoutProperty(clickedLayer, 'visibility', 'none');
this.className = '';
} else {
this.className = 'active';
map.setLayoutProperty(clickedLayer, 'visibility', 'visible');
}
};
var layers = document.getElementById('menu');
layers.appendChild(link);
}
I want to add 2 or 3 floors for each building using MapBox GL, but when i try using the addlayer, the colours are getting overriden but no layers or floors are added. Been stuck with this for some time now.
I want 3d extrusions of floors in a building.
Tried putting this into a button click as well, but still it is not returning expected results.
<!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.39.1/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.39.1/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.eyJ1IjoiZGFuc3dpY2siLCJhIjoiY2l1dTUzcmgxMDJ0djJ0b2VhY2sxNXBiMyJ9.25Qs4HNEkHubd4_Awbd8Og';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v9',
center: [-87.61694, 41.86625],
zoom: 15.99,
pitch: 40,
bearing: 20
});
map.on('load', function() {
map.addLayer({
'id': 'room-extrusion10',
'type': 'fill-extrusion',
'source': 'composite',
'source-layer': 'building',
'paint': {
'fill-extrusion-color': 'blue',
'fill-extrusion-height': {
'type': 'identity',
'property': 'height'
},
'fill-extrusion-base': {
'type': 'identity',
'property': 'max_height'
},
'fill-extrusion-opacity': 1
}
});
map.addLayer({
'id': 'room-extrusion11',
'type': 'fill-extrusion',
'source': 'composite',
'source-layer': 'building',
'paint': {
'fill-extrusion-color': 'red',
'fill-extrusion-height': {
'type': 'identity',
'property': 'height'
},
'fill-extrusion-base': {
'type': 'identity',
'property': 'min_height'
},
'fill-extrusion-opacity': 1
}
},'room-extrusion10');
});
</script>
</body>
</html>
fill-extrusion-height and fill-extrusion-base are the paint properties that control the lower and upper height (in meters) of a fill-extrusion feature. In your example these are styled with identity functions based on building height data from OpenStreetMap (in the Mapbox Streets data source), causing them to imitate real-world building shapes (as best as they are mapped). In order to create a fill-extrusion layer that spans only one floor you'd want fill-extrusion-height: 3 (or however tall, in meters, you perceive one story to be) and fill-extrusion-base: 0 for the first floor; the second would be height=6 and base=3, and so forth.
Note that in all released versions of Mapbox GL JS, multiple fill-extrusion layers don't render correctly with respect to each other. This is fixed in master and will be included in the next release this month.
I've countries GeoJson with a geometry of type polygon. Each polygon has only one property name (name is the country name). each polygon represents a country.
Now I want to paint each polygon with different color depending on the value of the name property, but this is not working properly.
See this JS bin Demo
map.on('load', function () {
map.addLayer({
'id': 'maine',
'type': 'fill',
'layout': {},
'paint': {
'fill-color': {
property: 'name',
stops: [
['Albania', '#F2F12D'],
['Algeria', '#7A4900'],
['Australia', '#63FFAC'],
["South Africa", "#4FC601"],
["South Korea", "#3B5DFF"],
]
},
'fill-opacity': 0.8
},
'source': {
'type': 'vector',
'url': 'mapbox://saurabhp.countries_tileset'
},
"source-layer": "countries",
});
});
Every thing in your code was perfect, the only thing which you have missed out is type: 'categorical' inside the fill-color, You need to specify the type
Checkout this link for more details run the below code snippet to see the demo
mapboxgl.accessToken = 'pk.eyJ1Ijoic2F1cmFiaHAiLCJhIjoiY2l6OWRwM2JlMDAxZTJ3b2ZwejAzdzhpdSJ9.nc4cEdRwhErEg2wuUkABbw';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v9',
center: [-1.41, 6.32],
zoom: 5
});
map.on('load', function () {
map.addLayer({
'id': 'maine',
'type': 'fill',
'layout': {},
'paint': {
'fill-color': {
property: 'name',
type: 'categorical',
stops: [
['Albania', '#F2F12D'],
['Algeria', '#7A4900'],
['Australia', '#63FFAC'],
["South Africa", "#4FC601"],
["South Korea", "#3B5DFF"],
]
},
'fill-opacity': 0.8
},
'source': {
'type': 'vector',
'url': 'mapbox://saurabhp.countries_tileset'
},
"source-layer": "countries",
});
});
<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.37.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.37.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>