From 23e3c1d8189622c143a6a9c9dc8c503e7cea2532 Mon Sep 17 00:00:00 2001 From: ftoromanoff Date: Fri, 15 Mar 2024 16:06:26 +0100 Subject: [PATCH] refactor(Fetcher): supp extent in parsed file --- src/Parser/GeoJsonParser.js | 2 +- src/Parser/VectorTileParser.js | 10 +++---- src/Renderer/RasterTile.js | 2 +- src/Source/OrientedImageSource.js | 1 - src/Source/Source.js | 26 +++++++++---------- src/Source/TMSSource.js | 1 - src/Source/VectorTilesSource.js | 40 ++++++++++------------------ test/unit/dataSourceProvider.js | 26 +++++++++---------- test/unit/vectortiles.js | 43 ++++++++++++------------------- 9 files changed, 61 insertions(+), 90 deletions(-) diff --git a/src/Parser/GeoJsonParser.js b/src/Parser/GeoJsonParser.js index 41905f4dc2..3c31645c5b 100644 --- a/src/Parser/GeoJsonParser.js +++ b/src/Parser/GeoJsonParser.js @@ -217,7 +217,7 @@ export default { if (out.filteringExtent) { if (typeof out.filteringExtent == 'boolean') { - out.filterExtent = json.extent.as(_in.crs); + out.filterExtent = options.extent.as(_in.crs); } else if (out.filteringExtent.isExtent) { out.filterExtent = out.filteringExtent; } diff --git a/src/Parser/VectorTileParser.js b/src/Parser/VectorTileParser.js index 5dc7986602..0a54d64b79 100644 --- a/src/Parser/VectorTileParser.js +++ b/src/Parser/VectorTileParser.js @@ -123,12 +123,12 @@ function readPBF(file, options) { } // x,y,z tile coordinates - const x = file.extent.col; - const z = file.extent.zoom; + const x = options.extent.col; + const z = options.extent.zoom; // We need to move from TMS to Google/Bing/OSM coordinates // https://alastaira.wordpress.com/2011/07/06/converting-tms-tile-coordinates-to-googlebingosm-tile-coordinates/ // Only if the layer.origin is top - const y = options.in.isInverted ? file.extent.row : (1 << z) - file.extent.row - 1; + const y = options.in.isInverted ? options.extent.row : (1 << z) - options.extent.row - 1; const collection = new FeatureCollection(options.out); @@ -148,7 +148,7 @@ function readPBF(file, options) { for (let i = sourceLayer.length - 1; i >= 0; i--) { const vtFeature = sourceLayer.feature(i); - vtFeature.tileNumbers = { x, y: file.extent.row, z }; + vtFeature.tileNumbers = { x, y: options.extent.row, z }; const layers = options.in.layers[layer_id].filter(l => l.filterExpression.filter({ zoom: z }, vtFeature) && z >= l.zoom.min && z < l.zoom.max); let feature; @@ -174,7 +174,7 @@ function readPBF(file, options) { collection.features.sort((a, b) => a.order - b.order); // TODO verify if is needed to updateExtent for previous features. collection.updateExtent(); - collection.extent = file.extent; + collection.extent = options.extent; collection.isInverted = options.in.isInverted; return Promise.resolve(collection); } diff --git a/src/Renderer/RasterTile.js b/src/Renderer/RasterTile.js index 0aa6a35572..b652d122be 100644 --- a/src/Renderer/RasterTile.js +++ b/src/Renderer/RasterTile.js @@ -99,7 +99,7 @@ class RasterTile extends THREE.EventDispatcher { } setTexture(index, texture, offsetScale) { - this.level = (texture && (index == 0)) ? texture.extent.zoom : this.level; + this.level = (texture && texture.extent && (index == 0)) ? texture.extent.zoom : this.level; this.textures[index] = texture || null; this.offsetScales[index] = offsetScale; this.material.layersNeedUpdate = true; diff --git a/src/Source/OrientedImageSource.js b/src/Source/OrientedImageSource.js index 06addadee9..77385a117c 100644 --- a/src/Source/OrientedImageSource.js +++ b/src/Source/OrientedImageSource.js @@ -17,7 +17,6 @@ class OrientedImageSource extends Source { * to find the good texture for each camera for each panoramic. */ constructor(source) { - source.format = source.format || 'json'; super(source); this.isOrientedImageSource = true; diff --git a/src/Source/Source.js b/src/Source/Source.js index c8183e0ca6..133b4f91ed 100644 --- a/src/Source/Source.js +++ b/src/Source/Source.js @@ -11,7 +11,6 @@ import Cache from 'Core/Scheduler/Cache'; import CRS from 'Core/Geographic/Crs'; export const supportedFetchers = new Map([ - ['image/x-bil;bits=32', Fetcher.textureFloat], ['geojson', Fetcher.json], ['application/json', Fetcher.json], ['application/kml', Fetcher.xml], @@ -20,6 +19,10 @@ export const supportedFetchers = new Map([ ['application/gtx', Fetcher.arrayBuffer], ['application/isg', Fetcher.text], ['application/gdf', Fetcher.text], + ['image/x-bil;bits=32', Fetcher.textureFloat], + ['image/jpeg', Fetcher.texture], + ['image/png', Fetcher.texture], + [undefined, Fetcher.texture], ]); export const supportedParsers = new Map([ @@ -66,14 +69,6 @@ class InformationsData { // eslint-disable-next-line 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; - }, err => source.handlingError(err)); -} - let uid = 0; /** @@ -139,8 +134,8 @@ class Source extends InformationsData { this.url = source.url; this.format = source.format; - this.fetcher = source.fetcher || supportedFetchers.get(source.format) || Fetcher.texture; - this.parser = source.parser || supportedParsers.get(source.format) || (d => d); + this.fetcher = source.fetcher || supportedFetchers.get(source.format); + this.parser = source.parser || supportedParsers.get(source.format) || ((d, opt) => { d.extent = opt.extent; return d; }); this.isVectorSource = (source.parser || supportedParsers.get(source.format)) != undefined; this.networkOptions = source.networkOptions || { crossOrigin: 'anonymous' }; this.attribution = source.attribution; @@ -189,9 +184,12 @@ 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( + this.fetcher(this.urlFromExtent(extent), this.networkOptions) + .then(file => this.parser(file, { out, in: this, extent })) + .catch(err => this.handlingError(err)), + key); + /* istanbul ignore next */ if (this.onParsedFile) { features.then((feat) => { diff --git a/src/Source/TMSSource.js b/src/Source/TMSSource.js index b86301f714..3604ccb21b 100644 --- a/src/Source/TMSSource.js +++ b/src/Source/TMSSource.js @@ -96,7 +96,6 @@ class TMSSource extends Source { this.zoom = source.zoom; this.isInverted = source.isInverted || false; - this.url = source.url; this.crs = CRS.formatToTms(source.crs); this.tileMatrixSetLimits = source.tileMatrixSetLimits; this.extentSetlimits = {}; diff --git a/src/Source/VectorTilesSource.js b/src/Source/VectorTilesSource.js index 979f42e829..601bbc9d6e 100644 --- a/src/Source/VectorTilesSource.js +++ b/src/Source/VectorTilesSource.js @@ -9,11 +9,6 @@ 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) => { @@ -70,6 +65,7 @@ class VectorTilesSource extends TMSSource { source.url = source.url || '.'; super(source); const ffilter = source.filter || (() => true); + this.urls = []; this.layers = {}; this.styles = {}; let promise; @@ -127,16 +123,16 @@ class VectorTilesSource extends TMSSource { }); if (this.url == '.') { - const TMSUrlList = Object.values(style.sources).map((source) => { - if (source.url) { - const urlSource = urlParser.normalizeSourceURL(source.url, this.accessToken); + const TMSUrlList = Object.values(style.sources).map((sourceVT) => { + if (sourceVT.url) { + const urlSource = urlParser.normalizeSourceURL(sourceVT.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])); + } else if (sourceVT.tiles) { + return Promise.resolve(toTMSUrl(sourceVT.tiles[0])); } return Promise.reject(); }); @@ -148,14 +144,8 @@ class VectorTilesSource extends TMSSource { }); } - urlFromExtent(extent) { - return this.url.map((url) => { - const options = { - tileMatrixCallback: this.tileMatrixCallback, - url, - }; - return URLBuilder.xyz(extent, options); - }); + urlFromExtent(extent, url) { + return URLBuilder.xyz(extent, { tileMatrixCallback: this.tileMatrixCallback, url }); } onLayerAdded(options) { @@ -176,14 +166,12 @@ class VectorTilesSource extends TMSSource { 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); + Promise.all(this.urls.map(url => + this.fetcher(this.urlFromExtent(extent, url), this.networkOptions) + .then(file => this.parser(file, { out, in: this, extent })))) + .then(collections => mergeCollections(collections)) + .catch(err => this.handlingError(err)), + key); /* istanbul ignore next */ if (this.onParsedFile) { diff --git a/test/unit/dataSourceProvider.js b/test/unit/dataSourceProvider.js index e43b216295..cec13cee3d 100644 --- a/test/unit/dataSourceProvider.js +++ b/test/unit/dataSourceProvider.js @@ -151,9 +151,8 @@ describe('Provide in Sources', function () { updateLayeredMaterialNodeImagery(context, colorlayer, tile, tile.parent); DataSourceProvider.executeCommand(context.scheduler.commands[0]) .then((textures) => { - assert.equal(textures[0].extent.zoom, zoom); - assert.equal(textures[0].extent.row, 511); - assert.equal(textures[0].extent.col, 512); + assert.equal(textures.length, 1); + assert.equal(textures[0].isTexture, true); done(); }).catch(done); }); @@ -181,12 +180,12 @@ describe('Provide in Sources', function () { updateLayeredMaterialNodeElevation(context, elevationlayer, tile, tile.parent); DataSourceProvider.executeCommand(context.scheduler.commands[0]) .then((textures) => { - assert.equal(textures[0].extent.zoom, zoom); - assert.equal(textures[0].extent.row, 511); - assert.equal(textures[0].extent.col, 512); + assert.equal(textures.length, 1); + assert.equal(textures[0].isTexture, true); done(); }).catch(done); }); + it('should get wms texture with DataSourceProvider', (done) => { colorlayer.source = new WMSSource({ url: 'http://', @@ -211,15 +210,12 @@ describe('Provide in Sources', function () { updateLayeredMaterialNodeImagery(context, colorlayer, tile, tile.parent); DataSourceProvider.executeCommand(context.scheduler.commands[0]) .then((textures) => { - const e = textures[0].extent.as(tile.extent.crs); - assert.equal(e.zoom, zoom); - assert.equal(e.west, tile.extent.west); - assert.equal(e.east, tile.extent.east); - assert.equal(e.north, tile.extent.north); - assert.equal(e.south, tile.extent.south); + assert.equal(textures.length, 1); + assert.equal(textures[0].isTexture, true); done(); }).catch(done); }); + it('should get 4 TileMesh from TileProvider', (done) => { const tile = new TileMesh(geom, material, planarlayer, extent, zoom); material.visible = true; @@ -237,6 +233,7 @@ describe('Provide in Sources', function () { done(); }).catch(done); }); + it('should get 3 meshs with WFS source and DataSourceProvider', (done) => { const tile = new TileMesh(geom, material, planarlayer, extent, featureLayer.zoom.min); material.visible = true; @@ -280,6 +277,7 @@ describe('Provide in Sources', function () { done(); }).catch(done); }); + it('should get 1 texture with WFS source and DataSourceProvider', (done) => { const tile = new TileMesh( geom, @@ -345,9 +343,9 @@ describe('Provide in Sources', function () { .then((result) => { tile.material.setSequence([colorlayer.id]); tile.material.getLayer(colorlayer.id).setTextures(result, [new THREE.Vector4()]); - assert.equal(tile.material.uniforms.colorTextures.value[0].extent, undefined); + assert.equal(tile.material.uniforms.colorTextures.value[0].anisotropy, 1); tile.material.updateLayersUniforms(); - assert.equal(tile.material.uniforms.colorTextures.value[0].extent.zoom, 10); + assert.equal(tile.material.uniforms.colorTextures.value[0].anisotropy, 16); done(); }).catch(done); }); diff --git a/test/unit/vectortiles.js b/test/unit/vectortiles.js index 5a55db0272..9b5b119847 100644 --- a/test/unit/vectortiles.js +++ b/test/unit/vectortiles.js @@ -20,35 +20,24 @@ const resources = { 'https://api.mapbox.com/v4/mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v7.json': mapboxStyle, }; -function parse(pbf, layers) { - return VectorTileParser.parse(pbf, { - in: { - layers, - styles: [[]], - }, - out: { - crs: 'EPSG:3857', - }, - }); -}; - describe('Vector tiles', function () { - let stub; - let multipolygon; - - before(function () { - // this PBF file comes from https://github.com/mapbox/vector-tile-js - // it contains two square polygons - multipolygon = fs.readFileSync('test/data/pbf/multipolygon.pbf'); - multipolygon.extent = new Extent('TMS', 1, 1, 1); - - stub = sinon.stub(Fetcher, 'json') - .callsFake(url => Promise.resolve(JSON.parse(resources[url]))); - }); + // this PBF file comes from https://github.com/mapbox/vector-tile-js + // it contains two square polygons + const multipolygon = fs.readFileSync('test/data/pbf/multipolygon.pbf'); + const extent = new Extent('TMS', 1, 1, 1); - after(function () { - stub.restore(); - }); + function parse(pbf, layers) { + return VectorTileParser.parse(pbf, { + in: { + layers, + styles: [[]], + }, + out: { + crs: 'EPSG:3857', + }, + extent, + }); + } it('returns two squares', (done) => { parse(multipolygon, {