Extrude land in MapBox - mapbox

I am trying to emphasize the fact that the land is higher than the water in my map so wanted to add an extrusion to the land layer. I thought taking the https://docs.mapbox.com/mapbox-gl-js/example/3d-buildings/ of the one with buildings and changing the layer source to 'land' would work but it didn't. Is this something specific to building layers or am I doing something wrong? Here is my layer definition in my style JSON:
{
"id": "3d-land",
"source": "composite",
"source-layer": "land", # Changed this from building
"filter": ["==", "extrude", "true"],
"type": "fill-extrusion",
"minzoom": 0,
"paint": {
"fill-extrusion-color": "#000",
"fill-extrusion-height": [
"interpolate", ["linear"], ["zoom"],
15, 0,
18.0, 30.0
],
"fill-extrusion-base": [
"interpolate", ["linear"], ["zoom"],
15, 0,
18.0, ["get", "min_height"]
],
"fill-extrusion-opacity": 0.8
}
}

First reason is as the console says, "land" does not exist on source "composite". "land" layer is background layer which is exist separately in the style. You cannot use fill-extrusion for background layer. You may want to use layers which use "compose" source.
The other reason is from filter. "filter": ["==", "extrude", "true"] means filtering if the value of layer's property called "extrude" is "true". land layer doesn't have a property extrude so it's always false.
So, the result of fix would be looks like:
map.addLayer(
{
id: "3d-landcover",
source: "composite",
"source-layer": "landcover",
"type": "fill-extrusion",
"minzoom": 0,
"paint": {
"fill-extrusion-color": "#000",
"fill-extrusion-height": [
"interpolate", ["linear"], ["zoom"],
15, 0,
18.0, 30.0
],
"fill-extrusion-base": [
"interpolate", ["linear"], ["zoom"],
15, 0,
18.0, ["get", "min_height"]
],
"fill-extrusion-opacity": 0.8
}
}
);
As the first reason, all the layers except water should be added as above if you want to make the land higher than water. it's not very effective.

Related

Mapbox GL JS - Change the color of selected 3D buildings

in my database I have ID numbers (mapbox) of about a million buildings, each building is associated with a category.
Buildings are scattered all over the world.
There can be many more buildings, so the data should be downloaded dynamically (json, geojson, etc.).
I would like to change the color of 3D buildings (fill-extrusion-color) depending on the category and add an icon next to it.
I have been browsing the documentation but I am not able to combine it into a solution.
I am asking for help as I should solve this problem.
Currently, it only controls color like this:
'fill-extrusion-color': [ "case", [ "! =", ["get", "min_height"], 0 ], "hsl (224, 18%, 56%)", [ "match", ["get", "type"], ["building: part"], true, false ], "hsl (224, 25%, 38%)", [ "interpolate", ["linear"], ["get", "height"], 0, "hsl (224.47%, 29%)", twenty, "hsl (224.61%, 33%)", 50, "hsl (224.53%, 48%)", 400, "hsl (224, 83%, 72%)" ] ]
Can you try:
'fill-extrusion-color':
[ "case",
[ "!=", ["get", "min_height"], 0 ],
"#7b85a3",
[ "match", ["get", "type"],
["building: part"], true, false ],
"#495679",
[ "interpolate", ["linear"],
["get", "height"],
0, "hsl (224, 47%, 29%)",
12, "hsl (224, 61%, 33%)",
50, "hsl (224, 53%, 48%)",
400, "hsl (224, 83%, 72%)" ] ]

Symbol placed with line-center doesn't rotate as the map rotates

I'm having a problem rotating an image with property symbol-placement set to line-center.
This is what it looks like
Removing the property half-solve the issue; the icon rotate as I rotate the map, but they position at the start of the line, and it's not what I'm trying to do.
The definition of my layer is:
{
"id": "my_symbol",
"type": "symbol",
"source": "XXXX",
"source-layer": "XXXXXXX",
"minzoom": 19,
"layout": {
"symbol-placement": "line-center",
"icon-size": {
"stops": [
[20, 0.2],
[21, 0.1],
[22, 0.3],
[23, 0.5],
[24, 0.7]
]
},
"icon-image": [
"concat",
"edge_",
["get", "status_list"]
],
"icon-allow-overlap": true
}
}
I'm trying to achieve this behaviour only by the layer's definition.
I tried looking for a solution, here on SO and on some other sites but I haven't found anything that would help me.
you can set your icon rotation with icon-rotation-alignment
setting it to viewport will fix the icon rotation to your viewport while setting it to map won't rotate it
i'm sorry the gif is hard to see!
{
"id": "my_symbol",
"type": "symbol",
"source": "XXXX",
"source-layer": "XXXXXXX",
"minzoom": 19,
"layout": {
"symbol-placement": "line-center",
"icon-size": {
"stops": [
[20, 0.2],
[21, 0.1],
[22, 0.3],
[23, 0.5],
[24, 0.7]
]
},
"icon-image": [
"concat",
"edge_",
["get", "status_list"]
],
"icon-allow-overlap": true,
"symbol-placement": "line-center",
"icon-rotation-alignment": "viewport"
}
}

Visibility of villages in Mapbox

In my Mapbox GL project, I have a layer with towns and villages which looks like this:
{
"id": "towns",
"type": "symbol",
"source": "composite",
"source-layer": "place_label",
"minzoom": 1,
"maxzoom": 14,
"filter": [
"all",
[
"match",
["get", "type"],
["town", "village", "hamlet"],
true,
false
],
["match", ["get", "name"], [
// list of villages
], true, false]
],
"layout": {
"text-variable-anchor": ["top", "bottom", "left", "right"],
"text-allow-overlap": true,
"text-ignore-placement": true,
"icon-allow-overlap": true,
"text-field": ["get", "name"],
"text-font": ["Roboto Regular", "Arial Unicode MS Regular"],
"text-size": [
"interpolate",
["linear"],
["zoom"],
3,
8,
22,
16
]
},
"paint": {
"text-halo-color": "hsla(0, 0%, 100%, 0.95)",
"text-halo-width": 1,
"text-halo-blur": 0.4
}
},
The text-size zoom interpolation works fine for the towns. However, the village will only show up after a zoomlevel of 9. Is there any way I could make the villages visible at all time?
Most likely, the Mapbox Streets Tileset you're using only includes those villages in the data after zoom 9, so there is nothing you can do in the style to make it show up earlier.
You'd need to create your own dataset which includes the data you want at lower zoom levels (and maybe just check this is the cause first in Mapbox Studio data view).

mapbox gl data driven style: What does the "value" parameter do?

I'm modifying my icon size based on the current zoom value by using the zoom data to drive the size.
As I understand it, I'm using the property "zoom" to track the zoom value (This is required as per the spec), In the stops I setup each desired "zoom" value and then output the icon-size value for that state (shown by the 0-1 > 3 range). If I don't include the parameter "value": something the code fails. If I set it all to 1, it works fine, so it seems that this value is ignored.
Can anyone explain its actual use?
// Add layer to map populating data from Geojson
map.addLayer({
"id": "seed",
"type": "symbol",
"source": "objects",
"layout": {
"icon-rotation-alignment": "map",
"icon-keep-upright": true,
"icon-rotate": 0,
"icon-image": "{icon}",
"icon-allow-overlap": true,
"icon-size": {
"property": "zoom",
"type": "exponential",
"stops": [
[{ "zoom": 15, "value": 1}, 0.1],
[{ "zoom": 16, "value": 1}, 0.3],
[{ "zoom": 17, "value": 1}, 0.6],
[{ "zoom": 18, "value": 1}, 0.8],
[{ "zoom": 19, "value": 1}, 2],
[{ "zoom": 20, "value": 1}, 3]
]
}
}
});
});
Apologies for the confusion #stuffyjoelab!
There are three types of functions in Mapbox GL:
Zoom functions allow the appearance of a map feature to change with map’s zoom level
Property functions allow the appearance of a map feature to change with its properties.
Zoom-and-property functions allow the appearance of a map feature to change with both its properties and zoom.
(There's more info about these in our style spec docs)
I'm using the property "zoom" to track the zoom value
We define a "property" as being per-feature metadata, a la GeoJSON feature properties. By this definition, zoom is not a property (unless you have a property on your features called zoom)
If you switch to the zoom function syntax by removing "property": "zoom" and replacing the {zoom, value} objects from your stops with numeric zooms, everything should work as expected.
// Add layer to map populating data from Geojson
map.addLayer({
"id": "seed",
"type": "symbol",
"source": "objects",
"layout": {
"icon-rotation-alignment": "map",
"icon-keep-upright": true,
"icon-rotate": 0,
"icon-image": "{icon}",
"icon-allow-overlap": true,
"icon-size": {
"type": "exponential",
"stops": [
[15, 0.1],
[16, 0.3],
[17, 0.6],
[18, 0.8],
[19, 2],
[20, 3]
]
}
}
});

AmCharts set to always display labels on stacked columns

I am trying to make my stacked column amChart always display value labels on the columns. Even if they do not fit.
I am using this code:
var qtrchart = AmCharts.makeChart("chartdiv", {
"type": "serial",
"theme": "none",
"legend": {
"autoMargins": false,
"borderAlpha": 0.2,
"equalWidths": false,
"horizontalGap": 10,
"markerSize": 10,
"useGraphSettings": true,
"valueAlign": "left",
"valueWidth": 0
},
"dataProvider": [{
"QTR":"FY14 Q2",
"DSAT":0.032602706911007306,
"Neutral":0.069205892921307938,
"CSAT":0.89819140016768484},
{"QTR":"FY14 Q3",
"DSAT":0.038609212354234618,
"Neutral":0.060273567620017982,
"CSAT":0.90111722002574746},
{"QTR":"FY14 Q4","DSAT":0.038757557172180282,
"Neutral":0.058425780441887579,
"CSAT":0.90281666238593217},
{"QTR":"FY15 Q1",
"DSAT":0.12391774891774893,
"Neutral":0.10355411255411255,
"CSAT":0.77252813852813851}],
"valueAxes": [{
"stackType": "100%",
"axisAlpha": 0,
"gridAlpha": 0,
"labelsEnabled": false,
"position": "left"
}],
"graphs": [{
"balloonText": "[[title]], [[category]]<br><span style='font-size:14px;'>[[percents]]%</span>",
"fillColors": "#87898b",
"lineColor": "#87898b",
"color": "#ffffff",
"fillAlphas": 0.9,
"fontSize": 11,
"labelText": "[[percents]]%",
"lineAlpha": 0.5,
"title": "DSAT",
"type": "column",
"valueField": "DSAT"
}, {
"balloonText": "[[title]], [[category]]<br><span style='font-size:14px;'>[[percents]]%</span>",
"fillColors": "#822980",
"lineColor": "#822980",
"color": "#ffffff",
"fillAlphas": 0.9,
"fontSize": 11,
"labelText": "[[percents]]%",
"lineAlpha": 0.5,
"title": "Neutral",
"type": "column",
"valueField": "Neutral"
}, {
"balloonText": "[[title]], [[category]]<br><span style='font-size:14px;'>[[percents]]%</span>",
"fillColors": "#0096d6",
"lineColor": "#0096d6",
"color": "#ffffff",
"fillAlphas": 0.9,
"fontSize": 11,
"labelText": "[[percents]]%",
"lineAlpha": 0.5,
"title": "CSAT",
"type": "column",
"valueField": "CSAT"
}],
"marginTop": 30,
"marginRight": 0,
"marginLeft": 0,
"marginBottom": 40,
"autoMargins": false,
"categoryField": "QTR",
"categoryAxis": {
"gridPosition": "start",
"axisAlpha": 0,
"gridAlpha": 0
},
"percentPrecision": 1,
"data_labels_always_on": true
});
http://jsfiddle.net/Cww3D/288/
Is there a way to achieve this? I found older versions had a special parameter "data_labels_always_on" that you could set to true. But that does not work.
Any ideas?
I'm using AmChart also, and found this that may help you, that goes on "graph" options:
showAllValueLabels Boolean false If graph's type is column and labelText is set, graph hides labels which do not fit into the column's space. If you don't want these labels to be hidden, set this to true.
Hope this helps you!
I got the labels to display by setting the graphs label position, like this:
"labelPosition": "bottom"
here is the JSFiddle: http://jsfiddle.net/Cww3D/291/
Apparently, this forces the labels to display, while the one you'd expect, "showAllValueLabels": true does not.
Weird!
The text labels are not showing because the font size assigned is larger than the space allowed. Modifying the "fontSize" property in the first two of the three "graphs" objects from 11 to 3 displays the percent values you are looking for. However, the font size is so small it isn't very legible even in the fourth column. It's not a solution, but maybe a starting point for you to investigate further?
No screen cap, sorry, I'm still new here.