How can I use a custom font in Mapbox GL JS? - mapbox-gl-js

I am using Mapbox GL JS (v2.8.0) to programmatically add a Style layer to my map, and I am trying to use a set of fonts that I have uploaded to my map via the Mapbox Studio.
I currently have this inside my code for my Style layer:
const layer = {
id: this.getLayerId(),
type: 'symbol',
layout: {
'text-field': ['get', 'name'],
'text-font': [
"Chakra Petch Italic", // My custom font inside Mapbox
"Arial Unicode MS Regular" // Fallback font
]
},
paint: {
'text-color': '#ffffff',
}
}
However when it comes to rendering my map, I am getting 404 errors in relation to trying to fetch my font.
It is trying to fetch the font from the following url:
https://api.mapbox.com/fonts/v1/mapbox/Chakra%20Petch%20Italic,Arial%20Unicode%20MS%20Regular/0-255.pbf?access_token={access_token}
And I believe this issue here is that instead of /mapbox/ it should be /{username}/ as when I go to the following url in the browser:
https://api.mapbox.com/fonts/v1/{username}/Chakra%20Petch%20Italic,Arial%20Unicode%20MS%20Regular/0-255.pbf?access_token={access_token}
I correctly get the .pbf data.
How am I able to specify that it should look under my username, rather than the public mapbox user, in my style layer json?
Additionally, as a test, if I create a simple layer inside Mapbox Studio - and set a label to use the custom font, in the Network tab in devtools I can see it fetching the font using the username url above. And unfortunately the "code inspector" in the Studio for this label shows the same two string array as I have inside my code.

You need to set the glyphs property of your style:
}, glyphs: 'mapbox://fonts/yourusername/{fontstack}/{range}.pbf'
}
More info: https://docs.mapbox.com/mapbox-gl-js/style-spec/glyphs/

Related

What I need to put "url" in mapbox addSource

This is my first time using mapbox and I can't figure out how to addSource when map load.
Below is the sample code.
I uploaded 'KML' file for tilesets and I want to use this tileset for source, but I don't know how to write 'url' part.
I also want to know what is 'source-layer'. What should I write in the 'source-layer?
I am sorry I know this is very basic question, but I really need to know.
Please help me.
Thanks.
map.on('load', function() {
// Add the source to query. In this example we're using
// county polygons uploaded as vector tiles
map.addSource('counties', {
"type": "vector",
"url": "mapbox://mapbox.82pkq93d" <<---here
});
map.addLayer({
"id": "counties",
"type": "fill",
"source": "counties",
"source-layer": "original", <<---source layer
"paint": {
"fill-outline-color": "rgba(0,0,0,0.1)",
"fill-color": "rgba(0,0,0,0.1)"
}
}, 'place-city-sm'); // Place polygon under these labels.
});
EDIT:
Your tile url should also be fine like this:
mapbox://{}
It is a bit tricky to find in the documentation: When uploading KML you are creating tileset for which you should get a map ID. With the map ID you can either request separate tiles using a tile url like this:
/v4/{map_id}/{zoom}/{x}/{y}{#2x}.{format}
You can use the tile url when adding a source
map.addSource({
type: 'vector',
tiles: ['https://api.mapbox.com/v4/{map_id}/{zoom}/{x}/{y}.mvt']
});
Or you can request a TileJSON metadata object and use this to add the source:
map.addSource({
type: 'vector',
url: 'https://api.mapbox.com/v4/{map_id}.json' // <-- tileJSON url
});
For your source layer question: Vector tiles include multiple "layers" of data/geometry, when adding a map layer you need to define which source-layer the map layer refers to. E.g. you can have a single vector tile set consisting of line strings and points (two different source-layers), but your map layer should only render on of them. You can either check to tile JSON to see what source-layers are included in your tile set or create a map style in mapbox studio, using your uploaded tile set as a source.

Mapbox GL JS unclustered point icon-image

I'm trying to display a clustered map with Mapbox GL JS.
Using this example from the documentation: https://www.mapbox.com/mapbox-gl-js/example/cluster/, I'd like to show a marker icon instead of a circle for unclustered points.
I modified the last addLayer call like this :
map.addLayer({
id: "unclustered-point",
type: "symbol",
source: "companies",
filter: ["!has", "point_count"],
layout: {
"icon-image": "marker-15", // THIS SHOULD BE A MARKER
"icon-size": 5 // ZOOMED FOR DEMO
},
});
Here is the result I got :
Why can't I get access to Maki Icons like it is suggested here : Mapbox GL js available icons
Without a link to your (non) working example, it's hard to diagnose fully, but one possibility is that that icon is not included in your style.
You could try starting from a style that definitely includes them, like these: https://github.com/mapbox/mapbox-gl-styles

Mapbox - Update data-driven styling in session

There are several tutorials on data-driven styling on Mapbox's site, but none of them address how to update an existing data-driven style (created in Mapbox Studio) in-session. For example, say I want to create a choropleth of US states, colored by area. User then selects 'color by population' and the color of the states update accordingly.
I've found some resources that would allow one to achieve this by adding the geojson of all the states and then doing map.addLayer, however the geojson I'm working with (census tracts) is too massive to add to the front-end, so I needed to change the data-driven styling of an existing layer (or find a similar work-around). The data has to be a persisted tileset from mapbox studio, with user updating the data coloration based on geojson properties.
Any ideas or examples would be much appreciated.
Updating data-driven styling at run-time is straightforward. You simply call map.setPaintProperty.
I usually implement this with one function that generates the property value. Something like this:
function fillColorByPopulation(min, max) {
return {
property: 'pop',
stops: [
[min, 'red'],
[max, 'blue']
],
type: 'exponential'
}
}
function updateStyle(prop) {
if (prop === 'population') {
map.setPaintStyle('regions', 'fill-color', fillColorByPopulation(data.minpopulation, data.maxpopulation));
} else {
map.setPaintStyle('regions', 'fill-color', 'transparent');
}
}
I generally don't create any data-driven styles within Mapbox Studio. It's simpler to create them all in Javascript.

How do I use OSM custom tags in Mapbox style

Here's a brief description of what I'd like to do (and I'm very, very new to this but seem to have hit a wall):
Display a map of color-coded buildings based on a custom tag (miamioh_lds).
What I've tried: in Mapbox Studio Classic starting with the Emerald style (coordinates 84.7286, 39.5033)
#building [miamioh_lds="uitcp"] {
polygon-fill: #f61313;
}
I would expect Hoyt Hall to be red, but it is not, even if I remove all other #building CartoCSS statements.
I would like the building filled, which is why I'm using tags and fill instead of using a data source, which seems to be focused at adding markers. I'm using Mapbox because my goal is to bring the map into Tableau (which I'll use to add a marker off dynamic data, which is why I need a fill, not a marker here).
Can I use custom tags in CartoCSS? If so, what am I doing wrong?
Thanks!

Remove "Browse" button from TinyMCE's "Insert Link" dialog when using MoxieManager

I have correctly configured MoxieManager to be integrated with TinyMCE and all works fine. But I'd like to remove the "browse" button (which opens the MoxieManager dialog) from the "Insert link" dialog.
So from the following screenshot, the green should stay but the red should go.
Self answer, but I guess it will be helpful to other people as well.
Each TinyMCE plugin usually has a JS file located under plugins/[plugin_name]/plugin.js (or plugin.min.js, depending on if you are using the minified version). Those plugins usually call the editor.windowManager.open(), passing an object of configuration options to be applied to the newly opened window.
One of the values this object can have is body which is an array of the items to be displayed in the dialog. Each item has some options to be configured on its own, including the type property.
In the below example, I have used plugins/link/plugin.js to show the difference needed to replace the (default) text field with the file browser button - with the standard text field without the browse button.
win = editor.windowManager.open({
// ...
body: [
{
name: 'href',
type: 'filepicker',
filetype: 'file',
// ...
},
// More code follows here
And the new version:
win = editor.windowManager.open({
// ...
body: [
{
name: 'href',
type: 'textbox',
filetype: 'file',
// ...
},
// More code follows here
Or, if you don't want to change the source .. say you're using a minified version etc, you can disable it via CSS:
div[aria-label="Insert link"] .mce-btn.mce-open {
display: none;
}
add it to you config
file_picker_types: 'media image'
file_picker_types
This option enables you to specify what types of file pickers you need
by a space or comma separated list of type names. There are currently
three valid types: file, image and media.
https://www.tiny.cloud/docs/tinymce/6/file-image-upload/#file_picker_types