diff --git a/models/layerMetadata/decorators/csw.decorator.ts b/models/layerMetadata/decorators/csw.decorator.ts new file mode 100644 index 0000000..88e960f --- /dev/null +++ b/models/layerMetadata/decorators/csw.decorator.ts @@ -0,0 +1,17 @@ +import "reflect-metadata"; + +const pycswMappingMetadataKey = Symbol("pycswmapping"); + +export interface IPYCSWMapping { + xmlElement: string; // pycsw XML element + queryableField: string; // pycsw ProfileRepository Queryable field + pycswField?: string; // pycsw core field +} + +export function pycsw(pycswmapping: IPYCSWMapping) { + return Reflect.metadata(pycswMappingMetadataKey, pycswmapping); +} + +export function getPyCSWMapping(target: any, propertyKey: string) { + return Reflect.getMetadata(pycswMappingMetadataKey, target, propertyKey); +} diff --git a/models/layerMetadata/decorators/shp.decorator.ts b/models/layerMetadata/decorators/shp.decorator.ts new file mode 100644 index 0000000..97d9f82 --- /dev/null +++ b/models/layerMetadata/decorators/shp.decorator.ts @@ -0,0 +1,22 @@ +import "reflect-metadata"; + +const shpMappingMetadataKey = Symbol("shpmapping"); + +export interface IShpMapping { + shpFile: ShapeFileType; + valuePath: string; +} + +export enum ShapeFileType { + FILES = 'Files', + PRODUCT = 'Product', + SHAPE_METADATA = 'ShapeMetadata', +} + +export function shpMapping(shpmapping: IShpMapping) { + return Reflect.metadata(shpMappingMetadataKey, shpmapping); +} + +export function getShpMapping(target: any, propertyKey: string) { + return Reflect.getMetadata(shpMappingMetadataKey, target, propertyKey); +} diff --git a/models/layerMetadata/layerMetadata-StatusFields.ts b/models/layerMetadata/layerMetadata-StatusFields.ts index 7e6fe5b..d4f618f 100644 --- a/models/layerMetadata/layerMetadata-StatusFields.ts +++ b/models/layerMetadata/layerMetadata-StatusFields.ts @@ -1,6 +1,6 @@ import { LayerMetadata } from "./layerMetadata"; -export interface StatusMetadata extends LayerMetadata { +export class StatusMetadata extends LayerMetadata { /** * Layer creation time */ diff --git a/models/layerMetadata/layerMetadata.ts b/models/layerMetadata/layerMetadata.ts index 0a0317f..a35ec97 100644 --- a/models/layerMetadata/layerMetadata.ts +++ b/models/layerMetadata/layerMetadata.ts @@ -1,56 +1,178 @@ import { GeoJSON } from "geojson"; +import { getPyCSWMapping, IPYCSWMapping, pycsw } from "./decorators/csw.decorator"; +import { getShpMapping, IShpMapping, ShapeFileType, shpMapping } from "./decorators/shp.decorator"; + +export interface IPropSHPMapping extends IShpMapping{ + prop: string +} + +export interface IPropPYCSWMapping extends IPYCSWMapping{ + prop: string +} export enum SensorType { - VIS = "VIS", - RGB = "RGB", - Pan_Sharpen = "Pan_Sharpen", - OTHER = "OTHER", + VIS = 'VIS', + RGB = 'RGB', + Pan_Sharpen = 'Pan_Sharpen', + OTHER = 'OTHER', } -export interface LayerMetadata { +export class LayerMetadata { /** * Layer's unique identifier */ - source?: string; + @pycsw({ + xmlElement: 'mc:source', + queryableField: 'mcgc:source', + pycswField: 'pycsw:Source', + }) + @shpMapping({ + shpFile: ShapeFileType.SHAPE_METADATA, + valuePath: 'features[0].properties.Source' + }) + source?: string = undefined; + /** * layer version */ - version?: string; + version?: string = undefined; + /** * Layer's source name */ - sourceName?: string; + @shpMapping({ + shpFile: ShapeFileType.SHAPE_METADATA, + valuePath: 'features[0].properties.SourceName' + }) + sourceName?: string = undefined; + /** * Layer creation time */ - updateDate?: Date; + @shpMapping({ + shpFile: ShapeFileType.SHAPE_METADATA, + valuePath: 'features[0].properties.UpdateDate' + }) + updateDate?: Date = undefined; + /** * Layer resolution */ - resolution?: number; + @shpMapping({ + shpFile: ShapeFileType.SHAPE_METADATA, + valuePath: 'features[0].properties.Resolution' + }) + resolution?: number = undefined; + /** * accuracy */ - ep90?: number; + @shpMapping({ + shpFile: ShapeFileType.SHAPE_METADATA, + valuePath: 'features[0].properties.Ep90' + }) + ep90?: number = undefined; + /** * Layer sensor type */ - sensorType?: SensorType; - rms?: number; + @shpMapping({ + shpFile: ShapeFileType.SHAPE_METADATA, + valuePath: 'features[0].properties.SensorType' + }) + sensorType?: SensorType = undefined; + + /** + * RMS + */ + @shpMapping({ + shpFile: ShapeFileType.SHAPE_METADATA, + valuePath: 'features[0].properties.Rms' + }) + rms?: number = undefined; + /** * Scale of layer */ - scale?: string; + @shpMapping({ + shpFile: ShapeFileType.SHAPE_METADATA, + valuePath: 'features[0].properties.Scale' + }) + scale?: string = undefined; + /** * Layer description */ - dsc?: string; + @pycsw({ + xmlElement: 'mc:description', + queryableField: 'mcgc:description', + pycswField: 'pycsw:Abstract', + }) + @shpMapping({ + shpFile: ShapeFileType.SHAPE_METADATA, + valuePath: 'features[0].properties.Dsc' + }) + dsc?: string = undefined; + /** * List of URIs for the layer files */ - fileUris?: string[]; + fileUris?: string[] = undefined; + /** * General geometry */ - geometry?: GeoJSON; + @pycsw({ + xmlElement: 'ows:BoundingBox', + queryableField: 'mcgc:boundingBox', + pycswField: 'pycsw:BoundingBox', + }) + @shpMapping({ + shpFile: ShapeFileType.SHAPE_METADATA, + valuePath: 'features[0].geometry' + }) + geometry?: GeoJSON = undefined; + + static getPyCSWMapping(prop: string): IPYCSWMapping { + return getPyCSWMapping(new LayerMetadata(), prop); + } + + static getShpMapping(prop: string): IShpMapping { + return getShpMapping(new LayerMetadata(), prop); + } + + static getPyCSWMappings(): IPropPYCSWMapping[] { + const ret = []; + const layer = new LayerMetadata(); + for(const prop in layer){ + if (layer.hasOwnProperty(prop)) { + const pycswMap = getPyCSWMapping(layer, prop); + if(pycswMap){ + ret.push({ + prop: prop, + ...pycswMap + }); + } + } + } + return ret; + } + + static getShpMappings(): IPropSHPMapping[] { + const ret = []; + const layer = new LayerMetadata(); + for(const prop in layer){ + if (layer.hasOwnProperty(prop)) { + const shpMap = getShpMapping(layer, prop); + if(shpMap){ + ret.push({ + prop: prop, + ...shpMap + }); + } + } + } + return ret; + } + } diff --git a/package-lock.json b/package-lock.json index bb20a4f..560023b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4085,6 +4085,12 @@ "strip-indent": "^3.0.0" } }, + "reflect-metadata": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.13.tgz", + "integrity": "sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==", + "dev": true + }, "regenerator-runtime": { "version": "0.13.7", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", diff --git a/package.json b/package.json index 5585fdf..60853e4 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,8 @@ "prepack": "npm run clean && npm run build && npm run copy" }, "dependencies": { - "@types/geojson": "^7946.0.7" + "@types/geojson": "^7946.0.7", + "reflect-metadata": "^0.1.13" }, "devDependencies": { "@commitlint/cli": "^9.1.2", diff --git a/tsconfig.json b/tsconfig.json index 0a1b7a3..31cf65a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,16 +1,20 @@ { - "compilerOptions": { - "target": "ES5", - "module": "commonjs", - "declaration": true, - "outDir": "Schema", - "rootDir": ".", - "strict": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "moduleResolution": "node" - }, - "include": ["models"], - "exclude": ["node_modules"] - } - \ No newline at end of file + "compilerOptions": { + "target": "ES5", + "module": "commonjs", + "experimentalDecorators": true, + "declaration": true, + "outDir": "Schema", + "rootDir": ".", + "strict": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "moduleResolution": "node" + }, + "include": [ + "models" + ], + "exclude": [ + "node_modules" + ] +}