diff --git a/web/client/api/ThreeDTiles.js b/web/client/api/ThreeDTiles.js index 207bcac839..1aca28ec02 100644 --- a/web/client/api/ThreeDTiles.js +++ b/web/client/api/ThreeDTiles.js @@ -142,3 +142,8 @@ export const getCapabilities = (url) => { return extractCapabilities(data).then((properties) => ({ tileset: data, ...properties })); }); }; + +/** + * constant of 3D tiles 'format' + */ +export const THREE_D_TILES = "3D Tiles"; diff --git a/web/client/api/catalog/CSW.js b/web/client/api/catalog/CSW.js index 4479975b26..e9cccaede7 100644 --- a/web/client/api/catalog/CSW.js +++ b/web/client/api/catalog/CSW.js @@ -9,6 +9,7 @@ import { head, isString, includes, castArray, sortBy, uniq } from 'lodash'; import { getLayerFromRecord as getLayerFromWMSRecord } from './WMS'; import { getMessageById } from '../../utils/LocaleUtils'; +import { transformExtentToObj} from '../../utils/CoordinatesUtils'; import { extractEsriReferences, extractOGCServicesReferences } from '../../utils/CatalogUtils'; import CSW, { getLayerReferenceFromDc } from '../CSW'; import { @@ -16,7 +17,7 @@ import { testService as commonTestService, preprocess as commonPreprocess } from './common'; - +import { THREE_D_TILES } from '../ThreeDTiles'; const getBaseCatalogUrl = (url) => { return url && url.replace(/\/csw$/, "/"); }; @@ -102,6 +103,27 @@ function getThumbnailFromDc(dc, options) { } return thumbURL; } +function getCatalogRecord3DTiles(record, metadata) { + const dc = record.dc; + let bbox = { + crs: record.boundingBox.crs, + bounds: transformExtentToObj(record.boundingBox.extent) + }; + return { + serviceType: '3dtiles', + isValid: true, + description: dc && isString(dc.abstract) && dc.abstract || '', + title: dc && isString(dc.title) && dc.title || '', + identifier: dc && isString(dc.identifier) && dc.identifier || '', + url: dc?.URI?.value || "", + thumbnail: null, + bbox, + format: dc && dc.format || "", + references: [], + catalogType: 'csw', + metadata + }; +} const recordToLayer = (record, options) => { switch (record.layerType) { @@ -210,22 +232,29 @@ export const getCatalogRecords = (records, options, locales) => { const ogcReferences = layerType && layerType !== 'esri' ? parsedReferences[layerType] : undefined; - return { - serviceType: 'csw', - layerType, - isValid: !!layerType, - boundingBox: record.boundingBox, - description: dc && isString(dc.abstract) && dc.abstract || '', - layerOptions: options && options.layerOptions || {}, - identifier: dc && isString(dc.identifier) && dc.identifier || '', - references: references, - thumbnail: getThumbnailFromDc(dc, options), - title: dc && isString(dc.title) && dc.title || '', - tags: dc && dc.tags || '', - metadata, - capabilities: record.capabilities, - ogcReferences - }; + let catRecord; + if (dc && dc.format === THREE_D_TILES) { + catRecord = getCatalogRecord3DTiles(record, metadata); + + } else { + catRecord = { + serviceType: 'csw', + layerType, + isValid: !!layerType, + boundingBox: record.boundingBox, + description: dc && isString(dc.abstract) && dc.abstract || '', + layerOptions: options && options.layerOptions || {}, + identifier: dc && isString(dc.identifier) && dc.identifier || '', + references: references, + thumbnail: getThumbnailFromDc(dc, options), + title: dc && isString(dc.title) && dc.title || '', + tags: dc && dc.tags || '', + metadata, + capabilities: record.capabilities, + ogcReferences + }; + } + return catRecord; }); } return null; diff --git a/web/client/api/catalog/__tests__/CSW-test.js b/web/client/api/catalog/__tests__/CSW-test.js index 97594d8212..04e7f6482a 100644 --- a/web/client/api/catalog/__tests__/CSW-test.js +++ b/web/client/api/catalog/__tests__/CSW-test.js @@ -11,6 +11,7 @@ import { map, clone } from 'lodash'; import { getCatalogRecords } from '../CSW'; +import { THREE_D_TILES } from '../../ThreeDTiles'; describe('Test correctness of the CSW catalog APIs', () => { it('csw empty', () => { @@ -302,7 +303,34 @@ describe('Test correctness of the CSW catalog APIs', () => { }, {}); expect(records.length).toBe(1); }); - + it('csw with DC URI 3D Tiles', ()=>{ + const records = [{ + boundingBox: { + "extent": [ + 43.718, 11.1, 43.84, 11.348 + ], + "crs": "EPSG:4326" + }, + dc: { + URI: { + TYPE_NAME: "DC_1_1.URI", + description: "access point", + protocol: "https://hostname/ProtocolValue/www-download", + value: "https://hostname/3dtiles/layername/tileset.json" + }, format: THREE_D_TILES, identifier: "test:layername", title: "3D Tiles layer for test" + } + }]; + const catalogRecords = getCatalogRecords({records}); + expect(catalogRecords.length).toBe(1); + expect(catalogRecords[0].bbox).toEqual({ bounds: {minx: 43.718, miny: 11.1, maxx: 43.84, maxy: 11.348}, crs: 'EPSG:4326' }); + expect(catalogRecords[0].url).toEqual("https://hostname/3dtiles/layername/tileset.json"); + expect(catalogRecords[0].identifier).toEqual("test:layername"); + expect(catalogRecords[0].title).toEqual("3D Tiles layer for test"); + expect(catalogRecords[0].serviceType).toEqual("3dtiles"); + expect(catalogRecords[0].isValid).toEqual(true); + expect(catalogRecords[0].format).toEqual('3D Tiles'); + expect(catalogRecords[0].catalogType).toEqual('csw'); + }); it('csw with DC references', () => { const records = getCatalogRecords({ records: [{ diff --git a/web/client/components/catalog/RecordItem.jsx b/web/client/components/catalog/RecordItem.jsx index 7fa87dc45b..ce4fe884e8 100644 --- a/web/client/components/catalog/RecordItem.jsx +++ b/web/client/components/catalog/RecordItem.jsx @@ -218,6 +218,8 @@ class RecordItem extends React.Component { caption={
{!this.props.hideIdentifier &&
{record && record.identifier}
} + {record?.serviceType === '3dtiles' && record?.catalogType === 'csw' && + }
{!record.isValid && }
{!this.props.hideExpand &&
{ return [lc[0], lc[1], uc[0], uc[1]]; }; +/** + * helper use to transform the extent array to bound object { minx, miny, maxx, maxy } + * if there is no provided param extent it will return the default bound object of wgs84 + * @param {number[]} extent is an array of 4 ordered coordinates [minx, miny, maxx, maxy] + */ +export const transformExtentToObj = (extent) => { + let [minx, miny, maxx, maxy] = extent ? [...extent] : [-180, -90, 180, 90]; + return { + minx, + miny, + maxx, + maxy + }; + +}; + /** * helper use to create a geojson Feature with a Polygon geometry diff --git a/web/client/utils/__tests__/CoordinatesUtils-test.js b/web/client/utils/__tests__/CoordinatesUtils-test.js index 820eb15970..a019bc2955 100644 --- a/web/client/utils/__tests__/CoordinatesUtils-test.js +++ b/web/client/utils/__tests__/CoordinatesUtils-test.js @@ -37,7 +37,7 @@ import { makeNumericEPSG, getPolygonFromCircle, checkIfLayerFitsExtentForProjection, - getLonLatFromPoint, convertRadianToDegrees, convertDegreesToRadian + getLonLatFromPoint, convertRadianToDegrees, convertDegreesToRadian, transformExtentToObj } from '../CoordinatesUtils'; import Proj4js from 'proj4'; @@ -766,6 +766,21 @@ describe('CoordinatesUtils', () => { const uc = [2, 4]; expect(makeBboxFromOWS(lc, uc)).toEqual([2, 2, 4, 4]); }); + describe('test transformExtentToObj to return bound obj', ()=>{ + + it('with provided extent ', ()=>{ + const extent = [1, 1, 5, 5]; + expect(transformExtentToObj(extent)).toEqual({ + minx: 1, miny: 1, maxx: 5, maxy: 5 + }); + }); + it('with no extent passed', ()=>{ + const extent = undefined; + expect(transformExtentToObj(extent)).toEqual({ + minx: -180, miny: -90, maxx: 180, maxy: 90 + }); + }); + }); it('extractCrsFromURN #1', () => { const urn = 'urn:ogc:def:crs:EPSG:6.6:4326'; expect(extractCrsFromURN(urn)).toBe('EPSG:4326');