bruce-cesium 6.6.0 → 6.6.1

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,6 +1,6 @@
1
- import { Cartes, Entity as Entity$1, Calculator, EntityRelationType, EntityType, Style, ENVIRONMENT, ProjectViewTile, DelayQueue, LRUCache, BruceEvent, ObjectUtils, Geometry, EntityHistoricData, EntityLod, ZoomControl, EntityTag, Tileset, Api, EntityCoords, DataLab, EntitySource, ClientFile, MenuItem, EntityRelation, ProgramKey, Bounds, Carto, ProjectView, ProjectViewBookmark, ProjectViewLegacyTile, Camera, AbstractApi, EntityAttachment, EntityAttachmentType, EntityAttribute, MathUtils, Session } from 'bruce-models';
1
+ import { Cartes, Entity as Entity$1, Calculator, EntityRelationType, EntityType, Style, ENVIRONMENT, ProjectViewTile, DelayQueue, LRUCache, BruceEvent, ObjectUtils, Geometry, EntityHistoricData, EntityLod, ZoomControl, EntityTag, Tileset, Api, DataLab, EntityCoords, EntitySource, ClientFile, MenuItem, EntityRelation, ProgramKey, Bounds, Carto, ProjectView, ProjectViewBookmark, ProjectViewLegacyTile, Camera, AbstractApi, EntityAttachment, EntityAttachmentType, EntityAttribute, MathUtils, Session } from 'bruce-models';
2
2
  import * as Cesium from 'cesium';
3
- import { Cartographic, ColorMaterialProperty, Entity, Color, ConstantProperty, CallbackProperty, Primitive, Cesium3DTileFeature, Math as Math$1, Cartesian3, JulianDate, Quaternion, Transforms, HeadingPitchRoll, Matrix4, DistanceDisplayCondition, HeightReference, HorizontalOrigin, VerticalOrigin, ClassificationType, ConstantPositionProperty, PolygonHierarchy, ShadowMode, PolylineGraphics, ArcType, CornerType, ColorBlendMode, Model, Cartesian2, SceneTransforms, NearFarScalar, Matrix3, Rectangle, KmlDataSource, GeoJsonDataSource, SceneMode, Cesium3DTileStyle, HeadingPitchRange, Cesium3DTileColorBlendMode, Ion, EllipsoidTerrainProvider, IonImageryProvider, createWorldImagery, createWorldImageryAsync, BingMapsImageryProvider, BingMapsStyle, MapboxImageryProvider, MapboxStyleImageryProvider, ArcGisMapServerImageryProvider, OpenStreetMapImageryProvider, UrlTemplateImageryProvider, GridImageryProvider, GeographicTilingScheme, ImageryLayer, TileMapServiceImageryProvider, CesiumTerrainProvider, IonResource, Cesium3DTileset, OrthographicFrustum, EasingFunction, ModelGraphics, PolygonGraphics, CorridorGraphics, PointGraphics, BillboardGraphics, EllipseGraphics, PolylineDashMaterialProperty, EllipsoidGeodesic, sampleTerrainMostDetailed, defined, BoundingSphere, GeometryInstance, PolygonPipeline, CesiumInspector, ClockRange, ScreenSpaceEventHandler, ScreenSpaceEventType, Intersect, CzmlDataSource, Fullscreen } from 'cesium';
3
+ import { Cartographic, ColorMaterialProperty, Entity, Color, ConstantProperty, CallbackProperty, Primitive, Cesium3DTileFeature, Math as Math$1, Cartesian3, JulianDate, Quaternion, Transforms, HeadingPitchRoll, Matrix4, DistanceDisplayCondition, HeightReference, ColorBlendMode, ShadowMode, ClassificationType, Model, HorizontalOrigin, VerticalOrigin, ConstantPositionProperty, PolygonHierarchy, PolylineGraphics, ArcType, CornerType, Cartesian2, SceneTransforms, NearFarScalar, Matrix3, Rectangle, KmlDataSource, GeoJsonDataSource, SceneMode, Cesium3DTileStyle, HeadingPitchRange, Cesium3DTileColorBlendMode, Ion, EllipsoidTerrainProvider, IonImageryProvider, createWorldImagery, createWorldImageryAsync, BingMapsImageryProvider, BingMapsStyle, MapboxImageryProvider, MapboxStyleImageryProvider, ArcGisMapServerImageryProvider, OpenStreetMapImageryProvider, UrlTemplateImageryProvider, GridImageryProvider, GeographicTilingScheme, ImageryLayer, TileMapServiceImageryProvider, CesiumTerrainProvider, IonResource, Cesium3DTileset, OrthographicFrustum, EasingFunction, ModelGraphics, PolygonGraphics, CorridorGraphics, PointGraphics, BillboardGraphics, EllipseGraphics, PolylineDashMaterialProperty, EllipsoidGeodesic, sampleTerrainMostDetailed, defined, BoundingSphere, GeometryInstance, PolygonPipeline, CesiumInspector, ClockRange, ScreenSpaceEventHandler, ScreenSpaceEventType, Intersect, CzmlDataSource, Fullscreen } from 'cesium';
4
4
 
5
5
  /**
6
6
  * Ensures a number is returned from a given value.
@@ -12852,6 +12852,236 @@ function getOrCreateCell(cells, cellSize, lon, maxLon, lat, maxLat) {
12852
12852
  return [id, cell];
12853
12853
  }
12854
12854
 
12855
+ const DEFAULT_GROUNDED_HEIGHT = 300;
12856
+ const MINIMUM_VIEW_AREA_SIZE_DEGREES = 0.01;
12857
+ const NET_STEP_PERCENT = 5;
12858
+ const BORDER_STEPS = 3;
12859
+ function isDefined(value) {
12860
+ return value !== null && value !== undefined;
12861
+ }
12862
+ function netScanViewForBoundaries(viewer, center) {
12863
+ let maxLong = -2 * Math.PI;
12864
+ let minLong = 2 * Math.PI;
12865
+ let maxLat = -2 * Math.PI;
12866
+ let minLat = 2 * Math.PI;
12867
+ let found = 0;
12868
+ const updateMinMax = (lon, lat) => {
12869
+ if (lon < -Math.PI || lon > Math.PI || lat < -Math.PI / 2 || lat > Math.PI / 2) {
12870
+ return;
12871
+ }
12872
+ maxLong = Math.max(maxLong, lon);
12873
+ maxLat = Math.max(maxLat, lat);
12874
+ minLong = Math.min(minLong, lon);
12875
+ minLat = Math.min(minLat, lat);
12876
+ };
12877
+ const updateMinMaxForPoint = (stepX, stepY) => {
12878
+ const x = Math.round((viewer.container.clientWidth / 100) * (stepX * NET_STEP_PERCENT));
12879
+ const y = Math.round((viewer.container.clientHeight / 100) * (stepY * NET_STEP_PERCENT));
12880
+ const winPos = new Cartesian2(x, y);
12881
+ try {
12882
+ const intersection = getAdjustedGroundIntersectionOfCameraRay(viewer, winPos);
12883
+ if (intersection) {
12884
+ const point = Cartographic.fromCartesian(intersection, viewer.scene.globe.ellipsoid);
12885
+ updateMinMax(point.longitude, point.latitude);
12886
+ found++;
12887
+ }
12888
+ }
12889
+ catch (e) {
12890
+ console.error(e);
12891
+ }
12892
+ };
12893
+ updateMinMaxForPoint(BORDER_STEPS, BORDER_STEPS);
12894
+ updateMinMaxForPoint((100 / NET_STEP_PERCENT) - BORDER_STEPS, BORDER_STEPS);
12895
+ updateMinMaxForPoint(BORDER_STEPS, (100 / NET_STEP_PERCENT) - BORDER_STEPS);
12896
+ updateMinMaxForPoint((100 / NET_STEP_PERCENT) - BORDER_STEPS, (100 / NET_STEP_PERCENT) - BORDER_STEPS);
12897
+ updateMinMaxForPoint(BORDER_STEPS * 2, BORDER_STEPS * 2);
12898
+ updateMinMaxForPoint((100 / NET_STEP_PERCENT) - BORDER_STEPS * 2, BORDER_STEPS * 2);
12899
+ updateMinMaxForPoint(BORDER_STEPS * 2, (100 / NET_STEP_PERCENT) - BORDER_STEPS * 2);
12900
+ updateMinMaxForPoint((100 / NET_STEP_PERCENT) - BORDER_STEPS * 2, (100 / NET_STEP_PERCENT) - BORDER_STEPS * 2);
12901
+ if (center && found <= 0) {
12902
+ updateMinMax(Math$1.toRadians(center.longitude), Math$1.toRadians(center.latitude));
12903
+ found += 1;
12904
+ const size = viewer.camera.positionCartographic.height;
12905
+ const pitch = viewer.camera.pitch;
12906
+ const distance = size / Math.tan(pitch);
12907
+ const p1 = offsetPoint({
12908
+ altitude: center.altitude,
12909
+ latitude: center.latitude,
12910
+ longitude: center.longitude
12911
+ }, distance, 45);
12912
+ const p2 = offsetPoint({
12913
+ altitude: center.altitude,
12914
+ latitude: center.latitude,
12915
+ longitude: center.longitude
12916
+ }, -distance, 45);
12917
+ if (isDefined(p1 === null || p1 === void 0 ? void 0 : p1.latitude) && isDefined(p1 === null || p1 === void 0 ? void 0 : p1.longitude)) {
12918
+ updateMinMax(Math$1.toRadians(p1.longitude), Math$1.toRadians(p1.latitude));
12919
+ }
12920
+ if (isDefined(p2 === null || p2 === void 0 ? void 0 : p2.latitude) && isDefined(p2 === null || p2 === void 0 ? void 0 : p2.longitude)) {
12921
+ updateMinMax(Math$1.toRadians(p2.longitude), Math$1.toRadians(p2.latitude));
12922
+ }
12923
+ }
12924
+ if (found > 0) {
12925
+ return {
12926
+ east: maxLong,
12927
+ west: minLong,
12928
+ north: maxLat,
12929
+ south: minLat
12930
+ };
12931
+ }
12932
+ return null;
12933
+ }
12934
+ function offsetPoint(point, distance, heading) {
12935
+ const radius = 6371e3;
12936
+ const delta = distance / radius;
12937
+ const theta = Math$1.toRadians(heading);
12938
+ const phi1 = Math$1.toRadians(point.latitude);
12939
+ const lambda1 = Math$1.toRadians(point.longitude);
12940
+ const sinPhi2 = Math.sin(phi1) * Math.cos(delta) + Math.cos(phi1) * Math.sin(delta) * Math.cos(theta);
12941
+ const phi2 = Math.asin(sinPhi2);
12942
+ const y = Math.sin(theta) * Math.sin(delta) * Math.cos(phi1);
12943
+ const x = Math.cos(delta) - Math.sin(phi1) * sinPhi2;
12944
+ const lambda2 = lambda1 + Math.atan2(y, x);
12945
+ return {
12946
+ altitude: point.altitude,
12947
+ latitude: Math$1.toDegrees(phi2),
12948
+ longitude: Math$1.toDegrees(lambda2)
12949
+ };
12950
+ }
12951
+ function offsetPos3d(pos3d, distance, heading) {
12952
+ const carto = Cartographic.fromCartesian(pos3d);
12953
+ const newCarto = offsetPoint({
12954
+ altitude: carto.height,
12955
+ latitude: Math$1.toDegrees(carto.latitude),
12956
+ longitude: Math$1.toDegrees(carto.longitude)
12957
+ }, distance, heading);
12958
+ return Cartesian3.fromDegrees(newCarto.longitude, newCarto.latitude, newCarto.altitude);
12959
+ }
12960
+ function getAdjustedGroundIntersectionOfCameraRay(viewer, screenPos) {
12961
+ const ray = viewer.camera.getPickRay(screenPos);
12962
+ const intersection = ray ? viewer.scene.globe.pick(ray, viewer.scene) : null;
12963
+ return intersection || null;
12964
+ }
12965
+ function getGroundCenterOfCameraRay(viewer, screenPos) {
12966
+ var _a, _b;
12967
+ const ray = viewer.camera.getPickRay(screenPos);
12968
+ const intersection = ray ? viewer.scene.globe.pick(ray, viewer.scene) : null;
12969
+ if (intersection) {
12970
+ return intersection;
12971
+ }
12972
+ const cameraHeight = viewer.camera.positionCartographic.height;
12973
+ if (!isNaN(cameraHeight) && isDefined(cameraHeight) && ((_b = (_a = viewer.camera) === null || _a === void 0 ? void 0 : _a.position) === null || _b === void 0 ? void 0 : _b.clone)) {
12974
+ const cameraPos3d = viewer.camera.position.clone();
12975
+ const pitch = viewer.camera.pitch;
12976
+ const distance = cameraHeight / Math.tan(pitch);
12977
+ return offsetPos3d(cameraPos3d, -distance, Math$1.toDegrees(viewer.camera.heading));
12978
+ }
12979
+ return null;
12980
+ }
12981
+ var ViewGroundArea;
12982
+ (function (ViewGroundArea) {
12983
+ function ToBboxPolygon(bounds) {
12984
+ return `${bounds.west},${bounds.south} ${bounds.west},${bounds.north} ${bounds.east},${bounds.north} ${bounds.east},${bounds.south}`;
12985
+ }
12986
+ ViewGroundArea.ToBboxPolygon = ToBboxPolygon;
12987
+ function NormalizeBounds(bounds, altitude) {
12988
+ if (!bounds ||
12989
+ !isDefined(bounds.east) ||
12990
+ !isDefined(bounds.west) ||
12991
+ !isDefined(bounds.north) ||
12992
+ !isDefined(bounds.south)) {
12993
+ return null;
12994
+ }
12995
+ const viewRect = { ...bounds };
12996
+ const centerLong = (viewRect.east + viewRect.west) / 2;
12997
+ const centerLat = (viewRect.north + viewRect.south) / 2;
12998
+ viewRect.east = Math.max(viewRect.east, centerLong + (MINIMUM_VIEW_AREA_SIZE_DEGREES / 2));
12999
+ viewRect.west = Math.min(viewRect.west, centerLong - (MINIMUM_VIEW_AREA_SIZE_DEGREES / 2));
13000
+ viewRect.south = Math.min(viewRect.south, centerLat - (MINIMUM_VIEW_AREA_SIZE_DEGREES / 2));
13001
+ viewRect.north = Math.max(viewRect.north, centerLat + (MINIMUM_VIEW_AREA_SIZE_DEGREES / 2));
13002
+ if (isDefined(altitude)) {
13003
+ viewRect.alt = altitude;
13004
+ }
13005
+ return viewRect;
13006
+ }
13007
+ ViewGroundArea.NormalizeBounds = NormalizeBounds;
13008
+ async function GetViewArea(viewer) {
13009
+ var _a, _b;
13010
+ if (!viewer || viewer.isDestroyed()) {
13011
+ return null;
13012
+ }
13013
+ if (!viewer.container || ((_a = viewer.container.style) === null || _a === void 0 ? void 0 : _a.display) == "none") {
13014
+ return null;
13015
+ }
13016
+ let viewRect = null;
13017
+ let center = null;
13018
+ const camera = viewer.camera;
13019
+ const terrData = await DrawingUtils.GetTerrainHeight({
13020
+ pos3d: camera.position,
13021
+ viewer
13022
+ });
13023
+ const cameraPosition = viewer.camera.positionCartographic;
13024
+ const terrHeight = terrData.error ? cameraPosition.height + DEFAULT_GROUNDED_HEIGHT : terrData.height;
13025
+ if (terrHeight && ((cameraPosition.height - terrHeight) < DEFAULT_GROUNDED_HEIGHT)) {
13026
+ viewRect = {};
13027
+ const viewRectRad = netScanViewForBoundaries(viewer);
13028
+ if (viewRectRad &&
13029
+ isDefined(viewRectRad.east) &&
13030
+ isDefined(viewRectRad.west) &&
13031
+ isDefined(viewRectRad.north) &&
13032
+ isDefined(viewRectRad.south)) {
13033
+ viewRect.east = Math$1.toDegrees(Math.max(viewRectRad.east, cameraPosition.longitude));
13034
+ viewRect.west = Math$1.toDegrees(Math.min(viewRectRad.west, cameraPosition.longitude));
13035
+ viewRect.south = Math$1.toDegrees(Math.min(viewRectRad.south, cameraPosition.latitude));
13036
+ viewRect.north = Math$1.toDegrees(Math.max(viewRectRad.north, cameraPosition.latitude));
13037
+ }
13038
+ else {
13039
+ viewRect.east = Math$1.toDegrees(cameraPosition.longitude);
13040
+ viewRect.west = Math$1.toDegrees(cameraPosition.longitude);
13041
+ viewRect.south = Math$1.toDegrees(cameraPosition.latitude);
13042
+ viewRect.north = Math$1.toDegrees(cameraPosition.latitude);
13043
+ }
13044
+ center = {
13045
+ altitude: camera.positionCartographic.height,
13046
+ latitude: Math$1.toDegrees(camera.positionCartographic.latitude),
13047
+ longitude: Math$1.toDegrees(camera.positionCartographic.longitude)
13048
+ };
13049
+ }
13050
+ else {
13051
+ const windowPosition = new Cartesian2(viewer.container.clientWidth / 2, viewer.container.clientHeight / 2);
13052
+ const intersection = getGroundCenterOfCameraRay(viewer, windowPosition);
13053
+ let point = null;
13054
+ if (intersection) {
13055
+ point = Cartographic.fromCartesian(intersection, viewer.scene.globe.ellipsoid);
13056
+ }
13057
+ if (point) {
13058
+ center = {
13059
+ altitude: point.height,
13060
+ latitude: Math$1.toDegrees(point.latitude),
13061
+ longitude: Math$1.toDegrees(point.longitude)
13062
+ };
13063
+ const viewRectRad = netScanViewForBoundaries(viewer, center);
13064
+ if (viewRectRad) {
13065
+ viewRect = {};
13066
+ viewRect.east = Math$1.toDegrees(viewRectRad.east);
13067
+ viewRect.west = Math$1.toDegrees(viewRectRad.west);
13068
+ viewRect.south = Math$1.toDegrees(viewRectRad.south);
13069
+ viewRect.north = Math$1.toDegrees(viewRectRad.north);
13070
+ }
13071
+ }
13072
+ }
13073
+ viewRect = NormalizeBounds(viewRect, (_b = viewer.scene.camera.positionCartographic) === null || _b === void 0 ? void 0 : _b.height);
13074
+ if (center && viewRect) {
13075
+ return {
13076
+ bounds: viewRect,
13077
+ target: center
13078
+ };
13079
+ }
13080
+ return null;
13081
+ }
13082
+ ViewGroundArea.GetViewArea = GetViewArea;
13083
+ })(ViewGroundArea || (ViewGroundArea = {}));
13084
+
12855
13085
  const MAX_AREA_IN_DEGREES$1 = 90;
12856
13086
  const MAX_RETRY_ATTEMPTS = 1;
12857
13087
  const RETRY_DELAY_INCREMENT = 500;
@@ -12929,7 +13159,7 @@ var EntityFilterGetter;
12929
13159
  // We use this for refreshing historic data without having to repeat geographic queries.
12930
13160
  this.gatheredIntegrity = null;
12931
13161
  this.gatheredEntityIds = [];
12932
- const { api, viewer, viewPort, typeIds, schemaId, batchSize, attrFilter, historicAttrKey, historicInterpolation, historic, viaCdn, scenario } = params;
13162
+ const { api, viewer, viewPort, typeIds, schemaId, batchSize, attrFilter, historicAttrKey, historicInterpolation, historic, viaCdn, scenario, dataLab } = params;
12933
13163
  this.api = api;
12934
13164
  this.typeIds = typeIds;
12935
13165
  this.schemaId = schemaId;
@@ -12940,6 +13170,7 @@ var EntityFilterGetter;
12940
13170
  this.batchSize = isNaN(batchSize) ? 300 : batchSize;
12941
13171
  this.viewPort = viewPort;
12942
13172
  this.attrFilter = attrFilter;
13173
+ this.dataLab = dataLab;
12943
13174
  this.viewer = viewer;
12944
13175
  this.scenario = scenario ? scenario : 0;
12945
13176
  this.updateBounds();
@@ -12964,6 +13195,9 @@ var EntityFilterGetter;
12964
13195
  if (this.typeIds) {
12965
13196
  integrity += this.typeIds.join();
12966
13197
  }
13198
+ if (this.dataLab) {
13199
+ integrity += JSON.stringify(this.dataLab);
13200
+ }
12967
13201
  return integrity;
12968
13202
  }
12969
13203
  viewAreaSub() {
@@ -13070,6 +13304,22 @@ var EntityFilterGetter;
13070
13304
  delete this.registeredItems[menuItemId];
13071
13305
  this.updateState(true);
13072
13306
  }
13307
+ Dispose() {
13308
+ var _a, _b, _c, _d;
13309
+ this.registeredItems = {};
13310
+ this.getterLoopId += 1;
13311
+ for (const key in this.getterLoopAbortControllers) {
13312
+ this.getterLoopAbortControllers[key].abort();
13313
+ }
13314
+ this.getterLoopAbortControllers = {};
13315
+ (_a = this.historicRefreshAbortController) === null || _a === void 0 ? void 0 : _a.abort();
13316
+ this.historicRefreshAbortController = null;
13317
+ this.viewAreaDispose();
13318
+ this.viewerDateTimeDispose();
13319
+ (_b = this.onUpdate) === null || _b === void 0 ? void 0 : _b.Clear();
13320
+ (_c = this.onStateUpdate) === null || _c === void 0 ? void 0 : _c.Clear();
13321
+ (_d = this.onScanUpdate) === null || _d === void 0 ? void 0 : _d.Clear();
13322
+ }
13073
13323
  updateBounds() {
13074
13324
  const viewRect = this.viewPort.GetBounds();
13075
13325
  const poi = this.viewPort.GetTarget();
@@ -13140,6 +13390,67 @@ var EntityFilterGetter;
13140
13390
  this.LastStateUpdates[status.msg] = status;
13141
13391
  (_a = this.onStateUpdate) === null || _a === void 0 ? void 0 : _a.Trigger(status);
13142
13392
  }
13393
+ createDataLabQuery(bounds) {
13394
+ var _a;
13395
+ const dataLab = this.dataLab;
13396
+ const userItems = (dataLab === null || dataLab === void 0 ? void 0 : dataLab.queryItems) ? JSON.parse(JSON.stringify(dataLab.queryItems)) : [];
13397
+ const primaryKey = DataLab.EReqKey.Primary;
13398
+ const baseQuery = (dataLab === null || dataLab === void 0 ? void 0 : dataLab.query) ? JSON.parse(JSON.stringify(dataLab.query)) : {};
13399
+ const basePrimary = (_a = baseQuery === null || baseQuery === void 0 ? void 0 : baseQuery[primaryKey]) !== null && _a !== void 0 ? _a : {};
13400
+ const items = [
13401
+ {
13402
+ LogicOperator: "AND",
13403
+ AttributeValue: {
13404
+ AttributePath: "Bruce/Boundaries",
13405
+ OperandA: ViewGroundArea.ToBboxPolygon(bounds),
13406
+ Operator: "intersects"
13407
+ },
13408
+ key: "attribute"
13409
+ }
13410
+ ];
13411
+ if (userItems.length) {
13412
+ items.push({
13413
+ LogicOperator: "AND",
13414
+ Items: [],
13415
+ key: "subquery",
13416
+ Subquery: {
13417
+ Items: userItems
13418
+ }
13419
+ });
13420
+ }
13421
+ baseQuery[primaryKey] = {
13422
+ ...basePrimary,
13423
+ Items: items
13424
+ };
13425
+ baseQuery.Expand = "location,source";
13426
+ return baseQuery;
13427
+ }
13428
+ async getDataLabResponse(params) {
13429
+ var _a;
13430
+ const { bounds, pageIndex, pageSize, abortSignal } = params;
13431
+ const skip = pageIndex * pageSize;
13432
+ const data = await DataLab.Run({
13433
+ api: this.api,
13434
+ query: this.createDataLabQuery(bounds),
13435
+ skip,
13436
+ load: pageSize,
13437
+ migrated: true,
13438
+ req: {
13439
+ noCache: true,
13440
+ abortSignal
13441
+ }
13442
+ });
13443
+ const entities = (_a = data.entities) !== null && _a !== void 0 ? _a : [];
13444
+ const totalCount = data.totalCount;
13445
+ const nextPage = totalCount != null
13446
+ ? skip + entities.length < totalCount
13447
+ : entities.length >= pageSize;
13448
+ return {
13449
+ entities,
13450
+ nextPage,
13451
+ nextPageUrl: null
13452
+ };
13453
+ }
13143
13454
  startGetterLoop() {
13144
13455
  // Increase id so that existing loops stop.
13145
13456
  this.getterLoopId += 1;
@@ -13218,13 +13529,24 @@ var EntityFilterGetter;
13218
13529
  nextPage: false,
13219
13530
  nextPageUrl: null
13220
13531
  };
13221
- await SharedGetters.Queue.Run("Loading Entities from Menu Item that loads Entity Type: " + this.typeIds, async () => {
13532
+ const queueName = this.dataLab
13533
+ ? "Loading DataLab Entities from Menu Item"
13534
+ : "Loading Entities from Menu Item that loads Entity Type: " + this.typeIds;
13535
+ await SharedGetters.Queue.Run(queueName, async () => {
13222
13536
  var _a;
13223
13537
  if (abortController.signal.aborted || !((_a = this.GetMenuItems()) === null || _a === void 0 ? void 0 : _a.length)) {
13224
13538
  return;
13225
13539
  }
13540
+ if (this.dataLab) {
13541
+ response = await this.getDataLabResponse({
13542
+ bounds: curCell.GetBounds(),
13543
+ pageIndex: curCell.FetchPageIndex,
13544
+ pageSize: PAGE_SIZE,
13545
+ abortSignal: abortController.signal
13546
+ });
13547
+ }
13226
13548
  // API gave us a URL to use.
13227
- if (curCell.FetchURL) {
13549
+ else if (curCell.FetchURL) {
13228
13550
  const tmpResponse = await this.api.get(curCell.FetchURL, {
13229
13551
  abortSignal: abortController.signal,
13230
13552
  noCache: true
@@ -13494,6 +13816,9 @@ function createFilterGetterCacheKey(params) {
13494
13816
  cacheKey += params.historicAttrKey ? params.historicAttrKey : "";
13495
13817
  cacheKey += params.historic ? "true" : "false";
13496
13818
  cacheKey += params.scenario ? params.scenario : 0;
13819
+ if (params.dataLab) {
13820
+ cacheKey += JSON.stringify(params.dataLab);
13821
+ }
13497
13822
  if (params.historicAttrKey) {
13498
13823
  cacheKey += params.historicInterpolation ? "true" : "false";
13499
13824
  }
@@ -13525,6 +13850,7 @@ var SharedGetters;
13525
13850
  historicInterpolation: params.historicInterpolation,
13526
13851
  viaCdn: params.cdn,
13527
13852
  scenario: params.scenario,
13853
+ dataLab: params.dataLab,
13528
13854
  });
13529
13855
  this.data[cacheKey] = getter;
13530
13856
  /**
@@ -14867,6 +15193,8 @@ var TilesetCadRenderManager;
14867
15193
  TilesetCadRenderManager.Manager = Manager;
14868
15194
  })(TilesetCadRenderManager || (TilesetCadRenderManager = {}));
14869
15195
 
15196
+ const BATCH_SIZE$3 = 500;
15197
+ const CHECK_BATCH_SIZE$2 = 250;
14870
15198
  var DataLabRenderManager;
14871
15199
  (function (DataLabRenderManager) {
14872
15200
  class Manager {
@@ -14875,7 +15203,18 @@ var DataLabRenderManager;
14875
15203
  }
14876
15204
  constructor(params) {
14877
15205
  this.getter = null;
15206
+ this.getterSub = null;
14878
15207
  this.disposed = false;
15208
+ this.renderedEntities = {};
15209
+ this.entityCheckQueue = null;
15210
+ this.entityCheckQueueIds = [];
15211
+ this.isRunningCheck = false;
15212
+ this.viewMonitorRemoval = null;
15213
+ this.renderQueue = [];
15214
+ this.renderQueueInterval = null;
15215
+ this.reRenderState = new EntityReRenderMaintainState();
15216
+ this.zoomControl = [];
15217
+ this.queryLoadId = 0;
14879
15218
  const { viewer, item, apiGetter, monitor, visualsRegister } = params;
14880
15219
  this.viewer = viewer;
14881
15220
  this.item = item;
@@ -14883,13 +15222,54 @@ var DataLabRenderManager;
14883
15222
  this.monitor = monitor;
14884
15223
  this.visualsManager = visualsRegister;
14885
15224
  }
14886
- Init() {
15225
+ Init(params) {
14887
15226
  var _a;
14888
15227
  if (this.disposed) {
14889
15228
  throw new Error("This manager has already been disposed.");
14890
15229
  }
14891
- if (!((_a = this.item.CameraZoomSettings) === null || _a === void 0 ? void 0 : _a.length)) {
14892
- this.item.CameraZoomSettings = [
15230
+ if (params === null || params === void 0 ? void 0 : params.item) {
15231
+ this.item = params.item;
15232
+ }
15233
+ this.queryLoadId += 1;
15234
+ const loadId = this.queryLoadId;
15235
+ this.unsetGetter();
15236
+ (_a = this.viewMonitorRemoval) === null || _a === void 0 ? void 0 : _a.call(this);
15237
+ this.viewMonitorRemoval = null;
15238
+ clearInterval(this.renderQueueInterval);
15239
+ this.renderQueueInterval = null;
15240
+ this.renderQueue = [];
15241
+ this.renderedEntities = {};
15242
+ this.ensureSettings();
15243
+ this.visualsManager.RemoveRegos({
15244
+ menuItemId: this.item.id
15245
+ });
15246
+ this.setEntityCheckQueue();
15247
+ (async () => {
15248
+ var _a, _b, _c, _d;
15249
+ try {
15250
+ const { query } = await DataLab.Get({
15251
+ api: this.apiGetter.getApi(),
15252
+ queryId: this.item.DataLabQueryID,
15253
+ req: {
15254
+ noCache: true
15255
+ }
15256
+ });
15257
+ if (this.disposed || loadId != this.queryLoadId) {
15258
+ return;
15259
+ }
15260
+ const queryItems = (_d = (_b = (_a = query === null || query === void 0 ? void 0 : query.PrimarySelectionCriteria) === null || _a === void 0 ? void 0 : _a.Items) !== null && _b !== void 0 ? _b : (_c = query === null || query === void 0 ? void 0 : query[DataLab.EReqKey.Primary]) === null || _c === void 0 ? void 0 : _c.Items) !== null && _d !== void 0 ? _d : [];
15261
+ this.setGetter(queryItems);
15262
+ }
15263
+ catch (e) {
15264
+ console.error("Failed to initialise DataLab render manager:", e);
15265
+ }
15266
+ })();
15267
+ }
15268
+ ensureSettings() {
15269
+ var _a;
15270
+ this.zoomControl = this.item.CameraZoomSettings;
15271
+ if (!((_a = this.zoomControl) === null || _a === void 0 ? void 0 : _a.length)) {
15272
+ this.zoomControl = [
14893
15273
  {
14894
15274
  MinZoom: 0,
14895
15275
  MaxZoom: 200000,
@@ -14899,17 +15279,74 @@ var DataLabRenderManager;
14899
15279
  StyleID: 0
14900
15280
  }
14901
15281
  ];
15282
+ this.item.CameraZoomSettings = this.zoomControl;
14902
15283
  }
14903
15284
  this.renderPriority = this.item.renderPriority;
14904
15285
  if (this.renderPriority == null) {
14905
15286
  this.renderPriority = 3;
14906
15287
  }
14907
- // Perform the initial query and subscribe to updates
14908
- this.getter = new BatchedDataGetter.Getter([this.item.DataLabQueryID], this.monitor, 1);
14909
- this.getter.OnUpdate.Subscribe((queryIds) => {
14910
- this.onGetterUpdate(queryIds[0]);
15288
+ }
15289
+ setGetter(queryItems) {
15290
+ this.unsetGetter();
15291
+ this.getter = new EntityFilterGetter.Getter({
15292
+ api: this.apiGetter.getApi(),
15293
+ attrFilter: {},
15294
+ batchSize: BATCH_SIZE$3,
15295
+ typeIds: null,
15296
+ viewPort: this.monitor,
15297
+ viewer: this.viewer,
15298
+ dataLab: {
15299
+ queryItems: queryItems !== null && queryItems !== void 0 ? queryItems : []
15300
+ }
15301
+ });
15302
+ const minMax = RenderManager.GetZoomMinMax({
15303
+ zoomControl: this.zoomControl
15304
+ });
15305
+ this.getter.IncludeMenuItem(this.item.id, null, [], minMax[0], minMax[1]);
15306
+ this.getterSub = this.getter.OnUpdate.Subscribe((data) => {
15307
+ var _a;
15308
+ if (!((_a = data === null || data === void 0 ? void 0 : data.entities) === null || _a === void 0 ? void 0 : _a.length)) {
15309
+ return;
15310
+ }
15311
+ this.distributeForRender(data.entities);
15312
+ });
15313
+ }
15314
+ unsetGetter() {
15315
+ var _a, _b, _c;
15316
+ (_a = this.getter) === null || _a === void 0 ? void 0 : _a.ExcludeMenuItem(this.item.id);
15317
+ (_b = this.getterSub) === null || _b === void 0 ? void 0 : _b.call(this);
15318
+ this.getterSub = null;
15319
+ (_c = this.getter) === null || _c === void 0 ? void 0 : _c.Dispose();
15320
+ this.getter = null;
15321
+ }
15322
+ setEntityCheckQueue() {
15323
+ var _a, _b;
15324
+ (_a = this.entityCheckQueue) === null || _a === void 0 ? void 0 : _a.Dispose();
15325
+ this.entityCheckQueue = null;
15326
+ const displayItems = this.zoomControl ? this.zoomControl.filter(x => x.DisplayType != ZoomControl.EDisplayType.Hidden) : [];
15327
+ const shouldCheck = displayItems.length > 1;
15328
+ this.entityCheckQueue = new DelayQueue(() => {
15329
+ this.doEntityCheck(Object.keys(this.renderedEntities));
15330
+ }, shouldCheck ? 3000 : 30000);
15331
+ (_b = this.viewMonitorRemoval) === null || _b === void 0 ? void 0 : _b.call(this);
15332
+ this.viewMonitorRemoval = this.monitor.Updated().Subscribe(() => {
15333
+ var _a;
15334
+ (_a = this.entityCheckQueue) === null || _a === void 0 ? void 0 : _a.Call();
14911
15335
  });
14912
- this.getter.Start();
15336
+ }
15337
+ preventCurrentCheckApiRefresh(entityIds) {
15338
+ var _a;
15339
+ this.reRenderState.markSkipForCurrentRun(entityIds, this.isRunningCheck);
15340
+ if ((_a = this.entityCheckQueueIds) === null || _a === void 0 ? void 0 : _a.length) {
15341
+ const lookup = {};
15342
+ for (let i = 0; i < entityIds.length; i++) {
15343
+ const id = entityIds[i];
15344
+ if (id) {
15345
+ lookup[id] = true;
15346
+ }
15347
+ }
15348
+ this.entityCheckQueueIds = this.entityCheckQueueIds.filter(id => !lookup[id]);
15349
+ }
14913
15350
  }
14914
15351
  Dispose() {
14915
15352
  if (this.disposed) {
@@ -14918,321 +15355,293 @@ var DataLabRenderManager;
14918
15355
  this.doDispose();
14919
15356
  }
14920
15357
  doDispose() {
14921
- var _a;
15358
+ var _a, _b;
14922
15359
  this.disposed = true;
14923
- (_a = this.getter) === null || _a === void 0 ? void 0 : _a.Dispose();
15360
+ this.queryLoadId += 1;
15361
+ this.unsetGetter();
15362
+ (_a = this.entityCheckQueue) === null || _a === void 0 ? void 0 : _a.Dispose();
15363
+ this.entityCheckQueue = null;
15364
+ (_b = this.viewMonitorRemoval) === null || _b === void 0 ? void 0 : _b.call(this);
15365
+ this.viewMonitorRemoval = null;
15366
+ clearInterval(this.renderQueueInterval);
15367
+ this.renderQueueInterval = null;
15368
+ this.renderQueue = [];
15369
+ this.entityCheckQueueIds = [];
14924
15370
  this.visualsManager.RemoveRegos({
14925
15371
  menuItemId: this.item.id
14926
15372
  });
14927
15373
  }
14928
- async onGetterUpdate(queryId) {
14929
- var _a;
14930
- if (this.disposed || this.viewer.isDestroyed()) {
15374
+ async ReRender(params) {
15375
+ let { entityIds, force, entities, maintain } = params;
15376
+ if (this.disposed) {
14931
15377
  return;
14932
15378
  }
14933
- try {
14934
- const api = this.apiGetter.getApi();
14935
- const result = await DataLab.Get({ api, queryId });
14936
- const query = result.query;
14937
- const queryResult = await DataLab.Run({ api, query: {
14938
- [DataLab.EReqKey.Primary]: {
14939
- Items: ((_a = query === null || query === void 0 ? void 0 : query.PrimarySelectionCriteria) === null || _a === void 0 ? void 0 : _a.Items) || [],
14940
- }
14941
- } });
14942
- this.renderDataLabEntities(queryResult.entities || []);
15379
+ if (entities && !entityIds) {
15380
+ entityIds = entities.map(x => { var _a; return (_a = x.Bruce) === null || _a === void 0 ? void 0 : _a.ID; });
14943
15381
  }
14944
- catch (error) {
14945
- console.error("Failed to perform query or render DataLab entities:", error);
15382
+ if (entityIds == null) {
15383
+ entityIds = Object.keys(this.renderedEntities);
14946
15384
  }
14947
- }
14948
- async renderDataLabEntities(entities) {
14949
- if (this.disposed || this.viewer.isDestroyed()) {
15385
+ entityIds = entityIds.filter((x, index) => !!x && entityIds.indexOf(x) === index);
15386
+ if (!entityIds.length) {
14950
15387
  return;
14951
15388
  }
14952
- const { updated, entities: cEntities } = await EntityRenderEngine.Render({
14953
- viewer: this.viewer,
14954
- apiGetter: this.apiGetter,
14955
- entities,
14956
- menuItemId: this.item.id,
14957
- visualRegister: this.visualsManager,
14958
- zoomControl: this.item.CameraZoomSettings
15389
+ if (entities === null || entities === void 0 ? void 0 : entities.length) {
15390
+ entities = [].concat(entities).filter(x => { var _a; return entityIds.includes((_a = x.Bruce) === null || _a === void 0 ? void 0 : _a.ID); });
15391
+ if (force) {
15392
+ this.reRenderState.bumpApiRevisions(entityIds);
15393
+ this.preventCurrentCheckApiRefresh(entityIds);
15394
+ }
15395
+ }
15396
+ if (maintain === true && (entities === null || entities === void 0 ? void 0 : entities.length)) {
15397
+ this.reRenderState.setMaintainedEntities(entities);
15398
+ }
15399
+ else if (maintain !== true) {
15400
+ this.reRenderState.clearMaintainedEntities(entityIds);
15401
+ }
15402
+ this.visualsManager.MarkStale({
15403
+ entityIds: entityIds,
15404
+ menuItemIds: [this.item.id]
14959
15405
  });
14960
- for (let i = 0; i < entities.length; i++) {
14961
- const entity = entities[i];
14962
- const id = entity.Bruce.ID;
14963
- const cEntity = cEntities.get(id);
14964
- if (cEntity) {
14965
- const rego = this.visualsManager.GetRego({
14966
- entityId: id,
14967
- menuItemId: this.item.id
14968
- });
14969
- if (!rego) {
14970
- this.visualsManager.AddRego({
14971
- rego: {
14972
- canEdit: true,
14973
- entityId: id,
14974
- menuItemId: this.item.id,
14975
- menuItemType: this.item.Type,
14976
- visual: cEntity,
14977
- priority: this.renderPriority,
14978
- entityTypeId: entity.Bruce["EntityType.ID"],
14979
- accountId: this.apiGetter.accountId,
14980
- name: cEntity.name
14981
- },
14982
- requestRender: false
14983
- });
14984
- }
15406
+ if (entities === null || entities === void 0 ? void 0 : entities.length) {
15407
+ if (force) {
15408
+ await this.renderDataLabEntities(entities, true);
14985
15409
  }
14986
15410
  else {
14987
- this.visualsManager.RemoveRegos({
14988
- entityId: id,
14989
- menuItemId: this.item.id,
14990
- requestRender: false
14991
- });
15411
+ this.distributeForRender(entities);
14992
15412
  }
14993
15413
  }
14994
- this.viewer.scene.requestRender();
15414
+ else {
15415
+ await this.doEntityCheck(entityIds, force);
15416
+ }
14995
15417
  }
14996
- async ReRender() {
15418
+ UpdateSettings(params) {
15419
+ const { zoomControl, queueRerender } = params;
14997
15420
  if (this.disposed) {
14998
15421
  return;
14999
15422
  }
15000
- // Re-perform the query and render again
15001
- await this.onGetterUpdate(this.item.DataLabQueryID);
15002
- }
15003
- }
15004
- DataLabRenderManager.Manager = Manager;
15005
- })(DataLabRenderManager || (DataLabRenderManager = {}));
15006
-
15007
- const DEFAULT_GROUNDED_HEIGHT = 300;
15008
- const MINIMUM_VIEW_AREA_SIZE_DEGREES = 0.01;
15009
- const NET_STEP_PERCENT = 5;
15010
- const BORDER_STEPS = 3;
15011
- function isDefined(value) {
15012
- return value !== null && value !== undefined;
15013
- }
15014
- function netScanViewForBoundaries(viewer, center) {
15015
- let maxLong = -2 * Math.PI;
15016
- let minLong = 2 * Math.PI;
15017
- let maxLat = -2 * Math.PI;
15018
- let minLat = 2 * Math.PI;
15019
- let found = 0;
15020
- const updateMinMax = (lon, lat) => {
15021
- if (lon < -Math.PI || lon > Math.PI || lat < -Math.PI / 2 || lat > Math.PI / 2) {
15022
- return;
15023
- }
15024
- maxLong = Math.max(maxLong, lon);
15025
- maxLat = Math.max(maxLat, lat);
15026
- minLong = Math.min(minLong, lon);
15027
- minLat = Math.min(minLat, lat);
15028
- };
15029
- const updateMinMaxForPoint = (stepX, stepY) => {
15030
- const x = Math.round((viewer.container.clientWidth / 100) * (stepX * NET_STEP_PERCENT));
15031
- const y = Math.round((viewer.container.clientHeight / 100) * (stepY * NET_STEP_PERCENT));
15032
- const winPos = new Cartesian2(x, y);
15033
- try {
15034
- const intersection = getAdjustedGroundIntersectionOfCameraRay(viewer, winPos);
15035
- if (intersection) {
15036
- const point = Cartographic.fromCartesian(intersection, viewer.scene.globe.ellipsoid);
15037
- updateMinMax(point.longitude, point.latitude);
15038
- found++;
15423
+ if (zoomControl === null || zoomControl === void 0 ? void 0 : zoomControl.length) {
15424
+ this.zoomControl = zoomControl;
15425
+ this.item.CameraZoomSettings = zoomControl;
15426
+ this.setEntityCheckQueue();
15427
+ }
15428
+ if (queueRerender != false) {
15429
+ const entityIds = Object.keys(this.renderedEntities);
15430
+ this.visualsManager.MarkStale({
15431
+ entityIds,
15432
+ menuItemIds: [this.item.id]
15433
+ });
15434
+ this.doEntityCheck(entityIds);
15039
15435
  }
15040
15436
  }
15041
- catch (e) {
15042
- console.error(e);
15043
- }
15044
- };
15045
- updateMinMaxForPoint(BORDER_STEPS, BORDER_STEPS);
15046
- updateMinMaxForPoint((100 / NET_STEP_PERCENT) - BORDER_STEPS, BORDER_STEPS);
15047
- updateMinMaxForPoint(BORDER_STEPS, (100 / NET_STEP_PERCENT) - BORDER_STEPS);
15048
- updateMinMaxForPoint((100 / NET_STEP_PERCENT) - BORDER_STEPS, (100 / NET_STEP_PERCENT) - BORDER_STEPS);
15049
- updateMinMaxForPoint(BORDER_STEPS * 2, BORDER_STEPS * 2);
15050
- updateMinMaxForPoint((100 / NET_STEP_PERCENT) - BORDER_STEPS * 2, BORDER_STEPS * 2);
15051
- updateMinMaxForPoint(BORDER_STEPS * 2, (100 / NET_STEP_PERCENT) - BORDER_STEPS * 2);
15052
- updateMinMaxForPoint((100 / NET_STEP_PERCENT) - BORDER_STEPS * 2, (100 / NET_STEP_PERCENT) - BORDER_STEPS * 2);
15053
- if (center && found <= 0) {
15054
- updateMinMax(Math$1.toRadians(center.longitude), Math$1.toRadians(center.latitude));
15055
- found += 1;
15056
- const size = viewer.camera.positionCartographic.height;
15057
- const pitch = viewer.camera.pitch;
15058
- const distance = size / Math.tan(pitch);
15059
- const p1 = offsetPoint({
15060
- altitude: center.altitude,
15061
- latitude: center.latitude,
15062
- longitude: center.longitude
15063
- }, distance, 45);
15064
- const p2 = offsetPoint({
15065
- altitude: center.altitude,
15066
- latitude: center.latitude,
15067
- longitude: center.longitude
15068
- }, -distance, 45);
15069
- if (isDefined(p1 === null || p1 === void 0 ? void 0 : p1.latitude) && isDefined(p1 === null || p1 === void 0 ? void 0 : p1.longitude)) {
15070
- updateMinMax(Math$1.toRadians(p1.longitude), Math$1.toRadians(p1.latitude));
15071
- }
15072
- if (isDefined(p2 === null || p2 === void 0 ? void 0 : p2.latitude) && isDefined(p2 === null || p2 === void 0 ? void 0 : p2.longitude)) {
15073
- updateMinMax(Math$1.toRadians(p2.longitude), Math$1.toRadians(p2.latitude));
15074
- }
15075
- }
15076
- if (found > 0) {
15077
- return {
15078
- east: maxLong,
15079
- west: minLong,
15080
- north: maxLat,
15081
- south: minLat
15082
- };
15083
- }
15084
- return null;
15085
- }
15086
- function offsetPoint(point, distance, heading) {
15087
- const radius = 6371e3;
15088
- const delta = distance / radius;
15089
- const theta = Math$1.toRadians(heading);
15090
- const phi1 = Math$1.toRadians(point.latitude);
15091
- const lambda1 = Math$1.toRadians(point.longitude);
15092
- const sinPhi2 = Math.sin(phi1) * Math.cos(delta) + Math.cos(phi1) * Math.sin(delta) * Math.cos(theta);
15093
- const phi2 = Math.asin(sinPhi2);
15094
- const y = Math.sin(theta) * Math.sin(delta) * Math.cos(phi1);
15095
- const x = Math.cos(delta) - Math.sin(phi1) * sinPhi2;
15096
- const lambda2 = lambda1 + Math.atan2(y, x);
15097
- return {
15098
- altitude: point.altitude,
15099
- latitude: Math$1.toDegrees(phi2),
15100
- longitude: Math$1.toDegrees(lambda2)
15101
- };
15102
- }
15103
- function offsetPos3d(pos3d, distance, heading) {
15104
- const carto = Cartographic.fromCartesian(pos3d);
15105
- const newCarto = offsetPoint({
15106
- altitude: carto.height,
15107
- latitude: Math$1.toDegrees(carto.latitude),
15108
- longitude: Math$1.toDegrees(carto.longitude)
15109
- }, distance, heading);
15110
- return Cartesian3.fromDegrees(newCarto.longitude, newCarto.latitude, newCarto.altitude);
15111
- }
15112
- function getAdjustedGroundIntersectionOfCameraRay(viewer, screenPos) {
15113
- const ray = viewer.camera.getPickRay(screenPos);
15114
- const intersection = ray ? viewer.scene.globe.pick(ray, viewer.scene) : null;
15115
- return intersection || null;
15116
- }
15117
- function getGroundCenterOfCameraRay(viewer, screenPos) {
15118
- var _a, _b;
15119
- const ray = viewer.camera.getPickRay(screenPos);
15120
- const intersection = ray ? viewer.scene.globe.pick(ray, viewer.scene) : null;
15121
- if (intersection) {
15122
- return intersection;
15123
- }
15124
- const cameraHeight = viewer.camera.positionCartographic.height;
15125
- if (!isNaN(cameraHeight) && isDefined(cameraHeight) && ((_b = (_a = viewer.camera) === null || _a === void 0 ? void 0 : _a.position) === null || _b === void 0 ? void 0 : _b.clone)) {
15126
- const cameraPos3d = viewer.camera.position.clone();
15127
- const pitch = viewer.camera.pitch;
15128
- const distance = cameraHeight / Math.tan(pitch);
15129
- return offsetPos3d(cameraPos3d, -distance, Math$1.toDegrees(viewer.camera.heading));
15130
- }
15131
- return null;
15132
- }
15133
- var ViewGroundArea;
15134
- (function (ViewGroundArea) {
15135
- function ToBboxPolygon(bounds) {
15136
- return `${bounds.west},${bounds.south} ${bounds.west},${bounds.north} ${bounds.east},${bounds.north} ${bounds.east},${bounds.south}`;
15137
- }
15138
- ViewGroundArea.ToBboxPolygon = ToBboxPolygon;
15139
- function NormalizeBounds(bounds, altitude) {
15140
- if (!bounds ||
15141
- !isDefined(bounds.east) ||
15142
- !isDefined(bounds.west) ||
15143
- !isDefined(bounds.north) ||
15144
- !isDefined(bounds.south)) {
15145
- return null;
15146
- }
15147
- const viewRect = { ...bounds };
15148
- const centerLong = (viewRect.east + viewRect.west) / 2;
15149
- const centerLat = (viewRect.north + viewRect.south) / 2;
15150
- viewRect.east = Math.max(viewRect.east, centerLong + (MINIMUM_VIEW_AREA_SIZE_DEGREES / 2));
15151
- viewRect.west = Math.min(viewRect.west, centerLong - (MINIMUM_VIEW_AREA_SIZE_DEGREES / 2));
15152
- viewRect.south = Math.min(viewRect.south, centerLat - (MINIMUM_VIEW_AREA_SIZE_DEGREES / 2));
15153
- viewRect.north = Math.max(viewRect.north, centerLat + (MINIMUM_VIEW_AREA_SIZE_DEGREES / 2));
15154
- if (isDefined(altitude)) {
15155
- viewRect.alt = altitude;
15156
- }
15157
- return viewRect;
15158
- }
15159
- ViewGroundArea.NormalizeBounds = NormalizeBounds;
15160
- async function GetViewArea(viewer) {
15161
- var _a, _b;
15162
- if (!viewer || viewer.isDestroyed()) {
15163
- return null;
15164
- }
15165
- if (!viewer.container || ((_a = viewer.container.style) === null || _a === void 0 ? void 0 : _a.display) == "none") {
15166
- return null;
15167
- }
15168
- let viewRect = null;
15169
- let center = null;
15170
- const camera = viewer.camera;
15171
- const terrData = await DrawingUtils.GetTerrainHeight({
15172
- pos3d: camera.position,
15173
- viewer
15174
- });
15175
- const cameraPosition = viewer.camera.positionCartographic;
15176
- const terrHeight = terrData.error ? cameraPosition.height + DEFAULT_GROUNDED_HEIGHT : terrData.height;
15177
- if (terrHeight && ((cameraPosition.height - terrHeight) < DEFAULT_GROUNDED_HEIGHT)) {
15178
- viewRect = {};
15179
- const viewRectRad = netScanViewForBoundaries(viewer);
15180
- if (viewRectRad &&
15181
- isDefined(viewRectRad.east) &&
15182
- isDefined(viewRectRad.west) &&
15183
- isDefined(viewRectRad.north) &&
15184
- isDefined(viewRectRad.south)) {
15185
- viewRect.east = Math$1.toDegrees(Math.max(viewRectRad.east, cameraPosition.longitude));
15186
- viewRect.west = Math$1.toDegrees(Math.min(viewRectRad.west, cameraPosition.longitude));
15187
- viewRect.south = Math$1.toDegrees(Math.min(viewRectRad.south, cameraPosition.latitude));
15188
- viewRect.north = Math$1.toDegrees(Math.max(viewRectRad.north, cameraPosition.latitude));
15437
+ async doEntityCheck(ids, force = false) {
15438
+ var _a, _b, _c, _d;
15439
+ if (this.isRunningCheck) {
15440
+ this.entityCheckQueueIds = this.entityCheckQueueIds.concat(ids);
15441
+ (_a = this.entityCheckQueue) === null || _a === void 0 ? void 0 : _a.Call();
15442
+ return;
15189
15443
  }
15190
- else {
15191
- viewRect.east = Math$1.toDegrees(cameraPosition.longitude);
15192
- viewRect.west = Math$1.toDegrees(cameraPosition.longitude);
15193
- viewRect.south = Math$1.toDegrees(cameraPosition.latitude);
15194
- viewRect.north = Math$1.toDegrees(cameraPosition.latitude);
15444
+ ids = ids.concat(this.entityCheckQueueIds);
15445
+ this.entityCheckQueueIds = [];
15446
+ ids = ids.filter((id, index) => {
15447
+ return id && ids.indexOf(id) === index;
15448
+ });
15449
+ if (!ids.length) {
15450
+ return;
15451
+ }
15452
+ this.isRunningCheck = true;
15453
+ const runId = this.reRenderState.startCheckRun();
15454
+ const api = this.apiGetter.getApi();
15455
+ try {
15456
+ if (this.disposed) {
15457
+ return;
15458
+ }
15459
+ const maintained = this.reRenderState.getMaintainedEntities(ids);
15460
+ const maintainedLookup = {};
15461
+ for (let i = 0; i < maintained.length; i++) {
15462
+ const id = (_c = (_b = maintained[i]) === null || _b === void 0 ? void 0 : _b.Bruce) === null || _c === void 0 ? void 0 : _c.ID;
15463
+ if (id) {
15464
+ maintainedLookup[id] = true;
15465
+ }
15466
+ }
15467
+ if (maintained.length) {
15468
+ if (force) {
15469
+ await this.renderDataLabEntities(maintained, true);
15470
+ }
15471
+ else {
15472
+ this.distributeForRender(maintained);
15473
+ }
15474
+ }
15475
+ let apiIds = ids.filter((id) => {
15476
+ return !maintainedLookup[id] && !this.reRenderState.shouldSkipInRun(id, runId);
15477
+ });
15478
+ const checkBatch = async () => {
15479
+ apiIds = this.reRenderState.filterNonSkippedIds(apiIds, runId);
15480
+ const entityIds = apiIds.splice(0, CHECK_BATCH_SIZE$2);
15481
+ if (!entityIds.length) {
15482
+ return;
15483
+ }
15484
+ const revisions = this.reRenderState.captureApiRevisions(entityIds);
15485
+ const { entities } = await Entity$1.GetListByIds({
15486
+ api,
15487
+ entityIds,
15488
+ expandSources: true,
15489
+ expandLocation: true,
15490
+ migrated: true,
15491
+ maxSearchTimeSec: 60 * 2
15492
+ });
15493
+ if (this.disposed) {
15494
+ return;
15495
+ }
15496
+ const resolved = this.reRenderState.filterCurrentApiEntities({
15497
+ entities,
15498
+ revisions,
15499
+ runId
15500
+ });
15501
+ if (resolved.length) {
15502
+ if (force) {
15503
+ await this.renderDataLabEntities(resolved, true);
15504
+ }
15505
+ else {
15506
+ this.distributeForRender(resolved);
15507
+ }
15508
+ }
15509
+ };
15510
+ while (apiIds.length > 0) {
15511
+ await checkBatch();
15512
+ }
15513
+ }
15514
+ catch (e) {
15515
+ console.error(e);
15516
+ }
15517
+ finally {
15518
+ this.isRunningCheck = false;
15519
+ if (this.entityCheckQueueIds.length) {
15520
+ (_d = this.entityCheckQueue) === null || _d === void 0 ? void 0 : _d.Call(true);
15521
+ }
15195
15522
  }
15196
- center = {
15197
- altitude: camera.positionCartographic.height,
15198
- latitude: Math$1.toDegrees(camera.positionCartographic.latitude),
15199
- longitude: Math$1.toDegrees(camera.positionCartographic.longitude)
15200
- };
15201
15523
  }
15202
- else {
15203
- const windowPosition = new Cartesian2(viewer.container.clientWidth / 2, viewer.container.clientHeight / 2);
15204
- const intersection = getGroundCenterOfCameraRay(viewer, windowPosition);
15205
- let point = null;
15206
- if (intersection) {
15207
- point = Cartographic.fromCartesian(intersection, viewer.scene.globe.ellipsoid);
15524
+ distributeForRender(entities) {
15525
+ if (this.disposed || !(entities === null || entities === void 0 ? void 0 : entities.length)) {
15526
+ return;
15208
15527
  }
15209
- if (point) {
15210
- center = {
15211
- altitude: point.height,
15212
- latitude: Math$1.toDegrees(point.latitude),
15213
- longitude: Math$1.toDegrees(point.longitude)
15214
- };
15215
- const viewRectRad = netScanViewForBoundaries(viewer, center);
15216
- if (viewRectRad) {
15217
- viewRect = {};
15218
- viewRect.east = Math$1.toDegrees(viewRectRad.east);
15219
- viewRect.west = Math$1.toDegrees(viewRectRad.west);
15220
- viewRect.south = Math$1.toDegrees(viewRectRad.south);
15221
- viewRect.north = Math$1.toDegrees(viewRectRad.north);
15528
+ this.renderQueue = this.renderQueue.concat(entities);
15529
+ if (!this.renderQueueInterval && this.renderQueue.length) {
15530
+ this.renderQueueInterval = setInterval(() => {
15531
+ const batch = this.deduplicateEntities(this.renderQueue.splice(0, BATCH_SIZE$3));
15532
+ this.renderDataLabEntities(batch);
15533
+ if (this.renderQueue.length <= 0) {
15534
+ clearInterval(this.renderQueueInterval);
15535
+ this.renderQueueInterval = null;
15536
+ }
15537
+ }, 50);
15538
+ }
15539
+ }
15540
+ deduplicateEntities(entities) {
15541
+ var _a;
15542
+ const entityMap = new Map();
15543
+ for (let i = 0; i < entities.length; i++) {
15544
+ const entity = entities[i];
15545
+ const id = (_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID;
15546
+ if (id) {
15547
+ entityMap.set(id, entity);
15222
15548
  }
15223
15549
  }
15550
+ return Array.from(entityMap.values());
15224
15551
  }
15225
- viewRect = NormalizeBounds(viewRect, (_b = viewer.scene.camera.positionCartographic) === null || _b === void 0 ? void 0 : _b.height);
15226
- if (center && viewRect) {
15227
- return {
15228
- bounds: viewRect,
15229
- target: center
15230
- };
15552
+ async renderDataLabEntities(entities, force = false) {
15553
+ var _a, _b, _c;
15554
+ if (this.disposed || this.viewer.isDestroyed() || !(entities === null || entities === void 0 ? void 0 : entities.length)) {
15555
+ return;
15556
+ }
15557
+ try {
15558
+ const { updated, entities: cEntities } = await EntityRenderEngine.Render({
15559
+ viewer: this.viewer,
15560
+ apiGetter: this.apiGetter,
15561
+ entities,
15562
+ menuItemId: this.item.id,
15563
+ visualRegister: this.visualsManager,
15564
+ zoomControl: this.zoomControl,
15565
+ force
15566
+ });
15567
+ if (this.disposed) {
15568
+ return;
15569
+ }
15570
+ for (let i = 0; i < entities.length; i++) {
15571
+ const entity = entities[i];
15572
+ const id = entity.Bruce.ID;
15573
+ const cEntity = cEntities.get(id);
15574
+ this.renderedEntities[id] = !!cEntity;
15575
+ if (cEntity) {
15576
+ const rego = this.visualsManager.GetRego({
15577
+ entityId: id,
15578
+ menuItemId: this.item.id
15579
+ });
15580
+ const canEdit = !((_a = entity.Bruce.Outline) === null || _a === void 0 ? void 0 : _a.find(x => x.Baseline && !x.Editable));
15581
+ const visual = rego === null || rego === void 0 ? void 0 : rego.visual;
15582
+ if (!visual || visual != cEntity) {
15583
+ this.visualsManager.AddRego({
15584
+ rego: {
15585
+ canEdit,
15586
+ entityId: id,
15587
+ schema: entity.Bruce.Schema,
15588
+ menuItemId: this.item.id,
15589
+ menuItemType: this.item.Type,
15590
+ visual: cEntity,
15591
+ priority: this.renderPriority,
15592
+ entityTypeId: entity.Bruce["EntityType.ID"],
15593
+ accountId: this.apiGetter.accountId,
15594
+ tagIds: entity.Bruce["Layer.ID"] ? [].concat(entity.Bruce["Layer.ID"]) : [],
15595
+ name: cEntity.name,
15596
+ cdn: this.item.cdnEnabled,
15597
+ outline: entity.Bruce.Outline
15598
+ },
15599
+ requestRender: false
15600
+ });
15601
+ }
15602
+ else if (updated.get(id) && rego) {
15603
+ rego.name = cEntity.name;
15604
+ rego.visual = cEntity;
15605
+ rego.entityTypeId = entity.Bruce["EntityType.ID"];
15606
+ rego.tagIds = entity.Bruce["Layer.ID"] ? [].concat(entity.Bruce["Layer.ID"]) : [];
15607
+ rego.outline = (_b = entity.Bruce) === null || _b === void 0 ? void 0 : _b.Outline;
15608
+ rego.cdn = this.item.cdnEnabled;
15609
+ rego.schema = (_c = entity.Bruce) === null || _c === void 0 ? void 0 : _c.Schema;
15610
+ rego.canEdit = canEdit;
15611
+ if (rego.stale) {
15612
+ this.visualsManager.RefreshMark({
15613
+ rego
15614
+ });
15615
+ this.visualsManager.ForceUpdate({
15616
+ entityIds: [id],
15617
+ refreshColors: true,
15618
+ requestRender: false
15619
+ });
15620
+ }
15621
+ this.visualsManager.OnUpdate.Trigger({
15622
+ type: VisualsRegister.EVisualUpdateType.Update,
15623
+ entityId: id,
15624
+ rego: rego
15625
+ });
15626
+ }
15627
+ }
15628
+ else {
15629
+ this.visualsManager.RemoveRegos({
15630
+ entityId: id,
15631
+ menuItemId: this.item.id,
15632
+ requestRender: false
15633
+ });
15634
+ }
15635
+ }
15636
+ this.viewer.scene.requestRender();
15637
+ }
15638
+ catch (e) {
15639
+ console.error("Failed to render DataLab entities:", e);
15640
+ }
15231
15641
  }
15232
- return null;
15233
15642
  }
15234
- ViewGroundArea.GetViewArea = GetViewArea;
15235
- })(ViewGroundArea || (ViewGroundArea = {}));
15643
+ DataLabRenderManager.Manager = Manager;
15644
+ })(DataLabRenderManager || (DataLabRenderManager = {}));
15236
15645
 
15237
15646
  const TIME_LAG = 300;
15238
15647
  const POSITION_CHECK_TIMER = 950;
@@ -15389,7 +15798,7 @@ var CesiumViewMonitor;
15389
15798
  })(CesiumViewMonitor || (CesiumViewMonitor = {}));
15390
15799
 
15391
15800
  const MAX_BATCHES = 2;
15392
- const BATCH_SIZE$3 = 1000;
15801
+ const BATCH_SIZE$4 = 1000;
15393
15802
  const BATCH_DELAY = 200;
15394
15803
  const MAX_RANGE = 3000;
15395
15804
  var TilesetOsmRenderManager;
@@ -15604,7 +16013,7 @@ var TilesetOsmRenderManager;
15604
16013
  const isClose = this.getIsVisualWithinRange(feature, MAX_RANGE);
15605
16014
  if (isClose) {
15606
16015
  batch.push(feature);
15607
- if (batch.length >= BATCH_SIZE$3) {
16016
+ if (batch.length >= BATCH_SIZE$4) {
15608
16017
  return batch;
15609
16018
  }
15610
16019
  }
@@ -15754,7 +16163,7 @@ var TilesetOsmRenderManager;
15754
16163
  delete this._loadedCesiumEntities[key];
15755
16164
  this.totalLoaded -= 1;
15756
16165
  removed += 1;
15757
- if (removed >= BATCH_SIZE$3) {
16166
+ if (removed >= BATCH_SIZE$4) {
15758
16167
  return true;
15759
16168
  }
15760
16169
  }
@@ -35541,7 +35950,7 @@ class WidgetViewBar extends Widget.AWidget {
35541
35950
  }
35542
35951
  }
35543
35952
 
35544
- const VERSION = "6.6.0";
35953
+ const VERSION = "6.6.1";
35545
35954
  /**
35546
35955
  * Updates the environment instance used by bruce-cesium to one specified.
35547
35956
  * This can be used to ensure that the instance a parent is referencing is shared between bruce-cesium, bruce-models, and the parent app.