MapBox GL JS (WMS Tile) - Add a single layer from different domains - mapbox

Basically I want some of my layer's tiles to use domain A and some tiles will use domain B, and some tiles domain C.

You can specify multiple tile endpoints https://docs.mapbox.com/mapbox-gl-js/style-spec/sources/ in your source
"mapbox-streets": {
"type": "vector",
"tiles": [
"http://a.example.com/tiles/{z}/{x}/{y}.pbf",
"http://b.example.com/tiles/{z}/{x}/{y}.pbf"
],
"maxzoom": 14
}

Related

Polygon features don't appear at higher than tileset's maxzoom level after MTS upload

I have uploaded a Mapbox tileset using MTS with the following recipe:
{
"version": 1,
"layers": {
"layer-name": {
"source": "mapbox://tileset-source/...",
"minzoom": 13,
"maxzoom": 14,
"tiles": {
"layer_size": 2050,
"limit": [
["highest_where", true, 40000, "attribute"],
],
"order": "attribute"
}
}
}
}
The uploaded layer has polygon features. The tiles make its way to Mapbox studio, no errors or warnings upon publish, but when styling the data I noticed that the polygons disappear at zoom levels above 14 in spite of the zoom extent being set to 13-22.
This is unexpected because I assumed overzooming would apply here and I would see the polygons in all high zoom levels, albeit possibly simplified as processed for zoom 14.
Trying other things, I added another layer with points, also capped at zoom 14, but the point features happily appear at zooms over 14.
How do I enable overzooming for polygon features for zooms above the tileset's maxzoom level?

Tile out of range error when using wmts on Geoserver with Mapbox

I'd like to render a layer from geoserver with using WMTS.
I'm using mapbox-gl to render a map and layers.
The website I'm referring to is https://docs.geoserver.org/stable/en/user/styling/mbstyle/source.html.
This shows how to create a layer on geoserver and render it on a mapbox map.
However, I'm getting an error TileOutOfRange when I request tiles.
For example, when I request tiles with this url,
http://<my_server>:8080/geoserver/gwc/service/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&LAYER=myspace:japan&STYLE=&TILEMATRIX=EPSG:4326:8&TILEMATRIXSET=EPSG:4326&FORMAT=application/vnd.mapbox-vector-tile&TILECOL=221&TILEROW=102.
I get this error message.
Column 221 is out of range, min: 440 max:462.
Here below is my code to fetch a layer that I created on geoserver.
map.on("load", () => {
map.addSource("test", {
type: "vector",
tiles: ["http://<my_server>:8080/geoserver/gwc/service/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&LAYER=myspace:japan&STYLE=&TILEMATRIX=EPSG:4326:{z}&TILEMATRIXSET=EPSG:4326&FORMAT=application/vnd.mapbox-vector-tile&TILECOL={x}&TILEROW={y}"],
generateId: true,
minZoom: 0,
maxZoom: 14,
});
map.addLayer({
"id": "test",
"type": "fill",
"source": "test",
"source-layer": "japan",
"layout": { "visibility": "visible" },
"paint": {}
});
});
It would be much appreciated if anyone gave me a way to solve this.
Thank you.
I made sure that I checked this box application/vnd.mapbox-vector-tile in the tile caching settings.
I left out 900913 from the default gridset settings, since my data is EPSG:4326.
When creating a layer, I made sure that I clicked Compute from data and Compute from native bounds to set bounding boxes.

Mapbox Tiling Service: Polygon features not showing up at low zoom levels

I am producing a vector tileset using a GeoJSON of Multipolygons, but when I create the tileset using the Mapbox Tiling Service API endpoints, most of my features are not getting rendered at low zoom levels. If I process the same GeoJSON into an .mbtiles file using tippecanoe, it looks fine at low zoom levels (correctly shows all the features).
Here is my tileset config that I am feeding to the tileset creation API:
{
"recipe": {
"version": 1,
"layers": {
"my-tileset-id": {
"source": "mapbox://tileset-source/myusername/my-source-id",
"minzoom": 0,
"maxzoom": 16
}
}
},
"name": "Layer name herey",
"description": "An incomplete dataset of things.",
"attribution": [
{ "text": "Not my organization", "link": "https://theonion.com" }
]
}
And here's my tippecanoe command:
tippecanoe -zg -o my-tileset-id.mbtiles -l my-tileset-id -n "Layer name herey" ~/Downloads/my-input.geojson
When I upload and publish the tileset with the API, I get a histogram of how many features are in each tile. The number of features trails off from many in z11, fewer in z10, almost none in z9 and 0 below z9. When I upload via an .mbtiles, there's no histogram, and it just says the Zoom Extent is from z0 – z12.

Nothing showing when plotting vector tile layer from Arcgis server on MapBox GL JS map

I'm trying to plot a supplied vector tile layer onto a map using MapBox GL JS. I've followed the documentation here but nothing apart from the basic map is being output and there are no console errors. In the browser's Network tab I can see lots of .pbf requests being returned with data so it would seem that the endpoint is passing data back, but I don't know how to determine what the problem is in plotting that data onto the map.
The code is as follows:
mapboxgl.accessToken = '[my access token]';
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v10',
zoom: 6,
center: [-0.118092, 51.509865]
});
map.once("load", () => {
map.addSource("ncn", {
type: "vector",
tiles: [
"https://tiles.arcgis.com/tiles/1ZHcUS1lwPTg4ms0/arcgis/rest/services/NCN_Vector_Tile_Package/VectorTileServer/tile/{z}/{y}/{x}.pbf"
]
});
map.addLayer({
id: "ncn-lines",
type: "line",
source: "ncn",
"source-layer": "NCN_Vector_Tile_Package",
"layout": {
"visibility": "visible"
},
'paint': {
'line-color': 'rgb(255, 0, 0)'
}
});
});
I am fairly sure that the type should be line (rather than fill) as the data is supposed to contain route lines rather than vector shapes.
I don't have access to the Arcgis server so can't see how anything is configured at that side. Can anyone suggest what might be wrong here and/or how to debug?
It looks like the value for source-layer is not correct - it should be NCN_2020. Here's a demo showing it working: https://jsbin.com/xunuhibuki/1/edit?html,output
How do you get that value? I'm not quite sure the best way, but the way I found: add ?f=html to your vector tile layer like this: https://tiles.arcgis.com/tiles/1ZHcUS1lwPTg4ms0/arcgis/rest/services/NCN_Vector_Tile_Package/VectorTileServer/?f=html then click "Styles" link at the bottom which gives you an example of how to construct your map.addLayer() commands in your mapboxgl code.

Definition of a Leaflet layer

What exactly does a layer represent in the Leaflet Mapping Library?
Conceptually, to me a layer would represent a single tier of some type of feature or object; for example all image tiles representing the base level map would be represented on a single layer, a set of polygons representing states in the US may be on their own separate layer.
Specifically looking at L.GeoJSON.addGeoJSON(geojson), it reads that each new polygon created is placed in it's own layer (and then maybe merged with the layer you're calling the method on?). My use case is that I need to add many geoJSON objects one at a time and want to ensure I'm not creating many unnecessary layers (or if I am, if this is actually a bad thing).
Thank you.
In Leaflet anything that can be added to the map is a layer. So polygons, circles, markers, popups, tiles are all layers. You can combine layers in a L.LayerGroup (or FeatureGroup), if you for example want to treat a set of polygons as a single layer. So maybe your interpretation of layers matches better with what is modelled by L.LayerGroup in Leaflet.
L.GeoJSON is a LayerGroup (specifically a FeatureGroup) that is initialized from GeoJSON. Each new polygon is added to the L.GeoJSON LayerGroup using addLayer, which is the method for adding anything (that is a layer) to a LayerGroup. It does not create a new layer for each polygon (other than the L.Polygon which is already considered a layer). It only creates new FeatureGroups (LayerGroups) for a GeometryCollection and MultiPoints, which (I assume) is in order to preserve the structure from the GeoJSON.
If you want to add geoJSON objects to the same LayerGroup one at a time, you can just call L.GeoJSON.geometryToLayer to convert your GeoJSON object, and then add it to your LayerGroup using L.LayerGroup.addLayer.
As you mentioned, "layer" is a concept coming from a wider scope than simply the Leaflet implementation.
It is an abstract concept of "collection" in the context of Geospatial data.
A tier is also an alternative name, but I see "layer" being used more, in several standards & technologies.
The first lines here describe it simply enough:
https://doc.arcgis.com/en/arcgis-online/reference/layers.htm
In the context of Leaflet you can have as many layers as you want and it is not necessary to "spare" them.
More than thinking to optimization of the technical implementation, I'd put effort more in trying to identify "layers" (according to your business domain) as logical-groups of geospatial data that belongs together.
Specifically looking at L.GeoJSON.addGeoJSON(geojson), it reads that each new polygon created is placed in its own layer (and then maybe merged with the layer you're calling the method on?).
one Leaflet layer => one GeoJSON Feature (or set of Feature, given that FeatureCollection extends Feature).
there will be no merge: Leaflet will replace the whole layer with newly generated geospatial data, when you add GeoJSON data. Merging might be possible with custom implementation, but I don't know if it is advisable.
My use case is that I need to add many geoJSON objects one at a time and want to ensure I'm not creating many unnecessary layers (or if I am, if this is actually a bad thing).
It is not a bad thing per-sé, to have many layers; as long as concrete performance concerns don't arise.
If you want to reduce the number of layers, then put effort in modelling the structure of your GeoJSON so that most of the related objects are contained in a single GeoJSON/Layer (grouping by domain), instead of having a layer for each individual object (grouping by technical implementation).
E.g. a layer related to "risk areas"
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"title": "virus spread area",
"risk": "high"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
114.521484375,
30.89279747750818
],
[
113.89251708984374,
30.64972717137329
],
[
114.28253173828124,
30.21635515266855
],
[
114.521484375,
30.89279747750818
]
]
]
}
},
{
"type": "Feature",
"properties": {
"name": "Wuhan Institute of Virology",
"risk": "high"
},
"geometry": {
"type": "Point",
"coordinates": [
114.35462951660156,
30.543338954230222
]
}
}
]
}
instead of having one layer for the Polygon:
{
"type": "Feature",
"properties": {
"title": "virus spread area",
"risk": "high"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
114.521484375,
30.89279747750818
],
[
113.89251708984374,
30.64972717137329
],
[
114.28253173828124,
30.21635515266855
],
[
114.521484375,
30.89279747750818
]
]
]
}
}
and a separated (but actually related) one for the Point:
{
"type": "Feature",
"properties": {
"name": "Wuhan Institute of Virology",
"risk": "high"
},
"geometry": {
"type": "Point",
"coordinates": [
114.35462951660156,
30.543338954230222
]
}
}
(imho) both features conceptually belong to the same Layer.