Is there a way to extrude the height of mapbox Point on the map? - mapbox

Is there a way to extrude the height of mapbox Point on the map?
Having the following example:
map.addSource("markers", {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [14.422063225409431,50.08273361716846]
},
"properties": {
"height": 12,
"base_height": 10,
"title": "Mapbox DC",
"marker-symbol": "spaceti-maintenance"
}
}, {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [14.421896271941648,50.08259946060207]
},
"properties": {
"height": 12,
"base_height": 10,
"title": "Mapbox SF",
"marker-symbol": "spaceti-maintenance"
}
}]
}
});
map.addLayer({
"id": "markers",
"source": "markers",
//"type": "symbol",
"type":"fill-extrusion",
// "layout": {
// "icon-image": "{marker-symbol}",
// "text-field": "{title}",
// "text-font": ["Open Sans Semibold", "Arial Unicode MS Bold"],
// "text-offset": [0, 0.6],
// "text-anchor": "top"
// },
"paint": {
// See the Mapbox Style Spec for details on property functions
// https://www.mapbox.com/mapbox-gl-style-spec/#types-function
"fill-extrusion-color": "#424242",
"fill-extrusion-height": {
// Get fill-extrusion-height from the source "height" property.
"property": "height",
"type": "identity"
},
"fill-extrusion-base": {
// Get fill-extrusion-base from the source "base_height" property.
"property": "base_height",
"type": "identity"
},
// Make extrusions slightly opaque for see through indoor walls.
"fill-extrusion-opacity": 0.90
}
});
am I able to use both layout and paint properties of the layer assuming that I want to have marker with custom icon + extrusion height? I am building indoor navigation with multiple floor, that is the reason.

​It's not possible at this time to extrude points, however, you can convert these to (small) circles and extrude them based on your values. Looks like some similar requests for point cloud support is here:
​https://github.com/mapbox/mapbox-gl-js/issues/3450 so you may be able to follow the progress should it makes its way into new releases.

Related

How can I take coordinates for a polygon from a geojson file and extrude a 3D polygon from that?

I am trying to build a custom polygon and extrude it to the desired height using a geojson format for the data of the layer. I cannot, however, get the layer to appear on the map.
Here is what my code currently looks like:
map.on('load', function() {
map.addLayer({
"id": "points",
"type": "fill-extrusion",
"source": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"properties": {
"height": 20
},
"geometry": {
"type": "Polygon",
"coordinates": [[-77.95156674578604,43.21028611031018],[-77.9515685764367,43.21023621803456],[-77.95164127121708,43.21023640149863],[-77.95163950226289,43.20994159756599],[-77.95156746849948,43.20994229766657],[-77.95156608216422,43.20984647340193],[-77.95163884784701,43.2098471878642],[-77.95163818870492,43.20974779426955],[-77.95156665824665,43.20974844351096],[-77.95156615562892,43.2096483942845],[-77.95163707195606,43.20964807835471],[-77.95163793551596,43.20955241242493],[-77.95156647756606,43.20955241987652],[-77.9515664774183,43.2094545892833],[-77.95163793511105,43.20945458922404],[-77.95163696894726,43.20935746267753],[-77.95156551159552,43.20935675861833],[-77.95156647716871,43.20929763788168],[-77.95105728862093,43.20929848258431],[-77.95105728634326,43.20935651174059],[-77.95094326166087,43.20935664235909],[-77.9509445324407,43.2094533024724],[-77.95105528277132,43.20945365396392], [-77.95105519319713,43.20955170962569],[-77.9509434596672,43.20955220425741],[-77.95094421091157,43.20964816606944],[-77.95105501443713,43.20964756032618],[-77.95105491497931,43.20974624410085], [-77.95094329958742,43.20974576773256],[-77.95094365714365,43.20984690983914],[-77.95105721793563,43.20984632462195],[-77.95105737381726,43.20994209364298], [-77.95094302334114,43.2099429224098], [-77.95094306509297,43.21003748562214],[-77.95105440575118,43.21003746846881],[-77.95105570050066,43.21013103703177],[-77.95094276571092,43.21013059432006],[-77.95094112502309,43.21023730976442],[-77.95105416431622,43.21023720143463],[-77.95105549775089,43.21028580291442],[-77.95156674578604,43.21028611031018]]
}
}]
}
},
"paint": {
"fill-extrusion-color": "#aaa",
"fill-extrusion-height": ['get', 'height']
}
});
});
Polygon is an array of LineStrings in GeoJSON (see https://en.wikipedia.org/wiki/GeoJSON#Geometries, for instance). So in your case the coordinates should look like this:
"coordinates": [[[-77.95156674578604,43.21028611031018],[-77.9515685764367,43.21023621803456],[-77.95164127121708,43.21023640149863],[-77.95163950226289,43.20994159756599],[-77.95156746849948,43.20994229766657],[-77.95156608216422,43.20984647340193],[-77.95163884784701,43.2098471878642],[-77.95163818870492,43.20974779426955],[-77.95156665824665,43.20974844351096],[-77.95156615562892,43.2096483942845],[-77.95163707195606,43.20964807835471],[-77.95163793551596,43.20955241242493],[-77.95156647756606,43.20955241987652],[-77.9515664774183,43.2094545892833],[-77.95163793511105,43.20945458922404],[-77.95163696894726,43.20935746267753],[-77.95156551159552,43.20935675861833],[-77.95156647716871,43.20929763788168],[-77.95105728862093,43.20929848258431],[-77.95105728634326,43.20935651174059],[-77.95094326166087,43.20935664235909],[-77.9509445324407,43.2094533024724],[-77.95105528277132,43.20945365396392], [-77.95105519319713,43.20955170962569],[-77.9509434596672,43.20955220425741],[-77.95094421091157,43.20964816606944],[-77.95105501443713,43.20964756032618],[-77.95105491497931,43.20974624410085], [-77.95094329958742,43.20974576773256],[-77.95094365714365,43.20984690983914],[-77.95105721793563,43.20984632462195],[-77.95105737381726,43.20994209364298], [-77.95094302334114,43.2099429224098], [-77.95094306509297,43.21003748562214],[-77.95105440575118,43.21003746846881],[-77.95105570050066,43.21013103703177],[-77.95094276571092,43.21013059432006],[-77.95094112502309,43.21023730976442],[-77.95105416431622,43.21023720143463],[-77.95105549775089,43.21028580291442],[-77.95156674578604,43.21028611031018]]]

How to set map.loadImage visibility by zoom level in Mapbox GL JS?

I'm loading an image with the following code:
map.on('load', function () {
map.loadImage('....png', function(error, image) {
if (error) throw error;
map.addImage('b7', image);
map.addLayer({
"id": "b7",
"type": "symbol",
"source": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [0, 0]
}
}]
}
},
"layout": {
"icon-image": "b7",
"icon-size": 0.2
}
});
});
How can i set the visibility to none, at a certain zoom level?
It looks like that you cant use map.setLayoutProperty on an loadImage. In the console, it says: Error: The layer 'b7' does not exist in the map's style and cannot be styled.
Whey i try something like:
map.setLayoutProperty( 'b7', 'visibility', 'none' );
Any ideas?
Two suggestions on how to solve this:
First, make sure your image name and layer name are different. It could be that the function is looking for b7 layer but it finds an image named b7 first (or vice versa). Either way this should be changed as it creates conflicting variables.
Second, if that doesn't work try adding your source separately instead of inside the layer.
map.addSource("mySource", {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-74.981906, 41.742503]
},
"properties": {
"title": "title ",
"icon": "myImage",
}
}]
}
});
And then add the layer with the source.
map.addLayer({
"id": "b7",
"type": "symbol",
"source": "mySource",
"layout": {
"icon-image": "myImage",
"icon-size": 0.2
}
});
You can now call the setLayoutProperty on a zoomstart listener. Add a conditional if you want it only at a specific zoom level using map.getZoom(); You need to be setting the visibility for the layer here, not the image.
map.on('zoomstart', 'b7', function(e) {
if (map.getZoom() > 12) {
map.setLayoutProperty('b7', 'visibility', 'none');
}
})
Snippet is below, let me know if you encounter any problems.
map.on('load', function() {
map.loadImage('myImage.png', function(error, image) {
if (error) throw error;
map.addImage('myImage', image);
map.addSource("mySource", {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-73.981906, 40.742503]
},
"properties": {
"title": "title ",
"icon": "myImage",
}
}]
}
});
map.addLayer({
"id": "b7",
"type": "symbol",
"source": "mySource",
"layout": {
"icon-image": "myImage",
"icon-size": 0.2
}
});
});
});
map.on('zoomstart', 'b7', function(e) {
if (map.getZoom() > 12) {
map.setLayoutProperty('b7', 'visibility', 'none');
}
})

Color Each Polygon Dynamically using mapbox?

I am trying to colour each polygon dynamically based on a computation. Is there a way possible using mapbox?
The computation is triggered when a value is selected from the dropdown, then each polygon's colour needs to be updated.
Below is the geojson source that I am adding to the map.
{
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [
{
"id": 1,
"type": "Feature",
"properties": {
"title": "Candolim"
},
"geometry": {
"type": "Polygon",
"coordinates": [[[73.68255615234375, 15.72088240269937], [73.707275390625, 15.670643235196232], [73.97232055664062, 15.640229310707543], [73.97232055664062, 15.685187424880764], [73.95721435546875, 15.698408515946419], [73.94760131835938, 15.74071024249738], [73.8885498046875, 15.753927728167556], [73.88717651367188, 15.769787575567598], [73.86245727539062, 15.798860741939269], [73.82675170898438, 15.742032029750966], [73.68255615234375, 15.72088240269937]]]
}
},
{
"id": 2,
"type": "Feature",
"properties": {
"title": "Morjim"
},
"geometry": {
"type": "Polygon",
"coordinates": [[[73.970947265625, 15.640229310707543], [73.70864868164062, 15.666676458207187], [73.73062133789062, 15.60584290961007], [73.76907348632812, 15.496032414238634], [73.79791259765625, 15.45765111021037], [74.17556762695312, 15.653453312049928], [74.11239624023438, 15.650808580175482], [74.08355712890625, 15.627004454829198], [74.03823852539062, 15.620391706641964], [74.02313232421875, 15.60584290961007], [73.99566650390625, 15.609810865724066], [73.98056030273438, 15.623036831528264], [73.970947265625, 15.640229310707543]]]
}
},
{
"id": 3,
"type": "Feature",
"properties": {
"title": "Panaji"
},
"geometry": {
"type": "Polygon",
"coordinates": [[[73.79928588867188, 15.458974721921672], [73.78280639648438, 15.411319377980993], [74.256591796875, 15.257689080778698], [74.29229736328125, 15.277561419418248], [74.33486938476562, 15.292133271452533], [74.31838989257811, 15.326571801420842], [74.32113647460938, 15.37027407332405], [74.2840576171875, 15.391459757417053], [74.27444458007812, 15.420586551727165], [74.27993774414062, 15.441767110328934], [74.24835205078124, 15.485445179478607], [74.27993774414062, 15.534406591252042], [74.25384521484375, 15.566159129772904], [74.26071166992188, 15.613778745064309], [74.24972534179688, 15.625681922266882], [74.24423217773438, 15.665354182093287], [74.2236328125, 15.65609800971696], [74.2071533203125, 15.658742673171389], [74.1961669921875, 15.669320984759295], [74.190673828125, 15.681220930466825], [74.17144775390625, 15.675932151334584], [74.17694091796875, 15.654775665159686], [73.79928588867188, 15.458974721921672]]]
}
}
]
}
}
You can achieve this using setPaintProperty and a "match" expression after the value is selected:
map.setPaintProperty('myLayer', 'fill-color', [
'match',
['get', 'title'],
layer.value, '#fbb03b',
/* other */ '#ccc'
]);
See this jsfiddle.

Color only the edge of a circle mapbox gl js

I want to show the outline of a circle on an interactive map (no fill) however, the paint options in mapbox-gl-js seem limited to fill only.
https://www.mapbox.com/mapbox-gl-style-spec/#layers-circle
var styles = [{
"id": 'points',
"interactive": true,
"type": "circle",
"source": "geojson",
"paint": {
"circle-radius": 5,
"circle-color": "#000
},
"filter": ["in", "$type", "Point"]
}, {
"type": "line",
"source": "geojson",
"layout": {
"line-cap": "round",
"line-join": "round"
},
"paint": {
"line-color": "#000",
"line-width": 2.5
},
"filter": ["in", "$type", "LineString"]
}];
Am i missing something or is this just not possible?
This is now possible, with circle-opacity.
E.g.:
"paint": {
"circle-opacity": 0,
"circle-stroke-width": 1,
"circle-stroke-color": #000
}
Not currently possible. Current top workaround appears to be layering two circles of slightly different sizes.
https://github.com/mapbox/mapbox-gl-js/issues/1713
https://github.com/mapbox/mapbox-gl-style-spec/issues/379
I'm having trouble running custom color 'match' and having opacity controls running simultaneously.
I can get both working, but not at the same time. See code below.
var coorAddresses = [ [ -75.7040473, 45.418067,"Medium" ], [-75.7040473, 45.418067, "Medium"], [-79.32930440000001, 43.7730495, "Unknown"]]
$.getJSON(coodAddresses, function(data) {
for(var itemIndex in data) {
// push new feature to the collection
featureCollection.push({
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [data[itemIndex][0], data[itemIndex][1]]
},
"properties": {
"size_by": data[itemIndex][2],
"color_by": data[itemIndex][2]
},
});
}
});
map.on('load', function () {
map.addLayer({
"id": "points",
"type": "circle",
"source": {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": featureCollection
}
},
"paint": {
"circle-color": [
'match',
['get', 'size_by'],
'Easy',
'#e4f400',
'Medium',
'#f48a00',
'Unknown',
'#6af400',
/* other */ '#00e4f4'
],
"circle-radius": [
'match',
['get', 'size_by'],
'Easy',
4,
'Medium',
7,
'Unknown',
2,
/* other */ 1000
],
// "circle-opacity": 0, // color does not show if i uncomment these lines
// "circle-stroke-width": 1, // do not get desired 'hollow' circle unless these lines run
}});
Trying to troubleshoot.

Can't get custom markers to work in Mapbox GL JS

I've followed both the example at Mapbox site and this instruction on GitHub but can't get markers to show on my map:
http://codepen.io/znak/pen/waPPRj (using Mapbox style and sprites)
http://codepen.io/znak/pen/PqOEyV (using custom style and sprites)
var center = [51.5, -0.1];
var map = new mapboxgl.Map({
container: 'map',
center: center,
zoom: 8,
style: 'https://www.mapbox.com/mapbox-gl-styles/styles/mapbox-streets-v7.json'
});
// Markers
map.on('style.load', function() {
map.addSource("markers", {
"type": "geojson",
"data": {
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [51.48, -0.08]
},
"properties": {
"title": "Lorem",
"marker-symbol": "default_marker"
}
}, {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [51.52, -0.12]
},
"properties": {
"title": "Ipsum",
"marker-symbol": "secondary_marker"
}
}]
}
});
map.addLayer({
"id": "markers",
"type": "symbol",
"source": "markers",
"layout": {
"icon-image": "{marker-symbol}",
"text-field": "{title}",
"text-font": "Open Sans Semibold, Arial Unicode MS Bold",
"text-offset": [0, 0.6],
"text-anchor": "top"
},
"paint": {
"text-size": 14
}
});
});
All styles, JSON and PNG files with markers seem to load properly.
Any ideas?
The GeoJSON layer type of Mapbox GL JS follows the GeoJSON specification, which requires that coordinates be in longitude, latitude order. Your examples have them reversed. Flipping them shows the markers, which have the correct icons.
"geometry": {
"type": "Point",
"coordinates": [-0.12, 51.52]
}