diff --git a/src/Core/Scheduler/Providers/3dTiles_Provider.js b/src/Core/Scheduler/Providers/3dTiles_Provider.js index 15a35573f6..63ba4a5473 100644 --- a/src/Core/Scheduler/Providers/3dTiles_Provider.js +++ b/src/Core/Scheduler/Providers/3dTiles_Provider.js @@ -1,5 +1,4 @@ import * as THREE from 'three'; -import Provider from './Provider'; import B3dmLoader from '../../../Renderer/ThreeExtended/B3dmLoader'; import PntsLoader from '../../../Renderer/ThreeExtended/PntsLoader'; import Fetcher from './Fetcher'; @@ -10,7 +9,6 @@ import Capabilities from '../../System/Capabilities'; import PrecisionQualifier from '../../../Renderer/Shader/Chunk/PrecisionQualifier.glsl'; import { init3dTilesLayer } from '../../../Process/3dTilesProcessing'; - function $3dTilesIndex(tileset, baseURL) { let counter = 0; this.index = {}; @@ -63,19 +61,7 @@ function $3dTilesIndex(tileset, baseURL) { }; } -function $3dTiles_Provider() { - Provider.call(this); -} - -$3dTiles_Provider.prototype = Object.create(Provider.prototype); - -$3dTiles_Provider.prototype.constructor = $3dTiles_Provider; - -$3dTiles_Provider.prototype.removeLayer = function removeLayer() { - -}; - -$3dTiles_Provider.prototype.preprocessDataLayer = function preprocessDataLayer(layer, view, scheduler) { +function preprocessDataLayer(layer, view, scheduler) { layer.sseThreshold = layer.sseThreshold || 16; layer.cleanupDelay = layer.cleanupDelay || 1000; @@ -87,7 +73,7 @@ $3dTiles_Provider.prototype.preprocessDataLayer = function preprocessDataLayer(l layer.asset = tileset.asset; return init3dTilesLayer(view, scheduler, layer, tileset.root); }); -}; +} function getBox(volume, inverseTileTransform) { if (volume.region) { @@ -159,9 +145,11 @@ export function patchMaterialForLogDepthSupport(material) { }; } -$3dTiles_Provider.prototype.b3dmToMesh = function b3dmToMesh(data, layer, url) { - this._b3dmLoader = this._b3dmLoader || new B3dmLoader(); - return this._b3dmLoader.parse(data, layer.asset.gltfUpAxis, url, this._textDecoder).then((result) => { +let b3dmLoader; +let textDecoder; +function b3dmToMesh(data, layer, url) { + b3dmLoader = b3dmLoader || new B3dmLoader(); + return b3dmLoader.parse(data, layer.asset.gltfUpAxis, url, textDecoder).then((result) => { const init = function f_init(mesh) { mesh.frustumCulled = false; if (mesh.material) { @@ -189,13 +177,13 @@ $3dTiles_Provider.prototype.b3dmToMesh = function b3dmToMesh(data, layer, url) { const object3d = result.gltf.scene; return { batchTable, object3d }; }); -}; +} -$3dTiles_Provider.prototype.pntsParse = function pntsParse(data) { +function pntsParse(data) { return new Promise((resolve) => { - resolve({ object3d: PntsLoader.parse(data, this._textDecoder).point }); + resolve({ object3d: PntsLoader.parse(data, textDecoder).point }); }); -}; +} function configureTile(tile, layer, metadata, parent) { tile.frustumCulled = false; @@ -220,14 +208,13 @@ function configureTile(tile, layer, metadata, parent) { tile.updateMatrixWorld(); } -$3dTiles_Provider.prototype.executeCommand = function executeCommand(command) { +function executeCommand(command) { const layer = command.layer; const metadata = command.metadata; const tile = new THREE.Object3D(); configureTile(tile, layer, metadata, command.requester); const path = metadata.content ? metadata.content.url : undefined; - this._textDecoder = this._textDecoder || new TextDecoder('utf-8'); - const textDecoder = this._textDecoder; + textDecoder = textDecoder || new TextDecoder('utf-8'); const setLayer = (obj) => { obj.layers.set(layer.threejsLayer); @@ -236,8 +223,8 @@ $3dTiles_Provider.prototype.executeCommand = function executeCommand(command) { // Check if we have relative or absolute url (with tileset's lopocs for example) const url = path.startsWith('http') ? path : metadata.baseURL + path; const supportedFormats = { - b3dm: this.b3dmToMesh.bind(this), - pnts: this.pntsParse.bind(this), + b3dm: b3dmToMesh, + pnts: pntsParse, }; return Fetcher.arrayBuffer(url, layer.networkOptions).then((result) => { if (result !== undefined) { @@ -276,6 +263,9 @@ $3dTiles_Provider.prototype.executeCommand = function executeCommand(command) { resolve(tile); }); } -}; +} -export default $3dTiles_Provider; +export default { + preprocessDataLayer, + executeCommand, +}; diff --git a/src/Core/Scheduler/Providers/BuildingBox_Provider.js b/src/Core/Scheduler/Providers/BuildingBox_Provider.js deleted file mode 100644 index 0a887b517e..0000000000 --- a/src/Core/Scheduler/Providers/BuildingBox_Provider.js +++ /dev/null @@ -1,211 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ - - -/** - * Generated On: 2015-10-5 - * Class: WMTS_Provider - * Description: Fournisseur de données à travers un flux WMTS - */ - - -// TODO , will use WFS_Provider -import * as THREE from 'three'; -import Earcut from 'earcut'; -import Provider from './Provider'; -import WFS_Provider from './WFS_Provider'; -import Coordinates, { C } from '../../Geographic/Coordinates'; - -function BuildingBox_Provider(options) { - // Constructor - - // Provider.call( this,new IoDriver_XBIL()); - // this.cache = CacheRessource(); - this.WFS_Provider = new WFS_Provider(options); - this.geometry = null; - this.geometryRoof = null; - this.pivot = null; - this.roadOn = true; - this.rtcOn = true; -} - -BuildingBox_Provider.prototype = Object.create(Provider.prototype); -BuildingBox_Provider.prototype.constructor = BuildingBox_Provider; - - -/** - * Return url wmts MNT - * @param {number} longitude - * @param {number} latitude - * @param {number} radius - * @returns {string} - */ -BuildingBox_Provider.prototype.url = function url(longitude, latitude, radius) { - // var key = "wmybzw30d6zg563hjlq8eeqb"; - // var key = coWMTS.zoom > 11 ? "va5orxd0pgzvq3jxutqfuy0b" : "wmybzw30d6zg563hjlq8eeqb"; // clef pro va5orxd0pgzvq3jxutqfuy0b - - var key = '72hpsel8j8nhb5qgdh07gcyp'; - - // var layer = "BDTOPO_BDD_WLD_WGS84G:bati_remarquable,BDTOPO_BDD_WLD_WGS84G:bati_indifferencie" - var serviceVersionRequestLayer = 'service=WFS&version=2.0.0&REQUEST=GetFeature&typeName=BDTOPO_BDD_WLD_WGS84G:bati_remarquable,BDTOPO_BDD_WLD_WGS84G:bati_indifferencie'; - - var bottomLeft = new THREE.Vector2(longitude - radius, latitude - radius); - var topRight = new THREE.Vector2(longitude + radius, latitude + radius); - - - var url = `http://wxs.ign.fr/${key}/geoportail/wfs?${serviceVersionRequestLayer - }&bbox=${bottomLeft.x},${bottomLeft.y},${topRight.x - },${topRight.y},epsg:4326&outputFormat=json`; - - return url; -}; - -BuildingBox_Provider.prototype.getData = function getData(bbox, altitude) { - return this.WFS_Provider.getData(bbox).then((data) => { - this.generateMesh(data, bbox, altitude); // console.log(data); - return this.geometry; - }); -}; - -BuildingBox_Provider.prototype.generateMesh = function generateMesh(elements, bbox, altitude) { - var roofGeometry = new THREE.Geometry(); // for the roof - var _geometry = new THREE.Geometry(); // for the walls - var geometry = new THREE.Geometry(); // for the roof - var suppHeight = 10; // So we don't cut the roof - var features = elements.features; - var altitude_ground = altitude - 1.5; // 35; // truck height - - for (const feature of features) { - const hauteur = (feature.properties.hauteur + suppHeight) || 0; - const z_min = altitude_ground; // features[r].properties.z_min; // altitude_ground // force altitude ground - const polygon = feature.geometry.coordinates[0][0]; - - const arrPoint2D = []; - if (polygon.length > 2) { - // VERTICES - for (let j = 0; j < polygon.length - 1; ++j) { - const pt2DTab = polygon[j]; // .split(' '); - const p1 = new THREE.Vector3(parseFloat(pt2DTab[0]), 0, parseFloat(pt2DTab[1])); - - const coordCarto1 = new Coordinates('EPSG:4326', p1.x, p1.z, z_min); - const coordCarto2 = new Coordinates('EPSG:4326', p1.x, p1.z, z_min + hauteur); // + Math.random(1000) ); - const pgeo1 = coordCarto1.as('EPSG:4978').xyz(); - const pgeo2 = coordCarto2.as('EPSG:4978').xyz(); - - const vector3_1 = new THREE.Vector3(pgeo1.x, pgeo1.y, pgeo1.z); // - x temporary, bug - const vector3_2 = new THREE.Vector3(pgeo2.x, pgeo2.y, pgeo2.z); - - - arrPoint2D.push(p1.z, p1.x); - _geometry.vertices.push(vector3_1, vector3_2); - } - - // FACES - // indice of the first point of the polygon 3D - for (let k = _geometry.vertices.length - ((polygon.length - 1) * 2); k < _geometry.vertices.length; k += 2) { - let l = k; // % (pts2DTab.length); - if (l > _geometry.vertices.length - 4) { - l = _geometry.vertices.length - ((polygon.length - 1) * 2); - } - _geometry.faces.push(new THREE.Face3(l, l + 1, l + 3)); - _geometry.faces.push(new THREE.Face3(l, l + 3, l + 2)); - } - - const ll = _geometry.vertices.length - ((polygon.length - 1) * 2); - _geometry.faces.push(new THREE.Face3(ll, ll + 1, _geometry.vertices.length - 1)); - _geometry.faces.push(new THREE.Face3(ll, _geometry.vertices.length - 1, _geometry.vertices.length - 2)); - } - - //* *************** ROOF **************************** - - var triangles = Earcut(arrPoint2D); - for (let w = 0; w < triangles.length; w += 3) { - const pt1 = new THREE.Vector2(arrPoint2D[triangles[w] * 2], arrPoint2D[triangles[w] * 2 + 1]); - const pt2 = new THREE.Vector2(arrPoint2D[triangles[w + 1] * 2], arrPoint2D[triangles[w + 1] * 2 + 1]); - const pt3 = new THREE.Vector2(arrPoint2D[triangles[w + 2] * 2], arrPoint2D[triangles[w + 2] * 2 + 1]); - const c1 = new C.EPSG_4326(pt1.x, pt1.y, z_min + hauteur); - const c2 = new C.EPSG_4326(pt2.x, pt2.y, z_min + hauteur); - const c3 = new C.EPSG_4326(pt3.x, pt3.y, z_min + hauteur); - - roofGeometry.vertices.push(c1.as('EPSG:4978').xyz()); - roofGeometry.vertices.push(c2.as('EPSG:4978').xyz()); - roofGeometry.vertices.push(c3.as('EPSG:4978').xyz()); - - var face = new THREE.Face3(geometry.vertices.length - 3, - geometry.vertices.length - 2, - geometry.vertices.length - 1); - geometry.faces.push(face); - } - } - - if (this.roadOn) { - this.addRoad(_geometry, bbox, altitude_ground); - } - - _geometry.computeFaceNormals(); // WARNING : VERY IMPORTANT WHILE WORKING WITH RAY CASTING ON CUSTOM MESH - geometry.computeFaceNormals(); - - /* - var matLambert = new THREE.MeshBasicMaterial({color: 0xffffff, transparent: true, opacity: 0.8}); - var _currentMeshForRoof = new THREE.Mesh(_geometry, matLambert);// //geometryClickToGo,mat); - gfxEngine().add3DScene(_currentMeshForRoof); - */ - - // Test if we return brute geometry or if we use local pivot (for useRTC) - var firstPos = new THREE.Vector3(); - if (this.rtcOn) { - firstPos = _geometry.vertices[0].clone(); - // create pivot from 1st pos vertex - for (const vertice of _geometry.vertices) { - vertice.sub(firstPos); - } - for (const vertice of geometry.vertices) { - vertice.sub(firstPos); - } - } - - this.geometry = _geometry; - this.pivot = firstPos; - this.geometryRoof = geometry; - - return { - geometry: _geometry, - pivot: firstPos, - geometryRoof: geometry, - }; -}; - - -BuildingBox_Provider.prototype.addRoad = function addRoad(geometry, bbox, altitude_road) { - // Version using SIMPLE PLANE ROAD for Click and Go - var ratio = 0.2; - var roadWidth = (bbox.east() - bbox.west()) * ratio; - var roadHeight = (bbox.north() - bbox.south()) * ratio; - var pos = new THREE.Vector3((bbox.south() + bbox.north()) / 2, - altitude_road, (bbox.west() + bbox.east()) / 2); // 48.8505774, altitude_sol, 2.3348124); - - var coordCarto1 = new Coordinates('EPSG:4326', pos.x - roadWidth, pos.z - roadHeight, altitude_road); - var coordCarto2 = new Coordinates('EPSG:4326', pos.x - roadWidth, pos.z + roadHeight, altitude_road); - var coordCarto3 = new Coordinates('EPSG:4326', pos.x + roadWidth, pos.z + roadHeight, altitude_road); - var coordCarto4 = new Coordinates('EPSG:4326', pos.x + roadWidth, pos.z - roadHeight, altitude_road); - - var pgeo1 = coordCarto1.as('EPSG:4978').xyz(); - var pgeo2 = coordCarto2.as('EPSG:4978').xyz(); - var pgeo3 = coordCarto3.as('EPSG:4978').xyz(); - var pgeo4 = coordCarto4.as('EPSG:4978').xyz(); - - geometry.vertices.push(new THREE.Vector3(pgeo1.x, pgeo1.y, pgeo1.z)); - geometry.vertices.push(new THREE.Vector3(pgeo2.x, pgeo2.y, pgeo2.z)); - geometry.vertices.push(new THREE.Vector3(pgeo3.x, pgeo3.y, pgeo3.z)); - geometry.vertices.push(new THREE.Vector3(pgeo4.x, pgeo4.y, pgeo4.z)); - - var len = geometry.vertices.length; - geometry.faces.push(new THREE.Face3(len - 4, len - 3, len - 2)); - geometry.faces.push(new THREE.Face3(len - 4, len - 2, len - 1)); -}; - - -export default BuildingBox_Provider; diff --git a/src/Core/Scheduler/Providers/KML_Provider.js b/src/Core/Scheduler/Providers/KML_Provider.js deleted file mode 100644 index a951ddbbb9..0000000000 --- a/src/Core/Scheduler/Providers/KML_Provider.js +++ /dev/null @@ -1,655 +0,0 @@ -import * as THREE from 'three'; -import Provider from './Provider'; -import Fetcher from './Fetcher'; -import KMZLoader from '../../../Renderer/ThreeExtended/KMZLoader'; - -function KML_Provider(ellipsoid) { - this.ellipsoid = ellipsoid; - this.kmzLoader = new KMZLoader(); - this.cache = new Map(); -} - -KML_Provider.prototype = Object.create(Provider.prototype); - -KML_Provider.prototype.constructor = KML_Provider; - - -const position = new THREE.Vector3(); -const axisX = new THREE.Vector3(1, 0, 0); -KML_Provider.prototype.loadKMZ = function loadKMZ(longitude, latitude) { - return this.getUrlCollada(longitude, latitude).then((result) => { - if (result === undefined) - { return undefined; } - - if (result.scene.children[0]) { - var child = result.scene.children[0]; - var coorCarto = result.coorCarto; - - this.ellipsoid.cartographicToCartesian(coorCarto, position); - coorCarto.altitude = 0; - var normal = this.ellipsoid.geodeticSurfaceNormalCartographic(coorCarto); - - var quaternion = new THREE.Quaternion(); - quaternion.setFromAxisAngle(axisX, Math.PI / 2); - - child.lookAt(position.add(normal)); - child.quaternion.multiply(quaternion); - child.position.copy(position); - - child.updateMatrix(); - child.visible = false; - - var changeMaterial = function changeMaterial(object3D) { - if (object3D.material instanceof THREE.MultiMaterial) { - object3D.material = new THREE.MeshBasicMaterial({ color: object3D.material.materials[0].color }); - } else if (object3D.material) - { object3D.material = new THREE.MeshBasicMaterial({ color: object3D.material.color }); } - }; - - - child.traverse(changeMaterial); - - return child; - } - return undefined; - }); -}; - -KML_Provider.prototype.parseKML = function parseKML(urlFile, longitude, latitude, networkOptions) { - var north = latitude; - var south = latitude; - var east = longitude; - var west = longitude; - var key = 'va5orxd0pgzvq3jxutqfuy0b'; - var url = `http://wxs.ign.fr/${key}/vecteurtuile3d/BATI3D/FXX/`; - return Fetcher.xml(urlFile, networkOptions).then((result) => { - var NetworkLink = []; - NetworkLink = result.getElementsByTagName('NetworkLink'); - - for (var i = 0; i < NetworkLink.length; i++) { - var coords = []; - coords[0] = NetworkLink[i].getElementsByTagName('north')[0].childNodes[0].nodeValue; - coords[1] = NetworkLink[i].getElementsByTagName('south')[0].childNodes[0].nodeValue; - coords[2] = NetworkLink[i].getElementsByTagName('east')[0].childNodes[0].nodeValue; - coords[3] = NetworkLink[i].getElementsByTagName('west')[0].childNodes[0].nodeValue; - - - if (north < coords[0] && south > coords[1] && east < coords[2] && west > coords[3]) { - var href = []; - href[i] = `${url}TREE/${NetworkLink[i].getElementsByTagName('href')[0].childNodes[0].nodeValue.replace('../', '')}`; - - if (href[i].toLowerCase().substr(-4) === '.kml') { - return this.parseKML(href[i], longitude, latitude); - } - // Next level : Get the next KMZ actual position's coords - else if (href[i].toLowerCase().substr(-4) === '.kmz') { - var url_kmz = url + NetworkLink[i].getElementsByTagName('href')[0].childNodes[0].nodeValue.replace('../../', ''); - // url_kmz = "http://localhost:8383/kmz/BT_000092.kmz"; - - var p = this.cache[url_kmz]; - if (!p) { - p = this.kmzLoader.load(url_kmz); - this.cache[url_kmz] = p; - } - return p; - } - } - } - }); -}; - - -KML_Provider.prototype.getUrlCollada = function getUrlCollada(longitude, latitude) { - return Fetcher.xml('http://wxs.ign.fr/va5orxd0pgzvq3jxutqfuy0b/vecteurtuile3d/BATI3D/BU.Building.kml').then(() => { - // get href's node value - // var kml_0 = result_0.getElementsByTagName("href"); - var url_href_1; - var key = 'va5orxd0pgzvq3jxutqfuy0b'; - - url_href_1 = `http://wxs.ign.fr/${key}/vecteurtuile3d/BATI3D/FXX/TREE/0/0_000_000.kml`; - - return this.parseKML(url_href_1, longitude, latitude); - }); -}; - -export default KML_Provider; -// If France -// if (url_href_1[i] === 'http://wxs.ign.fr/' + key + '/vecteurtuile3d/BATI3D/FXX/TREE/0/0_000_000.kml'){ -// //this.ParseKML(url_href_1[i]); -// //console.log("wesh"); -// Fetcher.xml(url_href_1[i]).then(function(result_1) -// { -// var kml_1 = []; -// kml_1 = result_1.getElementsByTagName("href"); -// //console.log(kml_1.length); -// -// for (j=0; j coords_3[k,2] && east < coords_3[k,3] && west > coords_3[k,4]){ -// -// Fetcher.xml(url_href_3[k]).then(function(result_3){ -// -// var kml_3 = []; -// kml_3 = result_3.getElementsByTagName("href"); -// -// for (l=0; l coords_4[l,2] && east < coords_4[l,3] && west > coords_4[l,4]){ -// -// Fetcher.xml(url_href_4[l]).then(function(result_4){ -// -// var kml_4 = []; -// kml_4 = result_4.getElementsByTagName("href"); -// -// //Get KMZ -// for (m=0; m coords_3[k,2] && east < coords_3[k,3] && west > coords_3[k,4]){ - Fetcher.xml(url_href_3[k]).then(function(result_3){ - - var kml_3 = []; - kml_3 = result_3.getElementsByTagName("href"); - - for (l=0; l coords_3[k,2] && east < coords_3[k,3] && west > coords_3[k,4]){ - Fetcher.xml(url_href_3[k]).then(function(result_3){ - - var kml_3 = []; - kml_3 = result_3.getElementsByTagName("href"); - - for (l=0; l coords_3[k,2] && east < coords_3[k,3] && west > coords_3[k,4]){ - Fetcher.xml(url_href_3[k]).then(function(result_3){ - - var kml_3 = []; - kml_3 = result_3.getElementsByTagName("href"); - - for (l=0; l coords_3[k,2] && east < coords_3[k,3] && west > coords_3[k,4]){ - Fetcher.xml(url_href_3[k]).then(function(result_3){ - - var kml_3 = []; - kml_3 = result_3.getElementsByTagName("href"); - - for (l=0; l coords_3[k,2] && east < coords_3[k,3] && west > coords_3[k,4]){ - Fetcher.xml(url_href_3[k]).then(function(result_3){ - - var kml_3 = []; - kml_3 = result_3.getElementsByTagName("href"); - - for (l=0; l { + return OGCWebServiceHelper.getColorTextureByUrl(urld, layer.networkOptions).then((texture) => { const result = {}; result.texture = texture; result.texture.coords = coordTMSParent || coordTMS; @@ -52,13 +49,13 @@ TMS_Provider.prototype.executeCommand = function executeCommand(command) { } return result; }); -}; +} -TMS_Provider.prototype.tileTextureCount = function tileTextureCount(tile, layer) { - return this.tileInsideLimit(tile, layer) ? 1 : 0; -}; +function tileTextureCount(tile, layer) { + return tileInsideLimit(tile, layer) ? 1 : 0; +} -TMS_Provider.prototype.tileInsideLimit = function tileInsideLimit(tile, layer, targetLevel) { +function tileInsideLimit(tile, layer, targetLevel) { // assume 1 TMS texture per tile (ie: tile geometry CRS is the same as layer's CRS) let tmsCoord = tile.getCoordsForLayer(layer)[0]; @@ -68,6 +65,11 @@ TMS_Provider.prototype.tileInsideLimit = function tileInsideLimit(tile, layer, t return layer.options.zoom.min <= tmsCoord.zoom && tmsCoord.zoom <= layer.options.zoom.max; -}; +} -export default TMS_Provider; +export default { + preprocessDataLayer, + executeCommand, + tileTextureCount, + tileInsideLimit, +}; diff --git a/src/Core/Scheduler/Providers/TileProvider.js b/src/Core/Scheduler/Providers/TileProvider.js index 706fddc234..3b186f7b32 100644 --- a/src/Core/Scheduler/Providers/TileProvider.js +++ b/src/Core/Scheduler/Providers/TileProvider.js @@ -4,22 +4,14 @@ * and open the template in the editor. */ import * as THREE from 'three'; -import Provider from './Provider'; import TileGeometry from '../../TileGeometry'; import TileMesh from '../../TileMesh'; import CancelledCommandException from '../CancelledCommandException'; import { requestNewTile } from '../../../Process/TiledNodeProcessing'; -function TileProvider() { - Provider.call(this, null); - this.cacheGeometry = new Map(); -} - -TileProvider.prototype = Object.create(Provider.prototype); +const cacheGeometry = new Map(); -TileProvider.prototype.constructor = TileProvider; - -TileProvider.prototype.preprocessDataLayer = function preprocessLayer(layer, view, scheduler) { +function preprocessDataLayer(layer, view, scheduler) { if (!layer.schemeTile) { throw new Error(`Cannot init tiled layer without schemeTile for layer ${layer.id}`); } @@ -39,9 +31,9 @@ TileProvider.prototype.preprocessDataLayer = function preprocessLayer(layer, vie level0.updateMatrixWorld(); } }); -}; +} -TileProvider.prototype.executeCommand = function executeCommand(command) { +function executeCommand(command) { const extent = command.extent; if (command.requester && !command.requester.material) { @@ -58,7 +50,7 @@ TileProvider.prototype.executeCommand = function executeCommand(command) { const segment = layer.segments || 16; const key = `${builder.type}_${layer.disableSkirt ? 0 : 1}_${segment}_${level}_${south}`; - let geometry = this.cacheGeometry.get(key); + let geometry = cacheGeometry.get(key); // build geometry if doesn't exist if (!geometry) { const paramsGeometry = { @@ -69,14 +61,14 @@ TileProvider.prototype.executeCommand = function executeCommand(command) { }; geometry = new TileGeometry(paramsGeometry, builder); - this.cacheGeometry.set(key, geometry); + cacheGeometry.set(key, geometry); geometry._count = 0; geometry.dispose = () => { geometry._count--; if (geometry._count == 0) { THREE.BufferGeometry.prototype.dispose.call(geometry); - this.cacheGeometry.delete(key); + cacheGeometry.delete(key); } }; } @@ -117,6 +109,9 @@ TileProvider.prototype.executeCommand = function executeCommand(command) { } return Promise.resolve(tile); -}; +} -export default TileProvider; +export default { + preprocessDataLayer, + executeCommand, +}; diff --git a/src/Core/Scheduler/Providers/WFS_Provider.js b/src/Core/Scheduler/Providers/WFS_Provider.js index 7293ca25da..c65574703a 100644 --- a/src/Core/Scheduler/Providers/WFS_Provider.js +++ b/src/Core/Scheduler/Providers/WFS_Provider.js @@ -5,21 +5,14 @@ */ import Extent from '../../Geographic/Extent'; -import Provider from './Provider'; import Fetcher from './Fetcher'; import CacheRessource from './CacheRessource'; import GeoJSON2Features from '../../../Renderer/ThreeExtended/GeoJSON2Features'; import Feature2Mesh from '../../../Renderer/ThreeExtended/Feature2Mesh'; -function WFS_Provider() { - this.cache = CacheRessource(); - this.pointOrder = new Map(); -} - -WFS_Provider.prototype = Object.create(Provider.prototype); -WFS_Provider.prototype.constructor = WFS_Provider; +const cache = CacheRessource(); -WFS_Provider.prototype.url = function url(bbox, layer) { +function url(bbox, layer) { const box = bbox.as(layer.projection); const w = box.west(); const s = box.south(); @@ -30,9 +23,9 @@ WFS_Provider.prototype.url = function url(bbox, layer) { const bboxInUnit = `${w},${s},${e},${n}`; return layer.customUrl.replace('%bbox', bboxInUnit); -}; +} -WFS_Provider.prototype.preprocessDataLayer = function preprocessDataLayer(layer) { +function preprocessDataLayer(layer) { if (!layer.typeName) { throw new Error('layer.typeName is required.'); } @@ -50,21 +43,21 @@ WFS_Provider.prototype.preprocessDataLayer = function preprocessDataLayer(layer) }&SRSNAME=${layer.crs }&outputFormat=${layer.format }&BBOX=%bbox,${layer.crs}`; -}; +} -WFS_Provider.prototype.tileInsideLimit = function tileInsideLimit(tile, layer) { +function tileInsideLimit(tile, layer) { return (layer.level === undefined || tile.level === layer.level) && layer.extent.intersectsExtent(tile.extent); -}; +} -WFS_Provider.prototype.executeCommand = function executeCommand(command) { +function executeCommand(command) { const layer = command.layer; const tile = command.requester; const destinationCrs = command.view.referenceCrs; // TODO : support xml, gml2 const supportedFormats = { - json: this.getFeatures.bind(this), - geojson: this.getFeatures.bind(this), + json: getFeatures, + geojson: getFeatures, }; const func = supportedFormats[layer.format]; @@ -73,7 +66,7 @@ WFS_Provider.prototype.executeCommand = function executeCommand(command) { } else { return Promise.reject(new Error(`Unsupported mimetype ${layer.format}`)); } -}; +} function assignLayer(object, layer) { if (object) { @@ -86,15 +79,15 @@ function assignLayer(object, layer) { } } -WFS_Provider.prototype.getFeatures = function getFeatures(crs, tile, layer) { +function getFeatures(crs, tile, layer) { if (!layer.tileInsideLimit(tile, layer) || tile.material === null) { return Promise.resolve(); } - const url = this.url(tile.extent.as(layer.crs), layer); + const urld = url(tile.extent.as(layer.crs), layer); const result = {}; - result.feature = this.cache.getRessource(url); + result.feature = cache.getRessource(url); if (result.feature !== undefined) { return Promise.resolve(result); @@ -102,36 +95,11 @@ WFS_Provider.prototype.getFeatures = function getFeatures(crs, tile, layer) { layer.convert = layer.convert ? layer.convert : Feature2Mesh.convert({}); - return Fetcher.json(url, layer.networkOptions).then(geojson => assignLayer(layer.convert(GeoJSON2Features.parse(crs, geojson, tile.extent, { filter: layer.filter })), layer)); -}; - -WFS_Provider.prototype.getPointOrder = function getPointOrder(crs) { - if (this.pointOrder[crs]) { - return this.pointOrder[crs]; - } + return Fetcher.json(urld, layer.networkOptions).then(geojson => assignLayer(layer.convert(GeoJSON2Features.parse(crs, geojson, tile.extent, { filter: layer.filter })), layer)); +} - var pointOrder = { lat: 0, long: 1 }; - - if (crs.type == 'EPSG' && crs.properties.code == '4326') { - pointOrder.long = 0; - pointOrder.lat = 1; - return pointOrder; - } else if (crs.type == 'name') { - if (crs.properties.name) { - var regExpEpsg = new RegExp(/^urn:[x-]?ogc:def:crs:EPSG:(\d*.?\d*)?:\d{4}/); - if (regExpEpsg.test(crs.properties.name)) { - return pointOrder; - } - else { - var regExpOgc = new RegExp(/^urn:[x-]?ogc:def:crs:OGC:(\d*.?\d*)?:(CRS)?(WSG)?\d{0,2}/); - if (regExpOgc.test(crs.properties.name)) { - pointOrder.long = 0; - pointOrder.lat = 1; - return pointOrder; - } - } - } - } +export default { + preprocessDataLayer, + executeCommand, + tileInsideLimit, }; - -export default WFS_Provider; diff --git a/src/Core/Scheduler/Providers/WMS_Provider.js b/src/Core/Scheduler/Providers/WMS_Provider.js index ffc731fd47..2391ba87cd 100644 --- a/src/Core/Scheduler/Providers/WMS_Provider.js +++ b/src/Core/Scheduler/Providers/WMS_Provider.js @@ -8,16 +8,7 @@ import * as THREE from 'three'; import Extent from '../../Geographic/Extent'; import OGCWebServiceHelper from './OGCWebServiceHelper'; -/** - * Return url wmts MNT - * @param {String} options.url: service base url - * @param {String} options.layer: requested data layer - * @param {String} options.format: image format (default: format/jpeg) - */ -function WMS_Provider() { -} - -WMS_Provider.prototype.url = function url(bbox, layer) { +function url(bbox, layer) { const box = bbox.as(layer.projection); const w = box.west(); const s = box.south(); @@ -29,13 +20,13 @@ WMS_Provider.prototype.url = function url(bbox, layer) { `${w},${s},${e},${n}`; return layer.customUrl.replace('%bbox', bboxInUnit); -}; +} -WMS_Provider.prototype.tileTextureCount = function tileTextureCount(tile, layer) { +function tileTextureCount(tile, layer) { return tile.extent.crs() == layer.projection ? 1 : tile.getCoordsForLayer(layer).length; -}; +} -WMS_Provider.prototype.preprocessDataLayer = function preprocessDataLayer(layer) { +function preprocessDataLayer(layer) { if (!layer.name) { throw new Error('layer.name is required.'); } @@ -86,16 +77,16 @@ WMS_Provider.prototype.preprocessDataLayer = function preprocessDataLayer(layer) `&${crsPropName}=${layer.projection }&WIDTH=${layer.width }&HEIGHT=${layer.width}`; -}; +} -WMS_Provider.prototype.tileInsideLimit = function tileInsideLimit(tile, layer) { +function tileInsideLimit(tile, layer) { return tile.level >= layer.options.zoom.min && tile.level <= layer.options.zoom.max && layer.extent.intersectsExtent(tile.extent); -}; +} -WMS_Provider.prototype.getColorTexture = function getColorTexture(tile, layer, targetLevel, tileCoords) { - if (!this.tileInsideLimit(tile, layer)) { +function getColorTexture(tile, layer, targetLevel, tileCoords) { + if (!tileInsideLimit(tile, layer)) { return Promise.reject(`Tile '${tile}' is outside layer bbox ${layer.extent}`); } if (tile.material === null) { @@ -119,11 +110,11 @@ WMS_Provider.prototype.getColorTexture = function getColorTexture(tile, layer, t } const coords = extent.as(layer.projection); - const url = this.url(coords, layer); + const urld = url(coords, layer); const pitch = tileCoords ? new THREE.Vector4(0, 0, 1, 1) : tile.extent.offsetToParent(extent); const result = { pitch }; - return OGCWebServiceHelper.getColorTextureByUrl(url, layer.networkOptions).then((texture) => { + return OGCWebServiceHelper.getColorTextureByUrl(urld, layer.networkOptions).then((texture) => { result.texture = texture; result.texture.extent = extent; if (layer.transparent) { @@ -139,17 +130,17 @@ WMS_Provider.prototype.getColorTexture = function getColorTexture(tile, layer, t } return result; }); -}; +} -WMS_Provider.prototype.executeCommand = function executeCommand(command) { +function executeCommand(command) { const tile = command.requester; const layer = command.layer; - const getTextureFunction = tile.extent.crs() == layer.projection ? this.getColorTexture : this.getColorTextures; + const getTextureFunction = tile.extent.crs() == layer.projection ? getColorTexture : getColorTextures; const supportedFormats = { - 'image/png': getTextureFunction.bind(this), - 'image/jpg': getTextureFunction.bind(this), - 'image/jpeg': getTextureFunction.bind(this), + 'image/png': getTextureFunction, + 'image/jpg': getTextureFunction, + 'image/jpeg': getTextureFunction, }; const func = supportedFormats[layer.format]; @@ -159,20 +150,25 @@ WMS_Provider.prototype.executeCommand = function executeCommand(command) { } else { return Promise.reject(new Error(`Unsupported mimetype ${layer.format}`)); } -}; +} // In the case where the tilematrixset of the tile don't correspond to the projection of the layer // when the projection of the layer corresponds to a tilematrixset inside the tile, like the PM -WMS_Provider.prototype.getColorTextures = function getColorTextures(tile, layer, targetLevel) { +function getColorTextures(tile, layer, targetLevel) { if (tile.material === null) { return Promise.resolve(); } const promises = []; for (const coord of tile.getCoordsForLayer(layer)) { - promises.push(this.getColorTexture(tile, layer, targetLevel, coord)); + promises.push(getColorTexture(tile, layer, targetLevel, coord)); } return Promise.all(promises); -}; +} -export default WMS_Provider; +export default { + preprocessDataLayer, + executeCommand, + tileTextureCount, + tileInsideLimit, +}; diff --git a/src/Core/Scheduler/Providers/WMTS_Provider.js b/src/Core/Scheduler/Providers/WMTS_Provider.js index b8c4dffdd1..285d2c649a 100644 --- a/src/Core/Scheduler/Providers/WMTS_Provider.js +++ b/src/Core/Scheduler/Providers/WMTS_Provider.js @@ -8,18 +8,17 @@ import * as THREE from 'three'; import OGCWebServiceHelper from './OGCWebServiceHelper'; import Extent from '../../Geographic/Extent'; -function WMTS_Provider() { -} +const coordTile = new Extent('WMTS:WGS84', 0, 0, 0); -WMTS_Provider.prototype.customUrl = function customUrl(layer, url, tilematrix, row, col) { +function customUrl(layer, url, tilematrix, row, col) { let urld = url.replace('%TILEMATRIX', tilematrix.toString()); urld = urld.replace('%ROW', row.toString()); urld = urld.replace('%COL', col.toString()); return urld; -}; +} -WMTS_Provider.prototype.preprocessDataLayer = function preprocessDataLayer(layer) { +function preprocessDataLayer(layer) { layer.fx = layer.fx || 0.0; layer.options = layer.options || {}; @@ -56,7 +55,7 @@ WMTS_Provider.prototype.preprocessDataLayer = function preprocessDataLayer(layer layer.customUrl = newBaseUrl; } layer.options.zoom = layer.options.zoom || { min: 2, max: 20 }; -}; +} /** * Return url wmts orthophoto @@ -64,9 +63,9 @@ WMTS_Provider.prototype.preprocessDataLayer = function preprocessDataLayer(layer * @param {Layer} layer * @returns {string} */ -WMTS_Provider.prototype.url = function url(coWMTS, layer) { - return this.customUrl(layer, layer.customUrl, coWMTS.zoom, coWMTS.row, coWMTS.col); -}; +function url(coWMTS, layer) { + return customUrl(layer, layer.customUrl, coWMTS.zoom, coWMTS.row, coWMTS.col); +} /** * return texture float alpha THREE.js of MNT @@ -75,7 +74,7 @@ WMTS_Provider.prototype.url = function url(coWMTS, layer) { * @param {number} targetZoom * @returns {Promise} */ -WMTS_Provider.prototype.getXbilTexture = function getXbilTexture(tile, layer, targetZoom) { +function getXbilTexture(tile, layer, targetZoom) { const pitch = new THREE.Vector4(0.0, 0.0, 1.0, 1.0); let coordWMTS = tile.getCoordsForLayer(layer)[0]; @@ -83,9 +82,9 @@ WMTS_Provider.prototype.getXbilTexture = function getXbilTexture(tile, layer, ta coordWMTS = OGCWebServiceHelper.WMTS_WGS84Parent(coordWMTS, targetZoom, pitch); } - const url = this.url(coordWMTS, layer); + const urld = url(coordWMTS, layer); - return OGCWebServiceHelper.getXBilTextureByUrl(url, layer.networkOptions).then((texture) => { + return OGCWebServiceHelper.getXBilTextureByUrl(urld, layer.networkOptions).then((texture) => { texture.coords = coordWMTS; return { texture, @@ -94,7 +93,7 @@ WMTS_Provider.prototype.getXbilTexture = function getXbilTexture(tile, layer, ta max: !texture.max ? 0 : texture.max, }; }); -}; +} /** * Return texture RGBA THREE.js of orthophoto @@ -103,9 +102,9 @@ WMTS_Provider.prototype.getXbilTexture = function getXbilTexture(tile, layer, ta * @param {Layer} layer * @returns {Promise} */ -WMTS_Provider.prototype.getColorTexture = function getColorTexture(coordWMTS, layer) { - const url = this.url(coordWMTS, layer); - return OGCWebServiceHelper.getColorTextureByUrl(url, layer.networkOptions).then((texture) => { +function getColorTexture(coordWMTS, layer) { + const urld = url(coordWMTS, layer); + return OGCWebServiceHelper.getColorTextureByUrl(urld, layer.networkOptions).then((texture) => { const result = {}; result.texture = texture; result.texture.coords = coordWMTS; @@ -116,17 +115,17 @@ WMTS_Provider.prototype.getColorTexture = function getColorTexture(coordWMTS, la return result; }); -}; +} -WMTS_Provider.prototype.executeCommand = function executeCommand(command) { +function executeCommand(command) { const layer = command.layer; const tile = command.requester; const supportedFormats = { - 'image/png': this.getColorTextures.bind(this), - 'image/jpg': this.getColorTextures.bind(this), - 'image/jpeg': this.getColorTextures.bind(this), - 'image/x-bil;bits=32': this.getXbilTexture.bind(this), + 'image/png': getColorTextures, + 'image/jpg': getColorTextures, + 'image/jpeg': getColorTextures, + 'image/x-bil;bits=32': getXbilTexture, }; const func = supportedFormats[layer.options.mimetype]; @@ -135,17 +134,15 @@ WMTS_Provider.prototype.executeCommand = function executeCommand(command) { } else { return Promise.reject(new Error(`Unsupported mimetype ${layer.options.mimetype}`)); } -}; +} -WMTS_Provider.prototype.tileTextureCount = function tileTextureCount(tile, layer) { +function tileTextureCount(tile, layer) { const tileMatrixSet = layer.options.tileMatrixSet; OGCWebServiceHelper.computeTileMatrixSetCoordinates(tile, tileMatrixSet); return tile.getCoordsForLayer(layer).length; -}; - +} -const coordTile = new Extent('WMTS:WGS84', 0, 0, 0); -WMTS_Provider.prototype.tileInsideLimit = function tileInsideLimit(tile, layer, targetLevel) { +function tileInsideLimit(tile, layer, targetLevel) { // This layer provides data starting at level = layer.options.zoom.min // (the zoom.max property is used when building the url to make // sure we don't use invalid levels) @@ -169,9 +166,9 @@ WMTS_Provider.prototype.tileInsideLimit = function tileInsideLimit(tile, layer, } } return true; -}; +} -WMTS_Provider.prototype.getColorTextures = function getColorTextures(tile, layer) { +function getColorTextures(tile, layer) { if (tile.material === null) { return Promise.resolve(); } @@ -179,10 +176,15 @@ WMTS_Provider.prototype.getColorTextures = function getColorTextures(tile, layer const bcoord = tile.getCoordsForLayer(layer); for (const coordWMTS of bcoord) { - promises.push(this.getColorTexture(coordWMTS, layer)); + promises.push(getColorTexture(coordWMTS, layer)); } return Promise.all(promises); -}; +} -export default WMTS_Provider; +export default { + preprocessDataLayer, + executeCommand, + tileTextureCount, + tileInsideLimit, +}; diff --git a/src/Core/Scheduler/Scheduler.js b/src/Core/Scheduler/Scheduler.js index 1432caef86..749b148d20 100644 --- a/src/Core/Scheduler/Scheduler.js +++ b/src/Core/Scheduler/Scheduler.js @@ -89,16 +89,15 @@ Scheduler.prototype.constructor = Scheduler; Scheduler.prototype.initDefaultProviders = function initDefaultProviders() { // Register all providers - var wmtsProvider = new WMTS_Provider(); - this.addProtocolProvider('wmts', wmtsProvider); - this.addProtocolProvider('wmtsc', wmtsProvider); - this.addProtocolProvider('tile', new TileProvider()); - this.addProtocolProvider('wms', new WMS_Provider()); - this.addProtocolProvider('3d-tiles', new $3dTiles_Provider()); - this.addProtocolProvider('tms', new TMS_Provider()); - this.addProtocolProvider('xyz', new TMS_Provider()); + this.addProtocolProvider('wmts', WMTS_Provider); + this.addProtocolProvider('wmtsc', WMTS_Provider); + this.addProtocolProvider('tile', TileProvider); + this.addProtocolProvider('wms', WMS_Provider); + this.addProtocolProvider('3d-tiles', $3dTiles_Provider); + this.addProtocolProvider('tms', TMS_Provider); + this.addProtocolProvider('xyz', TMS_Provider); this.addProtocolProvider('potreeconverter', PointCloudProvider); - this.addProtocolProvider('wfs', new WFS_Provider()); + this.addProtocolProvider('wfs', WFS_Provider); this.addProtocolProvider('rasterizer', Raster_Provider); this.addProtocolProvider('static', StaticProvider); }; @@ -162,8 +161,14 @@ Scheduler.prototype.execute = function execute(command) { return command.promise; }; - Scheduler.prototype.addProtocolProvider = function addProtocolProvider(protocol, provider) { + if (typeof (provider.executeCommand) !== 'function') { + throw new Error(`Can't add provider for ${protocol}: missing a executeCommand function.`); + } + if (typeof (provider.preprocessDataLayer) !== 'function') { + throw new Error(`Can't add provider for ${protocol}: missing a preprocessDataLayer function.`); + } + this.providers[protocol] = provider; };