Search code examples
angulartypescriptopenlayers

openlayers load vector tile from binary


I want to load a vector tile in binary format to openlayer and got hung up on the tileLoadFunction. I just don't seem to be able to set the data to the tile manually. I need to use the tileLoadFunction since an API key must be passed to the tile server for authentication. This is what I have so far:

    let http = HttpClient;

    let layer = new VectorTileLayer();
    layer.setSource(
      new VectorTileSource({
        format: new MVT(),
        url: 'TILE_SERVER_URL',
        tileLoadFunction: (tile, src) => {
          // set headers
          const headers = new HttpHeaders({
            accept: 'application/binary',
            'authentication_id': environment.auth_token,
          });
         
          // retrieve the tiles
          this.http
            .get(src, {
              headers: headers,
              responseType: 'blob',
            })
            .subscribe((data) => {
              if (data !== undefined) {
                console.log(data);
                let vector_tile = tile as VectorTile;
                const format = new MVT();
                // Setting the features as follows is not valid
                // vector_tile.setFeatures(format.readFeatures(data, {}));
              } else {
                tile.setState(TileState.ERROR);
              }
            });
        },
      })
    );

I tried to find similar examples but nothing pointed me in the right direction unfortunately.


Solution

  • so the main mistake was not to use the blob type but rather arraybuffer which lead to the following:

    
    import MVT from 'ol/format/MVT';
    import VectorTileLayer from 'ol/layer/VectorTile';
    import VectorTileSource from 'ol/source/VectorTile';
    
        layer.setSource(
          new VectorTileSource({
            url: 'https://your-vector-tile-api/{z}/{x}/{y}.pbf',
            format: new MVT(),
            tileLoadFunction: (tile: any, src) => {
              tile.setLoader(
                (extent: Extent, resolution: number, projection: Projection) => {
                  // set headers
                  const headers = new HttpHeaders({
                    accept: 'application/binary'
                  });
    
                  this.http
                    .get(src, {
                      headers: headers,
                      responseType: 'arraybuffer',
                    })
                    .subscribe((data: any) => {
                      if (data !== undefined) {
                        const format = new MVT();
    
                        let features = format.readFeatures(data, {
                          extent: extent,
                          featureProjection: projection,
                        });
                        tile.setFeatures(features);
                        this.map.updateSize();
                      } else {
                        this.logger.error('error while loading features');
                        tile.setState(TileState.ERROR);
                      }
                    });
                }
              );
            },
          })
        );