Is it possible to render mapbox vector tiles (pbf) from a custom tile-server

4604
12
10-10-2016 10:42 PM
EivindRønnevik
New Contributor

Hi,

I have been testing the VectorTileLayer, both in 3.18 and 4.1 version. However it seems that the implementation of these layers (or the vectorTileLayerLoader.js to be more explicit) constrains the use of the VectorTileLayer to either
a) A Mapbox service - providing the ACCESS_TOKEN
b) An ESRI vector tile service, either using the URL directly or the URL to a Style json


I have made a local/custom tileserver using node.js and some of the javascript libraries from mapbox, and I would like to know if there is a way to render the vector tiles coming from this local server?


A URL like "http:\\somehost\layerName\{level}\{col}\{row}.mvt" (similar to the concept of WebTiledLayer) is what I'm after, but this is not supported by the current implementation I believe (at least I have not found a way to get it working).


I have also tried to extend the VectorTileLayer object and override the getTileUrl method, but this has not worked either.

getTileUrl: function(level, row, col) {
              return url+level+"/"+col+"/"+row+".mvt";
}

Does anyone know if it is possible to get this to work?


Kind regards,
Eivind

Tags (1)
12 Replies
JoshGage
New Contributor II

Any updates on this?

0 Kudos
boeskmgmoes
New Contributor II

Agreed! At this point have there been any updates on this?

0 Kudos
RogerAustin
New Contributor II

We are doing pretty much exactly this using 4.12. We start with the style json, which comes from our server but could equally well be created on the client. It looks something like:

{
"version": 8,
"sources": {
"oursource": {
"type": "vector",
"url": "https://ourhost/oursource"
}
},
"sprite": "https://ourhost/sprite",
"glyphs": "https://basemaps.arcgis.com/arcgis/rest/services/World_Basemap_v2/VectorTileServer/resources/fonts/{fontstack}/{range}.pbf",
"layers": [
{  ...

}

]

We create our vector tile layer using this style and add it it to the map:

map.add(new VectorTileLayer({style: ourstyle}));

The source url (https://ourhost/oursource) needs to return a chunk of json that looks like an ArcGIS vector tile service. We serve up something like this:

{
"name": "OurName",
"capabilities": "TilesOnly",
"type": "indexedVector",
"tiles": [
"/{z}/{x}/{y}.pbf"
],
"fullExtent": {
"xmin": -20037507.067161845,
"ymin": -20037507.067161845,
"xmax": 20037507.067161845,
"ymax": 20037507.067161845
},
"minScale": 591657527.591555,
"maxScale": 70.5310735,
"tileInfo": {
"rows": 512,
"cols": 512,
"dpi": 96,
"format": "pbf",
"origin": {
"x": -20037508.342787,
"y": 20037508.342787
},
"spatialReference": {
"wkid": 102100,
"latestWkid": 3857
},
"lods": [
{
"level": 0,
"resolution": 78271.516964,
"scale": 295828763.79577729
},
{
"level": 1,
"resolution": 39135.75850391389,
"scale": 147914381.98071263
},
.......
{
"level": 20,
"resolution": 0.07464553627067128,
"scale": 282.1242972457275
}
]
}
}

I have omitted most of the lods but you can find them online. Possibly you could omit the tileinfo part and instead create a tileinfo using the TileInfo.create method (TileInfo | ArcGIS API for JavaScript 4.12) and then set the tileinfo property of the VectorTileLayer directly - I haven't tried this. Note that a 512x512 pixel tile is specified, which is the MapBox standard.

You now need to serve your actual (pbf) tiles using the url pattern specified. In this example, that would be https://ourhost/oursource/{z}/{x}/{y}.pbf.

You also need to serve sprite.png and sprite.json and their high-res variants, sprite@2x.png and sprite@2x.json 

0 Kudos
YohanBienvenue
Occasional Contributor II

Just to be clear are you saying that you're able to display .mvt format tiles in your VectorTileLayer?

More specfically, I need to know if the vector tiles generated on the fly by the ST_asMVT function in postgis 2.5 can be displayed in the ArcGIS API map (one way or another). Anyone know? If so, does that only work with the ArcGIS API 4.X or we could use 3.X instead?

0 Kudos
RogerAustin
New Contributor II

Yes, although we generate the tiles on the fly using our own code and database, not PostGIS, and we use a pbf extension rather than mvt (the file format is the same). The key is the "chunk of json" in my previous reply, which the ArcGIS JS API expects to find at the URL specified as the source URL in your style. We are using 4.12 so I don't know if it would work for 3.X.

0 Kudos
YohanBienvenue
Occasional Contributor II

Ok thanks for the confirmation. I see now that the 4.X VectorTileLayer can take more parameters then the 3.X VectorTileLayer so I'm not sure either, but at least knowing that the layer can display that format in the end is encouraging and means it's worth investing some time into building our own vector tile API between the ArcGIS API 3.X and PostGIS.

Edit: So I made my own tile server (a tiny Node.js/Express API) and I just wanted to confirm that indeed the tiles generated by ST_asMVT (PostGIS 2.4+) can be displayed using the VectorTileLayer in the ArcGIS API 3.X

0 Kudos
PaulDowling2
New Contributor II

For anyone finding this thread, I found the following source JSON worked to load tiles hosted by a Klokantech OpenMapTiles server. As with Roger Austin‌'s example, I've removed most of the LOD entries, but I had to add a few more fields to get JS API v3.31 to load it. YMMV.

{ "currentVersion": 10.7, "name": "Test tiles", "capabilities": "TilesOnly,Tilemap", "type": "indexedVector", "tileMap": "tilemap", "tiles": [ "http://<host>/{z}/{x}/{y}.pbf" ], "exportTilesAllowed": true, "initialExtent": { "xmin": -20037508.342787, "ymin": -20037508.342787, "xmax": 20037508.342787, "ymax": 20037508.342787, "spatialReference": { "wkid": 102100, "latestWkid": 3857 } }, "fullExtent": { "xmin": -20037508.342787, "ymin": -20037508.342787, "xmax": 20037508.342787, "ymax": 20037508.342787, "spatialReference": { "wkid": 102100, "latestWkid": 3857 } }, "minScale": 591657527.591555, "maxScale": 70.5310735, "tileInfo": { "rows": 512, "cols": 512, "dpi": 96, "format": "pbf", "origin": { "x": -20037508.342787, "y": 20037508.342787 }, "spatialReference": { "wkid": 102100, "latestWkid": 3857 }, "lods": [ { "level": 0, "resolution": 78271.51696401172, "scale": 295829355.45453244 }, { "level": 1, "resolution": 39135.75848200586, "scale": 147914677.72726622 },..., { "level": 22, "resolution": 0.01866138385868352, "scale": 70.5312145840007 } ] }, "resourceInfo": { "styleVersion": 8, "tileCompression": "gzip", "cacheInfo": { "storageInfo": { "packetSize": 128, "storageFormat": "compactV2" } } } }

0 Kudos
StephenSontag55
New Contributor II

@RogerAustin  Were you able to get this with type='symbol'?  I have points, lines and polygons working but anything that needs to the sprites, doesn't display even when matching icon-image.

0 Kudos
RogerAustin
New Contributor II

Yes. Perhaps check that your sprite.json and sprite.png (and the sprite@2x variants) are downloading correctly and that the sprite.json correctly maps from icon-image to a chunk of the png.

0 Kudos