UNPKG

@itwin/core-backend

Version:
288 lines • 12.5 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module iModels */ import { Id64, JsonUtils } from "@itwin/core-bentley"; import { BisCodeSpec, Code, Rank, SubCategoryAppearance, } from "@itwin/core-common"; import { DefinitionElement } from "./Element"; import { EditTxn } from "./EditTxn"; import { IModelDb } from "./IModelDb"; import { CategoryOwnsSubCategories } from "./NavigationRelationship"; import { _implicitTxn } from "./internal/Symbols"; /** Defines the appearance for graphics in Geometric elements * @public @preview */ export class SubCategory extends DefinitionElement { static get className() { return "SubCategory"; } /** The Appearance parameters for this SubCategory */ appearance; /** Optional description of this SubCategory. */ description; constructor(props, iModel) { super(props, iModel); this.appearance = new SubCategoryAppearance(props.appearance); this.description = JsonUtils.asString(props.description); } /** * SubCategory custom HandledProps include 'description' and 'properties'. * @inheritdoc * @beta */ static _customHandledProps = [ { propertyName: "description", source: "Class" }, { propertyName: "properties", source: "Class" }, ]; /** * SubCategory deserializes 'description' and 'properties'. * @inheritdoc * @beta */ static deserialize(props) { const elProps = super.deserialize(props); elProps.description = JsonUtils.asString(props.row.description); if (props.row.properties !== '') { elProps.appearance = JSON.parse(props.row.properties); } else { elProps.appearance = undefined; } return elProps; } /** * SubCategory serialize 'description' and 'properties'. * @inheritdoc * @beta */ static serialize(props, iModel) { const inst = super.serialize(props, iModel); if (props.description !== undefined) { inst.description = props.description; } if (props.appearance !== undefined) { inst.properties = JSON.stringify(props.appearance); } return inst; } toJSON() { const val = super.toJSON(); val.appearance = this.appearance.toJSON(); if (this.description && this.description.length > 0) val.description = this.description; return val; } /** Get the SubCategory's name (its Code value). */ getSubCategoryName() { return this.code.value; } /** Get the Id of the SubCategory. */ getSubCategoryId() { return this.id; } /** Get the Id of this SubCategory's parent Category. */ getCategoryId() { return this.parent ? this.parent.id : Id64.invalid; } /** Check if this is the default SubCategory of its parent Category. */ get isDefaultSubCategory() { return IModelDb.getDefaultSubCategoryId(this.getCategoryId()) === this.getSubCategoryId(); } /** Create a Code for a SubCategory given a name that is meant to be unique within the scope of the specified parent Category. * @param iModel The IModel * @param parentCategoryId The Id of the parent Category that owns the SubCategory and provides the scope for its name. * @param codeValue The name of the SubCategory */ static createCode(iModel, parentCategoryId, codeValue) { const codeSpec = iModel.codeSpecs.getByName(BisCodeSpec.subCategory); return new Code({ spec: codeSpec.id, scope: parentCategoryId, value: codeValue }); } /** Create a new SubCategory * @param iModelDb The iModel * @param parentCategoryId Create the new SubCategory as a child of this [[Category]] * @param name The name of the SubCategory * @param appearance The appearance settings to use for this SubCategory * @returns The newly constructed SubCategory element. * @throws [[IModelError]] if unable to create the element. */ static create(iModelDb, parentCategoryId, name, appearance) { if (appearance instanceof SubCategoryAppearance) appearance = appearance.toJSON(); const parentCategory = iModelDb.elements.getElement(parentCategoryId); const subCategoryProps = { classFullName: this.classFullName, model: parentCategory.model, parent: new CategoryOwnsSubCategories(parentCategoryId), code: this.createCode(iModelDb, parentCategoryId, name), appearance, }; return new SubCategory(subCategoryProps, iModelDb); } static insert(txnOrDb, parentCategoryId, name, appearance) { const txn = txnOrDb instanceof EditTxn ? txnOrDb : txnOrDb[_implicitTxn]; const subCategory = this.create(txn.iModel, parentCategoryId, name, appearance); return subCategory.insert(txn); } } /** A Category element is the target of the `category` member of [[GeometricElement]]. * @public @preview */ export class Category extends DefinitionElement { static get className() { return "Category"; } rank = Rank.User; description; constructor(props, iModel) { super(props, iModel); this.rank = JsonUtils.asInt(props.rank); this.description = JsonUtils.asString(props.description); } /** * Category custom HandledProps include 'rank' and 'description'. * @inheritdoc * @beta */ static _customHandledProps = [ { propertyName: "rank", source: "Class" }, { propertyName: "description", source: "Class" }, ]; /** * Category deserializes 'rank' and 'description'. * @inheritdoc * @beta */ static deserialize(props) { const elProps = super.deserialize(props); elProps.description = JsonUtils.asString(props.row.description); elProps.rank = JsonUtils.asInt(props.row.rank); return elProps; } /** * Category serialize 'rank' and 'description'. * @inheritdoc * @beta */ static serialize(props, iModel) { const inst = super.serialize(props, iModel); if (undefined !== props.description) { inst.description = props.description; } inst.rank = props.rank; return inst; } toJSON() { const val = super.toJSON(); val.rank = this.rank; if (this.description && this.description.length > 0) val.description = this.description; return val; } /** Get the Id of the default SubCategory for this Category. */ myDefaultSubCategoryId() { return IModelDb.getDefaultSubCategoryId(this.id); } setDefaultAppearance(txnOrProps, props) { let txn; let appearance; if (txnOrProps instanceof EditTxn) { txn = txnOrProps; if (props === undefined) throw new Error("Invalid argument"); appearance = props; } else { txn = this.iModel[_implicitTxn]; appearance = txnOrProps; } if (appearance instanceof SubCategoryAppearance) appearance = appearance.toJSON(); const subCat = this.iModel.elements.getElement(this.myDefaultSubCategoryId()); subCat.appearance = new SubCategoryAppearance(appearance); subCat.update(txn); } } /** Categorizes 2d GeometricElements. * @public @preview */ export class DrawingCategory extends Category { static get className() { return "DrawingCategory"; } constructor(opts, iModel) { super(opts, iModel); } /** Get the name of the CodeSpec that is used by DrawingCategory objects. */ static getCodeSpecName() { return BisCodeSpec.drawingCategory; } /** Looks up the CategoryId of a DrawingCategory by model and name */ static queryCategoryIdByName(iModel, scopeModelId, categoryName) { const code = DrawingCategory.createCode(iModel, scopeModelId, categoryName); return iModel.elements.queryElementIdByCode(code); } /** Create a Code for a DrawingCategory given a name that is meant to be unique within the scope of the specified DefinitionModel. * @param iModel The IModel * @param scopeModelId The Id of the DefinitionModel that contains the DrawingCategory and provides the scope for its name. * @param codeValue The name of the category * @return A drawing category Code */ static createCode(iModel, scopeModelId, codeValue) { const codeSpec = iModel.codeSpecs.getByName(DrawingCategory.getCodeSpecName()); return new Code({ spec: codeSpec.id, scope: scopeModelId, value: codeValue }); } /** Create a new DrawingCategory * @param iModelDb The iModel * @param definitionModelId The [[DefinitionModel]] * @param name The name of the DrawingCategory * @returns The newly constructed DrawingCategory element. * @throws [[IModelError]] if unable to create the element. */ static create(iModelDb, definitionModelId, name) { const categoryProps = { classFullName: this.classFullName, model: definitionModelId, code: this.createCode(iModelDb, definitionModelId, name), isPrivate: false, }; return new DrawingCategory(categoryProps, iModelDb); } static insert(txnOrDb, definitionModelId, name, defaultAppearance) { const txn = txnOrDb instanceof EditTxn ? txnOrDb : txnOrDb[_implicitTxn]; const category = this.create(txn.iModel, definitionModelId, name); category.id = category.insert(txn); category.setDefaultAppearance(txn, defaultAppearance); return category.id; } } /** Categorizes SpatialElements. See [how to create a SpatialCategory]($docs/learning/backend/CreateElements.md#SpatialCategory). * @public @preview */ export class SpatialCategory extends Category { static get className() { return "SpatialCategory"; } constructor(opts, iModel) { super(opts, iModel); } /** Get the name of the CodeSpec that is used by SpatialCategory objects. */ static getCodeSpecName() { return BisCodeSpec.spatialCategory; } /** Looks up the CategoryId of a SpatialCategory by model and name */ static queryCategoryIdByName(iModel, scopeModelId, categoryName) { const code = SpatialCategory.createCode(iModel, scopeModelId, categoryName); return iModel.elements.queryElementIdByCode(code); } /** Create a Code for a SpatialCategory given a name that is meant to be unique within the scope of the specified DefinitionModel. * @param iModel The IModel * @param scopeModelId The Id of the DefinitionModel that contains the SpatialCategory and provides the scope for its name. * @param codeValue The name of the category * @return A spatial category Code */ static createCode(iModel, scopeModelId, codeValue) { const codeSpec = iModel.codeSpecs.getByName(SpatialCategory.getCodeSpecName()); return new Code({ spec: codeSpec.id, scope: scopeModelId, value: codeValue }); } /** Create a new SpatialCategory * @param iModelDb The iModel * @param definitionModelId The [[DefinitionModel]] * @param name The name/CodeValue of the SpatialCategory * @returns The newly constructed SpatialCategory element. * @throws [[IModelError]] if unable to create the element. */ static create(iModelDb, definitionModelId, name) { const categoryProps = { classFullName: this.classFullName, model: definitionModelId, code: this.createCode(iModelDb, definitionModelId, name), isPrivate: false, }; return new SpatialCategory(categoryProps, iModelDb); } static insert(txnOrDb, definitionModelId, name, defaultAppearance) { const txn = txnOrDb instanceof EditTxn ? txnOrDb : txnOrDb[_implicitTxn]; const category = this.create(txn.iModel, definitionModelId, name); category.id = category.insert(txn); category.setDefaultAppearance(txn, defaultAppearance); return category.id; } } //# sourceMappingURL=Category.js.map