@itwin/measure-tools-react
Version:
Frontend framework and tools for measurements
392 lines • 21.5 kB
TypeScript
import type { Id64String } from "@itwin/core-bentley";
import type { GeometryStreamProps } from "@itwin/core-common";
import type { DecorateContext, HitDetail } from "@itwin/core-frontend";
import { BeButtonEvent } from "@itwin/core-frontend";
import type { TransformProps, XYProps, XYZProps } from "@itwin/core-geometry";
import { Point3d, Transform } from "@itwin/core-geometry";
import { Point2d } from "@itwin/core-geometry";
import type { FormatterSpec } from "@itwin/core-quantity";
import { MeasurementButtonHandledEvent } from "./MeasurementEnums.js";
import type { MeasurementProps } from "./MeasurementProps.js";
import { MeasurementViewTarget } from "./MeasurementViewTarget.js";
import { SheetMeasurementsHelper } from "./SheetMeasurementHelper.js";
/** A property value on a measurement that can be aggregated with other similarly-named properties from other measurements so aggregate totals can be displayed in the UI. */
export interface AggregatableValue {
value: number;
formatSpec: FormatterSpec;
}
/** Property value information to represent a value from a measurement in the UI. */
export interface WidgetValue {
label: string;
name: string;
value: string;
aggregatableValue?: AggregatableValue;
}
/** Interface for property grid data of a measurement. */
export interface MeasurementWidgetData {
title: string;
properties: WidgetValue[];
}
export declare namespace DrawingMetadata {
function toJSON(obj: DrawingMetadata | undefined): DrawingMetadataProps | undefined;
function fromJSON(json: DrawingMetadataProps): DrawingMetadata;
function withOverrides(current: DrawingMetadata, overrides?: Partial<DrawingMetadata>): DrawingMetadata;
}
/** Abstract class for serializers that read/write measurements from JSON. */
export declare abstract class MeasurementSerializer {
/** Gets the unique measurement name. This is the property that the serializer looks for on incoming JSON data and writes to when serializing. */
abstract get measurementName(): string;
/** Given a JSON object, a single or an array of Measurements is attempted to be parsed.
* @param data JSON object or undefined.
* @returns Single or Multiple measurements or undefined if data could not be parsed correctly.
*/
parse(data: any): Measurement | Measurement[] | undefined;
/** Serializes single or multiple measurements to a JSON object.
* @param measurement Single or multiple measurements.
* @returns JSON object that will have a single property (the measurementName) or undefined if serialization failed.
*/
serialize(measurement: Measurement | Measurement[]): any;
/** Determines if the measurements are all the same type. Serializers do not handle an array of differently typed measurements.
* @param measurement One or more measurements to check
* @returns true if all measurements are of the same type, false if otherwise.
*/
areValidTypes(measurement: Measurement | Measurement[]): boolean;
/** Subclasses need to implement this to do type checking.
* @param measurement Measurement to check.
* @returns true if the measurement is a valid type, false if otherwise.
*/
abstract isValidType(measurement: Measurement): boolean;
/**
* Subclasses can implement this to do JSON data validation. Some measurements may have optional properties, other measurements may need data that HAS to be present in order to
* create a new instance.
* @param json JSON data to validate.
*/
isValidJSON(_json: any): boolean;
/** Subclasses need to implement this to handle parsing a measurement type from JSON.
* @param data JSON data to parse.
* @returns Measurement instance or undefined if parsing failed.
*/
protected abstract parseSingle(data: MeasurementProps): Measurement | undefined;
/** Handles serializing a measurement type to JSON.
* @param measurement Measurement instance to serialize.
* @returns JSON object with measurement props.
*/
protected serializeSingle(measurement: Measurement): MeasurementProps | undefined;
}
/** Defines the context for testing if a measurement is being picked. */
export declare class MeasurementPickContext {
/** Geometry ID that was picked. */
readonly geomId: string;
/** Optional extended information about the pick hit on the geometry. */
readonly hitDetail?: HitDetail;
/** Optional extended information about the button event that generated the pick. */
readonly buttonEvent?: BeButtonEvent;
/**
* Constructs a new pick detail.
* @param geomId Geometry ID that was picked.
* @param hitDetail Optional information about the pick hit on the geometry.
* @param ev Optional information about the button event that generated the pick.
*/
constructor(geomId: string, hitDetail?: HitDetail, ev?: BeButtonEvent);
/**
* Creates a pick detail from the supplied arguments.
* @param hitDetail HitDetail containing the pick information.
* @param ev Button event, if undefined the current input state is queried.
*/
static create(hitDetail: HitDetail, ev?: BeButtonEvent): MeasurementPickContext;
/**
* Creates a pick detail from the supplied arguments.
* @param geomId Geometry ID that was picked
* @param ev Button event, if undefined the current input state is queried.
*/
static createFromSourceId(geomId: string, ev?: BeButtonEvent): MeasurementPickContext;
}
/** Represents how two measurements should be compared to in an equality test. If data-equality is desired, use some of these options to turn off checks for base properties. */
export interface MeasurementEqualityOptions {
/** If true, ignore styling properties when comparing. */
ignoreStyle?: true | undefined;
/** If true, ignore view target contents when comparing. */
ignoreViewTarget?: true | undefined;
/** If true, ignore any ID information (grouping or otherwise). */
ignoreIds?: true | undefined;
/** If true, ignore the measurement labels. */
ignoreLabel?: true | undefined;
/** If true, ignore any other non-data state information, such as if the measurement's lock state. When combined with the other ignore options, the equality will not test base measurement properties. */
ignoreNonDataState?: true | undefined;
/** Tolerance for numerical equality (usually [[Geometry.smallMetricDistance]] is a default). */
tolerance?: number;
/** Tolerance for angle equality, if needed (usually [[Geometry.smallAngleRadians]] is a default). */
angleTolerance?: number;
}
export interface DrawingMetadataProps extends Omit<DrawingMetadata, "origin" | "extents" | "sheetToWorldTransform"> {
origin: XYProps;
extents?: XYProps;
sheetToWorldTransform?: {
masterOrigin: XYZProps;
sheetTov8Drawing: TransformProps;
v8DrawingToDesign: TransformProps;
};
}
export interface DrawingMetadata {
/** Id of the drawing */
drawingId?: string;
/** Scaling from sheet to world distance */
worldScale: number;
/** Origin of the drawing in sheet coordinates */
origin: Point2d;
/** Extents of the drawing in sheet coordinates */
extents?: Point2d;
/** Represents the transform from sheet points to 3d points */
sheetToWorldTransform?: SheetMeasurementsHelper.SheetTransformParams;
/** Represents the transform from sheet points to distance along alignment (X) and vertical position related to alignment (Y) */
sheetToProfileTransform?: Transform;
}
/** Handler function that modifies the data sent to the widget for display. */
export type MeasurementDataWidgetHandlerFunction = (m: Measurement, currentData: MeasurementWidgetData) => Promise<void>;
/** Handler for modifying the data sent to the widget for display. The highest priority will execute last. */
export interface MeasurementDataWidgetHandler {
priority: number;
handlerFunction: MeasurementDataWidgetHandlerFunction;
}
/**
* Abstract class representing a Measurement. Measurements are semi-persistent annotation objects that can be drawn to a viewport. They are not stored
* in the iModel database, but can be serialized to a JSON string for storage.
*/
export declare abstract class Measurement {
private static _serializers;
private static _dataForMeasurementWidgetHandlers;
private _isLocked;
private _groupId?;
private _subgroupId?;
private _id?;
private _label?;
private _style?;
private _lockStyle?;
private _viewTarget;
private _displayLabels;
private _transientId?;
private _isVisible;
private _drawingMetadata?;
/** Default drawing style name. */
static readonly defaultStyle: string;
/** Default locked drawing styl name. */
static readonly defaultLockStyle: string;
/** Each subclass should register and set a serializer object for itself to this property. If undefined, the measurement does not participate in serialization. */
static readonly serializer: MeasurementSerializer | undefined;
/** Gets the serializer associated with this measurement type. If undefined, the measurement does not participate in serialization. */
get serializer(): MeasurementSerializer | undefined;
/** Gets or sets the transient ID used by this measurement. This enables using measurements with selection, snapping, and picking.
* Subclasses should get a transient ID when needed from the imodel in the global @see [[MeasurementSelectionSet]]. If the imodel
* changes, the transient ID of all measurements is reset. Normally you do not need to do this yourself.
*/
get transientId(): Id64String | undefined;
set transientId(newId: Id64String | undefined);
get drawingMetadata(): Readonly<DrawingMetadata | undefined>;
set drawingMetadata(data: DrawingMetadata | undefined);
get worldScale(): Readonly<number>;
set sheetViewId(id: string | undefined);
/** Gets or sets if the measurement should be drawn. */
get isVisible(): boolean;
set isVisible(v: boolean);
/** Gets or sets if the measurement is locked. Locked measurements have a different styling, cannot be edited, and cannot be cleared by the clear measurement tool. */
get isLocked(): boolean;
set isLocked(value: boolean);
/** Gets or sets the group ID for the measurement. This is used to categorize the measurement in a meaningful way to the application. */
get groupId(): string | undefined;
set groupId(value: string | undefined);
/** Gets or sets the subgroup ID for the measurement. This is used to categorize the measurement in a meaningful way to the application. */
get subgroupId(): string | undefined;
set subgroupId(value: string | undefined);
/** Gets or sets the ID for the measurement. This is used to categorize the measurement in a meaningful way to the application. */
get id(): string | undefined;
set id(value: string | undefined);
/** Gets or sets the display label for the measurement. */
get label(): string | undefined;
set label(value: string | undefined);
/** Gets or sets the mame of the StyleSet to apply when drawing this measurement. If undefined, the default style is used. */
get style(): string | undefined;
set style(value: string | undefined);
/** Gets or sets the name of the StyleSet to apply when drawing this measurement when it is locked. If undefined, the default lock style is used. */
get lockStyle(): string | undefined;
set lockStyle(value: string | undefined);
/**
* Computes the active style for the measurement.
* @returns the active style based on the locking flag. If the style is undefined, the default style is returned (default when unlocked, default-locked when locked).
*/
get activeStyle(): string;
/** Gets the views this measurement targets. */
get viewTarget(): MeasurementViewTarget;
get displayLabels(): boolean;
set displayLabels(display: boolean);
/** Communicates to the action toolbar this measurement wants to participate in actions. */
get allowActions(): boolean;
/** Protected constructor */
protected constructor(props?: MeasurementProps);
/** Copies the measurement data into a new instance.
* @returns clone of this measurement.
*/
clone<T extends Measurement>(): T;
/**
* Serializes the measurement's data into a JSON prop object. Subclasses participate by overriding the writeToJSON method.
* @returns prop object containing the values of the measurement.
*/
toJSON<T extends MeasurementProps>(): T;
/**
* Tests equality with another measurement.
* @param other Measurement to test equality for.
* @param opts Options for equality testing.
* @returns true if the other measurement is equal, false if some property is not the same or if the measurement is not of the same type.
*/
equals(other: Measurement, opts?: MeasurementEqualityOptions): boolean;
/** Draw the measurement. This is called every frame, e.g. when the mouse moves. This is suitable for small or dynamic graphics, but if the measurement
* has complicated graphics, consider using the decorateCached method.
* @param context Decorate context for drawing to a viewport.
*/
decorate(_context: DecorateContext): void;
/** Draw any graphics that need to be cached. This is called when the scene changes, e.g. zoom or rotate.
* @param context Decorate context for drawing to a viewport.
*/
decorateCached(_context: DecorateContext): void;
/** Test if the measurement was picked.
* @param _pickContext Picking context to test against.
* @returns true if the measurement has been picked, false otherwise.
*/
testDecorationHit(_pickContext: MeasurementPickContext): boolean;
/** Get a geometry stream representing the pickable geometry of the measurement. Usually this is simplier geometry than what is drawn.
* @param _pickContext Picking context to test against.
* @returns a geometry stream of pickable data or undefined.
*/
getDecorationGeometry(_pickContext: MeasurementPickContext): GeometryStreamProps | undefined;
/** Get a tooltip for this measurement.
* @param _pickContext Picking context to test against.
* @returns a tooltip HTML element or string.
*/
getDecorationToolTip(_pickContext: MeasurementPickContext): Promise<HTMLElement | string>;
/**
* Register a handler to modify the behavior of the widget data shown.
* @param handler Function that modifies the WidgetData
* @param priority Priority of the handler, highest priority will execute last
*/
static registerDataForMeasurementWidgetHandler(handler: MeasurementDataWidgetHandlerFunction, priority?: number): boolean;
/**
* Gets formatted property data for the measurement UI widget.
* @returns promise with data or undefined if there is no data to display.
*/
getDataForMeasurementWidget(): Promise<MeasurementWidgetData | undefined>;
/**
* Gets formatted property data for the measurement UI widget.
* @returns promise with data or undefined if there is no data to display.
*/
protected getDataForMeasurementWidgetInternal(): Promise<MeasurementWidgetData | undefined>;
/**
* Responds to a button event. By default this tests if the measurement was picked and opens the action toolbar.
* @param pickContext Picking context to test against.
* @returns Whether or not the event was handled.
*/
onDecorationButtonEvent(pickContext: MeasurementPickContext): Promise<MeasurementButtonHandledEvent>;
/** Cleans up any resources (e.g. IDisposable objects) */
onCleanup(): void;
/** Adjusts a point to account for Global Origin. This is required in order to display coordinates as text.
* May return a reference to the original point, or a new point if the global origin is applied
*/
protected adjustPointForGlobalOrigin(point: Point3d): Readonly<Point3d>;
/** Adjusts point with the sheetToWorldTransform
* This is used to display 3d world information in sheets
*/
protected adjustPointWithSheetToWorldTransform(point: Point3d): Readonly<Point3d>;
/**
* Creates a new instance of the measurement subclass. This works well for most subclasses that have a parameterless constructor (or one that takes in an optional props object).
* Otherwise, the subclass should override this if it has special needs to correctly instantiate a new instance of itself.
*/
protected createNewInstance(): Measurement;
/**
* Copies data from the other measurement into this instance.
* @param other Measurement to copy property values from.
*/
protected copyFrom(other: Measurement): void;
/**
* Deserializes properties (if they exist) from the JSON object.
* @param json JSON object to read data from.
*/
protected readFromJSON(json: MeasurementProps): void;
/**
* Serializes properties to a JSON object.
* @param json JSON object to append data to.
*/
protected writeToJSON(json: MeasurementProps): void;
/** Notify subclasses that style options have changed. This is to allow implementations to regenerate any cached graphics.
* @param _isLock true if the lock style was changed, false if the regular style.
* @param _prevStyle The previous style name.
*/
protected onStyleChanged(_isLock: boolean, _prevStyle?: string): void;
/** Notify subclasses the group ID changed.
* @param _prevGroupid The previous group ID.
*/
protected onGroupIdChanged(_prevGroupid?: string): void;
/** Notify subclasses the subgroup ID changed.
* @param _prevSubgroupId The previous subgroup ID.
*/
protected onSubGroupIdChanged(_prevSubgroupId?: string): void;
/** Notify subclasses the ID changed.
* @param _prevId The previous ID.
*/
protected onIdChanged(_prevId?: string): void;
/**
* Notify subclasses the label changed.
* @param _prevLabel The previous label value.
*/
protected onLabelChanged(_prevLabel?: string): void;
/** Notify subclasses when the measurement's lock is toggled. */
protected onLockToggled(): void;
/** Notify subclasses when the display units have changed. */
onDisplayUnitsChanged(): void;
/** Notify subclasses when the transient ID has changed.
* @param _prevId The previous ID, if any.
*/
protected onTransientIdChanged(_prevId?: Id64String): void;
/**
* Notify subclasses when DrawingMetadata changes
*/
protected onDrawingMetadataChanged(): void;
/**
* Notify subclasses when the display labels property has changed.
*/
protected onDisplayLabelsToggled(): void;
/** Parses a JSON object into a single or multiple measurements.
* @param data JSON object
* @returns single or multiple measurements or undefine if parsing failed, or the JSON object is undefined.
*/
static parse(data?: any): Measurement | Measurement[] | undefined;
/** Parses a JSON object into a single measurement. If the JSON object had multiple measurements, only the first
* one is returned.
* @param data JSON object
* @returns single measurement or undefined if parsing failed.
*/
static parseSingle(data?: any): Measurement | undefined;
/** Serializes one or more measurements into one or more JSON objects. For each type of measurement, the result will be a JSON object with a single
* named property representing the measuremnt (e.g. "distanceMeasurement") which itself will either be a single JSON object or an array if more than one. If all measurements
* are the same type, a single JSON object is returned. If there are multiple measurement types (e.g. distance, area, etc) then an array is returned where each entry is a JSON
* object with the single named property.
* @param measurement one or more measurements.
* @returns undefined if nothing could be serialized OR a single JSON object if all the measurements are of the same type OR an array of JSON objects.
*/
static serialize(measurement: Measurement | Measurement[]): any | any[];
/** Registers a measurement serializer that is used in the parse/serialize static methods. Once a serializer is registered, it cannot be dropped.
* If you need to override a measurement, do so by subclassing the measurement and it's serializer.
* @param serializer serializer that handles a unique measurement during parsing/serialization.
* @throws error if the serializer's name is not unique.
*/
static registerSerializer(serializer: MeasurementSerializer): MeasurementSerializer | undefined;
/**
* Finds a serializer for the given name.
* @param measurementName measurement name that a serializer is associated with.
* @returns the associated serializer or undefined if none exists for the given name.
*/
static findSerializer(measurementName: string): MeasurementSerializer | undefined;
/**
* Invalidate decorations for all viewports that can draw the specified measurements.
* @param measurements Array of measurements to invalidate views for.
*/
static invalidateDecorationsForAll(measurements: Measurement[]): void;
}
//# sourceMappingURL=Measurement.d.ts.map