From 1a0b756ac636546e89a3ed33072ebb6d2aba24cd Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Tue, 3 Dec 2024 23:24:49 +0100 Subject: [PATCH 1/4] Update 3D Tiles Tools to 0.4.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c7bcf185..b53fbf4e 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "@gltf-transform/core": "^3.2.1", "@gltf-transform/extensions": "^3.2.1", "@gltf-transform/functions": "^3.2.1", - "3d-tiles-tools": "0.4.2", + "3d-tiles-tools": "0.4.4", "cesium": "^1.97.0", "gltf-validator": "^2.0.0-dev.3.9", "minimatch": "^5.1.0", From d17fa650475d60853960571f11a2492dbad62137 Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Wed, 4 Dec 2024 23:58:39 +0100 Subject: [PATCH 2/4] Add general metadata semantics --- specs/MetadataSchemaValidationSpec.ts | 19 +++++- ...opertySemanticComponentTypeMismatchA.json} | 0 ...ropertySemanticComponentTypeMismatchB.json | 15 +++++ .../metadataClassPropertySemanticGeneric.json | 14 +++++ .../ClassPropertySemanticsValidator.ts | 60 ++++++++++++++++++- 5 files changed, 103 insertions(+), 5 deletions(-) rename specs/data/schemas/{metadataClassPropertySemanticComponentTypeMismatch.json => metadataClassPropertySemanticComponentTypeMismatchA.json} (100%) create mode 100644 specs/data/schemas/metadataClassPropertySemanticComponentTypeMismatchB.json create mode 100644 specs/data/schemas/metadataClassPropertySemanticGeneric.json diff --git a/specs/MetadataSchemaValidationSpec.ts b/specs/MetadataSchemaValidationSpec.ts index 00d2cb83..b9d8241d 100644 --- a/specs/MetadataSchemaValidationSpec.ts +++ b/specs/MetadataSchemaValidationSpec.ts @@ -603,9 +603,17 @@ describe("Metadata schema validation", function () { expect(result.get(0).type).toEqual("METADATA_SEMANTIC_INVALID"); }); - it("detects issues in metadataClassPropertySemanticComponentTypeMismatch", async function () { + it("detects issues in metadataClassPropertySemanticComponentTypeMismatchA", async function () { const result = await Validators.validateSchemaFile( - "specs/data/schemas/metadataClassPropertySemanticComponentTypeMismatch.json" + "specs/data/schemas/metadataClassPropertySemanticComponentTypeMismatchA.json" + ); + expect(result.length).toEqual(1); + expect(result.get(0).type).toEqual("METADATA_SEMANTIC_INVALID"); + }); + + it("detects issues in metadataClassPropertySemanticComponentTypeMismatchB", async function () { + const result = await Validators.validateSchemaFile( + "specs/data/schemas/metadataClassPropertySemanticComponentTypeMismatchB.json" ); expect(result.length).toEqual(1); expect(result.get(0).type).toEqual("METADATA_SEMANTIC_INVALID"); @@ -627,6 +635,13 @@ describe("Metadata schema validation", function () { expect(result.get(0).type).toEqual("TYPE_MISMATCH"); }); + it("detects no issues in metadataClassPropertySemanticGeneric", async function () { + const result = await Validators.validateSchemaFile( + "specs/data/schemas/metadataClassPropertySemanticGeneric.json" + ); + expect(result.length).toEqual(0); + }); + it("detects issues in metadataClassPropertySemanticNormalizedMismatch", async function () { const result = await Validators.validateSchemaFile( "specs/data/schemas/metadataClassPropertySemanticNormalizedMismatch.json" diff --git a/specs/data/schemas/metadataClassPropertySemanticComponentTypeMismatch.json b/specs/data/schemas/metadataClassPropertySemanticComponentTypeMismatchA.json similarity index 100% rename from specs/data/schemas/metadataClassPropertySemanticComponentTypeMismatch.json rename to specs/data/schemas/metadataClassPropertySemanticComponentTypeMismatchA.json diff --git a/specs/data/schemas/metadataClassPropertySemanticComponentTypeMismatchB.json b/specs/data/schemas/metadataClassPropertySemanticComponentTypeMismatchB.json new file mode 100644 index 00000000..828b9438 --- /dev/null +++ b/specs/data/schemas/metadataClassPropertySemanticComponentTypeMismatchB.json @@ -0,0 +1,15 @@ +{ + "id": "EXAMPLE_ID", + "classes": { + "exampleClass": { + "properties": { + "exampleProperty": { + "type": "SCALAR", + "componentType": "INT32", + "array": true, + "semantic": "ATTRIBUTION_IDS" + } + } + } + } +} diff --git a/specs/data/schemas/metadataClassPropertySemanticGeneric.json b/specs/data/schemas/metadataClassPropertySemanticGeneric.json new file mode 100644 index 00000000..12642aed --- /dev/null +++ b/specs/data/schemas/metadataClassPropertySemanticGeneric.json @@ -0,0 +1,14 @@ +{ + "id": "EXAMPLE_ID", + "classes": { + "exampleClass": { + "properties": { + "exampleProperty": { + "type": "STRING", + "array": true, + "semantic": "ATTRIBUTION_STRINGS" + } + } + } + } +} diff --git a/src/validation/metadata/ClassPropertySemanticsValidator.ts b/src/validation/metadata/ClassPropertySemanticsValidator.ts index 79b48d54..2ab7c76a 100644 --- a/src/validation/metadata/ClassPropertySemanticsValidator.ts +++ b/src/validation/metadata/ClassPropertySemanticsValidator.ts @@ -23,7 +23,7 @@ export class ClassPropertySemanticsValidator { * * @param metadataClassPath - The path for `ValidationIssue` instances * @param properties - The properties of the schema class - * @param context - The `ValidatonContext` + * @param context - The `ValidationContext` * @returns Whether the object was valid */ static validateSemantics( @@ -233,6 +233,29 @@ export class ClassPropertySemanticsValidator { return result; } + + /** + * Finds a "matcher" for the specified semantic in the given matching schema. + * + * The given semantic is just the name of the semantic. This is used property + * name in the matching schema. The classes in the given schema are searched + * for a property that has this (semantic) name. If such a "matching property" + * is found, it is returned, and used for checking if the property that + * contained the given semantic matches the "matching property". + * + * Ideally, comparing this "matching property" and the actual property should + * check whether the `type`, `component`, and `array` of the matching property + * are equal to these in the actual property. But given that semantics may + * have different `componentType` values, the returned property may define + * the `componentType` to be a RegEx that the actual component type must + * match against. + * + * Also see the comments for `createMatchingSchema`. + * + * @param matchingSchema - The matching metadata schema to search for semantics + * @param semantic - The name of the semantic + * @returns The matcher, or `undefined` + */ private static findSemanticMatcher( matchingSchema: any, semantic: string @@ -262,7 +285,7 @@ export class ClassPropertySemanticsValidator { * * Eventually, it might make sense to make the component types * unambiguous, so that the semantics definition is actually - * a proper `Schema`. This could be achived by specific semantics + * a proper `Schema`. This could be achieved by specific semantics * like `GEOMETRIC_ERROR_FLOAT32`. * * See https://github.com/CesiumGS/3d-tiles/issues/643 @@ -271,8 +294,39 @@ export class ClassPropertySemanticsValidator { */ private static createMatchingSchema() { const matchingSchema = { - id: "CesiumMetadataSemantics-0.0.0", + id: "CesiumMetadataSemantics-0.0.1", classes: { + GeneralSemantics: { + properties: { + ID: { + description: "The unique identifier for the entity..", + type: "STRING", + }, + NAME: { + description: + "The name of the entity. Names should be human-readable, and do not have to be unique.", + type: "STRING", + }, + DESCRIPTION: { + description: + "Description of the entity. Typically at least a phrase, and possibly several sentences or paragraphs.", + type: "STRING", + }, + ATTRIBUTION_IDS: { + description: + "List of attribution IDs that index into a global list of attribution strings. This semantic may be assigned to metadata at any level of granularity including tileset, group, subtree, tile, content, feature, vertex, and texel granularity. The global list of attribution strings is located in a tileset or subtree with the property semantic ATTRIBUTION_STRINGS. The following precedence order is used to locate the attribution strings: first the containing subtree (if applicable), then the containing external tileset (if applicable), and finally the root tileset.", + type: "SCALAR", + array: true, + componentType: "UINT(8|16|32|64)", + }, + ATTRIBUTION_STRINGS: { + description: + "List of attribution strings. Each string contains information about a data provider or copyright text. Text may include embedded markup languages such as HTML. This semantic may be assigned to metadata at any granularity (wherever STRING property values can be encoded). When used in combination with ATTRIBUTION_IDS it is assigned to subtrees and tilesets.", + type: "STRING", + array: true, + }, + }, + }, TilesetMetadataSemantics: { properties: { TILESET_FEATURE_ID_LABELS: { From 163bb1e49e09be3927bcebbb680131d1b45e300a Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Wed, 4 Dec 2024 23:58:55 +0100 Subject: [PATCH 3/4] Fix typo in TSDoc --- src/validation/metadata/MetadataClassValidator.ts | 2 +- src/validation/metadata/MetadataEnumValidator.ts | 2 +- src/validation/metadata/SchemaDefinitionValidator.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/validation/metadata/MetadataClassValidator.ts b/src/validation/metadata/MetadataClassValidator.ts index 91f6bd4f..22ecc0ee 100644 --- a/src/validation/metadata/MetadataClassValidator.ts +++ b/src/validation/metadata/MetadataClassValidator.ts @@ -25,7 +25,7 @@ export class MetadataClassValidator { * @param name - The name of the class * @param metadataClass - The actual `MetadataClass` * @param schema - The `Schema` - * @param context - The `ValidatonContext` + * @param context - The `ValidationContext` * @returns Whether the object was valid */ static validateMetadataClass( diff --git a/src/validation/metadata/MetadataEnumValidator.ts b/src/validation/metadata/MetadataEnumValidator.ts index 26cee63b..ebea3bfc 100644 --- a/src/validation/metadata/MetadataEnumValidator.ts +++ b/src/validation/metadata/MetadataEnumValidator.ts @@ -25,7 +25,7 @@ export class MetadataEnumValidator { * @param metadataEnumPath - The path for `ValidationIssue` instances * @param enumName - The name of the enum * @param metadataEnum - The actual `MetadataEnum` - * @param context - The `ValidatonContext` + * @param context - The `ValidationContext` * @returns Whether the object was valid */ static validateMetadataEnum( diff --git a/src/validation/metadata/SchemaDefinitionValidator.ts b/src/validation/metadata/SchemaDefinitionValidator.ts index 688f1bc7..9420c356 100644 --- a/src/validation/metadata/SchemaDefinitionValidator.ts +++ b/src/validation/metadata/SchemaDefinitionValidator.ts @@ -44,7 +44,7 @@ export class SchemaDefinitionValidator { * @param name - A name for the containing object (usually 'tileset') * @param schema - The `schema` object from the JSON * @param schemaUri - The `schemaUri` from the JSON - * @param context - The `ValidatonContext` + * @param context - The `ValidationContext` * @returns The schema definition validation result */ static async validateSchemaDefinition( From 971235a2552aab8715197ea616784ffdabf20069 Mon Sep 17 00:00:00 2001 From: Marco Hutter Date: Thu, 5 Dec 2024 00:10:39 +0100 Subject: [PATCH 4/4] Fix typo in description --- src/validation/metadata/ClassPropertySemanticsValidator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/validation/metadata/ClassPropertySemanticsValidator.ts b/src/validation/metadata/ClassPropertySemanticsValidator.ts index 2ab7c76a..4d8cb7e7 100644 --- a/src/validation/metadata/ClassPropertySemanticsValidator.ts +++ b/src/validation/metadata/ClassPropertySemanticsValidator.ts @@ -299,7 +299,7 @@ export class ClassPropertySemanticsValidator { GeneralSemantics: { properties: { ID: { - description: "The unique identifier for the entity..", + description: "The unique identifier for the entity.", type: "STRING", }, NAME: {