From 2d173806e0feaf82dbe54fc8ae4ef4b7334ffcdf Mon Sep 17 00:00:00 2001 From: Olivia Guyot Date: Thu, 1 Aug 2024 17:08:24 +0200 Subject: [PATCH] feat(iso-converter): use single geometry for spatial extent --- .../src/lib/fixtures/geocat-ch.records.ts | 24 ++++----- .../src/lib/iso19139/read-parts.spec.ts | 50 +++++++++---------- .../src/lib/iso19139/read-parts.ts | 23 ++++----- .../src/lib/iso19139/write-parts.spec.ts | 24 ++++----- .../src/lib/iso19139/write-parts.ts | 14 +++--- .../metadata-converter/src/lib/xml-utils.ts | 5 ++ .../src/lib/model/record/metadata.model.ts | 2 +- 7 files changed, 67 insertions(+), 75 deletions(-) diff --git a/libs/api/metadata-converter/src/lib/fixtures/geocat-ch.records.ts b/libs/api/metadata-converter/src/lib/fixtures/geocat-ch.records.ts index 9b199a9562..caf033ff51 100644 --- a/libs/api/metadata-converter/src/lib/fixtures/geocat-ch.records.ts +++ b/libs/api/metadata-converter/src/lib/fixtures/geocat-ch.records.ts @@ -342,22 +342,20 @@ Die Quelle ist zu bezeichnen: „Quelle: Stadt Zürich“.`, ], }, { - geometries: [ - { - type: 'MultiPolygon', - coordinates: [ + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ [ - [ - [6.777075, 45.827119, 0], - [6.755991, 47.517566, 0], - [10.541824, 47.477984, 0], - [10.446252, 45.788744, 0], - [6.777075, 45.827119, 0], - ], + [6.777075, 45.827119, 0], + [6.755991, 47.517566, 0], + [10.541824, 47.477984, 0], + [10.446252, 45.788744, 0], + [6.777075, 45.827119, 0], ], ], - }, - ], + ], + }, }, ], temporalExtents: [], diff --git a/libs/api/metadata-converter/src/lib/iso19139/read-parts.spec.ts b/libs/api/metadata-converter/src/lib/iso19139/read-parts.spec.ts index a3971433da..3877020857 100644 --- a/libs/api/metadata-converter/src/lib/iso19139/read-parts.spec.ts +++ b/libs/api/metadata-converter/src/lib/iso19139/read-parts.spec.ts @@ -1,9 +1,9 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ // @ts-ignore -// @ts-ignore import GEOCAT_CH_DATASET from '../fixtures/geocat-ch.iso19139.dataset.xml' // @ts-ignore import { XmlElement } from '@rgrove/parse-xml' +// @ts-ignore import GEOCAT_CH_SERVICE from '../fixtures/geocat-ch.iso19139.service.xml' import { pipe } from '../function-utils' import { @@ -448,22 +448,20 @@ describe('read parts', () => { it('returns an array of spatial extents with geometries, bbox and description', () => { expect(readSpatialExtents(recordRootEl)).toEqual([ { - geometries: [ - { - type: 'MultiPolygon', - coordinates: [ + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ [ - [ - [6.777075, 45.827119, 0], - [6.755991, 47.517566, 0], - [10.541824, 47.477984, 0], - [10.446252, 45.788744, 0], - [6.777075, 45.827119, 0], - ], + [6.777075, 45.827119, 0], + [6.755991, 47.517566, 0], + [10.541824, 47.477984, 0], + [10.446252, 45.788744, 0], + [6.777075, 45.827119, 0], ], ], - }, - ], + ], + }, bbox: [ 6.75599105586694, 45.7887442565203, 10.5418236945627, 47.5175655551557, @@ -486,22 +484,20 @@ describe('read parts', () => { ], }, { - geometries: [ - { - type: 'MultiPolygon', - coordinates: [ + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ [ - [ - [6.777075, 45.827119, 0], - [6.755991, 47.517566, 0], - [10.541824, 47.477984, 0], - [10.446252, 45.788744, 0], - [6.777075, 45.827119, 0], - ], + [6.777075, 45.827119, 0], + [6.755991, 47.517566, 0], + [10.541824, 47.477984, 0], + [10.446252, 45.788744, 0], + [6.777075, 45.827119, 0], ], ], - }, - ], + ], + }, }, ]) }) diff --git a/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts b/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts index acc844f7ec..1af1c9f52c 100644 --- a/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts +++ b/libs/api/metadata-converter/src/lib/iso19139/read-parts.ts @@ -14,7 +14,7 @@ import { UpdateFrequencyCustom, } from '@geonetwork-ui/common/domain/model/record' import { ThesaurusModel } from '@geonetwork-ui/common/domain/model/thesaurus' -import { Geometry } from 'geojson' +import { MultiPolygon, Polygon } from 'geojson' import { matchMimeType, matchProtocol } from '../common/distribution.mapper' import { ChainableFunction, @@ -28,14 +28,15 @@ import { pipe, } from '../function-utils' import { - XmlElement, findChildElement, findChildrenElement, findNestedElement, findNestedElements, findParent, + firstChildElement, readAttribute, readText, + XmlElement, } from '../xml-utils' import { readGeometry } from './utils/geometry' import { fullNameToParts } from './utils/individual-name' @@ -907,16 +908,12 @@ export function readTemporalExtents(rootEl: XmlElement) { } export function readSpatialExtents(rootEl: XmlElement) { - const extractGeometries = (rootEl: XmlElement): Geometry[] => { + const extractGeometry = (rootEl: XmlElement): Polygon | MultiPolygon => { if (!rootEl) return null return pipe( - findChildrenElement('gmd:polygon', false), - mapArray((el) => { - const elements = el.children.filter( - (child) => child instanceof XmlElement - ) - return readGeometry(elements[0] as XmlElement) - }) + findChildElement('gmd:polygon', false), + firstChildElement, + map((el) => readGeometry(el) as Polygon | MultiPolygon) )(rootEl) } @@ -951,7 +948,7 @@ export function readSpatialExtents(rootEl: XmlElement) { findNestedElements('gmd:extent', 'gmd:EX_Extent', 'gmd:geographicElement'), mapArray( combine( - pipe(findChildElement('gmd:EX_BoundingPolygon'), extractGeometries), + pipe(findChildElement('gmd:EX_BoundingPolygon'), extractGeometry), pipe(findChildElement('gmd:EX_GeographicBoundingBox'), extractBBox), pipe( findChildElement('gmd:EX_GeographicDescription'), @@ -959,9 +956,9 @@ export function readSpatialExtents(rootEl: XmlElement) { ) ) ), - mapArray(([geometries, bbox, description]) => { + mapArray(([geometry, bbox, description]) => { return { - ...(geometries && { geometries }), + ...(geometry && { geometry }), ...(bbox && { bbox }), ...(description && { description }), } diff --git a/libs/api/metadata-converter/src/lib/iso19139/write-parts.spec.ts b/libs/api/metadata-converter/src/lib/iso19139/write-parts.spec.ts index f8c528169a..7f1f891a72 100644 --- a/libs/api/metadata-converter/src/lib/iso19139/write-parts.spec.ts +++ b/libs/api/metadata-converter/src/lib/iso19139/write-parts.spec.ts @@ -354,22 +354,20 @@ describe('write parts', () => { ], }, { - geometries: [ - { - type: 'MultiPolygon', - coordinates: [ + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ [ - [ - [6.777075, 45.827119, 0], - [6.755991, 47.517566, 0], - [10.541824, 47.477984, 0], - [10.446252, 45.788744, 0], - [6.777075, 45.827119, 0], - ], + [6.777075, 45.827119, 0], + [6.755991, 47.517566, 0], + [10.541824, 47.477984, 0], + [10.446252, 45.788744, 0], + [6.777075, 45.827119, 0], ], ], - }, - ], + ], + }, }, ], }, diff --git a/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts b/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts index 7700f0557a..1b3ecc508c 100644 --- a/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts +++ b/libs/api/metadata-converter/src/lib/iso19139/write-parts.ts @@ -1196,16 +1196,14 @@ export function writeTemporalExtents( } export function writeSpatialExtents(record: DatasetRecord, rootEl: XmlElement) { - const appendBoundingPolygon = (geometries?: Geometry[]) => { - if (!geometries) return null + const appendBoundingPolygon = (geometry?: Geometry) => { + if (!geometry) return null return pipe( createElement('gmd:EX_BoundingPolygon'), appendChildren( - ...geometries.map((geometry) => - pipe( - createElement('gmd:polygon'), - appendChildren(() => writeGeometry(geometry)) - ) + pipe( + createElement('gmd:polygon'), + appendChildren(() => writeGeometry(geometry)) ) ) ) @@ -1246,7 +1244,7 @@ export function writeSpatialExtents(record: DatasetRecord, rootEl: XmlElement) { pipe( createElement('gmd:geographicElement'), appendChildren( - appendBoundingPolygon(extent.geometries), + appendBoundingPolygon(extent.geometry), appendGeographicBoundingBox(extent.bbox), appendGeographicDescription(extent.description) ) diff --git a/libs/api/metadata-converter/src/lib/xml-utils.ts b/libs/api/metadata-converter/src/lib/xml-utils.ts index 2e389a1f34..4b3789810c 100644 --- a/libs/api/metadata-converter/src/lib/xml-utils.ts +++ b/libs/api/metadata-converter/src/lib/xml-utils.ts @@ -6,6 +6,7 @@ import { XmlText, } from '@rgrove/parse-xml' import { ChainableFunction, fallback } from './function-utils' + export { XmlDocument, XmlElement } from '@rgrove/parse-xml' export class XmlParseError extends Error { @@ -115,6 +116,10 @@ export function allChildrenElement(element: XmlElement): Array { ] as Array } +export function firstChildElement(element: XmlElement): XmlElement { + return allChildrenElement(element)[0] ?? null +} + /** * Will return all matching elements nested according to the given * names (similar to a path), starting form the input element; diff --git a/libs/common/domain/src/lib/model/record/metadata.model.ts b/libs/common/domain/src/lib/model/record/metadata.model.ts index 359711e20c..2de74032c9 100644 --- a/libs/common/domain/src/lib/model/record/metadata.model.ts +++ b/libs/common/domain/src/lib/model/record/metadata.model.ts @@ -159,8 +159,8 @@ export interface GraphicOverview { } export interface DatasetSpatialExtent { - geometries?: Geometry[] bbox?: [number, number, number, number] + geometry?: Geometry description?: string }