@itwin/core-backend 5.13.0-dev.10 → 5.13.0-dev.12

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 (53) hide show
  1. package/lib/cjs/Element.d.ts +25 -1
  2. package/lib/cjs/Element.d.ts.map +1 -1
  3. package/lib/cjs/Element.js +45 -0
  4. package/lib/cjs/Element.js.map +1 -1
  5. package/lib/esm/Element.d.ts +25 -1
  6. package/lib/esm/Element.d.ts.map +1 -1
  7. package/lib/esm/Element.js +45 -0
  8. package/lib/esm/Element.js.map +1 -1
  9. package/lib/esm/test/ecdb/QueryReaders.test.js +2 -16
  10. package/lib/esm/test/ecdb/QueryReaders.test.js.map +1 -1
  11. package/lib/esm/test/ecsql/src/ECSqlTestRunner.test.js +2 -2
  12. package/lib/esm/test/ecsql/src/ECSqlTestRunner.test.js.map +1 -1
  13. package/lib/esm/test/imodel/IModelECSql.test.d.ts +2 -0
  14. package/lib/esm/test/imodel/IModelECSql.test.d.ts.map +1 -0
  15. package/lib/esm/test/imodel/IModelECSql.test.js +367 -0
  16. package/lib/esm/test/imodel/IModelECSql.test.js.map +1 -0
  17. package/lib/esm/test/imodel/IModelElements.test.d.ts +2 -0
  18. package/lib/esm/test/imodel/IModelElements.test.d.ts.map +1 -0
  19. package/lib/esm/test/imodel/IModelElements.test.js +969 -0
  20. package/lib/esm/test/imodel/IModelElements.test.js.map +1 -0
  21. package/lib/esm/test/imodel/IModelGeolocation.test.d.ts +2 -0
  22. package/lib/esm/test/imodel/IModelGeolocation.test.d.ts.map +1 -0
  23. package/lib/esm/test/imodel/IModelGeolocation.test.js +539 -0
  24. package/lib/esm/test/imodel/IModelGeolocation.test.js.map +1 -0
  25. package/lib/esm/test/imodel/IModelLifecycle.test.d.ts +2 -0
  26. package/lib/esm/test/imodel/IModelLifecycle.test.d.ts.map +1 -0
  27. package/lib/esm/test/imodel/IModelLifecycle.test.js +498 -0
  28. package/lib/esm/test/imodel/IModelLifecycle.test.js.map +1 -0
  29. package/lib/esm/test/imodel/IModelMetadata.test.d.ts +2 -0
  30. package/lib/esm/test/imodel/IModelMetadata.test.d.ts.map +1 -0
  31. package/lib/esm/test/imodel/IModelMetadata.test.js +274 -0
  32. package/lib/esm/test/imodel/IModelMetadata.test.js.map +1 -0
  33. package/lib/esm/test/imodel/IModelModels.test.d.ts +2 -0
  34. package/lib/esm/test/imodel/IModelModels.test.d.ts.map +1 -0
  35. package/lib/esm/test/imodel/IModelModels.test.js +357 -0
  36. package/lib/esm/test/imodel/IModelModels.test.js.map +1 -0
  37. package/lib/esm/test/imodel/IModelRelationships.test.d.ts +2 -0
  38. package/lib/esm/test/imodel/IModelRelationships.test.d.ts.map +1 -0
  39. package/lib/esm/test/imodel/IModelRelationships.test.js +407 -0
  40. package/lib/esm/test/imodel/IModelRelationships.test.js.map +1 -0
  41. package/lib/esm/test/imodel/IModelTestFixtures.d.ts +53 -0
  42. package/lib/esm/test/imodel/IModelTestFixtures.d.ts.map +1 -0
  43. package/lib/esm/test/imodel/IModelTestFixtures.js +107 -0
  44. package/lib/esm/test/imodel/IModelTestFixtures.js.map +1 -0
  45. package/lib/esm/test/imodel/IModelViews.test.d.ts +2 -0
  46. package/lib/esm/test/imodel/IModelViews.test.d.ts.map +1 -0
  47. package/lib/esm/test/imodel/IModelViews.test.js +199 -0
  48. package/lib/esm/test/imodel/IModelViews.test.js.map +1 -0
  49. package/package.json +13 -13
  50. package/lib/esm/test/imodel/IModel.test.d.ts +0 -2
  51. package/lib/esm/test/imodel/IModel.test.d.ts.map +0 -1
  52. package/lib/esm/test/imodel/IModel.test.js +0 -3277
  53. package/lib/esm/test/imodel/IModel.test.js.map +0 -1
@@ -0,0 +1,539 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { assert, expect } from "chai";
6
+ import { Guid } from "@itwin/core-bentley";
7
+ import { EcefLocation, GeoCoordStatus, GeographicCRS, } from "@itwin/core-common";
8
+ import { Geometry, Point3d } from "@itwin/core-geometry";
9
+ import { withEditTxn } from "../../EditTxn";
10
+ import { SnapshotDb } from "../../core-backend";
11
+ import { IModelTestUtils } from "../IModelTestUtils";
12
+ import { TestUtils } from "../TestUtils";
13
+ import { closeIfOpen, openReadonlySeedCopy } from "./IModelTestFixtures";
14
+ describe("iModel geolocation", () => {
15
+ let mirukuruReadonly;
16
+ let originalEnv;
17
+ before(async () => {
18
+ originalEnv = { ...process.env };
19
+ await TestUtils.shutdownBackend();
20
+ await TestUtils.startBackend({ loadGcsWorkspaces: true });
21
+ IModelTestUtils.registerTestBimSchema();
22
+ mirukuruReadonly = await openReadonlySeedCopy("geolocation-mirukuru.ibim", "mirukuru.ibim");
23
+ });
24
+ after(async () => {
25
+ process.env = originalEnv;
26
+ closeIfOpen(mirukuruReadonly);
27
+ await TestUtils.shutdownBackend();
28
+ await TestUtils.startBackend();
29
+ });
30
+ it("ecefLocation for iModels", () => {
31
+ assert.isTrue(mirukuruReadonly.isGeoLocated);
32
+ const center = { x: 289095, y: 3803860, z: 10 }; // near center of project extents, 10 meters above ground.
33
+ const ecefPt = mirukuruReadonly.spatialToEcef(center);
34
+ const pt = { x: -3575156.3661052254, y: 3873432.0891543664, z: 3578996.012643183 };
35
+ assert.isTrue(ecefPt.isAlmostEqual(pt), "spatialToEcef");
36
+ const z2 = mirukuruReadonly.ecefToSpatial(ecefPt);
37
+ assert.isTrue(z2.isAlmostEqual(center), "ecefToSpatial");
38
+ const carto = mirukuruReadonly.spatialToCartographicFromEcef(center);
39
+ assert.approximately(carto.longitudeDegrees, 132.70683882277805, .1); // this data is in Japan
40
+ assert.approximately(carto.latitudeDegrees, 34.35462768786055, .1);
41
+ const c2 = { longitude: 2.3161712773709127, latitude: 0.5996013664499733, height: 10 };
42
+ assert.isTrue(carto.equalsEpsilon(c2, .001), "spatialToCartographic");
43
+ mirukuruReadonly.cartographicToSpatialFromEcef(carto, z2);
44
+ assert.isTrue(z2.isAlmostEqual(center, .001), "cartographicToSpatial");
45
+ assert.isTrue(mirukuruReadonly.geographicCoordinateSystem !== undefined);
46
+ assert.isTrue(mirukuruReadonly.geographicCoordinateSystem.horizontalCRS !== undefined);
47
+ assert.isTrue(mirukuruReadonly.geographicCoordinateSystem.verticalCRS !== undefined);
48
+ assert.isTrue(mirukuruReadonly.geographicCoordinateSystem.verticalCRS.id !== undefined);
49
+ assert.isTrue(mirukuruReadonly.geographicCoordinateSystem.horizontalCRS.id === "UTM84-53N");
50
+ assert.isTrue(mirukuruReadonly.geographicCoordinateSystem.verticalCRS.id === "ELLIPSOID");
51
+ });
52
+ it("should be able to create a snapshot IModel and set geolocation by GCS", async () => {
53
+ const args = {
54
+ rootSubject: { name: "TestSubject", description: "test iTwin" },
55
+ client: "ABC Engineering",
56
+ globalOrigin: { x: 10, y: 10 },
57
+ projectExtents: { low: { x: -300, y: -300, z: -20 }, high: { x: 500, y: 500, z: 400 } },
58
+ guid: Guid.createValue(),
59
+ };
60
+ const gcs = new GeographicCRS({
61
+ horizontalCRS: {
62
+ id: "10TM115-27",
63
+ description: "",
64
+ source: "Mentor Software Client",
65
+ deprecated: false,
66
+ datumId: "NAD27",
67
+ unit: "Meter",
68
+ projection: {
69
+ method: "TransverseMercator",
70
+ centralMeridian: -115,
71
+ latitudeOfOrigin: 0,
72
+ scaleFactor: 0.9992,
73
+ falseEasting: 0.0,
74
+ falseNorthing: 0.0,
75
+ },
76
+ extent: {
77
+ southWest: { latitude: 48, longitude: -120.5 },
78
+ northEast: { latitude: 84, longitude: -109.5 },
79
+ },
80
+ },
81
+ verticalCRS: { id: "GEOID" },
82
+ additionalTransform: {
83
+ helmert2DWithZOffset: {
84
+ translationX: 10.0,
85
+ translationY: 15.0,
86
+ translationZ: 0.02,
87
+ rotDeg: 1.2,
88
+ scale: 1.0001,
89
+ },
90
+ },
91
+ });
92
+ const testFile = IModelTestUtils.prepareOutputFile("IModel", "TestSnapshot2.bim");
93
+ const iModel = SnapshotDb.createEmpty(testFile, args);
94
+ let eventListenedTo = false;
95
+ const gcsListener = (previousGCS) => {
96
+ assert.equal(previousGCS, undefined);
97
+ assert.isTrue(iModel.geographicCoordinateSystem !== undefined);
98
+ assert.isTrue(iModel.geographicCoordinateSystem.equals(gcs));
99
+ eventListenedTo = true;
100
+ };
101
+ iModel.onGeographicCoordinateSystemChanged.addListener(gcsListener);
102
+ assert.isTrue(iModel.geographicCoordinateSystem === undefined);
103
+ assert.isFalse(eventListenedTo);
104
+ iModel.geographicCoordinateSystem = gcs;
105
+ assert.isTrue(eventListenedTo);
106
+ withEditTxn(iModel, (txn) => {
107
+ txn.updateIModelProps();
108
+ });
109
+ iModel.close();
110
+ const iModel2 = SnapshotDb.openFile(testFile);
111
+ assert.isTrue(iModel2.geographicCoordinateSystem !== undefined);
112
+ // The reloaded gcs will be different as the datum definition will have been expanded
113
+ assert.isFalse(iModel2.geographicCoordinateSystem.equals(gcs));
114
+ // But other properties will be identical
115
+ assert.isTrue(iModel2.geographicCoordinateSystem !== undefined);
116
+ assert.isTrue(iModel2.geographicCoordinateSystem.verticalCRS !== undefined);
117
+ assert.isTrue(iModel2.geographicCoordinateSystem.verticalCRS.equals(gcs.verticalCRS));
118
+ assert.isTrue(iModel2.geographicCoordinateSystem.additionalTransform !== undefined);
119
+ assert.isTrue(iModel2.geographicCoordinateSystem.additionalTransform.equals(gcs.additionalTransform));
120
+ assert.isTrue(iModel2.geographicCoordinateSystem.horizontalCRS !== undefined);
121
+ assert.isTrue(iModel2.geographicCoordinateSystem.horizontalCRS.projection !== undefined);
122
+ assert.isTrue(iModel2.geographicCoordinateSystem.horizontalCRS.projection.equals(gcs.horizontalCRS.projection));
123
+ assert.isTrue(iModel2.geographicCoordinateSystem.horizontalCRS.id !== undefined);
124
+ assert.isTrue(iModel2.geographicCoordinateSystem.horizontalCRS.id === gcs.horizontalCRS.id);
125
+ assert.isTrue(iModel2.geographicCoordinateSystem.horizontalCRS.extent !== undefined);
126
+ assert.isTrue(iModel2.geographicCoordinateSystem.horizontalCRS.extent.equals(gcs.horizontalCRS.extent));
127
+ // The following were not in initial definition but were completed after storage.
128
+ assert.isTrue(iModel2.geographicCoordinateSystem.horizontalCRS.datum !== undefined);
129
+ assert.isTrue(iModel2.geographicCoordinateSystem.horizontalCRS.datum.additionalTransformPaths !== undefined);
130
+ assert.isTrue(iModel2.geographicCoordinateSystem.horizontalCRS.datum.additionalTransformPaths.length >= 0);
131
+ // When a gcs is present then the ECEF is automatically defined.
132
+ assert.isTrue(iModel2.ecefLocation !== undefined);
133
+ iModel2.close();
134
+ });
135
+ describe("async coordinate conversions", () => {
136
+ it("should output same number of points as input", async () => {
137
+ const iModelCoords = [];
138
+ const geoCoords = [];
139
+ for (let numPts = 0; numPts < 3; numPts++) {
140
+ const geoResponse = await mirukuruReadonly.getGeoCoordinatesFromIModelCoordinates({ target: "WGS84", iModelCoords });
141
+ expect(geoResponse.geoCoords.length).to.equal(numPts);
142
+ const iModelResponse = await mirukuruReadonly.getIModelCoordinatesFromGeoCoordinates({ source: "WGS84", geoCoords });
143
+ expect(iModelResponse.iModelCoords.length).to.equal(numPts);
144
+ iModelCoords.push(new Point3d());
145
+ geoCoords.push(new Point3d());
146
+ }
147
+ });
148
+ it("should always have fromCache = 0", async () => {
149
+ const iModelCoords = [];
150
+ const geoCoords = [];
151
+ for (let numPts = 0; numPts < 3; numPts++) {
152
+ const geoResponse = await mirukuruReadonly.getGeoCoordinatesFromIModelCoordinates({ target: "WGS84", iModelCoords });
153
+ expect(geoResponse.fromCache).to.equal(0);
154
+ const iModelResponse = await mirukuruReadonly.getIModelCoordinatesFromGeoCoordinates({ source: "WGS84", geoCoords });
155
+ expect(iModelResponse.iModelCoords.length).to.equal(numPts);
156
+ expect(iModelResponse.fromCache).to.equal(0);
157
+ iModelCoords.push(new Point3d());
158
+ geoCoords.push(new Point3d());
159
+ }
160
+ });
161
+ it("should be able to reproject with iModel coordinates to or from any other GeographicCRS", async () => {
162
+ const convertTest = async (fileName, fileGCS, datum, inputCoord, outputCoord) => {
163
+ const args = {
164
+ rootSubject: { name: "TestSubject", description: "test project" },
165
+ client: "ABC Engineering",
166
+ globalOrigin: { x: 0.0, y: 0.0 },
167
+ projectExtents: { low: { x: -300, y: -300, z: -20 }, high: { x: 500, y: 500, z: 400 } },
168
+ guid: Guid.createValue(),
169
+ };
170
+ let datumOrGCS;
171
+ if (typeof datum === "object")
172
+ datumOrGCS = JSON.stringify(datum);
173
+ else
174
+ datumOrGCS = datum;
175
+ const testFile = IModelTestUtils.prepareOutputFile("IModel", fileName);
176
+ const iModel = SnapshotDb.createEmpty(testFile, args);
177
+ withEditTxn(iModel, (txn) => {
178
+ iModel.setGeographicCoordinateSystem(fileGCS);
179
+ txn.updateIModelProps();
180
+ });
181
+ const testPoint1 = [];
182
+ testPoint1.push(inputCoord);
183
+ const requestProps1 = { target: datumOrGCS, iModelCoords: testPoint1 };
184
+ const response1 = await iModel.getGeoCoordinatesFromIModelCoordinates(requestProps1);
185
+ expect(response1.geoCoords[0].s === outputCoord.s).to.be.true;
186
+ // If success or warning we compare result
187
+ if (outputCoord.s === GeoCoordStatus.Success || outputCoord.s === GeoCoordStatus.OutOfUsefulRange) {
188
+ const expectedPt1 = Point3d.fromJSON(outputCoord.p);
189
+ const outPt1 = Point3d.fromJSON(response1.geoCoords[0].p);
190
+ expect(Geometry.isSamePoint3dXY(expectedPt1, outPt1, 0.001)).to.be.true;
191
+ expect(Math.abs(expectedPt1.z - outPt1.z) < 0.0001).to.be.true;
192
+ // No point testing reversal when Out of useful range since reversibility is doubtful
193
+ if (outputCoord.s !== GeoCoordStatus.OutOfUsefulRange) {
194
+ const testPoint2 = [];
195
+ testPoint2.push(outputCoord.p);
196
+ const requestProps2 = { source: datumOrGCS, geoCoords: testPoint2 };
197
+ const response2 = await iModel.getIModelCoordinatesFromGeoCoordinates(requestProps2);
198
+ const expectedPt2 = Point3d.fromJSON(inputCoord);
199
+ const outPt2 = Point3d.fromJSON(response2.iModelCoords[0].p);
200
+ expect(expectedPt2.distanceXY(outPt2) < 0.001).to.be.true;
201
+ expect(Math.abs(expectedPt2.z - outPt2.z) < 0.001).to.be.true;
202
+ }
203
+ }
204
+ iModel.close();
205
+ };
206
+ const EWRGCS = {
207
+ horizontalCRS: {
208
+ id: "EPSG:27700",
209
+ description: "OSGB 1936 / British National Grid",
210
+ source: "EPSG V6 [Large and medium scale topographic mapping and engin]",
211
+ datumId: "EPSG:6277",
212
+ datum: {
213
+ id: "EPSG:6277",
214
+ description: "OSGB36 - Use OSGB-7P-2. Consider OSGB/OSTN15 instead",
215
+ deprecated: true,
216
+ source: "EPSG V6.12 operation EPSG:1314 [EPSG]",
217
+ ellipsoidId: "EPSG:7001",
218
+ ellipsoid: {
219
+ equatorialRadius: 6377563.396,
220
+ polarRadius: 6356256.909237,
221
+ id: "EPSG:7001",
222
+ description: "Airy 1830",
223
+ source: "EPSG, Version 6 [EPSG]",
224
+ },
225
+ transforms: [
226
+ {
227
+ method: "PositionalVector",
228
+ sourceEllipsoid: {
229
+ equatorialRadius: 6377563.396,
230
+ polarRadius: 6356256.909237,
231
+ id: "EPSG:7001",
232
+ },
233
+ targetEllipsoid: {
234
+ equatorialRadius: 6378137,
235
+ polarRadius: 6356752.3142,
236
+ id: "WGS84",
237
+ },
238
+ positionalVector: {
239
+ delta: {
240
+ x: 446.448,
241
+ y: -125.157,
242
+ z: 542.06,
243
+ },
244
+ rotation: {
245
+ x: 0.15,
246
+ y: 0.247,
247
+ z: 0.842,
248
+ },
249
+ scalePPM: -20.489,
250
+ },
251
+ }
252
+ ],
253
+ },
254
+ unit: "Meter",
255
+ projection: {
256
+ method: "TransverseMercator",
257
+ falseEasting: 400000,
258
+ falseNorthing: -100000,
259
+ centralMeridian: -2,
260
+ latitudeOfOrigin: 49,
261
+ scaleFactor: 0.999601272737422,
262
+ },
263
+ extent: {
264
+ southWest: {
265
+ latitude: 49.96,
266
+ longitude: -7.56,
267
+ },
268
+ northEast: {
269
+ latitude: 60.84,
270
+ longitude: 1.78,
271
+ },
272
+ },
273
+ },
274
+ verticalCRS: {
275
+ id: "ELLIPSOID",
276
+ },
277
+ additionalTransform: {
278
+ helmert2DWithZOffset: {
279
+ translationX: 284597.3343,
280
+ translationY: 79859.4651,
281
+ translationZ: 0,
282
+ rotDeg: 0.5263624458992088,
283
+ scale: 0.9996703340508721,
284
+ },
285
+ },
286
+ };
287
+ await convertTest("ExtonCampus1.bim", { horizontalCRS: { id: "EPSG:2272" }, verticalCRS: { id: "NAVD88" } }, "WGS84", { x: 775970.3155166894, y: 83323.24543981979, z: 130.74977547686285 }, { p: { x: -75.68712011112366, y: 40.06524845273591, z: 95.9769083 }, s: GeoCoordStatus.Success });
288
+ await convertTest("UTM83-10-NGVD29-10.bim", { horizontalCRS: { id: "UTM83-10" }, verticalCRS: { id: "NAVD88" } }, { horizontalCRS: { id: "UTM27-10" }, verticalCRS: { id: "NGVD29" } }, { x: 548296.472, y: 4179414.470, z: 0.8457 }, { p: { x: 548392.9689991799, y: 4179217.683834238, z: -0.0006774162750405877 }, s: GeoCoordStatus.Success });
289
+ await convertTest("BritishNatGrid-EllipsoidHelmert1.bim", EWRGCS, "WGS84", { x: 199247.08883859176, y: 150141.68625139236, z: 0.0 }, { p: { x: -0.80184489371471, y: 51.978341907041205, z: 0.0 }, s: GeoCoordStatus.Success });
290
+ await convertTest("BritishNatGrid-Ellipsoid1.bim", { horizontalCRS: { id: "BritishNatGrid" }, verticalCRS: { id: "ELLIPSOID" } }, "", { x: 170370.718, y: 11572.405, z: 0.0 }, { p: { x: -5.2020119082059511, y: 49.959453295440234, z: 0.0 }, s: GeoCoordStatus.Success });
291
+ await convertTest("BritishNatGrid-Ellipsoid2.bim", { horizontalCRS: { id: "BritishNatGrid" }, verticalCRS: { id: "ELLIPSOID" } }, "ETRF89", { x: 170370.718, y: 11572.405, z: 0.0 }, { p: { x: -5.2030365061523707, y: 49.960007477936202, z: 0.0 }, s: GeoCoordStatus.Success });
292
+ await convertTest("BritishNatGrid-Ellipsoid3.bim", { horizontalCRS: { id: "BritishNatGrid" }, verticalCRS: { id: "ELLIPSOID" } }, "OSGB", { x: 170370.718, y: 11572.405, z: 0.0 }, { p: { x: -5.2020119082059511, y: 49.959453295440234, z: 0.0 }, s: GeoCoordStatus.Success });
293
+ await convertTest("GermanyDHDN-3-Ellipsoid1.bim", { horizontalCRS: { id: "DHDN/3.GK3d-4/EN" }, verticalCRS: { id: "ELLIPSOID" } }, "", { x: 4360857.005, y: 5606083.067, z: 0.0 }, { p: { x: 10.035413954488630, y: 50.575070810112159, z: 0.0 }, s: GeoCoordStatus.Success });
294
+ await convertTest("GermanyDHDN-3-Ellipsoid2.bim", { horizontalCRS: { id: "DHDN/3.GK3d-4/EN" }, verticalCRS: { id: "ELLIPSOID" } }, "DHDN/3", { x: 4360857.005, y: 5606083.067, z: 0.0 }, { p: { x: 10.035413954488630, y: 50.575070810112159, z: 0.0 }, s: GeoCoordStatus.Success });
295
+ await convertTest("GermanyDHDN-3-Ellipsoid3.bim", { horizontalCRS: { id: "DHDN/3.GK3d-4/EN" }, verticalCRS: { id: "ELLIPSOID" } }, "WGS84", { x: 4360857.005, y: 5606083.067, z: 0.0 }, { p: { x: 10.034215937440818, y: 50.573862480894853, z: 0.0 }, s: GeoCoordStatus.Success });
296
+ await convertTest("UTM83-10-NGVD29-1.bim", { horizontalCRS: { id: "UTM83-10" }, verticalCRS: { id: "NGVD29" } }, "", { x: 632748.112, y: 4263868.307, z: 0.0 }, { p: { x: -121.47738265889652, y: 38.513305313793019, z: 0.0 }, s: GeoCoordStatus.Success });
297
+ await convertTest("UTM83-10-NGVD29-2.bim", { horizontalCRS: { id: "UTM83-10" }, verticalCRS: { id: "NGVD29" } }, "NAD83", { x: 632748.112, y: 4263868.307, z: 0.0 }, { p: { x: -121.47738265889652, y: 38.513305313793019, z: -30.12668428839329 }, s: GeoCoordStatus.Success });
298
+ await convertTest("UTM83-10-NGVD29-3.bim", { horizontalCRS: { id: "UTM83-10" }, verticalCRS: { id: "NGVD29" } }, "WGS84", { x: 632748.112, y: 4263868.307, z: 0.0 }, { p: { x: -121.47738265889652, y: 38.513305313793019, z: -30.12668428839329 }, s: GeoCoordStatus.Success });
299
+ await convertTest("UTM27-10-Ellipsoid1.bim", { horizontalCRS: { id: "UTM27-10" }, verticalCRS: { id: "ELLIPSOID" } }, "", { x: 623075.328, y: 4265650.532, z: 0.0 }, { p: { x: -121.58798236995744, y: 38.532616292207997, z: 0.0 }, s: GeoCoordStatus.Success });
300
+ await convertTest("UTM27-10-Ellipsoid2.bim", { horizontalCRS: { id: "UTM27-10" }, verticalCRS: { id: "ELLIPSOID" } }, "NAD83", { x: 623075.328, y: 4265650.532, z: 0.0 }, { p: { x: -121.58905088839697, y: 38.532522753851708, z: 0.0 }, s: GeoCoordStatus.Success });
301
+ await convertTest("UTM83-10-NGVD29-4.bim", { horizontalCRS: { id: "UTM83-10" }, verticalCRS: { id: "NGVD29" } }, { horizontalCRS: { id: "LL84" }, verticalCRS: { id: "ELLIPSOID" } }, { x: 632748.112, y: 4263868.307, z: 0.0 }, { p: { x: -121.47738265889652, y: 38.513305313793019, z: -30.12668428839329 }, s: GeoCoordStatus.Success });
302
+ await convertTest("UTM83-10-NGVD29-5.bim", { horizontalCRS: { id: "UTM83-10" }, verticalCRS: { id: "NGVD29" } }, { horizontalCRS: { id: "LL84" }, verticalCRS: { id: "GEOID" } }, { x: 632748.112, y: 4263868.307, z: 0.0 }, { p: { x: -121.47738265889652, y: 38.513305313793019, z: 0.7621583779125531 }, s: GeoCoordStatus.Success });
303
+ await convertTest("UTM83-10-NGVD29-6.bim", { horizontalCRS: { id: "UTM83-10" }, verticalCRS: { id: "NGVD29" } }, { horizontalCRS: { id: "CA83-II" }, verticalCRS: { id: "NAVD88" } }, { x: 569024.940, y: 4386341.752, z: 0.0 }, { p: { x: 1983192.529823256, y: 717304.0311293667, z: 0.745910484422781 }, s: GeoCoordStatus.Success });
304
+ await convertTest("UTM83-10-NGVD29-7.bim", { horizontalCRS: { id: "UTM83-10" }, verticalCRS: { id: "NGVD29" } }, { horizontalCRS: { id: "CA83-II" }, verticalCRS: { id: "GEOID" } }, { x: 569024.940, y: 4386341.752, z: 0.0 }, { p: { x: 1983192.529823256, y: 717304.0311293667, z: 0.745910484422781 }, s: GeoCoordStatus.Success });
305
+ await convertTest("UTM83-10-NGVD29-8.bim", { horizontalCRS: { id: "UTM83-10" }, verticalCRS: { id: "NGVD29" } }, { horizontalCRS: { id: "CA83-II" }, verticalCRS: { id: "NGVD29" } }, { x: 569024.940, y: 4386341.752, z: 0.0 }, { p: { x: 1983192.529823256, y: 717304.0311293667, z: 0.0 }, s: GeoCoordStatus.Success });
306
+ await convertTest("UTM83-10-NGVD29-9.bim", { horizontalCRS: { id: "UTM83-10" }, verticalCRS: { id: "NGVD29" } }, { horizontalCRS: { epsg: 26942 }, verticalCRS: { id: "NAVD88" } }, { x: 569024.940, y: 4386341.752, z: 0.0 }, { p: { x: 1983192.529823256, y: 717304.0311293667, z: 0.745910484422781 }, s: GeoCoordStatus.Success });
307
+ await convertTest("UTM83-10-NGVD29-10.bim", { horizontalCRS: { id: "UTM83-10" }, verticalCRS: { id: "NAVD88" } }, { horizontalCRS: { id: "UTM27-10" }, verticalCRS: { id: "NGVD29" } }, { x: 548296.472, y: 4179414.470, z: 0.8457 }, { p: { x: 548392.9689991799, y: 4179217.683834238, z: -0.0006774162750405877 }, s: GeoCoordStatus.Success });
308
+ await convertTest("BritishNatGrid-Ellipsoid4.bim", { horizontalCRS: { id: "BritishNatGrid" }, verticalCRS: { id: "ELLIPSOID" } }, { horizontalCRS: { id: "HS2_Snake_2015" }, verticalCRS: { id: "GEOID" } }, { x: 473327.251, y: 257049.636, z: 0.0 }, { p: { x: 237732.58101946692, y: 364048.01547843055, z: -47.874172425966336 }, s: GeoCoordStatus.Success });
309
+ await convertTest("BritishNatGrid-Ellipsoid5.bim", { horizontalCRS: { id: "BritishNatGrid" }, verticalCRS: { id: "ELLIPSOID" } }, {
310
+ horizontalCRS: {
311
+ id: "HS2-MOCK",
312
+ description: "USES CUSTOM DATUM",
313
+ source: "Test",
314
+ deprecated: false,
315
+ datumId: "HS2SD_2015",
316
+ unit: "Meter",
317
+ projection: {
318
+ method: "TransverseMercator",
319
+ centralMeridian: -1.5,
320
+ latitudeOfOrigin: 52.30,
321
+ scaleFactor: 1.0,
322
+ falseEasting: 198873.0046,
323
+ falseNorthing: 375064.3871,
324
+ },
325
+ },
326
+ verticalCRS: {
327
+ id: "GEOID",
328
+ },
329
+ }, { x: 473327.251, y: 257049.636, z: 0.0 }, { p: { x: 237732.58101952373, y: 364048.01548327296, z: -47.874172425966336 }, s: GeoCoordStatus.Success });
330
+ await convertTest("BritishNatGrid-Ellipsoid.bim", { horizontalCRS: { id: "BritishNatGrid" }, verticalCRS: { id: "ELLIPSOID" } }, { horizontalCRS: { id: "OSGB-GPS-2015" }, verticalCRS: { id: "GEOID" } }, { x: 473327.251, y: 257049.636, z: 0.0 }, { p: { x: 473325.6830048648, y: 257049.77062273448, z: -47.87643904264457 }, s: GeoCoordStatus.Success });
331
+ await convertTest("UTM83-10-NGVD29-12.bim", { horizontalCRS: { id: "UTM83-10" }, verticalCRS: { id: "NGVD29" } }, {
332
+ horizontalCRS: {
333
+ id: "California2",
334
+ description: "USES CUSTOM DATUM",
335
+ source: "Test",
336
+ deprecated: false,
337
+ datumId: "NAD83",
338
+ unit: "Meter",
339
+ projection: {
340
+ method: "LambertConformalConicTwoParallels",
341
+ longitudeOfOrigin: -122,
342
+ latitudeOfOrigin: 37.66666666667,
343
+ standardParallel1: 39.833333333333336,
344
+ standardParallel2: 38.333333333333336,
345
+ falseEasting: 2000000.0,
346
+ falseNorthing: 500000.0,
347
+ },
348
+ extent: {
349
+ southWest: {
350
+ latitude: 35,
351
+ longitude: -125,
352
+ },
353
+ northEast: {
354
+ latitude: 39.1,
355
+ longitude: -120.45,
356
+ },
357
+ },
358
+ },
359
+ verticalCRS: {
360
+ id: "GEOID",
361
+ },
362
+ }, { x: 569024.940, y: 4386341.752, z: 0.0 }, { p: { x: 1983192.529823256, y: 717304.0311293667, z: 0.745910484422781 }, s: GeoCoordStatus.Success });
363
+ // Do some test that return errors
364
+ // First test uses one GCS in Eastern USA and the other in UK. This will produce a hard domain error
365
+ await convertTest("Error1.bim", { horizontalCRS: { id: "UTM84-17N" }, verticalCRS: { id: "ELLIPSOID" } }, { horizontalCRS: { id: "OSGB-GPS-2015" }, verticalCRS: { id: "GEOID" } }, { x: 1473327.251, y: 1257049.636, z: 0.0 }, { p: { x: 473325.6830048648, y: 257049.77062273448, z: -47.87643904264457 }, s: GeoCoordStatus.OutOfMathematicalDomain });
366
+ // This test performs conversion in a region outside normal use of GCS but still mathematically valid (soft domain error)
367
+ await convertTest("Error2.bim", { horizontalCRS: { id: "DanishS34-S99" }, verticalCRS: { id: "ELLIPSOID" } }, "", { x: -6618.5925260757449, y: 36058.097489683532, z: 0.0 }, { p: { x: 13.53250346041385, y: 54.71216475341563, z: 0.0 }, s: GeoCoordStatus.OutOfUsefulRange });
368
+ // -6618.5925260757449, 36058.097489683532
369
+ // { x: -221748.034, y: -10012.784, z: 0.0 } { p: { x: 10.36481105, y: 54.38462506, z: 0.0 }
370
+ // This test makes use of a GCS using a grid file that does not even exist and will return a datum conversion error.
371
+ const userGCSWithinexistentGridFile = {
372
+ horizontalCRS: {
373
+ id: "User1",
374
+ datumId: "UserDatum1",
375
+ datum: {
376
+ id: "UserDatum1",
377
+ ellipsoidId: "CLRK66",
378
+ transforms: [
379
+ {
380
+ method: "GridFiles",
381
+ sourceEllipsoid: {
382
+ id: "CLRK66",
383
+ equatorialRadius: 6378160.0,
384
+ polarRadius: 6356774.719195306,
385
+ },
386
+ targetEllipsoid: {
387
+ id: "WGS84",
388
+ equatorialRadius: 6378160.0,
389
+ polarRadius: 6356774.719195306,
390
+ },
391
+ gridFile: {
392
+ files: [
393
+ { fileName: "./user/inexistent.gdc", format: "NTv2", direction: "Direct" },
394
+ ],
395
+ },
396
+ },
397
+ ],
398
+ },
399
+ unit: "Meter",
400
+ projection: {
401
+ method: "TransverseMercator",
402
+ centralMeridian: -115,
403
+ latitudeOfOrigin: 0,
404
+ scaleFactor: 0.9992,
405
+ falseEasting: 1.0,
406
+ falseNorthing: 2.0,
407
+ },
408
+ extent: {
409
+ southWest: { latitude: 48, longitude: -120.5 },
410
+ northEast: { latitude: 84, longitude: -109.5 },
411
+ },
412
+ }, verticalCRS: { id: "ELLIPSOID" },
413
+ };
414
+ await convertTest("Error3.bim", userGCSWithinexistentGridFile, "WGS84", { x: 1473327.251, y: 1257049.636, z: 0.0 }, { p: { x: 473325.6830048648, y: 257049.77062273448, z: -47.87643904264457 }, s: GeoCoordStatus.NoDatumConverter });
415
+ // The model GCS is not valid
416
+ await convertTest("Error4.bim", { horizontalCRS: { id: "badfood" }, verticalCRS: { id: "ELLIPSOID" } }, { horizontalCRS: { id: "OSGB-GPS-2015" }, verticalCRS: { id: "GEOID" } }, { x: 1473327.251, y: 1257049.636, z: 0.0 }, { p: { x: 473325.6830048648, y: 257049.77062273448, z: -47.87643904264457 }, s: GeoCoordStatus.NoGCSDefined });
417
+ // The given GCS is not valid
418
+ await convertTest("Error5.bim", { horizontalCRS: { id: "UTM84-17N" }, verticalCRS: { id: "ELLIPSOID" } }, { horizontalCRS: { id: "badfood" }, verticalCRS: { id: "GEOID" } }, { x: 1473327.251, y: 1257049.636, z: 0.0 }, { p: { x: 473325.6830048648, y: 257049.77062273448, z: -47.87643904264457 }, s: GeoCoordStatus.NoGCSDefined });
419
+ });
420
+ });
421
+ it("should be able to create a snapshot IModel and set geolocation by ECEF", async () => {
422
+ const args = {
423
+ rootSubject: { name: "TestSubject", description: "test iTwin" },
424
+ client: "ABC Engineering",
425
+ globalOrigin: { x: 10, y: 10 },
426
+ projectExtents: { low: { x: -300, y: -300, z: -20 }, high: { x: 500, y: 500, z: 400 } },
427
+ guid: Guid.createValue(),
428
+ };
429
+ const ecef = new EcefLocation({
430
+ origin: [42, 21, 0],
431
+ orientation: { yaw: 1, pitch: 1, roll: -1 },
432
+ });
433
+ const testFile = IModelTestUtils.prepareOutputFile("IModel", "TestSnapshot3.bim");
434
+ const iModel = SnapshotDb.createEmpty(testFile, args);
435
+ assert.isTrue(iModel.ecefLocation === undefined);
436
+ iModel.ecefLocation = ecef;
437
+ withEditTxn(iModel, (txn) => {
438
+ txn.updateIModelProps();
439
+ });
440
+ iModel.close();
441
+ const iModel2 = SnapshotDb.openFile(testFile);
442
+ assert.isTrue(iModel2.ecefLocation !== undefined);
443
+ assert.isTrue(iModel2.ecefLocation.isAlmostEqual(ecef));
444
+ iModel2.close();
445
+ });
446
+ it("should be able to create a snapshot IModel and set geolocation by ECEF with 0,0,0 rotation", async () => {
447
+ const args = {
448
+ rootSubject: { name: "TestSubject", description: "test iTwin" },
449
+ client: "ABC Engineering",
450
+ globalOrigin: { x: 10, y: 10 },
451
+ projectExtents: { low: { x: -300, y: -300, z: -20 }, high: { x: 500, y: 500, z: 400 } },
452
+ guid: Guid.createValue(),
453
+ };
454
+ const ecef = new EcefLocation({
455
+ origin: [42, 21, 0],
456
+ orientation: { yaw: 0, pitch: 0, roll: 0 },
457
+ });
458
+ const testFile = IModelTestUtils.prepareOutputFile("IModel", "TestSnapshot3_000.bim");
459
+ const iModel = SnapshotDb.createEmpty(testFile, args);
460
+ assert.isTrue(iModel.ecefLocation === undefined);
461
+ iModel.ecefLocation = ecef;
462
+ withEditTxn(iModel, (txn) => {
463
+ txn.updateIModelProps();
464
+ });
465
+ iModel.close();
466
+ const iModel2 = SnapshotDb.openFile(testFile);
467
+ assert.isTrue(iModel2.ecefLocation !== undefined);
468
+ assert.isTrue(iModel2.ecefLocation.isAlmostEqual(ecef));
469
+ iModel2.close();
470
+ });
471
+ it("presence of a GCS imposes the ecef value", async () => {
472
+ const args = {
473
+ rootSubject: { name: "TestSubject", description: "test iTwin" },
474
+ client: "ABC Engineering",
475
+ globalOrigin: { x: 10, y: 10 },
476
+ projectExtents: { low: { x: -300, y: -300, z: -20 }, high: { x: 500, y: 500, z: 400 } },
477
+ guid: Guid.createValue(),
478
+ };
479
+ const gcs = new GeographicCRS({
480
+ horizontalCRS: {
481
+ id: "10TM115-27",
482
+ description: "",
483
+ source: "Mentor Software Client",
484
+ deprecated: false,
485
+ datumId: "NAD27",
486
+ unit: "Meter",
487
+ projection: {
488
+ method: "TransverseMercator",
489
+ centralMeridian: -115,
490
+ latitudeOfOrigin: 0,
491
+ scaleFactor: 0.9992,
492
+ falseEasting: 0.0,
493
+ falseNorthing: 0.0,
494
+ },
495
+ extent: {
496
+ southWest: { latitude: 48, longitude: -120.5 },
497
+ northEast: { latitude: 84, longitude: -109.5 },
498
+ },
499
+ },
500
+ verticalCRS: { id: "GEOID" },
501
+ additionalTransform: {
502
+ helmert2DWithZOffset: {
503
+ translationX: 10.0,
504
+ translationY: 15.0,
505
+ translationZ: 0.02,
506
+ rotDeg: 1.2,
507
+ scale: 1.0001,
508
+ },
509
+ },
510
+ });
511
+ const ecef = new EcefLocation({
512
+ origin: [42, 21, 0],
513
+ orientation: { yaw: 1, pitch: 1, roll: -1 },
514
+ });
515
+ const testFile = IModelTestUtils.prepareOutputFile("IModel", "TestSnapshot4.bim");
516
+ const iModel = SnapshotDb.createEmpty(testFile, args);
517
+ iModel.ecefLocation = ecef;
518
+ withEditTxn(iModel, (txn) => {
519
+ txn.updateIModelProps();
520
+ });
521
+ iModel.close();
522
+ const iModel2 = SnapshotDb.openForApplyChangesets(testFile);
523
+ assert.isTrue(iModel2.ecefLocation !== undefined);
524
+ assert.isTrue(iModel2.ecefLocation.isAlmostEqual(ecef));
525
+ assert.isTrue(iModel2.geographicCoordinateSystem === undefined);
526
+ iModel2.geographicCoordinateSystem = gcs;
527
+ withEditTxn(iModel2, (txn) => {
528
+ txn.updateIModelProps();
529
+ });
530
+ iModel2.close();
531
+ const iModel3 = SnapshotDb.openFile(testFile);
532
+ assert.isTrue(iModel3.geographicCoordinateSystem !== undefined);
533
+ // When a gcs is present then ecef value is imposed by the gcs disregarding previous value.
534
+ assert.isTrue(iModel3.ecefLocation !== undefined);
535
+ assert.isFalse(iModel3.ecefLocation.isAlmostEqual(ecef));
536
+ iModel3.close();
537
+ });
538
+ });
539
+ //# sourceMappingURL=IModelGeolocation.test.js.map