Skip to content

Commit fb40c69

Browse files
committed
use the specRegistry in quantity formatter
1 parent e259a70 commit fb40c69

File tree

8 files changed

+111
-113
lines changed

8 files changed

+111
-113
lines changed

packages/itwin/measure-tools/eslint.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export default [
1414
{
1515
tag: [
1616
"internal",
17+
"alpha",
1718
],
1819
},
1920
],

packages/itwin/measure-tools/src/api/Measurement.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,8 @@ export abstract class Measurement {
823823
/** Notify subclasses when the display units have changed. */
824824
public onDisplayUnitsChanged(): void { }
825825

826+
public async populateFormattingSpecsRegistry(): Promise<void> { }
827+
826828
/** Notify subclasses when the transient ID has changed.
827829
* @param _prevId The previous ID, if any.
828830
*/
@@ -995,4 +997,6 @@ export abstract class Measurement {
995997

996998
target.invalidateViewportDecorations();
997999
}
1000+
1001+
9981002
}

packages/itwin/measure-tools/src/api/MeasurementManager.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,6 @@ export class MeasurementManager implements Decorator {
455455
const unsubscribers = [IModelApp.quantityFormatter.onActiveFormattingUnitSystemChanged.addListener(this.onActiveUnitSystemChanged, this),
456456
IModelApp.quantityFormatter.onQuantityFormatsChanged.addListener(this.onActiveUnitSystemChanged, this),
457457
IModelApp.quantityFormatter.onUnitsProviderChanged.addListener(this.onActiveUnitSystemChanged, this),
458-
IModelApp.formatsProvider.onFormatsChanged.addListener(this.onActiveUnitSystemChanged, this) // TODO: Maybe add a different event handler for this, to handle individual format changes.
459458
];
460459
this._dropQuantityFormatterListeners = () => unsubscribers.forEach((unsubscriber) => {
461460
unsubscriber();

packages/itwin/measure-tools/src/measurements/AngleMeasurement.ts

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ import type { MeasurementFormattingProps, MeasurementProps } from "../api/Measur
3838
import { MeasurementSelectionSet } from "../api/MeasurementSelectionSet.js";
3939
import { TextMarker } from "../api/TextMarker.js";
4040
import { MeasureTools } from "../MeasureTools.js";
41-
import type { FormatterSpec } from "@itwin/core-quantity";
4241

4342
export interface AngleMeasurementProps extends MeasurementProps {
4443
startPoint?: XYZProps;
@@ -98,7 +97,8 @@ export class AngleMeasurement extends Measurement {
9897
this._anglePersistenceUnitName = "Units.RAD";
9998
if (props) this.readFromJSON(props);
10099

101-
this.createTextMarker().catch(); // eslint-disable-line @typescript-eslint/no-floating-promises
100+
this.populateFormattingSpecsRegistry().then(() => this.createTextMarker().catch())
101+
.catch();
102102
}
103103

104104
public get startPointRef(): Point3d | undefined {
@@ -176,6 +176,19 @@ export class AngleMeasurement extends Measurement {
176176
this.createTextMarker().catch(); // eslint-disable-line @typescript-eslint/no-floating-promises
177177
}
178178

179+
public override async populateFormattingSpecsRegistry(): Promise<void> {
180+
const angleEntry = IModelApp.quantityFormatter.getSpecsByName(this._angleKoQ);
181+
if (!angleEntry || angleEntry.formatterSpec.persistenceUnit?.name !== this._anglePersistenceUnitName) {
182+
const angleFormatProps = await IModelApp.formatsProvider.getFormat(this._angleKoQ);
183+
if (angleFormatProps) {
184+
await IModelApp.quantityFormatter.addFormattingSpecsToRegistry(
185+
this._angleKoQ,
186+
this._anglePersistenceUnitName,
187+
angleFormatProps
188+
);
189+
}
190+
}
191+
}
179192
/**
180193
* Tests equality with another measurement.
181194
* @param other Measurement to test equality for.
@@ -390,14 +403,7 @@ export class AngleMeasurement extends Measurement {
390403
}
391404

392405
protected override async getDataForMeasurementWidgetInternal(): Promise<MeasurementWidgetData> {
393-
const formatProps = await IModelApp.formatsProvider.getFormat(this._angleKoQ);
394-
let angleSpec: FormatterSpec | undefined;
395-
if (formatProps) {
396-
angleSpec = await IModelApp.quantityFormatter.createFormatterSpec({
397-
formatProps,
398-
persistenceUnitName: this._anglePersistenceUnitName
399-
});
400-
}
406+
const angleSpec = IModelApp.quantityFormatter.getSpecsByName(this._angleKoQ)?.formatterSpec;
401407
const angle = this.angle ?? 0;
402408
const fAngle = IModelApp.quantityFormatter.formatQuantity(angle, angleSpec);
403409

@@ -426,14 +432,7 @@ export class AngleMeasurement extends Measurement {
426432

427433
private async createTextMarker(): Promise<void> {
428434
if (this._center !== undefined && this.angle !== undefined) {
429-
const formatProps = await IModelApp.formatsProvider.getFormat(this._angleKoQ);
430-
let angleSpec: FormatterSpec | undefined;
431-
if (formatProps) {
432-
angleSpec = await IModelApp.quantityFormatter.createFormatterSpec({
433-
formatProps,
434-
persistenceUnitName: this._anglePersistenceUnitName
435-
});
436-
}
435+
const angleSpec = IModelApp.quantityFormatter.getSpecsByName(this._angleKoQ)?.formatterSpec;
437436
const angle = this.angle;
438437
const fAngle = IModelApp.quantityFormatter.formatQuantity(
439438
angle,

packages/itwin/measure-tools/src/measurements/AreaMeasurement.ts

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ import { MeasurementSelectionSet } from "../api/MeasurementSelectionSet.js";
3636
import { Polygon } from "../api/Polygon.js";
3737
import { DistanceMeasurement } from "./DistanceMeasurement.js";
3838
import { MeasureTools } from "../MeasureTools.js";
39-
import type { FormatterSpec } from "@itwin/core-quantity";
4039

4140
/**
4241
* Props for serializing a [[AreaMeasurement]].
@@ -178,6 +177,8 @@ export class AreaMeasurement extends Measurement {
178177
this._isDynamic = false;
179178

180179
if (props) this.readFromJSON(props);
180+
181+
this.populateFormattingSpecsRegistry().catch();
181182
}
182183

183184
private handleTextMarkerButtonEvent(ev: BeButtonEvent): boolean {
@@ -190,6 +191,23 @@ export class AreaMeasurement extends Measurement {
190191
return true;
191192
}
192193

194+
public override async populateFormattingSpecsRegistry(): Promise<void> {
195+
const lengthEntry = IModelApp.quantityFormatter.getSpecsByName(this._lengthKoQ);
196+
if (!lengthEntry || lengthEntry.formatterSpec.persistenceUnit?.name !== this._lengthPersistenceUnitName) {
197+
const lengthFormatProps = await IModelApp.formatsProvider.getFormat(this._lengthKoQ);
198+
if (lengthFormatProps) {
199+
await IModelApp.quantityFormatter.addFormattingSpecsToRegistry(this._lengthKoQ, this._lengthPersistenceUnitName, lengthFormatProps);
200+
}
201+
}
202+
const areaEntry = IModelApp.quantityFormatter.getSpecsByName(this._areaKoQ);
203+
if (!areaEntry || areaEntry.formatterSpec.persistenceUnit?.name !== this._areaPersistenceUnitName) {
204+
const areaFormatProps = await IModelApp.formatsProvider.getFormat(this._areaKoQ);
205+
if (areaFormatProps) {
206+
await IModelApp.quantityFormatter.addFormattingSpecsToRegistry(this._areaKoQ, this._areaPersistenceUnitName, areaFormatProps);
207+
}
208+
}
209+
}
210+
193211
public addPointToDynamicPolygon(point: Point3d): boolean {
194212
if (!this.isDynamic) return false;
195213

@@ -449,22 +467,8 @@ export class AreaMeasurement extends Measurement {
449467
}
450468

451469
protected override async getDataForMeasurementWidgetInternal(): Promise<MeasurementWidgetData> {
452-
let lengthSpec: FormatterSpec | undefined;
453-
let areaSpec: FormatterSpec | undefined;
454-
const lengthFormatProps = await IModelApp.formatsProvider.getFormat(this._lengthKoQ);
455-
const areaFormatProps = await IModelApp.formatsProvider.getFormat(this._areaKoQ);
456-
if (lengthFormatProps) {
457-
lengthSpec = await IModelApp.quantityFormatter.createFormatterSpec({
458-
formatProps: lengthFormatProps,
459-
persistenceUnitName: this._lengthPersistenceUnitName
460-
});
461-
}
462-
if (areaFormatProps) {
463-
areaSpec = await IModelApp.quantityFormatter.createFormatterSpec({
464-
formatProps: areaFormatProps,
465-
persistenceUnitName: this._areaPersistenceUnitName
466-
});
467-
}
470+
const lengthSpec = IModelApp.quantityFormatter.getSpecsByName(this._lengthKoQ)?.formatterSpec;
471+
const areaSpec = IModelApp.quantityFormatter.getSpecsByName(this._areaKoQ)?.formatterSpec;
468472

469473
const fPerimeter = IModelApp.quantityFormatter.formatQuantity(
470474
this.worldScale * this._polygon.perimeter,
@@ -666,7 +670,7 @@ export class AreaMeasurement extends Measurement {
666670

667671
public static create(pts: Point3d[], viewType?: string, formatting?: { length?: MeasurementFormattingProps, area?: MeasurementFormattingProps }): AreaMeasurement {
668672
// Don't ned to serialize the points, will just work as is
669-
const measurement = new AreaMeasurement({ polygonPoints: pts, formatting});
673+
const measurement = new AreaMeasurement({ polygonPoints: pts, formatting });
670674
if (viewType) measurement.viewTarget.include(viewType);
671675

672676
return measurement;

packages/itwin/measure-tools/src/measurements/DistanceMeasurement.ts

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ import type { MeasurementFormattingProps, MeasurementProps } from "../api/Measur
4343
import { MeasurementSelectionSet } from "../api/MeasurementSelectionSet.js";
4444
import { TextMarker } from "../api/TextMarker.js";
4545
import { MeasureTools } from "../MeasureTools.js";
46-
import type { FormatterSpec } from "@itwin/core-quantity";
4746

4847
/**
4948
* Props for serializing a [[DistanceMeasurement]].
@@ -197,7 +196,8 @@ export class DistanceMeasurement extends Measurement {
197196
this._bearingPersistenceUnitName = "Units.RAD"; // TODO: Once units schema 1.0.9 is released, change to Units.HORIZONTAL_DIR_RAD
198197
if (props) this.readFromJSON(props);
199198

200-
this.createTextMarker().catch(); // eslint-disable-line @typescript-eslint/no-floating-promises
199+
this.populateFormattingSpecsRegistry().then(() => this.createTextMarker().catch())
200+
.catch();
201201
}
202202

203203
public setStartPoint(point: XYAndZ) {
@@ -231,6 +231,21 @@ export class DistanceMeasurement extends Measurement {
231231
this._endPoint.setFrom(end);
232232
}
233233

234+
public override async populateFormattingSpecsRegistry(): Promise<void> {
235+
const lengthEntry = IModelApp.quantityFormatter.getSpecsByName(this._lengthKoQ);
236+
if (!lengthEntry || lengthEntry.formatterSpec.persistenceUnit?.name !== this._lengthPersistenceUnitName) {
237+
const lengthFormatProps = await IModelApp.formatsProvider.getFormat(this._lengthKoQ);
238+
if (lengthFormatProps) {
239+
await IModelApp.quantityFormatter.addFormattingSpecsToRegistry(this._lengthKoQ, this._lengthPersistenceUnitName, lengthFormatProps);
240+
}
241+
}
242+
const bearingEntry = IModelApp.quantityFormatter.getSpecsByName(this._bearingKoQ);
243+
if (!bearingEntry || bearingEntry.formatterSpec.persistenceUnit?.name !== this._bearingPersistenceUnitName) {
244+
const bearingFormatProps = FormatterUtils.getDefaultBearingFormatProps();
245+
await IModelApp.quantityFormatter.addFormattingSpecsToRegistry(this._bearingKoQ, this._bearingPersistenceUnitName, bearingFormatProps);
246+
}
247+
}
248+
234249
public override testDecorationHit(
235250
pickContext: MeasurementPickContext
236251
): boolean {
@@ -464,6 +479,7 @@ export class DistanceMeasurement extends Measurement {
464479
this._runRiseAxes.forEach((axis: DistanceMeasurement) =>
465480
axis.onDisplayUnitsChanged()
466481
);
482+
467483
}
468484

469485
private updateMarkerStyle() {
@@ -478,16 +494,9 @@ export class DistanceMeasurement extends Measurement {
478494
}
479495

480496
private async createTextMarker(): Promise<void> {
481-
const formatProps = await IModelApp.formatsProvider.getFormat(this._lengthKoQ);
497+
const lengthSpec = IModelApp.quantityFormatter.getSpecsByName(this._lengthKoQ)?.formatterSpec;
482498

483499
const distance = this._startPoint.distance(this._endPoint);
484-
let lengthSpec: FormatterSpec | undefined;
485-
if (formatProps) {
486-
lengthSpec = await IModelApp.quantityFormatter.createFormatterSpec({
487-
formatProps,
488-
persistenceUnitName: this._lengthPersistenceUnitName
489-
});
490-
}
491500
const fDistance = IModelApp.quantityFormatter.formatQuantity(
492501
distance,
493502
lengthSpec
@@ -523,7 +532,6 @@ export class DistanceMeasurement extends Measurement {
523532
}
524533

525534
protected override async getDataForMeasurementWidgetInternal(): Promise<MeasurementWidgetData> {
526-
const formatProps = await IModelApp.formatsProvider.getFormat(this._lengthKoQ);
527535

528536
const distance = this.worldScale * this._startPoint.distance(this._endPoint);
529537
const run = this.drawingMetadata?.worldScale !== undefined ? this.worldScale * Math.abs(this._endPoint.x - this._startPoint.x): this._startPoint.distanceXY(this._endPoint);
@@ -535,13 +543,7 @@ export class DistanceMeasurement extends Measurement {
535543
const bearing = FormatterUtils.calculateBearing(this._endPoint.x - this._startPoint.x, this._endPoint.y - this._startPoint.y);
536544
const adjustedStart = this.adjustPointForGlobalOrigin(this._startPoint);
537545
const adjustedEnd = this.adjustPointForGlobalOrigin(this._endPoint);
538-
let lengthSpec: FormatterSpec | undefined;
539-
if (formatProps) {
540-
lengthSpec = await IModelApp.quantityFormatter.createFormatterSpec({
541-
formatProps,
542-
persistenceUnitName: this._lengthPersistenceUnitName
543-
});
544-
}
546+
const lengthSpec = IModelApp.quantityFormatter.getSpecsByName(this._lengthKoQ)?.formatterSpec;
545547

546548
const fDistance = IModelApp.quantityFormatter.formatQuantity(distance, lengthSpec);
547549
const fStartCoords = FormatterUtils.formatCoordinatesImmediate(
@@ -603,18 +605,15 @@ export class DistanceMeasurement extends Measurement {
603605
},
604606
);
605607
if (this._bearingKoQ && this._bearingPersistenceUnitName) {
606-
const bearingSpecs = await IModelApp.quantityFormatter.createFormatterSpec({
607-
persistenceUnitName: this._bearingPersistenceUnitName,
608-
formatProps: FormatterUtils.getDefaultBearingFormatProps() // TODO: Replace with retrieving formatProps from formatsProvider and KoQ after demo.
609-
});
608+
const bearingSpecs = IModelApp.quantityFormatter.getSpecsByName(this._bearingKoQ)?.formatterSpec;
610609
const fBearing: string = IModelApp.quantityFormatter.formatQuantity(bearing, bearingSpecs);
611610
data.properties.push({
612611
label: MeasureTools.localization.getLocalizedString(
613612
"MeasureTools:tools.MeasureDistance.bearing"
614613
),
615614
name: "DistanceMeasurement_Bearing",
616615
value: fBearing,
617-
});
616+
});
618617
}
619618
if (this.drawingMetadata?.worldScale === undefined) {
620619
data.properties.push(

packages/itwin/measure-tools/src/measurements/LocationMeasurement.ts

Lines changed: 31 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ import type { MeasurementFormattingProps, MeasurementProps } from "../api/Measur
4040
import { MeasurementSelectionSet } from "../api/MeasurementSelectionSet.js";
4141
import { TextMarker } from "../api/TextMarker.js";
4242
import { MeasureTools } from "../MeasureTools.js";
43-
import type { FormatterSpec } from "@itwin/core-quantity";
4443

4544
/**
4645
* Props for serializing a [[LocationMeasurement]].
@@ -213,9 +212,10 @@ export class LocationMeasurement extends Measurement {
213212

214213
if (props) {
215214
this.readFromJSON(props);
216-
} else {
217-
this.createTextMarker().catch(); // eslint-disable-line @typescript-eslint/no-floating-promises
218215
}
216+
217+
this.populateFormattingSpecsRegistry().then(() => this.createTextMarker().catch())
218+
.catch();
219219
}
220220

221221
/** Changes the location. Only possible if the measurement is dynamic. */
@@ -269,6 +269,30 @@ export class LocationMeasurement extends Measurement {
269269
if (this._textMarker) this._textMarker.transientHiliteId = this.transientId;
270270
}
271271

272+
public override async populateFormattingSpecsRegistry(): Promise<void> {
273+
const lengthEntry = IModelApp.quantityFormatter.getSpecsByName(this._lengthKoQ);
274+
if (!lengthEntry || lengthEntry.formatterSpec.persistenceUnit?.name !== this._lengthPersistenceUnitName) {
275+
const lengthFormatProps = await IModelApp.formatsProvider.getFormat(this._lengthKoQ);
276+
if (lengthFormatProps) {
277+
await IModelApp.quantityFormatter.addFormattingSpecsToRegistry(this._lengthKoQ, this._lengthPersistenceUnitName, lengthFormatProps);
278+
}
279+
}
280+
const stationEntry = IModelApp.quantityFormatter.getSpecsByName(this._stationKoQ);
281+
if (!stationEntry || stationEntry.formatterSpec.persistenceUnit?.name !== this._stationPersistenceUnitName) {
282+
const stationFormatProps = await IModelApp.formatsProvider.getFormat(this._stationKoQ);
283+
if (stationFormatProps) {
284+
await IModelApp.quantityFormatter.addFormattingSpecsToRegistry(this._stationKoQ, this._stationPersistenceUnitName, stationFormatProps);
285+
}
286+
}
287+
const angleEntry = IModelApp.quantityFormatter.getSpecsByName(this._angleKoQ);
288+
if (!angleEntry || angleEntry.formatterSpec.persistenceUnit?.name !== this._anglePersistenceUnitName) {
289+
const angleFormatProps = await IModelApp.formatsProvider.getFormat(this._angleKoQ);
290+
if (angleFormatProps) {
291+
await IModelApp.quantityFormatter.addFormattingSpecsToRegistry(this._angleKoQ, this._anglePersistenceUnitName, angleFormatProps);
292+
}
293+
}
294+
}
295+
272296
public override decorate(context: DecorateContext): void {
273297
super.decorate(context);
274298

@@ -294,14 +318,7 @@ export class LocationMeasurement extends Measurement {
294318

295319
private async createTextMarker(): Promise<void> {
296320
const adjustedLocation = this.adjustPointWithSheetToWorldTransform(this.adjustPointForGlobalOrigin(this._location));
297-
let lengthSpec: FormatterSpec | undefined;
298-
const formatProps = await IModelApp.formatsProvider.getFormat(this._lengthKoQ);
299-
if (formatProps) {
300-
lengthSpec = await IModelApp.quantityFormatter.createFormatterSpec({
301-
formatProps,
302-
persistenceUnitName: this._lengthPersistenceUnitName
303-
});
304-
}
321+
const lengthSpec = IModelApp.quantityFormatter.getSpecsByName(this._lengthKoQ)?.formatterSpec;
305322

306323
const entries = [
307324
{
@@ -357,30 +374,9 @@ export class LocationMeasurement extends Measurement {
357374
protected override async getDataForMeasurementWidgetInternal(): Promise<
358375
MeasurementWidgetData | undefined
359376
> {
360-
let lengthSpec: FormatterSpec | undefined;
361-
let angleSpec: FormatterSpec | undefined;
362-
let stationSpec: FormatterSpec | undefined;
363-
const lengthFmtProps = await IModelApp.formatsProvider.getFormat(this._lengthKoQ);
364-
const angleFmtProps = await IModelApp.formatsProvider.getFormat(this._angleKoQ);
365-
const stationFmtProps = await IModelApp.formatsProvider.getFormat(this._stationKoQ);
366-
if (lengthFmtProps) {
367-
lengthSpec = await IModelApp.quantityFormatter.createFormatterSpec({
368-
formatProps: lengthFmtProps,
369-
persistenceUnitName: this._lengthPersistenceUnitName
370-
});
371-
}
372-
if (angleFmtProps) {
373-
angleSpec = await IModelApp.quantityFormatter.createFormatterSpec({
374-
formatProps: angleFmtProps,
375-
persistenceUnitName: this._anglePersistenceUnitName
376-
});
377-
}
378-
if (stationFmtProps) {
379-
stationSpec = await IModelApp.quantityFormatter.createFormatterSpec({
380-
formatProps: stationFmtProps,
381-
persistenceUnitName: this._stationPersistenceUnitName
382-
});
383-
}
377+
const lengthSpec = IModelApp.quantityFormatter.getSpecsByName(this._lengthKoQ)?.formatterSpec;
378+
const angleSpec = IModelApp.quantityFormatter.getSpecsByName(this._angleKoQ)?.formatterSpec;
379+
const stationSpec = IModelApp.quantityFormatter.getSpecsByName(this._stationKoQ)?.formatterSpec;
384380

385381
const adjustedLocation = this.adjustPointWithSheetToWorldTransform(this.adjustPointForGlobalOrigin(this._location));
386382
const fCoordinates = FormatterUtils.formatCoordinatesImmediate(adjustedLocation, lengthSpec);

0 commit comments

Comments
 (0)