[GIS] How to use Mapbox vector tiles as a vector source in OL3, so that labelling will not clip at tile boundaries

mbtilesopenlayersvector

I have been able to load and display mapbox vector tiles in OL3 using a vectorTile source and a vectorTile layer. The problem with this approach is that labels will clip at the tile boundaries and that features that extend across multiple tiles get multiple labels. I have increased the guttering around the tiles so that the symbols will not clip, but with potentially large labels, adjusting the guttering will not solve the problem.

I read that vector tiles in GeoJSON format can be used with vector sources, when using a tile loading strategy. Here is my code:

var tileGrid: ol.tilegrid.TileGrid = ol.tilegrid.createXYZ({
            maxZoom: 19
        });

        var vectorSource = new ol.source.Vector({
            format: new ol.format.MVT({
                featureClass: <any>ol.Feature
            }),
            url: function (extent, resolution) {
                var tileCoord = tileGrid.getTileCoordForCoordAndResolution(ol.extent.getCenter(extent), resolution);
                var tileUrl = cadastralTileURL +
                    tileCoord[0].toString() + '/' +
                    tileCoord[1].toString() + '/' +
                    (-tileCoord[2]).toString() + '.pbf';
                return tileUrl;
            }, 
            strategy: ol.loadingstrategy.tile(tileGrid),
            });

        var vectorLayer: ol.layer.Vector = new ol.layer.Vector({
            source: vectorSource,
            style: this.GetCadastralStyleFunction
        });

        var initCenter: [number, number] = ol.proj.fromLonLat([116, -32]);
        var viewOptions: olx.ViewOptions = <olx.ViewOptions>{
            center: initCenter,
            minZoom: 6,
            maxZoom: 22,
            zoom: 16
        };

        var view: ol.View = new ol.View(viewOptions);
        this.map = new ol.Map({
            layers: [vectorLayer],
            target: 'map',
            view: view
        });

Using the debugger in Chrome I can see the tiles loading properly (the network shows each tile coming down successfully), but nothing shows up on the display. I was hoping to see the polygon features being rendered as whole features, instead of a collection of parts in each tile, and thus getting around the issue of clipped labels.

Can anyone point me in the direction of what I am doing wrong?

Best Answer

I encountered similar problems when I first started working with VectorTiles, Your source polygons are being split across separate tiles, and OpenLayers has no knowledge of the original polygon anymore (and generally, tiles are processed independently and sometimes on different threads from one another). So each source polygon us being labeled for each tile it intersects.

As @ahocevar said, Your best bet is to create a separate point layer for the Polygon labels and use that point layer to label the features (you can just calculate the centroids of the polygons and use them to label the features).

Related Question