Reputation: 1
I am trying to display a vector tileset using mapbox gl js. The original data was in KML, and my goal is to display using vector tileset. So I converted the KML to MVT file using GDAL with following command:
ogr2ogr -f MVT thirdtileset i.kml -dsco COMPRESS=NO -dsco MAXZOOM=15
The output MVT has following structure:
myTileset
|---0 /* in zxy order */
|---1
...
|---15
metadata.json
I was able to display the lines in it using following code:
map.on("load", () => {
map.addSource("myMap", {
type: "vector",
tiles: ["http://127.0.0.1:8080/mytileset/{z}/{x}/{y}.pbf"],
minzoom: 0,
maxzoom: 15,
});
map.addLayer({
id: "lineLayer",
type: "line",
source: "myMap",
"source-layer": "mainlayer",
});
});
But the label contents (text) were missing in the map. I learnt that I need to add a symbol layer and set the "text-field" property. So I tried to figure out what should I put in this field.
Here is my code adding the symbol layer:
map.on("load", () => {
... /* same code as above adding source and line layer */
map.addLayer({
id: "symbolLayer", // Layer ID
type: "symbol",
source: "myMap",
"source-layer": "mainlayer",
paint: {
"text-color": "#ff0000",
"text-opacity": 1,
},
layout: {
"text-field": /* Here is what I am struggling */,
"text-rotation-alignment": "auto",
"text-allow-overlap": true,
"text-anchor": "top",
},
}
);
});
I checked the metadata.json, it has following structure:
{
"name":"thirdtileset",
"description":"",
"version":2,
"minzoom":0,
"maxzoom":15,
"center": /* two numbers in a string split by ',' */,
"bounds": /* four numbers in a string split by ',' */,
"type":"overlay",
"format":"pbf"
"json":"{\n \"vector_layers\":[\n ..." /* a very long string of a json file */
}
I copied out the json string in the end and formatted it, and here is its structure:
{
"vector_layers": [
{
"id": /* some layer id */,
"description": "",
"minzoom": 0,
"maxzoom": 15,
"fields": {
"Name": "String", // this field contains the string I want to display as label
... /* other field, not important */
}
},
... /* more layers, but the fields are all the same */
...
],
"tilestats": {
"layerCount": /* some number */,
"layers": [
{
"layer": /* some layer name */,
"count": /* some number */,
"geometry": "Point", /* only points are labels, all points are labels */
"attributeCount": /* some number */,
"attributes": [
{
"attribute": "Name",
"count": /* some number */,
"type": "string",
"values": [ \* here are the strings of the labels I want to show *\ ]
},
{\* some other attributes of other fields *\},
...
]
},
{\* tilestats of another layer *\},
...
]
}
The strings of the label contents are in
"tilestats" -> "layers"[0, 1, ..., 5] -> "attributes"[0] -> values
I am now struggling to create the "text-field" for it. Any suggestion on how should I compose the "text-field" properties or how to display the labels is appreciated!
I tried to use
["get", "values"]
["get", "Name"]
as text-field value, but neither worked for me. I also tried to write some longer MapBox expressions, but when I printed the symbol layer, the _filterCompiled
field is false for all of them, and none of them got the labels to display. I tried to convert the kml to GeoJson, and the labels display simply with ["get", "name"]
as "text-field", but I do need to use vector tileset.
Upvotes: 0
Views: 936
Reputation: 126617
It's hard to tell for sure since you haven't included your complete code.
But in one place you have written
"source-layer": "mainlayer",
and in another place:
"layer": /* some layer name */,
The value mainLayer
needs to match whatever is "some layer name".
Upvotes: 0