bruce-cesium 7.1.6 → 7.1.7
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.
- package/dist/bruce-cesium.es5.js +1251 -1223
- package/dist/bruce-cesium.es5.js.map +1 -1
- package/dist/bruce-cesium.umd.js +1249 -1220
- package/dist/bruce-cesium.umd.js.map +1 -1
- package/dist/lib/bruce-cesium.js +1 -1
- package/dist/lib/rendering/view-render-engine.js +1 -0
- package/dist/lib/rendering/view-render-engine.js.map +1 -1
- package/dist/lib/utils/view-utils.js +26 -1
- package/dist/lib/utils/view-utils.js.map +1 -1
- package/dist/lib/viewer/viewer-utils.js +3 -0
- package/dist/lib/viewer/viewer-utils.js.map +1 -1
- package/dist/types/bruce-cesium.d.ts +1 -1
- package/dist/types/utils/view-utils.d.ts +7 -0
- package/package.json +4 -1
package/dist/bruce-cesium.es5.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as Cesium from 'cesium';
|
|
2
|
-
import { Cartographic, ColorMaterialProperty, Entity, Color, ConstantProperty, CallbackProperty, Primitive, Cesium3DTileFeature, ShaderSource, Cartesian3, Math as Math$1, Ellipsoid, Transforms, Matrix4, Geometry, GeometryAttribute, ComponentDatatype, PrimitiveType, BoundingSphere, GeometryPipeline, sampleTerrain, Texture, PixelFormat, Sampler, TextureWrap, TextureMinificationFilter, TextureMagnificationFilter, VertexArray, BufferUsage, ShaderProgram, RenderState, BlendingState, DrawCommand, Pass, Cartesian2, DistanceDisplayCondition,
|
|
3
|
-
import { Cartes, Entity as Entity$1, ENVIRONMENT, Calculator,
|
|
2
|
+
import { Cartographic, ColorMaterialProperty, Entity, Color, ConstantProperty, CallbackProperty, Primitive, Cesium3DTileFeature, ShaderSource, Cartesian3, Math as Math$1, Ellipsoid, Transforms, Matrix4, Geometry, GeometryAttribute, ComponentDatatype, PrimitiveType, BoundingSphere, GeometryPipeline, sampleTerrain, Texture, PixelFormat, Sampler, TextureWrap, TextureMinificationFilter, TextureMagnificationFilter, VertexArray, BufferUsage, ShaderProgram, RenderState, BlendingState, DrawCommand, Pass, Cartesian2, DistanceDisplayCondition, HeightReference, ColorBlendMode, HeadingPitchRoll, ShadowMode, ClassificationType, Model, HorizontalOrigin, VerticalOrigin, ConstantPositionProperty, JulianDate, Quaternion, ArcType, CornerType, ImageMaterialProperty, PolygonHierarchy, PolylineGraphics, Rectangle, SceneTransforms, NearFarScalar, Matrix3, KmlDataSource, GeoJsonDataSource, SceneMode, Cesium3DTileStyle, HeadingPitchRange, Ion, IonResource, Cesium3DTileColorBlendMode, EllipsoidTerrainProvider, IonImageryProvider, createWorldImagery, createWorldImageryAsync, BingMapsImageryProvider, BingMapsStyle, MapboxImageryProvider, MapboxStyleImageryProvider, ArcGisMapServerImageryProvider, OpenStreetMapImageryProvider, UrlTemplateImageryProvider, GridImageryProvider, GeographicTilingScheme, ImageryLayer, TileMapServiceImageryProvider, CesiumTerrainProvider, Cesium3DTileset, OrthographicFrustum, EasingFunction, Intersect, CustomDataSource, EllipsoidGeodesic, sampleTerrainMostDetailed, defined, PolygonPipeline, ModelGraphics, PolygonGraphics, CorridorGraphics, PointGraphics, BillboardGraphics, EllipseGraphics, PolylineDashMaterialProperty, CesiumInspector, ClockRange, GeometryInstance, ScreenSpaceEventHandler, ScreenSpaceEventType, Fullscreen, CzmlDataSource } from 'cesium';
|
|
3
|
+
import { Cartes, Entity as Entity$1, ProjectViewTile, ENVIRONMENT, Calculator, ClientFile, EntityLod, EntityTag, EntityType, LRUCache, ObjectUtils, Style, Api, Carto, Geometry as Geometry$1, MenuItem, ProjectView, ProjectViewBookmark, Tileset, ZoomControl, Bounds, Color as Color$1, BruceEvent, EntityCoords, DataLab, DelayQueue, EntityHistoricData, AccountConcept, RecordChangeFeed, BruceApi, EntityRelation, ProgramKey, EntitySource, ProjectViewLegacyTile, Camera, Account, AccountLimits, Session, UrlUtils, EntityAttachment, EntityAttachmentType, EntityAttribute, MathUtils, ProjectViewBookmarkGroup, EntityRelationType } from 'bruce-models';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Ensures a number is returned from a given value.
|
|
@@ -2674,184 +2674,909 @@ var CesiumEntityStyler;
|
|
|
2674
2674
|
CesiumEntityStyler.Unhighlight = Unhighlight;
|
|
2675
2675
|
})(CesiumEntityStyler || (CesiumEntityStyler = {}));
|
|
2676
2676
|
|
|
2677
|
+
function OnNextCRender(viewer, callback) {
|
|
2678
|
+
const removal = viewer.scene.postRender.addEventListener(() => {
|
|
2679
|
+
removal();
|
|
2680
|
+
callback();
|
|
2681
|
+
});
|
|
2682
|
+
}
|
|
2683
|
+
function GetCValue(viewer, obj) {
|
|
2684
|
+
if (obj === null || obj === void 0 ? void 0 : obj.getValue) {
|
|
2685
|
+
let date = viewer.scene.lastRenderTime;
|
|
2686
|
+
if (!date) {
|
|
2687
|
+
date = viewer.clock.currentTime;
|
|
2688
|
+
}
|
|
2689
|
+
return obj.getValue(date);
|
|
2690
|
+
}
|
|
2691
|
+
return obj;
|
|
2692
|
+
}
|
|
2693
|
+
/*
|
|
2694
|
+
* Marks an EntityCollection as one this library created and fully controls (a menu item's own data source).
|
|
2695
|
+
*/
|
|
2696
|
+
const OWNED_CCOLLECTION_KEY = "_bruceOwnedCollection";
|
|
2697
|
+
function MarkCCollectionOwned(collection) {
|
|
2698
|
+
if (collection) {
|
|
2699
|
+
collection[OWNED_CCOLLECTION_KEY] = true;
|
|
2700
|
+
}
|
|
2701
|
+
}
|
|
2702
|
+
function IsCCollectionOwned(collection) {
|
|
2703
|
+
return Boolean(collection && collection[OWNED_CCOLLECTION_KEY]);
|
|
2704
|
+
}
|
|
2677
2705
|
/**
|
|
2678
|
-
*
|
|
2706
|
+
* Runs a bulk collection mutation with every given collection's events suspended, so Cesium raises one
|
|
2707
|
+
* collectionChanged per collection for the whole pass instead of one per entity.
|
|
2708
|
+
*
|
|
2709
|
+
* Takes a set of collections rather than assuming `viewer.entities`, because managed visuals live in their menu
|
|
2710
|
+
* item's own data source: suspending the wrong collection silently does nothing.
|
|
2711
|
+
* @param collections Duplicates and empty entries are ignored.
|
|
2712
|
+
* @param run
|
|
2679
2713
|
*/
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
}
|
|
2686
|
-
get Viewer() {
|
|
2687
|
-
return this._viewer;
|
|
2688
|
-
}
|
|
2689
|
-
get Container() {
|
|
2690
|
-
return this._container;
|
|
2691
|
-
}
|
|
2692
|
-
get Element() {
|
|
2693
|
-
return this._element;
|
|
2694
|
-
}
|
|
2695
|
-
constructor(params) {
|
|
2696
|
-
this.widgetId = ObjectUtils.UId();
|
|
2697
|
-
let { viewer, container, manager } = params;
|
|
2698
|
-
// A host app can pass an undefined viewer (eg. mid-teardown); fall back to
|
|
2699
|
-
// no container rather than crashing on viewer.container.
|
|
2700
|
-
if (!container && viewer) {
|
|
2701
|
-
container = viewer.container;
|
|
2702
|
-
}
|
|
2703
|
-
this._viewer = viewer;
|
|
2704
|
-
this._manager = manager;
|
|
2705
|
-
this._container = container;
|
|
2706
|
-
this._apiGetters = params.apiGetters;
|
|
2707
|
-
if (viewer) {
|
|
2708
|
-
markViewerWithWidget(viewer, this.widgetId, this);
|
|
2709
|
-
}
|
|
2714
|
+
function WithSuspendedCCollections(collections, run) {
|
|
2715
|
+
const unique = [];
|
|
2716
|
+
for (const collection of collections) {
|
|
2717
|
+
if (collection && unique.indexOf(collection) === -1) {
|
|
2718
|
+
unique.push(collection);
|
|
2710
2719
|
}
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2720
|
+
}
|
|
2721
|
+
for (const collection of unique) {
|
|
2722
|
+
collection.suspendEvents();
|
|
2723
|
+
}
|
|
2724
|
+
try {
|
|
2725
|
+
return run();
|
|
2726
|
+
}
|
|
2727
|
+
finally {
|
|
2728
|
+
for (const collection of unique) {
|
|
2729
|
+
try {
|
|
2730
|
+
collection.resumeEvents();
|
|
2714
2731
|
}
|
|
2715
|
-
|
|
2716
|
-
|
|
2732
|
+
catch (e) {
|
|
2733
|
+
console.error(e);
|
|
2717
2734
|
}
|
|
2718
2735
|
}
|
|
2719
2736
|
}
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2737
|
+
}
|
|
2738
|
+
/**
|
|
2739
|
+
* Returns the collection a graphic belongs to, falling back to the viewer's own when it has never been added.
|
|
2740
|
+
* @param viewer
|
|
2741
|
+
* @param entity
|
|
2742
|
+
*/
|
|
2743
|
+
function GetCEntityCollection(viewer, entity) {
|
|
2744
|
+
const owner = entity === null || entity === void 0 ? void 0 : entity.entityCollection;
|
|
2745
|
+
return owner ? owner : viewer === null || viewer === void 0 ? void 0 : viewer.entities;
|
|
2746
|
+
}
|
|
2747
|
+
/**
|
|
2748
|
+
* Returns whether a graphic is currently in the scene, looking in whichever collection owns it.
|
|
2749
|
+
* @param viewer
|
|
2750
|
+
* @param entity
|
|
2751
|
+
*/
|
|
2752
|
+
function IsCEntityInScene(viewer, entity) {
|
|
2753
|
+
const collection = GetCEntityCollection(viewer, entity);
|
|
2754
|
+
return Boolean(collection && entity && collection.contains(entity));
|
|
2755
|
+
}
|
|
2756
|
+
/**
|
|
2757
|
+
* Removes a graphic from whichever collection owns it. Returns whether it removed anything.
|
|
2758
|
+
* @param viewer
|
|
2759
|
+
* @param entity
|
|
2760
|
+
*/
|
|
2761
|
+
function RemoveCEntityFromScene(viewer, entity) {
|
|
2762
|
+
var _a;
|
|
2763
|
+
if (!entity) {
|
|
2764
|
+
return false;
|
|
2726
2765
|
}
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
if (!viewer["_nextspaceWidgets"]) {
|
|
2731
|
-
viewer["_nextspaceWidgets"] = {};
|
|
2766
|
+
const collection = GetCEntityCollection(viewer, entity);
|
|
2767
|
+
if (collection === null || collection === void 0 ? void 0 : collection.contains(entity)) {
|
|
2768
|
+
return collection.remove(entity);
|
|
2732
2769
|
}
|
|
2733
|
-
viewer
|
|
2770
|
+
// A stale owner reference and the graphic ended up in the viewer's collection anyway.
|
|
2771
|
+
if (collection !== (viewer === null || viewer === void 0 ? void 0 : viewer.entities) && ((_a = viewer === null || viewer === void 0 ? void 0 : viewer.entities) === null || _a === void 0 ? void 0 : _a.contains(entity))) {
|
|
2772
|
+
return viewer.entities.remove(entity);
|
|
2773
|
+
}
|
|
2774
|
+
return false;
|
|
2734
2775
|
}
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2776
|
+
/**
|
|
2777
|
+
* Adds a graphic back into whichever collection owns it, or the viewer's if it has no owner yet.
|
|
2778
|
+
* @param viewer
|
|
2779
|
+
* @param entity
|
|
2780
|
+
*/
|
|
2781
|
+
function AddCEntityToScene(viewer, entity, fallbackCollection) {
|
|
2782
|
+
if (!entity) {
|
|
2783
|
+
return false;
|
|
2784
|
+
}
|
|
2785
|
+
// An existing owner always wins, so a graphic is never migrated out from under whoever holds it.
|
|
2786
|
+
const owner = entity.entityCollection;
|
|
2787
|
+
const collection = owner ? owner : (fallbackCollection ? fallbackCollection : viewer === null || viewer === void 0 ? void 0 : viewer.entities);
|
|
2788
|
+
if (!collection || collection.contains(entity)) {
|
|
2789
|
+
return false;
|
|
2738
2790
|
}
|
|
2791
|
+
collection.add(entity);
|
|
2792
|
+
return true;
|
|
2739
2793
|
}
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2794
|
+
/**
|
|
2795
|
+
* Returns whether toggling `show` on these graphics is safe, rather than having to add/remove them from the
|
|
2796
|
+
* entity collection to hide them.
|
|
2797
|
+
*
|
|
2798
|
+
* Toggling show is far cheaper than re-adding the graphic to the viewer however a Cesium bug means we can't always use it.
|
|
2799
|
+
* See: https://github.com/CesiumGS/cesium/issues/9370
|
|
2800
|
+
* @param parts The graphic and any sibling graphics, eg. from EntityUtils.GatherEntity.
|
|
2801
|
+
*/
|
|
2802
|
+
function CanToggleShowSafely(parts) {
|
|
2803
|
+
if (!(parts === null || parts === void 0 ? void 0 : parts.length)) {
|
|
2804
|
+
return false;
|
|
2805
|
+
}
|
|
2806
|
+
for (const part of parts) {
|
|
2807
|
+
if (!(part instanceof Entity)) {
|
|
2808
|
+
// Not an Entity, so not something whose `show` we can drive.
|
|
2809
|
+
return false;
|
|
2749
2810
|
}
|
|
2750
|
-
|
|
2751
|
-
return
|
|
2811
|
+
if (part.polyline && isTruthyCValue(part.polyline.clampToGround)) {
|
|
2812
|
+
return false;
|
|
2752
2813
|
}
|
|
2753
|
-
|
|
2754
|
-
|
|
2814
|
+
const materialGraphics = [part.polygon, part.corridor, part.ellipse, part.rectangle, part.wall, part.polylineVolume];
|
|
2815
|
+
for (const graphic of materialGraphics) {
|
|
2816
|
+
if (graphic && !isPlainColorMaterial(graphic.material)) {
|
|
2817
|
+
return false;
|
|
2818
|
+
}
|
|
2755
2819
|
}
|
|
2756
|
-
|
|
2757
|
-
|
|
2820
|
+
}
|
|
2821
|
+
return true;
|
|
2822
|
+
}
|
|
2823
|
+
/**
|
|
2824
|
+
* Returns whether a material is a plain colour, which is what keeps a graphic out of Cesium's per-material batches.
|
|
2825
|
+
* Anything unrecognised counts as not plain, so callers stay on the conservative side.
|
|
2826
|
+
* @param material
|
|
2827
|
+
*/
|
|
2828
|
+
function isPlainColorMaterial(material) {
|
|
2829
|
+
if (material == null) {
|
|
2830
|
+
// Cesium defaults an absent material to white, a plain colour.
|
|
2831
|
+
return true;
|
|
2832
|
+
}
|
|
2833
|
+
return material instanceof ColorMaterialProperty || material instanceof Color;
|
|
2834
|
+
}
|
|
2835
|
+
/**
|
|
2836
|
+
* Resolves a possibly-property boolean without needing a viewer clock, treating anything undeterminable as true
|
|
2837
|
+
* so callers stay on the conservative side.
|
|
2838
|
+
* @param value
|
|
2839
|
+
*/
|
|
2840
|
+
function isTruthyCValue(value) {
|
|
2841
|
+
if (value == null) {
|
|
2842
|
+
return false;
|
|
2843
|
+
}
|
|
2844
|
+
if (typeof value.getValue === "function") {
|
|
2845
|
+
if (value instanceof ConstantProperty) {
|
|
2846
|
+
return Boolean(value.valueOf());
|
|
2758
2847
|
}
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2848
|
+
// A non-constant property could be true at any moment, so assume it is.
|
|
2849
|
+
return true;
|
|
2850
|
+
}
|
|
2851
|
+
return Boolean(value);
|
|
2852
|
+
}
|
|
2853
|
+
/**
|
|
2854
|
+
* Returns if two resolved Cesium property values are equal, using the value's own equals() when it has one.
|
|
2855
|
+
* @param a
|
|
2856
|
+
* @param b
|
|
2857
|
+
*/
|
|
2858
|
+
function AreCValuesEqual(a, b) {
|
|
2859
|
+
if (a === b) {
|
|
2860
|
+
return true;
|
|
2861
|
+
}
|
|
2862
|
+
// One side is null/undefined and the other isn't.
|
|
2863
|
+
if (a == null || b == null) {
|
|
2864
|
+
return false;
|
|
2865
|
+
}
|
|
2866
|
+
if (typeof a.equals === "function") {
|
|
2867
|
+
return a.equals(b) === true;
|
|
2868
|
+
}
|
|
2869
|
+
return false;
|
|
2870
|
+
}
|
|
2871
|
+
/**
|
|
2872
|
+
* Wraps a value in a ConstantProperty and assigns it to a graphic's property, but only when the resolved
|
|
2873
|
+
* value actually differs. Returns whether it assigned.
|
|
2874
|
+
* @param params
|
|
2875
|
+
*/
|
|
2876
|
+
function SetCPropIfChanged(params) {
|
|
2877
|
+
const { viewer, graphic, property, value, compare } = params;
|
|
2878
|
+
if (!graphic) {
|
|
2879
|
+
return false;
|
|
2880
|
+
}
|
|
2881
|
+
const oldValue = GetCValue(viewer, graphic[property]);
|
|
2882
|
+
const isEqual = compare ? compare(oldValue, value) : AreCValuesEqual(oldValue, value);
|
|
2883
|
+
if (isEqual) {
|
|
2884
|
+
return false;
|
|
2885
|
+
}
|
|
2886
|
+
graphic[property] = new ConstantProperty(value);
|
|
2887
|
+
return true;
|
|
2888
|
+
}
|
|
2889
|
+
function ColorToCColor(color) {
|
|
2890
|
+
return new Color(color.red ? color.red / 255 : 0, color.green ? color.green / 255 : 0, color.blue ? color.blue / 255 : 0, color.alpha);
|
|
2891
|
+
}
|
|
2892
|
+
/**
|
|
2893
|
+
* Removes duplicate points in a row and returns a new array.
|
|
2894
|
+
* Passed array is not mutated.
|
|
2895
|
+
* @param posses
|
|
2896
|
+
*/
|
|
2897
|
+
function CullDuplicateCPosses(posses) {
|
|
2898
|
+
const newPosses = [];
|
|
2899
|
+
let lastPos = null;
|
|
2900
|
+
for (let i = 0; i < posses.length; i++) {
|
|
2901
|
+
const pos = posses[i];
|
|
2902
|
+
// Avoiding 'Cesium.Cartesian3.equals' because passed data might be just a json blob in certain cases.
|
|
2903
|
+
if (pos && (!lastPos || (pos.x != lastPos.x || pos.y != lastPos.y || pos.z != lastPos.z))) {
|
|
2904
|
+
newPosses.push(pos);
|
|
2905
|
+
lastPos = pos;
|
|
2766
2906
|
}
|
|
2767
|
-
|
|
2907
|
+
}
|
|
2908
|
+
return newPosses;
|
|
2909
|
+
}
|
|
2910
|
+
/**
|
|
2911
|
+
* Returns if the given positions are equal.
|
|
2912
|
+
* @param a
|
|
2913
|
+
* @param b
|
|
2914
|
+
*/
|
|
2915
|
+
function CompareCPosses(a, b) {
|
|
2916
|
+
// Same reference.
|
|
2917
|
+
if (a == b) {
|
|
2918
|
+
return true;
|
|
2919
|
+
}
|
|
2920
|
+
// Different lengths or one is null.
|
|
2921
|
+
if ((!a || !b) || (a.length != b.length)) {
|
|
2922
|
+
return false;
|
|
2923
|
+
}
|
|
2924
|
+
for (let i = 0; i < a.length; i++) {
|
|
2925
|
+
const posA = a[i];
|
|
2926
|
+
const posB = b[i];
|
|
2927
|
+
// Null detected.
|
|
2928
|
+
if (!posA || !posB) {
|
|
2929
|
+
return false;
|
|
2768
2930
|
}
|
|
2769
|
-
|
|
2770
|
-
|
|
2931
|
+
// Position values don't match.
|
|
2932
|
+
if (!Cartes.IsEqualCartes3(posA, posB)) {
|
|
2933
|
+
return false;
|
|
2771
2934
|
}
|
|
2772
2935
|
}
|
|
2773
|
-
|
|
2774
|
-
}
|
|
2775
|
-
|
|
2936
|
+
return true;
|
|
2937
|
+
}
|
|
2776
2938
|
/**
|
|
2777
|
-
*
|
|
2778
|
-
*
|
|
2939
|
+
* Returns if the given polygon hierarchies are equal.
|
|
2940
|
+
* @param a
|
|
2941
|
+
* @param b
|
|
2779
2942
|
*/
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2943
|
+
function CompareCPolygonHierarchies(a, b) {
|
|
2944
|
+
// Same reference.
|
|
2945
|
+
if (a == b) {
|
|
2946
|
+
return true;
|
|
2783
2947
|
}
|
|
2784
|
-
|
|
2785
|
-
|
|
2948
|
+
// Different lengths or one is null.
|
|
2949
|
+
if ((!a || !b) || (a.positions.length != b.positions.length)) {
|
|
2950
|
+
return false;
|
|
2786
2951
|
}
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
}
|
|
2952
|
+
// Positions don't match.
|
|
2953
|
+
if (!CompareCPosses(a.positions, b.positions)) {
|
|
2954
|
+
return false;
|
|
2955
|
+
}
|
|
2956
|
+
const holes = a.holes;
|
|
2957
|
+
const bHoles = b.holes;
|
|
2958
|
+
// Number of holes don't match.
|
|
2959
|
+
if (holes.length != bHoles.length) {
|
|
2960
|
+
return false;
|
|
2961
|
+
}
|
|
2962
|
+
for (let i = 0; i < holes.length; i++) {
|
|
2963
|
+
// Hole positions don't match.
|
|
2964
|
+
if (!CompareCPosses(holes[i].positions, bHoles[i].positions)) {
|
|
2965
|
+
return false;
|
|
2802
2966
|
}
|
|
2803
2967
|
}
|
|
2968
|
+
return true;
|
|
2804
2969
|
}
|
|
2805
2970
|
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2971
|
+
const CESIUM_INSPECTOR_KEY = "_nextspace_inspector";
|
|
2972
|
+
const CESIUM_TIMELINE_KEY = "_nextspace_timeline";
|
|
2973
|
+
const CESIUM_TIMELINE_LIVE_KEY = "_nextspace_timeline_live";
|
|
2974
|
+
const CESIUM_TIMELINE_LIVE_PADDING_KEY = "_nextspace_timeline_live_padding";
|
|
2975
|
+
const CESIUM_TIMELINE_INTERVAL_KEY = "_nextspace_timeline_interval";
|
|
2976
|
+
const CESIUM_MODEL_SPACE_KEY = "_nextspace_model_space";
|
|
2977
|
+
const DEFAULT_LIVE_PADDING_SECONDS = 30 * 60;
|
|
2978
|
+
const DEFAULT_BRIGHTNESS_SHIFT = 0.2;
|
|
2979
|
+
var ViewUtils;
|
|
2980
|
+
(function (ViewUtils) {
|
|
2981
|
+
function GatherLegacyMapTiles(params) {
|
|
2982
|
+
const viewer = params.viewer;
|
|
2983
|
+
const collection = viewer.imageryLayers;
|
|
2984
|
+
const tiles = [];
|
|
2985
|
+
for (let i = 0; i < collection.length; i++) {
|
|
2986
|
+
const layer = collection.get(i);
|
|
2987
|
+
if (layer._bName) {
|
|
2988
|
+
tiles.push({
|
|
2989
|
+
alpha: layer.alpha,
|
|
2990
|
+
brightness: layer.brightness,
|
|
2991
|
+
contrast: layer.contrast,
|
|
2992
|
+
hue: layer.hue,
|
|
2993
|
+
saturation: layer.saturation,
|
|
2994
|
+
gamma: layer.gamma,
|
|
2995
|
+
title: layer._bName,
|
|
2996
|
+
});
|
|
2997
|
+
}
|
|
2998
|
+
}
|
|
2999
|
+
return {
|
|
3000
|
+
imagery: tiles.reverse()
|
|
3001
|
+
};
|
|
2812
3002
|
}
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
3003
|
+
ViewUtils.GatherLegacyMapTiles = GatherLegacyMapTiles;
|
|
3004
|
+
function GatherLegacyTerrainTile(params) {
|
|
3005
|
+
const viewer = params.viewer;
|
|
3006
|
+
const enabled = viewer.terrainProvider;
|
|
3007
|
+
if (enabled === null || enabled === void 0 ? void 0 : enabled._bName) {
|
|
3008
|
+
return {
|
|
3009
|
+
terrain: enabled._bName
|
|
3010
|
+
};
|
|
2817
3011
|
}
|
|
2818
|
-
|
|
2819
|
-
|
|
3012
|
+
return {
|
|
3013
|
+
terrain: "flatterrain"
|
|
3014
|
+
};
|
|
3015
|
+
}
|
|
3016
|
+
ViewUtils.GatherLegacyTerrainTile = GatherLegacyTerrainTile;
|
|
3017
|
+
function GatherMapTiles(params) {
|
|
3018
|
+
const viewer = params.viewer;
|
|
3019
|
+
const imagery = viewer.imageryLayers;
|
|
3020
|
+
const tiles = [];
|
|
3021
|
+
for (let i = 0; i < imagery.length; i++) {
|
|
3022
|
+
const provider = imagery.get(i);
|
|
3023
|
+
if (provider._bMeta) {
|
|
3024
|
+
const idCombo = provider._bMeta.accountId + provider._bMeta.tilesetId;
|
|
3025
|
+
if (!tiles.find(x => x.accountId + x.tilesetId === idCombo)) {
|
|
3026
|
+
tiles.push({
|
|
3027
|
+
accountId: provider._bMeta.accountId,
|
|
3028
|
+
tilesetId: provider._bMeta.tilesetId,
|
|
3029
|
+
alpha: provider.alpha,
|
|
3030
|
+
brightness: provider.brightness,
|
|
3031
|
+
contrast: provider.contrast,
|
|
3032
|
+
hue: provider.hue,
|
|
3033
|
+
saturation: provider.saturation,
|
|
3034
|
+
gamma: provider.gamma
|
|
3035
|
+
});
|
|
3036
|
+
}
|
|
3037
|
+
}
|
|
2820
3038
|
}
|
|
3039
|
+
return {
|
|
3040
|
+
imagery: tiles
|
|
3041
|
+
};
|
|
2821
3042
|
}
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
3043
|
+
ViewUtils.GatherMapTiles = GatherMapTiles;
|
|
3044
|
+
function GatherTerrainTile(params) {
|
|
3045
|
+
const viewer = params.viewer;
|
|
3046
|
+
const provider = viewer.terrainProvider;
|
|
3047
|
+
if (provider === null || provider === void 0 ? void 0 : provider._bMeta) {
|
|
3048
|
+
return {
|
|
3049
|
+
terrain: {
|
|
3050
|
+
accountId: provider._bMeta.accountId,
|
|
3051
|
+
tilesetId: provider._bMeta.tilesetId,
|
|
3052
|
+
}
|
|
3053
|
+
};
|
|
2825
3054
|
}
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
3055
|
+
else if (provider instanceof EllipsoidTerrainProvider) {
|
|
3056
|
+
return {
|
|
3057
|
+
terrain: {
|
|
3058
|
+
tilesetId: ProjectViewTile.EDefaultTerrain.FlatTerrain,
|
|
3059
|
+
accountId: null
|
|
3060
|
+
}
|
|
3061
|
+
};
|
|
2830
3062
|
}
|
|
2831
|
-
|
|
2832
|
-
|
|
3063
|
+
return null;
|
|
3064
|
+
}
|
|
3065
|
+
ViewUtils.GatherTerrainTile = GatherTerrainTile;
|
|
3066
|
+
function SetTerrainWireframeStatus(params) {
|
|
3067
|
+
if (!params.viewer[CESIUM_INSPECTOR_KEY]) {
|
|
3068
|
+
const InspectorClass = CesiumInspector;
|
|
3069
|
+
if (InspectorClass) {
|
|
3070
|
+
const inspector = new InspectorClass(document.createElement("div"), params.viewer.scene);
|
|
3071
|
+
inspector.container.style.display = "none";
|
|
3072
|
+
params.viewer[CESIUM_INSPECTOR_KEY] = inspector;
|
|
3073
|
+
params.viewer.scene.requestRender();
|
|
3074
|
+
}
|
|
3075
|
+
}
|
|
3076
|
+
if (params.viewer[CESIUM_INSPECTOR_KEY]) {
|
|
3077
|
+
params.viewer[CESIUM_INSPECTOR_KEY].viewModel.wireframe = params.status;
|
|
2833
3078
|
}
|
|
2834
3079
|
}
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
3080
|
+
ViewUtils.SetTerrainWireframeStatus = SetTerrainWireframeStatus;
|
|
3081
|
+
function GetTerrainWireframeStatus(params) {
|
|
3082
|
+
var _a, _b;
|
|
3083
|
+
if (!params.viewer[CESIUM_INSPECTOR_KEY]) {
|
|
3084
|
+
return false;
|
|
2838
3085
|
}
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
3086
|
+
return (_b = (_a = params.viewer[CESIUM_INSPECTOR_KEY]) === null || _a === void 0 ? void 0 : _a.viewModel) === null || _b === void 0 ? void 0 : _b.wireframe;
|
|
3087
|
+
}
|
|
3088
|
+
ViewUtils.GetTerrainWireframeStatus = GetTerrainWireframeStatus;
|
|
3089
|
+
/**
|
|
3090
|
+
* Changes between perspective and orthographic view.
|
|
3091
|
+
* When Cesium stops being bad at picking positions in 2d mode we'll use the flat earth mode instead.
|
|
3092
|
+
* @param params
|
|
3093
|
+
*/
|
|
3094
|
+
function Set2dStatus(params) {
|
|
3095
|
+
const { viewer, status: is2d, moveCamera } = params;
|
|
3096
|
+
const curLens2d = viewer.camera.frustum instanceof OrthographicFrustum;
|
|
3097
|
+
if (curLens2d && !is2d) {
|
|
3098
|
+
OnNextCRender(viewer, () => {
|
|
3099
|
+
viewer.camera.switchToPerspectiveFrustum();
|
|
3100
|
+
viewer.scene.screenSpaceCameraController.enableTilt = true;
|
|
3101
|
+
});
|
|
3102
|
+
viewer.scene.requestRender();
|
|
3103
|
+
}
|
|
3104
|
+
else if (!curLens2d && is2d) {
|
|
3105
|
+
OnNextCRender(viewer, () => {
|
|
3106
|
+
viewer.camera.switchToOrthographicFrustum();
|
|
3107
|
+
viewer.scene.screenSpaceCameraController.enableTilt = false;
|
|
3108
|
+
});
|
|
3109
|
+
if (moveCamera != false) {
|
|
3110
|
+
try {
|
|
3111
|
+
// Face camera downwards to make it look 2d.
|
|
3112
|
+
// We want to try make it look at the center-point of the current view.
|
|
3113
|
+
// If center cannot be calculated then we'll simply raise the camera and face it downwards.
|
|
3114
|
+
const scene = viewer.scene;
|
|
3115
|
+
const windowPosition = new Cartesian2(scene.canvas.clientWidth / 2, scene.canvas.clientHeight / 2);
|
|
3116
|
+
const ray = viewer.camera.getPickRay(windowPosition);
|
|
3117
|
+
const intersection = scene.globe.pick(ray, scene);
|
|
3118
|
+
let center;
|
|
3119
|
+
if (defined(intersection)) {
|
|
3120
|
+
center = Cartographic.fromCartesian(intersection);
|
|
3121
|
+
}
|
|
3122
|
+
// Use current camera position if we can't calculate the center.
|
|
3123
|
+
else {
|
|
3124
|
+
center = Cartographic.fromCartesian(viewer.camera.position);
|
|
3125
|
+
center.height = 0;
|
|
3126
|
+
}
|
|
3127
|
+
center.height = viewer.camera.positionCartographic.height + 100;
|
|
3128
|
+
viewer.camera.setView({
|
|
3129
|
+
destination: Cartographic.toCartesian(center),
|
|
3130
|
+
orientation: {
|
|
3131
|
+
heading: 0.0,
|
|
3132
|
+
pitch: Math$1.toRadians(-90.0),
|
|
3133
|
+
roll: 0.0
|
|
3134
|
+
}
|
|
3135
|
+
});
|
|
3136
|
+
}
|
|
3137
|
+
catch (e) {
|
|
3138
|
+
console.error(e);
|
|
3139
|
+
}
|
|
3140
|
+
}
|
|
3141
|
+
viewer.scene.requestRender();
|
|
3142
|
+
}
|
|
3143
|
+
}
|
|
3144
|
+
ViewUtils.Set2dStatus = Set2dStatus;
|
|
3145
|
+
function Get2dStatus(params) {
|
|
3146
|
+
const { viewer } = params;
|
|
3147
|
+
return viewer.camera.frustum instanceof OrthographicFrustum;
|
|
3148
|
+
}
|
|
3149
|
+
ViewUtils.Get2dStatus = Get2dStatus;
|
|
3150
|
+
function SetLockedCameraStatus(params) {
|
|
3151
|
+
const { viewer, status } = params;
|
|
3152
|
+
const scene = viewer === null || viewer === void 0 ? void 0 : viewer.scene;
|
|
3153
|
+
if (!scene) {
|
|
3154
|
+
return;
|
|
3155
|
+
}
|
|
3156
|
+
if (status) {
|
|
3157
|
+
scene.screenSpaceCameraController.enableInputs = false;
|
|
3158
|
+
scene.screenSpaceCameraController.enableTranslate = false;
|
|
3159
|
+
scene.screenSpaceCameraController.enableZoom = false;
|
|
3160
|
+
scene.screenSpaceCameraController.enableRotate = false;
|
|
3161
|
+
scene.screenSpaceCameraController.enableTilt = false;
|
|
3162
|
+
}
|
|
3163
|
+
else {
|
|
3164
|
+
scene.screenSpaceCameraController.enableInputs = true;
|
|
3165
|
+
scene.screenSpaceCameraController.enableTranslate = true;
|
|
3166
|
+
scene.screenSpaceCameraController.enableZoom = true;
|
|
3167
|
+
scene.screenSpaceCameraController.enableRotate = true;
|
|
3168
|
+
if (!ViewUtils.Get2dStatus({ viewer })) {
|
|
3169
|
+
scene.screenSpaceCameraController.enableTilt = true;
|
|
3170
|
+
}
|
|
3171
|
+
}
|
|
3172
|
+
viewer.scene.requestRender();
|
|
3173
|
+
}
|
|
3174
|
+
ViewUtils.SetLockedCameraStatus = SetLockedCameraStatus;
|
|
3175
|
+
function GetLockedCameraStatus(params) {
|
|
3176
|
+
var _a;
|
|
3177
|
+
const scene = (_a = params.viewer) === null || _a === void 0 ? void 0 : _a.scene;
|
|
3178
|
+
if (!scene) {
|
|
3179
|
+
return false;
|
|
3180
|
+
}
|
|
3181
|
+
return !scene.screenSpaceCameraController.enableTranslate;
|
|
3182
|
+
}
|
|
3183
|
+
ViewUtils.GetLockedCameraStatus = GetLockedCameraStatus;
|
|
3184
|
+
/**
|
|
3185
|
+
* Returns the current camera time and related settings.
|
|
3186
|
+
* @param params
|
|
3187
|
+
* @returns
|
|
3188
|
+
*/
|
|
3189
|
+
function GetTimeDetails(params) {
|
|
3190
|
+
const { viewer } = params;
|
|
3191
|
+
const clock = viewer.clock;
|
|
3192
|
+
return {
|
|
3193
|
+
animationSpeed: clock.multiplier,
|
|
3194
|
+
isAnimating: clock.shouldAnimate,
|
|
3195
|
+
startTime: clock.startTime,
|
|
3196
|
+
startTimeIso: clock.startTime.toString(),
|
|
3197
|
+
currentTime: clock.currentTime,
|
|
3198
|
+
currentTimeIso: clock.currentTime.toString(),
|
|
3199
|
+
stopTime: clock.stopTime,
|
|
3200
|
+
stopTimeIso: clock.stopTime.toString(),
|
|
3201
|
+
areCesiumValues: clock[CESIUM_TIMELINE_KEY] != true,
|
|
3202
|
+
isLive: clock[CESIUM_TIMELINE_LIVE_KEY] == true,
|
|
3203
|
+
livePaddingSeconds: clock[CESIUM_TIMELINE_LIVE_PADDING_KEY] || DEFAULT_LIVE_PADDING_SECONDS
|
|
3204
|
+
};
|
|
3205
|
+
}
|
|
3206
|
+
ViewUtils.GetTimeDetails = GetTimeDetails;
|
|
3207
|
+
/**
|
|
3208
|
+
* Sets the Cesium clock values.
|
|
3209
|
+
* If a value is not provided, then 'areCesiumValues' checked to see if the values are Cesium values.
|
|
3210
|
+
* If they're currently Cesium set values then our defaults are used.
|
|
3211
|
+
* @param params
|
|
3212
|
+
*/
|
|
3213
|
+
function SetTimeDetails(params) {
|
|
3214
|
+
let { viewer, animationSpeed, isAnimating, startTime, currentTime, stopTime, startTimeIso, stopTimeIso, currentTimeIso, isLive, livePaddingSeconds } = params;
|
|
3215
|
+
const clock = viewer.clock;
|
|
3216
|
+
if (startTime) {
|
|
3217
|
+
clock.startTime = startTime;
|
|
3218
|
+
}
|
|
3219
|
+
else if (startTimeIso) {
|
|
3220
|
+
const startDate = JulianDate.fromIso8601(startTimeIso);
|
|
3221
|
+
if (startDate) {
|
|
3222
|
+
clock.startTime = startDate;
|
|
3223
|
+
}
|
|
3224
|
+
}
|
|
3225
|
+
if (currentTime) {
|
|
3226
|
+
clock.currentTime = currentTime;
|
|
3227
|
+
}
|
|
3228
|
+
else if (currentTimeIso) {
|
|
3229
|
+
const currentDate = JulianDate.fromIso8601(currentTimeIso);
|
|
3230
|
+
if (currentDate) {
|
|
3231
|
+
clock.currentTime = currentDate;
|
|
3232
|
+
}
|
|
3233
|
+
}
|
|
3234
|
+
if (stopTime) {
|
|
3235
|
+
clock.stopTime = stopTime;
|
|
3236
|
+
}
|
|
3237
|
+
else if (stopTimeIso) {
|
|
3238
|
+
const stopDate = JulianDate.fromIso8601(stopTimeIso);
|
|
3239
|
+
if (stopDate) {
|
|
3240
|
+
clock.stopTime = stopDate;
|
|
3241
|
+
}
|
|
3242
|
+
}
|
|
3243
|
+
clock.clockRange = ClockRange.LOOP_STOP;
|
|
3244
|
+
const areCesiumValues = clock[CESIUM_TIMELINE_KEY] != true;
|
|
3245
|
+
if (areCesiumValues) {
|
|
3246
|
+
if (isNaN(animationSpeed) || animationSpeed == null) {
|
|
3247
|
+
animationSpeed = 1;
|
|
3248
|
+
}
|
|
3249
|
+
if (isAnimating == null) {
|
|
3250
|
+
isAnimating = false;
|
|
3251
|
+
}
|
|
3252
|
+
if (isLive == null) {
|
|
3253
|
+
isLive = false;
|
|
3254
|
+
}
|
|
3255
|
+
if (livePaddingSeconds == null) {
|
|
3256
|
+
livePaddingSeconds = DEFAULT_LIVE_PADDING_SECONDS;
|
|
3257
|
+
}
|
|
3258
|
+
}
|
|
3259
|
+
if (!isNaN(animationSpeed) && animationSpeed != null) {
|
|
3260
|
+
clock.multiplier = animationSpeed;
|
|
3261
|
+
}
|
|
3262
|
+
if (isAnimating != null) {
|
|
3263
|
+
clock.shouldAnimate = isAnimating;
|
|
3264
|
+
}
|
|
3265
|
+
viewer.scene.requestRender();
|
|
3266
|
+
clock[CESIUM_TIMELINE_KEY] = true;
|
|
3267
|
+
if (livePaddingSeconds != null) {
|
|
3268
|
+
clock[CESIUM_TIMELINE_LIVE_PADDING_KEY] = livePaddingSeconds || DEFAULT_LIVE_PADDING_SECONDS;
|
|
3269
|
+
}
|
|
3270
|
+
if (isLive != null) {
|
|
3271
|
+
clock[CESIUM_TIMELINE_LIVE_KEY] = params.isLive == true;
|
|
3272
|
+
}
|
|
3273
|
+
if (clock[CESIUM_TIMELINE_LIVE_KEY]) {
|
|
3274
|
+
startLive(viewer);
|
|
3275
|
+
}
|
|
3276
|
+
else {
|
|
3277
|
+
stopLive(viewer);
|
|
3278
|
+
}
|
|
3279
|
+
}
|
|
3280
|
+
ViewUtils.SetTimeDetails = SetTimeDetails;
|
|
3281
|
+
function startLive(viewer) {
|
|
3282
|
+
const doUpdate = () => {
|
|
3283
|
+
if (!viewer || viewer.isDestroyed() || !viewer.scene) {
|
|
3284
|
+
stopLive(viewer);
|
|
3285
|
+
return;
|
|
3286
|
+
}
|
|
3287
|
+
// Get the current settings.
|
|
3288
|
+
const tDetails = GetTimeDetails({ viewer });
|
|
3289
|
+
const clock = viewer.clock;
|
|
3290
|
+
if (clock) {
|
|
3291
|
+
clock.shouldAnimate = true;
|
|
3292
|
+
clock.multiplier = 1;
|
|
3293
|
+
clock.currentTime = JulianDate.now();
|
|
3294
|
+
clock.startTime = JulianDate.addSeconds(clock.currentTime, -tDetails.livePaddingSeconds, new JulianDate());
|
|
3295
|
+
clock.stopTime = JulianDate.addSeconds(clock.currentTime, tDetails.livePaddingSeconds, new JulianDate());
|
|
3296
|
+
clock.clockRange = ClockRange.UNBOUNDED;
|
|
3297
|
+
}
|
|
3298
|
+
};
|
|
3299
|
+
if (viewer[CESIUM_TIMELINE_INTERVAL_KEY]) {
|
|
3300
|
+
doUpdate();
|
|
3301
|
+
return;
|
|
3302
|
+
}
|
|
3303
|
+
// We'll start an interval that occasionally updates the Cesium clock to stay in the desired settings.
|
|
3304
|
+
// Since it moves live (1 second per second), we don't have to worry about the ranges being out of date quickly.
|
|
3305
|
+
viewer[CESIUM_TIMELINE_INTERVAL_KEY] = setInterval(() => {
|
|
3306
|
+
doUpdate();
|
|
3307
|
+
}, 800);
|
|
3308
|
+
viewer[CESIUM_TIMELINE_LIVE_KEY] = true;
|
|
3309
|
+
// Initial update.
|
|
3310
|
+
doUpdate();
|
|
3311
|
+
}
|
|
3312
|
+
function stopLive(viewer) {
|
|
3313
|
+
if (!viewer) {
|
|
3314
|
+
return;
|
|
3315
|
+
}
|
|
3316
|
+
let interval = viewer[CESIUM_TIMELINE_INTERVAL_KEY];
|
|
3317
|
+
if (interval) {
|
|
3318
|
+
clearInterval(interval);
|
|
3319
|
+
viewer[CESIUM_TIMELINE_INTERVAL_KEY] = null;
|
|
3320
|
+
}
|
|
3321
|
+
viewer[CESIUM_TIMELINE_LIVE_KEY] = false;
|
|
3322
|
+
}
|
|
3323
|
+
/**
|
|
3324
|
+
* Brightens a scene's atmosphere, using whichever control the host app's CesiumJS exposes.
|
|
3325
|
+
* @param viewer the viewer to brighten. Safe to call with null.
|
|
3326
|
+
* @param shift -1 to 1, where 0 or less leaves CesiumJS's own defaults alone.
|
|
3327
|
+
*/
|
|
3328
|
+
function ApplyDefaultBrightness(viewer, shift = DEFAULT_BRIGHTNESS_SHIFT) {
|
|
3329
|
+
const scene = viewer === null || viewer === void 0 ? void 0 : viewer.scene;
|
|
3330
|
+
if (!scene || !(shift > 0)) {
|
|
3331
|
+
return;
|
|
3332
|
+
}
|
|
3333
|
+
// Atmosphere settings moved from Globe onto Scene, and the sky keeps its own copy, so each is
|
|
3334
|
+
// probed rather than version checked: host apps bring their own CesiumJS.
|
|
3335
|
+
const SCENE = scene;
|
|
3336
|
+
if (SCENE.atmosphere && typeof SCENE.atmosphere.brightnessShift === "number") {
|
|
3337
|
+
SCENE.atmosphere.brightnessShift = shift;
|
|
3338
|
+
}
|
|
3339
|
+
if (SCENE.globe && typeof SCENE.globe.atmosphereBrightnessShift === "number") {
|
|
3340
|
+
SCENE.globe.atmosphereBrightnessShift = shift;
|
|
3341
|
+
}
|
|
3342
|
+
if (SCENE.skyAtmosphere && typeof SCENE.skyAtmosphere.brightnessShift === "number") {
|
|
3343
|
+
SCENE.skyAtmosphere.brightnessShift = shift;
|
|
3344
|
+
}
|
|
3345
|
+
}
|
|
3346
|
+
ViewUtils.ApplyDefaultBrightness = ApplyDefaultBrightness;
|
|
3347
|
+
function SetGlobeDetails(params) {
|
|
3348
|
+
let { viewer, hidden, baseColor } = params;
|
|
3349
|
+
const scene = viewer === null || viewer === void 0 ? void 0 : viewer.scene;
|
|
3350
|
+
if (!(scene === null || scene === void 0 ? void 0 : scene.globe)) {
|
|
3351
|
+
return;
|
|
3352
|
+
}
|
|
3353
|
+
if (hidden == null) {
|
|
3354
|
+
hidden = !scene.globe.show;
|
|
3355
|
+
}
|
|
3356
|
+
else {
|
|
3357
|
+
scene.globe.show = !hidden;
|
|
3358
|
+
}
|
|
3359
|
+
if (baseColor == null) {
|
|
3360
|
+
baseColor = scene.globe.baseColor;
|
|
3361
|
+
}
|
|
3362
|
+
// When globe is off, we'll also hide the stars/moon.
|
|
3363
|
+
// We also grab the globe color and apply it to the sky.
|
|
3364
|
+
if (hidden && GetModelSpace(viewer)) {
|
|
3365
|
+
scene.skyBox.show = false;
|
|
3366
|
+
scene.skyAtmosphere.show = false;
|
|
3367
|
+
scene.sun.show = false;
|
|
3368
|
+
scene.moon.show = false;
|
|
3369
|
+
scene.backgroundColor = baseColor.clone();
|
|
3370
|
+
}
|
|
3371
|
+
else {
|
|
3372
|
+
scene.skyBox.show = true;
|
|
3373
|
+
scene.skyAtmosphere.show = true;
|
|
3374
|
+
scene.sun.show = true;
|
|
3375
|
+
scene.moon.show = true;
|
|
3376
|
+
scene.backgroundColor = Color.BLACK;
|
|
3377
|
+
}
|
|
3378
|
+
scene.globe.baseColor = baseColor;
|
|
3379
|
+
}
|
|
3380
|
+
ViewUtils.SetGlobeDetails = SetGlobeDetails;
|
|
3381
|
+
function SetModelSpace(viewer, modelSpace) {
|
|
3382
|
+
if (!viewer) {
|
|
3383
|
+
return;
|
|
3384
|
+
}
|
|
3385
|
+
if (viewer[CESIUM_MODEL_SPACE_KEY] === modelSpace) {
|
|
3386
|
+
return;
|
|
3387
|
+
}
|
|
3388
|
+
viewer[CESIUM_MODEL_SPACE_KEY] = modelSpace;
|
|
3389
|
+
// Reload globe since we display it differently between the two modes.
|
|
3390
|
+
SetGlobeDetails({ viewer });
|
|
3391
|
+
}
|
|
3392
|
+
ViewUtils.SetModelSpace = SetModelSpace;
|
|
3393
|
+
function GetModelSpace(viewer) {
|
|
3394
|
+
if (!viewer) {
|
|
3395
|
+
return false;
|
|
3396
|
+
}
|
|
3397
|
+
return Boolean(viewer[CESIUM_MODEL_SPACE_KEY]);
|
|
3398
|
+
}
|
|
3399
|
+
ViewUtils.GetModelSpace = GetModelSpace;
|
|
3400
|
+
})(ViewUtils || (ViewUtils = {}));
|
|
3401
|
+
|
|
3402
|
+
/**
|
|
3403
|
+
* Describes a Nextspace provided UI widget.
|
|
3404
|
+
*/
|
|
3405
|
+
var Widget;
|
|
3406
|
+
(function (Widget) {
|
|
3407
|
+
class AWidget {
|
|
3408
|
+
get WidgetId() {
|
|
3409
|
+
return this.widgetId;
|
|
3410
|
+
}
|
|
3411
|
+
get Viewer() {
|
|
3412
|
+
return this._viewer;
|
|
3413
|
+
}
|
|
3414
|
+
get Container() {
|
|
3415
|
+
return this._container;
|
|
3416
|
+
}
|
|
3417
|
+
get Element() {
|
|
3418
|
+
return this._element;
|
|
3419
|
+
}
|
|
3420
|
+
constructor(params) {
|
|
3421
|
+
this.widgetId = ObjectUtils.UId();
|
|
3422
|
+
let { viewer, container, manager } = params;
|
|
3423
|
+
// A host app can pass an undefined viewer (eg. mid-teardown); fall back to
|
|
3424
|
+
// no container rather than crashing on viewer.container.
|
|
3425
|
+
if (!container && viewer) {
|
|
3426
|
+
container = viewer.container;
|
|
3427
|
+
}
|
|
3428
|
+
this._viewer = viewer;
|
|
3429
|
+
this._manager = manager;
|
|
3430
|
+
this._container = container;
|
|
3431
|
+
this._apiGetters = params.apiGetters;
|
|
3432
|
+
if (viewer) {
|
|
3433
|
+
markViewerWithWidget(viewer, this.widgetId, this);
|
|
3434
|
+
}
|
|
3435
|
+
}
|
|
3436
|
+
Dispose() {
|
|
3437
|
+
if (this._element && this._element.parentElement) {
|
|
3438
|
+
this._element.parentElement.removeChild(this._element);
|
|
3439
|
+
}
|
|
3440
|
+
if (this._viewer) {
|
|
3441
|
+
unmarkViewerWithWidget(this._viewer, this.widgetId, this);
|
|
3442
|
+
}
|
|
3443
|
+
}
|
|
3444
|
+
}
|
|
3445
|
+
Widget.AWidget = AWidget;
|
|
3446
|
+
function GetWidgets(viewer) {
|
|
3447
|
+
if (viewer && viewer["_nextspaceWidgets"]) {
|
|
3448
|
+
return Object.values(viewer["_nextspaceWidgets"]);
|
|
3449
|
+
}
|
|
3450
|
+
return [];
|
|
3451
|
+
}
|
|
3452
|
+
Widget.GetWidgets = GetWidgets;
|
|
3453
|
+
})(Widget || (Widget = {}));
|
|
3454
|
+
function markViewerWithWidget(viewer, widgetId, widget) {
|
|
3455
|
+
if (!viewer["_nextspaceWidgets"]) {
|
|
3456
|
+
viewer["_nextspaceWidgets"] = {};
|
|
3457
|
+
}
|
|
3458
|
+
viewer["_nextspaceWidgets"][widgetId] = widget;
|
|
3459
|
+
}
|
|
3460
|
+
function unmarkViewerWithWidget(viewer, widgetId, widget) {
|
|
3461
|
+
if (viewer["_nextspaceWidgets"]) {
|
|
3462
|
+
delete viewer["_nextspaceWidgets"][widgetId];
|
|
3463
|
+
}
|
|
3464
|
+
}
|
|
3465
|
+
|
|
3466
|
+
var WidgetControlViewBar;
|
|
3467
|
+
(function (WidgetControlViewBar) {
|
|
3468
|
+
class AControl {
|
|
3469
|
+
get WidgetViewBar() {
|
|
3470
|
+
return this._widget;
|
|
3471
|
+
}
|
|
3472
|
+
get Container() {
|
|
3473
|
+
return this._container;
|
|
3474
|
+
}
|
|
3475
|
+
get Element() {
|
|
3476
|
+
return this._element;
|
|
3477
|
+
}
|
|
3478
|
+
get Disposed() {
|
|
3479
|
+
return this._disposed;
|
|
3480
|
+
}
|
|
3481
|
+
get Enabled() {
|
|
3482
|
+
return this._enabled;
|
|
3483
|
+
}
|
|
3484
|
+
constructor(params) {
|
|
3485
|
+
this._disposed = false;
|
|
3486
|
+
this._enabled = false;
|
|
3487
|
+
let { container, widget, element } = params;
|
|
3488
|
+
this._widget = widget;
|
|
3489
|
+
this._container = container;
|
|
3490
|
+
this._element = element;
|
|
3491
|
+
}
|
|
3492
|
+
Toggle() {
|
|
3493
|
+
}
|
|
3494
|
+
Dispose() {
|
|
3495
|
+
this._disposed = true;
|
|
3496
|
+
}
|
|
3497
|
+
}
|
|
3498
|
+
WidgetControlViewBar.AControl = AControl;
|
|
3499
|
+
})(WidgetControlViewBar || (WidgetControlViewBar = {}));
|
|
3500
|
+
|
|
3501
|
+
/**
|
|
3502
|
+
* The fullscreen control is a simple toggle.
|
|
3503
|
+
* There is no HTML element. However we do swap the icon based on the toggle state.
|
|
3504
|
+
*/
|
|
3505
|
+
class WidgetControlViewBarFullscreen extends WidgetControlViewBar.AControl {
|
|
3506
|
+
constructor(params) {
|
|
3507
|
+
super(params);
|
|
3508
|
+
}
|
|
3509
|
+
Dispose() {
|
|
3510
|
+
super.Dispose();
|
|
3511
|
+
}
|
|
3512
|
+
Toggle() {
|
|
3513
|
+
if (this.Disposed) {
|
|
3514
|
+
return;
|
|
3515
|
+
}
|
|
3516
|
+
super.Toggle();
|
|
3517
|
+
// Toggle fullscreen.
|
|
3518
|
+
this._enabled = false;
|
|
3519
|
+
if (Fullscreen.enabled) {
|
|
3520
|
+
if (Fullscreen.fullscreen) {
|
|
3521
|
+
Fullscreen.exitFullscreen();
|
|
3522
|
+
}
|
|
3523
|
+
else {
|
|
3524
|
+
Fullscreen.requestFullscreen(document.body);
|
|
3525
|
+
this._enabled = true;
|
|
3526
|
+
}
|
|
3527
|
+
}
|
|
3528
|
+
}
|
|
3529
|
+
}
|
|
3530
|
+
|
|
3531
|
+
class WidgetControlViewBarSearch extends WidgetControlViewBar.AControl {
|
|
3532
|
+
constructor(params) {
|
|
3533
|
+
super(params);
|
|
3534
|
+
this.STYLESHEET_ID = "nextspace-control-view-bar-searchbar-stylesheet";
|
|
3535
|
+
this._generateStyles();
|
|
3536
|
+
this._generateElement();
|
|
3537
|
+
}
|
|
3538
|
+
Dispose() {
|
|
3539
|
+
super.Dispose();
|
|
3540
|
+
if (this._element && this._element.parentElement) {
|
|
3541
|
+
this._element.parentElement.removeChild(this._element);
|
|
3542
|
+
}
|
|
3543
|
+
if (this._results && this._results.parentElement) {
|
|
3544
|
+
this._results.parentElement.removeChild(this._results);
|
|
3545
|
+
}
|
|
3546
|
+
}
|
|
3547
|
+
Toggle() {
|
|
3548
|
+
if (this.Disposed) {
|
|
3549
|
+
return;
|
|
3550
|
+
}
|
|
3551
|
+
super.Toggle();
|
|
3552
|
+
this._enabled = !this._enabled;
|
|
3553
|
+
if (this._enabled) {
|
|
3554
|
+
this._display();
|
|
3555
|
+
}
|
|
3556
|
+
else {
|
|
3557
|
+
this._hide();
|
|
3558
|
+
}
|
|
3559
|
+
}
|
|
3560
|
+
_generateStyles() {
|
|
3561
|
+
if (document.getElementById(this.STYLESHEET_ID)) {
|
|
3562
|
+
return;
|
|
3563
|
+
}
|
|
3564
|
+
const style = document.createElement("style");
|
|
3565
|
+
style.id = this.STYLESHEET_ID;
|
|
3566
|
+
style.innerHTML = `
|
|
3567
|
+
.NextspaceSearchBar {
|
|
3568
|
+
display: flex;
|
|
3569
|
+
box-sizing: border-box;
|
|
3570
|
+
height: 100%;
|
|
3571
|
+
font-family: sans-serif;
|
|
3572
|
+
}
|
|
3573
|
+
|
|
3574
|
+
.NextspaceSearchBar * {
|
|
3575
|
+
box-sizing: border-box;
|
|
3576
|
+
}
|
|
3577
|
+
|
|
3578
|
+
.NextspaceSearchBar[is-opened="true"] .NextspaceSearchBarContent {
|
|
3579
|
+
display: flex;
|
|
2855
3580
|
width: 260px;
|
|
2856
3581
|
}
|
|
2857
3582
|
|
|
@@ -3564,1123 +4289,423 @@ var SimplifyGeometry;
|
|
|
3564
4289
|
for (let i = 0; i < geometry.Polygon.length; i++) {
|
|
3565
4290
|
const polygon = geometry.Polygon[i];
|
|
3566
4291
|
count += Geometry$1.ParsePoints(polygon.LinearRing).length;
|
|
3567
|
-
}
|
|
3568
|
-
}
|
|
3569
|
-
else if (geometry.LineString) {
|
|
3570
|
-
count += Geometry$1.ParsePoints(geometry.LineString).length;
|
|
3571
|
-
}
|
|
3572
|
-
else if (geometry.Point) {
|
|
3573
|
-
count += 1;
|
|
3574
|
-
}
|
|
3575
|
-
};
|
|
3576
|
-
traverse(geometry);
|
|
3577
|
-
return count;
|
|
3578
|
-
}
|
|
3579
|
-
SimplifyGeometry.CountPoints = CountPoints;
|
|
3580
|
-
/**
|
|
3581
|
-
* Simplifies input geometry.
|
|
3582
|
-
* This will turn it into GeoJSON, run it through turf, then back to Bruce geometry.
|
|
3583
|
-
* @param geometry
|
|
3584
|
-
*/
|
|
3585
|
-
function Simplify(entityId, geometry, tolerance) {
|
|
3586
|
-
var _a;
|
|
3587
|
-
if (!geometry || !isTurfAvailable() || !turf.simplify) {
|
|
3588
|
-
return geometry;
|
|
3589
|
-
}
|
|
3590
|
-
const original = geometry;
|
|
3591
|
-
// Convert to geojson so that we can interact with turf.
|
|
3592
|
-
const gFeature = Geometry$1.ToGeoJsonFeature({
|
|
3593
|
-
geometry: geometry
|
|
3594
|
-
});
|
|
3595
|
-
// Unkink the geometry.
|
|
3596
|
-
// This removes overlapping polygons before we start merging and simplifying.
|
|
3597
|
-
// Commented out because it has crashes and doesn't handle holes.
|
|
3598
|
-
untangleFeature(gFeature);
|
|
3599
|
-
// Union the geometry.
|
|
3600
|
-
// This merges overlapping polygons.
|
|
3601
|
-
unionFeature(gFeature);
|
|
3602
|
-
// Simplify the geometry.
|
|
3603
|
-
if (tolerance > 0) {
|
|
3604
|
-
gFeature.geometry = turf.simplify(gFeature.geometry, {
|
|
3605
|
-
tolerance: tolerance,
|
|
3606
|
-
highQuality: true,
|
|
3607
|
-
mutate: true
|
|
3608
|
-
});
|
|
3609
|
-
}
|
|
3610
|
-
// Converting back to Bruce geometry.
|
|
3611
|
-
const simplified = (_a = Geometry$1.FromGeoJson({
|
|
3612
|
-
geoJson: gFeature
|
|
3613
|
-
})) === null || _a === void 0 ? void 0 : _a.geometry;
|
|
3614
|
-
// A polygon we cannot vouch for is worse than an unsimplified one, so fall back instead of shipping it.
|
|
3615
|
-
if (!simplified || !isSafeToRender(simplified)) {
|
|
3616
|
-
return original;
|
|
3617
|
-
}
|
|
3618
|
-
return simplified;
|
|
3619
|
-
}
|
|
3620
|
-
SimplifyGeometry.Simplify = Simplify;
|
|
3621
|
-
/**
|
|
3622
|
-
* Whether a simplified geometry still describes something a renderer can triangulate.
|
|
3623
|
-
* @param geometry the simplification result.
|
|
3624
|
-
* @returns false when any polygon has a collapsed ring, a hole outside its outer ring, or a hole
|
|
3625
|
-
* wound the same way as its outer ring.
|
|
3626
|
-
*/
|
|
3627
|
-
function IsSafeToRender(geometry) {
|
|
3628
|
-
return isSafeToRender(geometry);
|
|
3629
|
-
}
|
|
3630
|
-
SimplifyGeometry.IsSafeToRender = IsSafeToRender;
|
|
3631
|
-
})(SimplifyGeometry || (SimplifyGeometry = {}));
|
|
3632
|
-
// A ring needs three distinct corners plus the closing repeat before it encloses any area.
|
|
3633
|
-
const MIN_RING_POSITIONS = 4;
|
|
3634
|
-
function isSafeToRender(geometry) {
|
|
3635
|
-
let safe = true;
|
|
3636
|
-
const check = (g) => {
|
|
3637
|
-
if (!safe) {
|
|
3638
|
-
return;
|
|
3639
|
-
}
|
|
3640
|
-
if (g === null || g === void 0 ? void 0 : g.MultiGeometry) {
|
|
3641
|
-
g.MultiGeometry.forEach(check);
|
|
3642
|
-
return;
|
|
3643
|
-
}
|
|
3644
|
-
if (!(g === null || g === void 0 ? void 0 : g.Polygon) || g.Polygon.length === 0) {
|
|
3645
|
-
return;
|
|
3646
|
-
}
|
|
3647
|
-
let outer = null;
|
|
3648
|
-
let outerIsClockwise = false;
|
|
3649
|
-
for (let i = 0; i < g.Polygon.length; i++) {
|
|
3650
|
-
const points = Geometry$1.ParsePoints(g.Polygon[i].LinearRing);
|
|
3651
|
-
if (!points || points.length < MIN_RING_POSITIONS) {
|
|
3652
|
-
safe = false;
|
|
3653
|
-
return;
|
|
3654
|
-
}
|
|
3655
|
-
const clockwise = signedRingArea(points) < 0;
|
|
3656
|
-
if (g.Polygon[i].Facing !== "in") {
|
|
3657
|
-
outer = points;
|
|
3658
|
-
outerIsClockwise = clockwise;
|
|
3659
|
-
continue;
|
|
3660
|
-
}
|
|
3661
|
-
// A hole with no outer ring ahead of it cannot be subtracted from anything.
|
|
3662
|
-
if (!outer) {
|
|
3663
|
-
safe = false;
|
|
3664
|
-
return;
|
|
3665
|
-
}
|
|
3666
|
-
if (clockwise === outerIsClockwise) {
|
|
3667
|
-
safe = false;
|
|
3668
|
-
return;
|
|
3669
|
-
}
|
|
3670
|
-
for (let j = 0; j < points.length; j++) {
|
|
3671
|
-
if (!isPointInRing(points[j], outer)) {
|
|
3672
|
-
safe = false;
|
|
3673
|
-
return;
|
|
3674
|
-
}
|
|
3675
|
-
}
|
|
3676
|
-
}
|
|
3677
|
-
};
|
|
3678
|
-
check(geometry);
|
|
3679
|
-
return safe;
|
|
3680
|
-
}
|
|
3681
|
-
function signedRingArea(points) {
|
|
3682
|
-
let sum = 0;
|
|
3683
|
-
for (let i = 0; i < points.length; i++) {
|
|
3684
|
-
const a = points[i];
|
|
3685
|
-
const b = points[(i + 1) % points.length];
|
|
3686
|
-
sum += a.longitude * b.latitude - b.longitude * a.latitude;
|
|
3687
|
-
}
|
|
3688
|
-
return sum / 2;
|
|
3689
|
-
}
|
|
3690
|
-
function isPointInRing(point, ring) {
|
|
3691
|
-
let inside = false;
|
|
3692
|
-
for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {
|
|
3693
|
-
const a = ring[i];
|
|
3694
|
-
const b = ring[j];
|
|
3695
|
-
if ((a.latitude > point.latitude) !== (b.latitude > point.latitude)
|
|
3696
|
-
&& point.longitude < (b.longitude - a.longitude) * (point.latitude - a.latitude) / (b.latitude - a.latitude) + a.longitude) {
|
|
3697
|
-
inside = !inside;
|
|
3698
|
-
}
|
|
3699
|
-
}
|
|
3700
|
-
return inside;
|
|
3701
|
-
}
|
|
3702
|
-
/**
|
|
3703
|
-
* Runs through all found polygons and runs unkink through turf on them.
|
|
3704
|
-
* @param feature
|
|
3705
|
-
*/
|
|
3706
|
-
function untangleFeature(feature) {
|
|
3707
|
-
// Collection to add to because the result might be multiple from an unkink.
|
|
3708
|
-
const collection = {
|
|
3709
|
-
geometries: [],
|
|
3710
|
-
type: "GeometryCollection"
|
|
3711
|
-
};
|
|
3712
|
-
// Runs a dedupe and unkink on the coordinates.
|
|
3713
|
-
// Returns if the coordinates were added to the collection.
|
|
3714
|
-
const processCoordinates = (coords) => {
|
|
3715
|
-
try {
|
|
3716
|
-
// Dedupe the coordinates to avoid issues with unkink.
|
|
3717
|
-
coords = dedupeCoordinates(coords);
|
|
3718
|
-
const outer = [];
|
|
3719
|
-
let inner = [];
|
|
3720
|
-
// We'll unkink each ring separately as this is killing the holes when it is done as a whole.
|
|
3721
|
-
// So we'll do it separate then recombine.
|
|
3722
|
-
for (let i = 0; i < coords.length; i++) {
|
|
3723
|
-
const ring = coords[i];
|
|
3724
|
-
const unkink = turf.unkinkPolygon({
|
|
3725
|
-
type: "Polygon",
|
|
3726
|
-
coordinates: [ring]
|
|
3727
|
-
});
|
|
3728
|
-
if (unkink.type == "FeatureCollection") {
|
|
3729
|
-
let target = i == 0 ? outer : inner;
|
|
3730
|
-
for (let j = 0; j < unkink.features.length; j++) {
|
|
3731
|
-
const unkinked = unkink.features[j].geometry.coordinates;
|
|
3732
|
-
if (unkinked.length > 0) {
|
|
3733
|
-
target.push(unkinked[0]);
|
|
3734
|
-
}
|
|
3735
|
-
}
|
|
3736
|
-
}
|
|
3737
|
-
else {
|
|
3738
|
-
console.error("Unexpected unkink result.", unkink);
|
|
3739
|
-
}
|
|
3740
|
-
}
|
|
3741
|
-
// Recreate the rings and reapply to the collection.
|
|
3742
|
-
if (outer.length > 0) {
|
|
3743
|
-
// Unkinking a self touching boundary splits it into pieces. Keeping whichever piece
|
|
3744
|
-
// happened to come back first can discard most of the shape, so keep the biggest one.
|
|
3745
|
-
let keep = outer[0];
|
|
3746
|
-
if (outer.length > 1) {
|
|
3747
|
-
let best = Math.abs(ringArea(keep));
|
|
3748
|
-
for (let i = 1; i < outer.length; i++) {
|
|
3749
|
-
const area = Math.abs(ringArea(outer[i]));
|
|
3750
|
-
if (area > best) {
|
|
3751
|
-
best = area;
|
|
3752
|
-
keep = outer[i];
|
|
3753
|
-
}
|
|
3754
|
-
}
|
|
3755
|
-
}
|
|
3756
|
-
const combinedCoords = [keep];
|
|
3757
|
-
for (let i = 0; i < inner.length; i++) {
|
|
3758
|
-
// A hole belonging to a piece that was just discarded is no longer inside anything,
|
|
3759
|
-
// and a hole crossing the boundary is what tears the fill.
|
|
3760
|
-
if (isRingInsideRing(inner[i], keep)) {
|
|
3761
|
-
combinedCoords.push(inner[i]);
|
|
3762
|
-
}
|
|
3763
|
-
}
|
|
3764
|
-
// Add the combined coordinates to the collection
|
|
3765
|
-
const polygon = {
|
|
3766
|
-
type: "Polygon",
|
|
3767
|
-
coordinates: combinedCoords
|
|
3768
|
-
};
|
|
3769
|
-
// Ensure right-hand rule is followed.
|
|
3770
|
-
ensureRightHandRule(polygon);
|
|
3771
|
-
// Add to the collection.
|
|
3772
|
-
collection.geometries.push(polygon);
|
|
3773
|
-
return true;
|
|
3774
|
-
}
|
|
3775
|
-
}
|
|
3776
|
-
catch (e) {
|
|
3777
|
-
// console.error("Failed to unkink polygon.", e);
|
|
3778
|
-
}
|
|
3779
|
-
return false;
|
|
3780
|
-
};
|
|
3781
|
-
const processGeometry = (geometry) => {
|
|
3782
|
-
let added = false;
|
|
3783
|
-
if (geometry.type == "Polygon") {
|
|
3784
|
-
added = processCoordinates(geometry.coordinates);
|
|
3785
|
-
}
|
|
3786
|
-
else if (geometry.type == "MultiPolygon") {
|
|
3787
|
-
for (let i = 0; i < geometry.coordinates.length; i++) {
|
|
3788
|
-
added = processCoordinates(geometry.coordinates[i]) || added;
|
|
3789
|
-
}
|
|
3790
|
-
}
|
|
3791
|
-
if (!added) {
|
|
3792
|
-
// Adding original since we can't unkink it.
|
|
3793
|
-
collection.geometries.push(geometry);
|
|
3794
|
-
}
|
|
3795
|
-
};
|
|
3796
|
-
if (feature.geometry.type == "GeometryCollection") {
|
|
3797
|
-
feature.geometry.geometries.forEach((geometry) => {
|
|
3798
|
-
processGeometry(geometry);
|
|
3799
|
-
});
|
|
3800
|
-
}
|
|
3801
|
-
else {
|
|
3802
|
-
processGeometry(feature.geometry);
|
|
3803
|
-
}
|
|
3804
|
-
// Re-assign the geometry.
|
|
3805
|
-
if (collection.geometries.length == 1) {
|
|
3806
|
-
feature.geometry = collection.geometries[0];
|
|
3807
|
-
}
|
|
3808
|
-
else {
|
|
3809
|
-
feature.geometry = collection;
|
|
3810
|
-
}
|
|
3811
|
-
}
|
|
3812
|
-
/**
|
|
3813
|
-
* Runs through all found polygons and unions them using turf.
|
|
3814
|
-
* Failed unions are ignored and the original is kept.
|
|
3815
|
-
* @param feature
|
|
3816
|
-
*/
|
|
3817
|
-
function unionFeature(feature) {
|
|
3818
|
-
// Collection to add to because the result might be multiple from an unkink.
|
|
3819
|
-
const collection = {
|
|
3820
|
-
geometries: [],
|
|
3821
|
-
type: "GeometryCollection"
|
|
3822
|
-
};
|
|
3823
|
-
// We'll turn each geometry into a feature and union them.
|
|
3824
|
-
const tmpCollection = {
|
|
3825
|
-
features: [],
|
|
3826
|
-
type: "FeatureCollection"
|
|
3827
|
-
};
|
|
3828
|
-
if (feature.geometry.type == "GeometryCollection") {
|
|
3829
|
-
feature.geometry.geometries.forEach((geometry) => {
|
|
3830
|
-
if (geometry.type == "Polygon") {
|
|
3831
|
-
tmpCollection.features.push({
|
|
3832
|
-
type: "Feature",
|
|
3833
|
-
geometry: geometry,
|
|
3834
|
-
properties: {}
|
|
3835
|
-
});
|
|
3836
|
-
}
|
|
3837
|
-
else if (geometry.type == "MultiPolygon") {
|
|
3838
|
-
for (let i = 0; i < geometry.coordinates.length; i++) {
|
|
3839
|
-
tmpCollection.features.push({
|
|
3840
|
-
type: "Feature",
|
|
3841
|
-
geometry: {
|
|
3842
|
-
type: "Polygon",
|
|
3843
|
-
coordinates: geometry.coordinates[i]
|
|
3844
|
-
},
|
|
3845
|
-
properties: {}
|
|
3846
|
-
});
|
|
3847
|
-
}
|
|
3848
|
-
}
|
|
3849
|
-
// Only focusing on polygons.
|
|
3850
|
-
else {
|
|
3851
|
-
collection.geometries.push(geometry);
|
|
3852
|
-
}
|
|
3853
|
-
});
|
|
3854
|
-
}
|
|
3855
|
-
else if (feature.geometry.type == "Polygon") {
|
|
3856
|
-
tmpCollection.features.push({
|
|
3857
|
-
type: "Feature",
|
|
3858
|
-
geometry: feature.geometry,
|
|
3859
|
-
properties: {}
|
|
3860
|
-
});
|
|
3861
|
-
}
|
|
3862
|
-
else if (feature.geometry.type == "MultiPolygon") {
|
|
3863
|
-
for (let i = 0; i < feature.geometry.coordinates.length; i++) {
|
|
3864
|
-
tmpCollection.features.push({
|
|
3865
|
-
type: "Feature",
|
|
3866
|
-
geometry: {
|
|
3867
|
-
type: "Polygon",
|
|
3868
|
-
coordinates: feature.geometry.coordinates[i]
|
|
3869
|
-
},
|
|
3870
|
-
properties: {}
|
|
3871
|
-
});
|
|
3872
|
-
}
|
|
3873
|
-
}
|
|
3874
|
-
// No polygons to union.
|
|
3875
|
-
// Need at least 2 to union.
|
|
3876
|
-
if (tmpCollection.features.length < 2) {
|
|
3877
|
-
return;
|
|
3878
|
-
}
|
|
3879
|
-
// Now we'll union them.
|
|
3880
|
-
try {
|
|
3881
|
-
const union = turf.union(tmpCollection);
|
|
3882
|
-
if (union.geometry.type == "Polygon") {
|
|
3883
|
-
collection.geometries.push(union.geometry);
|
|
3884
|
-
}
|
|
3885
|
-
else if (union.geometry.type == "MultiPolygon") {
|
|
3886
|
-
for (let i = 0; i < union.geometry.coordinates.length; i++) {
|
|
3887
|
-
collection.geometries.push({
|
|
3888
|
-
type: "Polygon",
|
|
3889
|
-
coordinates: union.geometry.coordinates[i]
|
|
3890
|
-
});
|
|
3891
|
-
}
|
|
3892
|
-
}
|
|
3893
|
-
else {
|
|
3894
|
-
// Returning early because the result is unexpected.
|
|
3895
|
-
return;
|
|
3896
|
-
}
|
|
3897
|
-
}
|
|
3898
|
-
catch (e) {
|
|
3899
|
-
// console.error("Failed to union polygons.", e);
|
|
3900
|
-
return;
|
|
3901
|
-
}
|
|
3902
|
-
// Re-assign the geometry.
|
|
3903
|
-
if (collection.geometries.length == 1) {
|
|
3904
|
-
feature.geometry = collection.geometries[0];
|
|
3905
|
-
}
|
|
3906
|
-
else {
|
|
3907
|
-
feature.geometry = collection;
|
|
3908
|
-
}
|
|
3909
|
-
}
|
|
3910
|
-
function ringArea(ring) {
|
|
3911
|
-
let sum = 0;
|
|
3912
|
-
for (let i = 0; i < ring.length; i++) {
|
|
3913
|
-
const a = ring[i];
|
|
3914
|
-
const b = ring[(i + 1) % ring.length];
|
|
3915
|
-
sum += a[0] * b[1] - b[0] * a[1];
|
|
3916
|
-
}
|
|
3917
|
-
return sum / 2;
|
|
3918
|
-
}
|
|
3919
|
-
function isRingInsideRing(inner, outer) {
|
|
3920
|
-
for (let i = 0; i < inner.length; i++) {
|
|
3921
|
-
let inside = false;
|
|
3922
|
-
for (let a = 0, b = outer.length - 1; a < outer.length; b = a++) {
|
|
3923
|
-
if ((outer[a][1] > inner[i][1]) !== (outer[b][1] > inner[i][1])
|
|
3924
|
-
&& inner[i][0] < (outer[b][0] - outer[a][0]) * (inner[i][1] - outer[a][1]) / (outer[b][1] - outer[a][1]) + outer[a][0]) {
|
|
3925
|
-
inside = !inside;
|
|
3926
|
-
}
|
|
3927
|
-
}
|
|
3928
|
-
if (!inside) {
|
|
3929
|
-
return false;
|
|
3930
|
-
}
|
|
3931
|
-
}
|
|
3932
|
-
return true;
|
|
3933
|
-
}
|
|
3934
|
-
function dedupeCoordinates(inputCoords) {
|
|
3935
|
-
return inputCoords.map(ring => {
|
|
3936
|
-
if (ring.length < 2) {
|
|
3937
|
-
return ring;
|
|
3938
|
-
}
|
|
3939
|
-
const dedupeCoords = [];
|
|
3940
|
-
const uniqueCoords = new Set();
|
|
3941
|
-
// Dedupe the points.
|
|
3942
|
-
ring.forEach(coord => {
|
|
3943
|
-
const key = coord.join(',');
|
|
3944
|
-
if (!uniqueCoords.has(key)) {
|
|
3945
|
-
uniqueCoords.add(key);
|
|
3946
|
-
dedupeCoords.push(coord);
|
|
3947
|
-
}
|
|
3948
|
-
});
|
|
3949
|
-
// Make sure the last point matches the first.
|
|
3950
|
-
if (dedupeCoords.length > 1) {
|
|
3951
|
-
if (dedupeCoords[0][0] != dedupeCoords[dedupeCoords.length - 1][0] ||
|
|
3952
|
-
dedupeCoords[0][1] != dedupeCoords[dedupeCoords.length - 1][1]) {
|
|
3953
|
-
dedupeCoords.push(dedupeCoords[0]);
|
|
3954
|
-
}
|
|
3955
|
-
}
|
|
3956
|
-
return dedupeCoords;
|
|
3957
|
-
});
|
|
3958
|
-
}
|
|
3959
|
-
function ensureRightHandRule(polygon) {
|
|
3960
|
-
// Ensure the outer ring follows the right-hand rule
|
|
3961
|
-
if (polygon.coordinates.length > 0) {
|
|
3962
|
-
const outerRing = polygon.coordinates[0];
|
|
3963
|
-
if (isClockwise(outerRing)) {
|
|
3964
|
-
polygon.coordinates[0] = outerRing.reverse();
|
|
3965
|
-
}
|
|
3966
|
-
}
|
|
3967
|
-
// Ensure any inner rings (holes) follow the right-hand rule
|
|
3968
|
-
for (let i = 1; i < polygon.coordinates.length; i++) {
|
|
3969
|
-
const innerRing = polygon.coordinates[i];
|
|
3970
|
-
if (!isClockwise(innerRing)) {
|
|
3971
|
-
polygon.coordinates[i] = innerRing.reverse();
|
|
3972
|
-
}
|
|
3973
|
-
}
|
|
3974
|
-
}
|
|
3975
|
-
function isClockwise(ring) {
|
|
3976
|
-
let sum = 0;
|
|
3977
|
-
for (let i = 0; i < ring.length - 1; i++) {
|
|
3978
|
-
const p1 = ring[i];
|
|
3979
|
-
const p2 = ring[i + 1];
|
|
3980
|
-
sum += (p2[0] - p1[0]) * (p2[1] + p1[1]);
|
|
3981
|
-
}
|
|
3982
|
-
return sum > 0;
|
|
3983
|
-
}
|
|
3984
|
-
|
|
3985
|
-
function OnNextCRender(viewer, callback) {
|
|
3986
|
-
const removal = viewer.scene.postRender.addEventListener(() => {
|
|
3987
|
-
removal();
|
|
3988
|
-
callback();
|
|
3989
|
-
});
|
|
3990
|
-
}
|
|
3991
|
-
function GetCValue(viewer, obj) {
|
|
3992
|
-
if (obj === null || obj === void 0 ? void 0 : obj.getValue) {
|
|
3993
|
-
let date = viewer.scene.lastRenderTime;
|
|
3994
|
-
if (!date) {
|
|
3995
|
-
date = viewer.clock.currentTime;
|
|
3996
|
-
}
|
|
3997
|
-
return obj.getValue(date);
|
|
3998
|
-
}
|
|
3999
|
-
return obj;
|
|
4000
|
-
}
|
|
4001
|
-
/*
|
|
4002
|
-
* Marks an EntityCollection as one this library created and fully controls (a menu item's own data source).
|
|
4003
|
-
*/
|
|
4004
|
-
const OWNED_CCOLLECTION_KEY = "_bruceOwnedCollection";
|
|
4005
|
-
function MarkCCollectionOwned(collection) {
|
|
4006
|
-
if (collection) {
|
|
4007
|
-
collection[OWNED_CCOLLECTION_KEY] = true;
|
|
4008
|
-
}
|
|
4009
|
-
}
|
|
4010
|
-
function IsCCollectionOwned(collection) {
|
|
4011
|
-
return Boolean(collection && collection[OWNED_CCOLLECTION_KEY]);
|
|
4012
|
-
}
|
|
4013
|
-
/**
|
|
4014
|
-
* Runs a bulk collection mutation with every given collection's events suspended, so Cesium raises one
|
|
4015
|
-
* collectionChanged per collection for the whole pass instead of one per entity.
|
|
4016
|
-
*
|
|
4017
|
-
* Takes a set of collections rather than assuming `viewer.entities`, because managed visuals live in their menu
|
|
4018
|
-
* item's own data source: suspending the wrong collection silently does nothing.
|
|
4019
|
-
* @param collections Duplicates and empty entries are ignored.
|
|
4020
|
-
* @param run
|
|
4021
|
-
*/
|
|
4022
|
-
function WithSuspendedCCollections(collections, run) {
|
|
4023
|
-
const unique = [];
|
|
4024
|
-
for (const collection of collections) {
|
|
4025
|
-
if (collection && unique.indexOf(collection) === -1) {
|
|
4026
|
-
unique.push(collection);
|
|
4027
|
-
}
|
|
4028
|
-
}
|
|
4029
|
-
for (const collection of unique) {
|
|
4030
|
-
collection.suspendEvents();
|
|
4031
|
-
}
|
|
4032
|
-
try {
|
|
4033
|
-
return run();
|
|
4034
|
-
}
|
|
4035
|
-
finally {
|
|
4036
|
-
for (const collection of unique) {
|
|
4037
|
-
try {
|
|
4038
|
-
collection.resumeEvents();
|
|
4039
|
-
}
|
|
4040
|
-
catch (e) {
|
|
4041
|
-
console.error(e);
|
|
4042
|
-
}
|
|
4043
|
-
}
|
|
4044
|
-
}
|
|
4045
|
-
}
|
|
4046
|
-
/**
|
|
4047
|
-
* Returns the collection a graphic belongs to, falling back to the viewer's own when it has never been added.
|
|
4048
|
-
* @param viewer
|
|
4049
|
-
* @param entity
|
|
4050
|
-
*/
|
|
4051
|
-
function GetCEntityCollection(viewer, entity) {
|
|
4052
|
-
const owner = entity === null || entity === void 0 ? void 0 : entity.entityCollection;
|
|
4053
|
-
return owner ? owner : viewer === null || viewer === void 0 ? void 0 : viewer.entities;
|
|
4054
|
-
}
|
|
4055
|
-
/**
|
|
4056
|
-
* Returns whether a graphic is currently in the scene, looking in whichever collection owns it.
|
|
4057
|
-
* @param viewer
|
|
4058
|
-
* @param entity
|
|
4059
|
-
*/
|
|
4060
|
-
function IsCEntityInScene(viewer, entity) {
|
|
4061
|
-
const collection = GetCEntityCollection(viewer, entity);
|
|
4062
|
-
return Boolean(collection && entity && collection.contains(entity));
|
|
4063
|
-
}
|
|
4064
|
-
/**
|
|
4065
|
-
* Removes a graphic from whichever collection owns it. Returns whether it removed anything.
|
|
4066
|
-
* @param viewer
|
|
4067
|
-
* @param entity
|
|
4068
|
-
*/
|
|
4069
|
-
function RemoveCEntityFromScene(viewer, entity) {
|
|
4070
|
-
var _a;
|
|
4071
|
-
if (!entity) {
|
|
4072
|
-
return false;
|
|
4073
|
-
}
|
|
4074
|
-
const collection = GetCEntityCollection(viewer, entity);
|
|
4075
|
-
if (collection === null || collection === void 0 ? void 0 : collection.contains(entity)) {
|
|
4076
|
-
return collection.remove(entity);
|
|
4077
|
-
}
|
|
4078
|
-
// A stale owner reference and the graphic ended up in the viewer's collection anyway.
|
|
4079
|
-
if (collection !== (viewer === null || viewer === void 0 ? void 0 : viewer.entities) && ((_a = viewer === null || viewer === void 0 ? void 0 : viewer.entities) === null || _a === void 0 ? void 0 : _a.contains(entity))) {
|
|
4080
|
-
return viewer.entities.remove(entity);
|
|
4081
|
-
}
|
|
4082
|
-
return false;
|
|
4083
|
-
}
|
|
4084
|
-
/**
|
|
4085
|
-
* Adds a graphic back into whichever collection owns it, or the viewer's if it has no owner yet.
|
|
4086
|
-
* @param viewer
|
|
4087
|
-
* @param entity
|
|
4088
|
-
*/
|
|
4089
|
-
function AddCEntityToScene(viewer, entity, fallbackCollection) {
|
|
4090
|
-
if (!entity) {
|
|
4091
|
-
return false;
|
|
4092
|
-
}
|
|
4093
|
-
// An existing owner always wins, so a graphic is never migrated out from under whoever holds it.
|
|
4094
|
-
const owner = entity.entityCollection;
|
|
4095
|
-
const collection = owner ? owner : (fallbackCollection ? fallbackCollection : viewer === null || viewer === void 0 ? void 0 : viewer.entities);
|
|
4096
|
-
if (!collection || collection.contains(entity)) {
|
|
4097
|
-
return false;
|
|
4098
|
-
}
|
|
4099
|
-
collection.add(entity);
|
|
4100
|
-
return true;
|
|
4101
|
-
}
|
|
4102
|
-
/**
|
|
4103
|
-
* Returns whether toggling `show` on these graphics is safe, rather than having to add/remove them from the
|
|
4104
|
-
* entity collection to hide them.
|
|
4105
|
-
*
|
|
4106
|
-
* Toggling show is far cheaper than re-adding the graphic to the viewer however a Cesium bug means we can't always use it.
|
|
4107
|
-
* See: https://github.com/CesiumGS/cesium/issues/9370
|
|
4108
|
-
* @param parts The graphic and any sibling graphics, eg. from EntityUtils.GatherEntity.
|
|
4109
|
-
*/
|
|
4110
|
-
function CanToggleShowSafely(parts) {
|
|
4111
|
-
if (!(parts === null || parts === void 0 ? void 0 : parts.length)) {
|
|
4112
|
-
return false;
|
|
4113
|
-
}
|
|
4114
|
-
for (const part of parts) {
|
|
4115
|
-
if (!(part instanceof Entity)) {
|
|
4116
|
-
// Not an Entity, so not something whose `show` we can drive.
|
|
4117
|
-
return false;
|
|
4118
|
-
}
|
|
4119
|
-
if (part.polyline && isTruthyCValue(part.polyline.clampToGround)) {
|
|
4120
|
-
return false;
|
|
4121
|
-
}
|
|
4122
|
-
const materialGraphics = [part.polygon, part.corridor, part.ellipse, part.rectangle, part.wall, part.polylineVolume];
|
|
4123
|
-
for (const graphic of materialGraphics) {
|
|
4124
|
-
if (graphic && !isPlainColorMaterial(graphic.material)) {
|
|
4125
|
-
return false;
|
|
4126
|
-
}
|
|
4127
|
-
}
|
|
4128
|
-
}
|
|
4129
|
-
return true;
|
|
4130
|
-
}
|
|
4131
|
-
/**
|
|
4132
|
-
* Returns whether a material is a plain colour, which is what keeps a graphic out of Cesium's per-material batches.
|
|
4133
|
-
* Anything unrecognised counts as not plain, so callers stay on the conservative side.
|
|
4134
|
-
* @param material
|
|
4135
|
-
*/
|
|
4136
|
-
function isPlainColorMaterial(material) {
|
|
4137
|
-
if (material == null) {
|
|
4138
|
-
// Cesium defaults an absent material to white, a plain colour.
|
|
4139
|
-
return true;
|
|
4140
|
-
}
|
|
4141
|
-
return material instanceof ColorMaterialProperty || material instanceof Color;
|
|
4142
|
-
}
|
|
4143
|
-
/**
|
|
4144
|
-
* Resolves a possibly-property boolean without needing a viewer clock, treating anything undeterminable as true
|
|
4145
|
-
* so callers stay on the conservative side.
|
|
4146
|
-
* @param value
|
|
4147
|
-
*/
|
|
4148
|
-
function isTruthyCValue(value) {
|
|
4149
|
-
if (value == null) {
|
|
4150
|
-
return false;
|
|
4151
|
-
}
|
|
4152
|
-
if (typeof value.getValue === "function") {
|
|
4153
|
-
if (value instanceof ConstantProperty) {
|
|
4154
|
-
return Boolean(value.valueOf());
|
|
4155
|
-
}
|
|
4156
|
-
// A non-constant property could be true at any moment, so assume it is.
|
|
4157
|
-
return true;
|
|
4158
|
-
}
|
|
4159
|
-
return Boolean(value);
|
|
4160
|
-
}
|
|
4161
|
-
/**
|
|
4162
|
-
* Returns if two resolved Cesium property values are equal, using the value's own equals() when it has one.
|
|
4163
|
-
* @param a
|
|
4164
|
-
* @param b
|
|
4165
|
-
*/
|
|
4166
|
-
function AreCValuesEqual(a, b) {
|
|
4167
|
-
if (a === b) {
|
|
4168
|
-
return true;
|
|
4169
|
-
}
|
|
4170
|
-
// One side is null/undefined and the other isn't.
|
|
4171
|
-
if (a == null || b == null) {
|
|
4172
|
-
return false;
|
|
4173
|
-
}
|
|
4174
|
-
if (typeof a.equals === "function") {
|
|
4175
|
-
return a.equals(b) === true;
|
|
4176
|
-
}
|
|
4177
|
-
return false;
|
|
4178
|
-
}
|
|
4179
|
-
/**
|
|
4180
|
-
* Wraps a value in a ConstantProperty and assigns it to a graphic's property, but only when the resolved
|
|
4181
|
-
* value actually differs. Returns whether it assigned.
|
|
4182
|
-
* @param params
|
|
4183
|
-
*/
|
|
4184
|
-
function SetCPropIfChanged(params) {
|
|
4185
|
-
const { viewer, graphic, property, value, compare } = params;
|
|
4186
|
-
if (!graphic) {
|
|
4187
|
-
return false;
|
|
4188
|
-
}
|
|
4189
|
-
const oldValue = GetCValue(viewer, graphic[property]);
|
|
4190
|
-
const isEqual = compare ? compare(oldValue, value) : AreCValuesEqual(oldValue, value);
|
|
4191
|
-
if (isEqual) {
|
|
4192
|
-
return false;
|
|
4193
|
-
}
|
|
4194
|
-
graphic[property] = new ConstantProperty(value);
|
|
4195
|
-
return true;
|
|
4196
|
-
}
|
|
4197
|
-
function ColorToCColor(color) {
|
|
4198
|
-
return new Color(color.red ? color.red / 255 : 0, color.green ? color.green / 255 : 0, color.blue ? color.blue / 255 : 0, color.alpha);
|
|
4199
|
-
}
|
|
4200
|
-
/**
|
|
4201
|
-
* Removes duplicate points in a row and returns a new array.
|
|
4202
|
-
* Passed array is not mutated.
|
|
4203
|
-
* @param posses
|
|
4204
|
-
*/
|
|
4205
|
-
function CullDuplicateCPosses(posses) {
|
|
4206
|
-
const newPosses = [];
|
|
4207
|
-
let lastPos = null;
|
|
4208
|
-
for (let i = 0; i < posses.length; i++) {
|
|
4209
|
-
const pos = posses[i];
|
|
4210
|
-
// Avoiding 'Cesium.Cartesian3.equals' because passed data might be just a json blob in certain cases.
|
|
4211
|
-
if (pos && (!lastPos || (pos.x != lastPos.x || pos.y != lastPos.y || pos.z != lastPos.z))) {
|
|
4212
|
-
newPosses.push(pos);
|
|
4213
|
-
lastPos = pos;
|
|
4214
|
-
}
|
|
4215
|
-
}
|
|
4216
|
-
return newPosses;
|
|
4217
|
-
}
|
|
4218
|
-
/**
|
|
4219
|
-
* Returns if the given positions are equal.
|
|
4220
|
-
* @param a
|
|
4221
|
-
* @param b
|
|
4222
|
-
*/
|
|
4223
|
-
function CompareCPosses(a, b) {
|
|
4224
|
-
// Same reference.
|
|
4225
|
-
if (a == b) {
|
|
4226
|
-
return true;
|
|
4227
|
-
}
|
|
4228
|
-
// Different lengths or one is null.
|
|
4229
|
-
if ((!a || !b) || (a.length != b.length)) {
|
|
4230
|
-
return false;
|
|
4231
|
-
}
|
|
4232
|
-
for (let i = 0; i < a.length; i++) {
|
|
4233
|
-
const posA = a[i];
|
|
4234
|
-
const posB = b[i];
|
|
4235
|
-
// Null detected.
|
|
4236
|
-
if (!posA || !posB) {
|
|
4237
|
-
return false;
|
|
4238
|
-
}
|
|
4239
|
-
// Position values don't match.
|
|
4240
|
-
if (!Cartes.IsEqualCartes3(posA, posB)) {
|
|
4241
|
-
return false;
|
|
4242
|
-
}
|
|
4243
|
-
}
|
|
4244
|
-
return true;
|
|
4245
|
-
}
|
|
4246
|
-
/**
|
|
4247
|
-
* Returns if the given polygon hierarchies are equal.
|
|
4248
|
-
* @param a
|
|
4249
|
-
* @param b
|
|
4250
|
-
*/
|
|
4251
|
-
function CompareCPolygonHierarchies(a, b) {
|
|
4252
|
-
// Same reference.
|
|
4253
|
-
if (a == b) {
|
|
4254
|
-
return true;
|
|
4255
|
-
}
|
|
4256
|
-
// Different lengths or one is null.
|
|
4257
|
-
if ((!a || !b) || (a.positions.length != b.positions.length)) {
|
|
4258
|
-
return false;
|
|
4259
|
-
}
|
|
4260
|
-
// Positions don't match.
|
|
4261
|
-
if (!CompareCPosses(a.positions, b.positions)) {
|
|
4262
|
-
return false;
|
|
4263
|
-
}
|
|
4264
|
-
const holes = a.holes;
|
|
4265
|
-
const bHoles = b.holes;
|
|
4266
|
-
// Number of holes don't match.
|
|
4267
|
-
if (holes.length != bHoles.length) {
|
|
4268
|
-
return false;
|
|
4269
|
-
}
|
|
4270
|
-
for (let i = 0; i < holes.length; i++) {
|
|
4271
|
-
// Hole positions don't match.
|
|
4272
|
-
if (!CompareCPosses(holes[i].positions, bHoles[i].positions)) {
|
|
4273
|
-
return false;
|
|
4274
|
-
}
|
|
4275
|
-
}
|
|
4276
|
-
return true;
|
|
4277
|
-
}
|
|
4278
|
-
|
|
4279
|
-
const CESIUM_INSPECTOR_KEY = "_nextspace_inspector";
|
|
4280
|
-
const CESIUM_TIMELINE_KEY = "_nextspace_timeline";
|
|
4281
|
-
const CESIUM_TIMELINE_LIVE_KEY = "_nextspace_timeline_live";
|
|
4282
|
-
const CESIUM_TIMELINE_LIVE_PADDING_KEY = "_nextspace_timeline_live_padding";
|
|
4283
|
-
const CESIUM_TIMELINE_INTERVAL_KEY = "_nextspace_timeline_interval";
|
|
4284
|
-
const CESIUM_MODEL_SPACE_KEY = "_nextspace_model_space";
|
|
4285
|
-
const DEFAULT_LIVE_PADDING_SECONDS = 30 * 60;
|
|
4286
|
-
var ViewUtils;
|
|
4287
|
-
(function (ViewUtils) {
|
|
4288
|
-
function GatherLegacyMapTiles(params) {
|
|
4289
|
-
const viewer = params.viewer;
|
|
4290
|
-
const collection = viewer.imageryLayers;
|
|
4291
|
-
const tiles = [];
|
|
4292
|
-
for (let i = 0; i < collection.length; i++) {
|
|
4293
|
-
const layer = collection.get(i);
|
|
4294
|
-
if (layer._bName) {
|
|
4295
|
-
tiles.push({
|
|
4296
|
-
alpha: layer.alpha,
|
|
4297
|
-
brightness: layer.brightness,
|
|
4298
|
-
contrast: layer.contrast,
|
|
4299
|
-
hue: layer.hue,
|
|
4300
|
-
saturation: layer.saturation,
|
|
4301
|
-
gamma: layer.gamma,
|
|
4302
|
-
title: layer._bName,
|
|
4303
|
-
});
|
|
4304
|
-
}
|
|
4305
|
-
}
|
|
4306
|
-
return {
|
|
4307
|
-
imagery: tiles.reverse()
|
|
4308
|
-
};
|
|
4309
|
-
}
|
|
4310
|
-
ViewUtils.GatherLegacyMapTiles = GatherLegacyMapTiles;
|
|
4311
|
-
function GatherLegacyTerrainTile(params) {
|
|
4312
|
-
const viewer = params.viewer;
|
|
4313
|
-
const enabled = viewer.terrainProvider;
|
|
4314
|
-
if (enabled === null || enabled === void 0 ? void 0 : enabled._bName) {
|
|
4315
|
-
return {
|
|
4316
|
-
terrain: enabled._bName
|
|
4317
|
-
};
|
|
4318
|
-
}
|
|
4319
|
-
return {
|
|
4320
|
-
terrain: "flatterrain"
|
|
4321
|
-
};
|
|
4322
|
-
}
|
|
4323
|
-
ViewUtils.GatherLegacyTerrainTile = GatherLegacyTerrainTile;
|
|
4324
|
-
function GatherMapTiles(params) {
|
|
4325
|
-
const viewer = params.viewer;
|
|
4326
|
-
const imagery = viewer.imageryLayers;
|
|
4327
|
-
const tiles = [];
|
|
4328
|
-
for (let i = 0; i < imagery.length; i++) {
|
|
4329
|
-
const provider = imagery.get(i);
|
|
4330
|
-
if (provider._bMeta) {
|
|
4331
|
-
const idCombo = provider._bMeta.accountId + provider._bMeta.tilesetId;
|
|
4332
|
-
if (!tiles.find(x => x.accountId + x.tilesetId === idCombo)) {
|
|
4333
|
-
tiles.push({
|
|
4334
|
-
accountId: provider._bMeta.accountId,
|
|
4335
|
-
tilesetId: provider._bMeta.tilesetId,
|
|
4336
|
-
alpha: provider.alpha,
|
|
4337
|
-
brightness: provider.brightness,
|
|
4338
|
-
contrast: provider.contrast,
|
|
4339
|
-
hue: provider.hue,
|
|
4340
|
-
saturation: provider.saturation,
|
|
4341
|
-
gamma: provider.gamma
|
|
4342
|
-
});
|
|
4343
|
-
}
|
|
4344
|
-
}
|
|
4345
|
-
}
|
|
4346
|
-
return {
|
|
4347
|
-
imagery: tiles
|
|
4348
|
-
};
|
|
4349
|
-
}
|
|
4350
|
-
ViewUtils.GatherMapTiles = GatherMapTiles;
|
|
4351
|
-
function GatherTerrainTile(params) {
|
|
4352
|
-
const viewer = params.viewer;
|
|
4353
|
-
const provider = viewer.terrainProvider;
|
|
4354
|
-
if (provider === null || provider === void 0 ? void 0 : provider._bMeta) {
|
|
4355
|
-
return {
|
|
4356
|
-
terrain: {
|
|
4357
|
-
accountId: provider._bMeta.accountId,
|
|
4358
|
-
tilesetId: provider._bMeta.tilesetId,
|
|
4359
|
-
}
|
|
4360
|
-
};
|
|
4361
|
-
}
|
|
4362
|
-
else if (provider instanceof EllipsoidTerrainProvider) {
|
|
4363
|
-
return {
|
|
4364
|
-
terrain: {
|
|
4365
|
-
tilesetId: ProjectViewTile.EDefaultTerrain.FlatTerrain,
|
|
4366
|
-
accountId: null
|
|
4367
|
-
}
|
|
4368
|
-
};
|
|
4369
|
-
}
|
|
4370
|
-
return null;
|
|
4371
|
-
}
|
|
4372
|
-
ViewUtils.GatherTerrainTile = GatherTerrainTile;
|
|
4373
|
-
function SetTerrainWireframeStatus(params) {
|
|
4374
|
-
if (!params.viewer[CESIUM_INSPECTOR_KEY]) {
|
|
4375
|
-
const InspectorClass = CesiumInspector;
|
|
4376
|
-
if (InspectorClass) {
|
|
4377
|
-
const inspector = new InspectorClass(document.createElement("div"), params.viewer.scene);
|
|
4378
|
-
inspector.container.style.display = "none";
|
|
4379
|
-
params.viewer[CESIUM_INSPECTOR_KEY] = inspector;
|
|
4380
|
-
params.viewer.scene.requestRender();
|
|
4381
|
-
}
|
|
4382
|
-
}
|
|
4383
|
-
if (params.viewer[CESIUM_INSPECTOR_KEY]) {
|
|
4384
|
-
params.viewer[CESIUM_INSPECTOR_KEY].viewModel.wireframe = params.status;
|
|
4385
|
-
}
|
|
4386
|
-
}
|
|
4387
|
-
ViewUtils.SetTerrainWireframeStatus = SetTerrainWireframeStatus;
|
|
4388
|
-
function GetTerrainWireframeStatus(params) {
|
|
4389
|
-
var _a, _b;
|
|
4390
|
-
if (!params.viewer[CESIUM_INSPECTOR_KEY]) {
|
|
4391
|
-
return false;
|
|
4392
|
-
}
|
|
4393
|
-
return (_b = (_a = params.viewer[CESIUM_INSPECTOR_KEY]) === null || _a === void 0 ? void 0 : _a.viewModel) === null || _b === void 0 ? void 0 : _b.wireframe;
|
|
4394
|
-
}
|
|
4395
|
-
ViewUtils.GetTerrainWireframeStatus = GetTerrainWireframeStatus;
|
|
4396
|
-
/**
|
|
4397
|
-
* Changes between perspective and orthographic view.
|
|
4398
|
-
* When Cesium stops being bad at picking positions in 2d mode we'll use the flat earth mode instead.
|
|
4399
|
-
* @param params
|
|
4400
|
-
*/
|
|
4401
|
-
function Set2dStatus(params) {
|
|
4402
|
-
const { viewer, status: is2d, moveCamera } = params;
|
|
4403
|
-
const curLens2d = viewer.camera.frustum instanceof OrthographicFrustum;
|
|
4404
|
-
if (curLens2d && !is2d) {
|
|
4405
|
-
OnNextCRender(viewer, () => {
|
|
4406
|
-
viewer.camera.switchToPerspectiveFrustum();
|
|
4407
|
-
viewer.scene.screenSpaceCameraController.enableTilt = true;
|
|
4408
|
-
});
|
|
4409
|
-
viewer.scene.requestRender();
|
|
4410
|
-
}
|
|
4411
|
-
else if (!curLens2d && is2d) {
|
|
4412
|
-
OnNextCRender(viewer, () => {
|
|
4413
|
-
viewer.camera.switchToOrthographicFrustum();
|
|
4414
|
-
viewer.scene.screenSpaceCameraController.enableTilt = false;
|
|
4415
|
-
});
|
|
4416
|
-
if (moveCamera != false) {
|
|
4417
|
-
try {
|
|
4418
|
-
// Face camera downwards to make it look 2d.
|
|
4419
|
-
// We want to try make it look at the center-point of the current view.
|
|
4420
|
-
// If center cannot be calculated then we'll simply raise the camera and face it downwards.
|
|
4421
|
-
const scene = viewer.scene;
|
|
4422
|
-
const windowPosition = new Cartesian2(scene.canvas.clientWidth / 2, scene.canvas.clientHeight / 2);
|
|
4423
|
-
const ray = viewer.camera.getPickRay(windowPosition);
|
|
4424
|
-
const intersection = scene.globe.pick(ray, scene);
|
|
4425
|
-
let center;
|
|
4426
|
-
if (defined(intersection)) {
|
|
4427
|
-
center = Cartographic.fromCartesian(intersection);
|
|
4428
|
-
}
|
|
4429
|
-
// Use current camera position if we can't calculate the center.
|
|
4430
|
-
else {
|
|
4431
|
-
center = Cartographic.fromCartesian(viewer.camera.position);
|
|
4432
|
-
center.height = 0;
|
|
4433
|
-
}
|
|
4434
|
-
center.height = viewer.camera.positionCartographic.height + 100;
|
|
4435
|
-
viewer.camera.setView({
|
|
4436
|
-
destination: Cartographic.toCartesian(center),
|
|
4437
|
-
orientation: {
|
|
4438
|
-
heading: 0.0,
|
|
4439
|
-
pitch: Math$1.toRadians(-90.0),
|
|
4440
|
-
roll: 0.0
|
|
4441
|
-
}
|
|
4442
|
-
});
|
|
4443
|
-
}
|
|
4444
|
-
catch (e) {
|
|
4445
|
-
console.error(e);
|
|
4446
|
-
}
|
|
4447
|
-
}
|
|
4448
|
-
viewer.scene.requestRender();
|
|
4449
|
-
}
|
|
4450
|
-
}
|
|
4451
|
-
ViewUtils.Set2dStatus = Set2dStatus;
|
|
4452
|
-
function Get2dStatus(params) {
|
|
4453
|
-
const { viewer } = params;
|
|
4454
|
-
return viewer.camera.frustum instanceof OrthographicFrustum;
|
|
4455
|
-
}
|
|
4456
|
-
ViewUtils.Get2dStatus = Get2dStatus;
|
|
4457
|
-
function SetLockedCameraStatus(params) {
|
|
4458
|
-
const { viewer, status } = params;
|
|
4459
|
-
const scene = viewer === null || viewer === void 0 ? void 0 : viewer.scene;
|
|
4460
|
-
if (!scene) {
|
|
4461
|
-
return;
|
|
4462
|
-
}
|
|
4463
|
-
if (status) {
|
|
4464
|
-
scene.screenSpaceCameraController.enableInputs = false;
|
|
4465
|
-
scene.screenSpaceCameraController.enableTranslate = false;
|
|
4466
|
-
scene.screenSpaceCameraController.enableZoom = false;
|
|
4467
|
-
scene.screenSpaceCameraController.enableRotate = false;
|
|
4468
|
-
scene.screenSpaceCameraController.enableTilt = false;
|
|
4469
|
-
}
|
|
4470
|
-
else {
|
|
4471
|
-
scene.screenSpaceCameraController.enableInputs = true;
|
|
4472
|
-
scene.screenSpaceCameraController.enableTranslate = true;
|
|
4473
|
-
scene.screenSpaceCameraController.enableZoom = true;
|
|
4474
|
-
scene.screenSpaceCameraController.enableRotate = true;
|
|
4475
|
-
if (!ViewUtils.Get2dStatus({ viewer })) {
|
|
4476
|
-
scene.screenSpaceCameraController.enableTilt = true;
|
|
4477
|
-
}
|
|
4478
|
-
}
|
|
4479
|
-
viewer.scene.requestRender();
|
|
4480
|
-
}
|
|
4481
|
-
ViewUtils.SetLockedCameraStatus = SetLockedCameraStatus;
|
|
4482
|
-
function GetLockedCameraStatus(params) {
|
|
4483
|
-
var _a;
|
|
4484
|
-
const scene = (_a = params.viewer) === null || _a === void 0 ? void 0 : _a.scene;
|
|
4485
|
-
if (!scene) {
|
|
4486
|
-
return false;
|
|
4487
|
-
}
|
|
4488
|
-
return !scene.screenSpaceCameraController.enableTranslate;
|
|
4489
|
-
}
|
|
4490
|
-
ViewUtils.GetLockedCameraStatus = GetLockedCameraStatus;
|
|
4491
|
-
/**
|
|
4492
|
-
* Returns the current camera time and related settings.
|
|
4493
|
-
* @param params
|
|
4494
|
-
* @returns
|
|
4495
|
-
*/
|
|
4496
|
-
function GetTimeDetails(params) {
|
|
4497
|
-
const { viewer } = params;
|
|
4498
|
-
const clock = viewer.clock;
|
|
4499
|
-
return {
|
|
4500
|
-
animationSpeed: clock.multiplier,
|
|
4501
|
-
isAnimating: clock.shouldAnimate,
|
|
4502
|
-
startTime: clock.startTime,
|
|
4503
|
-
startTimeIso: clock.startTime.toString(),
|
|
4504
|
-
currentTime: clock.currentTime,
|
|
4505
|
-
currentTimeIso: clock.currentTime.toString(),
|
|
4506
|
-
stopTime: clock.stopTime,
|
|
4507
|
-
stopTimeIso: clock.stopTime.toString(),
|
|
4508
|
-
areCesiumValues: clock[CESIUM_TIMELINE_KEY] != true,
|
|
4509
|
-
isLive: clock[CESIUM_TIMELINE_LIVE_KEY] == true,
|
|
4510
|
-
livePaddingSeconds: clock[CESIUM_TIMELINE_LIVE_PADDING_KEY] || DEFAULT_LIVE_PADDING_SECONDS
|
|
4292
|
+
}
|
|
4293
|
+
}
|
|
4294
|
+
else if (geometry.LineString) {
|
|
4295
|
+
count += Geometry$1.ParsePoints(geometry.LineString).length;
|
|
4296
|
+
}
|
|
4297
|
+
else if (geometry.Point) {
|
|
4298
|
+
count += 1;
|
|
4299
|
+
}
|
|
4511
4300
|
};
|
|
4301
|
+
traverse(geometry);
|
|
4302
|
+
return count;
|
|
4512
4303
|
}
|
|
4513
|
-
|
|
4304
|
+
SimplifyGeometry.CountPoints = CountPoints;
|
|
4514
4305
|
/**
|
|
4515
|
-
*
|
|
4516
|
-
*
|
|
4517
|
-
*
|
|
4518
|
-
* @param params
|
|
4306
|
+
* Simplifies input geometry.
|
|
4307
|
+
* This will turn it into GeoJSON, run it through turf, then back to Bruce geometry.
|
|
4308
|
+
* @param geometry
|
|
4519
4309
|
*/
|
|
4520
|
-
function
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
clock.startTime = startTime;
|
|
4310
|
+
function Simplify(entityId, geometry, tolerance) {
|
|
4311
|
+
var _a;
|
|
4312
|
+
if (!geometry || !isTurfAvailable() || !turf.simplify) {
|
|
4313
|
+
return geometry;
|
|
4525
4314
|
}
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4315
|
+
const original = geometry;
|
|
4316
|
+
// Convert to geojson so that we can interact with turf.
|
|
4317
|
+
const gFeature = Geometry$1.ToGeoJsonFeature({
|
|
4318
|
+
geometry: geometry
|
|
4319
|
+
});
|
|
4320
|
+
// Unkink the geometry.
|
|
4321
|
+
// This removes overlapping polygons before we start merging and simplifying.
|
|
4322
|
+
// Commented out because it has crashes and doesn't handle holes.
|
|
4323
|
+
untangleFeature(gFeature);
|
|
4324
|
+
// Union the geometry.
|
|
4325
|
+
// This merges overlapping polygons.
|
|
4326
|
+
unionFeature(gFeature);
|
|
4327
|
+
// Simplify the geometry.
|
|
4328
|
+
if (tolerance > 0) {
|
|
4329
|
+
gFeature.geometry = turf.simplify(gFeature.geometry, {
|
|
4330
|
+
tolerance: tolerance,
|
|
4331
|
+
highQuality: true,
|
|
4332
|
+
mutate: true
|
|
4333
|
+
});
|
|
4531
4334
|
}
|
|
4532
|
-
|
|
4533
|
-
|
|
4335
|
+
// Converting back to Bruce geometry.
|
|
4336
|
+
const simplified = (_a = Geometry$1.FromGeoJson({
|
|
4337
|
+
geoJson: gFeature
|
|
4338
|
+
})) === null || _a === void 0 ? void 0 : _a.geometry;
|
|
4339
|
+
// A polygon we cannot vouch for is worse than an unsimplified one, so fall back instead of shipping it.
|
|
4340
|
+
if (!simplified || !isSafeToRender(simplified)) {
|
|
4341
|
+
return original;
|
|
4534
4342
|
}
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4343
|
+
return simplified;
|
|
4344
|
+
}
|
|
4345
|
+
SimplifyGeometry.Simplify = Simplify;
|
|
4346
|
+
/**
|
|
4347
|
+
* Whether a simplified geometry still describes something a renderer can triangulate.
|
|
4348
|
+
* @param geometry the simplification result.
|
|
4349
|
+
* @returns false when any polygon has a collapsed ring, a hole outside its outer ring, or a hole
|
|
4350
|
+
* wound the same way as its outer ring.
|
|
4351
|
+
*/
|
|
4352
|
+
function IsSafeToRender(geometry) {
|
|
4353
|
+
return isSafeToRender(geometry);
|
|
4354
|
+
}
|
|
4355
|
+
SimplifyGeometry.IsSafeToRender = IsSafeToRender;
|
|
4356
|
+
})(SimplifyGeometry || (SimplifyGeometry = {}));
|
|
4357
|
+
// A ring needs three distinct corners plus the closing repeat before it encloses any area.
|
|
4358
|
+
const MIN_RING_POSITIONS = 4;
|
|
4359
|
+
function isSafeToRender(geometry) {
|
|
4360
|
+
let safe = true;
|
|
4361
|
+
const check = (g) => {
|
|
4362
|
+
if (!safe) {
|
|
4363
|
+
return;
|
|
4540
4364
|
}
|
|
4541
|
-
if (
|
|
4542
|
-
|
|
4365
|
+
if (g === null || g === void 0 ? void 0 : g.MultiGeometry) {
|
|
4366
|
+
g.MultiGeometry.forEach(check);
|
|
4367
|
+
return;
|
|
4543
4368
|
}
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
if (stopDate) {
|
|
4547
|
-
clock.stopTime = stopDate;
|
|
4548
|
-
}
|
|
4369
|
+
if (!(g === null || g === void 0 ? void 0 : g.Polygon) || g.Polygon.length === 0) {
|
|
4370
|
+
return;
|
|
4549
4371
|
}
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4372
|
+
let outer = null;
|
|
4373
|
+
let outerIsClockwise = false;
|
|
4374
|
+
for (let i = 0; i < g.Polygon.length; i++) {
|
|
4375
|
+
const points = Geometry$1.ParsePoints(g.Polygon[i].LinearRing);
|
|
4376
|
+
if (!points || points.length < MIN_RING_POSITIONS) {
|
|
4377
|
+
safe = false;
|
|
4378
|
+
return;
|
|
4555
4379
|
}
|
|
4556
|
-
|
|
4557
|
-
|
|
4380
|
+
const clockwise = signedRingArea(points) < 0;
|
|
4381
|
+
if (g.Polygon[i].Facing !== "in") {
|
|
4382
|
+
outer = points;
|
|
4383
|
+
outerIsClockwise = clockwise;
|
|
4384
|
+
continue;
|
|
4558
4385
|
}
|
|
4559
|
-
|
|
4560
|
-
|
|
4386
|
+
// A hole with no outer ring ahead of it cannot be subtracted from anything.
|
|
4387
|
+
if (!outer) {
|
|
4388
|
+
safe = false;
|
|
4389
|
+
return;
|
|
4561
4390
|
}
|
|
4562
|
-
if (
|
|
4563
|
-
|
|
4391
|
+
if (clockwise === outerIsClockwise) {
|
|
4392
|
+
safe = false;
|
|
4393
|
+
return;
|
|
4394
|
+
}
|
|
4395
|
+
for (let j = 0; j < points.length; j++) {
|
|
4396
|
+
if (!isPointInRing(points[j], outer)) {
|
|
4397
|
+
safe = false;
|
|
4398
|
+
return;
|
|
4399
|
+
}
|
|
4564
4400
|
}
|
|
4565
4401
|
}
|
|
4566
|
-
|
|
4567
|
-
|
|
4402
|
+
};
|
|
4403
|
+
check(geometry);
|
|
4404
|
+
return safe;
|
|
4405
|
+
}
|
|
4406
|
+
function signedRingArea(points) {
|
|
4407
|
+
let sum = 0;
|
|
4408
|
+
for (let i = 0; i < points.length; i++) {
|
|
4409
|
+
const a = points[i];
|
|
4410
|
+
const b = points[(i + 1) % points.length];
|
|
4411
|
+
sum += a.longitude * b.latitude - b.longitude * a.latitude;
|
|
4412
|
+
}
|
|
4413
|
+
return sum / 2;
|
|
4414
|
+
}
|
|
4415
|
+
function isPointInRing(point, ring) {
|
|
4416
|
+
let inside = false;
|
|
4417
|
+
for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {
|
|
4418
|
+
const a = ring[i];
|
|
4419
|
+
const b = ring[j];
|
|
4420
|
+
if ((a.latitude > point.latitude) !== (b.latitude > point.latitude)
|
|
4421
|
+
&& point.longitude < (b.longitude - a.longitude) * (point.latitude - a.latitude) / (b.latitude - a.latitude) + a.longitude) {
|
|
4422
|
+
inside = !inside;
|
|
4568
4423
|
}
|
|
4569
|
-
|
|
4570
|
-
|
|
4424
|
+
}
|
|
4425
|
+
return inside;
|
|
4426
|
+
}
|
|
4427
|
+
/**
|
|
4428
|
+
* Runs through all found polygons and runs unkink through turf on them.
|
|
4429
|
+
* @param feature
|
|
4430
|
+
*/
|
|
4431
|
+
function untangleFeature(feature) {
|
|
4432
|
+
// Collection to add to because the result might be multiple from an unkink.
|
|
4433
|
+
const collection = {
|
|
4434
|
+
geometries: [],
|
|
4435
|
+
type: "GeometryCollection"
|
|
4436
|
+
};
|
|
4437
|
+
// Runs a dedupe and unkink on the coordinates.
|
|
4438
|
+
// Returns if the coordinates were added to the collection.
|
|
4439
|
+
const processCoordinates = (coords) => {
|
|
4440
|
+
try {
|
|
4441
|
+
// Dedupe the coordinates to avoid issues with unkink.
|
|
4442
|
+
coords = dedupeCoordinates(coords);
|
|
4443
|
+
const outer = [];
|
|
4444
|
+
let inner = [];
|
|
4445
|
+
// We'll unkink each ring separately as this is killing the holes when it is done as a whole.
|
|
4446
|
+
// So we'll do it separate then recombine.
|
|
4447
|
+
for (let i = 0; i < coords.length; i++) {
|
|
4448
|
+
const ring = coords[i];
|
|
4449
|
+
const unkink = turf.unkinkPolygon({
|
|
4450
|
+
type: "Polygon",
|
|
4451
|
+
coordinates: [ring]
|
|
4452
|
+
});
|
|
4453
|
+
if (unkink.type == "FeatureCollection") {
|
|
4454
|
+
let target = i == 0 ? outer : inner;
|
|
4455
|
+
for (let j = 0; j < unkink.features.length; j++) {
|
|
4456
|
+
const unkinked = unkink.features[j].geometry.coordinates;
|
|
4457
|
+
if (unkinked.length > 0) {
|
|
4458
|
+
target.push(unkinked[0]);
|
|
4459
|
+
}
|
|
4460
|
+
}
|
|
4461
|
+
}
|
|
4462
|
+
else {
|
|
4463
|
+
console.error("Unexpected unkink result.", unkink);
|
|
4464
|
+
}
|
|
4465
|
+
}
|
|
4466
|
+
// Recreate the rings and reapply to the collection.
|
|
4467
|
+
if (outer.length > 0) {
|
|
4468
|
+
// Unkinking a self touching boundary splits it into pieces. Keeping whichever piece
|
|
4469
|
+
// happened to come back first can discard most of the shape, so keep the biggest one.
|
|
4470
|
+
let keep = outer[0];
|
|
4471
|
+
if (outer.length > 1) {
|
|
4472
|
+
let best = Math.abs(ringArea(keep));
|
|
4473
|
+
for (let i = 1; i < outer.length; i++) {
|
|
4474
|
+
const area = Math.abs(ringArea(outer[i]));
|
|
4475
|
+
if (area > best) {
|
|
4476
|
+
best = area;
|
|
4477
|
+
keep = outer[i];
|
|
4478
|
+
}
|
|
4479
|
+
}
|
|
4480
|
+
}
|
|
4481
|
+
const combinedCoords = [keep];
|
|
4482
|
+
for (let i = 0; i < inner.length; i++) {
|
|
4483
|
+
// A hole belonging to a piece that was just discarded is no longer inside anything,
|
|
4484
|
+
// and a hole crossing the boundary is what tears the fill.
|
|
4485
|
+
if (isRingInsideRing(inner[i], keep)) {
|
|
4486
|
+
combinedCoords.push(inner[i]);
|
|
4487
|
+
}
|
|
4488
|
+
}
|
|
4489
|
+
// Add the combined coordinates to the collection
|
|
4490
|
+
const polygon = {
|
|
4491
|
+
type: "Polygon",
|
|
4492
|
+
coordinates: combinedCoords
|
|
4493
|
+
};
|
|
4494
|
+
// Ensure right-hand rule is followed.
|
|
4495
|
+
ensureRightHandRule(polygon);
|
|
4496
|
+
// Add to the collection.
|
|
4497
|
+
collection.geometries.push(polygon);
|
|
4498
|
+
return true;
|
|
4499
|
+
}
|
|
4571
4500
|
}
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
if (livePaddingSeconds != null) {
|
|
4575
|
-
clock[CESIUM_TIMELINE_LIVE_PADDING_KEY] = livePaddingSeconds || DEFAULT_LIVE_PADDING_SECONDS;
|
|
4501
|
+
catch (e) {
|
|
4502
|
+
// console.error("Failed to unkink polygon.", e);
|
|
4576
4503
|
}
|
|
4577
|
-
|
|
4578
|
-
|
|
4504
|
+
return false;
|
|
4505
|
+
};
|
|
4506
|
+
const processGeometry = (geometry) => {
|
|
4507
|
+
let added = false;
|
|
4508
|
+
if (geometry.type == "Polygon") {
|
|
4509
|
+
added = processCoordinates(geometry.coordinates);
|
|
4579
4510
|
}
|
|
4580
|
-
if (
|
|
4581
|
-
|
|
4511
|
+
else if (geometry.type == "MultiPolygon") {
|
|
4512
|
+
for (let i = 0; i < geometry.coordinates.length; i++) {
|
|
4513
|
+
added = processCoordinates(geometry.coordinates[i]) || added;
|
|
4514
|
+
}
|
|
4582
4515
|
}
|
|
4583
|
-
|
|
4584
|
-
|
|
4516
|
+
if (!added) {
|
|
4517
|
+
// Adding original since we can't unkink it.
|
|
4518
|
+
collection.geometries.push(geometry);
|
|
4585
4519
|
}
|
|
4520
|
+
};
|
|
4521
|
+
if (feature.geometry.type == "GeometryCollection") {
|
|
4522
|
+
feature.geometry.geometries.forEach((geometry) => {
|
|
4523
|
+
processGeometry(geometry);
|
|
4524
|
+
});
|
|
4586
4525
|
}
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4526
|
+
else {
|
|
4527
|
+
processGeometry(feature.geometry);
|
|
4528
|
+
}
|
|
4529
|
+
// Re-assign the geometry.
|
|
4530
|
+
if (collection.geometries.length == 1) {
|
|
4531
|
+
feature.geometry = collection.geometries[0];
|
|
4532
|
+
}
|
|
4533
|
+
else {
|
|
4534
|
+
feature.geometry = collection;
|
|
4535
|
+
}
|
|
4536
|
+
}
|
|
4537
|
+
/**
|
|
4538
|
+
* Runs through all found polygons and unions them using turf.
|
|
4539
|
+
* Failed unions are ignored and the original is kept.
|
|
4540
|
+
* @param feature
|
|
4541
|
+
*/
|
|
4542
|
+
function unionFeature(feature) {
|
|
4543
|
+
// Collection to add to because the result might be multiple from an unkink.
|
|
4544
|
+
const collection = {
|
|
4545
|
+
geometries: [],
|
|
4546
|
+
type: "GeometryCollection"
|
|
4547
|
+
};
|
|
4548
|
+
// We'll turn each geometry into a feature and union them.
|
|
4549
|
+
const tmpCollection = {
|
|
4550
|
+
features: [],
|
|
4551
|
+
type: "FeatureCollection"
|
|
4552
|
+
};
|
|
4553
|
+
if (feature.geometry.type == "GeometryCollection") {
|
|
4554
|
+
feature.geometry.geometries.forEach((geometry) => {
|
|
4555
|
+
if (geometry.type == "Polygon") {
|
|
4556
|
+
tmpCollection.features.push({
|
|
4557
|
+
type: "Feature",
|
|
4558
|
+
geometry: geometry,
|
|
4559
|
+
properties: {}
|
|
4560
|
+
});
|
|
4593
4561
|
}
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4562
|
+
else if (geometry.type == "MultiPolygon") {
|
|
4563
|
+
for (let i = 0; i < geometry.coordinates.length; i++) {
|
|
4564
|
+
tmpCollection.features.push({
|
|
4565
|
+
type: "Feature",
|
|
4566
|
+
geometry: {
|
|
4567
|
+
type: "Polygon",
|
|
4568
|
+
coordinates: geometry.coordinates[i]
|
|
4569
|
+
},
|
|
4570
|
+
properties: {}
|
|
4571
|
+
});
|
|
4572
|
+
}
|
|
4604
4573
|
}
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
4608
|
-
|
|
4609
|
-
}
|
|
4610
|
-
// We'll start an interval that occasionally updates the Cesium clock to stay in the desired settings.
|
|
4611
|
-
// Since it moves live (1 second per second), we don't have to worry about the ranges being out of date quickly.
|
|
4612
|
-
viewer[CESIUM_TIMELINE_INTERVAL_KEY] = setInterval(() => {
|
|
4613
|
-
doUpdate();
|
|
4614
|
-
}, 800);
|
|
4615
|
-
viewer[CESIUM_TIMELINE_LIVE_KEY] = true;
|
|
4616
|
-
// Initial update.
|
|
4617
|
-
doUpdate();
|
|
4574
|
+
// Only focusing on polygons.
|
|
4575
|
+
else {
|
|
4576
|
+
collection.geometries.push(geometry);
|
|
4577
|
+
}
|
|
4578
|
+
});
|
|
4618
4579
|
}
|
|
4619
|
-
|
|
4620
|
-
|
|
4621
|
-
|
|
4622
|
-
|
|
4623
|
-
|
|
4624
|
-
|
|
4625
|
-
|
|
4626
|
-
|
|
4580
|
+
else if (feature.geometry.type == "Polygon") {
|
|
4581
|
+
tmpCollection.features.push({
|
|
4582
|
+
type: "Feature",
|
|
4583
|
+
geometry: feature.geometry,
|
|
4584
|
+
properties: {}
|
|
4585
|
+
});
|
|
4586
|
+
}
|
|
4587
|
+
else if (feature.geometry.type == "MultiPolygon") {
|
|
4588
|
+
for (let i = 0; i < feature.geometry.coordinates.length; i++) {
|
|
4589
|
+
tmpCollection.features.push({
|
|
4590
|
+
type: "Feature",
|
|
4591
|
+
geometry: {
|
|
4592
|
+
type: "Polygon",
|
|
4593
|
+
coordinates: feature.geometry.coordinates[i]
|
|
4594
|
+
},
|
|
4595
|
+
properties: {}
|
|
4596
|
+
});
|
|
4627
4597
|
}
|
|
4628
|
-
viewer[CESIUM_TIMELINE_LIVE_KEY] = false;
|
|
4629
4598
|
}
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
4599
|
+
// No polygons to union.
|
|
4600
|
+
// Need at least 2 to union.
|
|
4601
|
+
if (tmpCollection.features.length < 2) {
|
|
4602
|
+
return;
|
|
4603
|
+
}
|
|
4604
|
+
// Now we'll union them.
|
|
4605
|
+
try {
|
|
4606
|
+
const union = turf.union(tmpCollection);
|
|
4607
|
+
if (union.geometry.type == "Polygon") {
|
|
4608
|
+
collection.geometries.push(union.geometry);
|
|
4635
4609
|
}
|
|
4636
|
-
if (
|
|
4637
|
-
|
|
4610
|
+
else if (union.geometry.type == "MultiPolygon") {
|
|
4611
|
+
for (let i = 0; i < union.geometry.coordinates.length; i++) {
|
|
4612
|
+
collection.geometries.push({
|
|
4613
|
+
type: "Polygon",
|
|
4614
|
+
coordinates: union.geometry.coordinates[i]
|
|
4615
|
+
});
|
|
4616
|
+
}
|
|
4638
4617
|
}
|
|
4639
4618
|
else {
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
if (baseColor == null) {
|
|
4643
|
-
baseColor = scene.globe.baseColor;
|
|
4619
|
+
// Returning early because the result is unexpected.
|
|
4620
|
+
return;
|
|
4644
4621
|
}
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4622
|
+
}
|
|
4623
|
+
catch (e) {
|
|
4624
|
+
// console.error("Failed to union polygons.", e);
|
|
4625
|
+
return;
|
|
4626
|
+
}
|
|
4627
|
+
// Re-assign the geometry.
|
|
4628
|
+
if (collection.geometries.length == 1) {
|
|
4629
|
+
feature.geometry = collection.geometries[0];
|
|
4630
|
+
}
|
|
4631
|
+
else {
|
|
4632
|
+
feature.geometry = collection;
|
|
4633
|
+
}
|
|
4634
|
+
}
|
|
4635
|
+
function ringArea(ring) {
|
|
4636
|
+
let sum = 0;
|
|
4637
|
+
for (let i = 0; i < ring.length; i++) {
|
|
4638
|
+
const a = ring[i];
|
|
4639
|
+
const b = ring[(i + 1) % ring.length];
|
|
4640
|
+
sum += a[0] * b[1] - b[0] * a[1];
|
|
4641
|
+
}
|
|
4642
|
+
return sum / 2;
|
|
4643
|
+
}
|
|
4644
|
+
function isRingInsideRing(inner, outer) {
|
|
4645
|
+
for (let i = 0; i < inner.length; i++) {
|
|
4646
|
+
let inside = false;
|
|
4647
|
+
for (let a = 0, b = outer.length - 1; a < outer.length; b = a++) {
|
|
4648
|
+
if ((outer[a][1] > inner[i][1]) !== (outer[b][1] > inner[i][1])
|
|
4649
|
+
&& inner[i][0] < (outer[b][0] - outer[a][0]) * (inner[i][1] - outer[a][1]) / (outer[b][1] - outer[a][1]) + outer[a][0]) {
|
|
4650
|
+
inside = !inside;
|
|
4651
|
+
}
|
|
4653
4652
|
}
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
scene.skyAtmosphere.show = true;
|
|
4657
|
-
scene.sun.show = true;
|
|
4658
|
-
scene.moon.show = true;
|
|
4659
|
-
scene.backgroundColor = Color.BLACK;
|
|
4653
|
+
if (!inside) {
|
|
4654
|
+
return false;
|
|
4660
4655
|
}
|
|
4661
|
-
scene.globe.baseColor = baseColor;
|
|
4662
4656
|
}
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4657
|
+
return true;
|
|
4658
|
+
}
|
|
4659
|
+
function dedupeCoordinates(inputCoords) {
|
|
4660
|
+
return inputCoords.map(ring => {
|
|
4661
|
+
if (ring.length < 2) {
|
|
4662
|
+
return ring;
|
|
4667
4663
|
}
|
|
4668
|
-
|
|
4669
|
-
|
|
4664
|
+
const dedupeCoords = [];
|
|
4665
|
+
const uniqueCoords = new Set();
|
|
4666
|
+
// Dedupe the points.
|
|
4667
|
+
ring.forEach(coord => {
|
|
4668
|
+
const key = coord.join(',');
|
|
4669
|
+
if (!uniqueCoords.has(key)) {
|
|
4670
|
+
uniqueCoords.add(key);
|
|
4671
|
+
dedupeCoords.push(coord);
|
|
4672
|
+
}
|
|
4673
|
+
});
|
|
4674
|
+
// Make sure the last point matches the first.
|
|
4675
|
+
if (dedupeCoords.length > 1) {
|
|
4676
|
+
if (dedupeCoords[0][0] != dedupeCoords[dedupeCoords.length - 1][0] ||
|
|
4677
|
+
dedupeCoords[0][1] != dedupeCoords[dedupeCoords.length - 1][1]) {
|
|
4678
|
+
dedupeCoords.push(dedupeCoords[0]);
|
|
4679
|
+
}
|
|
4680
|
+
}
|
|
4681
|
+
return dedupeCoords;
|
|
4682
|
+
});
|
|
4683
|
+
}
|
|
4684
|
+
function ensureRightHandRule(polygon) {
|
|
4685
|
+
// Ensure the outer ring follows the right-hand rule
|
|
4686
|
+
if (polygon.coordinates.length > 0) {
|
|
4687
|
+
const outerRing = polygon.coordinates[0];
|
|
4688
|
+
if (isClockwise(outerRing)) {
|
|
4689
|
+
polygon.coordinates[0] = outerRing.reverse();
|
|
4670
4690
|
}
|
|
4671
|
-
viewer[CESIUM_MODEL_SPACE_KEY] = modelSpace;
|
|
4672
|
-
// Reload globe since we display it differently between the two modes.
|
|
4673
|
-
SetGlobeDetails({ viewer });
|
|
4674
4691
|
}
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4692
|
+
// Ensure any inner rings (holes) follow the right-hand rule
|
|
4693
|
+
for (let i = 1; i < polygon.coordinates.length; i++) {
|
|
4694
|
+
const innerRing = polygon.coordinates[i];
|
|
4695
|
+
if (!isClockwise(innerRing)) {
|
|
4696
|
+
polygon.coordinates[i] = innerRing.reverse();
|
|
4679
4697
|
}
|
|
4680
|
-
return Boolean(viewer[CESIUM_MODEL_SPACE_KEY]);
|
|
4681
4698
|
}
|
|
4682
|
-
|
|
4683
|
-
|
|
4699
|
+
}
|
|
4700
|
+
function isClockwise(ring) {
|
|
4701
|
+
let sum = 0;
|
|
4702
|
+
for (let i = 0; i < ring.length - 1; i++) {
|
|
4703
|
+
const p1 = ring[i];
|
|
4704
|
+
const p2 = ring[i + 1];
|
|
4705
|
+
sum += (p2[0] - p1[0]) * (p2[1] + p1[1]);
|
|
4706
|
+
}
|
|
4707
|
+
return sum > 0;
|
|
4708
|
+
}
|
|
4684
4709
|
|
|
4685
4710
|
/*
|
|
4686
4711
|
* Lets something decide WHEN a `show` flag is honoured, without owning WHAT it should be.
|
|
@@ -29042,6 +29067,7 @@ async function renderNavigator(iteration, params, bookmark, view, getters) {
|
|
|
29042
29067
|
light.color = Color.fromCssColorString(lighting.color);
|
|
29043
29068
|
light.intensity = EnsureNumber(lighting.intensity);
|
|
29044
29069
|
}
|
|
29070
|
+
ViewUtils.ApplyDefaultBrightness(viewer, EnsureNumber(lighting.brightnessShift, DEFAULT_BRIGHTNESS_SHIFT));
|
|
29045
29071
|
let quality = bSettings === null || bSettings === void 0 ? void 0 : bSettings.quality;
|
|
29046
29072
|
if (quality == null) {
|
|
29047
29073
|
quality = (_x = defaults === null || defaults === void 0 ? void 0 : defaults.settings) === null || _x === void 0 ? void 0 : _x.quality;
|
|
@@ -35235,6 +35261,8 @@ var ViewerUtils;
|
|
|
35235
35261
|
viewer
|
|
35236
35262
|
});
|
|
35237
35263
|
}
|
|
35264
|
+
// Newer cesium is much dimmer by default so we shift brightness a bit.
|
|
35265
|
+
ViewUtils.ApplyDefaultBrightness(viewer);
|
|
35238
35266
|
backgroundRendering(viewer);
|
|
35239
35267
|
// Capturing the destroy call to destroy all widgets.
|
|
35240
35268
|
const olDestroy = viewer.destroy;
|
|
@@ -43509,7 +43537,7 @@ var StyleUtils;
|
|
|
43509
43537
|
StyleUtils.ApplyTypeStyle = ApplyTypeStyle;
|
|
43510
43538
|
})(StyleUtils || (StyleUtils = {}));
|
|
43511
43539
|
|
|
43512
|
-
const VERSION = "7.1.
|
|
43540
|
+
const VERSION = "7.1.7";
|
|
43513
43541
|
/**
|
|
43514
43542
|
* Updates the environment instance used by bruce-cesium to one specified.
|
|
43515
43543
|
* This can be used to ensure that the instance a parent is referencing is shared between bruce-cesium, bruce-models, and the parent app.
|
|
@@ -43526,5 +43554,5 @@ const getENVIRONMENT = () => {
|
|
|
43526
43554
|
return ENVIRONMENT;
|
|
43527
43555
|
};
|
|
43528
43556
|
|
|
43529
|
-
export { VERSION, setENVIRONMENT, getENVIRONMENT, CesiumAnimatedInOut, DisplacedSurfacePrimitive, CesiumAnimatedProperty, isStyleChanged, isOutlineChanged$1 as isOutlineChanged, StyleEffective, EntityRenderEngine, EntityRenderEngineModel3d, EntityRenderEnginePoint, EntityRenderEnginePolygon, EntityRenderEnginePolyline, MenuItemCreator, MenuItemManager, CesiumParabola, EntityLabel, LiveCursor, SharedGetters, DataSourceStaticKmlManager, DataLabRenderManager, EntitiesIdsRenderManager, EntitiesLoadedRenderManager, EntitiesRenderManager, EntityRenderManager, AssemblyRenderManager, GoogleSearchRenderManager, RelationsRenderManager, RenderManager, TilesetArbRenderManager, TilesetCadRenderManager, TilesetEntitiesRenderManager, TilesetGooglePhotosRenderManager, TilesetOsmRenderManager, TilesetPointcloudRenderManager, TileRenderEngine, createTileset, TilesetRenderEngine, ViewRenderEngine, VisualRegisterCuller, VisualsRegister, XGridsRenderEngine, CesiumEntityStyler, DrawingUtils, EntityUtils, MeasureUtils, StyleUtils, CESIUM_INSPECTOR_KEY, CESIUM_TIMELINE_KEY, CESIUM_TIMELINE_LIVE_KEY, CESIUM_TIMELINE_LIVE_PADDING_KEY, CESIUM_TIMELINE_INTERVAL_KEY, CESIUM_MODEL_SPACE_KEY, DEFAULT_LIVE_PADDING_SECONDS, ViewUtils, CesiumViewMonitor, ViewGroundArea, ViewerEventTracker, ViewerUtils, Draw3dPolygon, Draw3dPolyline, MeasureCreator, Walkthrough, WidgetControlViewBar, WidgetControlViewBarSearch, WidgetLeftPanelTab, WidgetLeftPanelTabBookmarks, WidgetLeftPanelTabDashboard, EMenuItemState, WidgetLeftPanelTabMenuItems, Widget, VIEWER_BOOKMARKS_WIDGET_KEY, WidgetBookmarks, WidgetBranding, WidgetCursorBar, WidgetEmbeddedInfoView, WidgetInfoView, VIEWER_LEFT_PANEL_WIDGET_KEY, VIEWER_LEFT_PANEL_CSS_VAR_LEFT, WidgetLeftPanel, WidgetNavCompass$$1 as WidgetNavCompass, VIEWER_VIEW_BAR_WIDGET_KEY, WidgetViewBar };
|
|
43557
|
+
export { VERSION, setENVIRONMENT, getENVIRONMENT, CesiumAnimatedInOut, DisplacedSurfacePrimitive, CesiumAnimatedProperty, isStyleChanged, isOutlineChanged$1 as isOutlineChanged, StyleEffective, EntityRenderEngine, EntityRenderEngineModel3d, EntityRenderEnginePoint, EntityRenderEnginePolygon, EntityRenderEnginePolyline, MenuItemCreator, MenuItemManager, CesiumParabola, EntityLabel, LiveCursor, SharedGetters, DataSourceStaticKmlManager, DataLabRenderManager, EntitiesIdsRenderManager, EntitiesLoadedRenderManager, EntitiesRenderManager, EntityRenderManager, AssemblyRenderManager, GoogleSearchRenderManager, RelationsRenderManager, RenderManager, TilesetArbRenderManager, TilesetCadRenderManager, TilesetEntitiesRenderManager, TilesetGooglePhotosRenderManager, TilesetOsmRenderManager, TilesetPointcloudRenderManager, TileRenderEngine, createTileset, TilesetRenderEngine, ViewRenderEngine, VisualRegisterCuller, VisualsRegister, XGridsRenderEngine, CesiumEntityStyler, DrawingUtils, EntityUtils, MeasureUtils, StyleUtils, CESIUM_INSPECTOR_KEY, CESIUM_TIMELINE_KEY, CESIUM_TIMELINE_LIVE_KEY, CESIUM_TIMELINE_LIVE_PADDING_KEY, CESIUM_TIMELINE_INTERVAL_KEY, CESIUM_MODEL_SPACE_KEY, DEFAULT_LIVE_PADDING_SECONDS, DEFAULT_BRIGHTNESS_SHIFT, ViewUtils, CesiumViewMonitor, ViewGroundArea, ViewerEventTracker, ViewerUtils, Draw3dPolygon, Draw3dPolyline, MeasureCreator, Walkthrough, WidgetControlViewBar, WidgetControlViewBarSearch, WidgetLeftPanelTab, WidgetLeftPanelTabBookmarks, WidgetLeftPanelTabDashboard, EMenuItemState, WidgetLeftPanelTabMenuItems, Widget, VIEWER_BOOKMARKS_WIDGET_KEY, WidgetBookmarks, WidgetBranding, WidgetCursorBar, WidgetEmbeddedInfoView, WidgetInfoView, VIEWER_LEFT_PANEL_WIDGET_KEY, VIEWER_LEFT_PANEL_CSS_VAR_LEFT, WidgetLeftPanel, WidgetNavCompass$$1 as WidgetNavCompass, VIEWER_VIEW_BAR_WIDGET_KEY, WidgetViewBar };
|
|
43530
43558
|
//# sourceMappingURL=bruce-cesium.es5.js.map
|