bruce-cesium 6.6.4 → 6.6.6
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 +1653 -1465
- package/dist/bruce-cesium.es5.js.map +1 -1
- package/dist/bruce-cesium.umd.js +1650 -1462
- package/dist/bruce-cesium.umd.js.map +1 -1
- package/dist/lib/bruce-cesium.js +1 -1
- package/dist/lib/rendering/render-managers/entities/entities-render-manager.js +119 -14
- package/dist/lib/rendering/render-managers/entities/entities-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/tilesets/tileset-cad-render-manager.js +18 -3
- package/dist/lib/rendering/render-managers/tilesets/tileset-cad-render-manager.js.map +1 -1
- package/dist/lib/rendering/render-managers/tilesets/tileset-entities-render-manager.js +11 -0
- package/dist/lib/rendering/render-managers/tilesets/tileset-entities-render-manager.js.map +1 -1
- package/dist/lib/rendering/tileset-styler.js +61 -4
- package/dist/lib/rendering/tileset-styler.js.map +1 -1
- package/dist/lib/rendering/visuals-register.js +3 -3
- package/dist/lib/rendering/visuals-register.js.map +1 -1
- package/dist/types/bruce-cesium.d.ts +1 -1
- package/dist/types/rendering/render-managers/entities/entities-render-manager.d.ts +6 -1
- package/dist/types/rendering/render-managers/tilesets/tileset-cad-render-manager.d.ts +2 -2
- package/dist/types/rendering/render-managers/tilesets/tileset-entities-render-manager.d.ts +2 -2
- package/dist/types/rendering/tileset-styler.d.ts +4 -0
- package/dist/types/rendering/visuals-register.d.ts +1 -0
- package/package.json +2 -2
package/dist/bruce-cesium.umd.js
CHANGED
|
@@ -2576,609 +2576,845 @@
|
|
|
2576
2576
|
CesiumEntityStyler.Unhighlight = Unhighlight;
|
|
2577
2577
|
})(exports.CesiumEntityStyler || (exports.CesiumEntityStyler = {}));
|
|
2578
2578
|
|
|
2579
|
+
function isTurfAvailable() {
|
|
2580
|
+
return window && window.turf != null;
|
|
2581
|
+
}
|
|
2579
2582
|
/**
|
|
2580
|
-
*
|
|
2583
|
+
* Util for simplifying geometry on the fly.
|
|
2581
2584
|
*/
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2585
|
+
var SimplifyGeometry;
|
|
2586
|
+
(function (SimplifyGeometry) {
|
|
2587
|
+
/**
|
|
2588
|
+
* Returns the total number of points in the geometry.
|
|
2589
|
+
* @param geometry
|
|
2590
|
+
* @param limit number to count up to before returning.
|
|
2591
|
+
* @returns
|
|
2592
|
+
*/
|
|
2593
|
+
function CountPoints(geometry, limit) {
|
|
2594
|
+
let count = 0;
|
|
2595
|
+
const traverse = (geometry) => {
|
|
2596
|
+
if (geometry.MultiGeometry) {
|
|
2597
|
+
for (let i = 0; i < geometry.MultiGeometry.length; i++) {
|
|
2598
|
+
traverse(geometry.MultiGeometry[i]);
|
|
2599
|
+
// Reached the limit, return.
|
|
2600
|
+
if (limit && count >= limit) {
|
|
2601
|
+
return;
|
|
2602
|
+
}
|
|
2603
|
+
}
|
|
2604
|
+
}
|
|
2605
|
+
else if (geometry.Polygon) {
|
|
2606
|
+
for (let i = 0; i < geometry.Polygon.length; i++) {
|
|
2607
|
+
const polygon = geometry.Polygon[i];
|
|
2608
|
+
count += BModels.Geometry.ParsePoints(polygon.LinearRing).length;
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2611
|
+
else if (geometry.LineString) {
|
|
2612
|
+
count += BModels.Geometry.ParsePoints(geometry.LineString).length;
|
|
2613
|
+
}
|
|
2614
|
+
else if (geometry.Point) {
|
|
2615
|
+
count += 1;
|
|
2616
|
+
}
|
|
2617
|
+
};
|
|
2618
|
+
traverse(geometry);
|
|
2619
|
+
return count;
|
|
2591
2620
|
}
|
|
2592
|
-
|
|
2593
|
-
|
|
2621
|
+
SimplifyGeometry.CountPoints = CountPoints;
|
|
2622
|
+
/**
|
|
2623
|
+
* Simplifies input geometry.
|
|
2624
|
+
* This will turn it into GeoJSON, run it through turf, then back to Bruce geometry.
|
|
2625
|
+
* @param geometry
|
|
2626
|
+
*/
|
|
2627
|
+
function Simplify(entityId, geometry, tolerance) {
|
|
2628
|
+
var _a;
|
|
2629
|
+
if (!geometry || !isTurfAvailable() || !turf.simplify) {
|
|
2630
|
+
return geometry;
|
|
2631
|
+
}
|
|
2632
|
+
// Convert to geojson so that we can interact with turf.
|
|
2633
|
+
const gFeature = BModels.Geometry.ToGeoJsonFeature({
|
|
2634
|
+
geometry: geometry
|
|
2635
|
+
});
|
|
2636
|
+
// Unkink the geometry.
|
|
2637
|
+
// This removes overlapping polygons before we start merging and simplifying.
|
|
2638
|
+
// Commented out because it has crashes and doesn't handle holes.
|
|
2639
|
+
untangleFeature(gFeature);
|
|
2640
|
+
// Union the geometry.
|
|
2641
|
+
// This merges overlapping polygons.
|
|
2642
|
+
unionFeature(gFeature);
|
|
2643
|
+
// Simplify the geometry.
|
|
2644
|
+
if (tolerance > 0) {
|
|
2645
|
+
gFeature.geometry = turf.simplify(gFeature.geometry, {
|
|
2646
|
+
tolerance: tolerance,
|
|
2647
|
+
highQuality: true,
|
|
2648
|
+
mutate: true
|
|
2649
|
+
});
|
|
2650
|
+
}
|
|
2651
|
+
// Converting back to Bruce geometry.
|
|
2652
|
+
geometry = (_a = BModels.Geometry.FromGeoJson({
|
|
2653
|
+
geoJson: gFeature
|
|
2654
|
+
})) === null || _a === void 0 ? void 0 : _a.geometry;
|
|
2655
|
+
return geometry;
|
|
2594
2656
|
}
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2657
|
+
SimplifyGeometry.Simplify = Simplify;
|
|
2658
|
+
})(SimplifyGeometry || (SimplifyGeometry = {}));
|
|
2659
|
+
/**
|
|
2660
|
+
* Runs through all found polygons and runs unkink through turf on them.
|
|
2661
|
+
* @param feature
|
|
2662
|
+
*/
|
|
2663
|
+
function untangleFeature(feature) {
|
|
2664
|
+
// Collection to add to because the result might be multiple from an unkink.
|
|
2665
|
+
const collection = {
|
|
2666
|
+
geometries: [],
|
|
2667
|
+
type: "GeometryCollection"
|
|
2668
|
+
};
|
|
2669
|
+
// Runs a dedupe and unkink on the coordinates.
|
|
2670
|
+
// Returns if the coordinates were added to the collection.
|
|
2671
|
+
const processCoordinates = (coords) => {
|
|
2672
|
+
try {
|
|
2673
|
+
// Dedupe the coordinates to avoid issues with unkink.
|
|
2674
|
+
coords = dedupeCoordinates(coords);
|
|
2675
|
+
const outer = [];
|
|
2676
|
+
let inner = [];
|
|
2677
|
+
// We'll unkink each ring separately as this is killing the holes when it is done as a whole.
|
|
2678
|
+
// So we'll do it separate then recombine.
|
|
2679
|
+
for (let i = 0; i < coords.length; i++) {
|
|
2680
|
+
const ring = coords[i];
|
|
2681
|
+
const unkink = turf.unkinkPolygon({
|
|
2682
|
+
type: "Polygon",
|
|
2683
|
+
coordinates: [ring]
|
|
2684
|
+
});
|
|
2685
|
+
if (unkink.type == "FeatureCollection") {
|
|
2686
|
+
let target = i == 0 ? outer : inner;
|
|
2687
|
+
for (let j = 0; j < unkink.features.length; j++) {
|
|
2688
|
+
const unkinked = unkink.features[j].geometry.coordinates;
|
|
2689
|
+
if (unkinked.length > 0) {
|
|
2690
|
+
target.push(unkinked[0]);
|
|
2691
|
+
}
|
|
2692
|
+
}
|
|
2693
|
+
}
|
|
2694
|
+
else {
|
|
2695
|
+
console.error("Unexpected unkink result.", unkink);
|
|
2696
|
+
}
|
|
2697
|
+
}
|
|
2698
|
+
// Recreate the rings and reapply to the collection.
|
|
2699
|
+
if (outer.length > 0) {
|
|
2700
|
+
const combinedCoords = [outer[0]];
|
|
2701
|
+
for (let i = 0; i < inner.length; i++) {
|
|
2702
|
+
combinedCoords.push(inner[i]);
|
|
2703
|
+
}
|
|
2704
|
+
// Add the combined coordinates to the collection
|
|
2705
|
+
const polygon = {
|
|
2706
|
+
type: "Polygon",
|
|
2707
|
+
coordinates: combinedCoords
|
|
2708
|
+
};
|
|
2709
|
+
// Ensure right-hand rule is followed.
|
|
2710
|
+
ensureRightHandRule(polygon);
|
|
2711
|
+
// Add to the collection.
|
|
2712
|
+
collection.geometries.push(polygon);
|
|
2713
|
+
return true;
|
|
2714
|
+
}
|
|
2610
2715
|
}
|
|
2611
|
-
|
|
2612
|
-
|
|
2716
|
+
catch (e) {
|
|
2717
|
+
// console.error("Failed to unkink polygon.", e);
|
|
2613
2718
|
}
|
|
2614
|
-
|
|
2615
|
-
|
|
2719
|
+
return false;
|
|
2720
|
+
};
|
|
2721
|
+
const processGeometry = (geometry) => {
|
|
2722
|
+
let added = false;
|
|
2723
|
+
if (geometry.type == "Polygon") {
|
|
2724
|
+
added = processCoordinates(geometry.coordinates);
|
|
2616
2725
|
}
|
|
2617
|
-
if (
|
|
2618
|
-
|
|
2726
|
+
else if (geometry.type == "MultiPolygon") {
|
|
2727
|
+
for (let i = 0; i < geometry.coordinates.length; i++) {
|
|
2728
|
+
added = processCoordinates(geometry.coordinates[i]) || added;
|
|
2729
|
+
}
|
|
2619
2730
|
}
|
|
2620
|
-
|
|
2731
|
+
if (!added) {
|
|
2732
|
+
// Adding original since we can't unkink it.
|
|
2733
|
+
collection.geometries.push(geometry);
|
|
2734
|
+
}
|
|
2735
|
+
};
|
|
2736
|
+
if (feature.geometry.type == "GeometryCollection") {
|
|
2737
|
+
feature.geometry.geometries.forEach((geometry) => {
|
|
2738
|
+
processGeometry(geometry);
|
|
2739
|
+
});
|
|
2621
2740
|
}
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2741
|
+
else {
|
|
2742
|
+
processGeometry(feature.geometry);
|
|
2743
|
+
}
|
|
2744
|
+
// Re-assign the geometry.
|
|
2745
|
+
if (collection.geometries.length == 1) {
|
|
2746
|
+
feature.geometry = collection.geometries[0];
|
|
2747
|
+
}
|
|
2748
|
+
else {
|
|
2749
|
+
feature.geometry = collection;
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
2752
|
+
/**
|
|
2753
|
+
* Runs through all found polygons and unions them using turf.
|
|
2754
|
+
* Failed unions are ignored and the original is kept.
|
|
2755
|
+
* @param feature
|
|
2756
|
+
*/
|
|
2757
|
+
function unionFeature(feature) {
|
|
2758
|
+
// Collection to add to because the result might be multiple from an unkink.
|
|
2759
|
+
const collection = {
|
|
2760
|
+
geometries: [],
|
|
2761
|
+
type: "GeometryCollection"
|
|
2762
|
+
};
|
|
2763
|
+
// We'll turn each geometry into a feature and union them.
|
|
2764
|
+
const tmpCollection = {
|
|
2765
|
+
features: [],
|
|
2766
|
+
type: "FeatureCollection"
|
|
2767
|
+
};
|
|
2768
|
+
if (feature.geometry.type == "GeometryCollection") {
|
|
2769
|
+
feature.geometry.geometries.forEach((geometry) => {
|
|
2770
|
+
if (geometry.type == "Polygon") {
|
|
2771
|
+
tmpCollection.features.push({
|
|
2772
|
+
type: "Feature",
|
|
2773
|
+
geometry: geometry,
|
|
2774
|
+
properties: {}
|
|
2775
|
+
});
|
|
2633
2776
|
}
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
show: new Cesium.CallbackProperty(() => {
|
|
2646
|
-
return !this.hidden;
|
|
2647
|
-
}, false)
|
|
2777
|
+
else if (geometry.type == "MultiPolygon") {
|
|
2778
|
+
for (let i = 0; i < geometry.coordinates.length; i++) {
|
|
2779
|
+
tmpCollection.features.push({
|
|
2780
|
+
type: "Feature",
|
|
2781
|
+
geometry: {
|
|
2782
|
+
type: "Polygon",
|
|
2783
|
+
coordinates: geometry.coordinates[i]
|
|
2784
|
+
},
|
|
2785
|
+
properties: {}
|
|
2786
|
+
});
|
|
2787
|
+
}
|
|
2648
2788
|
}
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
return this.curPoints.length ? this.curPoints[this.curPoints.length - 1] : new Cesium.Cartesian3();
|
|
2653
|
-
}, false),
|
|
2654
|
-
point: {
|
|
2655
|
-
heightReference: Cesium.HeightReference.NONE,
|
|
2656
|
-
pixelSize: this.width * 1.8,
|
|
2657
|
-
color: Cesium.Color.fromCssColorString(this.color),
|
|
2658
|
-
outlineColor: Cesium.Color.WHITE,
|
|
2659
|
-
outlineWidth: 2,
|
|
2660
|
-
show: new Cesium.CallbackProperty(() => {
|
|
2661
|
-
return !this.hidden;
|
|
2662
|
-
}, false)
|
|
2789
|
+
// Only focusing on polygons.
|
|
2790
|
+
else {
|
|
2791
|
+
collection.geometries.push(geometry);
|
|
2663
2792
|
}
|
|
2664
2793
|
});
|
|
2665
|
-
p1Entity.parent = parabola;
|
|
2666
|
-
p2Entity.parent = parabola;
|
|
2667
|
-
const siblings = [p1Entity, p2Entity];
|
|
2668
|
-
this.parabola = parabola;
|
|
2669
|
-
this.siblings = siblings;
|
|
2670
|
-
// The parabola is hidden while this entity is not added.
|
|
2671
|
-
// If we avoid adding it now, then the parent can control if the parabola is visible at first or not.
|
|
2672
|
-
// this.viewer.entities.add(this.parabola);
|
|
2673
|
-
this.viewer.entities.add(p1Entity);
|
|
2674
|
-
this.viewer.entities.add(p2Entity);
|
|
2675
2794
|
}
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2795
|
+
else if (feature.geometry.type == "Polygon") {
|
|
2796
|
+
tmpCollection.features.push({
|
|
2797
|
+
type: "Feature",
|
|
2798
|
+
geometry: feature.geometry,
|
|
2799
|
+
properties: {}
|
|
2800
|
+
});
|
|
2801
|
+
}
|
|
2802
|
+
else if (feature.geometry.type == "MultiPolygon") {
|
|
2803
|
+
for (let i = 0; i < feature.geometry.coordinates.length; i++) {
|
|
2804
|
+
tmpCollection.features.push({
|
|
2805
|
+
type: "Feature",
|
|
2806
|
+
geometry: {
|
|
2807
|
+
type: "Polygon",
|
|
2808
|
+
coordinates: feature.geometry.coordinates[i]
|
|
2809
|
+
},
|
|
2810
|
+
properties: {}
|
|
2811
|
+
});
|
|
2679
2812
|
}
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2813
|
+
}
|
|
2814
|
+
// No polygons to union.
|
|
2815
|
+
// Need at least 2 to union.
|
|
2816
|
+
if (tmpCollection.features.length < 2) {
|
|
2817
|
+
return;
|
|
2818
|
+
}
|
|
2819
|
+
// Now we'll union them.
|
|
2820
|
+
try {
|
|
2821
|
+
const union = turf.union(tmpCollection);
|
|
2822
|
+
if (union.geometry.type == "Polygon") {
|
|
2823
|
+
collection.geometries.push(union.geometry);
|
|
2683
2824
|
}
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2825
|
+
else if (union.geometry.type == "MultiPolygon") {
|
|
2826
|
+
for (let i = 0; i < union.geometry.coordinates.length; i++) {
|
|
2827
|
+
collection.geometries.push({
|
|
2828
|
+
type: "Polygon",
|
|
2829
|
+
coordinates: union.geometry.coordinates[i]
|
|
2830
|
+
});
|
|
2831
|
+
}
|
|
2687
2832
|
}
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
}, 2000);
|
|
2692
|
-
return {
|
|
2693
|
-
parabola: this.parabola,
|
|
2694
|
-
siblings: this.siblings
|
|
2695
|
-
};
|
|
2833
|
+
else {
|
|
2834
|
+
// Returning early because the result is unexpected.
|
|
2835
|
+
return;
|
|
2696
2836
|
}
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
TOTAL_POINTS = Math.max(MIN_POINTS, Math.min(totalPoints, TOTAL_LENGTH * 0.1));
|
|
2724
|
-
POINT_LENGTH = TOTAL_LENGTH / TOTAL_POINTS;
|
|
2725
|
-
TICK_LENGTH_INC = SEC_DURATION == 0 ? TOTAL_LENGTH : TOTAL_POINTS / (RATE_PER_SECOND * SEC_DURATION);
|
|
2726
|
-
};
|
|
2727
|
-
updateParams();
|
|
2728
|
-
let curPoint = 0;
|
|
2729
|
-
let quadraticKey = null;
|
|
2730
|
-
let quadratic = null;
|
|
2731
|
-
let quadraticPreparing = false;
|
|
2732
|
-
const prepareQuadratic = async () => {
|
|
2733
|
-
if (quadraticPreparing) {
|
|
2734
|
-
return;
|
|
2735
|
-
}
|
|
2736
|
-
quadraticPreparing = true;
|
|
2737
|
-
try {
|
|
2738
|
-
const p1 = this.curPos1;
|
|
2739
|
-
const p2 = this.curPos2;
|
|
2740
|
-
if (!p1 || !p2 || !BModels.Cartes.ValidateCartes3(p1) || !BModels.Cartes.ValidateCartes3(p2)) {
|
|
2741
|
-
return;
|
|
2742
|
-
}
|
|
2743
|
-
const height1 = Cesium.Cartographic.fromCartesian(p1).height;
|
|
2744
|
-
const height2 = Cesium.Cartographic.fromCartesian(p2).height;
|
|
2745
|
-
if (isNaN(height1) || isNaN(height2)) {
|
|
2746
|
-
return;
|
|
2747
|
-
}
|
|
2748
|
-
const totalHeight = height2 + height1;
|
|
2749
|
-
const curQuadraticKey = `${height1}-${height2}-${TOTAL_LENGTH}`;
|
|
2750
|
-
if (quadraticKey == curQuadraticKey) {
|
|
2751
|
-
return;
|
|
2752
|
-
}
|
|
2753
|
-
const points2d = [
|
|
2754
|
-
new Cesium.Cartesian2(0, height1),
|
|
2755
|
-
new Cesium.Cartesian2(TOTAL_LENGTH, height2)
|
|
2756
|
-
];
|
|
2757
|
-
let vertexHeight = 0;
|
|
2758
|
-
// Flat line.
|
|
2759
|
-
if (HEIGHT_DISTANCE_RATIO == 0) {
|
|
2760
|
-
vertexHeight = totalHeight * 0.5;
|
|
2761
|
-
}
|
|
2762
|
-
else {
|
|
2763
|
-
const largestHeight = Math.max(height1, height2);
|
|
2764
|
-
vertexHeight = largestHeight + (TOTAL_LENGTH * HEIGHT_DISTANCE_RATIO);
|
|
2765
|
-
}
|
|
2766
|
-
points2d.push(new Cesium.Cartesian2(TOTAL_LENGTH * 0.5, vertexHeight));
|
|
2767
|
-
const calcQuadratic = (points) => {
|
|
2768
|
-
// Swaps position of two rows in matrix.
|
|
2769
|
-
function swapRows(matrix, rowAIndex, rowBIndex) {
|
|
2770
|
-
const rowAVal = matrix[rowAIndex];
|
|
2771
|
-
matrix[rowAIndex] = matrix[rowBIndex];
|
|
2772
|
-
matrix[rowBIndex] = rowAVal;
|
|
2773
|
-
return matrix;
|
|
2774
|
-
}
|
|
2775
|
-
// Zeros rowA at colIndex by subtracting a multiplied rowB from it.
|
|
2776
|
-
function reduceMatrixRowByRow(matrix, zeroingIndex, parentIndex, colIndex) {
|
|
2777
|
-
const zeroRow = matrix[zeroingIndex];
|
|
2778
|
-
const parentRow = matrix[parentIndex];
|
|
2779
|
-
if (zeroRow[colIndex] == 0) {
|
|
2780
|
-
return matrix;
|
|
2781
|
-
}
|
|
2782
|
-
else if (parentRow[colIndex] == 0) {
|
|
2783
|
-
matrix = swapRows(matrix, parentIndex, zeroingIndex);
|
|
2784
|
-
return divideMatrixRow(matrix, parentIndex, colIndex);
|
|
2785
|
-
}
|
|
2786
|
-
// rowAIndex colIndex / rowBIndex colIndex = factor;
|
|
2787
|
-
let factor = zeroRow[colIndex] / parentRow[colIndex];
|
|
2788
|
-
for (let i = 0; i < zeroRow.length; i++) {
|
|
2789
|
-
if (i >= colIndex) {
|
|
2790
|
-
zeroRow[i] -= parentRow[i] * factor;
|
|
2791
|
-
}
|
|
2792
|
-
}
|
|
2793
|
-
return matrix;
|
|
2794
|
-
}
|
|
2795
|
-
// Makes a given row column equal 1 by diving while row by that column.
|
|
2796
|
-
function divideMatrixRow(matrix, rowIndex, colIndex) {
|
|
2797
|
-
const row = matrix[rowIndex];
|
|
2798
|
-
const colValue = row[colIndex];
|
|
2799
|
-
for (let i = 0; i < row.length; i++) {
|
|
2800
|
-
if (i >= colIndex) {
|
|
2801
|
-
row[i] /= colValue;
|
|
2802
|
-
}
|
|
2803
|
-
}
|
|
2804
|
-
return matrix;
|
|
2805
|
-
}
|
|
2806
|
-
// Returns initial matrix for calculating a, b and c for quadratic formula from given points.
|
|
2807
|
-
function matrixFromPoints(points) {
|
|
2808
|
-
const rows = [];
|
|
2809
|
-
const constructRow = (point) => {
|
|
2810
|
-
rows.push([
|
|
2811
|
-
-Math.pow(point.x, 2),
|
|
2812
|
-
point.x,
|
|
2813
|
-
1,
|
|
2814
|
-
point.y
|
|
2815
|
-
]);
|
|
2816
|
-
};
|
|
2817
|
-
for (let i = 0; i < points.length; i++) {
|
|
2818
|
-
constructRow(points[i]);
|
|
2819
|
-
}
|
|
2820
|
-
return rows;
|
|
2821
|
-
}
|
|
2822
|
-
const initialMatrix = matrixFromPoints(points);
|
|
2823
|
-
const step1Matrix = reduceMatrixRowByRow(initialMatrix, 1, 0, 0);
|
|
2824
|
-
const step2Matrix = reduceMatrixRowByRow(step1Matrix, 2, 0, 0);
|
|
2825
|
-
const step3Matrix = reduceMatrixRowByRow(step2Matrix, 2, 1, 1);
|
|
2826
|
-
const step4Matrix = reduceMatrixRowByRow(step3Matrix, 0, 1, 1);
|
|
2827
|
-
const step5Matrix = reduceMatrixRowByRow(step4Matrix, 0, 2, 2);
|
|
2828
|
-
const step6Matrix = reduceMatrixRowByRow(step5Matrix, 1, 2, 2);
|
|
2829
|
-
const a = step6Matrix[0][3];
|
|
2830
|
-
const b = step6Matrix[1][3];
|
|
2831
|
-
const c = step6Matrix[2][3];
|
|
2832
|
-
return { a: a, b: b, c: c };
|
|
2833
|
-
};
|
|
2834
|
-
quadratic = calcQuadratic(points2d);
|
|
2837
|
+
}
|
|
2838
|
+
catch (e) {
|
|
2839
|
+
// console.error("Failed to union polygons.", e);
|
|
2840
|
+
return;
|
|
2841
|
+
}
|
|
2842
|
+
// Re-assign the geometry.
|
|
2843
|
+
if (collection.geometries.length == 1) {
|
|
2844
|
+
feature.geometry = collection.geometries[0];
|
|
2845
|
+
}
|
|
2846
|
+
else {
|
|
2847
|
+
feature.geometry = collection;
|
|
2848
|
+
}
|
|
2849
|
+
}
|
|
2850
|
+
function dedupeCoordinates(inputCoords) {
|
|
2851
|
+
return inputCoords.map(ring => {
|
|
2852
|
+
if (ring.length < 2) {
|
|
2853
|
+
return ring;
|
|
2854
|
+
}
|
|
2855
|
+
const dedupeCoords = [];
|
|
2856
|
+
const uniqueCoords = new Set();
|
|
2857
|
+
// Dedupe the points.
|
|
2858
|
+
ring.forEach(coord => {
|
|
2859
|
+
const key = coord.join(',');
|
|
2860
|
+
if (!uniqueCoords.has(key)) {
|
|
2861
|
+
uniqueCoords.add(key);
|
|
2862
|
+
dedupeCoords.push(coord);
|
|
2835
2863
|
}
|
|
2836
|
-
|
|
2837
|
-
|
|
2864
|
+
});
|
|
2865
|
+
// Make sure the last point matches the first.
|
|
2866
|
+
if (dedupeCoords.length > 1) {
|
|
2867
|
+
if (dedupeCoords[0][0] != dedupeCoords[dedupeCoords.length - 1][0] ||
|
|
2868
|
+
dedupeCoords[0][1] != dedupeCoords[dedupeCoords.length - 1][1]) {
|
|
2869
|
+
dedupeCoords.push(dedupeCoords[0]);
|
|
2838
2870
|
}
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
}
|
|
2851
|
-
const getParabolaYFromX = (x, quadLetters) => {
|
|
2852
|
-
let a = quadLetters.a;
|
|
2853
|
-
let b = quadLetters.b;
|
|
2854
|
-
let c = quadLetters.c;
|
|
2855
|
-
return (-a * Math.pow(x, 2)) + (b * x) + c;
|
|
2856
|
-
};
|
|
2857
|
-
const { point: pos3d } = exports.DrawingUtils.PointAcrossPolyline({
|
|
2858
|
-
viewer: this.viewer,
|
|
2859
|
-
distance: lengthAcross,
|
|
2860
|
-
posses: [this.curPos1, this.curPos2]
|
|
2861
|
-
});
|
|
2862
|
-
const point = Cesium.Cartographic.fromCartesian(pos3d);
|
|
2863
|
-
const posHeight = getParabolaYFromX(lengthAcross, quadratic);
|
|
2864
|
-
return Cesium.Cartesian3.fromRadians(point.longitude, point.latitude, posHeight);
|
|
2865
|
-
};
|
|
2866
|
-
const updatePoints = () => {
|
|
2867
|
-
if (!quadratic) {
|
|
2868
|
-
return;
|
|
2869
|
-
}
|
|
2870
|
-
const increment = Math.floor(curPoint);
|
|
2871
|
-
const chips = curPoint - Math.floor(curPoint);
|
|
2872
|
-
const posses = [];
|
|
2873
|
-
posses.push(getPosition(0));
|
|
2874
|
-
const addLast = increment >= TOTAL_POINTS;
|
|
2875
|
-
const totalCycles = addLast ? increment + 1 : increment;
|
|
2876
|
-
for (let i = 0; i < totalCycles; i++) {
|
|
2877
|
-
posses.push(getPosition(i));
|
|
2878
|
-
}
|
|
2879
|
-
if (chips) {
|
|
2880
|
-
posses.push(getPosition(increment + chips));
|
|
2881
|
-
}
|
|
2882
|
-
if (posses.find(x => !x || !BModels.Cartes.ValidateCartes3(x))) {
|
|
2883
|
-
return;
|
|
2884
|
-
}
|
|
2885
|
-
this.curPoints = posses;
|
|
2886
|
-
};
|
|
2887
|
-
let lastTickDate = new Date();
|
|
2888
|
-
let finished = false;
|
|
2889
|
-
const doTick = () => {
|
|
2890
|
-
const curDate = new Date();
|
|
2891
|
-
const seconds = (curDate.getTime() - lastTickDate.getTime()) / 1000;
|
|
2892
|
-
const ticks = seconds * RATE_PER_SECOND;
|
|
2893
|
-
if (!isNaN(ticks) && ticks >= 1) {
|
|
2894
|
-
lastTickDate = curDate;
|
|
2895
|
-
const p1 = this.curPos1;
|
|
2896
|
-
const p2 = this.curPos2;
|
|
2897
|
-
const newLength = p1 && p2 ? Cesium.Cartesian3.distance(p1, p2) : -1;
|
|
2898
|
-
if (newLength > 0 && newLength != TOTAL_LENGTH) {
|
|
2899
|
-
TOTAL_LENGTH = newLength;
|
|
2900
|
-
updateParams();
|
|
2901
|
-
}
|
|
2902
|
-
prepareQuadratic();
|
|
2903
|
-
if (quadratic) {
|
|
2904
|
-
if (curPoint < TOTAL_POINTS) {
|
|
2905
|
-
curPoint += (TICK_LENGTH_INC * ticks);
|
|
2906
|
-
}
|
|
2907
|
-
updatePoints();
|
|
2908
|
-
}
|
|
2909
|
-
this.viewer.scene.requestRender();
|
|
2910
|
-
if (curPoint >= TOTAL_POINTS && !finished) {
|
|
2911
|
-
finished = true;
|
|
2912
|
-
// We can make the interval update super slow now.
|
|
2913
|
-
// We keep it updating in case the positions move.
|
|
2914
|
-
clearInterval(this.animateInterval);
|
|
2915
|
-
this.animateInterval = setInterval(doTick, 3000);
|
|
2916
|
-
}
|
|
2917
|
-
}
|
|
2918
|
-
};
|
|
2919
|
-
this.animateInterval = setInterval(doTick, RATE_PER_SECOND);
|
|
2920
|
-
return {
|
|
2921
|
-
parabola: this.parabola,
|
|
2922
|
-
siblings: this.siblings
|
|
2923
|
-
};
|
|
2871
|
+
}
|
|
2872
|
+
return dedupeCoords;
|
|
2873
|
+
});
|
|
2874
|
+
}
|
|
2875
|
+
function ensureRightHandRule(polygon) {
|
|
2876
|
+
// Ensure the outer ring follows the right-hand rule
|
|
2877
|
+
if (polygon.coordinates.length > 0) {
|
|
2878
|
+
const outerRing = polygon.coordinates[0];
|
|
2879
|
+
if (isClockwise(outerRing)) {
|
|
2880
|
+
polygon.coordinates[0] = outerRing.reverse();
|
|
2881
|
+
}
|
|
2924
2882
|
}
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2883
|
+
// Ensure any inner rings (holes) follow the right-hand rule
|
|
2884
|
+
for (let i = 1; i < polygon.coordinates.length; i++) {
|
|
2885
|
+
const innerRing = polygon.coordinates[i];
|
|
2886
|
+
if (!isClockwise(innerRing)) {
|
|
2887
|
+
polygon.coordinates[i] = innerRing.reverse();
|
|
2888
|
+
}
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2891
|
+
function isClockwise(ring) {
|
|
2892
|
+
let sum = 0;
|
|
2893
|
+
for (let i = 0; i < ring.length - 1; i++) {
|
|
2894
|
+
const p1 = ring[i];
|
|
2895
|
+
const p2 = ring[i + 1];
|
|
2896
|
+
sum += (p2[0] - p1[0]) * (p2[1] + p1[1]);
|
|
2937
2897
|
}
|
|
2898
|
+
return sum > 0;
|
|
2938
2899
|
}
|
|
2939
2900
|
|
|
2940
|
-
function
|
|
2941
|
-
|
|
2901
|
+
function OnNextCRender(viewer, callback) {
|
|
2902
|
+
const removal = viewer.scene.postRender.addEventListener(() => {
|
|
2903
|
+
removal();
|
|
2904
|
+
callback();
|
|
2905
|
+
});
|
|
2942
2906
|
}
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
api,
|
|
2949
|
-
styleId
|
|
2950
|
-
})).style;
|
|
2951
|
-
}
|
|
2952
|
-
// Probably deleted.
|
|
2953
|
-
catch (e) {
|
|
2954
|
-
console.error(e);
|
|
2907
|
+
function GetCValue(viewer, obj) {
|
|
2908
|
+
if (obj === null || obj === void 0 ? void 0 : obj.getValue) {
|
|
2909
|
+
let date = viewer.scene.lastRenderTime;
|
|
2910
|
+
if (!date) {
|
|
2911
|
+
date = viewer.clock.currentTime;
|
|
2955
2912
|
}
|
|
2913
|
+
return obj.getValue(date);
|
|
2956
2914
|
}
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
// This happens when rendering entities that don't have records.
|
|
2977
|
-
hideError = String(code).toLowerCase() == "notfound";
|
|
2978
|
-
}
|
|
2979
|
-
if (!hideError) {
|
|
2980
|
-
console.error(e);
|
|
2981
|
-
}
|
|
2982
|
-
}
|
|
2915
|
+
return obj;
|
|
2916
|
+
}
|
|
2917
|
+
function ColorToCColor(color) {
|
|
2918
|
+
return new Cesium.Color(color.red ? color.red / 255 : 0, color.green ? color.green / 255 : 0, color.blue ? color.blue / 255 : 0, color.alpha);
|
|
2919
|
+
}
|
|
2920
|
+
/**
|
|
2921
|
+
* Removes duplicate points in a row and returns a new array.
|
|
2922
|
+
* Passed array is not mutated.
|
|
2923
|
+
* @param posses
|
|
2924
|
+
*/
|
|
2925
|
+
function CullDuplicateCPosses(posses) {
|
|
2926
|
+
const newPosses = [];
|
|
2927
|
+
let lastPos = null;
|
|
2928
|
+
for (let i = 0; i < posses.length; i++) {
|
|
2929
|
+
const pos = posses[i];
|
|
2930
|
+
// Avoiding 'Cesium.Cartesian3.equals' because passed data might be just a json blob in certain cases.
|
|
2931
|
+
if (pos && (!lastPos || (pos.x != lastPos.x || pos.y != lastPos.y || pos.z != lastPos.z))) {
|
|
2932
|
+
newPosses.push(pos);
|
|
2933
|
+
lastPos = pos;
|
|
2983
2934
|
}
|
|
2984
2935
|
}
|
|
2985
|
-
return
|
|
2936
|
+
return newPosses;
|
|
2986
2937
|
}
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2938
|
+
/**
|
|
2939
|
+
* Returns if the given positions are equal.
|
|
2940
|
+
* @param a
|
|
2941
|
+
* @param b
|
|
2942
|
+
*/
|
|
2943
|
+
function CompareCPosses(a, b) {
|
|
2944
|
+
// Same reference.
|
|
2945
|
+
if (a == b) {
|
|
2946
|
+
return true;
|
|
2991
2947
|
}
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
}
|
|
3003
|
-
if (relation["Related.Entity.ID"]) {
|
|
3004
|
-
neededEntityIdsIds.push(relation["Related.Entity.ID"]);
|
|
3005
|
-
}
|
|
3006
|
-
if (relation["Data.Entity.ID"]) {
|
|
3007
|
-
neededEntityIdsIds.push(relation["Data.Entity.ID"]);
|
|
3008
|
-
}
|
|
2948
|
+
// Different lengths or one is null.
|
|
2949
|
+
if ((!a || !b) || (a.length != b.length)) {
|
|
2950
|
+
return false;
|
|
2951
|
+
}
|
|
2952
|
+
for (let i = 0; i < a.length; i++) {
|
|
2953
|
+
const posA = a[i];
|
|
2954
|
+
const posB = b[i];
|
|
2955
|
+
// Null detected.
|
|
2956
|
+
if (!posA || !posB) {
|
|
2957
|
+
return false;
|
|
3009
2958
|
}
|
|
3010
|
-
//
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
let entities = (await BModels.Entity.GetListByIds({
|
|
3014
|
-
entityIds: neededEntityIdsIds,
|
|
3015
|
-
api: apiGetter.getApi(),
|
|
3016
|
-
migrated: true,
|
|
3017
|
-
maxSearchTimeSec: 60 * 2
|
|
3018
|
-
})).entities;
|
|
3019
|
-
// Create a map for quick reference.
|
|
3020
|
-
const entitiesMap = {};
|
|
3021
|
-
for (let i = 0; i < entities.length; i++) {
|
|
3022
|
-
const entity = entities[i];
|
|
3023
|
-
entitiesMap[entity.Bruce.ID] = entity;
|
|
2959
|
+
// Position values don't match.
|
|
2960
|
+
if (!BModels.Cartes.IsEqualCartes3(posA, posB)) {
|
|
2961
|
+
return false;
|
|
3024
2962
|
}
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
2963
|
+
}
|
|
2964
|
+
return true;
|
|
2965
|
+
}
|
|
2966
|
+
/**
|
|
2967
|
+
* Returns if the given polygon hierarchies are equal.
|
|
2968
|
+
* @param a
|
|
2969
|
+
* @param b
|
|
2970
|
+
*/
|
|
2971
|
+
function CompareCPolygonHierarchies(a, b) {
|
|
2972
|
+
// Same reference.
|
|
2973
|
+
if (a == b) {
|
|
2974
|
+
return true;
|
|
2975
|
+
}
|
|
2976
|
+
// Different lengths or one is null.
|
|
2977
|
+
if ((!a || !b) || (a.positions.length != b.positions.length)) {
|
|
2978
|
+
return false;
|
|
2979
|
+
}
|
|
2980
|
+
// Positions don't match.
|
|
2981
|
+
if (!CompareCPosses(a.positions, b.positions)) {
|
|
2982
|
+
return false;
|
|
2983
|
+
}
|
|
2984
|
+
const holes = a.holes;
|
|
2985
|
+
const bHoles = b.holes;
|
|
2986
|
+
// Number of holes don't match.
|
|
2987
|
+
if (holes.length != bHoles.length) {
|
|
2988
|
+
return false;
|
|
2989
|
+
}
|
|
2990
|
+
for (let i = 0; i < holes.length; i++) {
|
|
2991
|
+
// Hole positions don't match.
|
|
2992
|
+
if (!CompareCPosses(holes[i].positions, bHoles[i].positions)) {
|
|
2993
|
+
return false;
|
|
3035
2994
|
}
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
2995
|
+
}
|
|
2996
|
+
return true;
|
|
2997
|
+
}
|
|
2998
|
+
|
|
2999
|
+
const CESIUM_INSPECTOR_KEY = "_nextspace_inspector";
|
|
3000
|
+
const CESIUM_TIMELINE_KEY = "_nextspace_timeline";
|
|
3001
|
+
const CESIUM_TIMELINE_LIVE_KEY = "_nextspace_timeline_live";
|
|
3002
|
+
const CESIUM_TIMELINE_LIVE_PADDING_KEY = "_nextspace_timeline_live_padding";
|
|
3003
|
+
const CESIUM_TIMELINE_INTERVAL_KEY = "_nextspace_timeline_interval";
|
|
3004
|
+
const CESIUM_MODEL_SPACE_KEY = "_nextspace_model_space";
|
|
3005
|
+
const DEFAULT_LIVE_PADDING_SECONDS = 30 * 60;
|
|
3006
|
+
(function (ViewUtils) {
|
|
3007
|
+
function GatherLegacyMapTiles(params) {
|
|
3008
|
+
const viewer = params.viewer;
|
|
3009
|
+
const collection = viewer.imageryLayers;
|
|
3010
|
+
const tiles = [];
|
|
3011
|
+
for (let i = 0; i < collection.length; i++) {
|
|
3012
|
+
const layer = collection.get(i);
|
|
3013
|
+
if (layer._bName) {
|
|
3014
|
+
tiles.push({
|
|
3015
|
+
alpha: layer.alpha,
|
|
3016
|
+
brightness: layer.brightness,
|
|
3017
|
+
contrast: layer.contrast,
|
|
3018
|
+
hue: layer.hue,
|
|
3019
|
+
saturation: layer.saturation,
|
|
3020
|
+
gamma: layer.gamma,
|
|
3021
|
+
title: layer._bName,
|
|
3053
3022
|
});
|
|
3054
|
-
cEntity._renderGroup = GetRenderGroupId(relation);
|
|
3055
|
-
rendered[GetRenderGroupId(relation)] = cEntity;
|
|
3056
|
-
}
|
|
3057
|
-
catch (e) {
|
|
3058
|
-
console.error(e);
|
|
3059
3023
|
}
|
|
3060
3024
|
}
|
|
3061
|
-
return
|
|
3025
|
+
return {
|
|
3026
|
+
imagery: tiles.reverse()
|
|
3027
|
+
};
|
|
3062
3028
|
}
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
visualRegister: params.visualRegister,
|
|
3096
|
-
api: params.apiGetter.getApi()
|
|
3097
|
-
});
|
|
3098
|
-
fromPos = fromData.pos3d;
|
|
3099
|
-
const toData = await exports.EntityUtils.GetLocation({
|
|
3100
|
-
samples: [{
|
|
3101
|
-
entity: params.toEntity,
|
|
3102
|
-
entityId: params.toEntity.Bruce.ID,
|
|
3103
|
-
heightRef: Cesium.HeightReference.CLAMP_TO_GROUND,
|
|
3104
|
-
returnHeightRef: Cesium.HeightReference.NONE
|
|
3105
|
-
}],
|
|
3106
|
-
viewer: params.viewer,
|
|
3107
|
-
visualRegister: params.visualRegister,
|
|
3108
|
-
api: params.apiGetter.getApi()
|
|
3029
|
+
ViewUtils.GatherLegacyMapTiles = GatherLegacyMapTiles;
|
|
3030
|
+
function GatherLegacyTerrainTile(params) {
|
|
3031
|
+
const viewer = params.viewer;
|
|
3032
|
+
const enabled = viewer.terrainProvider;
|
|
3033
|
+
if (enabled === null || enabled === void 0 ? void 0 : enabled._bName) {
|
|
3034
|
+
return {
|
|
3035
|
+
terrain: enabled._bName
|
|
3036
|
+
};
|
|
3037
|
+
}
|
|
3038
|
+
return {
|
|
3039
|
+
terrain: "flatterrain"
|
|
3040
|
+
};
|
|
3041
|
+
}
|
|
3042
|
+
ViewUtils.GatherLegacyTerrainTile = GatherLegacyTerrainTile;
|
|
3043
|
+
function GatherMapTiles(params) {
|
|
3044
|
+
const viewer = params.viewer;
|
|
3045
|
+
const imagery = viewer.imageryLayers;
|
|
3046
|
+
const tiles = [];
|
|
3047
|
+
for (let i = 0; i < imagery.length; i++) {
|
|
3048
|
+
const provider = imagery.get(i);
|
|
3049
|
+
if (provider._bMeta) {
|
|
3050
|
+
const idCombo = provider._bMeta.accountId + provider._bMeta.tilesetId;
|
|
3051
|
+
if (!tiles.find(x => x.accountId + x.tilesetId === idCombo)) {
|
|
3052
|
+
tiles.push({
|
|
3053
|
+
accountId: provider._bMeta.accountId,
|
|
3054
|
+
tilesetId: provider._bMeta.tilesetId,
|
|
3055
|
+
alpha: provider.alpha,
|
|
3056
|
+
brightness: provider.brightness,
|
|
3057
|
+
contrast: provider.contrast,
|
|
3058
|
+
hue: provider.hue,
|
|
3059
|
+
saturation: provider.saturation,
|
|
3060
|
+
gamma: provider.gamma
|
|
3109
3061
|
});
|
|
3110
|
-
toPos = toData.pos3d;
|
|
3111
|
-
}
|
|
3112
|
-
catch (e) {
|
|
3113
|
-
console.error(e);
|
|
3114
3062
|
}
|
|
3115
|
-
updatingPosses = false;
|
|
3116
|
-
};
|
|
3117
|
-
updatePosses();
|
|
3118
|
-
const parabola = new CesiumParabola({
|
|
3119
|
-
viewer: params.viewer,
|
|
3120
|
-
pos1: () => fromPos,
|
|
3121
|
-
pos2: () => toPos,
|
|
3122
|
-
color: cColor.toCssColorString(),
|
|
3123
|
-
width: width,
|
|
3124
|
-
duration: duration,
|
|
3125
|
-
heightDistanceRatio: hDistanceRatio
|
|
3126
|
-
});
|
|
3127
|
-
parabola.Hidden = true;
|
|
3128
|
-
const cEntities = parabola.Animate();
|
|
3129
|
-
const cEntity = cEntities.parabola;
|
|
3130
|
-
cEntity._siblingGraphics = [];
|
|
3131
|
-
for (let i = 0; i < cEntities.siblings.length; i++) {
|
|
3132
|
-
const sibling = cEntities.siblings[i];
|
|
3133
|
-
cEntity._siblingGraphics.push(sibling);
|
|
3134
3063
|
}
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
params.viewer.scene.requestRender();
|
|
3150
|
-
}, 1000);
|
|
3151
|
-
let disposed = false;
|
|
3152
|
-
cEntity._dispose = () => {
|
|
3153
|
-
if (disposed) {
|
|
3154
|
-
return;
|
|
3155
|
-
}
|
|
3156
|
-
disposed = true;
|
|
3157
|
-
clearInterval(updateInterval);
|
|
3158
|
-
if (parabola) {
|
|
3159
|
-
parabola.Dispose();
|
|
3064
|
+
}
|
|
3065
|
+
return {
|
|
3066
|
+
imagery: tiles
|
|
3067
|
+
};
|
|
3068
|
+
}
|
|
3069
|
+
ViewUtils.GatherMapTiles = GatherMapTiles;
|
|
3070
|
+
function GatherTerrainTile(params) {
|
|
3071
|
+
const viewer = params.viewer;
|
|
3072
|
+
const provider = viewer.terrainProvider;
|
|
3073
|
+
if (provider === null || provider === void 0 ? void 0 : provider._bMeta) {
|
|
3074
|
+
return {
|
|
3075
|
+
terrain: {
|
|
3076
|
+
accountId: provider._bMeta.accountId,
|
|
3077
|
+
tilesetId: provider._bMeta.tilesetId,
|
|
3160
3078
|
}
|
|
3161
3079
|
};
|
|
3162
|
-
return cEntity;
|
|
3163
3080
|
}
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
* Eg: const pos3d = getValue<Cesium.Cartesian3>(cViewer, cEntity.point.position);
|
|
3172
|
-
* @param viewer
|
|
3173
|
-
* @param obj
|
|
3174
|
-
*/
|
|
3175
|
-
function getValue(viewer, obj) {
|
|
3176
|
-
if (obj === null || obj === void 0 ? void 0 : obj.getValue) {
|
|
3177
|
-
let date = viewer.scene.lastRenderTime;
|
|
3178
|
-
if (!date) {
|
|
3179
|
-
date = viewer.clock.currentTime;
|
|
3081
|
+
else if (provider instanceof Cesium.EllipsoidTerrainProvider) {
|
|
3082
|
+
return {
|
|
3083
|
+
terrain: {
|
|
3084
|
+
tilesetId: BModels.ProjectViewTile.EDefaultTerrain.FlatTerrain,
|
|
3085
|
+
accountId: null
|
|
3086
|
+
}
|
|
3087
|
+
};
|
|
3180
3088
|
}
|
|
3181
|
-
return
|
|
3089
|
+
return null;
|
|
3090
|
+
}
|
|
3091
|
+
ViewUtils.GatherTerrainTile = GatherTerrainTile;
|
|
3092
|
+
function SetTerrainWireframeStatus(params) {
|
|
3093
|
+
if (!params.viewer[CESIUM_INSPECTOR_KEY]) {
|
|
3094
|
+
const InspectorClass = Cesium.CesiumInspector;
|
|
3095
|
+
if (InspectorClass) {
|
|
3096
|
+
const inspector = new InspectorClass(document.createElement("div"), params.viewer.scene);
|
|
3097
|
+
inspector.container.style.display = "none";
|
|
3098
|
+
params.viewer[CESIUM_INSPECTOR_KEY] = inspector;
|
|
3099
|
+
params.viewer.scene.requestRender();
|
|
3100
|
+
}
|
|
3101
|
+
}
|
|
3102
|
+
if (params.viewer[CESIUM_INSPECTOR_KEY]) {
|
|
3103
|
+
params.viewer[CESIUM_INSPECTOR_KEY].viewModel.wireframe = params.status;
|
|
3104
|
+
}
|
|
3105
|
+
}
|
|
3106
|
+
ViewUtils.SetTerrainWireframeStatus = SetTerrainWireframeStatus;
|
|
3107
|
+
function GetTerrainWireframeStatus(params) {
|
|
3108
|
+
var _a, _b;
|
|
3109
|
+
if (!params.viewer[CESIUM_INSPECTOR_KEY]) {
|
|
3110
|
+
return false;
|
|
3111
|
+
}
|
|
3112
|
+
return (_b = (_a = params.viewer[CESIUM_INSPECTOR_KEY]) === null || _a === void 0 ? void 0 : _a.viewModel) === null || _b === void 0 ? void 0 : _b.wireframe;
|
|
3113
|
+
}
|
|
3114
|
+
ViewUtils.GetTerrainWireframeStatus = GetTerrainWireframeStatus;
|
|
3115
|
+
/**
|
|
3116
|
+
* Changes between perspective and orthographic view.
|
|
3117
|
+
* When Cesium stops being bad at picking positions in 2d mode we'll use the flat earth mode instead.
|
|
3118
|
+
* @param params
|
|
3119
|
+
*/
|
|
3120
|
+
function Set2dStatus(params) {
|
|
3121
|
+
const { viewer, status: is2d, moveCamera } = params;
|
|
3122
|
+
const curLens2d = viewer.camera.frustum instanceof Cesium.OrthographicFrustum;
|
|
3123
|
+
if (curLens2d && !is2d) {
|
|
3124
|
+
OnNextCRender(viewer, () => {
|
|
3125
|
+
viewer.camera.switchToPerspectiveFrustum();
|
|
3126
|
+
viewer.scene.screenSpaceCameraController.enableTilt = true;
|
|
3127
|
+
});
|
|
3128
|
+
viewer.scene.requestRender();
|
|
3129
|
+
}
|
|
3130
|
+
else if (!curLens2d && is2d) {
|
|
3131
|
+
OnNextCRender(viewer, () => {
|
|
3132
|
+
viewer.camera.switchToOrthographicFrustum();
|
|
3133
|
+
viewer.scene.screenSpaceCameraController.enableTilt = false;
|
|
3134
|
+
});
|
|
3135
|
+
if (moveCamera != false) {
|
|
3136
|
+
try {
|
|
3137
|
+
// Face camera downwards to make it look 2d.
|
|
3138
|
+
// We want to try make it look at the center-point of the current view.
|
|
3139
|
+
// If center cannot be calculated then we'll simply raise the camera and face it downwards.
|
|
3140
|
+
const scene = viewer.scene;
|
|
3141
|
+
const windowPosition = new Cesium.Cartesian2(scene.canvas.clientWidth / 2, scene.canvas.clientHeight / 2);
|
|
3142
|
+
const ray = viewer.camera.getPickRay(windowPosition);
|
|
3143
|
+
const intersection = scene.globe.pick(ray, scene);
|
|
3144
|
+
let center;
|
|
3145
|
+
if (Cesium.defined(intersection)) {
|
|
3146
|
+
center = Cesium.Cartographic.fromCartesian(intersection);
|
|
3147
|
+
}
|
|
3148
|
+
// Use current camera position if we can't calculate the center.
|
|
3149
|
+
else {
|
|
3150
|
+
center = Cesium.Cartographic.fromCartesian(viewer.camera.position);
|
|
3151
|
+
center.height = 0;
|
|
3152
|
+
}
|
|
3153
|
+
center.height = viewer.camera.positionCartographic.height + 100;
|
|
3154
|
+
viewer.camera.setView({
|
|
3155
|
+
destination: Cesium.Cartographic.toCartesian(center),
|
|
3156
|
+
orientation: {
|
|
3157
|
+
heading: 0.0,
|
|
3158
|
+
pitch: Cesium.Math.toRadians(-90.0),
|
|
3159
|
+
roll: 0.0
|
|
3160
|
+
}
|
|
3161
|
+
});
|
|
3162
|
+
}
|
|
3163
|
+
catch (e) {
|
|
3164
|
+
console.error(e);
|
|
3165
|
+
}
|
|
3166
|
+
}
|
|
3167
|
+
viewer.scene.requestRender();
|
|
3168
|
+
}
|
|
3169
|
+
}
|
|
3170
|
+
ViewUtils.Set2dStatus = Set2dStatus;
|
|
3171
|
+
function Get2dStatus(params) {
|
|
3172
|
+
const { viewer } = params;
|
|
3173
|
+
return viewer.camera.frustum instanceof Cesium.OrthographicFrustum;
|
|
3174
|
+
}
|
|
3175
|
+
ViewUtils.Get2dStatus = Get2dStatus;
|
|
3176
|
+
function SetLockedCameraStatus(params) {
|
|
3177
|
+
const { viewer, status } = params;
|
|
3178
|
+
const scene = viewer === null || viewer === void 0 ? void 0 : viewer.scene;
|
|
3179
|
+
if (!scene) {
|
|
3180
|
+
return;
|
|
3181
|
+
}
|
|
3182
|
+
if (status) {
|
|
3183
|
+
scene.screenSpaceCameraController.enableInputs = false;
|
|
3184
|
+
scene.screenSpaceCameraController.enableTranslate = false;
|
|
3185
|
+
scene.screenSpaceCameraController.enableZoom = false;
|
|
3186
|
+
scene.screenSpaceCameraController.enableRotate = false;
|
|
3187
|
+
scene.screenSpaceCameraController.enableTilt = false;
|
|
3188
|
+
}
|
|
3189
|
+
else {
|
|
3190
|
+
scene.screenSpaceCameraController.enableInputs = true;
|
|
3191
|
+
scene.screenSpaceCameraController.enableTranslate = true;
|
|
3192
|
+
scene.screenSpaceCameraController.enableZoom = true;
|
|
3193
|
+
scene.screenSpaceCameraController.enableRotate = true;
|
|
3194
|
+
if (!ViewUtils.Get2dStatus({ viewer })) {
|
|
3195
|
+
scene.screenSpaceCameraController.enableTilt = true;
|
|
3196
|
+
}
|
|
3197
|
+
}
|
|
3198
|
+
viewer.scene.requestRender();
|
|
3199
|
+
}
|
|
3200
|
+
ViewUtils.SetLockedCameraStatus = SetLockedCameraStatus;
|
|
3201
|
+
function GetLockedCameraStatus(params) {
|
|
3202
|
+
var _a;
|
|
3203
|
+
const scene = (_a = params.viewer) === null || _a === void 0 ? void 0 : _a.scene;
|
|
3204
|
+
if (!scene) {
|
|
3205
|
+
return false;
|
|
3206
|
+
}
|
|
3207
|
+
return !scene.screenSpaceCameraController.enableTranslate;
|
|
3208
|
+
}
|
|
3209
|
+
ViewUtils.GetLockedCameraStatus = GetLockedCameraStatus;
|
|
3210
|
+
/**
|
|
3211
|
+
* Returns the current camera time and related settings.
|
|
3212
|
+
* @param params
|
|
3213
|
+
* @returns
|
|
3214
|
+
*/
|
|
3215
|
+
function GetTimeDetails(params) {
|
|
3216
|
+
const { viewer } = params;
|
|
3217
|
+
const clock = viewer.clock;
|
|
3218
|
+
return {
|
|
3219
|
+
animationSpeed: clock.multiplier,
|
|
3220
|
+
isAnimating: clock.shouldAnimate,
|
|
3221
|
+
startTime: clock.startTime,
|
|
3222
|
+
startTimeIso: clock.startTime.toString(),
|
|
3223
|
+
currentTime: clock.currentTime,
|
|
3224
|
+
currentTimeIso: clock.currentTime.toString(),
|
|
3225
|
+
stopTime: clock.stopTime,
|
|
3226
|
+
stopTimeIso: clock.stopTime.toString(),
|
|
3227
|
+
areCesiumValues: clock[CESIUM_TIMELINE_KEY] != true,
|
|
3228
|
+
isLive: clock[CESIUM_TIMELINE_LIVE_KEY] == true,
|
|
3229
|
+
livePaddingSeconds: clock[CESIUM_TIMELINE_LIVE_PADDING_KEY] || DEFAULT_LIVE_PADDING_SECONDS
|
|
3230
|
+
};
|
|
3231
|
+
}
|
|
3232
|
+
ViewUtils.GetTimeDetails = GetTimeDetails;
|
|
3233
|
+
/**
|
|
3234
|
+
* Sets the Cesium clock values.
|
|
3235
|
+
* If a value is not provided, then 'areCesiumValues' checked to see if the values are Cesium values.
|
|
3236
|
+
* If they're currently Cesium set values then our defaults are used.
|
|
3237
|
+
* @param params
|
|
3238
|
+
*/
|
|
3239
|
+
function SetTimeDetails(params) {
|
|
3240
|
+
let { viewer, animationSpeed, isAnimating, startTime, currentTime, stopTime, startTimeIso, stopTimeIso, currentTimeIso, isLive, livePaddingSeconds } = params;
|
|
3241
|
+
const clock = viewer.clock;
|
|
3242
|
+
if (startTime) {
|
|
3243
|
+
clock.startTime = startTime;
|
|
3244
|
+
}
|
|
3245
|
+
else if (startTimeIso) {
|
|
3246
|
+
const startDate = Cesium.JulianDate.fromIso8601(startTimeIso);
|
|
3247
|
+
if (startDate) {
|
|
3248
|
+
clock.startTime = startDate;
|
|
3249
|
+
}
|
|
3250
|
+
}
|
|
3251
|
+
if (currentTime) {
|
|
3252
|
+
clock.currentTime = currentTime;
|
|
3253
|
+
}
|
|
3254
|
+
else if (currentTimeIso) {
|
|
3255
|
+
const currentDate = Cesium.JulianDate.fromIso8601(currentTimeIso);
|
|
3256
|
+
if (currentDate) {
|
|
3257
|
+
clock.currentTime = currentDate;
|
|
3258
|
+
}
|
|
3259
|
+
}
|
|
3260
|
+
if (stopTime) {
|
|
3261
|
+
clock.stopTime = stopTime;
|
|
3262
|
+
}
|
|
3263
|
+
else if (stopTimeIso) {
|
|
3264
|
+
const stopDate = Cesium.JulianDate.fromIso8601(stopTimeIso);
|
|
3265
|
+
if (stopDate) {
|
|
3266
|
+
clock.stopTime = stopDate;
|
|
3267
|
+
}
|
|
3268
|
+
}
|
|
3269
|
+
clock.clockRange = Cesium.ClockRange.LOOP_STOP;
|
|
3270
|
+
const areCesiumValues = clock[CESIUM_TIMELINE_KEY] != true;
|
|
3271
|
+
if (areCesiumValues) {
|
|
3272
|
+
if (isNaN(animationSpeed) || animationSpeed == null) {
|
|
3273
|
+
animationSpeed = 1;
|
|
3274
|
+
}
|
|
3275
|
+
if (isAnimating == null) {
|
|
3276
|
+
isAnimating = false;
|
|
3277
|
+
}
|
|
3278
|
+
if (isLive == null) {
|
|
3279
|
+
isLive = false;
|
|
3280
|
+
}
|
|
3281
|
+
if (livePaddingSeconds == null) {
|
|
3282
|
+
livePaddingSeconds = DEFAULT_LIVE_PADDING_SECONDS;
|
|
3283
|
+
}
|
|
3284
|
+
}
|
|
3285
|
+
if (!isNaN(animationSpeed) && animationSpeed != null) {
|
|
3286
|
+
clock.multiplier = animationSpeed;
|
|
3287
|
+
}
|
|
3288
|
+
if (isAnimating != null) {
|
|
3289
|
+
clock.shouldAnimate = isAnimating;
|
|
3290
|
+
}
|
|
3291
|
+
viewer.scene.requestRender();
|
|
3292
|
+
clock[CESIUM_TIMELINE_KEY] = true;
|
|
3293
|
+
if (livePaddingSeconds != null) {
|
|
3294
|
+
clock[CESIUM_TIMELINE_LIVE_PADDING_KEY] = livePaddingSeconds || DEFAULT_LIVE_PADDING_SECONDS;
|
|
3295
|
+
}
|
|
3296
|
+
if (isLive != null) {
|
|
3297
|
+
clock[CESIUM_TIMELINE_LIVE_KEY] = params.isLive == true;
|
|
3298
|
+
}
|
|
3299
|
+
if (clock[CESIUM_TIMELINE_LIVE_KEY]) {
|
|
3300
|
+
startLive(viewer);
|
|
3301
|
+
}
|
|
3302
|
+
else {
|
|
3303
|
+
stopLive(viewer);
|
|
3304
|
+
}
|
|
3305
|
+
}
|
|
3306
|
+
ViewUtils.SetTimeDetails = SetTimeDetails;
|
|
3307
|
+
function startLive(viewer) {
|
|
3308
|
+
const doUpdate = () => {
|
|
3309
|
+
if (!viewer || viewer.isDestroyed() || !viewer.scene) {
|
|
3310
|
+
stopLive(viewer);
|
|
3311
|
+
return;
|
|
3312
|
+
}
|
|
3313
|
+
// Get the current settings.
|
|
3314
|
+
const tDetails = GetTimeDetails({ viewer });
|
|
3315
|
+
const clock = viewer.clock;
|
|
3316
|
+
if (clock) {
|
|
3317
|
+
clock.shouldAnimate = true;
|
|
3318
|
+
clock.multiplier = 1;
|
|
3319
|
+
clock.currentTime = Cesium.JulianDate.now();
|
|
3320
|
+
clock.startTime = Cesium.JulianDate.addSeconds(clock.currentTime, -tDetails.livePaddingSeconds, new Cesium.JulianDate());
|
|
3321
|
+
clock.stopTime = Cesium.JulianDate.addSeconds(clock.currentTime, tDetails.livePaddingSeconds, new Cesium.JulianDate());
|
|
3322
|
+
clock.clockRange = Cesium.ClockRange.UNBOUNDED;
|
|
3323
|
+
}
|
|
3324
|
+
};
|
|
3325
|
+
if (viewer[CESIUM_TIMELINE_INTERVAL_KEY]) {
|
|
3326
|
+
doUpdate();
|
|
3327
|
+
return;
|
|
3328
|
+
}
|
|
3329
|
+
// We'll start an interval that occasionally updates the Cesium clock to stay in the desired settings.
|
|
3330
|
+
// Since it moves live (1 second per second), we don't have to worry about the ranges being out of date quickly.
|
|
3331
|
+
viewer[CESIUM_TIMELINE_INTERVAL_KEY] = setInterval(() => {
|
|
3332
|
+
doUpdate();
|
|
3333
|
+
}, 800);
|
|
3334
|
+
viewer[CESIUM_TIMELINE_LIVE_KEY] = true;
|
|
3335
|
+
// Initial update.
|
|
3336
|
+
doUpdate();
|
|
3337
|
+
}
|
|
3338
|
+
function stopLive(viewer) {
|
|
3339
|
+
if (!viewer) {
|
|
3340
|
+
return;
|
|
3341
|
+
}
|
|
3342
|
+
let interval = viewer[CESIUM_TIMELINE_INTERVAL_KEY];
|
|
3343
|
+
if (interval) {
|
|
3344
|
+
clearInterval(interval);
|
|
3345
|
+
viewer[CESIUM_TIMELINE_INTERVAL_KEY] = null;
|
|
3346
|
+
}
|
|
3347
|
+
viewer[CESIUM_TIMELINE_LIVE_KEY] = false;
|
|
3348
|
+
}
|
|
3349
|
+
function SetGlobeDetails(params) {
|
|
3350
|
+
let { viewer, hidden, baseColor } = params;
|
|
3351
|
+
const scene = viewer === null || viewer === void 0 ? void 0 : viewer.scene;
|
|
3352
|
+
if (!(scene === null || scene === void 0 ? void 0 : scene.globe)) {
|
|
3353
|
+
return;
|
|
3354
|
+
}
|
|
3355
|
+
if (hidden == null) {
|
|
3356
|
+
hidden = !scene.globe.show;
|
|
3357
|
+
}
|
|
3358
|
+
else {
|
|
3359
|
+
scene.globe.show = !hidden;
|
|
3360
|
+
}
|
|
3361
|
+
if (baseColor == null) {
|
|
3362
|
+
baseColor = scene.globe.baseColor;
|
|
3363
|
+
}
|
|
3364
|
+
// When globe is off, we'll also hide the stars/moon.
|
|
3365
|
+
// We also grab the globe color and apply it to the sky.
|
|
3366
|
+
if (hidden && GetModelSpace(viewer)) {
|
|
3367
|
+
scene.skyBox.show = false;
|
|
3368
|
+
scene.skyAtmosphere.show = false;
|
|
3369
|
+
scene.sun.show = false;
|
|
3370
|
+
scene.moon.show = false;
|
|
3371
|
+
scene.backgroundColor = baseColor.clone();
|
|
3372
|
+
}
|
|
3373
|
+
else {
|
|
3374
|
+
scene.skyBox.show = true;
|
|
3375
|
+
scene.skyAtmosphere.show = true;
|
|
3376
|
+
scene.sun.show = true;
|
|
3377
|
+
scene.moon.show = true;
|
|
3378
|
+
scene.backgroundColor = Cesium.Color.BLACK;
|
|
3379
|
+
}
|
|
3380
|
+
scene.globe.baseColor = baseColor;
|
|
3381
|
+
}
|
|
3382
|
+
ViewUtils.SetGlobeDetails = SetGlobeDetails;
|
|
3383
|
+
function SetModelSpace(viewer, modelSpace) {
|
|
3384
|
+
if (!viewer) {
|
|
3385
|
+
return;
|
|
3386
|
+
}
|
|
3387
|
+
if (viewer[CESIUM_MODEL_SPACE_KEY] === modelSpace) {
|
|
3388
|
+
return;
|
|
3389
|
+
}
|
|
3390
|
+
viewer[CESIUM_MODEL_SPACE_KEY] = modelSpace;
|
|
3391
|
+
// Reload globe since we display it differently between the two modes.
|
|
3392
|
+
SetGlobeDetails({ viewer });
|
|
3393
|
+
}
|
|
3394
|
+
ViewUtils.SetModelSpace = SetModelSpace;
|
|
3395
|
+
function GetModelSpace(viewer) {
|
|
3396
|
+
if (!viewer) {
|
|
3397
|
+
return false;
|
|
3398
|
+
}
|
|
3399
|
+
return Boolean(viewer[CESIUM_MODEL_SPACE_KEY]);
|
|
3400
|
+
}
|
|
3401
|
+
ViewUtils.GetModelSpace = GetModelSpace;
|
|
3402
|
+
})(exports.ViewUtils || (exports.ViewUtils = {}));
|
|
3403
|
+
|
|
3404
|
+
/**
|
|
3405
|
+
* Returns cesium property's value.
|
|
3406
|
+
* This will check if it's one that changes over time, or just a fixed value.
|
|
3407
|
+
* Eg: const pos3d = getValue<Cesium.Cartesian3>(cViewer, cEntity.point.position);
|
|
3408
|
+
* @param viewer
|
|
3409
|
+
* @param obj
|
|
3410
|
+
*/
|
|
3411
|
+
function getValue(viewer, obj) {
|
|
3412
|
+
if (obj === null || obj === void 0 ? void 0 : obj.getValue) {
|
|
3413
|
+
let date = viewer.scene.lastRenderTime;
|
|
3414
|
+
if (!date) {
|
|
3415
|
+
date = viewer.clock.currentTime;
|
|
3416
|
+
}
|
|
3417
|
+
return obj.getValue(date);
|
|
3182
3418
|
}
|
|
3183
3419
|
return obj;
|
|
3184
3420
|
}
|
|
@@ -3862,508 +4098,594 @@
|
|
|
3862
4098
|
EntityLabel.GetLabel = GetLabel;
|
|
3863
4099
|
})(exports.EntityLabel || (exports.EntityLabel = {}));
|
|
3864
4100
|
|
|
3865
|
-
function OnNextCRender(viewer, callback) {
|
|
3866
|
-
const removal = viewer.scene.postRender.addEventListener(() => {
|
|
3867
|
-
removal();
|
|
3868
|
-
callback();
|
|
3869
|
-
});
|
|
3870
|
-
}
|
|
3871
|
-
function GetCValue(viewer, obj) {
|
|
3872
|
-
if (obj === null || obj === void 0 ? void 0 : obj.getValue) {
|
|
3873
|
-
let date = viewer.scene.lastRenderTime;
|
|
3874
|
-
if (!date) {
|
|
3875
|
-
date = viewer.clock.currentTime;
|
|
3876
|
-
}
|
|
3877
|
-
return obj.getValue(date);
|
|
3878
|
-
}
|
|
3879
|
-
return obj;
|
|
3880
|
-
}
|
|
3881
|
-
function ColorToCColor(color) {
|
|
3882
|
-
return new Cesium.Color(color.red ? color.red / 255 : 0, color.green ? color.green / 255 : 0, color.blue ? color.blue / 255 : 0, color.alpha);
|
|
3883
|
-
}
|
|
3884
4101
|
/**
|
|
3885
|
-
*
|
|
3886
|
-
* Passed array is not mutated.
|
|
3887
|
-
* @param posses
|
|
4102
|
+
* Utility for rendering parabolas between two points on the map.
|
|
3888
4103
|
*/
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
for (let i = 0; i < posses.length; i++) {
|
|
3893
|
-
const pos = posses[i];
|
|
3894
|
-
// Avoiding 'Cesium.Cartesian3.equals' because passed data might be just a json blob in certain cases.
|
|
3895
|
-
if (pos && (!lastPos || (pos.x != lastPos.x || pos.y != lastPos.y || pos.z != lastPos.z))) {
|
|
3896
|
-
newPosses.push(pos);
|
|
3897
|
-
lastPos = pos;
|
|
3898
|
-
}
|
|
4104
|
+
class CesiumParabola {
|
|
4105
|
+
get Disposed() {
|
|
4106
|
+
return this.disposed;
|
|
3899
4107
|
}
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
/**
|
|
3903
|
-
* Returns if the given positions are equal.
|
|
3904
|
-
* @param a
|
|
3905
|
-
* @param b
|
|
3906
|
-
*/
|
|
3907
|
-
function CompareCPosses(a, b) {
|
|
3908
|
-
// Same reference.
|
|
3909
|
-
if (a == b) {
|
|
3910
|
-
return true;
|
|
4108
|
+
set Hidden(value) {
|
|
4109
|
+
this.hidden = value;
|
|
3911
4110
|
}
|
|
3912
|
-
|
|
3913
|
-
|
|
3914
|
-
return false;
|
|
4111
|
+
get curPos1() {
|
|
4112
|
+
return this.pos1 instanceof Function ? this.pos1() : this.pos1;
|
|
3915
4113
|
}
|
|
3916
|
-
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
|
|
4114
|
+
get curPos2() {
|
|
4115
|
+
return this.pos2 instanceof Function ? this.pos2() : this.pos2;
|
|
4116
|
+
}
|
|
4117
|
+
constructor(params) {
|
|
4118
|
+
this.disposed = false;
|
|
4119
|
+
this.color = "white";
|
|
4120
|
+
this.width = 2;
|
|
4121
|
+
this.duration = 10;
|
|
4122
|
+
this.heightDistanceRatio = 0.25;
|
|
4123
|
+
this.curPoints = [];
|
|
4124
|
+
this.animateInterval = null;
|
|
4125
|
+
this.retryTimeout = null;
|
|
4126
|
+
this.hidden = false;
|
|
4127
|
+
this.viewer = params.viewer;
|
|
4128
|
+
this.pos1 = params.pos1;
|
|
4129
|
+
this.pos2 = params.pos2;
|
|
4130
|
+
if (params.color) {
|
|
4131
|
+
this.color = params.color;
|
|
3922
4132
|
}
|
|
3923
|
-
|
|
3924
|
-
|
|
3925
|
-
return false;
|
|
4133
|
+
if (!isNaN(params.width)) {
|
|
4134
|
+
this.width = params.width;
|
|
3926
4135
|
}
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
* @param a
|
|
3933
|
-
* @param b
|
|
3934
|
-
*/
|
|
3935
|
-
function CompareCPolygonHierarchies(a, b) {
|
|
3936
|
-
// Same reference.
|
|
3937
|
-
if (a == b) {
|
|
3938
|
-
return true;
|
|
3939
|
-
}
|
|
3940
|
-
// Different lengths or one is null.
|
|
3941
|
-
if ((!a || !b) || (a.positions.length != b.positions.length)) {
|
|
3942
|
-
return false;
|
|
3943
|
-
}
|
|
3944
|
-
// Positions don't match.
|
|
3945
|
-
if (!CompareCPosses(a.positions, b.positions)) {
|
|
3946
|
-
return false;
|
|
3947
|
-
}
|
|
3948
|
-
const holes = a.holes;
|
|
3949
|
-
const bHoles = b.holes;
|
|
3950
|
-
// Number of holes don't match.
|
|
3951
|
-
if (holes.length != bHoles.length) {
|
|
3952
|
-
return false;
|
|
3953
|
-
}
|
|
3954
|
-
for (let i = 0; i < holes.length; i++) {
|
|
3955
|
-
// Hole positions don't match.
|
|
3956
|
-
if (!CompareCPosses(holes[i].positions, bHoles[i].positions)) {
|
|
3957
|
-
return false;
|
|
4136
|
+
if (!isNaN(params.duration)) {
|
|
4137
|
+
this.duration = params.duration;
|
|
4138
|
+
}
|
|
4139
|
+
if (!isNaN(params.heightDistanceRatio)) {
|
|
4140
|
+
this.heightDistanceRatio = params.heightDistanceRatio;
|
|
3958
4141
|
}
|
|
4142
|
+
this.prepareEntities();
|
|
3959
4143
|
}
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
3971
|
-
function GatherLegacyMapTiles(params) {
|
|
3972
|
-
const viewer = params.viewer;
|
|
3973
|
-
const collection = viewer.imageryLayers;
|
|
3974
|
-
const tiles = [];
|
|
3975
|
-
for (let i = 0; i < collection.length; i++) {
|
|
3976
|
-
const layer = collection.get(i);
|
|
3977
|
-
if (layer._bName) {
|
|
3978
|
-
tiles.push({
|
|
3979
|
-
alpha: layer.alpha,
|
|
3980
|
-
brightness: layer.brightness,
|
|
3981
|
-
contrast: layer.contrast,
|
|
3982
|
-
hue: layer.hue,
|
|
3983
|
-
saturation: layer.saturation,
|
|
3984
|
-
gamma: layer.gamma,
|
|
3985
|
-
title: layer._bName,
|
|
3986
|
-
});
|
|
4144
|
+
prepareEntities() {
|
|
4145
|
+
const parabola = new Cesium.Entity({
|
|
4146
|
+
polyline: {
|
|
4147
|
+
positions: new Cesium.CallbackProperty(() => {
|
|
4148
|
+
return this.curPoints;
|
|
4149
|
+
}, false),
|
|
4150
|
+
width: this.width,
|
|
4151
|
+
material: Cesium.Color.fromCssColorString(this.color),
|
|
4152
|
+
show: new Cesium.CallbackProperty(() => {
|
|
4153
|
+
return !this.hidden;
|
|
4154
|
+
}, false)
|
|
3987
4155
|
}
|
|
3988
|
-
}
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
4156
|
+
});
|
|
4157
|
+
const p1Entity = new Cesium.Entity({
|
|
4158
|
+
position: new Cesium.CallbackProperty(() => {
|
|
4159
|
+
return this.curPoints.length ? this.curPoints[0] : new Cesium.Cartesian3();
|
|
4160
|
+
}, false),
|
|
4161
|
+
point: {
|
|
4162
|
+
heightReference: Cesium.HeightReference.NONE,
|
|
4163
|
+
pixelSize: this.width * 1.3,
|
|
4164
|
+
color: Cesium.Color.fromCssColorString(this.color),
|
|
4165
|
+
outlineColor: Cesium.Color.WHITE,
|
|
4166
|
+
outlineWidth: 2,
|
|
4167
|
+
show: new Cesium.CallbackProperty(() => {
|
|
4168
|
+
return !this.hidden;
|
|
4169
|
+
}, false)
|
|
4170
|
+
}
|
|
4171
|
+
});
|
|
4172
|
+
const p2Entity = new Cesium.Entity({
|
|
4173
|
+
position: new Cesium.CallbackProperty(() => {
|
|
4174
|
+
return this.curPoints.length ? this.curPoints[this.curPoints.length - 1] : new Cesium.Cartesian3();
|
|
4175
|
+
}, false),
|
|
4176
|
+
point: {
|
|
4177
|
+
heightReference: Cesium.HeightReference.NONE,
|
|
4178
|
+
pixelSize: this.width * 1.8,
|
|
4179
|
+
color: Cesium.Color.fromCssColorString(this.color),
|
|
4180
|
+
outlineColor: Cesium.Color.WHITE,
|
|
4181
|
+
outlineWidth: 2,
|
|
4182
|
+
show: new Cesium.CallbackProperty(() => {
|
|
4183
|
+
return !this.hidden;
|
|
4184
|
+
}, false)
|
|
4185
|
+
}
|
|
4186
|
+
});
|
|
4187
|
+
p1Entity.parent = parabola;
|
|
4188
|
+
p2Entity.parent = parabola;
|
|
4189
|
+
const siblings = [p1Entity, p2Entity];
|
|
4190
|
+
this.parabola = parabola;
|
|
4191
|
+
this.siblings = siblings;
|
|
4192
|
+
// The parabola is hidden while this entity is not added.
|
|
4193
|
+
// If we avoid adding it now, then the parent can control if the parabola is visible at first or not.
|
|
4194
|
+
// this.viewer.entities.add(this.parabola);
|
|
4195
|
+
this.viewer.entities.add(p1Entity);
|
|
4196
|
+
this.viewer.entities.add(p2Entity);
|
|
3992
4197
|
}
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
|
|
3996
|
-
const enabled = viewer.terrainProvider;
|
|
3997
|
-
if (enabled === null || enabled === void 0 ? void 0 : enabled._bName) {
|
|
3998
|
-
return {
|
|
3999
|
-
terrain: enabled._bName
|
|
4000
|
-
};
|
|
4198
|
+
Animate() {
|
|
4199
|
+
if (this.disposed) {
|
|
4200
|
+
return null;
|
|
4001
4201
|
}
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
}
|
|
4006
|
-
ViewUtils.GatherLegacyTerrainTile = GatherLegacyTerrainTile;
|
|
4007
|
-
function GatherMapTiles(params) {
|
|
4008
|
-
const viewer = params.viewer;
|
|
4009
|
-
const imagery = viewer.imageryLayers;
|
|
4010
|
-
const tiles = [];
|
|
4011
|
-
for (let i = 0; i < imagery.length; i++) {
|
|
4012
|
-
const provider = imagery.get(i);
|
|
4013
|
-
if (provider._bMeta) {
|
|
4014
|
-
const idCombo = provider._bMeta.accountId + provider._bMeta.tilesetId;
|
|
4015
|
-
if (!tiles.find(x => x.accountId + x.tilesetId === idCombo)) {
|
|
4016
|
-
tiles.push({
|
|
4017
|
-
accountId: provider._bMeta.accountId,
|
|
4018
|
-
tilesetId: provider._bMeta.tilesetId,
|
|
4019
|
-
alpha: provider.alpha,
|
|
4020
|
-
brightness: provider.brightness,
|
|
4021
|
-
contrast: provider.contrast,
|
|
4022
|
-
hue: provider.hue,
|
|
4023
|
-
saturation: provider.saturation,
|
|
4024
|
-
gamma: provider.gamma
|
|
4025
|
-
});
|
|
4026
|
-
}
|
|
4027
|
-
}
|
|
4202
|
+
let retry = false;
|
|
4203
|
+
if (!this.curPos1 || !this.curPos2 || !BModels.Cartes.ValidateCartes3(this.curPos1) || !BModels.Cartes.ValidateCartes3(this.curPos2)) {
|
|
4204
|
+
retry = true;
|
|
4028
4205
|
}
|
|
4029
|
-
|
|
4030
|
-
|
|
4031
|
-
|
|
4032
|
-
}
|
|
4033
|
-
ViewUtils.GatherMapTiles = GatherMapTiles;
|
|
4034
|
-
function GatherTerrainTile(params) {
|
|
4035
|
-
const viewer = params.viewer;
|
|
4036
|
-
const provider = viewer.terrainProvider;
|
|
4037
|
-
if (provider === null || provider === void 0 ? void 0 : provider._bMeta) {
|
|
4038
|
-
return {
|
|
4039
|
-
terrain: {
|
|
4040
|
-
accountId: provider._bMeta.accountId,
|
|
4041
|
-
tilesetId: provider._bMeta.tilesetId,
|
|
4042
|
-
}
|
|
4043
|
-
};
|
|
4206
|
+
let TOTAL_LENGTH = retry ? 0 : Cesium.Cartesian3.distance(this.curPos1, this.curPos2);
|
|
4207
|
+
if (TOTAL_LENGTH <= 0) {
|
|
4208
|
+
retry = true;
|
|
4044
4209
|
}
|
|
4045
|
-
|
|
4210
|
+
if (retry) {
|
|
4211
|
+
this.retryTimeout = setTimeout(() => {
|
|
4212
|
+
this.Animate();
|
|
4213
|
+
}, 2000);
|
|
4046
4214
|
return {
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
accountId: null
|
|
4050
|
-
}
|
|
4215
|
+
parabola: this.parabola,
|
|
4216
|
+
siblings: this.siblings
|
|
4051
4217
|
};
|
|
4052
4218
|
}
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4219
|
+
const RATE_PER_SECOND = 1000 / 40;
|
|
4220
|
+
const SEC_DURATION = this.duration;
|
|
4221
|
+
const HEIGHT_DISTANCE_RATIO = this.heightDistanceRatio;
|
|
4222
|
+
let TOTAL_POINTS = null;
|
|
4223
|
+
let POINT_LENGTH = null;
|
|
4224
|
+
let TICK_LENGTH_INC = null;
|
|
4225
|
+
// Updates TOTAL_POINTS, POINT_LENGTH, and TICK_LENGTH_INC based on current TOTAL_LENGTH and camera position.
|
|
4226
|
+
// We want less points the further away the camera is.
|
|
4227
|
+
const updateParams = () => {
|
|
4228
|
+
var _a, _b;
|
|
4229
|
+
// TODO: Do distance to parabola line instead.
|
|
4230
|
+
const MIN_POINTS = 30;
|
|
4231
|
+
let totalPoints = 80;
|
|
4232
|
+
let cameraHeight = (_b = (_a = this.viewer.camera) === null || _a === void 0 ? void 0 : _a.positionCartographic) === null || _b === void 0 ? void 0 : _b.height;
|
|
4233
|
+
if (isNaN(cameraHeight) || cameraHeight >= 100000) {
|
|
4234
|
+
totalPoints = MIN_POINTS;
|
|
4064
4235
|
}
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4236
|
+
else if (cameraHeight >= 10000) {
|
|
4237
|
+
totalPoints = 50;
|
|
4238
|
+
}
|
|
4239
|
+
else if (cameraHeight >= 1000) {
|
|
4240
|
+
totalPoints = 80;
|
|
4241
|
+
}
|
|
4242
|
+
else if (cameraHeight >= 100) {
|
|
4243
|
+
totalPoints = 100;
|
|
4244
|
+
}
|
|
4245
|
+
TOTAL_POINTS = Math.max(MIN_POINTS, Math.min(totalPoints, TOTAL_LENGTH * 0.1));
|
|
4246
|
+
POINT_LENGTH = TOTAL_LENGTH / TOTAL_POINTS;
|
|
4247
|
+
TICK_LENGTH_INC = SEC_DURATION == 0 ? TOTAL_LENGTH : TOTAL_POINTS / (RATE_PER_SECOND * SEC_DURATION);
|
|
4248
|
+
};
|
|
4249
|
+
updateParams();
|
|
4250
|
+
let curPoint = 0;
|
|
4251
|
+
let quadraticKey = null;
|
|
4252
|
+
let quadratic = null;
|
|
4253
|
+
let quadraticPreparing = false;
|
|
4254
|
+
const prepareQuadratic = async () => {
|
|
4255
|
+
if (quadraticPreparing) {
|
|
4256
|
+
return;
|
|
4257
|
+
}
|
|
4258
|
+
quadraticPreparing = true;
|
|
4259
|
+
try {
|
|
4260
|
+
const p1 = this.curPos1;
|
|
4261
|
+
const p2 = this.curPos2;
|
|
4262
|
+
if (!p1 || !p2 || !BModels.Cartes.ValidateCartes3(p1) || !BModels.Cartes.ValidateCartes3(p2)) {
|
|
4263
|
+
return;
|
|
4264
|
+
}
|
|
4265
|
+
const height1 = Cesium.Cartographic.fromCartesian(p1).height;
|
|
4266
|
+
const height2 = Cesium.Cartographic.fromCartesian(p2).height;
|
|
4267
|
+
if (isNaN(height1) || isNaN(height2)) {
|
|
4268
|
+
return;
|
|
4269
|
+
}
|
|
4270
|
+
const totalHeight = height2 + height1;
|
|
4271
|
+
const curQuadraticKey = `${height1}-${height2}-${TOTAL_LENGTH}`;
|
|
4272
|
+
if (quadraticKey == curQuadraticKey) {
|
|
4273
|
+
return;
|
|
4274
|
+
}
|
|
4275
|
+
const points2d = [
|
|
4276
|
+
new Cesium.Cartesian2(0, height1),
|
|
4277
|
+
new Cesium.Cartesian2(TOTAL_LENGTH, height2)
|
|
4278
|
+
];
|
|
4279
|
+
let vertexHeight = 0;
|
|
4280
|
+
// Flat line.
|
|
4281
|
+
if (HEIGHT_DISTANCE_RATIO == 0) {
|
|
4282
|
+
vertexHeight = totalHeight * 0.5;
|
|
4283
|
+
}
|
|
4284
|
+
else {
|
|
4285
|
+
const largestHeight = Math.max(height1, height2);
|
|
4286
|
+
vertexHeight = largestHeight + (TOTAL_LENGTH * HEIGHT_DISTANCE_RATIO);
|
|
4287
|
+
}
|
|
4288
|
+
points2d.push(new Cesium.Cartesian2(TOTAL_LENGTH * 0.5, vertexHeight));
|
|
4289
|
+
const calcQuadratic = (points) => {
|
|
4290
|
+
// Swaps position of two rows in matrix.
|
|
4291
|
+
function swapRows(matrix, rowAIndex, rowBIndex) {
|
|
4292
|
+
const rowAVal = matrix[rowAIndex];
|
|
4293
|
+
matrix[rowAIndex] = matrix[rowBIndex];
|
|
4294
|
+
matrix[rowBIndex] = rowAVal;
|
|
4295
|
+
return matrix;
|
|
4111
4296
|
}
|
|
4112
|
-
//
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4297
|
+
// Zeros rowA at colIndex by subtracting a multiplied rowB from it.
|
|
4298
|
+
function reduceMatrixRowByRow(matrix, zeroingIndex, parentIndex, colIndex) {
|
|
4299
|
+
const zeroRow = matrix[zeroingIndex];
|
|
4300
|
+
const parentRow = matrix[parentIndex];
|
|
4301
|
+
if (zeroRow[colIndex] == 0) {
|
|
4302
|
+
return matrix;
|
|
4303
|
+
}
|
|
4304
|
+
else if (parentRow[colIndex] == 0) {
|
|
4305
|
+
matrix = swapRows(matrix, parentIndex, zeroingIndex);
|
|
4306
|
+
return divideMatrixRow(matrix, parentIndex, colIndex);
|
|
4307
|
+
}
|
|
4308
|
+
// rowAIndex colIndex / rowBIndex colIndex = factor;
|
|
4309
|
+
let factor = zeroRow[colIndex] / parentRow[colIndex];
|
|
4310
|
+
for (let i = 0; i < zeroRow.length; i++) {
|
|
4311
|
+
if (i >= colIndex) {
|
|
4312
|
+
zeroRow[i] -= parentRow[i] * factor;
|
|
4313
|
+
}
|
|
4314
|
+
}
|
|
4315
|
+
return matrix;
|
|
4116
4316
|
}
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4317
|
+
// Makes a given row column equal 1 by diving while row by that column.
|
|
4318
|
+
function divideMatrixRow(matrix, rowIndex, colIndex) {
|
|
4319
|
+
const row = matrix[rowIndex];
|
|
4320
|
+
const colValue = row[colIndex];
|
|
4321
|
+
for (let i = 0; i < row.length; i++) {
|
|
4322
|
+
if (i >= colIndex) {
|
|
4323
|
+
row[i] /= colValue;
|
|
4324
|
+
}
|
|
4124
4325
|
}
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4326
|
+
return matrix;
|
|
4327
|
+
}
|
|
4328
|
+
// Returns initial matrix for calculating a, b and c for quadratic formula from given points.
|
|
4329
|
+
function matrixFromPoints(points) {
|
|
4330
|
+
const rows = [];
|
|
4331
|
+
const constructRow = (point) => {
|
|
4332
|
+
rows.push([
|
|
4333
|
+
-Math.pow(point.x, 2),
|
|
4334
|
+
point.x,
|
|
4335
|
+
1,
|
|
4336
|
+
point.y
|
|
4337
|
+
]);
|
|
4338
|
+
};
|
|
4339
|
+
for (let i = 0; i < points.length; i++) {
|
|
4340
|
+
constructRow(points[i]);
|
|
4341
|
+
}
|
|
4342
|
+
return rows;
|
|
4343
|
+
}
|
|
4344
|
+
const initialMatrix = matrixFromPoints(points);
|
|
4345
|
+
const step1Matrix = reduceMatrixRowByRow(initialMatrix, 1, 0, 0);
|
|
4346
|
+
const step2Matrix = reduceMatrixRowByRow(step1Matrix, 2, 0, 0);
|
|
4347
|
+
const step3Matrix = reduceMatrixRowByRow(step2Matrix, 2, 1, 1);
|
|
4348
|
+
const step4Matrix = reduceMatrixRowByRow(step3Matrix, 0, 1, 1);
|
|
4349
|
+
const step5Matrix = reduceMatrixRowByRow(step4Matrix, 0, 2, 2);
|
|
4350
|
+
const step6Matrix = reduceMatrixRowByRow(step5Matrix, 1, 2, 2);
|
|
4351
|
+
const a = step6Matrix[0][3];
|
|
4352
|
+
const b = step6Matrix[1][3];
|
|
4353
|
+
const c = step6Matrix[2][3];
|
|
4354
|
+
return { a: a, b: b, c: c };
|
|
4355
|
+
};
|
|
4356
|
+
quadratic = calcQuadratic(points2d);
|
|
4130
4357
|
}
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
}
|
|
4134
|
-
ViewUtils.Set2dStatus = Set2dStatus;
|
|
4135
|
-
function Get2dStatus(params) {
|
|
4136
|
-
const { viewer } = params;
|
|
4137
|
-
return viewer.camera.frustum instanceof Cesium.OrthographicFrustum;
|
|
4138
|
-
}
|
|
4139
|
-
ViewUtils.Get2dStatus = Get2dStatus;
|
|
4140
|
-
function SetLockedCameraStatus(params) {
|
|
4141
|
-
const { viewer, status } = params;
|
|
4142
|
-
const scene = viewer === null || viewer === void 0 ? void 0 : viewer.scene;
|
|
4143
|
-
if (!scene) {
|
|
4144
|
-
return;
|
|
4145
|
-
}
|
|
4146
|
-
if (status) {
|
|
4147
|
-
scene.screenSpaceCameraController.enableInputs = false;
|
|
4148
|
-
scene.screenSpaceCameraController.enableTranslate = false;
|
|
4149
|
-
scene.screenSpaceCameraController.enableZoom = false;
|
|
4150
|
-
scene.screenSpaceCameraController.enableRotate = false;
|
|
4151
|
-
scene.screenSpaceCameraController.enableTilt = false;
|
|
4152
|
-
}
|
|
4153
|
-
else {
|
|
4154
|
-
scene.screenSpaceCameraController.enableInputs = true;
|
|
4155
|
-
scene.screenSpaceCameraController.enableTranslate = true;
|
|
4156
|
-
scene.screenSpaceCameraController.enableZoom = true;
|
|
4157
|
-
scene.screenSpaceCameraController.enableRotate = true;
|
|
4158
|
-
if (!ViewUtils.Get2dStatus({ viewer })) {
|
|
4159
|
-
scene.screenSpaceCameraController.enableTilt = true;
|
|
4358
|
+
catch (e) {
|
|
4359
|
+
console.error(e);
|
|
4160
4360
|
}
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
|
|
4164
|
-
|
|
4165
|
-
|
|
4166
|
-
|
|
4167
|
-
|
|
4168
|
-
|
|
4169
|
-
|
|
4170
|
-
|
|
4171
|
-
|
|
4172
|
-
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4361
|
+
finally {
|
|
4362
|
+
quadraticPreparing = false;
|
|
4363
|
+
}
|
|
4364
|
+
};
|
|
4365
|
+
const getPosition = (increment) => {
|
|
4366
|
+
if (!quadratic) {
|
|
4367
|
+
return null;
|
|
4368
|
+
}
|
|
4369
|
+
let lengthAcross = POINT_LENGTH * increment;
|
|
4370
|
+
if (lengthAcross > TOTAL_LENGTH) {
|
|
4371
|
+
lengthAcross = TOTAL_LENGTH;
|
|
4372
|
+
}
|
|
4373
|
+
const getParabolaYFromX = (x, quadLetters) => {
|
|
4374
|
+
let a = quadLetters.a;
|
|
4375
|
+
let b = quadLetters.b;
|
|
4376
|
+
let c = quadLetters.c;
|
|
4377
|
+
return (-a * Math.pow(x, 2)) + (b * x) + c;
|
|
4378
|
+
};
|
|
4379
|
+
const { point: pos3d } = exports.DrawingUtils.PointAcrossPolyline({
|
|
4380
|
+
viewer: this.viewer,
|
|
4381
|
+
distance: lengthAcross,
|
|
4382
|
+
posses: [this.curPos1, this.curPos2]
|
|
4383
|
+
});
|
|
4384
|
+
const point = Cesium.Cartographic.fromCartesian(pos3d);
|
|
4385
|
+
const posHeight = getParabolaYFromX(lengthAcross, quadratic);
|
|
4386
|
+
return Cesium.Cartesian3.fromRadians(point.longitude, point.latitude, posHeight);
|
|
4387
|
+
};
|
|
4388
|
+
const updatePoints = () => {
|
|
4389
|
+
if (!quadratic) {
|
|
4390
|
+
return;
|
|
4391
|
+
}
|
|
4392
|
+
const increment = Math.floor(curPoint);
|
|
4393
|
+
const chips = curPoint - Math.floor(curPoint);
|
|
4394
|
+
const posses = [];
|
|
4395
|
+
posses.push(getPosition(0));
|
|
4396
|
+
const addLast = increment >= TOTAL_POINTS;
|
|
4397
|
+
const totalCycles = addLast ? increment + 1 : increment;
|
|
4398
|
+
for (let i = 0; i < totalCycles; i++) {
|
|
4399
|
+
posses.push(getPosition(i));
|
|
4400
|
+
}
|
|
4401
|
+
if (chips) {
|
|
4402
|
+
posses.push(getPosition(increment + chips));
|
|
4403
|
+
}
|
|
4404
|
+
if (posses.find(x => !x || !BModels.Cartes.ValidateCartes3(x))) {
|
|
4405
|
+
return;
|
|
4406
|
+
}
|
|
4407
|
+
this.curPoints = posses;
|
|
4408
|
+
};
|
|
4409
|
+
let lastTickDate = new Date();
|
|
4410
|
+
let finished = false;
|
|
4411
|
+
const doTick = () => {
|
|
4412
|
+
const curDate = new Date();
|
|
4413
|
+
const seconds = (curDate.getTime() - lastTickDate.getTime()) / 1000;
|
|
4414
|
+
const ticks = seconds * RATE_PER_SECOND;
|
|
4415
|
+
if (!isNaN(ticks) && ticks >= 1) {
|
|
4416
|
+
lastTickDate = curDate;
|
|
4417
|
+
const p1 = this.curPos1;
|
|
4418
|
+
const p2 = this.curPos2;
|
|
4419
|
+
const newLength = p1 && p2 ? Cesium.Cartesian3.distance(p1, p2) : -1;
|
|
4420
|
+
if (newLength > 0 && newLength != TOTAL_LENGTH) {
|
|
4421
|
+
TOTAL_LENGTH = newLength;
|
|
4422
|
+
updateParams();
|
|
4423
|
+
}
|
|
4424
|
+
prepareQuadratic();
|
|
4425
|
+
if (quadratic) {
|
|
4426
|
+
if (curPoint < TOTAL_POINTS) {
|
|
4427
|
+
curPoint += (TICK_LENGTH_INC * ticks);
|
|
4428
|
+
}
|
|
4429
|
+
updatePoints();
|
|
4430
|
+
}
|
|
4431
|
+
this.viewer.scene.requestRender();
|
|
4432
|
+
if (curPoint >= TOTAL_POINTS && !finished) {
|
|
4433
|
+
finished = true;
|
|
4434
|
+
// We can make the interval update super slow now.
|
|
4435
|
+
// We keep it updating in case the positions move.
|
|
4436
|
+
clearInterval(this.animateInterval);
|
|
4437
|
+
this.animateInterval = setInterval(doTick, 3000);
|
|
4438
|
+
}
|
|
4439
|
+
}
|
|
4440
|
+
};
|
|
4441
|
+
this.animateInterval = setInterval(doTick, RATE_PER_SECOND);
|
|
4182
4442
|
return {
|
|
4183
|
-
|
|
4184
|
-
|
|
4185
|
-
startTime: clock.startTime,
|
|
4186
|
-
startTimeIso: clock.startTime.toString(),
|
|
4187
|
-
currentTime: clock.currentTime,
|
|
4188
|
-
currentTimeIso: clock.currentTime.toString(),
|
|
4189
|
-
stopTime: clock.stopTime,
|
|
4190
|
-
stopTimeIso: clock.stopTime.toString(),
|
|
4191
|
-
areCesiumValues: clock[CESIUM_TIMELINE_KEY] != true,
|
|
4192
|
-
isLive: clock[CESIUM_TIMELINE_LIVE_KEY] == true,
|
|
4193
|
-
livePaddingSeconds: clock[CESIUM_TIMELINE_LIVE_PADDING_KEY] || DEFAULT_LIVE_PADDING_SECONDS
|
|
4443
|
+
parabola: this.parabola,
|
|
4444
|
+
siblings: this.siblings
|
|
4194
4445
|
};
|
|
4195
4446
|
}
|
|
4196
|
-
|
|
4197
|
-
|
|
4198
|
-
|
|
4199
|
-
|
|
4200
|
-
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
if (startTime) {
|
|
4207
|
-
clock.startTime = startTime;
|
|
4208
|
-
}
|
|
4209
|
-
else if (startTimeIso) {
|
|
4210
|
-
const startDate = Cesium.JulianDate.fromIso8601(startTimeIso);
|
|
4211
|
-
if (startDate) {
|
|
4212
|
-
clock.startTime = startDate;
|
|
4447
|
+
Dispose() {
|
|
4448
|
+
this.disposed = true;
|
|
4449
|
+
clearTimeout(this.retryTimeout);
|
|
4450
|
+
clearInterval(this.animateInterval);
|
|
4451
|
+
const cEntities = [
|
|
4452
|
+
this.parabola
|
|
4453
|
+
].concat(this.siblings);
|
|
4454
|
+
cEntities.forEach(e => {
|
|
4455
|
+
if (e && this.viewer.entities.contains(e)) {
|
|
4456
|
+
this.viewer.entities.remove(e);
|
|
4213
4457
|
}
|
|
4458
|
+
});
|
|
4459
|
+
}
|
|
4460
|
+
}
|
|
4461
|
+
|
|
4462
|
+
function colorToCColor(color) {
|
|
4463
|
+
return new Cesium.Color(color.red ? color.red / 255 : 0, color.green ? color.green / 255 : 0, color.blue ? color.blue / 255 : 0, color.alpha);
|
|
4464
|
+
}
|
|
4465
|
+
async function getStyle(api, typeId, styleId) {
|
|
4466
|
+
let style = null;
|
|
4467
|
+
if (styleId && styleId != -1) {
|
|
4468
|
+
try {
|
|
4469
|
+
style = (await BModels.Style.Get({
|
|
4470
|
+
api,
|
|
4471
|
+
styleId
|
|
4472
|
+
})).style;
|
|
4214
4473
|
}
|
|
4215
|
-
|
|
4216
|
-
|
|
4474
|
+
// Probably deleted.
|
|
4475
|
+
catch (e) {
|
|
4476
|
+
console.error(e);
|
|
4217
4477
|
}
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4478
|
+
}
|
|
4479
|
+
if (!style && typeId) {
|
|
4480
|
+
const { entityType: type } = await BModels.EntityType.Get({
|
|
4481
|
+
api,
|
|
4482
|
+
entityTypeId: typeId
|
|
4483
|
+
});
|
|
4484
|
+
if (type["DisplaySetting.ID"]) {
|
|
4485
|
+
try {
|
|
4486
|
+
style = (await BModels.Style.Get({
|
|
4487
|
+
api,
|
|
4488
|
+
styleId: type["DisplaySetting.ID"]
|
|
4489
|
+
})).style;
|
|
4222
4490
|
}
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4491
|
+
catch (e) {
|
|
4492
|
+
let hideError = false;
|
|
4493
|
+
// TODO: we need a util for extracting code + message rather than writing all this every time.
|
|
4494
|
+
if (e && typeof e == "object" && e.ERROR) {
|
|
4495
|
+
const error = e.ERROR;
|
|
4496
|
+
const code = error && typeof error == "object" ? error.Code : "";
|
|
4497
|
+
// Avoiding logging a common error.
|
|
4498
|
+
// This happens when rendering entities that don't have records.
|
|
4499
|
+
hideError = String(code).toLowerCase() == "notfound";
|
|
4500
|
+
}
|
|
4501
|
+
if (!hideError) {
|
|
4502
|
+
console.error(e);
|
|
4503
|
+
}
|
|
4231
4504
|
}
|
|
4232
4505
|
}
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4506
|
+
}
|
|
4507
|
+
return style;
|
|
4508
|
+
}
|
|
4509
|
+
var RelationRenderEngine;
|
|
4510
|
+
(function (RelationRenderEngine) {
|
|
4511
|
+
function GetRenderGroupId(relation) {
|
|
4512
|
+
return `${relation["Related.Entity.ID"]}-${relation["Principal.Entity.ID"]}-${relation["Relation.Type.ID"]}`;
|
|
4513
|
+
}
|
|
4514
|
+
RelationRenderEngine.GetRenderGroupId = GetRenderGroupId;
|
|
4515
|
+
async function Render(params) {
|
|
4516
|
+
const { apiGetter, viewer, visualRegister, menuItemId, relations } = params;
|
|
4517
|
+
const api = apiGetter.getApi(apiGetter.accountId);
|
|
4518
|
+
const rendered = {};
|
|
4519
|
+
let neededEntityIdsIds = [];
|
|
4520
|
+
for (let i = 0; i < relations.length; i++) {
|
|
4521
|
+
const relation = relations[i];
|
|
4522
|
+
if (relation["Principal.Entity.ID"]) {
|
|
4523
|
+
neededEntityIdsIds.push(relation["Principal.Entity.ID"]);
|
|
4241
4524
|
}
|
|
4242
|
-
if (
|
|
4243
|
-
|
|
4525
|
+
if (relation["Related.Entity.ID"]) {
|
|
4526
|
+
neededEntityIdsIds.push(relation["Related.Entity.ID"]);
|
|
4244
4527
|
}
|
|
4245
|
-
if (
|
|
4246
|
-
|
|
4528
|
+
if (relation["Data.Entity.ID"]) {
|
|
4529
|
+
neededEntityIdsIds.push(relation["Data.Entity.ID"]);
|
|
4247
4530
|
}
|
|
4248
4531
|
}
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
}
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
if (clock[CESIUM_TIMELINE_LIVE_KEY]) {
|
|
4264
|
-
startLive(viewer);
|
|
4532
|
+
// Turn the set unique.
|
|
4533
|
+
neededEntityIdsIds = neededEntityIdsIds.filter((v, i, a) => a.indexOf(v) === i);
|
|
4534
|
+
// Get all entities in one go.
|
|
4535
|
+
let entities = (await BModels.Entity.GetListByIds({
|
|
4536
|
+
entityIds: neededEntityIdsIds,
|
|
4537
|
+
api: apiGetter.getApi(),
|
|
4538
|
+
migrated: true,
|
|
4539
|
+
maxSearchTimeSec: 60 * 2
|
|
4540
|
+
})).entities;
|
|
4541
|
+
// Create a map for quick reference.
|
|
4542
|
+
const entitiesMap = {};
|
|
4543
|
+
for (let i = 0; i < entities.length; i++) {
|
|
4544
|
+
const entity = entities[i];
|
|
4545
|
+
entitiesMap[entity.Bruce.ID] = entity;
|
|
4265
4546
|
}
|
|
4266
|
-
|
|
4267
|
-
|
|
4547
|
+
entities = null;
|
|
4548
|
+
// Gather needed relationship types.
|
|
4549
|
+
// Right now this means just getting the full list.
|
|
4550
|
+
const relationTypes = (await BModels.EntityRelationType.GetList({
|
|
4551
|
+
api
|
|
4552
|
+
})).relationTypes;
|
|
4553
|
+
const relationTypesMap = {};
|
|
4554
|
+
for (let i = 0; i < relationTypes.length; i++) {
|
|
4555
|
+
const relationType = relationTypes[i];
|
|
4556
|
+
relationTypesMap[relationType.ID] = relationType;
|
|
4268
4557
|
}
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4558
|
+
for (let i = 0; i < relations.length; i++) {
|
|
4559
|
+
try {
|
|
4560
|
+
const relation = relations[i];
|
|
4561
|
+
const fromEntity = entitiesMap[relation["Principal.Entity.ID"]];
|
|
4562
|
+
const toEntity = entitiesMap[relation["Related.Entity.ID"]];
|
|
4563
|
+
const dataEntity = relation["Data.Entity.ID"] ? entitiesMap[relation["Data.Entity.ID"]] : null;
|
|
4564
|
+
const relationType = relationTypesMap[relation["Relation.Type.ID"]];
|
|
4565
|
+
const style = await getStyle(api, relationType === null || relationType === void 0 ? void 0 : relationType["Relation.EntityType.ID"], Number(relationType === null || relationType === void 0 ? void 0 : relationType.EntityDisplaySettingID));
|
|
4566
|
+
const cEntity = await Parabola.Render({
|
|
4567
|
+
dataEntity,
|
|
4568
|
+
fromEntity,
|
|
4569
|
+
relation,
|
|
4570
|
+
style,
|
|
4571
|
+
toEntity,
|
|
4572
|
+
viewer,
|
|
4573
|
+
visualRegister,
|
|
4574
|
+
apiGetter
|
|
4575
|
+
});
|
|
4576
|
+
cEntity._renderGroup = GetRenderGroupId(relation);
|
|
4577
|
+
rendered[GetRenderGroupId(relation)] = cEntity;
|
|
4276
4578
|
}
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
const clock = viewer.clock;
|
|
4280
|
-
if (clock) {
|
|
4281
|
-
clock.shouldAnimate = true;
|
|
4282
|
-
clock.multiplier = 1;
|
|
4283
|
-
clock.currentTime = Cesium.JulianDate.now();
|
|
4284
|
-
clock.startTime = Cesium.JulianDate.addSeconds(clock.currentTime, -tDetails.livePaddingSeconds, new Cesium.JulianDate());
|
|
4285
|
-
clock.stopTime = Cesium.JulianDate.addSeconds(clock.currentTime, tDetails.livePaddingSeconds, new Cesium.JulianDate());
|
|
4286
|
-
clock.clockRange = Cesium.ClockRange.UNBOUNDED;
|
|
4579
|
+
catch (e) {
|
|
4580
|
+
console.error(e);
|
|
4287
4581
|
}
|
|
4288
|
-
};
|
|
4289
|
-
if (viewer[CESIUM_TIMELINE_INTERVAL_KEY]) {
|
|
4290
|
-
doUpdate();
|
|
4291
|
-
return;
|
|
4292
|
-
}
|
|
4293
|
-
// We'll start an interval that occasionally updates the Cesium clock to stay in the desired settings.
|
|
4294
|
-
// Since it moves live (1 second per second), we don't have to worry about the ranges being out of date quickly.
|
|
4295
|
-
viewer[CESIUM_TIMELINE_INTERVAL_KEY] = setInterval(() => {
|
|
4296
|
-
doUpdate();
|
|
4297
|
-
}, 800);
|
|
4298
|
-
viewer[CESIUM_TIMELINE_LIVE_KEY] = true;
|
|
4299
|
-
// Initial update.
|
|
4300
|
-
doUpdate();
|
|
4301
|
-
}
|
|
4302
|
-
function stopLive(viewer) {
|
|
4303
|
-
if (!viewer) {
|
|
4304
|
-
return;
|
|
4305
|
-
}
|
|
4306
|
-
let interval = viewer[CESIUM_TIMELINE_INTERVAL_KEY];
|
|
4307
|
-
if (interval) {
|
|
4308
|
-
clearInterval(interval);
|
|
4309
|
-
viewer[CESIUM_TIMELINE_INTERVAL_KEY] = null;
|
|
4310
|
-
}
|
|
4311
|
-
viewer[CESIUM_TIMELINE_LIVE_KEY] = false;
|
|
4312
|
-
}
|
|
4313
|
-
function SetGlobeDetails(params) {
|
|
4314
|
-
let { viewer, hidden, baseColor } = params;
|
|
4315
|
-
const scene = viewer === null || viewer === void 0 ? void 0 : viewer.scene;
|
|
4316
|
-
if (!(scene === null || scene === void 0 ? void 0 : scene.globe)) {
|
|
4317
|
-
return;
|
|
4318
|
-
}
|
|
4319
|
-
if (hidden == null) {
|
|
4320
|
-
hidden = !scene.globe.show;
|
|
4321
|
-
}
|
|
4322
|
-
else {
|
|
4323
|
-
scene.globe.show = !hidden;
|
|
4324
|
-
}
|
|
4325
|
-
if (baseColor == null) {
|
|
4326
|
-
baseColor = scene.globe.baseColor;
|
|
4327
|
-
}
|
|
4328
|
-
// When globe is off, we'll also hide the stars/moon.
|
|
4329
|
-
// We also grab the globe color and apply it to the sky.
|
|
4330
|
-
if (hidden && GetModelSpace(viewer)) {
|
|
4331
|
-
scene.skyBox.show = false;
|
|
4332
|
-
scene.skyAtmosphere.show = false;
|
|
4333
|
-
scene.sun.show = false;
|
|
4334
|
-
scene.moon.show = false;
|
|
4335
|
-
scene.backgroundColor = baseColor.clone();
|
|
4336
|
-
}
|
|
4337
|
-
else {
|
|
4338
|
-
scene.skyBox.show = true;
|
|
4339
|
-
scene.skyAtmosphere.show = true;
|
|
4340
|
-
scene.sun.show = true;
|
|
4341
|
-
scene.moon.show = true;
|
|
4342
|
-
scene.backgroundColor = Cesium.Color.BLACK;
|
|
4343
|
-
}
|
|
4344
|
-
scene.globe.baseColor = baseColor;
|
|
4345
|
-
}
|
|
4346
|
-
ViewUtils.SetGlobeDetails = SetGlobeDetails;
|
|
4347
|
-
function SetModelSpace(viewer, modelSpace) {
|
|
4348
|
-
if (!viewer) {
|
|
4349
|
-
return;
|
|
4350
4582
|
}
|
|
4351
|
-
|
|
4352
|
-
return;
|
|
4353
|
-
}
|
|
4354
|
-
viewer[CESIUM_MODEL_SPACE_KEY] = modelSpace;
|
|
4355
|
-
// Reload globe since we display it differently between the two modes.
|
|
4356
|
-
SetGlobeDetails({ viewer });
|
|
4583
|
+
return rendered;
|
|
4357
4584
|
}
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4585
|
+
RelationRenderEngine.Render = Render;
|
|
4586
|
+
let Parabola;
|
|
4587
|
+
(function (Parabola) {
|
|
4588
|
+
async function Render(params) {
|
|
4589
|
+
var _a;
|
|
4590
|
+
const style = (_a = params.style) === null || _a === void 0 ? void 0 : _a.Settings;
|
|
4591
|
+
const entity = params.dataEntity;
|
|
4592
|
+
const bColor = (style === null || style === void 0 ? void 0 : style.lineColor) ? BModels.Calculator.GetColor(style === null || style === void 0 ? void 0 : style.lineColor, entity, []) : null;
|
|
4593
|
+
const cColor = bColor ? colorToCColor(bColor) : Cesium.Color.WHITE;
|
|
4594
|
+
let width = EnsureNumber((style === null || style === void 0 ? void 0 : style.lineWidth) ? BModels.Calculator.GetNumber(style === null || style === void 0 ? void 0 : style.lineWidth, entity, []) : 4, 4);
|
|
4595
|
+
if (width < 1) {
|
|
4596
|
+
width = 1;
|
|
4597
|
+
}
|
|
4598
|
+
const duration = EnsureNumber((style === null || style === void 0 ? void 0 : style.duration) ? BModels.Calculator.GetNumber(style === null || style === void 0 ? void 0 : style.duration, entity, []) : 2, 2);
|
|
4599
|
+
const hDistanceRatio = EnsureNumber((style === null || style === void 0 ? void 0 : style.heightDistanceRatio) ? BModels.Calculator.GetNumber(style === null || style === void 0 ? void 0 : style.heightDistanceRatio, entity, []) : 0.25, 0.25);
|
|
4600
|
+
let fromPos = null;
|
|
4601
|
+
let toPos = null;
|
|
4602
|
+
let updatingPosses = false;
|
|
4603
|
+
const updatePosses = async () => {
|
|
4604
|
+
if (updatingPosses) {
|
|
4605
|
+
return;
|
|
4606
|
+
}
|
|
4607
|
+
updatingPosses = true;
|
|
4608
|
+
try {
|
|
4609
|
+
const fromData = await exports.EntityUtils.GetLocation({
|
|
4610
|
+
samples: [{
|
|
4611
|
+
entity: params.fromEntity,
|
|
4612
|
+
entityId: params.fromEntity.Bruce.ID,
|
|
4613
|
+
heightRef: Cesium.HeightReference.CLAMP_TO_GROUND,
|
|
4614
|
+
returnHeightRef: Cesium.HeightReference.NONE
|
|
4615
|
+
}],
|
|
4616
|
+
viewer: params.viewer,
|
|
4617
|
+
visualRegister: params.visualRegister,
|
|
4618
|
+
api: params.apiGetter.getApi()
|
|
4619
|
+
});
|
|
4620
|
+
fromPos = fromData.pos3d;
|
|
4621
|
+
const toData = await exports.EntityUtils.GetLocation({
|
|
4622
|
+
samples: [{
|
|
4623
|
+
entity: params.toEntity,
|
|
4624
|
+
entityId: params.toEntity.Bruce.ID,
|
|
4625
|
+
heightRef: Cesium.HeightReference.CLAMP_TO_GROUND,
|
|
4626
|
+
returnHeightRef: Cesium.HeightReference.NONE
|
|
4627
|
+
}],
|
|
4628
|
+
viewer: params.viewer,
|
|
4629
|
+
visualRegister: params.visualRegister,
|
|
4630
|
+
api: params.apiGetter.getApi()
|
|
4631
|
+
});
|
|
4632
|
+
toPos = toData.pos3d;
|
|
4633
|
+
}
|
|
4634
|
+
catch (e) {
|
|
4635
|
+
console.error(e);
|
|
4636
|
+
}
|
|
4637
|
+
updatingPosses = false;
|
|
4638
|
+
};
|
|
4639
|
+
updatePosses();
|
|
4640
|
+
const parabola = new CesiumParabola({
|
|
4641
|
+
viewer: params.viewer,
|
|
4642
|
+
pos1: () => fromPos,
|
|
4643
|
+
pos2: () => toPos,
|
|
4644
|
+
color: cColor.toCssColorString(),
|
|
4645
|
+
width: width,
|
|
4646
|
+
duration: duration,
|
|
4647
|
+
heightDistanceRatio: hDistanceRatio
|
|
4648
|
+
});
|
|
4649
|
+
parabola.Hidden = true;
|
|
4650
|
+
const cEntities = parabola.Animate();
|
|
4651
|
+
const cEntity = cEntities.parabola;
|
|
4652
|
+
cEntity._siblingGraphics = [];
|
|
4653
|
+
for (let i = 0; i < cEntities.siblings.length; i++) {
|
|
4654
|
+
const sibling = cEntities.siblings[i];
|
|
4655
|
+
cEntity._siblingGraphics.push(sibling);
|
|
4656
|
+
}
|
|
4657
|
+
let updateInterval = setInterval(() => {
|
|
4658
|
+
var _a;
|
|
4659
|
+
if (!((_a = params.viewer) === null || _a === void 0 ? void 0 : _a.scene) ||
|
|
4660
|
+
params.viewer.isDestroyed() ||
|
|
4661
|
+
(!parabola || parabola.Disposed)) {
|
|
4662
|
+
clearInterval(updateInterval);
|
|
4663
|
+
parabola.Dispose();
|
|
4664
|
+
return;
|
|
4665
|
+
}
|
|
4666
|
+
if (parabola) {
|
|
4667
|
+
const visible = cEntity && cEntity.show != false && params.viewer.entities.contains(cEntity);
|
|
4668
|
+
parabola.Hidden = !visible;
|
|
4669
|
+
}
|
|
4670
|
+
updatePosses();
|
|
4671
|
+
params.viewer.scene.requestRender();
|
|
4672
|
+
}, 1000);
|
|
4673
|
+
let disposed = false;
|
|
4674
|
+
cEntity._dispose = () => {
|
|
4675
|
+
if (disposed) {
|
|
4676
|
+
return;
|
|
4677
|
+
}
|
|
4678
|
+
disposed = true;
|
|
4679
|
+
clearInterval(updateInterval);
|
|
4680
|
+
if (parabola) {
|
|
4681
|
+
parabola.Dispose();
|
|
4682
|
+
}
|
|
4683
|
+
};
|
|
4684
|
+
return cEntity;
|
|
4362
4685
|
}
|
|
4363
|
-
|
|
4364
|
-
}
|
|
4365
|
-
|
|
4366
|
-
})(exports.ViewUtils || (exports.ViewUtils = {}));
|
|
4686
|
+
Parabola.Render = Render;
|
|
4687
|
+
})(Parabola = RelationRenderEngine.Parabola || (RelationRenderEngine.Parabola = {}));
|
|
4688
|
+
})(RelationRenderEngine || (RelationRenderEngine = {}));
|
|
4367
4689
|
|
|
4368
4690
|
const MODEL_MIN_RADIUS = 10;
|
|
4369
4691
|
const POINT_MIN_RADIUS = 15;
|
|
@@ -7023,6 +7345,116 @@
|
|
|
7023
7345
|
VisualsRegister.Register = Register;
|
|
7024
7346
|
})(exports.VisualsRegister || (exports.VisualsRegister = {}));
|
|
7025
7347
|
|
|
7348
|
+
/**
|
|
7349
|
+
* Tracks per-entity rerender state for unsaved blob maintenance and stale API response suppression.
|
|
7350
|
+
*/
|
|
7351
|
+
class EntityReRenderMaintainState {
|
|
7352
|
+
constructor() {
|
|
7353
|
+
this.maintainedEntitiesById = {};
|
|
7354
|
+
this.apiRevisionByEntityId = {};
|
|
7355
|
+
this.skipApiRunByEntityId = {};
|
|
7356
|
+
this.checkRunId = 0;
|
|
7357
|
+
}
|
|
7358
|
+
setMaintainedEntities(entities) {
|
|
7359
|
+
var _a;
|
|
7360
|
+
for (let i = 0; i < entities.length; i++) {
|
|
7361
|
+
const entity = entities[i];
|
|
7362
|
+
const id = (_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID;
|
|
7363
|
+
if (!id) {
|
|
7364
|
+
continue;
|
|
7365
|
+
}
|
|
7366
|
+
this.maintainedEntitiesById[id] = entity;
|
|
7367
|
+
}
|
|
7368
|
+
}
|
|
7369
|
+
clearMaintainedEntities(entityIds) {
|
|
7370
|
+
for (let i = 0; i < entityIds.length; i++) {
|
|
7371
|
+
const id = entityIds[i];
|
|
7372
|
+
if (!id) {
|
|
7373
|
+
continue;
|
|
7374
|
+
}
|
|
7375
|
+
delete this.maintainedEntitiesById[id];
|
|
7376
|
+
}
|
|
7377
|
+
}
|
|
7378
|
+
getMaintainedEntities(entityIds) {
|
|
7379
|
+
const entities = [];
|
|
7380
|
+
for (let i = 0; i < entityIds.length; i++) {
|
|
7381
|
+
const id = entityIds[i];
|
|
7382
|
+
if (!id) {
|
|
7383
|
+
continue;
|
|
7384
|
+
}
|
|
7385
|
+
const entity = this.maintainedEntitiesById[id];
|
|
7386
|
+
if (entity) {
|
|
7387
|
+
entities.push(entity);
|
|
7388
|
+
}
|
|
7389
|
+
}
|
|
7390
|
+
return entities;
|
|
7391
|
+
}
|
|
7392
|
+
bumpApiRevisions(entityIds) {
|
|
7393
|
+
var _a;
|
|
7394
|
+
for (let i = 0; i < entityIds.length; i++) {
|
|
7395
|
+
const id = entityIds[i];
|
|
7396
|
+
if (!id) {
|
|
7397
|
+
continue;
|
|
7398
|
+
}
|
|
7399
|
+
this.apiRevisionByEntityId[id] = ((_a = this.apiRevisionByEntityId[id]) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
7400
|
+
}
|
|
7401
|
+
}
|
|
7402
|
+
captureApiRevisions(entityIds) {
|
|
7403
|
+
var _a;
|
|
7404
|
+
const revisions = {};
|
|
7405
|
+
for (let i = 0; i < entityIds.length; i++) {
|
|
7406
|
+
const id = entityIds[i];
|
|
7407
|
+
if (!id) {
|
|
7408
|
+
continue;
|
|
7409
|
+
}
|
|
7410
|
+
revisions[id] = (_a = this.apiRevisionByEntityId[id]) !== null && _a !== void 0 ? _a : 0;
|
|
7411
|
+
}
|
|
7412
|
+
return revisions;
|
|
7413
|
+
}
|
|
7414
|
+
startCheckRun() {
|
|
7415
|
+
this.checkRunId += 1;
|
|
7416
|
+
return this.checkRunId;
|
|
7417
|
+
}
|
|
7418
|
+
getCurrentCheckRun() {
|
|
7419
|
+
return this.checkRunId;
|
|
7420
|
+
}
|
|
7421
|
+
markSkipForCurrentRun(entityIds, isRunningCheck) {
|
|
7422
|
+
if (!isRunningCheck) {
|
|
7423
|
+
return;
|
|
7424
|
+
}
|
|
7425
|
+
const runId = this.checkRunId;
|
|
7426
|
+
for (let i = 0; i < entityIds.length; i++) {
|
|
7427
|
+
const id = entityIds[i];
|
|
7428
|
+
if (!id) {
|
|
7429
|
+
continue;
|
|
7430
|
+
}
|
|
7431
|
+
this.skipApiRunByEntityId[id] = runId;
|
|
7432
|
+
}
|
|
7433
|
+
}
|
|
7434
|
+
shouldSkipInRun(entityId, runId) {
|
|
7435
|
+
return this.skipApiRunByEntityId[entityId] === runId;
|
|
7436
|
+
}
|
|
7437
|
+
filterNonSkippedIds(entityIds, runId) {
|
|
7438
|
+
return entityIds.filter((id) => {
|
|
7439
|
+
return id && !this.shouldSkipInRun(id, runId);
|
|
7440
|
+
});
|
|
7441
|
+
}
|
|
7442
|
+
filterCurrentApiEntities(params) {
|
|
7443
|
+
const { entities, revisions, runId } = params;
|
|
7444
|
+
return entities.filter((entity) => {
|
|
7445
|
+
var _a, _b, _c;
|
|
7446
|
+
const id = (_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID;
|
|
7447
|
+
if (!id) {
|
|
7448
|
+
return false;
|
|
7449
|
+
}
|
|
7450
|
+
if (runId != null && this.shouldSkipInRun(id, runId)) {
|
|
7451
|
+
return false;
|
|
7452
|
+
}
|
|
7453
|
+
return ((_b = this.apiRevisionByEntityId[id]) !== null && _b !== void 0 ? _b : 0) === ((_c = revisions[id]) !== null && _c !== void 0 ? _c : 0);
|
|
7454
|
+
});
|
|
7455
|
+
}
|
|
7456
|
+
}
|
|
7457
|
+
|
|
7026
7458
|
function GetValue(viewer, obj) {
|
|
7027
7459
|
if (obj === null || obj === void 0 ? void 0 : obj.getValue) {
|
|
7028
7460
|
let date = viewer.scene.lastRenderTime;
|
|
@@ -7842,438 +8274,6 @@
|
|
|
7842
8274
|
}
|
|
7843
8275
|
}
|
|
7844
8276
|
|
|
7845
|
-
/**
|
|
7846
|
-
* Tracks per-entity rerender state for unsaved blob maintenance and stale API response suppression.
|
|
7847
|
-
*/
|
|
7848
|
-
class EntityReRenderMaintainState {
|
|
7849
|
-
constructor() {
|
|
7850
|
-
this.maintainedEntitiesById = {};
|
|
7851
|
-
this.apiRevisionByEntityId = {};
|
|
7852
|
-
this.skipApiRunByEntityId = {};
|
|
7853
|
-
this.checkRunId = 0;
|
|
7854
|
-
}
|
|
7855
|
-
setMaintainedEntities(entities) {
|
|
7856
|
-
var _a;
|
|
7857
|
-
for (let i = 0; i < entities.length; i++) {
|
|
7858
|
-
const entity = entities[i];
|
|
7859
|
-
const id = (_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID;
|
|
7860
|
-
if (!id) {
|
|
7861
|
-
continue;
|
|
7862
|
-
}
|
|
7863
|
-
this.maintainedEntitiesById[id] = entity;
|
|
7864
|
-
}
|
|
7865
|
-
}
|
|
7866
|
-
clearMaintainedEntities(entityIds) {
|
|
7867
|
-
for (let i = 0; i < entityIds.length; i++) {
|
|
7868
|
-
const id = entityIds[i];
|
|
7869
|
-
if (!id) {
|
|
7870
|
-
continue;
|
|
7871
|
-
}
|
|
7872
|
-
delete this.maintainedEntitiesById[id];
|
|
7873
|
-
}
|
|
7874
|
-
}
|
|
7875
|
-
getMaintainedEntities(entityIds) {
|
|
7876
|
-
const entities = [];
|
|
7877
|
-
for (let i = 0; i < entityIds.length; i++) {
|
|
7878
|
-
const id = entityIds[i];
|
|
7879
|
-
if (!id) {
|
|
7880
|
-
continue;
|
|
7881
|
-
}
|
|
7882
|
-
const entity = this.maintainedEntitiesById[id];
|
|
7883
|
-
if (entity) {
|
|
7884
|
-
entities.push(entity);
|
|
7885
|
-
}
|
|
7886
|
-
}
|
|
7887
|
-
return entities;
|
|
7888
|
-
}
|
|
7889
|
-
bumpApiRevisions(entityIds) {
|
|
7890
|
-
var _a;
|
|
7891
|
-
for (let i = 0; i < entityIds.length; i++) {
|
|
7892
|
-
const id = entityIds[i];
|
|
7893
|
-
if (!id) {
|
|
7894
|
-
continue;
|
|
7895
|
-
}
|
|
7896
|
-
this.apiRevisionByEntityId[id] = ((_a = this.apiRevisionByEntityId[id]) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
7897
|
-
}
|
|
7898
|
-
}
|
|
7899
|
-
captureApiRevisions(entityIds) {
|
|
7900
|
-
var _a;
|
|
7901
|
-
const revisions = {};
|
|
7902
|
-
for (let i = 0; i < entityIds.length; i++) {
|
|
7903
|
-
const id = entityIds[i];
|
|
7904
|
-
if (!id) {
|
|
7905
|
-
continue;
|
|
7906
|
-
}
|
|
7907
|
-
revisions[id] = (_a = this.apiRevisionByEntityId[id]) !== null && _a !== void 0 ? _a : 0;
|
|
7908
|
-
}
|
|
7909
|
-
return revisions;
|
|
7910
|
-
}
|
|
7911
|
-
startCheckRun() {
|
|
7912
|
-
this.checkRunId += 1;
|
|
7913
|
-
return this.checkRunId;
|
|
7914
|
-
}
|
|
7915
|
-
getCurrentCheckRun() {
|
|
7916
|
-
return this.checkRunId;
|
|
7917
|
-
}
|
|
7918
|
-
markSkipForCurrentRun(entityIds, isRunningCheck) {
|
|
7919
|
-
if (!isRunningCheck) {
|
|
7920
|
-
return;
|
|
7921
|
-
}
|
|
7922
|
-
const runId = this.checkRunId;
|
|
7923
|
-
for (let i = 0; i < entityIds.length; i++) {
|
|
7924
|
-
const id = entityIds[i];
|
|
7925
|
-
if (!id) {
|
|
7926
|
-
continue;
|
|
7927
|
-
}
|
|
7928
|
-
this.skipApiRunByEntityId[id] = runId;
|
|
7929
|
-
}
|
|
7930
|
-
}
|
|
7931
|
-
shouldSkipInRun(entityId, runId) {
|
|
7932
|
-
return this.skipApiRunByEntityId[entityId] === runId;
|
|
7933
|
-
}
|
|
7934
|
-
filterNonSkippedIds(entityIds, runId) {
|
|
7935
|
-
return entityIds.filter((id) => {
|
|
7936
|
-
return id && !this.shouldSkipInRun(id, runId);
|
|
7937
|
-
});
|
|
7938
|
-
}
|
|
7939
|
-
filterCurrentApiEntities(params) {
|
|
7940
|
-
const { entities, revisions, runId } = params;
|
|
7941
|
-
return entities.filter((entity) => {
|
|
7942
|
-
var _a, _b, _c;
|
|
7943
|
-
const id = (_a = entity === null || entity === void 0 ? void 0 : entity.Bruce) === null || _a === void 0 ? void 0 : _a.ID;
|
|
7944
|
-
if (!id) {
|
|
7945
|
-
return false;
|
|
7946
|
-
}
|
|
7947
|
-
if (runId != null && this.shouldSkipInRun(id, runId)) {
|
|
7948
|
-
return false;
|
|
7949
|
-
}
|
|
7950
|
-
return ((_b = this.apiRevisionByEntityId[id]) !== null && _b !== void 0 ? _b : 0) === ((_c = revisions[id]) !== null && _c !== void 0 ? _c : 0);
|
|
7951
|
-
});
|
|
7952
|
-
}
|
|
7953
|
-
}
|
|
7954
|
-
|
|
7955
|
-
function isTurfAvailable() {
|
|
7956
|
-
return window && window.turf != null;
|
|
7957
|
-
}
|
|
7958
|
-
/**
|
|
7959
|
-
* Util for simplifying geometry on the fly.
|
|
7960
|
-
*/
|
|
7961
|
-
var SimplifyGeometry;
|
|
7962
|
-
(function (SimplifyGeometry) {
|
|
7963
|
-
/**
|
|
7964
|
-
* Returns the total number of points in the geometry.
|
|
7965
|
-
* @param geometry
|
|
7966
|
-
* @param limit number to count up to before returning.
|
|
7967
|
-
* @returns
|
|
7968
|
-
*/
|
|
7969
|
-
function CountPoints(geometry, limit) {
|
|
7970
|
-
let count = 0;
|
|
7971
|
-
const traverse = (geometry) => {
|
|
7972
|
-
if (geometry.MultiGeometry) {
|
|
7973
|
-
for (let i = 0; i < geometry.MultiGeometry.length; i++) {
|
|
7974
|
-
traverse(geometry.MultiGeometry[i]);
|
|
7975
|
-
// Reached the limit, return.
|
|
7976
|
-
if (limit && count >= limit) {
|
|
7977
|
-
return;
|
|
7978
|
-
}
|
|
7979
|
-
}
|
|
7980
|
-
}
|
|
7981
|
-
else if (geometry.Polygon) {
|
|
7982
|
-
for (let i = 0; i < geometry.Polygon.length; i++) {
|
|
7983
|
-
const polygon = geometry.Polygon[i];
|
|
7984
|
-
count += BModels.Geometry.ParsePoints(polygon.LinearRing).length;
|
|
7985
|
-
}
|
|
7986
|
-
}
|
|
7987
|
-
else if (geometry.LineString) {
|
|
7988
|
-
count += BModels.Geometry.ParsePoints(geometry.LineString).length;
|
|
7989
|
-
}
|
|
7990
|
-
else if (geometry.Point) {
|
|
7991
|
-
count += 1;
|
|
7992
|
-
}
|
|
7993
|
-
};
|
|
7994
|
-
traverse(geometry);
|
|
7995
|
-
return count;
|
|
7996
|
-
}
|
|
7997
|
-
SimplifyGeometry.CountPoints = CountPoints;
|
|
7998
|
-
/**
|
|
7999
|
-
* Simplifies input geometry.
|
|
8000
|
-
* This will turn it into GeoJSON, run it through turf, then back to Bruce geometry.
|
|
8001
|
-
* @param geometry
|
|
8002
|
-
*/
|
|
8003
|
-
function Simplify(entityId, geometry, tolerance) {
|
|
8004
|
-
var _a;
|
|
8005
|
-
if (!geometry || !isTurfAvailable() || !turf.simplify) {
|
|
8006
|
-
return geometry;
|
|
8007
|
-
}
|
|
8008
|
-
// Convert to geojson so that we can interact with turf.
|
|
8009
|
-
const gFeature = BModels.Geometry.ToGeoJsonFeature({
|
|
8010
|
-
geometry: geometry
|
|
8011
|
-
});
|
|
8012
|
-
// Unkink the geometry.
|
|
8013
|
-
// This removes overlapping polygons before we start merging and simplifying.
|
|
8014
|
-
// Commented out because it has crashes and doesn't handle holes.
|
|
8015
|
-
untangleFeature(gFeature);
|
|
8016
|
-
// Union the geometry.
|
|
8017
|
-
// This merges overlapping polygons.
|
|
8018
|
-
unionFeature(gFeature);
|
|
8019
|
-
// Simplify the geometry.
|
|
8020
|
-
if (tolerance > 0) {
|
|
8021
|
-
gFeature.geometry = turf.simplify(gFeature.geometry, {
|
|
8022
|
-
tolerance: tolerance,
|
|
8023
|
-
highQuality: true,
|
|
8024
|
-
mutate: true
|
|
8025
|
-
});
|
|
8026
|
-
}
|
|
8027
|
-
// Converting back to Bruce geometry.
|
|
8028
|
-
geometry = (_a = BModels.Geometry.FromGeoJson({
|
|
8029
|
-
geoJson: gFeature
|
|
8030
|
-
})) === null || _a === void 0 ? void 0 : _a.geometry;
|
|
8031
|
-
return geometry;
|
|
8032
|
-
}
|
|
8033
|
-
SimplifyGeometry.Simplify = Simplify;
|
|
8034
|
-
})(SimplifyGeometry || (SimplifyGeometry = {}));
|
|
8035
|
-
/**
|
|
8036
|
-
* Runs through all found polygons and runs unkink through turf on them.
|
|
8037
|
-
* @param feature
|
|
8038
|
-
*/
|
|
8039
|
-
function untangleFeature(feature) {
|
|
8040
|
-
// Collection to add to because the result might be multiple from an unkink.
|
|
8041
|
-
const collection = {
|
|
8042
|
-
geometries: [],
|
|
8043
|
-
type: "GeometryCollection"
|
|
8044
|
-
};
|
|
8045
|
-
// Runs a dedupe and unkink on the coordinates.
|
|
8046
|
-
// Returns if the coordinates were added to the collection.
|
|
8047
|
-
const processCoordinates = (coords) => {
|
|
8048
|
-
try {
|
|
8049
|
-
// Dedupe the coordinates to avoid issues with unkink.
|
|
8050
|
-
coords = dedupeCoordinates(coords);
|
|
8051
|
-
const outer = [];
|
|
8052
|
-
let inner = [];
|
|
8053
|
-
// We'll unkink each ring separately as this is killing the holes when it is done as a whole.
|
|
8054
|
-
// So we'll do it separate then recombine.
|
|
8055
|
-
for (let i = 0; i < coords.length; i++) {
|
|
8056
|
-
const ring = coords[i];
|
|
8057
|
-
const unkink = turf.unkinkPolygon({
|
|
8058
|
-
type: "Polygon",
|
|
8059
|
-
coordinates: [ring]
|
|
8060
|
-
});
|
|
8061
|
-
if (unkink.type == "FeatureCollection") {
|
|
8062
|
-
let target = i == 0 ? outer : inner;
|
|
8063
|
-
for (let j = 0; j < unkink.features.length; j++) {
|
|
8064
|
-
const unkinked = unkink.features[j].geometry.coordinates;
|
|
8065
|
-
if (unkinked.length > 0) {
|
|
8066
|
-
target.push(unkinked[0]);
|
|
8067
|
-
}
|
|
8068
|
-
}
|
|
8069
|
-
}
|
|
8070
|
-
else {
|
|
8071
|
-
console.error("Unexpected unkink result.", unkink);
|
|
8072
|
-
}
|
|
8073
|
-
}
|
|
8074
|
-
// Recreate the rings and reapply to the collection.
|
|
8075
|
-
if (outer.length > 0) {
|
|
8076
|
-
const combinedCoords = [outer[0]];
|
|
8077
|
-
for (let i = 0; i < inner.length; i++) {
|
|
8078
|
-
combinedCoords.push(inner[i]);
|
|
8079
|
-
}
|
|
8080
|
-
// Add the combined coordinates to the collection
|
|
8081
|
-
const polygon = {
|
|
8082
|
-
type: "Polygon",
|
|
8083
|
-
coordinates: combinedCoords
|
|
8084
|
-
};
|
|
8085
|
-
// Ensure right-hand rule is followed.
|
|
8086
|
-
ensureRightHandRule(polygon);
|
|
8087
|
-
// Add to the collection.
|
|
8088
|
-
collection.geometries.push(polygon);
|
|
8089
|
-
return true;
|
|
8090
|
-
}
|
|
8091
|
-
}
|
|
8092
|
-
catch (e) {
|
|
8093
|
-
// console.error("Failed to unkink polygon.", e);
|
|
8094
|
-
}
|
|
8095
|
-
return false;
|
|
8096
|
-
};
|
|
8097
|
-
const processGeometry = (geometry) => {
|
|
8098
|
-
let added = false;
|
|
8099
|
-
if (geometry.type == "Polygon") {
|
|
8100
|
-
added = processCoordinates(geometry.coordinates);
|
|
8101
|
-
}
|
|
8102
|
-
else if (geometry.type == "MultiPolygon") {
|
|
8103
|
-
for (let i = 0; i < geometry.coordinates.length; i++) {
|
|
8104
|
-
added = processCoordinates(geometry.coordinates[i]) || added;
|
|
8105
|
-
}
|
|
8106
|
-
}
|
|
8107
|
-
if (!added) {
|
|
8108
|
-
// Adding original since we can't unkink it.
|
|
8109
|
-
collection.geometries.push(geometry);
|
|
8110
|
-
}
|
|
8111
|
-
};
|
|
8112
|
-
if (feature.geometry.type == "GeometryCollection") {
|
|
8113
|
-
feature.geometry.geometries.forEach((geometry) => {
|
|
8114
|
-
processGeometry(geometry);
|
|
8115
|
-
});
|
|
8116
|
-
}
|
|
8117
|
-
else {
|
|
8118
|
-
processGeometry(feature.geometry);
|
|
8119
|
-
}
|
|
8120
|
-
// Re-assign the geometry.
|
|
8121
|
-
if (collection.geometries.length == 1) {
|
|
8122
|
-
feature.geometry = collection.geometries[0];
|
|
8123
|
-
}
|
|
8124
|
-
else {
|
|
8125
|
-
feature.geometry = collection;
|
|
8126
|
-
}
|
|
8127
|
-
}
|
|
8128
|
-
/**
|
|
8129
|
-
* Runs through all found polygons and unions them using turf.
|
|
8130
|
-
* Failed unions are ignored and the original is kept.
|
|
8131
|
-
* @param feature
|
|
8132
|
-
*/
|
|
8133
|
-
function unionFeature(feature) {
|
|
8134
|
-
// Collection to add to because the result might be multiple from an unkink.
|
|
8135
|
-
const collection = {
|
|
8136
|
-
geometries: [],
|
|
8137
|
-
type: "GeometryCollection"
|
|
8138
|
-
};
|
|
8139
|
-
// We'll turn each geometry into a feature and union them.
|
|
8140
|
-
const tmpCollection = {
|
|
8141
|
-
features: [],
|
|
8142
|
-
type: "FeatureCollection"
|
|
8143
|
-
};
|
|
8144
|
-
if (feature.geometry.type == "GeometryCollection") {
|
|
8145
|
-
feature.geometry.geometries.forEach((geometry) => {
|
|
8146
|
-
if (geometry.type == "Polygon") {
|
|
8147
|
-
tmpCollection.features.push({
|
|
8148
|
-
type: "Feature",
|
|
8149
|
-
geometry: geometry,
|
|
8150
|
-
properties: {}
|
|
8151
|
-
});
|
|
8152
|
-
}
|
|
8153
|
-
else if (geometry.type == "MultiPolygon") {
|
|
8154
|
-
for (let i = 0; i < geometry.coordinates.length; i++) {
|
|
8155
|
-
tmpCollection.features.push({
|
|
8156
|
-
type: "Feature",
|
|
8157
|
-
geometry: {
|
|
8158
|
-
type: "Polygon",
|
|
8159
|
-
coordinates: geometry.coordinates[i]
|
|
8160
|
-
},
|
|
8161
|
-
properties: {}
|
|
8162
|
-
});
|
|
8163
|
-
}
|
|
8164
|
-
}
|
|
8165
|
-
// Only focusing on polygons.
|
|
8166
|
-
else {
|
|
8167
|
-
collection.geometries.push(geometry);
|
|
8168
|
-
}
|
|
8169
|
-
});
|
|
8170
|
-
}
|
|
8171
|
-
else if (feature.geometry.type == "Polygon") {
|
|
8172
|
-
tmpCollection.features.push({
|
|
8173
|
-
type: "Feature",
|
|
8174
|
-
geometry: feature.geometry,
|
|
8175
|
-
properties: {}
|
|
8176
|
-
});
|
|
8177
|
-
}
|
|
8178
|
-
else if (feature.geometry.type == "MultiPolygon") {
|
|
8179
|
-
for (let i = 0; i < feature.geometry.coordinates.length; i++) {
|
|
8180
|
-
tmpCollection.features.push({
|
|
8181
|
-
type: "Feature",
|
|
8182
|
-
geometry: {
|
|
8183
|
-
type: "Polygon",
|
|
8184
|
-
coordinates: feature.geometry.coordinates[i]
|
|
8185
|
-
},
|
|
8186
|
-
properties: {}
|
|
8187
|
-
});
|
|
8188
|
-
}
|
|
8189
|
-
}
|
|
8190
|
-
// No polygons to union.
|
|
8191
|
-
// Need at least 2 to union.
|
|
8192
|
-
if (tmpCollection.features.length < 2) {
|
|
8193
|
-
return;
|
|
8194
|
-
}
|
|
8195
|
-
// Now we'll union them.
|
|
8196
|
-
try {
|
|
8197
|
-
const union = turf.union(tmpCollection);
|
|
8198
|
-
if (union.geometry.type == "Polygon") {
|
|
8199
|
-
collection.geometries.push(union.geometry);
|
|
8200
|
-
}
|
|
8201
|
-
else if (union.geometry.type == "MultiPolygon") {
|
|
8202
|
-
for (let i = 0; i < union.geometry.coordinates.length; i++) {
|
|
8203
|
-
collection.geometries.push({
|
|
8204
|
-
type: "Polygon",
|
|
8205
|
-
coordinates: union.geometry.coordinates[i]
|
|
8206
|
-
});
|
|
8207
|
-
}
|
|
8208
|
-
}
|
|
8209
|
-
else {
|
|
8210
|
-
// Returning early because the result is unexpected.
|
|
8211
|
-
return;
|
|
8212
|
-
}
|
|
8213
|
-
}
|
|
8214
|
-
catch (e) {
|
|
8215
|
-
// console.error("Failed to union polygons.", e);
|
|
8216
|
-
return;
|
|
8217
|
-
}
|
|
8218
|
-
// Re-assign the geometry.
|
|
8219
|
-
if (collection.geometries.length == 1) {
|
|
8220
|
-
feature.geometry = collection.geometries[0];
|
|
8221
|
-
}
|
|
8222
|
-
else {
|
|
8223
|
-
feature.geometry = collection;
|
|
8224
|
-
}
|
|
8225
|
-
}
|
|
8226
|
-
function dedupeCoordinates(inputCoords) {
|
|
8227
|
-
return inputCoords.map(ring => {
|
|
8228
|
-
if (ring.length < 2) {
|
|
8229
|
-
return ring;
|
|
8230
|
-
}
|
|
8231
|
-
const dedupeCoords = [];
|
|
8232
|
-
const uniqueCoords = new Set();
|
|
8233
|
-
// Dedupe the points.
|
|
8234
|
-
ring.forEach(coord => {
|
|
8235
|
-
const key = coord.join(',');
|
|
8236
|
-
if (!uniqueCoords.has(key)) {
|
|
8237
|
-
uniqueCoords.add(key);
|
|
8238
|
-
dedupeCoords.push(coord);
|
|
8239
|
-
}
|
|
8240
|
-
});
|
|
8241
|
-
// Make sure the last point matches the first.
|
|
8242
|
-
if (dedupeCoords.length > 1) {
|
|
8243
|
-
if (dedupeCoords[0][0] != dedupeCoords[dedupeCoords.length - 1][0] ||
|
|
8244
|
-
dedupeCoords[0][1] != dedupeCoords[dedupeCoords.length - 1][1]) {
|
|
8245
|
-
dedupeCoords.push(dedupeCoords[0]);
|
|
8246
|
-
}
|
|
8247
|
-
}
|
|
8248
|
-
return dedupeCoords;
|
|
8249
|
-
});
|
|
8250
|
-
}
|
|
8251
|
-
function ensureRightHandRule(polygon) {
|
|
8252
|
-
// Ensure the outer ring follows the right-hand rule
|
|
8253
|
-
if (polygon.coordinates.length > 0) {
|
|
8254
|
-
const outerRing = polygon.coordinates[0];
|
|
8255
|
-
if (isClockwise(outerRing)) {
|
|
8256
|
-
polygon.coordinates[0] = outerRing.reverse();
|
|
8257
|
-
}
|
|
8258
|
-
}
|
|
8259
|
-
// Ensure any inner rings (holes) follow the right-hand rule
|
|
8260
|
-
for (let i = 1; i < polygon.coordinates.length; i++) {
|
|
8261
|
-
const innerRing = polygon.coordinates[i];
|
|
8262
|
-
if (!isClockwise(innerRing)) {
|
|
8263
|
-
polygon.coordinates[i] = innerRing.reverse();
|
|
8264
|
-
}
|
|
8265
|
-
}
|
|
8266
|
-
}
|
|
8267
|
-
function isClockwise(ring) {
|
|
8268
|
-
let sum = 0;
|
|
8269
|
-
for (let i = 0; i < ring.length - 1; i++) {
|
|
8270
|
-
const p1 = ring[i];
|
|
8271
|
-
const p2 = ring[i + 1];
|
|
8272
|
-
sum += (p2[0] - p1[0]) * (p2[1] + p1[1]);
|
|
8273
|
-
}
|
|
8274
|
-
return sum > 0;
|
|
8275
|
-
}
|
|
8276
|
-
|
|
8277
8277
|
const BATCH_SIZE = 500;
|
|
8278
8278
|
const CHECK_BATCH_SIZE = 250;
|
|
8279
8279
|
function getValue$2(viewer, obj) {
|
|
@@ -8313,6 +8313,16 @@
|
|
|
8313
8313
|
this.getterSub = null;
|
|
8314
8314
|
this.disposed = false;
|
|
8315
8315
|
this.renderedEntities = {};
|
|
8316
|
+
// InternalID to public Entity ID, populated when Entity blob is available.
|
|
8317
|
+
// Used to match WS entity-change events (which carry internal ID ranges) to rendered Entities.
|
|
8318
|
+
this.renderedByInternalId = new Map();
|
|
8319
|
+
// Entity ID to internal ID, reverse lookup for cleanup.
|
|
8320
|
+
this.internalByEntityId = new Map();
|
|
8321
|
+
// Cleanup function for the RecordChangeFeed subscription.
|
|
8322
|
+
this.feedSub = null;
|
|
8323
|
+
// Entity IDs waiting for a throttled re-render pass (1s rate limit).
|
|
8324
|
+
this.feedPendingUpdateIds = new Set();
|
|
8325
|
+
this.feedUpdateThrottleTimer = null;
|
|
8316
8326
|
this.entityCheckQueue = null;
|
|
8317
8327
|
this.entityCheckQueueIds = [];
|
|
8318
8328
|
this.entityCheckRemoval = null;
|
|
@@ -8477,7 +8487,7 @@
|
|
|
8477
8487
|
}
|
|
8478
8488
|
}
|
|
8479
8489
|
setGetter() {
|
|
8480
|
-
var _a, _b, _c, _d;
|
|
8490
|
+
var _a, _b, _c, _d, _e;
|
|
8481
8491
|
this.unsetGetter();
|
|
8482
8492
|
const isTagItem = Boolean(this.item.BruceEntity.ExpandLayers);
|
|
8483
8493
|
let tagsToRender = isTagItem ? this.item.BruceEntity.SelectedExpandLayers : null;
|
|
@@ -8535,15 +8545,90 @@
|
|
|
8535
8545
|
this.entityCheckQueue = new BModels.DelayQueue(() => {
|
|
8536
8546
|
this.doEntityCheck(Object.keys(this.renderedEntities));
|
|
8537
8547
|
}, shouldCheck ? 3000 : 30000);
|
|
8548
|
+
const feed = (_e = this.apiGetter.getApi()) === null || _e === void 0 ? void 0 : _e.RecordChangeFeed;
|
|
8549
|
+
if (feed) {
|
|
8550
|
+
this.feedSub = feed.Subscribe({
|
|
8551
|
+
concepts: [BModels.AccountConcept.EConcept.ENTITY],
|
|
8552
|
+
actions: ["U", "D"]
|
|
8553
|
+
}, (event) => {
|
|
8554
|
+
var _a;
|
|
8555
|
+
if (!this.renderedByInternalId.size) {
|
|
8556
|
+
return;
|
|
8557
|
+
}
|
|
8558
|
+
const rangeStr = typeof event.data === "string" ? event.data : "";
|
|
8559
|
+
if (!rangeStr) {
|
|
8560
|
+
return;
|
|
8561
|
+
}
|
|
8562
|
+
const affectedIds = [];
|
|
8563
|
+
for (const [internalId, entityId] of this.renderedByInternalId) {
|
|
8564
|
+
if (BModels.RecordChangeFeed.isEntityInternalIdInRangeString(rangeStr, internalId)) {
|
|
8565
|
+
affectedIds.push(entityId);
|
|
8566
|
+
}
|
|
8567
|
+
}
|
|
8568
|
+
if (!affectedIds.length) {
|
|
8569
|
+
return;
|
|
8570
|
+
}
|
|
8571
|
+
// Remove regos directly.
|
|
8572
|
+
if (event.action === "D") {
|
|
8573
|
+
for (const entityId of affectedIds) {
|
|
8574
|
+
this.visualsManager.RemoveRegos({
|
|
8575
|
+
entityId,
|
|
8576
|
+
menuItemId: this.item.id,
|
|
8577
|
+
requestRender: false
|
|
8578
|
+
});
|
|
8579
|
+
delete this.renderedEntities[entityId];
|
|
8580
|
+
(_a = this.clustering) === null || _a === void 0 ? void 0 : _a.RemoveEntity(entityId, false);
|
|
8581
|
+
const knownId = this.internalByEntityId.get(entityId);
|
|
8582
|
+
if (knownId != null) {
|
|
8583
|
+
this.renderedByInternalId.delete(knownId);
|
|
8584
|
+
this.internalByEntityId.delete(entityId);
|
|
8585
|
+
}
|
|
8586
|
+
}
|
|
8587
|
+
if (this.clustering) {
|
|
8588
|
+
this.clustering.Update();
|
|
8589
|
+
}
|
|
8590
|
+
this.viewer.scene.requestRender();
|
|
8591
|
+
}
|
|
8592
|
+
// Accumulate IDs and flush at most once per second.
|
|
8593
|
+
else {
|
|
8594
|
+
for (const entityId of affectedIds) {
|
|
8595
|
+
this.feedPendingUpdateIds.add(entityId);
|
|
8596
|
+
}
|
|
8597
|
+
if (!this.feedUpdateThrottleTimer) {
|
|
8598
|
+
this.feedUpdateThrottleTimer = setTimeout(() => {
|
|
8599
|
+
this.feedUpdateThrottleTimer = null;
|
|
8600
|
+
if (this.disposed || !this.feedPendingUpdateIds.size) {
|
|
8601
|
+
return;
|
|
8602
|
+
}
|
|
8603
|
+
const ids = [...this.feedPendingUpdateIds];
|
|
8604
|
+
this.feedPendingUpdateIds.clear();
|
|
8605
|
+
this.ReRender({
|
|
8606
|
+
entityIds: ids,
|
|
8607
|
+
force: true
|
|
8608
|
+
});
|
|
8609
|
+
}, 1000);
|
|
8610
|
+
}
|
|
8611
|
+
}
|
|
8612
|
+
});
|
|
8613
|
+
}
|
|
8538
8614
|
}
|
|
8539
8615
|
unsetGetter() {
|
|
8540
|
-
var _a, _b, _c;
|
|
8616
|
+
var _a, _b, _c, _d;
|
|
8541
8617
|
(_a = this.getter) === null || _a === void 0 ? void 0 : _a.ExcludeMenuItem(this.item.id);
|
|
8542
8618
|
this.getter = null;
|
|
8543
8619
|
(_b = this.getterSub) === null || _b === void 0 ? void 0 : _b.call(this);
|
|
8544
8620
|
this.getterSub = null;
|
|
8545
8621
|
(_c = this.entityCheckQueue) === null || _c === void 0 ? void 0 : _c.Dispose();
|
|
8546
8622
|
this.entityCheckQueue = null;
|
|
8623
|
+
(_d = this.feedSub) === null || _d === void 0 ? void 0 : _d.call(this);
|
|
8624
|
+
this.feedSub = null;
|
|
8625
|
+
if (this.feedUpdateThrottleTimer) {
|
|
8626
|
+
clearTimeout(this.feedUpdateThrottleTimer);
|
|
8627
|
+
this.feedUpdateThrottleTimer = null;
|
|
8628
|
+
}
|
|
8629
|
+
this.feedPendingUpdateIds.clear();
|
|
8630
|
+
this.renderedByInternalId.clear();
|
|
8631
|
+
this.internalByEntityId.clear();
|
|
8547
8632
|
}
|
|
8548
8633
|
preventCurrentCheckApiRefresh(entityIds) {
|
|
8549
8634
|
var _a;
|
|
@@ -9096,7 +9181,7 @@
|
|
|
9096
9181
|
* @returns
|
|
9097
9182
|
*/
|
|
9098
9183
|
const register = (thing) => {
|
|
9099
|
-
var _a, _b, _c, _d, _e, _f;
|
|
9184
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
9100
9185
|
// See if the cesium entity already exists in a group.
|
|
9101
9186
|
let group = groups.find((x) => { var _a; return ((_a = x.visual) === null || _a === void 0 ? void 0 : _a.id) == thing.id || x.siblings.find(x => (x === null || x === void 0 ? void 0 : x.id) == thing.id); });
|
|
9102
9187
|
if (group) {
|
|
@@ -9140,8 +9225,14 @@
|
|
|
9140
9225
|
cdn: this.item.cdnEnabled,
|
|
9141
9226
|
collection: source.entities,
|
|
9142
9227
|
outline: (_f = (_e = group.data) === null || _e === void 0 ? void 0 : _e.Bruce) === null || _f === void 0 ? void 0 : _f.Outline,
|
|
9228
|
+
internalId: (_j = (_h = (_g = group.data) === null || _g === void 0 ? void 0 : _g.Bruce) === null || _h === void 0 ? void 0 : _h.InternalID) !== null && _j !== void 0 ? _j : undefined,
|
|
9143
9229
|
};
|
|
9144
9230
|
group.rego = rego;
|
|
9231
|
+
const groupInternalId = (_l = (_k = group.data) === null || _k === void 0 ? void 0 : _k.Bruce) === null || _l === void 0 ? void 0 : _l.InternalID;
|
|
9232
|
+
if (groupInternalId != null) {
|
|
9233
|
+
this.renderedByInternalId.set(groupInternalId, entityId);
|
|
9234
|
+
this.internalByEntityId.set(entityId, groupInternalId);
|
|
9235
|
+
}
|
|
9145
9236
|
this.visualsManager.AddRego({
|
|
9146
9237
|
rego,
|
|
9147
9238
|
requestRender: false
|
|
@@ -9185,7 +9276,7 @@
|
|
|
9185
9276
|
* @returns
|
|
9186
9277
|
*/
|
|
9187
9278
|
async renderAsIndividuals(entities, force = false) {
|
|
9188
|
-
var _a, _b, _c, _d, _e, _f;
|
|
9279
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
9189
9280
|
// When live we just want to show the latest pos.
|
|
9190
9281
|
// When not live, the user might scroll the timeline and want to see it a fluid animation between points in time.
|
|
9191
9282
|
const isLive = exports.ViewUtils.GetTimeDetails({
|
|
@@ -9239,13 +9330,25 @@
|
|
|
9239
9330
|
const id = entity.Bruce.ID;
|
|
9240
9331
|
const cEntity = cEntities.get(id);
|
|
9241
9332
|
this.renderedEntities[id] = !!cEntity;
|
|
9333
|
+
const internalId = (_c = entity.Bruce) === null || _c === void 0 ? void 0 : _c.InternalID;
|
|
9334
|
+
if (cEntity && internalId != null) {
|
|
9335
|
+
this.renderedByInternalId.set(internalId, id);
|
|
9336
|
+
this.internalByEntityId.set(id, internalId);
|
|
9337
|
+
}
|
|
9338
|
+
else if (!cEntity) {
|
|
9339
|
+
const knownInternalId = this.internalByEntityId.get(id);
|
|
9340
|
+
if (knownInternalId != null) {
|
|
9341
|
+
this.renderedByInternalId.delete(knownInternalId);
|
|
9342
|
+
this.internalByEntityId.delete(id);
|
|
9343
|
+
}
|
|
9344
|
+
}
|
|
9242
9345
|
if (cEntity) {
|
|
9243
9346
|
const rego = this.visualsManager.GetRego({
|
|
9244
9347
|
entityId: id,
|
|
9245
9348
|
menuItemId: this.item.id
|
|
9246
9349
|
});
|
|
9247
9350
|
// The baseline data source must be editable.
|
|
9248
|
-
const canEdit = !((
|
|
9351
|
+
const canEdit = !((_d = entity.Bruce.Outline) === null || _d === void 0 ? void 0 : _d.find(x => x.Baseline && !x.Editable));
|
|
9249
9352
|
const visual = rego === null || rego === void 0 ? void 0 : rego.visual;
|
|
9250
9353
|
if (!visual || visual != cEntity) {
|
|
9251
9354
|
const wasClustered = this.clustering ? this.clustering.AddEntity(id, cEntity, false) : false;
|
|
@@ -9264,7 +9367,8 @@
|
|
|
9264
9367
|
overrideShow: wasClustered ? false : null,
|
|
9265
9368
|
name: cEntity.name,
|
|
9266
9369
|
cdn: this.item.cdnEnabled,
|
|
9267
|
-
outline: entity.Bruce.Outline
|
|
9370
|
+
outline: entity.Bruce.Outline,
|
|
9371
|
+
internalId: (_f = (_e = entity.Bruce) === null || _e === void 0 ? void 0 : _e.InternalID) !== null && _f !== void 0 ? _f : undefined,
|
|
9268
9372
|
};
|
|
9269
9373
|
this.visualsManager.AddRego({
|
|
9270
9374
|
rego,
|
|
@@ -9276,10 +9380,11 @@
|
|
|
9276
9380
|
rego.visual = cEntity;
|
|
9277
9381
|
rego.entityTypeId = entity.Bruce["EntityType.ID"];
|
|
9278
9382
|
rego.tagIds = entity.Bruce["Layer.ID"] ? [].concat(entity.Bruce["Layer.ID"]) : [];
|
|
9279
|
-
rego.outline = (
|
|
9383
|
+
rego.outline = (_g = entity.Bruce) === null || _g === void 0 ? void 0 : _g.Outline;
|
|
9280
9384
|
rego.cdn = this.item.cdnEnabled;
|
|
9281
|
-
rego.schema = (
|
|
9385
|
+
rego.schema = (_h = entity.Bruce) === null || _h === void 0 ? void 0 : _h.Schema;
|
|
9282
9386
|
rego.canEdit = canEdit;
|
|
9387
|
+
rego.internalId = (_k = (_j = entity.Bruce) === null || _j === void 0 ? void 0 : _j.InternalID) !== null && _k !== void 0 ? _k : rego.internalId;
|
|
9283
9388
|
// Marked as stale meaning some change was performed that requires a refresh.
|
|
9284
9389
|
// This usually means a new sibling was added that we need to update.
|
|
9285
9390
|
if (rego.stale) {
|
|
@@ -9309,7 +9414,7 @@
|
|
|
9309
9414
|
menuItemId: this.item.id,
|
|
9310
9415
|
requestRender: false
|
|
9311
9416
|
});
|
|
9312
|
-
(
|
|
9417
|
+
(_l = this.clustering) === null || _l === void 0 ? void 0 : _l.RemoveEntity(id, false);
|
|
9313
9418
|
}
|
|
9314
9419
|
}
|
|
9315
9420
|
this.viewer.scene.requestRender();
|
|
@@ -11347,6 +11452,14 @@
|
|
|
11347
11452
|
// Entity ID -> styled status.
|
|
11348
11453
|
// Helps us emit progress events.
|
|
11349
11454
|
this.styledEntityIds = new Map();
|
|
11455
|
+
// InternalID to Entity ID for Styled Tileset Entities.
|
|
11456
|
+
// Populated when Entity data is available in styleTilesetFeatureFullData.
|
|
11457
|
+
this.styledByInternalId = new Map();
|
|
11458
|
+
// Cleanup function for the RecordChangeFeed subscription.
|
|
11459
|
+
this.feedSub = null;
|
|
11460
|
+
// Entity IDs waiting for a throttled re-style pass (1s rate limit).
|
|
11461
|
+
this.feedPendingRestyleIds = new Set();
|
|
11462
|
+
this.feedRestyleThrottleTimer = null;
|
|
11350
11463
|
// % progress for how many Entities have been styled so far.
|
|
11351
11464
|
// This can change as Tiles load in and more queue.
|
|
11352
11465
|
this._styleProgress = 0;
|
|
@@ -11366,7 +11479,7 @@
|
|
|
11366
11479
|
return this._styleProgress;
|
|
11367
11480
|
}
|
|
11368
11481
|
Init(params) {
|
|
11369
|
-
var _a;
|
|
11482
|
+
var _a, _b;
|
|
11370
11483
|
let { viewer, api, cTileset, fallbackStyleId, styleMapping, expandSources, menuItemId, register, scenario, historic } = params;
|
|
11371
11484
|
this.viewer = viewer;
|
|
11372
11485
|
this.api = api;
|
|
@@ -11422,6 +11535,37 @@
|
|
|
11422
11535
|
});
|
|
11423
11536
|
this.loaded = true;
|
|
11424
11537
|
this.loadStyles();
|
|
11538
|
+
const feed = (_b = this.api) === null || _b === void 0 ? void 0 : _b.RecordChangeFeed;
|
|
11539
|
+
if (feed) {
|
|
11540
|
+
this.feedSub = feed.Subscribe({
|
|
11541
|
+
concepts: [BModels.AccountConcept.EConcept.ENTITY],
|
|
11542
|
+
actions: ["U"]
|
|
11543
|
+
}, (event) => {
|
|
11544
|
+
if (!this.styledByInternalId.size || !this.entityGatherer) {
|
|
11545
|
+
return;
|
|
11546
|
+
}
|
|
11547
|
+
const rangeStr = typeof event.data === "string" ? event.data : "";
|
|
11548
|
+
if (!rangeStr) {
|
|
11549
|
+
return;
|
|
11550
|
+
}
|
|
11551
|
+
for (const [internalId, entityId] of this.styledByInternalId) {
|
|
11552
|
+
if (BModels.RecordChangeFeed.isEntityInternalIdInRangeString(rangeStr, internalId)) {
|
|
11553
|
+
this.feedPendingRestyleIds.add(entityId);
|
|
11554
|
+
}
|
|
11555
|
+
}
|
|
11556
|
+
if (this.feedPendingRestyleIds.size && !this.feedRestyleThrottleTimer) {
|
|
11557
|
+
this.feedRestyleThrottleTimer = setTimeout(() => {
|
|
11558
|
+
this.feedRestyleThrottleTimer = null;
|
|
11559
|
+
if (this.disposed || !this.feedPendingRestyleIds.size || !this.entityGatherer) {
|
|
11560
|
+
return;
|
|
11561
|
+
}
|
|
11562
|
+
const ids = [...this.feedPendingRestyleIds];
|
|
11563
|
+
this.feedPendingRestyleIds.clear();
|
|
11564
|
+
this.entityGatherer.Queue(ids, true);
|
|
11565
|
+
}, 1000);
|
|
11566
|
+
}
|
|
11567
|
+
});
|
|
11568
|
+
}
|
|
11425
11569
|
}
|
|
11426
11570
|
/**
|
|
11427
11571
|
* Updates style mapping and fallback style.
|
|
@@ -11574,11 +11718,19 @@
|
|
|
11574
11718
|
});
|
|
11575
11719
|
}
|
|
11576
11720
|
Dispose() {
|
|
11721
|
+
var _a;
|
|
11577
11722
|
if (this.disposed) {
|
|
11578
11723
|
return;
|
|
11579
11724
|
}
|
|
11580
11725
|
this.disposed = true;
|
|
11581
11726
|
this._styleProgressQueue.Dispose();
|
|
11727
|
+
(_a = this.feedSub) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
11728
|
+
this.feedSub = null;
|
|
11729
|
+
if (this.feedRestyleThrottleTimer) {
|
|
11730
|
+
clearTimeout(this.feedRestyleThrottleTimer);
|
|
11731
|
+
this.feedRestyleThrottleTimer = null;
|
|
11732
|
+
}
|
|
11733
|
+
this.feedPendingRestyleIds.clear();
|
|
11582
11734
|
this.disposeGatherer();
|
|
11583
11735
|
}
|
|
11584
11736
|
async loadStyles() {
|
|
@@ -11754,6 +11906,12 @@
|
|
|
11754
11906
|
}
|
|
11755
11907
|
}
|
|
11756
11908
|
disposeGatherer() {
|
|
11909
|
+
if (this.feedRestyleThrottleTimer) {
|
|
11910
|
+
clearTimeout(this.feedRestyleThrottleTimer);
|
|
11911
|
+
this.feedRestyleThrottleTimer = null;
|
|
11912
|
+
}
|
|
11913
|
+
this.feedPendingRestyleIds.clear();
|
|
11914
|
+
this.styledByInternalId.clear();
|
|
11757
11915
|
if (this.entityGatherer) {
|
|
11758
11916
|
this.entityGatherer.Dispose();
|
|
11759
11917
|
this.entityGatherer = null;
|
|
@@ -11816,7 +11974,7 @@
|
|
|
11816
11974
|
this.styleTilesetFeatureFullData(rego, null, []);
|
|
11817
11975
|
}
|
|
11818
11976
|
styleTilesetFeatureFullData(rego, data, tags) {
|
|
11819
|
-
var _a, _b;
|
|
11977
|
+
var _a, _b, _c;
|
|
11820
11978
|
const visual = rego.visual;
|
|
11821
11979
|
if (!visual || !(visual instanceof Cesium.Cesium3DTileFeature)) {
|
|
11822
11980
|
return;
|
|
@@ -11838,6 +11996,10 @@
|
|
|
11838
11996
|
override: override
|
|
11839
11997
|
});
|
|
11840
11998
|
this.overrideFeatureColor.set(rego.entityId, true);
|
|
11999
|
+
if (((_b = data === null || data === void 0 ? void 0 : data.Bruce) === null || _b === void 0 ? void 0 : _b.InternalID) != null) {
|
|
12000
|
+
rego.internalId = data.Bruce.InternalID;
|
|
12001
|
+
this.styledByInternalId.set(data.Bruce.InternalID, rego.entityId);
|
|
12002
|
+
}
|
|
11841
12003
|
this.styledEntityIds.set(rego.entityId, true);
|
|
11842
12004
|
this._styleProgressQueue.Call();
|
|
11843
12005
|
// Since we only need to update it for scenarios right now.
|
|
@@ -11846,7 +12008,7 @@
|
|
|
11846
12008
|
// Update the Entity's rego state.
|
|
11847
12009
|
let changed = false;
|
|
11848
12010
|
if (isOutlineChanged(rego, data)) {
|
|
11849
|
-
rego.outline = (
|
|
12011
|
+
rego.outline = (_c = data === null || data === void 0 ? void 0 : data.Bruce) === null || _c === void 0 ? void 0 : _c.Outline;
|
|
11850
12012
|
changed = true;
|
|
11851
12013
|
}
|
|
11852
12014
|
// Something changed, trigger a rego update.
|
|
@@ -12877,6 +13039,10 @@
|
|
|
12877
13039
|
viaCdn: false
|
|
12878
13040
|
});
|
|
12879
13041
|
}
|
|
13042
|
+
// Should not occur.
|
|
13043
|
+
if (!tileset.loadUrl && loadUrl) {
|
|
13044
|
+
tileset.loadUrl = loadUrl;
|
|
13045
|
+
}
|
|
12880
13046
|
// TODO: we shouldn't just assume we'll need it, huge assemblies are 100+ MB.
|
|
12881
13047
|
// TODO: this is a problem as we need to know what nodes are collapsed...
|
|
12882
13048
|
// In >v1 the model-tree sits in its own file.
|
|
@@ -13155,6 +13321,9 @@
|
|
|
13155
13321
|
else if (lowered === "brucepath") {
|
|
13156
13322
|
this.featurePropCache.set("brucePath", prop);
|
|
13157
13323
|
}
|
|
13324
|
+
else if (lowered === "internalid") {
|
|
13325
|
+
this.featurePropCache.set("internalId", prop);
|
|
13326
|
+
}
|
|
13158
13327
|
}
|
|
13159
13328
|
}
|
|
13160
13329
|
/**
|
|
@@ -13283,6 +13452,14 @@
|
|
|
13283
13452
|
}
|
|
13284
13453
|
}
|
|
13285
13454
|
}
|
|
13455
|
+
const internalIdProp = this.featurePropCache.get("internalId");
|
|
13456
|
+
if (internalIdProp) {
|
|
13457
|
+
const raw = feature.getProperty(internalIdProp);
|
|
13458
|
+
const parsed = raw != null ? +raw : NaN;
|
|
13459
|
+
if (Number.isInteger(parsed)) {
|
|
13460
|
+
rego.internalId = parsed;
|
|
13461
|
+
}
|
|
13462
|
+
}
|
|
13286
13463
|
this.loadedCesiumEntities[rego.entityId] = rego;
|
|
13287
13464
|
this.visualsManager.AddRego({
|
|
13288
13465
|
rego,
|
|
@@ -16485,6 +16662,9 @@
|
|
|
16485
16662
|
else if (lowered === "building_id" || lowered === "buildingid") {
|
|
16486
16663
|
this.featurePropCache.set("BuildingID", prop);
|
|
16487
16664
|
}
|
|
16665
|
+
else if (lowered === "internalid") {
|
|
16666
|
+
this.featurePropCache.set("internalId", prop);
|
|
16667
|
+
}
|
|
16488
16668
|
}
|
|
16489
16669
|
}
|
|
16490
16670
|
Dispose() {
|
|
@@ -16595,6 +16775,14 @@
|
|
|
16595
16775
|
}
|
|
16596
16776
|
}
|
|
16597
16777
|
}
|
|
16778
|
+
const internalIdProp = this.featurePropCache.get("internalId");
|
|
16779
|
+
if (internalIdProp) {
|
|
16780
|
+
const raw = feature.getProperty(internalIdProp);
|
|
16781
|
+
const parsed = raw != null ? +raw : NaN;
|
|
16782
|
+
if (Number.isInteger(parsed)) {
|
|
16783
|
+
rego.internalId = parsed;
|
|
16784
|
+
}
|
|
16785
|
+
}
|
|
16598
16786
|
this.loadedCesiumEntities[rego.entityId] = rego;
|
|
16599
16787
|
this.visualsManager.AddRego({
|
|
16600
16788
|
rego,
|
|
@@ -36071,7 +36259,7 @@
|
|
|
36071
36259
|
}
|
|
36072
36260
|
}
|
|
36073
36261
|
|
|
36074
|
-
const VERSION = "6.6.
|
|
36262
|
+
const VERSION = "6.6.6";
|
|
36075
36263
|
/**
|
|
36076
36264
|
* Updates the environment instance used by bruce-cesium to one specified.
|
|
36077
36265
|
* This can be used to ensure that the instance a parent is referencing is shared between bruce-cesium, bruce-models, and the parent app.
|