From 61bc55609d0b53daaf6a6e4b926ff5db4d6076cb Mon Sep 17 00:00:00 2001 From: mahmoud adel <58145645+mahmoudadel54@users.noreply.github.com> Date: Tue, 24 Oct 2023 12:42:24 +0300 Subject: [PATCH] #9585: fix zoom to 3d layer to the correct extent in csw catalog (#9610) (#9649) * #9585: fix zoom to 3d layer from csw catalog --- web/client/api/CSW.js | 297 ++-- web/client/api/__tests__/CSW-test.js | 242 +++- .../3dtiles/tileSetSample2.json | 1286 +++++++++++++++++ .../getRecordsResponseDCWith3DLayersAt1st.xml | 79 + ...getRecordsResponseDCWith3DLayersAtLast.xml | 79 + ...tRecordsResponseDCWith3DLayersAtMiddle.xml | 61 + 6 files changed, 1884 insertions(+), 160 deletions(-) create mode 100644 web/client/test-resources/3dtiles/tileSetSample2.json create mode 100644 web/client/test-resources/csw/getRecordsResponseDCWith3DLayersAt1st.xml create mode 100644 web/client/test-resources/csw/getRecordsResponseDCWith3DLayersAtLast.xml create mode 100644 web/client/test-resources/csw/getRecordsResponseDCWith3DLayersAtMiddle.xml diff --git a/web/client/api/CSW.js b/web/client/api/CSW.js index f842cf467a..2d61e4b4e0 100644 --- a/web/client/api/CSW.js +++ b/web/client/api/CSW.js @@ -13,16 +13,17 @@ import assign from 'object-assign'; import axios from '../libs/ajax'; import { cleanDuplicatedQuestionMarks } from '../utils/ConfigUtils'; -import { extractCrsFromURN, makeBboxFromOWS, makeNumericEPSG } from '../utils/CoordinatesUtils'; +import { extractCrsFromURN, makeBboxFromOWS, makeNumericEPSG, getExtentFromNormalized } from '../utils/CoordinatesUtils'; import WMS from "../api/WMS"; +import { THREE_D_TILES, getCapabilities } from './ThreeDTiles'; const parseUrl = (url) => { const parsed = urlUtil.parse(url, true); - return urlUtil.format(assign({}, parsed, {search: null}, { + return urlUtil.format(assign({}, parsed, { search: null }, { query: assign({ service: "CSW", version: "2.0.2" - }, parsed.query, {request: undefined}) + }, parsed.query, { request: undefined }) })); }; @@ -73,13 +74,13 @@ export const cswGetRecordsXml = ' { return result; } const { value: _url } = _dcRef?.find(t => - REGEX_WMS_ALL.some(regex=> t?.scheme?.match(regex) || t?.protocol?.match(regex))) || {}; // Get WMS URL from references + REGEX_WMS_ALL.some(regex => t?.scheme?.match(regex) || t?.protocol?.match(regex))) || {}; // Get WMS URL from references const [parsedUrl] = _url && _url.split('?') || []; - if (!parsedUrl) return {...result}; // Return record when no url found + if (!parsedUrl) return { ...result }; // Return record when no url found const cached = capabilitiesCache[parsedUrl]; const isCached = !isEmpty(cached); @@ -207,8 +208,8 @@ const addCapabilitiesToRecords = (_dcRef, result, options) => { isCached ? cached : WMS.getCapabilities(parsedUrl + '?version=') - .then((caps)=> WMS.flatLayers(caps.Capability)) - .catch(()=> [])) + .then((caps) => WMS.flatLayers(caps.Capability)) + .catch(() => [])) .then((layers) => { if (!isCached) { capabilitiesCache[parsedUrl] = layers; @@ -216,22 +217,61 @@ const addCapabilitiesToRecords = (_dcRef, result, options) => { // Add visibility limits scale data of the layer to the record return { ...result, - records: result?.records?.map(record=> { + records: result?.records?.map(record => { const name = get(getLayerReferenceFromDc(record?.dc, null, false), 'params.name', ''); const { MinScaleDenominator, MaxScaleDenominator - } = layers.find(l=> l.Name === name) || {}; + } = layers.find(l => l.Name === name) || {}; return { ...record, ...((!isNil(MinScaleDenominator) || !isNil(MaxScaleDenominator)) - && {capabilities: {MaxScaleDenominator, MinScaleDenominator}}) + && { capabilities: { MaxScaleDenominator, MinScaleDenominator } }) }; }) }; }); }; +/** + * handle getting bbox from capabilities in case of 3D tile layer for CSW records + * @param {object} result csw results object + * @return {object} csw records + */ +const getBboxFor3DLayersToRecords = async(result)=> { + if (!result) return result; + let { records } = result; + if (records?.length) { + let records3DPromisesForCapabilities = records.map((rec)=>{ + if (rec?.dc?.format === THREE_D_TILES) { + let tilesetJsonURL = rec.dc?.URI?.value; + return getCapabilities(tilesetJsonURL); + } + return Promise.resolve(null); + }); + let allPromises = await Promise.all(records3DPromisesForCapabilities); + const newRecords = records.map( + (record, idx) => { + const capabilityResult = allPromises[idx]; + if (!capabilityResult) { + return record; + } + let bbox = getExtentFromNormalized(capabilityResult.bbox.bounds, capabilityResult.bbox.crs); + return { + ...record, + boundingBox: { + extent: bbox.extent, + crs: capabilityResult.bbox.crs + } + }; + }); + return { + ...result, + records: newRecords + }; + } + return result; +}; /** * API for local config */ @@ -243,7 +283,7 @@ const Api = { resolve(axios.get(catalogURL) .then((response) => { if (response) { - const {unmarshaller} = require('../utils/ogc/CSW'); + const { unmarshaller } = require('../utils/ogc/CSW'); const json = unmarshaller.unmarshalString(response.data); if (json && json.name && json.name.localPart === "GetRecordByIdResponse" && json.value && json.value.abstractRecord) { let dcElement = json.value.abstractRecord[0].value.dcElement; @@ -276,7 +316,7 @@ const Api = { dc[elName] = finalEl; } } - return {dc}; + return { dc }; } } else if (json && json.name && json.name.localPart === "ExceptionReport") { return { @@ -293,7 +333,7 @@ const Api = { getRecords: function(url, startPosition, maxRecords, filter, options) { return new Promise((resolve) => { require.ensure(['../utils/ogc/CSW', '../utils/ogc/Filter'], () => { - const {CSW, marshaller, unmarshaller } = require('../utils/ogc/CSW'); + const { CSW, marshaller, unmarshaller } = require('../utils/ogc/CSW'); let body = marshaller.marshalString({ name: "csw:GetRecords", value: CSW.getRecords(startPosition, maxRecords, typeof filter !== "string" && filter) @@ -301,127 +341,128 @@ const Api = { if (!filter || typeof filter === "string") { body = constructXMLBody(startPosition, maxRecords, filter, options); } - resolve(axios.post(parseUrl(url), body, { headers: { - 'Content-Type': 'application/xml' - }}).then( - (response) => { - if (response) { - let json = unmarshaller.unmarshalString(response.data); - if (json && json.name && json.name.localPart === "GetRecordsResponse" && json.value && json.value.searchResults) { - let rawResult = json.value; - let rawRecords = rawResult.searchResults.abstractRecord || rawResult.searchResults.any; - let result = { - numberOfRecordsMatched: rawResult.searchResults.numberOfRecordsMatched, - numberOfRecordsReturned: rawResult.searchResults.numberOfRecordsReturned, - nextRecord: rawResult.searchResults.nextRecord - // searchStatus: rawResult.searchStatus - }; - let records = []; - let _dcRef; - if (rawRecords) { - for (let i = 0; i < rawRecords.length; i++) { - let rawRec = rawRecords[i].value; - let obj = { - dateStamp: rawRec.dateStamp && rawRec.dateStamp.date, - fileIdentifier: rawRec.fileIdentifier && rawRec.fileIdentifier.characterString && rawRec.fileIdentifier.characterString.value, - identificationInfo: rawRec.abstractMDIdentification && rawRec.abstractMDIdentification.value - }; - if (rawRec.boundingBox) { - let bbox; - let crs; - let el; - if (Array.isArray(rawRec.boundingBox)) { - el = head(rawRec.boundingBox); - } else { - el = rawRec.boundingBox; - } - if (el && el.value) { - const crsValue = el.value?.crs ?? ''; - const urn = crsValue.match(/[\w-]*:[\w-]*:[\w-]*:[\w-]*:[\w-]*:[^:]*:(([\w-]+\s[\w-]+)|[\w-]*)/)?.[0]; - const epsg = makeNumericEPSG(crsValue.match(/EPSG:[0-9]+/)?.[0]); + resolve(axios.post(parseUrl(url), body, { + headers: { + 'Content-Type': 'application/xml' + } + }).then((response) => { + if (response) { + let json = unmarshaller.unmarshalString(response.data); + if (json && json.name && json.name.localPart === "GetRecordsResponse" && json.value && json.value.searchResults) { + let rawResult = json.value; + let rawRecords = rawResult.searchResults.abstractRecord || rawResult.searchResults.any; + let result = { + numberOfRecordsMatched: rawResult.searchResults.numberOfRecordsMatched, + numberOfRecordsReturned: rawResult.searchResults.numberOfRecordsReturned, + nextRecord: rawResult.searchResults.nextRecord + // searchStatus: rawResult.searchStatus + }; + let records = []; + let _dcRef; + if (rawRecords) { + for (let i = 0; i < rawRecords.length; i++) { + let rawRec = rawRecords[i].value; + let obj = { + dateStamp: rawRec.dateStamp && rawRec.dateStamp.date, + fileIdentifier: rawRec.fileIdentifier && rawRec.fileIdentifier.characterString && rawRec.fileIdentifier.characterString.value, + identificationInfo: rawRec.abstractMDIdentification && rawRec.abstractMDIdentification.value + }; + if (rawRec.boundingBox) { + let bbox; + let crs; + let el; + if (Array.isArray(rawRec.boundingBox)) { + el = head(rawRec.boundingBox); + } else { + el = rawRec.boundingBox; + } + if (el && el.value) { + const crsValue = el.value?.crs ?? ''; + const urn = crsValue.match(/[\w-]*:[\w-]*:[\w-]*:[\w-]*:[\w-]*:[^:]*:(([\w-]+\s[\w-]+)|[\w-]*)/)?.[0]; + const epsg = makeNumericEPSG(crsValue.match(/EPSG:[0-9]+/)?.[0]); - let lc = el.value.lowerCorner; - let uc = el.value.upperCorner; + let lc = el.value.lowerCorner; + let uc = el.value.upperCorner; - const extractedCrs = epsg || (extractCrsFromURN(urn) || last(crsValue.split(':'))); + const extractedCrs = epsg || (extractCrsFromURN(urn) || last(crsValue.split(':'))); - if (!extractedCrs) { - crs = 'EPSG:4326'; - } else if (extractedCrs.slice(0, 5) === 'EPSG:') { - crs = makeNumericEPSG(extractedCrs); - } else { - crs = makeNumericEPSG(`EPSG:${extractedCrs}`); - } + if (!extractedCrs) { + crs = 'EPSG:4326'; + } else if (extractedCrs.slice(0, 5) === 'EPSG:') { + crs = makeNumericEPSG(extractedCrs); + } else { + crs = makeNumericEPSG(`EPSG:${extractedCrs}`); + } - // Usually switched, GeoServer sometimes doesn't. See https://docs.geoserver.org/latest/en/user/services/wfs/axis_order.html#axis-ordering - if (crs === 'EPSG:4326' && extractedCrs !== 'CRS84' && extractedCrs !== 'OGC:CRS84') { - lc = [lc[1], lc[0]]; - uc = [uc[1], uc[0]]; - } - bbox = makeBboxFromOWS(lc, uc); + // Usually switched, GeoServer sometimes doesn't. See https://docs.geoserver.org/latest/en/user/services/wfs/axis_order.html#axis-ordering + if (crs === 'EPSG:4326' && extractedCrs !== 'CRS84' && extractedCrs !== 'OGC:CRS84') { + lc = [lc[1], lc[0]]; + uc = [uc[1], uc[0]]; } - obj.boundingBox = { - extent: bbox, - crs: 'EPSG:4326' - }; + bbox = makeBboxFromOWS(lc, uc); } - // dcElement is an array of objects, each item is a dc tag in the XML - let dcElement = rawRec.dcElement; - if (dcElement) { - let dc = { - references: [] - }; - for (let j = 0; j < dcElement.length; j++) { - let dcel = dcElement[j]; - // here the element name is taken (i.e. "URI", "title", "description", etc) - let elName = dcel.name.localPart; - let finalEl = {}; - /* Some services (e.g. GeoServer) support http://schemas.opengis.net/csw/2.0.2/record.xsd only - * Usually they publish the WMS URL at dct:"references" with scheme=OGC:WMS - * So we place references as they are. - */ - if (elName === "references" && dcel.value) { - let urlString = dcel.value.content && cleanDuplicatedQuestionMarks(dcel.value.content[0]) || dcel.value.content || dcel.value; - finalEl = { - value: urlString, - scheme: dcel.value.scheme - }; - } else { - finalEl = dcel.value.content && dcel.value.content[0] || dcel.value.content || dcel.value; - } - /** - grouping all tags with same property together (i.e mobilità traffico) - will become { subject: ["mobilità", "traffico"] } - **/ - if (dc[elName] && Array.isArray(dc[elName])) { - dc[elName].push(finalEl); - } else if (dc[elName]) { - dc[elName] = [dc[elName], finalEl]; - } else { - dc[elName] = finalEl; - } + obj.boundingBox = { + extent: bbox, + crs: 'EPSG:4326' + }; + } + // dcElement is an array of objects, each item is a dc tag in the XML + let dcElement = rawRec.dcElement; + if (dcElement) { + let dc = { + references: [] + }; + for (let j = 0; j < dcElement.length; j++) { + let dcel = dcElement[j]; + // here the element name is taken (i.e. "URI", "title", "description", etc) + let elName = dcel.name.localPart; + let finalEl = {}; + /* Some services (e.g. GeoServer) support http://schemas.opengis.net/csw/2.0.2/record.xsd only + * Usually they publish the WMS URL at dct:"references" with scheme=OGC:WMS + * So we place references as they are. + */ + if (elName === "references" && dcel.value) { + let urlString = dcel.value.content && cleanDuplicatedQuestionMarks(dcel.value.content[0]) || dcel.value.content || dcel.value; + finalEl = { + value: urlString, + scheme: dcel.value.scheme + }; + } else { + finalEl = dcel.value.content && dcel.value.content[0] || dcel.value.content || dcel.value; } - const URIs = castArray(dc.references.length > 0 ? dc.references : dc.URI); - if (!_dcRef) { - _dcRef = URIs; + /** + grouping all tags with same property together (i.e mobilità traffico) + will become { subject: ["mobilità", "traffico"] } + **/ + if (dc[elName] && Array.isArray(dc[elName])) { + dc[elName].push(finalEl); + } else if (dc[elName]) { + dc[elName] = [dc[elName], finalEl]; } else { - _dcRef = _dcRef.concat(URIs); + dc[elName] = finalEl; } - obj.dc = dc; } - records.push(obj); + const URIs = castArray(dc.references.length > 0 ? dc.references : dc.URI); + if (!_dcRef) { + _dcRef = URIs; + } else { + _dcRef = _dcRef.concat(URIs); + } + obj.dc = dc; } + records.push(obj); } - result.records = records; - return addCapabilitiesToRecords(_dcRef, result, options); - } else if (json && json.name && json.name.localPart === "ExceptionReport") { - return { - error: json.value.exception && json.value.exception.length && json.value.exception[0].exceptionText || 'GenericError' - }; } + result.records = records; + return addCapabilitiesToRecords(_dcRef, result, options); + } else if (json && json.name && json.name.localPart === "ExceptionReport") { + return { + error: json.value.exception && json.value.exception.length && json.value.exception[0].exceptionText || 'GenericError' + }; } - return null; - })); + } + return null; + }).then(results => getBboxFor3DLayersToRecords(results))); // handle getting bbox from capabilities in case of 3D tile layer }); }); }, @@ -433,7 +474,7 @@ const Api = { workspaceSearch: function(url, startPosition, maxRecords, text, workspace) { return new Promise((resolve) => { require.ensure(['../utils/ogc/CSW', '../utils/ogc/Filter'], () => { - const {Filter} = require('../utils/ogc/Filter'); + const { Filter } = require('../utils/ogc/Filter'); const workspaceTerm = workspace || "%"; const layerNameTerm = text && "%" + text + "%" || "%"; const ops = Filter.propertyIsLike("dc:identifier", workspaceTerm + ":" + layerNameTerm); @@ -442,7 +483,7 @@ const Api = { }); }); }, - reset: () => {} + reset: () => { } }; export default Api; diff --git a/web/client/api/__tests__/CSW-test.js b/web/client/api/__tests__/CSW-test.js index abce7330bc..98c1bc6063 100644 --- a/web/client/api/__tests__/CSW-test.js +++ b/web/client/api/__tests__/CSW-test.js @@ -10,8 +10,14 @@ import expect from 'expect'; import axios from '../../libs/ajax'; import MockAdapter from 'axios-mock-adapter'; import GRDCResponse from 'raw-loader!../../test-resources/csw/getRecordsResponseDC.xml'; +import GRDCResponseWith3DLayersAt1st from 'raw-loader!../../test-resources/csw/getRecordsResponseDCWith3DLayersAt1st.xml'; +import GRDCResponseWith3DLayersAtMiddle from 'raw-loader!../../test-resources/csw/getRecordsResponseDCWith3DLayersAtMiddle.xml'; +import GRDCResponseWith3DLayersAtLast from 'raw-loader!../../test-resources/csw/getRecordsResponseDCWith3DLayersAtLast.xml'; +import API, {constructXMLBody, getLayerReferenceFromDc } from '../CSW'; -import API, {constructXMLBody, getLayerReferenceFromDc} from '../CSW'; +import tileSetResponse from '../../test-resources/3dtiles/tileSetSample2.json'; + +let mockAxios; describe('Test correctness of the CSW APIs', () => { it('getRecords ISO Metadata Profile', (done) => { @@ -163,46 +169,215 @@ describe('Test capabilities data in CSW records', () => { }); }); -describe('workspaceSearch', () => { - let mockAxios; - beforeEach(() => { + +describe('tests with mockedActions', () => { + beforeEach(done => { mockAxios = new MockAdapter(axios); + setTimeout(done); }); - afterEach(() => { + afterEach(done => { mockAxios.restore(); + setTimeout(done); }); - it('workspaceSearch', (done) => { - mockAxios.onPost().reply( (config) => { - expect(config.data).toEqual( - "" - + "full" - + "" - + "dc:identifierwp:%test%" - + "" - + "" - + "" - ); - return [200, GRDCResponse]; + describe('workspaceSearch', () => { + it('workspaceSearch test', (done) => { + mockAxios.onPost().reply( (config) => { + expect(config.data).toEqual( + "" + + "full" + + "" + + "dc:identifierwp:%test%" + + "" + + "" + + "" + ); + return [200, GRDCResponse]; + }); + API.workspaceSearch('/TESTURL', 1, 1, "test", "wp").then((data) => { + expect(data).toExist(); + expect(data.records).toExist(); + expect(data.records.length).toBe(4); + done(); + }); + }); + }); + describe("getRecords for 3D layers", () => { + const threeDLayerRecord = { + "boundingBox": { + "extent": [ + 11.244154369601063, + 43.75907090685874, + 11.265929832205956, + 43.78084636946362 + ], + "crs": "EPSG:4326" + }, + "dc": { + "references": [], + "identifier": "test:20230829_test_3dtile_01", + "date": "2023-09-22", + "title": "Metadato di test per 3D-tile", + "abstract": "Breve descrizione della risorsa", + "description": "Breve descrizione della risorsa", + "type": "dataset", + "subject": [ + "Zone a rischio naturale", + "health" + ], + "format": "3D Tiles", + "contributor": "Nome dell'ufficio responsabile del dato", + "rights": [ + "otherRestrictions", + "otherRestrictions" + ], + "language": "ita", + "source": "Descrizione della provenienza e del processo di produzione del dato (storia, ciclo di vita, rilevazione, acquisizione, forma attuale, qualità richiesta per garantirne l'interoperabilità)", + "temporal": "start=2009-01-01; end=2013-12-31", + "URI": { + "TYPE_NAME": "DC_1_1.URI", + "protocol": "https://registry.geodati.gov.it/metadata-codelist/ProtocolValue/www-download", + "description": "access point", + "value": "https://3d-layers.s3.eu-central-1.amazonaws.com/3dtiles/centro_storico_di_firenze_-_brass_city_model/tileset.json" + } + } + }; + it('test getRecords that contain 3D tile layers at 1st index ', (done) => { + mockAxios.onPost().replyOnce(()=>{ + return [200, GRDCResponseWith3DLayersAt1st]; + }); + mockAxios.onGet().reply(()=>{ + return [200, tileSetResponse]; + }); + API.getRecords('base/web/client/test-resources/csw/getRecordsResponseDCWith3DLayersAt1st.xml', 1, 2).then((result) => { + try { + expect(result).toExist(); + expect(result.records).toExist(); + expect(result.records.length).toBe(4); + const [rec0, rec1, rec2, rec3] = result.records; + expect(rec0.dc.format).toEqual("3D Tiles"); + expect(rec0.boundingBox).toExist(); + expect(rec0.boundingBox.crs).toBe('EPSG:4326'); + expect(rec0.boundingBox.extent[0]).toEqual(threeDLayerRecord.boundingBox.extent[0]); + expect(rec0.boundingBox.extent[1]).toEqual(threeDLayerRecord.boundingBox.extent[1]); + expect(rec0.boundingBox.extent[2]).toEqual(threeDLayerRecord.boundingBox.extent[2]); + expect(rec0.boundingBox.extent[3]).toEqual(threeDLayerRecord.boundingBox.extent[3]); + expect(rec1.dc).toExist(); + expect(rec1.boundingBox).toExist(); + expect(rec1.boundingBox.crs).toBe('EPSG:4326'); + expect(rec1.boundingBox.extent).toEqual([45.542, 11.874, 46.026, 12.718]); + expect(rec2.boundingBox).toExist(); + expect(rec2.boundingBox.crs).toBe('EPSG:4326'); + expect(rec2.boundingBox.extent).toEqual([ 12.002717999999996, 45.760718, 12.429282000000002, 46.187282]); + expect(rec3.boundingBox).toExist(); + expect(rec3.boundingBox.crs).toBe('EPSG:4326'); + expect(rec3.boundingBox.extent).toEqual([ -4.14168, 47.93257, -4.1149, 47.959353362144 ]); + done(); + } catch (ex) { + done(ex); + } + }).catch(ex=>{ + done(ex); + }); + }); + it('test getRecords that contain 3D tile layers at last index', (done) => { + mockAxios.onPost().replyOnce(()=>{ + return [200, GRDCResponseWith3DLayersAtLast]; + }); + mockAxios.onGet().reply(()=>{ + return [200, tileSetResponse]; + }); + API.getRecords('base/web/client/test-resources/csw/getRecordsResponseDCWith3DLayersAtLast.xml', 1, 2).then((result) => { + try { + expect(result).toExist(); + expect(result.records).toExist(); + expect(result.records.length).toBe(4); + const [rec0, rec1, rec2, rec3] = result.records; + expect(rec0.dc).toExist(); + expect(rec0.boundingBox).toExist(); + expect(rec0.boundingBox.crs).toBe('EPSG:4326'); + expect(rec0.boundingBox.extent).toEqual([45.542, 11.874, 46.026, 12.718]); + expect(rec1.dc.URI).toExist(); + expect(rec1.dc.URI[0]).toExist(); + const uri = rec1.dc.URI[0]; + expect(uri.name).toExist(); + expect(uri.value).toExist(); + expect(uri.description).toExist(); + expect(rec1.boundingBox).toExist(); + expect(rec1.boundingBox.crs).toBe('EPSG:4326'); + expect(rec1.boundingBox.extent).toEqual([ 12.002717999999996, 45.760718, 12.429282000000002, 46.187282]); + expect(rec2.boundingBox).toExist(); + expect(rec2.boundingBox.crs).toBe('EPSG:4326'); + expect(rec2.boundingBox.extent).toEqual([ -4.14168, 47.93257, -4.1149, 47.959353362144 ]); + expect(rec3.dc.format).toEqual("3D Tiles"); + expect(rec3.boundingBox).toExist(); + expect(rec3.boundingBox.crs).toBe('EPSG:4326'); + expect(rec3.boundingBox.extent[0]).toEqual(threeDLayerRecord.boundingBox.extent[0]); + expect(rec3.boundingBox.extent[1]).toEqual(threeDLayerRecord.boundingBox.extent[1]); + expect(rec3.boundingBox.extent[2]).toEqual(threeDLayerRecord.boundingBox.extent[2]); + expect(rec3.boundingBox.extent[3]).toEqual(threeDLayerRecord.boundingBox.extent[3]); + done(); + } catch (ex) { + done(ex); + } + }).catch(ex=>{ + done(ex); + }); }); - API.workspaceSearch('/TESTURL', 1, 1, "test", "wp").then((data) => { - expect(data).toExist(); - expect(data.records).toExist(); - expect(data.records.length).toBe(4); - done(); + it('test getRecords that contain 3D tile layers at the middle', (done) => { + mockAxios.onPost().replyOnce(()=>{ + return [200, GRDCResponseWith3DLayersAtMiddle]; + }); + mockAxios.onGet().reply(()=>{ + return [200, tileSetResponse]; + }); + API.getRecords('base/web/client/test-resources/csw/getRecordsResponseDCWith3DLayersAtMiddle.xml', 1, 2).then((result) => { + try { + expect(result).toExist(); + expect(result.records).toExist(); + expect(result.records.length).toBe(3); + const [rec0, rec1, rec2] = result.records; + expect(rec0.dc).toExist(); + expect(rec0.boundingBox).toExist(); + expect(rec0.boundingBox.crs).toBe('EPSG:4326'); + expect(rec0.boundingBox.extent).toEqual([45.542, 11.874, 46.026, 12.718]); + expect(rec1.dc.format).toEqual("3D Tiles"); + expect(rec1.boundingBox).toExist(); + expect(rec1.boundingBox.crs).toBe('EPSG:4326'); + expect(rec1.boundingBox.extent[0]).toEqual(threeDLayerRecord.boundingBox.extent[0]); + expect(rec1.boundingBox.extent[1]).toEqual(threeDLayerRecord.boundingBox.extent[1]); + expect(rec1.boundingBox.extent[2]).toEqual(threeDLayerRecord.boundingBox.extent[2]); + expect(rec1.boundingBox.extent[3]).toEqual(threeDLayerRecord.boundingBox.extent[3]); + expect(rec2.dc.URI).toExist(); + expect(rec2.dc.URI[0]).toExist(); + const uri = rec2.dc.URI[0]; + expect(uri.name).toExist(); + expect(uri.value).toExist(); + expect(uri.description).toExist(); + expect(rec2.boundingBox).toExist(); + expect(rec2.boundingBox.crs).toBe('EPSG:4326'); + expect(rec2.boundingBox.extent).toEqual([ 12.002717999999996, 45.760718, 12.429282000000002, 46.187282]); + done(); + } catch (ex) { + done(ex); + } + }).catch(ex=>{ + done(ex); + }); }); }); }); + describe("constructXMLBody", () => { it("construct body without PropertyIsLike when there is no search text", () => { const body = constructXMLBody(1, 5, null); @@ -281,4 +456,7 @@ describe("getLayerReferenceFromDc", () => { expect(layerRef.type).toBe('arcgis'); expect(layerRef.url).toBe('http://esri_url'); }); + }); + + diff --git a/web/client/test-resources/3dtiles/tileSetSample2.json b/web/client/test-resources/3dtiles/tileSetSample2.json new file mode 100644 index 0000000000..f66c8a7071 --- /dev/null +++ b/web/client/test-resources/3dtiles/tileSetSample2.json @@ -0,0 +1,1286 @@ +{ + "asset": { + "version": "1.0", + "extras": { + "cesium":{ + "credits": [{ + "html": "'CENTRO STORICO DI FIRENZE - BRASS CITY MODEL' (https://skfb.ly/ozsuX) by Blayne Jackson is licensed under Creative Commons Attribution (http://creativecommons.org/licenses/by/4.0/)." + }] + } + } + }, + "geometricError": 100.0, + "root": { + "transform": [ + -0.19518643826956167, + 0.9807661567956159, + 0.0, + 0.0, + -0.7081936612571651, + -0.14094062829155365, + -0.6918073991017686, + 0.0, + -0.6785012840598124, + -0.13503142219920336, + 0.7220820746619087, + 0.0, + 4524243.58964167, + 900388.9316605763, + 4389975.148663257, + 1.0 + ], + "boundingVolume": { + "box": [ + -46.12789900000001, + -45.779855500000004, + -376.9231565, + 887.7269590000001, + 0.0, + 0.0, + 0.0, + -92.34474750000001, + 0.0, + 0.0, + 0.0, + 817.9918825 + ] + }, + "geometricError": 100.0, + "refine": "ADD", + "content": null, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + 419.85219192144916, + 4.095745422540702, + 42.213073407500616, + 22.116611421449136, + 0.0, + 0.0, + 0.0, + -20.506155663600108, + 0.0, + 0.0, + 0.0, + 10.140288657500601 + ] + }, + "geometricError": 9.250805133486388, + "refine": "REPLACE", + "content": { + "uri": "LOD-2/Mesh-XR-YR-XR-YR.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + 420.6972960044431, + 4.178090504776833, + 42.213073407500616, + 22.961715504443077, + 0.0, + 0.0, + 0.0, + -20.481441743868658, + 0.0, + 0.0, + 0.0, + 10.140288657500601 + ] + }, + "geometricError": 3.0044851085938626, + "refine": "REPLACE", + "content": { + "uri": "LOD-1/Mesh-XR-YR-XR-YR.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + 420.7135110832271, + 4.093270917621091, + 42.213073407500616, + 22.97793058322705, + 0.0, + 0.0, + 0.0, + -20.558839672437735, + 0.0, + 0.0, + 0.0, + 10.140288657500601 + ] + }, + "geometricError": 0.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-0/Mesh-XR-YR-XR-YR.b3dm" + }, + "children": [] + } + ] + } + ] + }, + { + "transform": null, + "boundingVolume": { + "box": [ + 175.80384075, + 1.820949500000001, + 143.62393773310916, + 221.93173975000002, + 0.0, + 0.0, + 0.0, + -24.0937825, + 0.0, + 0.0, + 0.0, + 111.55115298310915 + ] + }, + "geometricError": 9.009745481719476, + "refine": "REPLACE", + "content": { + "uri": "LOD-2/Mesh-XR-YR-XL-YR.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + 175.80384075, + 1.820949500000001, + 143.81010388335957, + 221.93173975000002, + 0.0, + 0.0, + 0.0, + -24.0937825, + 0.0, + 0.0, + 0.0, + 111.73731913335956 + ] + }, + "geometricError": 3.0000450033348196, + "refine": "REPLACE", + "content": { + "uri": "LOD-1/Mesh-XR-YR-XL-YR.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + 175.80384075, + 1.820949500000001, + 143.80507533137478, + 221.93173975000002, + 0.0, + 0.0, + 0.0, + -24.0937825, + 0.0, + 0.0, + 0.0, + 111.73229058137476 + ] + }, + "geometricError": 0.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-0/Mesh-XR-YR-XL-YR.b3dm" + }, + "children": [] + } + ] + } + ] + }, + { + "transform": null, + "boundingVolume": { + "box": [ + 619.66732025, + 13.9466365, + -172.425185875, + 221.93173975, + 0.0, + 0.0, + 0.0, + -32.618255500000004, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 9.000419677857408, + "refine": "REPLACE", + "content": { + "uri": "LOD-2/Mesh-XR-YR-XR-YL.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + 619.66732025, + 13.9466365, + -172.425185875, + 221.93173975, + 0.0, + 0.0, + 0.0, + -32.618255500000004, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 3.0000699454941726, + "refine": "REPLACE", + "content": { + "uri": "LOD-1/Mesh-XR-YR-XR-YL.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + 619.66732025, + 13.944355, + -172.425185875, + 221.93173975, + 0.0, + 0.0, + 0.0, + -32.620537, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 0.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-0/Mesh-XR-YR-XR-YL.b3dm" + }, + "children": [] + } + ] + } + ] + }, + { + "transform": null, + "boundingVolume": { + "box": [ + 175.80384075, + -57.392518115365164, + -172.425185875, + 221.93173975000002, + 0.0, + 0.0, + 0.0, + -80.64890411536516, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 9.00309444695593, + "refine": "REPLACE", + "content": { + "uri": "LOD-2/Mesh-XR-YR-XL-YL.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + 175.80384075, + -57.43410850000001, + -172.425185875, + 221.93173975000002, + 0.0, + 0.0, + 0.0, + -80.6904945, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 3.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-1/Mesh-XR-YR-XL-YL.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + 175.80384075, + -57.43410850000001, + -172.425185875, + 221.93173975000002, + 0.0, + 0.0, + 0.0, + -80.6904945, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 0.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-0/Mesh-XR-YR-XL-YL.b3dm" + }, + "children": [] + } + ] + } + ] + }, + { + "transform": null, + "boundingVolume": { + "box": [ + -268.05963875, + -27.100245277938605, + 236.57075537500003, + 221.93173975, + 0.0, + 0.0, + 0.0, + -50.57774872206139, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 9.007984542748456, + "refine": "REPLACE", + "content": { + "uri": "LOD-2/Mesh-XL-YR-XR-YR.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + -268.05963875, + -27.100245277938605, + 236.57075537500003, + 221.93173975, + 0.0, + 0.0, + 0.0, + -50.57774872206139, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 3.0013304621031747, + "refine": "REPLACE", + "content": { + "uri": "LOD-1/Mesh-XL-YR-XR-YR.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + -268.05963875, + -27.032953499999998, + 236.57075537500003, + 221.93173975, + 0.0, + 0.0, + 0.0, + -50.6450405, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 0.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-0/Mesh-XL-YR-XR-YR.b3dm" + }, + "children": [] + } + ] + } + ] + }, + { + "transform": null, + "boundingVolume": { + "box": [ + -571.4786864988677, + -28.829253992945397, + 206.02029611656252, + 81.48730799886766, + 0.0, + 0.0, + 0.0, + -59.572296007054604, + 0.0, + 0.0, + 0.0, + 173.94751136656248 + ] + }, + "geometricError": 9.024395503911954, + "refine": "REPLACE", + "content": { + "uri": "LOD-2/Mesh-XL-YR-XL-YR.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + -571.4786864988677, + -28.829253992945397, + 206.30275865898983, + 81.48730799886766, + 0.0, + 0.0, + 0.0, + -59.572296007054604, + 0.0, + 0.0, + 0.0, + 174.2299739089898 + ] + }, + "geometricError": 3.002857224933117, + "refine": "REPLACE", + "content": { + "uri": "LOD-1/Mesh-XL-YR-XL-YR.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + -571.4786864988677, + -28.987028000000002, + 206.26638310502358, + 81.48730799886766, + 0.0, + 0.0, + 0.0, + -59.414522, + 0.0, + 0.0, + 0.0, + 174.1935983550236 + ] + }, + "geometricError": 0.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-0/Mesh-XL-YR-XL-YR.b3dm" + }, + "children": [] + } + ] + } + ] + }, + { + "transform": null, + "boundingVolume": { + "box": [ + -268.05963875, + -12.949604532282189, + -172.425185875, + 221.93173975, + 0.0, + 0.0, + 0.0, + -31.37277253228219, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 9.06715492705682, + "refine": "REPLACE", + "content": { + "uri": "LOD-2/Mesh-XL-YR-XR-YL.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + -268.05963875, + -13.158411494229224, + -172.425185875, + 221.93173975, + 0.0, + 0.0, + 0.0, + -31.723042135653397, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 3.000006846244177, + "refine": "REPLACE", + "content": { + "uri": "LOD-1/Mesh-XL-YR-XR-YL.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + -268.05963875, + -13.257099319345885, + -172.425185875, + 221.93173975, + 0.0, + 0.0, + 0.0, + -31.723259319345885, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 0.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-0/Mesh-XL-YR-XR-YL.b3dm" + }, + "children": [] + } + ] + } + ] + }, + { + "transform": null, + "boundingVolume": { + "box": [ + -661.22945751898, + 6.100170523205582, + -172.425185875, + 171.23807901898, + 0.0, + 0.0, + 0.0, + -32.022994476794416, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 9.091012569601437, + "refine": "REPLACE", + "content": { + "uri": "LOD-2/Mesh-XL-YR-XL-YL.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + -661.4706318493029, + 5.747224965764039, + -172.425185875, + 171.47925334930284, + 0.0, + 0.0, + 0.0, + -32.37594003423596, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 3.002785511456154, + "refine": "REPLACE", + "content": { + "uri": "LOD-1/Mesh-XL-YR-XL-YL.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + -661.46077725, + 5.658901999999999, + -172.425185875, + 171.46939874999998, + 0.0, + 0.0, + 0.0, + -32.464263, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 0.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-0/Mesh-XL-YR-XL-YL.b3dm" + }, + "children": [] + } + ] + } + ] + }, + { + "transform": null, + "boundingVolume": { + "box": [ + 568.4202192500001, + -20.583627999999997, + -581.421127125, + 170.68463875, + 0.0, + 0.0, + 0.0, + -58.508108, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 9.045561832193199, + "refine": "REPLACE", + "content": { + "uri": "LOD-2/Mesh-XR-YL-XR-YR.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + 568.64925375, + -20.583627999999997, + -581.421127125, + 170.91367324999996, + 0.0, + 0.0, + 0.0, + -58.508108, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 3.0062421946715485, + "refine": "REPLACE", + "content": { + "uri": "LOD-1/Mesh-XR-YL-XR-YR.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + 568.64925375, + -20.948847, + -581.421127125, + 170.91367324999996, + 0.0, + 0.0, + 0.0, + -58.873327, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 0.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-0/Mesh-XR-YL-XR-YR.b3dm" + }, + "children": [] + } + ] + } + ] + }, + { + "transform": null, + "boundingVolume": { + "box": [ + 175.80384075, + -40.4709845, + -581.421127125, + 221.93173975000002, + 0.0, + 0.0, + 0.0, + -70.7598965, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 9.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-2/Mesh-XR-YL-XL-YR.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + 175.80384075, + -40.4709845, + -581.421127125, + 221.93173975000002, + 0.0, + 0.0, + 0.0, + -70.7598965, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 3.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-1/Mesh-XR-YL-XL-YR.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + 175.80384075, + -40.4709845, + -581.421127125, + 221.93173975000002, + 0.0, + 0.0, + 0.0, + -70.7598965, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 0.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-0/Mesh-XR-YL-XL-YR.b3dm" + }, + "children": [] + } + ] + } + ] + }, + { + "transform": null, + "boundingVolume": { + "box": [ + 474.01867281378895, + 13.884999124593019, + -952.6590779651754, + 76.28309231378896, + 0.0, + 0.0, + 0.0, + -21.413729875406982, + 0.0, + 0.0, + 0.0, + 166.73998021517536 + ] + }, + "geometricError": 9.035181333117173, + "refine": "REPLACE", + "content": { + "uri": "LOD-2/Mesh-XR-YL-XR-YL.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + 474.01867281378895, + 13.784376000000002, + -952.6590779651754, + 76.28309231378896, + 0.0, + 0.0, + 0.0, + -21.514353, + 0.0, + 0.0, + 0.0, + 166.73998021517536 + ] + }, + "geometricError": 3.001158836108843, + "refine": "REPLACE", + "content": { + "uri": "LOD-1/Mesh-XR-YL-XR-YL.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + 474.01867281378895, + 13.784376000000002, + -952.8523022750364, + 76.28309231378896, + 0.0, + 0.0, + 0.0, + -21.514353, + 0.0, + 0.0, + 0.0, + 166.93320452503644 + ] + }, + "geometricError": 0.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-0/Mesh-XR-YL-XR-YL.b3dm" + }, + "children": [] + } + ] + } + ] + }, + { + "transform": null, + "boundingVolume": { + "box": [ + 175.80384075, + 12.857098, + -990.417068375, + 221.93173975000002, + 0.0, + 0.0, + 0.0, + -21.532020000000003, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 9.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-2/Mesh-XR-YL-XL-YL.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + 175.80384075, + 12.857098, + -990.417068375, + 221.93173975000002, + 0.0, + 0.0, + 0.0, + -21.532020000000003, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 3.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-1/Mesh-XR-YL-XL-YL.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + 175.80384075, + 12.857098, + -990.417068375, + 221.93173975000002, + 0.0, + 0.0, + 0.0, + -21.532020000000003, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 0.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-0/Mesh-XR-YL-XL-YL.b3dm" + }, + "children": [] + } + ] + } + ] + }, + { + "transform": null, + "boundingVolume": { + "box": [ + -268.05963875, + -0.24298320162245446, + -581.421127125, + 221.93173975, + 0.0, + 0.0, + 0.0, + -29.475140798377545, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 9.050170085022257, + "refine": "REPLACE", + "content": { + "uri": "LOD-2/Mesh-XL-YL-XR-YR.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + -268.05963875, + -0.04077669028951547, + -581.421127125, + 221.93173975, + 0.0, + 0.0, + 0.0, + -29.677347309710484, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 3.0014796703300752, + "refine": "REPLACE", + "content": { + "uri": "LOD-1/Mesh-XL-YL-XR-YR.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + -268.05963875, + 0.0020330000000008397, + -581.421127125, + 221.93173975, + 0.0, + 0.0, + 0.0, + -29.72126, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 0.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-0/Mesh-XL-YL-XR-YR.b3dm" + }, + "children": [] + } + ] + } + ] + }, + { + "transform": null, + "boundingVolume": { + "box": [ + -711.92311825, + 14.111128606047746, + -581.421127125, + 221.93173975000002, + 0.0, + 0.0, + 0.0, + -26.256765267608944, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 9.062620376021641, + "refine": "REPLACE", + "content": { + "uri": "LOD-2/Mesh-XL-YL-XL-YR.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + -711.92311825, + 14.160693436828346, + -581.421127125, + 221.93173975000002, + 0.0, + 0.0, + 0.0, + -26.207200436828344, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 3.01232961009897, + "refine": "REPLACE", + "content": { + "uri": "LOD-1/Mesh-XL-YL-XL-YR.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + -711.92311825, + 14.243437, + -581.421127125, + 221.93173975000002, + 0.0, + 0.0, + 0.0, + -26.530324999999998, + 0.0, + 0.0, + 0.0, + 204.497970625 + ] + }, + "geometricError": 0.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-0/Mesh-XL-YL-XL-YR.b3dm" + }, + "children": [] + } + ] + } + ] + }, + { + "transform": null, + "boundingVolume": { + "box": [ + -268.05963875, + 14.376728000000002, + -900.2939233462467, + 221.93173975, + 0.0, + 0.0, + 0.0, + -22.692677000000003, + 0.0, + 0.0, + 0.0, + 114.37482559624675 + ] + }, + "geometricError": 9.023518079997174, + "refine": "REPLACE", + "content": { + "uri": "LOD-2/Mesh-XL-YL-XR-YL.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + -268.05963875, + 14.465618000000001, + -900.2939233462467, + 221.93173975, + 0.0, + 0.0, + 0.0, + -22.781567000000003, + 0.0, + 0.0, + 0.0, + 114.37482559624675 + ] + }, + "geometricError": 3.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-1/Mesh-XL-YL-XR-YL.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + -268.05963875, + 14.465618000000001, + -900.2939233462467, + 221.93173975, + 0.0, + 0.0, + 0.0, + -22.781567000000003, + 0.0, + 0.0, + 0.0, + 114.37482559624675 + ] + }, + "geometricError": 0.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-0/Mesh-XL-YL-XR-YL.b3dm" + }, + "children": [] + } + ] + } + ] + }, + { + "transform": null, + "boundingVolume": { + "box": [ + -519.655372386611, + 28.868679, + -800.1277477470123, + 29.663993886611024, + 0.0, + 0.0, + 0.0, + -7.142448000000002, + 0.0, + 0.0, + 0.0, + 14.208649997012344 + ] + }, + "geometricError": 9.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-2/Mesh-XL-YL-XL-YL.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + -519.655372386611, + 28.868679, + -800.1277477470123, + 29.663993886611024, + 0.0, + 0.0, + 0.0, + -7.142448000000002, + 0.0, + 0.0, + 0.0, + 14.208649997012344 + ] + }, + "geometricError": 3.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-1/Mesh-XL-YL-XL-YL.b3dm" + }, + "children": [ + { + "transform": null, + "boundingVolume": { + "box": [ + -519.655372386611, + 28.868679, + -800.1277477470123, + 29.663993886611024, + 0.0, + 0.0, + 0.0, + -7.142448000000002, + 0.0, + 0.0, + 0.0, + 14.208649997012344 + ] + }, + "geometricError": 0.0, + "refine": "REPLACE", + "content": { + "uri": "LOD-0/Mesh-XL-YL-XL-YL.b3dm" + }, + "children": [] + } + ] + } + ] + } + ] + } + } \ No newline at end of file diff --git a/web/client/test-resources/csw/getRecordsResponseDCWith3DLayersAt1st.xml b/web/client/test-resources/csw/getRecordsResponseDCWith3DLayersAt1st.xml new file mode 100644 index 0000000000..801cf1ea4a --- /dev/null +++ b/web/client/test-resources/csw/getRecordsResponseDCWith3DLayersAt1st.xml @@ -0,0 +1,79 @@ + + + + + test:20230829_test_3dtile_01 + 2023-09-22 + Metadato di test per 3D-tile + Breve descrizione della risorsa + Breve descrizione della risorsa + dataset + Zone a rischio naturale + health + 3D Tiles + Nome dell'ufficio responsabile del dato + otherRestrictions + otherRestrictions + ita + Descrizione della provenienza e del processo di produzione del dato (storia, ciclo di vita, rilevazione, acquisizione, forma attuale, qualità richiesta per garantirne l'interoperabilità) + + 11.331132423112592 43.72700677229733 + 11.154076443108027 43.82471910604458 + + start=2009-01-01; end=2013-12-31 + https://server.org/name/tileset.json + + + c1020047_title + dataset + sub1, sub2, sub3 + sub4 + + Abstract + + + + base/web/client/test-resources/csw/getCapability.xml + workspace:layer_name1 + + 12.718 45.542 + 11.874 46.026 + + + + + d698f693-6e7e-47a9-a138-918068d0b082 + Title2 + dataset + geoscientificInformation + + + + + + + 12.002717999999996 46.187282 + 12.429282000000002 45.760718 + + http://ows.domain.it:80/geoserver/wms?SERVICE=WMS& + resources.get?id=187049&fname=d698f693-6e7e-47a9-a138-918068d0b082_s.png&access=public + + + urn:isogeo:metadata:uuid:01ca64b3-6d69-43b7-b953-7743e11daafe + Title3 + dataset + infoMapAccessService + + + + + + + -4.1149 47.93257 + -4.14168 47.959353362144 + + http://ows.domain.it:80/geoserver/wms?SERVICE=WMS& + http://geowww.agrocampus-ouest.fr/img/metadata/KBZ.png + + + diff --git a/web/client/test-resources/csw/getRecordsResponseDCWith3DLayersAtLast.xml b/web/client/test-resources/csw/getRecordsResponseDCWith3DLayersAtLast.xml new file mode 100644 index 0000000000..69ff0507ae --- /dev/null +++ b/web/client/test-resources/csw/getRecordsResponseDCWith3DLayersAtLast.xml @@ -0,0 +1,79 @@ + + + + + c1020047_title + dataset + sub1, sub2, sub3 + sub4 + + Abstract + + + + base/web/client/test-resources/csw/getCapability.xml + workspace:layer_name1 + + 12.718 45.542 + 11.874 46.026 + + + + + d698f693-6e7e-47a9-a138-918068d0b082 + Title2 + dataset + geoscientificInformation + + + + + + + 12.002717999999996 46.187282 + 12.429282000000002 45.760718 + + http://ows.domain.it:80/geoserver/wms?SERVICE=WMS& + resources.get?id=187049&fname=d698f693-6e7e-47a9-a138-918068d0b082_s.png&access=public + + + urn:isogeo:metadata:uuid:01ca64b3-6d69-43b7-b953-7743e11daafe + Title3 + dataset + infoMapAccessService + + + + + + + -4.1149 47.93257 + -4.14168 47.959353362144 + + http://ows.domain.it:80/geoserver/wms?SERVICE=WMS& + http://geowww.agrocampus-ouest.fr/img/metadata/KBZ.png + + + test:20230829_test_3dtile_01 + 2023-09-22 + Metadato di test per 3D-tile + Breve descrizione della risorsa + Breve descrizione della risorsa + dataset + Zone a rischio naturale + health + 3D Tiles + Nome dell'ufficio responsabile del dato + otherRestrictions + otherRestrictions + ita + Descrizione della provenienza e del processo di produzione del dato (storia, ciclo di vita, rilevazione, acquisizione, forma attuale, qualità richiesta per garantirne l'interoperabilità) + + 11.331132423112592 43.72700677229733 + 11.154076443108027 43.82471910604458 + + start=2009-01-01; end=2013-12-31 + https://server.org/name/tileset.json + + + diff --git a/web/client/test-resources/csw/getRecordsResponseDCWith3DLayersAtMiddle.xml b/web/client/test-resources/csw/getRecordsResponseDCWith3DLayersAtMiddle.xml new file mode 100644 index 0000000000..939c38a94a --- /dev/null +++ b/web/client/test-resources/csw/getRecordsResponseDCWith3DLayersAtMiddle.xml @@ -0,0 +1,61 @@ + + + + + c1020047_title + dataset + sub1, sub2, sub3 + sub4 + + Abstract + + + + base/web/client/test-resources/csw/getCapability.xml + workspace:layer_name1 + + 12.718 45.542 + 11.874 46.026 + + + + test:20230829_test_3dtile_01 + 2023-09-22 + Metadato di test per 3D-tile + Breve descrizione della risorsa + Breve descrizione della risorsa + dataset + Zone a rischio naturale + health + 3D Tiles + Nome dell'ufficio responsabile del dato + otherRestrictions + otherRestrictions + ita + Descrizione della provenienza e del processo di produzione del dato (storia, ciclo di vita, rilevazione, acquisizione, forma attuale, qualità richiesta per garantirne l'interoperabilità) + + 11.331132423112592 43.72700677229733 + 11.154076443108027 43.82471910604458 + + start=2009-01-01; end=2013-12-31 + https://server.org/name/tileset.json + + + d698f693-6e7e-47a9-a138-918068d0b082 + Title2 + dataset + geoscientificInformation + + + + + + + 12.002717999999996 46.187282 + 12.429282000000002 45.760718 + + http://ows.domain.it:80/geoserver/wms?SERVICE=WMS& + resources.get?id=187049&fname=d698f693-6e7e-47a9-a138-918068d0b082_s.png&access=public + + +