@itwin/rpcinterface-full-stack-tests 4.1.0-dev.29 → 4.1.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.
@@ -1 +1 @@
1
- {"version":3,"file":"_a8a9.bundled-tests.js","mappings":";;;;;;;;AAAA","sources":["file:///ignored|D:\\vsts_a\\4\\s\\common\\temp\\node_modules\\.pnpm\\@loaders.gl+worker-utils@3.3.3\\node_modules\\@loaders.gl\\worker-utils\\dist\\esm\\lib\\library-utils|../node/require-utils.node"],"names":[],"sourceRoot":""}
1
+ {"version":3,"file":"_a8a9.bundled-tests.js","mappings":";;;;;;;;AAAA","sources":["file:///ignored|D:\\vsts_a\\7\\s\\common\\temp\\node_modules\\.pnpm\\@loaders.gl+worker-utils@3.3.3\\node_modules\\@loaders.gl\\worker-utils\\dist\\esm\\lib\\library-utils|../node/require-utils.node"],"names":[],"sourceRoot":""}
@@ -76324,8 +76324,12 @@ class BackgroundMapGeometry {
76324
76324
  static getCartesianTransitionDistance(iModel) {
76325
76325
  return BackgroundMapGeometry.getCartesianRange(iModel, scratchRange).diagonal().magnitudeXY() * BackgroundMapGeometry._transitionDistanceMultiplier;
76326
76326
  }
76327
- async dbToCartographicFromGcs(db, result) {
76328
- return this.cartesianRange.containsPoint(_itwin_core_geometry__WEBPACK_IMPORTED_MODULE_1__.Point3d.createFrom(db)) ? this._iModel.spatialToCartographic(db, result) : this.dbToCartographic(db, result);
76327
+ async dbToCartographicFromGcs(db) {
76328
+ const scratch = new _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_1__.Point3d();
76329
+ const promises = db.map(async (p) => {
76330
+ return this.cartesianRange.containsPoint(_itwin_core_geometry__WEBPACK_IMPORTED_MODULE_1__.Point3d.createFrom(p, scratch)) ? this._iModel.spatialToCartographic(p) : this.dbToCartographic(p);
76331
+ });
76332
+ return Promise.all(promises);
76329
76333
  }
76330
76334
  dbToCartographic(db, result) {
76331
76335
  if (undefined === result)
@@ -76339,17 +76343,24 @@ class BackgroundMapGeometry {
76339
76343
  return _itwin_core_common__WEBPACK_IMPORTED_MODULE_2__.Cartographic.fromEcef(ecef, result);
76340
76344
  }
76341
76345
  }
76342
- async cartographicToDbFromGcs(cartographic, result) {
76346
+ async cartographicToDbFromGcs(cartographic) {
76343
76347
  let db;
76344
76348
  if (this.globeMode === _itwin_core_common__WEBPACK_IMPORTED_MODULE_2__.GlobeMode.Plane) {
76345
76349
  const fraction = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_1__.Point2d.create(0, 0);
76346
- this._mercatorTilingScheme.cartographicToFraction(cartographic.latitude, cartographic.longitude, fraction);
76347
- db = this._mercatorFractionToDb.multiplyXYZ(fraction.x, fraction.y, cartographic.height, result);
76350
+ db = cartographic.map((p) => {
76351
+ this._mercatorTilingScheme.cartographicToFraction(p.latitude, p.longitude, fraction);
76352
+ return this._mercatorFractionToDb.multiplyXYZ(fraction.x, fraction.y, p.height);
76353
+ });
76348
76354
  }
76349
76355
  else {
76350
- db = this._ecefToDb.multiplyPoint3d(cartographic.toEcef());
76356
+ db = cartographic.map((p) => this._ecefToDb.multiplyPoint3d(p.toEcef()));
76351
76357
  }
76352
- return (!this._iModel.noGcsDefined && this.cartesianRange.containsPoint(db)) ? this._iModel.cartographicToSpatialFromGcs(cartographic) : db;
76358
+ if (this._iModel.noGcsDefined)
76359
+ return db;
76360
+ const promises = db.map(async (p, i) => {
76361
+ return this.cartesianRange.containsPoint(p) ? this._iModel.cartographicToSpatialFromGcs(cartographic[i]) : p;
76362
+ });
76363
+ return Promise.all(promises);
76353
76364
  }
76354
76365
  cartographicToDb(cartographic, result) {
76355
76366
  if (this.globeMode === _itwin_core_common__WEBPACK_IMPORTED_MODULE_2__.GlobeMode.Plane) {
@@ -81003,6 +81014,9 @@ function cloneXYAndZ(xyz) {
81003
81014
  * @internal exported strictly for tests.
81004
81015
  */
81005
81016
  class CoordinateConverter {
81017
+ get isIdle() {
81018
+ return "idle" === this._state;
81019
+ }
81006
81020
  toXYAndZ(input, output) {
81007
81021
  if (Array.isArray(input)) {
81008
81022
  output.x = input[0] ?? 0;
@@ -81022,8 +81036,12 @@ class CoordinateConverter {
81022
81036
  this._onCompleted = new _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.BeEvent();
81023
81037
  // Used for creating cache keys (XYAndZ) from XYZProps without having to allocate temporary objects.
81024
81038
  this._scratchXYZ = { x: 0, y: 0, z: 0 };
81039
+ // If true, [[dispatch]] will schedule another dispatch after it receives a response.
81040
+ // This is needed when all the points requested after the most recent dispatch were included in the currently-in-flight request -
81041
+ // _pending will be empty but new callers will be awaiting the results of the in-flight request.
81042
+ this._redispatchOnCompletion = false;
81025
81043
  this._maxPointsPerRequest = Math.max(1, opts.maxPointsPerRequest ?? 300);
81026
- this._iModel = opts.iModel;
81044
+ this._isIModelClosed = opts.isIModelClosed;
81027
81045
  this._requestPoints = opts.requestPoints;
81028
81046
  this._cache = new _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Dictionary(compareXYAndZ, cloneXYAndZ);
81029
81047
  this._pending = new _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.SortedArray(compareXYAndZ, false, cloneXYAndZ);
@@ -81031,7 +81049,7 @@ class CoordinateConverter {
81031
81049
  }
81032
81050
  async dispatch() {
81033
81051
  (0,_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.assert)(this._state === "scheduled");
81034
- if (this._iModel.isClosed || this._pending.isEmpty) {
81052
+ if (this._isIModelClosed() || this._pending.isEmpty) {
81035
81053
  this._state = "idle";
81036
81054
  this._onCompleted.raiseEvent();
81037
81055
  return;
@@ -81050,7 +81068,7 @@ class CoordinateConverter {
81050
81068
  for (let i = 0; i < inflight.length; i += this._maxPointsPerRequest) {
81051
81069
  const requests = inflight.slice(i, i + this._maxPointsPerRequest).extractArray();
81052
81070
  const promise = this._requestPoints(requests).then((results) => {
81053
- if (this._iModel.isClosed)
81071
+ if (this._isIModelClosed())
81054
81072
  return;
81055
81073
  if (results.length !== requests.length)
81056
81074
  _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.Logger.logError(`${_common_FrontendLoggerCategory__WEBPACK_IMPORTED_MODULE_2__.FrontendLoggerCategory.Package}.geoservices`, `requested conversion of ${requests.length} points, but received ${results.length} points`);
@@ -81068,8 +81086,10 @@ class CoordinateConverter {
81068
81086
  this._state = "idle";
81069
81087
  this._inflight.clear();
81070
81088
  // If any more pending conversions arrived while awaiting this request, schedule another request.
81071
- if (!this._pending.isEmpty)
81089
+ if (!this._pending.isEmpty || this._redispatchOnCompletion) {
81090
+ this._redispatchOnCompletion = false;
81072
81091
  this.scheduleDispatch(); // eslint-disable-line @typescript-eslint/no-floating-promises
81092
+ }
81073
81093
  // Resolve promises of all callers who were awaiting this request.
81074
81094
  onCompleted.raiseEvent();
81075
81095
  }
@@ -81081,7 +81101,9 @@ class CoordinateConverter {
81081
81101
  const xyz = this.toXYAndZ(point, this._scratchXYZ);
81082
81102
  if (this._cache.get(xyz))
81083
81103
  ++numInCache;
81084
- else if (!this._inflight.contains(xyz))
81104
+ else if (this._inflight.contains(xyz))
81105
+ this._redispatchOnCompletion = true;
81106
+ else
81085
81107
  this._pending.insert(xyz);
81086
81108
  }
81087
81109
  return numInCache;
@@ -81142,25 +81164,19 @@ class CoordinateConverter {
81142
81164
  */
81143
81165
  class GeoConverter {
81144
81166
  /** @internal */
81145
- constructor(iModel, datumOrGCRS) {
81146
- const datum = typeof datumOrGCRS === "object" ? JSON.stringify(datumOrGCRS) : datumOrGCRS;
81167
+ constructor(opts) {
81168
+ /** Used for removing this converter from GeoServices' cache after all requests are completed.
81169
+ * @internal
81170
+ */
81171
+ this.onAllRequestsCompleted = new _itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.BeEvent();
81172
+ const isIModelClosed = opts.isIModelClosed;
81147
81173
  this._geoToIModel = new CoordinateConverter({
81148
- iModel,
81149
- requestPoints: async (geoCoords) => {
81150
- const request = { source: datum, geoCoords };
81151
- const rpc = _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.IModelReadRpcInterface.getClientForRouting(iModel.routingContext.token);
81152
- const response = await rpc.getIModelCoordinatesFromGeoCoordinates(iModel.getRpcProps(), request);
81153
- return response.iModelCoords;
81154
- },
81174
+ isIModelClosed,
81175
+ requestPoints: async (geoCoords) => opts.toIModelCoords({ source: opts.datum, geoCoords }),
81155
81176
  });
81156
81177
  this._iModelToGeo = new CoordinateConverter({
81157
- iModel,
81158
- requestPoints: async (iModelCoords) => {
81159
- const request = { target: datum, iModelCoords };
81160
- const rpc = _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.IModelReadRpcInterface.getClientForRouting(iModel.routingContext.token);
81161
- const response = await rpc.getGeoCoordinatesFromIModelCoordinates(iModel.getRpcProps(), request);
81162
- return response.geoCoords;
81163
- },
81178
+ isIModelClosed,
81179
+ requestPoints: async (iModelCoords) => opts.fromIModelCoords({ target: opts.datum, iModelCoords }),
81164
81180
  });
81165
81181
  }
81166
81182
  /** Convert the specified geographic coordinates into iModel coordinates. */
@@ -81176,6 +81192,7 @@ class GeoConverter {
81176
81192
  /** @internal */
81177
81193
  async getIModelCoordinatesFromGeoCoordinates(geoPoints) {
81178
81194
  const result = await this._geoToIModel.convert(geoPoints);
81195
+ this.checkCompletion();
81179
81196
  return {
81180
81197
  iModelCoords: result.points,
81181
81198
  fromCache: result.fromCache,
@@ -81184,11 +81201,16 @@ class GeoConverter {
81184
81201
  /** @internal */
81185
81202
  async getGeoCoordinatesFromIModelCoordinates(iModelPoints) {
81186
81203
  const result = await this._iModelToGeo.convert(iModelPoints);
81204
+ this.checkCompletion();
81187
81205
  return {
81188
81206
  geoCoords: result.points,
81189
81207
  fromCache: result.fromCache,
81190
81208
  };
81191
81209
  }
81210
+ checkCompletion() {
81211
+ if (this._geoToIModel.isIdle && this._iModelToGeo.isIdle)
81212
+ this.onAllRequestsCompleted.raiseEvent();
81213
+ }
81192
81214
  /** @internal */
81193
81215
  getCachedIModelCoordinatesFromGeoCoordinates(geoPoints) {
81194
81216
  return this._geoToIModel.findCached(geoPoints);
@@ -81200,8 +81222,35 @@ class GeoConverter {
81200
81222
  */
81201
81223
  class GeoServices {
81202
81224
  /** @internal */
81203
- constructor(iModel) {
81204
- this._iModel = iModel;
81225
+ constructor(options) {
81226
+ /** Each GeoConverter has its own independent request queue and cache of previously-converted points.
81227
+ * Some callers like RealityTileTree obtain a single GeoConverter and reuse it throughout their own lifetime. Therefore they benefit from both batching and caching, and
81228
+ * the cache gets deleted once the RealityTileTree becomes disused.
81229
+ *
81230
+ * Other callers like IModelConnection.spatialToCartographic obtain a new GeoConverter every time they need one, use it to convert a single point(!), and then discard the converter.
81231
+ * This entirely prevents batching - e.g., calling spatialToCartographic 20 times in one frame results in 20 http requests.
81232
+ * To address that, we cache each GeoConverter returned by getConverter until it has converted at least one point and has no further outstanding conversion requests.
81233
+ * In this way, the converter lives for as long as (and no longer than) any caller is awaiting conversion to/from its datum - it and its cache are deleted once it becomes disused.
81234
+ * This makes the coordinate caching generally less useful, but at least bounded - and maximizes batching of requests.
81235
+ */
81236
+ this._cache = new Map();
81237
+ this._options = options;
81238
+ }
81239
+ /** @internal */
81240
+ static createForIModel(iModel) {
81241
+ return new GeoServices({
81242
+ isIModelClosed: () => iModel.isClosed,
81243
+ toIModelCoords: async (request) => {
81244
+ const rpc = _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.IModelReadRpcInterface.getClientForRouting(iModel.routingContext.token);
81245
+ const response = await rpc.getIModelCoordinatesFromGeoCoordinates(iModel.getRpcProps(), request);
81246
+ return response.iModelCoords;
81247
+ },
81248
+ fromIModelCoords: async (request) => {
81249
+ const rpc = _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.IModelReadRpcInterface.getClientForRouting(iModel.routingContext.token);
81250
+ const response = await rpc.getGeoCoordinatesFromIModelCoordinates(iModel.getRpcProps(), request);
81251
+ return response.geoCoords;
81252
+ },
81253
+ });
81205
81254
  }
81206
81255
  /** Obtain a converter that can convert between a geographic coordinate system and the iModel's own coordinate system.
81207
81256
  * @param datumOrGCRS The name or JSON representation of the geographic coordinate system datum - for example, "WGS84".
@@ -81209,7 +81258,19 @@ class GeoServices {
81209
81258
  * @note A [[BlankConnection]] has no connection to a backend, so it is never "open"; therefore it always returns `undefined`.
81210
81259
  */
81211
81260
  getConverter(datumOrGCRS) {
81212
- return this._iModel.isOpen ? new GeoConverter(this._iModel, datumOrGCRS ? datumOrGCRS : "") : undefined;
81261
+ if (this._options.isIModelClosed())
81262
+ return undefined;
81263
+ const datum = (typeof datumOrGCRS === "object" ? JSON.stringify(datumOrGCRS) : datumOrGCRS) ?? "";
81264
+ let converter = this._cache.get(datum);
81265
+ if (!converter) {
81266
+ converter = new GeoConverter({ ...this._options, datum });
81267
+ this._cache.set(datum, converter);
81268
+ converter.onAllRequestsCompleted.addOnce(() => {
81269
+ if (converter === this._cache.get(datum))
81270
+ this._cache.delete(datum);
81271
+ });
81272
+ }
81273
+ return converter;
81213
81274
  }
81214
81275
  }
81215
81276
 
@@ -82859,7 +82920,7 @@ class IModelConnection extends _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.I
82859
82920
  this.selectionSet = new _SelectionSet__WEBPACK_IMPORTED_MODULE_8__.SelectionSet(this);
82860
82921
  this.hilited = new _SelectionSet__WEBPACK_IMPORTED_MODULE_8__.HiliteSet(this);
82861
82922
  this.tiles = new _Tiles__WEBPACK_IMPORTED_MODULE_11__.Tiles(this);
82862
- this.geoServices = new _GeoServices__WEBPACK_IMPORTED_MODULE_4__.GeoServices(this);
82923
+ this.geoServices = _GeoServices__WEBPACK_IMPORTED_MODULE_4__.GeoServices.createForIModel(this);
82863
82924
  /* eslint-disable-next-line deprecation/deprecation */
82864
82925
  this.displayedExtents = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Range3d.fromJSON(this.projectExtents);
82865
82926
  this.onProjectExtentsChanged.addListener(() => {
@@ -83040,6 +83101,7 @@ class IModelConnection extends _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.I
83040
83101
  * @param result If defined, use this for output
83041
83102
  * @returns A Cartographic location
83042
83103
  * @throws IModelError if [[isGeoLocated]] is false or point could not be converted.
83104
+ * @see [[cartographicFromSpatial]] if you have more than one point to convert, or you don't know whether the iModel has a GCS.
83043
83105
  */
83044
83106
  async spatialToCartographicFromGcs(spatial, result) {
83045
83107
  if (!this.isGeoLocated && this.noGcsDefined)
@@ -83060,17 +83122,51 @@ class IModelConnection extends _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.I
83060
83122
  * @param result If defined, use this for output
83061
83123
  * @returns A Cartographic location
83062
83124
  * @throws IModelError if [[isGeoLocated]] is false or point could not be converted.
83063
- * @see [[spatialToCartographicFromGcs]]
83064
- * @see [[spatialToCartographicFromEcef]]
83125
+ * @see [[cartographicFromSpatial]] to convert multiple points at once.
83126
+ * @see [[spatialToCartographicFromEcef]] to synchronously convert points using the iModel's ECEF transform.
83065
83127
  */
83066
83128
  async spatialToCartographic(spatial, result) {
83067
83129
  return (this.noGcsDefined ? this.spatialToCartographicFromEcef(spatial, result) : this.spatialToCartographicFromGcs(spatial, result));
83068
83130
  }
83069
- /** Convert a [[Cartographic]] to a point in this iModel's Spatial coordinates using the Geographic location services for this IModelConnection.
83131
+ /** Convert points in this iModel's spatial coordinate system to [Cartographic]($common) coordinates using either a [[GeoConverter]] or the iModel's [EcefLocation]($common).
83132
+ * @param spatial Coordiantes to be converted from the iModel's spatial coordinate system
83133
+ * @returns The `spatial` coordinates converted to cartographic coordinates, of the same length and order as the `spatial`.
83134
+ * @throws IModelError if [[isGeoLocated]] is false or any point could not be converted.
83135
+ * @see [[spatialFromCartographic]] to perform the inverse conversion.
83136
+ * @see [[spatialToCartographicFromEcef]] to synchronously convert points using the iModel's ECEF transform.
83137
+ */
83138
+ async cartographicFromSpatial(spatial) {
83139
+ if (this.noGcsDefined)
83140
+ return spatial.map((p) => this.spatialToCartographicFromEcef(p));
83141
+ if (!this.isGeoLocated)
83142
+ throw new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.IModelError(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.GeoServiceStatus.NoGeoLocation, "iModel is not GeoLocated");
83143
+ if (!this.isOpen)
83144
+ throw new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.IModelError(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.GeoServiceStatus.NoGeoLocation, "iModel is not open");
83145
+ if (spatial.length === 0)
83146
+ return [];
83147
+ const geoConverter = this.geoServices.getConverter();
83148
+ (0,_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.assert)(undefined !== geoConverter);
83149
+ const coordResponse = await geoConverter.getGeoCoordinatesFromIModelCoordinates(spatial);
83150
+ if (coordResponse.geoCoords.length !== spatial.length)
83151
+ throw new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.IModelError(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.GeoServiceStatus.NoGeoLocation, "iModel is not GeoLocated");
83152
+ return coordResponse.geoCoords.map((coord) => {
83153
+ switch (coord.s) {
83154
+ case _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.GeoCoordStatus.NoGCSDefined:
83155
+ throw new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.IModelError(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.GeoServiceStatus.NoGeoLocation, "iModel is not GeoLocated");
83156
+ case _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.GeoCoordStatus.Success:
83157
+ const llh = _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Point3d.fromJSON(coord.p);
83158
+ return _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.Cartographic.fromDegrees({ longitude: llh.x, latitude: llh.y, height: llh.z });
83159
+ default:
83160
+ throw new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.IModelError((0,_itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.mapToGeoServiceStatus)(coord.s), "Error converting spatial to cartographic");
83161
+ }
83162
+ });
83163
+ }
83164
+ /** Convert a [Cartographic]($common) to a point in this iModel's spatial coordinate system using a [[GeoConverter]].
83070
83165
  * @param cartographic A cartographic location
83071
83166
  * @param result If defined, use this for output
83072
83167
  * @returns A point in this iModel's spatial coordinates
83073
83168
  * @throws IModelError if [[isGeoLocated]] is false or cartographic location could not be converted.
83169
+ * @see [[spatialFromCartographic]] to convert multiple points at once, or you don't know whether the iModel has a GCS.
83074
83170
  */
83075
83171
  async cartographicToSpatialFromGcs(cartographic, result) {
83076
83172
  if (!this.isGeoLocated && this.noGcsDefined)
@@ -83088,17 +83184,49 @@ class IModelConnection extends _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.I
83088
83184
  result.setFromJSON(coordResponse.iModelCoords[0].p);
83089
83185
  return result;
83090
83186
  }
83091
- /** Convert a [[Cartographic]] to a point in this iModel's Spatial coordinates using the Geographic location services for this IModelConnection or [[IModel.ecefLocation]].
83187
+ /** Convert a [Cartographic]($common) to a point in this iModel's Spatial coordinates using a [[GeoConverter]] or[[IModel.ecefLocation]($common).
83092
83188
  * @param cartographic A cartographic location
83093
83189
  * @param result If defined, use this for output
83094
83190
  * @returns A point in this iModel's spatial coordinates
83095
83191
  * @throws IModelError if [[isGeoLocated]] is false or cartographic location could not be converted.
83096
- * @see [[cartographicToSpatialFromGcs]]
83097
- * @see [[cartographicToSpatialFromEcef]]
83192
+ * @see [[spatialFromCartographic]] to convert multiple points at once.
83193
+ * @see [[cartographicToSpatialFromEcef]] to synchronously convert points using the iModel's ECEF transform.
83098
83194
  */
83099
83195
  async cartographicToSpatial(cartographic, result) {
83100
83196
  return (this.noGcsDefined ? this.cartographicToSpatialFromEcef(cartographic, result) : this.cartographicToSpatialFromGcs(cartographic, result));
83101
83197
  }
83198
+ /** Convert [Cartographic]($common) coordinates into points in this iModel's spatial coordinate system using a [[GeoConverter]] or the iModel's [EcefLocation]($common).
83199
+ * @param cartographic Coordinates to be converted to the iModel's spatial coordinate system.
83200
+ * @returns The `cartographic` coordinates converted to spatial coordinates, of the same length and order as `cartographic`.
83201
+ * @throws IModelError if [[isGeoLocated]] is false or any point could not be converted.
83202
+ * @see [[cartographicFromSpatial]] to perform the inverse conversion.
83203
+ */
83204
+ async spatialFromCartographic(cartographic) {
83205
+ if (this.noGcsDefined)
83206
+ return cartographic.map((p) => this.cartographicToSpatialFromEcef(p));
83207
+ if (!this.isGeoLocated)
83208
+ throw new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.IModelError(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.GeoServiceStatus.NoGeoLocation, "iModel is not GeoLocated");
83209
+ if (!this.isOpen)
83210
+ throw new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.IModelError(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.GeoServiceStatus.NoGeoLocation, "iModel is not open");
83211
+ if (cartographic.length === 0)
83212
+ return [];
83213
+ const geoConverter = this.geoServices.getConverter();
83214
+ (0,_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.assert)(undefined !== geoConverter);
83215
+ const geoCoords = cartographic.map((p) => _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Point3d.create(p.longitudeDegrees, p.latitudeDegrees, p.height));
83216
+ const coordResponse = await geoConverter.getIModelCoordinatesFromGeoCoordinates(geoCoords);
83217
+ if (coordResponse.iModelCoords.length !== cartographic.length)
83218
+ throw new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.IModelError(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.GeoServiceStatus.NoGeoLocation, "iModel is not GeoLocated");
83219
+ return coordResponse.iModelCoords.map((coord) => {
83220
+ switch (coord.s) {
83221
+ case _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.GeoCoordStatus.NoGCSDefined:
83222
+ throw new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.IModelError(_itwin_core_bentley__WEBPACK_IMPORTED_MODULE_0__.GeoServiceStatus.NoGeoLocation, "iModel is not GeoLocated");
83223
+ case _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.GeoCoordStatus.Success:
83224
+ return _itwin_core_geometry__WEBPACK_IMPORTED_MODULE_2__.Point3d.fromJSON(coord.p);
83225
+ default:
83226
+ throw new _itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.IModelError((0,_itwin_core_common__WEBPACK_IMPORTED_MODULE_1__.mapToGeoServiceStatus)(coord.s), "Error converting cartographic to spatial");
83227
+ }
83228
+ });
83229
+ }
83102
83230
  /** Expand this iModel's [[displayedExtents]] to include the specified range.
83103
83231
  * This is done automatically when reality models are added to a spatial view. In some cases a [[TiledGraphicsProvider]] may wish to expand
83104
83232
  * the extents explicitly to include its geometry.
@@ -90313,9 +90441,10 @@ function areaToEyeHeight(view3d, area, offset = 0) {
90313
90441
  * @internal
90314
90442
  */
90315
90443
  async function areaToEyeHeightFromGcs(view3d, area, offset = 0) {
90316
- const ne = await view3d.cartographicToRootFromGcs(area.northeast);
90317
- const sw = await view3d.cartographicToRootFromGcs(area.southwest);
90318
- return _areaToEyeHeight(view3d, ne, sw, offset);
90444
+ const corners = await view3d.cartographicToRootUsingGcs([area.northeast, area.southwest]);
90445
+ if (!corners)
90446
+ return 0;
90447
+ return _areaToEyeHeight(view3d, corners[0], corners[1], offset);
90319
90448
  }
90320
90449
  /** Converts a root range (often project extents) to a cartographic area.
90321
90450
  * @internal
@@ -92187,25 +92316,55 @@ class ViewState3d extends ViewState {
92187
92316
  this.turnCameraOff();
92188
92317
  return eyePoint.distance(origEyePoint);
92189
92318
  }
92190
- /** Convert a point in spatial space to a cartographic coordinate. */
92319
+ /** Convert a point in spatial coordinates to a cartographic coordinate. */
92191
92320
  rootToCartographic(root, result) {
92192
92321
  const backgroundMapGeometry = this.displayStyle.getBackgroundMapGeometry();
92193
92322
  return backgroundMapGeometry ? backgroundMapGeometry.dbToCartographic(root, result) : undefined;
92194
92323
  }
92195
- /** Convert a cartographic coordinate to a point in spatial space. */
92324
+ /** Convert a cartographic coordinate to a point in spatial coordinates. */
92196
92325
  cartographicToRoot(cartographic, result) {
92197
92326
  const backgroundMapGeometry = this.displayStyle.getBackgroundMapGeometry();
92198
92327
  return backgroundMapGeometry ? backgroundMapGeometry.cartographicToDb(cartographic, result) : undefined;
92199
92328
  }
92200
- /** Convert a point in spatial space to a cartographic coordinate using the GCS reprojection. */
92329
+ /** Convert a point in spatial coordinates to a cartographic coordinate using the GCS reprojection.
92330
+ * @see [[rootToCartographicUsingGcs]] to convert multiple points at once.
92331
+ * @see [[cartographicToRootFromGcs]] for the inverse conversion.
92332
+ */
92201
92333
  async rootToCartographicFromGcs(root, result) {
92202
92334
  const backgroundMapGeometry = this.displayStyle.getBackgroundMapGeometry();
92203
- return backgroundMapGeometry ? backgroundMapGeometry.dbToCartographicFromGcs(root, result) : undefined;
92335
+ if (!backgroundMapGeometry)
92336
+ return undefined;
92337
+ const carto = (await backgroundMapGeometry.dbToCartographicFromGcs([root]))[0];
92338
+ return carto.clone(result);
92204
92339
  }
92205
- /** Convert a cartographic coordinate to a point in spatial space using the GCS reprojection. */
92340
+ /** Convert spatial coordinates to cartographic coordinates using the GCS reprojection.
92341
+ * @param root Spatial coordinates to be converted
92342
+ * @returns the converted coordinates of the same length and order as `root`, or `undefined` if the conversion cannot be performed.
92343
+ * @see [[cartographicToRootUsingGcs]] for the inverse conversion.
92344
+ */
92345
+ async rootToCartographicUsingGcs(root) {
92346
+ const bgmap = this.displayStyle.getBackgroundMapGeometry();
92347
+ return bgmap?.dbToCartographicFromGcs(root);
92348
+ }
92349
+ /** Convert a cartographic coordinate to a point in spatial coordinates using the GCS reprojection.
92350
+ * @see [[cartographicToRootUsingGcs]] to convert multiple points at once.
92351
+ * @see [[rootToCartographicFromGcs]] for the inverse conversion.
92352
+ */
92206
92353
  async cartographicToRootFromGcs(cartographic, result) {
92207
92354
  const backgroundMapGeometry = this.displayStyle.getBackgroundMapGeometry();
92208
- return backgroundMapGeometry ? backgroundMapGeometry.cartographicToDbFromGcs(cartographic, result) : undefined;
92355
+ if (!backgroundMapGeometry)
92356
+ return undefined;
92357
+ const root = (await backgroundMapGeometry.cartographicToDbFromGcs([cartographic]))[0];
92358
+ return root.clone(result);
92359
+ }
92360
+ /** Convert cartographic coordinates to spatial coordinates using the GCS reprojection.
92361
+ * @param cartographic Cartographic coordinates to be converted
92362
+ * @returns the converted coordinates of the same length and order as `cartographic`, or `undefined` if the conversion cannot be performed.
92363
+ * @see [[rootToCartographicUsingGcs]] for the inverse conversion.
92364
+ */
92365
+ async cartographicToRootUsingGcs(cartographic) {
92366
+ const bgmap = this.displayStyle.getBackgroundMapGeometry();
92367
+ return bgmap?.cartographicToDbFromGcs(cartographic);
92209
92368
  }
92210
92369
  setupFromFrustum(frustum, opts) {
92211
92370
  const stat = super.setupFromFrustum(frustum, opts);
@@ -94056,7 +94215,7 @@ class Viewport {
94056
94215
  const worldPoint = hit.hitPoint.clone();
94057
94216
  const backgroundMapGeometry = hit.viewport.displayStyle.getBackgroundMapGeometry();
94058
94217
  if (undefined !== backgroundMapGeometry) {
94059
- featureInfo.hitPoint = await backgroundMapGeometry.dbToCartographicFromGcs(worldPoint);
94218
+ featureInfo.hitPoint = (await backgroundMapGeometry.dbToCartographicFromGcs([worldPoint]))[0];
94060
94219
  }
94061
94220
  const results = await Promise.all(promises);
94062
94221
  for (const result of results)
@@ -155420,7 +155579,7 @@ class MapTileTreeReference extends _internal__WEBPACK_IMPORTED_MODULE_7__.TileTr
155420
155579
  const worldPoint = hit.hitPoint.clone();
155421
155580
  let cartoGraphic;
155422
155581
  try {
155423
- cartoGraphic = await backgroundMapGeometry.dbToCartographicFromGcs(worldPoint);
155582
+ cartoGraphic = (await backgroundMapGeometry.dbToCartographicFromGcs([worldPoint]))[0];
155424
155583
  }
155425
155584
  catch {
155426
155585
  }
@@ -277148,7 +277307,7 @@ class TestContext {
277148
277307
  this.initializeRpcInterfaces({ title: this.settings.Backend.name, version: this.settings.Backend.version });
277149
277308
  const iModelClient = new imodels_client_management_1.IModelsClient({ api: { baseUrl: `https://${process.env.IMJS_URL_PREFIX ?? ""}api.bentley.com/imodels` } });
277150
277309
  await core_frontend_1.NoRenderApp.startup({
277151
- applicationVersion: "4.1.0-dev.29",
277310
+ applicationVersion: "4.1.0-dev.30",
277152
277311
  applicationId: this.settings.gprid,
277153
277312
  authorizationClient: new frontend_1.TestFrontendAuthorizationClient(this.adminUserAccessToken),
277154
277313
  hubAccess: new imodels_access_frontend_1.FrontendIModelsAccess(iModelClient),
@@ -296522,7 +296681,7 @@ module.exports = JSON.parse('{"name":"axios","version":"0.21.4","description":"P
296522
296681
  /***/ ((module) => {
296523
296682
 
296524
296683
  "use strict";
296525
- module.exports = JSON.parse('{"name":"@itwin/core-frontend","version":"4.1.0-dev.29","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs && npm run -s build:esm && npm run -s webpackWorkers && npm run -s copy:workers","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2020 --outDir lib/esm","clean":"rimraf lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","copy:workers":"cpx \\"./lib/workers/webpack/parse-imdl-worker.js\\" ./lib/public/scripts","docs":"betools docs --includes=../../generated-docs/extract --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/primitives,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-eslintrc -c \\"./node_modules/@itwin/eslint-plugin/dist/configs/extension-exports-config.js\\" \\"./src/**/*.ts\\" 1>&2","lint":"eslint -f visualstudio \\"./src/**/*.ts\\" 1>&2","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run -s webpackTests && certa -r chrome","cover":"npm -s test","test:debug":"certa -r chrome --debug","webpackTests":"webpack --config ./src/test/utils/webpack.config.js 1>&2 && npm run -s webpackTestWorker","webpackTestWorker":"webpack --config ./src/test/worker/webpack.config.js 1>&2 && cpx \\"./lib/test/test-worker.js\\" ./lib/test","webpackWorkers":"webpack --config ./src/workers/ImdlParser/webpack.config.js 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core.git","directory":"core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:^4.1.0-dev.29","@itwin/core-bentley":"workspace:^4.1.0-dev.29","@itwin/core-common":"workspace:^4.1.0-dev.29","@itwin/core-geometry":"workspace:^4.1.0-dev.29","@itwin/core-orbitgt":"workspace:^4.1.0-dev.29","@itwin/core-quantity":"workspace:^4.1.0-dev.29"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/certa":"workspace:*","@itwin/eslint-plugin":"^4.0.0-dev.33","@types/chai":"4.3.1","@types/chai-as-promised":"^7","@types/mocha":"^8.2.2","@types/node":"^18.11.5","@types/sinon":"^9.0.0","babel-loader":"~8.2.5","babel-plugin-istanbul":"~6.1.1","chai":"^4.1.2","chai-as-promised":"^7","cpx2":"^3.0.0","eslint":"^8.36.0","glob":"^7.1.2","mocha":"^10.0.0","nyc":"^15.1.0","rimraf":"^3.0.2","sinon":"^9.0.2","source-map-loader":"^4.0.0","typescript":"~5.0.2","webpack":"^5.76.0"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/object-storage-azure":"^1.5.0","@itwin/cloud-agnostic-core":"^1.5.0","@itwin/object-storage-core":"^1.5.0","@itwin/core-i18n":"workspace:*","@itwin/core-telemetry":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"^3.1.6","@loaders.gl/draco":"^3.1.6","fuse.js":"^3.3.0","wms-capabilities":"0.4.0","reflect-metadata":"0.1.13"},"nyc":{"extends":"./node_modules/@itwin/build-tools/.nycrc"},"eslintConfig":{"plugins":["@itwin"],"extends":"plugin:@itwin/itwinjs-recommended","rules":{"@itwin/no-internal-barrel-imports":["error",{"required-barrel-modules":["./src/tile/internal.ts"]}],"@itwin/public-extension-exports":["error",{"releaseTags":["public","preview"],"outputApiFile":false}]},"overrides":[{"files":["*.test.ts","*.test.tsx","**/test/**/*.ts"],"rules":{"@itwin/no-internal-barrel-imports":"off"}}]}}');
296684
+ module.exports = JSON.parse('{"name":"@itwin/core-frontend","version":"4.1.0-dev.30","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs && npm run -s build:esm && npm run -s webpackWorkers && npm run -s copy:workers","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2020 --outDir lib/esm","clean":"rimraf lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","copy:workers":"cpx \\"./lib/workers/webpack/parse-imdl-worker.js\\" ./lib/public/scripts","docs":"betools docs --includes=../../generated-docs/extract --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/primitives,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint --no-eslintrc -c \\"./node_modules/@itwin/eslint-plugin/dist/configs/extension-exports-config.js\\" \\"./src/**/*.ts\\" 1>&2","lint":"eslint -f visualstudio \\"./src/**/*.ts\\" 1>&2","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run -s webpackTests && certa -r chrome","cover":"npm -s test","test:debug":"certa -r chrome --debug","webpackTests":"webpack --config ./src/test/utils/webpack.config.js 1>&2 && npm run -s webpackTestWorker","webpackTestWorker":"webpack --config ./src/test/worker/webpack.config.js 1>&2 && cpx \\"./lib/test/test-worker.js\\" ./lib/test","webpackWorkers":"webpack --config ./src/workers/ImdlParser/webpack.config.js 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core.git","directory":"core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:^4.1.0-dev.30","@itwin/core-bentley":"workspace:^4.1.0-dev.30","@itwin/core-common":"workspace:^4.1.0-dev.30","@itwin/core-geometry":"workspace:^4.1.0-dev.30","@itwin/core-orbitgt":"workspace:^4.1.0-dev.30","@itwin/core-quantity":"workspace:^4.1.0-dev.30"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/certa":"workspace:*","@itwin/eslint-plugin":"^4.0.0-dev.33","@types/chai":"4.3.1","@types/chai-as-promised":"^7","@types/mocha":"^8.2.2","@types/node":"^18.11.5","@types/sinon":"^9.0.0","babel-loader":"~8.2.5","babel-plugin-istanbul":"~6.1.1","chai":"^4.1.2","chai-as-promised":"^7","cpx2":"^3.0.0","eslint":"^8.36.0","glob":"^7.1.2","mocha":"^10.0.0","nyc":"^15.1.0","rimraf":"^3.0.2","sinon":"^9.0.2","source-map-loader":"^4.0.0","typescript":"~5.0.2","webpack":"^5.76.0"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/object-storage-azure":"^1.5.0","@itwin/cloud-agnostic-core":"^1.5.0","@itwin/object-storage-core":"^1.5.0","@itwin/core-i18n":"workspace:*","@itwin/core-telemetry":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"^3.1.6","@loaders.gl/draco":"^3.1.6","fuse.js":"^3.3.0","wms-capabilities":"0.4.0","reflect-metadata":"0.1.13"},"nyc":{"extends":"./node_modules/@itwin/build-tools/.nycrc"},"eslintConfig":{"plugins":["@itwin"],"extends":"plugin:@itwin/itwinjs-recommended","rules":{"@itwin/no-internal-barrel-imports":["error",{"required-barrel-modules":["./src/tile/internal.ts"]}],"@itwin/public-extension-exports":["error",{"releaseTags":["public","preview"],"outputApiFile":false}]},"overrides":[{"files":["*.test.ts","*.test.tsx","**/test/**/*.ts"],"rules":{"@itwin/no-internal-barrel-imports":"off"}}]}}');
296526
296685
 
296527
296686
  /***/ }),
296528
296687