Skip to content

Commit

Permalink
feature(VectorTileSource): add support for multiple source
Browse files Browse the repository at this point in the history
  • Loading branch information
Aymeric DUTREMBLE authored and ftoromanoff committed Mar 20, 2024
1 parent e6eb4cf commit c51e64a
Show file tree
Hide file tree
Showing 4 changed files with 307 additions and 147 deletions.
6 changes: 3 additions & 3 deletions src/Source/Source.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ class /* istanbul ignore next */ ParsingOptions {}

function fetchSourceData(source, extent) {
const url = source.urlFromExtent(extent);

return source.fetcher(url, source.networkOptions).then((f) => {
f.extent = extent;
return f;
Expand Down Expand Up @@ -190,8 +189,9 @@ class Source extends InformationsData {
let features = cache.getByArray(key);
if (!features) {
// otherwise fetch/parse the data
features = cache.setByArray(fetchSourceData(this, extent).then(file => this.parser(file, { out, in: this }),
err => this.handlingError(err)), key);
features = cache.setByArray(fetchSourceData(this, extent)
.then(file => this.parser(file, { out, in: this }),
err => this.handlingError(err)), key);
/* istanbul ignore next */
if (this.onParsedFile) {
features.then((feat) => {
Expand Down
86 changes: 73 additions & 13 deletions src/Source/VectorTilesSource.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
import { featureFilter } from '@mapbox/mapbox-gl-style-spec';
import Style from 'Core/Style';
import TMSSource from 'Source/TMSSource';
import URLBuilder from 'Provider/URLBuilder';
import Fetcher from 'Provider/Fetcher';
import urlParser from 'Parser/MapBoxUrlParser';

function toTMSUrl(url) {
return url.replace(/\{/g, '${');
}

function fetchSourceData(source, url) {
return source.fetcher(url, source.networkOptions)
.then(f => f, err => source.handlingError(err));
}

function mergeCollections(collections) {
const collection = collections[0];
collections.forEach((col, index) => {
if (index === 0) { return; }
col.features.forEach((feature) => {
collection.features.push(feature);
});
});
return collection;
}

/**
* @classdesc
* VectorTilesSource are object containing informations on how to fetch vector
Expand Down Expand Up @@ -86,9 +103,6 @@ class VectorTilesSource extends TMSSource {

return style;
}).then((style) => {
const s = Object.keys(style.sources)[0];
const os = style.sources[s];

style.layers.forEach((layer, order) => {
layer.sourceUid = this.uid;
if (layer.type === 'background') {
Expand All @@ -113,17 +127,34 @@ class VectorTilesSource extends TMSSource {
});

if (this.url == '.') {
if (os.url) {
const urlSource = urlParser.normalizeSourceURL(os.url, this.accessToken);
return Fetcher.json(urlSource, this.networkOptions).then((tileJSON) => {
if (tileJSON.tiles[0]) {
this.url = toTMSUrl(tileJSON.tiles[0]);
}
});
} else if (os.tiles[0]) {
this.url = toTMSUrl(os.tiles[0]);
}
const TMSUrlList = Object.values(style.sources).map((source) => {
if (source.url) {
const urlSource = urlParser.normalizeSourceURL(source.url, this.accessToken);
return Fetcher.json(urlSource, this.networkOptions).then((tileJSON) => {
if (tileJSON.tiles[0]) {
return toTMSUrl(tileJSON.tiles[0]);
}
});
} else if (source.tiles) {
return Promise.resolve(toTMSUrl(source.tiles[0]));
}
return Promise.reject();
});
return Promise.all(TMSUrlList);
}
return (Promise.resolve([this.url]));
}).then((TMSUrlList) => {
this.url = new Set(TMSUrlList);
});
}

urlFromExtent(extent) {
return this.url.map((url) => {
const options = {
tileMatrixCallback: this.tileMatrixCallback,
url,
};
return URLBuilder.xyz(extent, options);
});
}

Expand All @@ -136,6 +167,35 @@ class VectorTilesSource extends TMSSource {
}
}
}

loadData(extent, out) {
const cache = this._featuresCaches[out.crs];
const key = this.requestToKey(extent);
// try to get parsed data from cache
let features = cache.getByArray(key);
if (!features) {
// otherwise fetch/parse the data
features = cache.setByArray(
Promise.all(this.urlFromExtent(extent).map(url =>
fetchSourceData(this, url)
.then((file) => {
file.extent = extent;
return this.parser(file, { out, in: this });
}),
)).then(collections => mergeCollections(collections),
err => this.handlingError(err)), key);

/* istanbul ignore next */
if (this.onParsedFile) {
features.then((feat) => {
this.onParsedFile(feat);
console.warn('Source.onParsedFile was deprecated');
return feat;
});
}
}
return features;
}
}

export default VectorTilesSource;
6 changes: 3 additions & 3 deletions test/functional/vector_tile_3d_mesh_mapbox.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const assert = require('assert');

describe('vector_tile_3d_mesh_mapbox', function _() {
describe('vector_tile_3d_mesh_mapbox', function _describe() {
let result;
before(async () => {
result = await loadExample('examples/vector_tile_3d_mesh_mapbox.html', this.fullTitle());
Expand All @@ -10,8 +10,8 @@ describe('vector_tile_3d_mesh_mapbox', function _() {
assert.ok(result);
});

it('should correctly load building features on a given TMS tile', async function _2() {
const featuresCollection = await page.evaluate(async function _3() {
it('should correctly load building features on a given TMS tile', async function _it() {
const featuresCollection = await page.evaluate(async function _() {
const layers = view.getLayers(l => l.source && l.source.isVectorSource);
const res = await layers[0].source.loadData({ zoom: 15, row: 11634, col: 16859 }, { crs: 'EPSG:4978', source: { crs: 'TMS:3857' } });
return res;
Expand Down
Loading

0 comments on commit c51e64a

Please sign in to comment.