@itwin/map-layers-formats 4.2.0-dev.3 → 4.2.0-dev.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +59 -1
  2. package/lib/cjs/ArcGisFeature/ArcGisFeatureProvider.d.ts +2 -2
  3. package/lib/cjs/ArcGisFeature/ArcGisFeatureProvider.d.ts.map +1 -1
  4. package/lib/cjs/ArcGisFeature/ArcGisFeatureProvider.js +5 -5
  5. package/lib/cjs/ArcGisFeature/ArcGisFeatureProvider.js.map +1 -1
  6. package/lib/cjs/ArcGisFeature/ArcGisSymbologyRenderer.d.ts +36 -1
  7. package/lib/cjs/ArcGisFeature/ArcGisSymbologyRenderer.d.ts.map +1 -1
  8. package/lib/cjs/ArcGisFeature/ArcGisSymbologyRenderer.js +202 -21
  9. package/lib/cjs/ArcGisFeature/ArcGisSymbologyRenderer.js.map +1 -1
  10. package/lib/cjs/ArcGisFeature/EsriSymbology.d.ts +38 -10
  11. package/lib/cjs/ArcGisFeature/EsriSymbology.d.ts.map +1 -1
  12. package/lib/cjs/ArcGisFeature/EsriSymbology.js +28 -3
  13. package/lib/cjs/ArcGisFeature/EsriSymbology.js.map +1 -1
  14. package/lib/cjs/Tools/MapFeatureInfoDecorator.d.ts +2 -0
  15. package/lib/cjs/Tools/MapFeatureInfoDecorator.d.ts.map +1 -1
  16. package/lib/cjs/Tools/MapFeatureInfoDecorator.js +12 -2
  17. package/lib/cjs/Tools/MapFeatureInfoDecorator.js.map +1 -1
  18. package/lib/cjs/Tools/MapFeatureInfoTool.d.ts +4 -0
  19. package/lib/cjs/Tools/MapFeatureInfoTool.d.ts.map +1 -1
  20. package/lib/cjs/Tools/MapFeatureInfoTool.js +117 -6
  21. package/lib/cjs/Tools/MapFeatureInfoTool.js.map +1 -1
  22. package/lib/esm/ArcGisFeature/ArcGisFeatureProvider.d.ts +2 -2
  23. package/lib/esm/ArcGisFeature/ArcGisFeatureProvider.d.ts.map +1 -1
  24. package/lib/esm/ArcGisFeature/ArcGisFeatureProvider.js +5 -5
  25. package/lib/esm/ArcGisFeature/ArcGisFeatureProvider.js.map +1 -1
  26. package/lib/esm/ArcGisFeature/ArcGisSymbologyRenderer.d.ts +36 -1
  27. package/lib/esm/ArcGisFeature/ArcGisSymbologyRenderer.d.ts.map +1 -1
  28. package/lib/esm/ArcGisFeature/ArcGisSymbologyRenderer.js +201 -20
  29. package/lib/esm/ArcGisFeature/ArcGisSymbologyRenderer.js.map +1 -1
  30. package/lib/esm/ArcGisFeature/EsriSymbology.d.ts +38 -10
  31. package/lib/esm/ArcGisFeature/EsriSymbology.d.ts.map +1 -1
  32. package/lib/esm/ArcGisFeature/EsriSymbology.js +26 -2
  33. package/lib/esm/ArcGisFeature/EsriSymbology.js.map +1 -1
  34. package/lib/esm/Tools/MapFeatureInfoDecorator.d.ts +2 -0
  35. package/lib/esm/Tools/MapFeatureInfoDecorator.d.ts.map +1 -1
  36. package/lib/esm/Tools/MapFeatureInfoDecorator.js +13 -3
  37. package/lib/esm/Tools/MapFeatureInfoDecorator.js.map +1 -1
  38. package/lib/esm/Tools/MapFeatureInfoTool.d.ts +4 -0
  39. package/lib/esm/Tools/MapFeatureInfoTool.d.ts.map +1 -1
  40. package/lib/esm/Tools/MapFeatureInfoTool.js +118 -7
  41. package/lib/esm/Tools/MapFeatureInfoTool.js.map +1 -1
  42. package/package.json +12 -11
@@ -5,10 +5,69 @@
5
5
  /** @packageDocumentation
6
6
  * @module MapLayersFormats
7
7
  */
8
- import { EventHandled, IModelApp, LocateFilterStatus, LocateResponse, PrimitiveTool, } from "@itwin/core-frontend";
8
+ import { EventHandled, IModelApp, LocateFilterStatus, LocateResponse, MapTileTreeScaleRangeVisibility, PrimitiveTool, } from "@itwin/core-frontend";
9
9
  import { BeEvent } from "@itwin/core-bentley";
10
10
  import { ImageMapLayerSettings } from "@itwin/core-common";
11
11
  import { MapFeatureInfoDecorator } from "./MapFeatureInfoDecorator";
12
+ class ActiveMapLayerState {
13
+ constructor() {
14
+ this.isVisible = true;
15
+ this.isInRange = true;
16
+ this.existsInDisplayStyle = true;
17
+ }
18
+ get activeMapLayers() { return this._activeMapLayers; }
19
+ set activeMapLayers(active) {
20
+ this._activeMapLayers = active;
21
+ this.isVisible = true;
22
+ this.isInRange = true;
23
+ this.existsInDisplayStyle = true;
24
+ }
25
+ get hasMapLayers() { return (this.activeMapLayers && this.activeMapLayers.length > 0); }
26
+ updateWithImagerySettings(imagery) {
27
+ const result = { exists: false, hidden: false };
28
+ this.existsInDisplayStyle = false;
29
+ this.isVisible = false;
30
+ if (this.hasMapLayers) {
31
+ const oldMls = this._activeMapLayers[0]; // consider only first layer for now
32
+ let newMls;
33
+ if (oldMls.isBaseLayer) {
34
+ if (typeof (imagery.backgroundBase) !== "number") {
35
+ newMls = imagery.backgroundBase;
36
+ }
37
+ }
38
+ else if (oldMls.index?.isOverlay && imagery.overlayLayers && imagery.overlayLayers.length > oldMls.index.index) {
39
+ newMls = imagery.overlayLayers[oldMls.index.index];
40
+ }
41
+ else if ((oldMls.index !== undefined) && imagery.backgroundLayers && imagery.backgroundLayers.length > oldMls.index.index) {
42
+ newMls = imagery.backgroundLayers[oldMls.index.index];
43
+ }
44
+ // We want to make sure that newMls and OldMls are the same (but ignoring the 'visible' flag).
45
+ // by using the serialized JSON object
46
+ let tmpNewMls = newMls;
47
+ if (newMls && newMls.visible !== oldMls.settings.visible) {
48
+ tmpNewMls = { ...newMls, visible: oldMls.settings.visible };
49
+ }
50
+ const newJson = tmpNewMls ? JSON.stringify(tmpNewMls) : "";
51
+ const oldJson = JSON.stringify(oldMls.settings.toJSON());
52
+ if (newJson === oldJson) {
53
+ // We consider newMls and OldMls to be the same mapLayer instance.
54
+ this.existsInDisplayStyle = true;
55
+ this.isVisible = newMls.visible ? true : false;
56
+ }
57
+ }
58
+ return result;
59
+ }
60
+ updateWithScaleRangeVisibility(layerIndexes) {
61
+ if (this.hasMapLayers) {
62
+ const currentMls = this.activeMapLayers[0]; // consider only first layer for now
63
+ for (const scaleRangeVisibility of layerIndexes) {
64
+ if (currentMls.index?.index === scaleRangeVisibility.index) {
65
+ this.isInRange = scaleRangeVisibility.visibility === MapTileTreeScaleRangeVisibility.Visible || scaleRangeVisibility.visibility === MapTileTreeScaleRangeVisibility.Partial;
66
+ }
67
+ }
68
+ }
69
+ }
70
+ }
12
71
  /** Tools that allow extracting feature information from map-layers.
13
72
  * Simulate feature highlight by drawing overlay decorations. It also
14
73
  * fire an event that provide further feature information meant to be displayed in a UI / Widget.
@@ -19,33 +78,80 @@ class MapFeatureInfoTool extends PrimitiveTool {
19
78
  constructor() {
20
79
  super(...arguments);
21
80
  this.onInfoReady = new BeEvent();
81
+ this.onInfoCleared = new BeEvent();
22
82
  this._decorator = new MapFeatureInfoDecorator();
23
83
  this._layerSettingsCache = new Map();
84
+ this._state = new ActiveMapLayerState();
24
85
  this._detachListeners = [];
25
86
  }
26
87
  requireWriteableTarget() {
27
88
  return false;
28
89
  }
90
+ updateDecorator(vp) {
91
+ if (this._state.existsInDisplayStyle) {
92
+ if (this._state.isInRange) {
93
+ this._decorator.hidden = !this._state.isVisible;
94
+ }
95
+ }
96
+ else {
97
+ // Flush existing decorations until a new selection is made
98
+ this.onInfoCleared.raiseEvent();
99
+ this._decorator.clearState();
100
+ }
101
+ vp.invalidateDecorations();
102
+ }
29
103
  async onPostInstall() {
30
104
  await super.onPostInstall();
31
105
  this.initLocateElements();
32
106
  IModelApp.locateManager.options.allowDecorations = true;
33
107
  this._layerSettingsCache.clear();
34
- // Listen of display style configuration changes, that we don't have to restart the tool to be up to date.
108
+ // Listen of display style configuration changes, that way we don't have to restart the tool to be up to date.
35
109
  const vp = this.targetView;
36
110
  if (vp) {
37
- this._detachListeners.push(vp.onChangeView.addListener((_vp, _previous) => {
111
+ const mapImageryChangeHandler = (newImagery) => {
112
+ if (this._state.hasMapLayers) {
113
+ this._state.updateWithImagerySettings(newImagery.toJSON());
114
+ this.updateDecorator(vp);
115
+ }
38
116
  this._layerSettingsCache.clear();
39
- }));
40
- this._detachListeners.push(vp.displayStyle.settings.onMapImageryChanged.addListener((_newImagery) => {
117
+ };
118
+ this._detachListeners.push(vp.onChangeView.addListener((viewport, _previousViewState) => {
119
+ // When a saved view is loaded, 'onMapImageryChanged' events are no longer handled, we have to re-attach.
120
+ if (this._detachOnMapImageryChanged) {
121
+ this._detachOnMapImageryChanged();
122
+ }
123
+ this._detachOnMapImageryChanged = viewport.displayStyle.settings.onMapImageryChanged.addListener(mapImageryChangeHandler);
124
+ if (this._state.hasMapLayers) {
125
+ this._state.updateWithImagerySettings({
126
+ backgroundBase: viewport.displayStyle.backgroundMapBase.toJSON(),
127
+ backgroundLayers: viewport.displayStyle.getMapLayers(false).map((value) => value.toJSON()),
128
+ overlayLayers: viewport.displayStyle.getMapLayers(true).map((value) => value.toJSON()),
129
+ });
130
+ this.updateDecorator(vp);
131
+ }
41
132
  this._layerSettingsCache.clear();
42
133
  }));
134
+ this._detachOnMapImageryChanged = vp.displayStyle.settings.onMapImageryChanged.addListener(mapImageryChangeHandler);
135
+ // Every time a layer goes out of range it, its associated decoration should be hidden (and restore if enter again the range)
136
+ this._detachListeners.push(vp.onMapLayerScaleRangeVisibilityChanged.addListener(((layerIndexes) => {
137
+ if (this._state.hasMapLayers) {
138
+ this._state.updateWithScaleRangeVisibility(layerIndexes);
139
+ if (this._state.existsInDisplayStyle && this._state.isVisible) {
140
+ this._decorator.hidden = !this._state.isInRange;
141
+ vp.invalidateDecorations();
142
+ }
143
+ }
144
+ this._layerSettingsCache.clear();
145
+ })));
43
146
  }
44
147
  IModelApp.viewManager.addDecorator(this._decorator);
45
148
  }
46
149
  async onCleanup() {
47
150
  this._detachListeners.forEach((f) => f());
48
151
  this._detachListeners.length = 0;
152
+ if (this._detachOnMapImageryChanged) {
153
+ this._detachOnMapImageryChanged();
154
+ }
49
155
  IModelApp.viewManager.dropDecorator(this._decorator);
50
156
  }
51
157
  /** @internal */
@@ -76,10 +182,14 @@ class MapFeatureInfoTool extends PrimitiveTool {
76
182
  const hit = await IModelApp.locateManager.doLocate(new LocateResponse(), true, ev.point, ev.viewport, ev.inputSource);
77
183
  if (hit !== undefined) {
78
184
  let mapInfo;
79
- if (this.getMapLayerInfoFromHit(hit).length > 0) {
185
+ const mapLayersHit = this.getMapLayerInfoFromHit(hit);
186
+ if (mapLayersHit.length > 0) {
187
+ this._state.activeMapLayers = mapLayersHit;
80
188
  IModelApp.toolAdmin.setCursor("wait");
81
189
  try {
82
- mapInfo = await hit.viewport.getMapFeatureInfo(hit);
190
+ const aperture = (hit.viewport.pixelsFromInches(IModelApp.locateManager.apertureInches) / 2.0) + 1.5;
191
+ const pixelRadius = Math.floor(aperture + 0.5);
192
+ mapInfo = await hit.viewport.getMapFeatureInfo(hit, { tolerance: pixelRadius });
83
193
  if (mapInfo) {
84
194
  this._decorator.setState({ hit, mapInfo });
85
195
  }
@@ -94,6 +204,7 @@ class MapFeatureInfoTool extends PrimitiveTool {
94
204
  return EventHandled.No;
95
205
  }
96
206
  async onResetButtonUp(_ev) {
207
+ this._state.activeMapLayers = undefined;
97
208
  /* Common reset behavior for primitive tools is calling onReinitialize to restart or exitTool to terminate. */
98
209
  await this.onReinitialize();
99
210
  return EventHandled.No;
@@ -1 +1 @@
1
- {"version":3,"file":"MapFeatureInfoTool.js","sourceRoot":"","sources":["../../../src/Tools/MapFeatureInfoTool.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module MapLayersFormats\r\n */\r\n\r\nimport {\r\n BeButtonEvent,\r\n EventHandled,\r\n HitDetail,\r\n IModelApp,\r\n LocateFilterStatus,\r\n LocateResponse,\r\n MapFeatureInfo,\r\n MapLayerInfoFromTileTree,\r\n PrimitiveTool,\r\n} from \"@itwin/core-frontend\";\r\nimport { BeEvent } from \"@itwin/core-bentley\";\r\nimport { ImageMapLayerSettings } from \"@itwin/core-common\";\r\nimport { MapFeatureInfoDecorator } from \"./MapFeatureInfoDecorator\";\r\n\r\n/** Data provided every time [[MapFeatureInfoTool]] retrieve feature information.\r\n * @see [[MapFeatureInfoToolData]]\r\n * @beta\r\n */\r\nexport interface MapFeatureInfoToolData {\r\n hit: HitDetail;\r\n mapInfo?: MapFeatureInfo;\r\n}\r\n\r\n/** Tools that allow extracting feature information from map-layers.\r\n * Simulate feature highlight by drawing overlay decorations. It also\r\n * fire an event that provide further feature information meant to be displayed in a UI / Widget.\r\n * @see [[MapFeatureInfoToolData]]\r\n * @beta\r\n */\r\nexport class MapFeatureInfoTool extends PrimitiveTool {\r\n public readonly onInfoReady = new BeEvent<(data: MapFeatureInfoToolData) => void>();\r\n\r\n public static override toolId = \"MapFeatureInfoTool\";\r\n public static override iconSpec = \"icon-map\";\r\n\r\n private _decorator: MapFeatureInfoDecorator = new MapFeatureInfoDecorator();\r\n private _layerSettingsCache = new Map<string, MapLayerInfoFromTileTree[]>();\r\n private readonly _detachListeners: VoidFunction[] = [];\r\n\r\n public override requireWriteableTarget(): boolean {\r\n return false;\r\n }\r\n\r\n public override async onPostInstall() {\r\n await super.onPostInstall();\r\n this.initLocateElements();\r\n IModelApp.locateManager.options.allowDecorations = true;\r\n\r\n this._layerSettingsCache.clear();\r\n\r\n // Listen of display style configuration changes, that we don't have to restart the tool to be up to date.\r\n const vp = this.targetView;\r\n if (vp) {\r\n\r\n this._detachListeners.push(vp.onChangeView.addListener((_vp, _previous) => {\r\n this._layerSettingsCache.clear();\r\n }));\r\n\r\n this._detachListeners.push(vp.displayStyle.settings.onMapImageryChanged.addListener((_newImagery: any) => {\r\n this._layerSettingsCache.clear();\r\n }));\r\n }\r\n\r\n IModelApp.viewManager.addDecorator(this._decorator);\r\n }\r\n\r\n public override async onCleanup() {\r\n this._detachListeners.forEach((f) => f());\r\n this._detachListeners.length = 0;\r\n\r\n IModelApp.viewManager.dropDecorator(this._decorator);\r\n }\r\n\r\n /** @internal */\r\n private getMapLayerInfoFromHit(hit: HitDetail) {\r\n let mapLayerFromHit: MapLayerInfoFromTileTree[] = [];\r\n const fromCache = this._layerSettingsCache.get(hit.sourceId);\r\n if (fromCache) {\r\n mapLayerFromHit = fromCache;\r\n } else if (this.targetView) {\r\n mapLayerFromHit = this.targetView?.mapLayerFromHit(hit).filter(((info) => info.settings instanceof ImageMapLayerSettings && info.provider?.supportsMapFeatureInfo));\r\n this._layerSettingsCache.set(hit.sourceId, mapLayerFromHit);\r\n }\r\n\r\n return mapLayerFromHit;\r\n }\r\n\r\n public override async getToolTip(hit: HitDetail): Promise<HTMLElement | string> {\r\n const infos = this.getMapLayerInfoFromHit(hit);\r\n if (infos.length > 0) {\r\n const names = infos.map((info) => info.settings.name);\r\n return `Layer${names.length > 1 ? \"s\" : \"\"}: ${names.join(\", \")}`;\r\n }\r\n return \"\";\r\n }\r\n\r\n public override async filterHit(hit: HitDetail, _out?: LocateResponse): Promise<LocateFilterStatus> {\r\n return this.getMapLayerInfoFromHit(hit).length > 0 ? LocateFilterStatus.Accept : LocateFilterStatus.Reject;\r\n }\r\n\r\n public override async onDataButtonDown(\r\n ev: BeButtonEvent,\r\n ): Promise<EventHandled> {\r\n const hit = await IModelApp.locateManager.doLocate(\r\n new LocateResponse(),\r\n true,\r\n ev.point,\r\n ev.viewport,\r\n ev.inputSource,\r\n );\r\n if (hit !== undefined) {\r\n let mapInfo: MapFeatureInfo | undefined;\r\n if (this.getMapLayerInfoFromHit(hit).length > 0) {\r\n IModelApp.toolAdmin.setCursor(\"wait\");\r\n try {\r\n mapInfo = await hit.viewport.getMapFeatureInfo(hit);\r\n if (mapInfo) {\r\n this._decorator.setState({ hit, mapInfo });\r\n }\r\n } finally {\r\n IModelApp.toolAdmin.setCursor(undefined);\r\n }\r\n }\r\n\r\n this.onInfoReady.raiseEvent({ hit, mapInfo });\r\n return EventHandled.Yes;\r\n }\r\n return EventHandled.No;\r\n }\r\n\r\n public override async onResetButtonUp(\r\n _ev: BeButtonEvent,\r\n ): Promise<EventHandled> {\r\n /* Common reset behavior for primitive tools is calling onReinitialize to restart or exitTool to terminate. */\r\n await this.onReinitialize();\r\n return EventHandled.No;\r\n }\r\n\r\n public override async onRestartTool() {\r\n const tool = new MapFeatureInfoTool();\r\n if (!(await tool.run()))\r\n return this.exitTool();\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"MapFeatureInfoTool.js","sourceRoot":"","sources":["../../../src/Tools/MapFeatureInfoTool.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module MapLayersFormats\r\n */\r\n\r\nimport {\r\n BeButtonEvent,\r\n EventHandled,\r\n HitDetail,\r\n IModelApp,\r\n LocateFilterStatus,\r\n LocateResponse,\r\n MapFeatureInfo,\r\n MapLayerInfoFromTileTree,\r\n MapLayerScaleRangeVisibility,\r\n MapTileTreeScaleRangeVisibility,\r\n PrimitiveTool,\r\n Viewport,\r\n} from \"@itwin/core-frontend\";\r\nimport { BeEvent } from \"@itwin/core-bentley\";\r\nimport { ImageMapLayerSettings, MapImageryProps, MapImagerySettings, MapLayerProps } from \"@itwin/core-common\";\r\nimport { MapFeatureInfoDecorator } from \"./MapFeatureInfoDecorator\";\r\n\r\n/** Data provided every time [[MapFeatureInfoTool]] retrieve feature information.\r\n * @see [[MapFeatureInfoToolData]]\r\n * @beta\r\n */\r\nexport interface MapFeatureInfoToolData {\r\n hit: HitDetail;\r\n mapInfo?: MapFeatureInfo;\r\n}\r\n\r\nclass ActiveMapLayerState {\r\n private _activeMapLayers: MapLayerInfoFromTileTree[]|undefined;\r\n public get activeMapLayers() {return this._activeMapLayers;}\r\n public set activeMapLayers(active: MapLayerInfoFromTileTree[]|undefined) {\r\n this._activeMapLayers = active;\r\n this.isVisible = true;\r\n this.isInRange = true;\r\n this.existsInDisplayStyle = true;\r\n\r\n }\r\n public isVisible: boolean = true;\r\n public isInRange: boolean = true;\r\n public existsInDisplayStyle: boolean = true;\r\n\r\n public get hasMapLayers() { return (this.activeMapLayers && this.activeMapLayers.length > 0);}\r\n\r\n public updateWithImagerySettings(imagery: MapImageryProps) {\r\n const result = {exists: false, hidden: false};\r\n this.existsInDisplayStyle = false;\r\n this.isVisible = false;\r\n if (this.hasMapLayers) {\r\n const oldMls = this._activeMapLayers![0]; // consider only first layer for now\r\n\r\n let newMls: MapLayerProps|undefined;\r\n if (oldMls.isBaseLayer) {\r\n if (typeof (imagery.backgroundBase) !== \"number\") {\r\n newMls = imagery.backgroundBase;\r\n }\r\n } else if (oldMls.index?.isOverlay && imagery.overlayLayers && imagery.overlayLayers.length > oldMls.index.index) {\r\n newMls = imagery.overlayLayers[oldMls.index.index];\r\n\r\n } else if ((oldMls.index !== undefined) && imagery.backgroundLayers && imagery.backgroundLayers.length > oldMls.index.index) {\r\n newMls = imagery.backgroundLayers[oldMls.index.index];\r\n }\r\n\r\n // We want to make sure that newMls and OldMls are the same (but ignoring the 'visible' flag).\r\n // by using the serialized JSON object\r\n let tmpNewMls = newMls;\r\n if (newMls && newMls.visible !== oldMls.settings.visible) {\r\n tmpNewMls = {...newMls, visible: oldMls.settings.visible};\r\n }\r\n const newJson = tmpNewMls ? JSON.stringify(tmpNewMls) : \"\";\r\n const oldJson = JSON.stringify(oldMls.settings.toJSON());\r\n\r\n if (newJson === oldJson ) {\r\n // We consider newMls and OldMls to be the same mapLayer instance.\r\n this.existsInDisplayStyle = true;\r\n this.isVisible = newMls!.visible ? true : false;\r\n }\r\n\r\n }\r\n return result;\r\n }\r\n\r\n public updateWithScaleRangeVisibility(layerIndexes: MapLayerScaleRangeVisibility[]) {\r\n if (this.hasMapLayers) {\r\n const currentMls = this.activeMapLayers![0]; // consider only first layer for now\r\n for (const scaleRangeVisibility of layerIndexes) {\r\n if (currentMls.index?.index === scaleRangeVisibility.index) {\r\n this.isInRange = scaleRangeVisibility.visibility === MapTileTreeScaleRangeVisibility.Visible || scaleRangeVisibility.visibility === MapTileTreeScaleRangeVisibility.Partial;\r\n }\r\n }\r\n }\r\n\r\n }\r\n}\r\n/** Tools that allow extracting feature information from map-layers.\r\n * Simulate feature highlight by drawing overlay decorations. It also\r\n * fire an event that provide further feature information meant to be displayed in a UI / Widget.\r\n * @see [[MapFeatureInfoToolData]]\r\n * @beta\r\n */\r\nexport class MapFeatureInfoTool extends PrimitiveTool {\r\n public readonly onInfoReady = new BeEvent<(data: MapFeatureInfoToolData) => void>();\r\n public readonly onInfoCleared = new BeEvent();\r\n\r\n public static override toolId = \"MapFeatureInfoTool\";\r\n public static override iconSpec = \"icon-map\";\r\n\r\n private _decorator: MapFeatureInfoDecorator = new MapFeatureInfoDecorator();\r\n private _layerSettingsCache = new Map<string, MapLayerInfoFromTileTree[]>();\r\n\r\n private _state: ActiveMapLayerState = new ActiveMapLayerState();\r\n private readonly _detachListeners: VoidFunction[] = [];\r\n private _detachOnMapImageryChanged: VoidFunction|undefined;\r\n\r\n public override requireWriteableTarget(): boolean {\r\n return false;\r\n }\r\n\r\n private updateDecorator(vp: Viewport) {\r\n if (this._state.existsInDisplayStyle) {\r\n if (this._state.isInRange) {\r\n this._decorator.hidden = !this._state.isVisible;\r\n }\r\n } else {\r\n // Flush existing decorations until a new selection is made\r\n this.onInfoCleared.raiseEvent();\r\n this._decorator.clearState();\r\n }\r\n vp.invalidateDecorations();\r\n }\r\n\r\n public override async onPostInstall() {\r\n await super.onPostInstall();\r\n this.initLocateElements();\r\n IModelApp.locateManager.options.allowDecorations = true;\r\n\r\n this._layerSettingsCache.clear();\r\n\r\n // Listen of display style configuration changes, that way we don't have to restart the tool to be up to date.\r\n const vp = this.targetView;\r\n if (vp) {\r\n const mapImageryChangeHandler = (newImagery: Readonly<MapImagerySettings>) => {\r\n if (this._state.hasMapLayers) {\r\n this._state.updateWithImagerySettings(newImagery.toJSON());\r\n this.updateDecorator(vp);\r\n }\r\n this._layerSettingsCache.clear();\r\n };\r\n\r\n this._detachListeners.push(vp.onChangeView.addListener((viewport, _previousViewState) => {\r\n\r\n // When a saved view is loaded, 'onMapImageryChanged' events are no longer handled, we have to re-attach.\r\n if (this._detachOnMapImageryChanged) {\r\n this._detachOnMapImageryChanged();\r\n }\r\n this._detachOnMapImageryChanged = viewport.displayStyle.settings.onMapImageryChanged.addListener(mapImageryChangeHandler);\r\n\r\n if (this._state.hasMapLayers) {\r\n this._state.updateWithImagerySettings({\r\n backgroundBase: viewport.displayStyle.backgroundMapBase.toJSON(),\r\n backgroundLayers: viewport.displayStyle.getMapLayers(false).map((value) => value.toJSON()),\r\n overlayLayers: viewport.displayStyle.getMapLayers(true).map((value) => value.toJSON()),\r\n });\r\n this.updateDecorator(vp);\r\n }\r\n this._layerSettingsCache.clear();\r\n }));\r\n\r\n this._detachOnMapImageryChanged = vp.displayStyle.settings.onMapImageryChanged.addListener(mapImageryChangeHandler);\r\n\r\n // Every time a layer goes out of range it, its associated decoration should be hidden (and restore if enter again the range)\r\n this._detachListeners.push(vp.onMapLayerScaleRangeVisibilityChanged.addListener(((layerIndexes: MapLayerScaleRangeVisibility[]) => {\r\n if (this._state.hasMapLayers) {\r\n this._state.updateWithScaleRangeVisibility(layerIndexes);\r\n if (this._state.existsInDisplayStyle && this._state.isVisible) {\r\n this._decorator.hidden = !this._state.isInRange;\r\n vp.invalidateDecorations();\r\n }\r\n }\r\n this._layerSettingsCache.clear();\r\n })));\r\n\r\n }\r\n\r\n IModelApp.viewManager.addDecorator(this._decorator);\r\n }\r\n\r\n public override async onCleanup() {\r\n this._detachListeners.forEach((f) => f());\r\n this._detachListeners.length = 0;\r\n if (this._detachOnMapImageryChanged) {\r\n this._detachOnMapImageryChanged();\r\n }\r\n\r\n IModelApp.viewManager.dropDecorator(this._decorator);\r\n }\r\n\r\n /** @internal */\r\n private getMapLayerInfoFromHit(hit: HitDetail) {\r\n let mapLayerFromHit: MapLayerInfoFromTileTree[] = [];\r\n const fromCache = this._layerSettingsCache.get(hit.sourceId);\r\n if (fromCache) {\r\n mapLayerFromHit = fromCache;\r\n } else if (this.targetView) {\r\n mapLayerFromHit = this.targetView?.mapLayerFromHit(hit).filter(((info) => info.settings instanceof ImageMapLayerSettings && info.provider?.supportsMapFeatureInfo));\r\n this._layerSettingsCache.set(hit.sourceId, mapLayerFromHit);\r\n }\r\n\r\n return mapLayerFromHit;\r\n }\r\n\r\n public override async getToolTip(hit: HitDetail): Promise<HTMLElement | string> {\r\n const infos = this.getMapLayerInfoFromHit(hit);\r\n if (infos.length > 0) {\r\n const names = infos.map((info) => info.settings.name);\r\n return `Layer${names.length > 1 ? \"s\" : \"\"}: ${names.join(\", \")}`;\r\n }\r\n return \"\";\r\n }\r\n\r\n public override async filterHit(hit: HitDetail, _out?: LocateResponse): Promise<LocateFilterStatus> {\r\n return this.getMapLayerInfoFromHit(hit).length > 0 ? LocateFilterStatus.Accept : LocateFilterStatus.Reject;\r\n }\r\n\r\n public override async onDataButtonDown(\r\n ev: BeButtonEvent,\r\n ): Promise<EventHandled> {\r\n const hit = await IModelApp.locateManager.doLocate(\r\n new LocateResponse(),\r\n true,\r\n ev.point,\r\n ev.viewport,\r\n ev.inputSource,\r\n );\r\n if (hit !== undefined) {\r\n let mapInfo: MapFeatureInfo | undefined;\r\n\r\n const mapLayersHit = this.getMapLayerInfoFromHit(hit);\r\n if (mapLayersHit.length > 0) {\r\n this._state.activeMapLayers = mapLayersHit;\r\n IModelApp.toolAdmin.setCursor(\"wait\");\r\n try {\r\n const aperture = (hit.viewport.pixelsFromInches(IModelApp.locateManager.apertureInches) / 2.0) + 1.5;\r\n const pixelRadius = Math.floor(aperture + 0.5);\r\n mapInfo = await hit.viewport.getMapFeatureInfo(hit, {tolerance: pixelRadius});\r\n if (mapInfo) {\r\n this._decorator.setState({ hit, mapInfo });\r\n }\r\n } finally {\r\n IModelApp.toolAdmin.setCursor(undefined);\r\n }\r\n }\r\n\r\n this.onInfoReady.raiseEvent({ hit, mapInfo });\r\n return EventHandled.Yes;\r\n }\r\n return EventHandled.No;\r\n }\r\n\r\n public override async onResetButtonUp(\r\n _ev: BeButtonEvent,\r\n ): Promise<EventHandled> {\r\n this._state.activeMapLayers = undefined;\r\n /* Common reset behavior for primitive tools is calling onReinitialize to restart or exitTool to terminate. */\r\n await this.onReinitialize();\r\n return EventHandled.No;\r\n }\r\n\r\n public override async onRestartTool() {\r\n const tool = new MapFeatureInfoTool();\r\n if (!(await tool.run()))\r\n return this.exitTool();\r\n }\r\n}\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/map-layers-formats",
3
- "version": "4.2.0-dev.3",
3
+ "version": "4.2.0-dev.30",
4
4
  "description": "Enables additional map-layers formats in iTwin.js",
5
5
  "main": "lib/cjs/map-layers-formats.js",
6
6
  "module": "lib/esm/map-layers-formats.js",
@@ -42,19 +42,20 @@
42
42
  "sinon": "^15.0.4",
43
43
  "sinon-chai": "^3.2.0",
44
44
  "source-map-support": "^0.5.6",
45
+ "typemoq": "^2.1.0",
45
46
  "typescript": "~5.0.2",
46
- "@itwin/appui-abstract": "4.2.0-dev.3",
47
- "@itwin/build-tools": "4.2.0-dev.3",
48
- "@itwin/core-bentley": "4.2.0-dev.3",
49
- "@itwin/core-common": "4.2.0-dev.3",
50
- "@itwin/core-geometry": "4.2.0-dev.3",
51
- "@itwin/core-frontend": "4.2.0-dev.3"
47
+ "@itwin/core-common": "4.2.0-dev.30",
48
+ "@itwin/appui-abstract": "4.2.0-dev.30",
49
+ "@itwin/core-frontend": "4.2.0-dev.30",
50
+ "@itwin/core-geometry": "4.2.0-dev.30",
51
+ "@itwin/build-tools": "4.2.0-dev.30",
52
+ "@itwin/core-bentley": "4.2.0-dev.30"
52
53
  },
53
54
  "peerDependencies": {
54
- "@itwin/appui-abstract": "4.2.0-dev.3",
55
- "@itwin/core-bentley": "4.2.0-dev.3",
56
- "@itwin/core-geometry": "4.2.0-dev.3",
57
- "@itwin/core-common": "4.2.0-dev.3"
55
+ "@itwin/core-bentley": "4.2.0-dev.30",
56
+ "@itwin/appui-abstract": "4.2.0-dev.30",
57
+ "@itwin/core-geometry": "4.2.0-dev.30",
58
+ "@itwin/core-common": "4.2.0-dev.30"
58
59
  },
59
60
  "dependencies": {
60
61
  "google-protobuf": "~3.20.1"