bruce-cesium 2.1.9 → 2.2.0
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 +162 -129
- package/dist/bruce-cesium.es5.js.map +1 -1
- package/dist/bruce-cesium.umd.js +161 -128
- package/dist/bruce-cesium.umd.js.map +1 -1
- package/dist/lib/bruce-cesium.js +1 -1
- package/dist/lib/rendering/render-managers/common/point-clustering.js +160 -127
- package/dist/lib/rendering/render-managers/common/point-clustering.js.map +1 -1
- package/dist/types/bruce-cesium.d.ts +1 -1
- package/dist/types/rendering/render-managers/common/point-clustering.d.ts +5 -25
- package/package.json +1 -1
package/dist/bruce-cesium.es5.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BruceEvent, Cartes, Carto, Entity as Entity$1, Geometry, Tileset, MathUtils, LRUCache, ZoomControl, Style, EntityTag, Calculator, EntityLod, EntityType, ClientFile, ObjectUtils, DelayQueue, BatchedDataGetter, EntityRelationType, EntityCoords, EntityFilterGetter, EntitySource, MenuItem, EntityRelation, ENVIRONMENT, ProjectView, ProjectViewBookmark, ProjectViewTile, ProjectViewLegacyTile, ProgramKey, Camera } from 'bruce-models';
|
|
2
2
|
import * as Cesium from 'cesium';
|
|
3
|
-
import { Cartesian2, Cartographic, CallbackProperty, Cartesian3, Color, Rectangle, Math as Math$1,
|
|
3
|
+
import { Cartesian2, Cartographic, CallbackProperty, Cartesian3, Color, Rectangle, Math as Math$1, HeightReference, DistanceDisplayCondition, NearFarScalar, Entity, HorizontalOrigin, VerticalOrigin, ClassificationType, ArcType, PolygonHierarchy, ShadowMode, PolylineGraphics, HeadingPitchRoll, Transforms, ColorBlendMode, SceneMode, Primitive, Cesium3DTileFeature, Cesium3DTileColorBlendMode, HeadingPitchRange, KmlDataSource, OrthographicFrustum, JulianDate, createOsmBuildings, Cesium3DTileStyle, createWorldTerrain, EllipsoidTerrainProvider, CesiumTerrainProvider, BingMapsImageryProvider, BingMapsStyle, MapboxImageryProvider, MapboxStyleImageryProvider, ArcGisMapServerImageryProvider, OpenStreetMapImageryProvider, GridImageryProvider, GeographicTilingScheme, ImageryLayer, UrlTemplateImageryProvider, TileMapServiceImageryProvider, IonImageryProvider, Cesium3DTileset, Matrix4, Matrix3, IonResource, CesiumInspector, ColorMaterialProperty, EasingFunction, GeometryInstance, EllipsoidGeodesic, sampleTerrainMostDetailed, PolygonPipeline } from 'cesium';
|
|
4
4
|
|
|
5
5
|
var TIME_LAG = 300;
|
|
6
6
|
var POSITION_CHECK_TIMER = 950;
|
|
@@ -2711,6 +2711,30 @@ var Quad = /** @class */ (function () {
|
|
|
2711
2711
|
this.southeast.Remove(point);
|
|
2712
2712
|
}
|
|
2713
2713
|
};
|
|
2714
|
+
Quad.prototype.GetDistanceToQuad = function (pos3d) {
|
|
2715
|
+
var minLat = this.boundary.y - this.boundary.h;
|
|
2716
|
+
var maxLat = this.boundary.y + this.boundary.h;
|
|
2717
|
+
var minLon = this.boundary.x - this.boundary.w;
|
|
2718
|
+
var maxLon = this.boundary.x + this.boundary.w;
|
|
2719
|
+
var points = [
|
|
2720
|
+
// Corners.
|
|
2721
|
+
new Cartesian3(minLon, minLat, 0),
|
|
2722
|
+
new Cartesian3(minLon, maxLat, 0),
|
|
2723
|
+
new Cartesian3(maxLon, minLat, 0),
|
|
2724
|
+
new Cartesian3(maxLon, maxLat, 0),
|
|
2725
|
+
// Center.
|
|
2726
|
+
new Cartesian3(this.boundary.x, this.boundary.y, 0)
|
|
2727
|
+
];
|
|
2728
|
+
var shortest = Number.MAX_VALUE;
|
|
2729
|
+
for (var _i = 0, points_1 = points; _i < points_1.length; _i++) {
|
|
2730
|
+
var point = points_1[_i];
|
|
2731
|
+
var distance = Cartesian3.distance(pos3d, point);
|
|
2732
|
+
if (distance < shortest) {
|
|
2733
|
+
shortest = distance;
|
|
2734
|
+
}
|
|
2735
|
+
}
|
|
2736
|
+
return shortest;
|
|
2737
|
+
};
|
|
2714
2738
|
return Quad;
|
|
2715
2739
|
}());
|
|
2716
2740
|
var _clusterImageCache = new LRUCache(500);
|
|
@@ -2733,14 +2757,15 @@ function _loadClusterImage(params) {
|
|
|
2733
2757
|
canvas.width = size;
|
|
2734
2758
|
canvas.height = size;
|
|
2735
2759
|
var ctx = canvas.getContext("2d");
|
|
2760
|
+
var WHITESPACE_PADDING_PERCENT = 0.05;
|
|
2761
|
+
var radius = (size / 2) - (size * WHITESPACE_PADDING_PERCENT);
|
|
2736
2762
|
var drawWithoutImage = function (img) {
|
|
2737
2763
|
ctx.beginPath();
|
|
2738
|
-
ctx.arc(size / 2, size / 2,
|
|
2764
|
+
ctx.arc(size / 2, size / 2, radius, 0, 2 * Math.PI, false);
|
|
2739
2765
|
var fill = null;
|
|
2740
2766
|
var txt = null;
|
|
2741
2767
|
if (img) {
|
|
2742
2768
|
var brightness = calculateImageBrightness(img);
|
|
2743
|
-
// brightness < 128 = light background.
|
|
2744
2769
|
fill = brightness < 128 ? "white" : "#114d78";
|
|
2745
2770
|
txt = brightness < 128 ? "black" : "white";
|
|
2746
2771
|
}
|
|
@@ -2750,9 +2775,9 @@ function _loadClusterImage(params) {
|
|
|
2750
2775
|
}
|
|
2751
2776
|
ctx.fillStyle = fill;
|
|
2752
2777
|
ctx.fill();
|
|
2753
|
-
var maxTextWidth = size * 0.
|
|
2754
|
-
var maxTextHeight = size * 0.
|
|
2755
|
-
var minTextSize = Math.floor(size /
|
|
2778
|
+
var maxTextWidth = size * 0.7;
|
|
2779
|
+
var maxTextHeight = size * 0.7;
|
|
2780
|
+
var minTextSize = Math.floor(size / 12);
|
|
2756
2781
|
var textSize = findOptimalFontSize(text, maxTextWidth, maxTextHeight, minTextSize);
|
|
2757
2782
|
ctx.font = "bold ".concat(textSize, "px Arial");
|
|
2758
2783
|
ctx.fillStyle = txt;
|
|
@@ -2762,14 +2787,14 @@ function _loadClusterImage(params) {
|
|
|
2762
2787
|
};
|
|
2763
2788
|
var drawWithImage = function (img) {
|
|
2764
2789
|
var aspectRatio = img.width / img.height;
|
|
2765
|
-
var imageSize = Math.min(
|
|
2766
|
-
if (imageSize / aspectRatio >
|
|
2767
|
-
imageSize =
|
|
2790
|
+
var imageSize = Math.min(radius, img.width, img.height);
|
|
2791
|
+
if (imageSize / aspectRatio > radius) {
|
|
2792
|
+
imageSize = radius * aspectRatio;
|
|
2768
2793
|
}
|
|
2769
2794
|
var imageX = (size - imageSize) / 2;
|
|
2770
2795
|
var imageY = (size - imageSize) / 2 - imageSize / 3;
|
|
2771
2796
|
ctx.beginPath();
|
|
2772
|
-
ctx.arc(size / 2, size / 2,
|
|
2797
|
+
ctx.arc(size / 2, size / 2, radius, 0, 2 * Math.PI, false);
|
|
2773
2798
|
var brightness = calculateImageBrightness(img);
|
|
2774
2799
|
var bgColor = brightness < 128 ? "white" : "#114d78";
|
|
2775
2800
|
var txtColor = brightness < 128 ? "black" : "white";
|
|
@@ -2780,7 +2805,7 @@ function _loadClusterImage(params) {
|
|
|
2780
2805
|
ctx.shadowOffsetY = 3;
|
|
2781
2806
|
ctx.shadowBlur = 5;
|
|
2782
2807
|
ctx.drawImage(img, imageX, imageY, imageSize, imageSize);
|
|
2783
|
-
var padding = imageSize /
|
|
2808
|
+
var padding = imageSize / 7;
|
|
2784
2809
|
var maxTextWidth = imageSize;
|
|
2785
2810
|
var maxTextHeight = imageSize - padding;
|
|
2786
2811
|
var minTextSize = Math.floor(imageSize / 5);
|
|
@@ -2802,7 +2827,7 @@ function _loadClusterImage(params) {
|
|
|
2802
2827
|
while (fontSize > minSize) {
|
|
2803
2828
|
tempCtx.font = "bold ".concat(fontSize, "px Arial");
|
|
2804
2829
|
var measuredWidth = tempCtx.measureText(text).width;
|
|
2805
|
-
var measuredHeight = fontSize * 1.2;
|
|
2830
|
+
var measuredHeight = fontSize * 1.2;
|
|
2806
2831
|
if (measuredWidth <= maxWidth && measuredHeight <= maxHeight) {
|
|
2807
2832
|
break;
|
|
2808
2833
|
}
|
|
@@ -2874,17 +2899,20 @@ function getClusterImage(params) {
|
|
|
2874
2899
|
}
|
|
2875
2900
|
return null;
|
|
2876
2901
|
}
|
|
2902
|
+
var FORCE_UPDATE_BATCH_SIZE = 1000;
|
|
2903
|
+
var FORCE_UPDATE_BATCH_DELAY = 100;
|
|
2877
2904
|
var PointClustering = /** @class */ (function () {
|
|
2878
2905
|
function PointClustering(register, menuItemId) {
|
|
2879
2906
|
var _this = this;
|
|
2880
2907
|
this.disposed = false;
|
|
2881
2908
|
this.registeredEntityIds = new Set();
|
|
2909
|
+
// Queue to force update entities.
|
|
2910
|
+
this.updateEntityQueue = [];
|
|
2882
2911
|
this.register = register;
|
|
2883
2912
|
this.viewer = register.Viewer;
|
|
2884
2913
|
this.menuItemId = menuItemId;
|
|
2885
|
-
this.updateClusterSpacing(0);
|
|
2886
2914
|
var boundary = new Rectangle$1(0, 0, 360, 180);
|
|
2887
|
-
this.quadTree = new Quad(boundary,
|
|
2915
|
+
this.quadTree = new Quad(boundary, 30);
|
|
2888
2916
|
this.prevClusteredEntities = new Set();
|
|
2889
2917
|
this.currClusteredEntities = new Set();
|
|
2890
2918
|
this.clusterEntities = new Map();
|
|
@@ -2893,6 +2921,39 @@ var PointClustering = /** @class */ (function () {
|
|
|
2893
2921
|
}, 1000);
|
|
2894
2922
|
this.listenCamera();
|
|
2895
2923
|
}
|
|
2924
|
+
PointClustering.prototype.queueForceUpdate = function (entityIds) {
|
|
2925
|
+
for (var i = 0; i < entityIds.length; i++) {
|
|
2926
|
+
if (this.updateEntityQueue.includes(entityIds[i])) {
|
|
2927
|
+
continue;
|
|
2928
|
+
}
|
|
2929
|
+
this.updateEntityQueue.push(entityIds[i]);
|
|
2930
|
+
}
|
|
2931
|
+
this.runForceUpdateQueue();
|
|
2932
|
+
};
|
|
2933
|
+
PointClustering.prototype.runForceUpdateQueue = function () {
|
|
2934
|
+
var _this = this;
|
|
2935
|
+
if (!this.updateEntityQueue.length) {
|
|
2936
|
+
return;
|
|
2937
|
+
}
|
|
2938
|
+
if (this.queueInterval) {
|
|
2939
|
+
return;
|
|
2940
|
+
}
|
|
2941
|
+
this.queueInterval = setInterval(function () {
|
|
2942
|
+
if (_this.disposed) {
|
|
2943
|
+
clearInterval(_this.queueInterval);
|
|
2944
|
+
_this.queueInterval = null;
|
|
2945
|
+
return;
|
|
2946
|
+
}
|
|
2947
|
+
var ids = _this.updateEntityQueue.splice(0, FORCE_UPDATE_BATCH_SIZE);
|
|
2948
|
+
_this.register.ForceUpdate({
|
|
2949
|
+
entityIds: ids
|
|
2950
|
+
});
|
|
2951
|
+
if (!_this.updateEntityQueue.length) {
|
|
2952
|
+
clearInterval(_this.queueInterval);
|
|
2953
|
+
_this.queueInterval = null;
|
|
2954
|
+
}
|
|
2955
|
+
}, FORCE_UPDATE_BATCH_DELAY);
|
|
2956
|
+
};
|
|
2896
2957
|
/**
|
|
2897
2958
|
* Starts listening to camera changes.
|
|
2898
2959
|
* This will trigger the clustering update whenever camera is moved.
|
|
@@ -2947,6 +3008,7 @@ var PointClustering = /** @class */ (function () {
|
|
|
2947
3008
|
this.clusterEntities.clear();
|
|
2948
3009
|
this.unlistenCamera();
|
|
2949
3010
|
this.disposed = true;
|
|
3011
|
+
this.updateEntityQueue = [];
|
|
2950
3012
|
// Restore entities.
|
|
2951
3013
|
var toUpdateIds = [];
|
|
2952
3014
|
for (var _c = 0, _d = Array.from(this.registeredEntityIds); _c < _d.length; _c++) {
|
|
@@ -2974,8 +3036,8 @@ var PointClustering = /** @class */ (function () {
|
|
|
2974
3036
|
PointClustering.prototype.calculateCentroid = function (points) {
|
|
2975
3037
|
var lonSum = 0;
|
|
2976
3038
|
var latSum = 0;
|
|
2977
|
-
for (var _i = 0,
|
|
2978
|
-
var point =
|
|
3039
|
+
for (var _i = 0, points_2 = points; _i < points_2.length; _i++) {
|
|
3040
|
+
var point = points_2[_i];
|
|
2979
3041
|
lonSum += point.lon;
|
|
2980
3042
|
latSum += point.lat;
|
|
2981
3043
|
}
|
|
@@ -2995,9 +3057,10 @@ var PointClustering = /** @class */ (function () {
|
|
|
2995
3057
|
// 1: Update precision.
|
|
2996
3058
|
// This defines how far apart these clusters can be.
|
|
2997
3059
|
var cameraHeight = this.viewer.camera.positionCartographic.height;
|
|
2998
|
-
this.
|
|
3060
|
+
this.getClusterSpacing(cameraHeight);
|
|
2999
3061
|
// 2: Get clusters.
|
|
3000
3062
|
var _a = this.getClusters(), clusters = _a.clusters, noLongerClustered = _a.noLongerClustered;
|
|
3063
|
+
var entitiesToUpdate = [];
|
|
3001
3064
|
// 3: Remove all cesium cluster entities that are no longer clustered.
|
|
3002
3065
|
for (var _i = 0, _b = Array.from(noLongerClustered); _i < _b.length; _i++) {
|
|
3003
3066
|
var id = _b[_i];
|
|
@@ -3014,18 +3077,30 @@ var PointClustering = /** @class */ (function () {
|
|
|
3014
3077
|
});
|
|
3015
3078
|
if (rego && rego.suppressShow) {
|
|
3016
3079
|
rego.suppressShow = false;
|
|
3017
|
-
|
|
3018
|
-
entityIds: [id],
|
|
3019
|
-
});
|
|
3080
|
+
entitiesToUpdate.push(id);
|
|
3020
3081
|
}
|
|
3021
3082
|
}
|
|
3022
3083
|
}
|
|
3023
3084
|
var getScale = function (count) {
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
scale =
|
|
3028
|
-
|
|
3085
|
+
// const MIN_SCALE = 15;
|
|
3086
|
+
// const MAX_SCALE = 80;
|
|
3087
|
+
// const SCALE_PER_POINT = 1.01;
|
|
3088
|
+
// let scale = MIN_SCALE + (count * SCALE_PER_POINT);
|
|
3089
|
+
// scale = Math.min(scale, MAX_SCALE);
|
|
3090
|
+
// return scale;
|
|
3091
|
+
if (count >= 10000) {
|
|
3092
|
+
return 140;
|
|
3093
|
+
}
|
|
3094
|
+
if (count >= 1000) {
|
|
3095
|
+
return 120;
|
|
3096
|
+
}
|
|
3097
|
+
if (count >= 100) {
|
|
3098
|
+
return 90;
|
|
3099
|
+
}
|
|
3100
|
+
if (count >= 10) {
|
|
3101
|
+
return 80;
|
|
3102
|
+
}
|
|
3103
|
+
return 70;
|
|
3029
3104
|
};
|
|
3030
3105
|
/**
|
|
3031
3106
|
* Generate circle with label in center.
|
|
@@ -3067,7 +3142,8 @@ var PointClustering = /** @class */ (function () {
|
|
|
3067
3142
|
height: getScale(count),
|
|
3068
3143
|
verticalOrigin: VerticalOrigin.CENTER,
|
|
3069
3144
|
horizontalOrigin: HorizontalOrigin.CENTER,
|
|
3070
|
-
disableDepthTestDistance: Number.POSITIVE_INFINITY
|
|
3145
|
+
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
|
3146
|
+
scaleByDistance: new NearFarScalar(1.5e2, 0.5, 3.0e7, 0.1),
|
|
3071
3147
|
}
|
|
3072
3148
|
});
|
|
3073
3149
|
this_1.clusterEntities.set(clusterId, clusterEntity);
|
|
@@ -3080,9 +3156,7 @@ var PointClustering = /** @class */ (function () {
|
|
|
3080
3156
|
});
|
|
3081
3157
|
if (rego && !rego.suppressShow) {
|
|
3082
3158
|
rego.suppressShow = true;
|
|
3083
|
-
|
|
3084
|
-
entityIds: [entityId],
|
|
3085
|
-
});
|
|
3159
|
+
entitiesToUpdate.push(entityId);
|
|
3086
3160
|
}
|
|
3087
3161
|
}
|
|
3088
3162
|
};
|
|
@@ -3092,6 +3166,7 @@ var PointClustering = /** @class */ (function () {
|
|
|
3092
3166
|
var cluster = clusters_1[_e];
|
|
3093
3167
|
_loop_1(cluster);
|
|
3094
3168
|
}
|
|
3169
|
+
this.queueForceUpdate(entitiesToUpdate);
|
|
3095
3170
|
var _loop_2 = function (clusterId, clusterEntity) {
|
|
3096
3171
|
if (!clusters.find(function (x) { return x.center.id == clusterId; })) {
|
|
3097
3172
|
this_2.viewer.entities.remove(clusterEntity);
|
|
@@ -3105,105 +3180,77 @@ var PointClustering = /** @class */ (function () {
|
|
|
3105
3180
|
_loop_2(clusterId, clusterEntity);
|
|
3106
3181
|
}
|
|
3107
3182
|
};
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
*/
|
|
3112
|
-
PointClustering.prototype.updateClusterSpacing = function (cameraHeight) {
|
|
3113
|
-
// Camera height thresholds in meters.
|
|
3114
|
-
var cameraHeightThresholds = [4000, 5000, 8000, 13000, 25000, 40000];
|
|
3183
|
+
PointClustering.prototype.getClusterSpacing = function (distanceFromCluster) {
|
|
3184
|
+
// Distance thresholds in meters from the cluster.
|
|
3185
|
+
var distanceThresholds = [3000, 4000, 5300, 6000, 7000];
|
|
3115
3186
|
// Distance increments in degrees.
|
|
3116
|
-
var distanceIncrements = [0.
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3187
|
+
var distanceIncrements = [0.001, 0.002, 0.01, 0.03, 0.09];
|
|
3188
|
+
var index = 0;
|
|
3189
|
+
if (distanceFromCluster) {
|
|
3190
|
+
for (var i = 0; i < distanceThresholds.length; i++) {
|
|
3191
|
+
if (distanceFromCluster > distanceThresholds[i]) {
|
|
3192
|
+
index = i;
|
|
3193
|
+
}
|
|
3123
3194
|
}
|
|
3124
|
-
spacing += distanceIncrements[i];
|
|
3125
3195
|
}
|
|
3126
|
-
|
|
3196
|
+
return distanceIncrements[index];
|
|
3127
3197
|
};
|
|
3128
|
-
/**
|
|
3129
|
-
* Gathers clusters.
|
|
3130
|
-
* @returns
|
|
3131
|
-
*/
|
|
3132
3198
|
PointClustering.prototype.getClusters = function () {
|
|
3133
3199
|
var _this = this;
|
|
3134
3200
|
this.currClusteredEntities.clear();
|
|
3135
3201
|
var clusters = [];
|
|
3136
3202
|
var processedPoints = new Set();
|
|
3137
3203
|
var cameraPosition = this.viewer.camera.position;
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
//
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3204
|
+
var MIN_CAMERA_DISTANCE = 5000;
|
|
3205
|
+
var processQuad = function (quad) {
|
|
3206
|
+
// Distance to quad.
|
|
3207
|
+
// TODO: Needs improvement.
|
|
3208
|
+
var distanceToQuad = quad.GetDistanceToQuad(cameraPosition);
|
|
3209
|
+
// Skip quads that are too close.
|
|
3210
|
+
if (distanceToQuad >= MIN_CAMERA_DISTANCE) {
|
|
3211
|
+
for (var _i = 0, _a = quad.points; _i < _a.length; _i++) {
|
|
3212
|
+
var point = _a[_i];
|
|
3213
|
+
// Skip points already processed in previous clusters.
|
|
3214
|
+
if (processedPoints.has(point.id)) {
|
|
3215
|
+
continue;
|
|
3216
|
+
}
|
|
3217
|
+
// Skip points closer than MIN_CAMERA_DISTANCE meters to the camera.
|
|
3218
|
+
var cartesian3 = Cartesian3.fromDegrees(point.lon, point.lat);
|
|
3219
|
+
var distanceFromCluster = Cartesian3.distance(cartesian3, cameraPosition);
|
|
3220
|
+
if (distanceFromCluster <= MIN_CAMERA_DISTANCE) {
|
|
3221
|
+
continue;
|
|
3222
|
+
}
|
|
3223
|
+
var found = [];
|
|
3224
|
+
var nearbyPoints = quad.Query(new Circle(point.lon, point.lat, _this.getClusterSpacing(distanceFromCluster)), found);
|
|
3225
|
+
if (nearbyPoints.length > 1) {
|
|
3226
|
+
var cluster = { center: point, points: [] };
|
|
3227
|
+
for (var _b = 0, nearbyPoints_1 = nearbyPoints; _b < nearbyPoints_1.length; _b++) {
|
|
3228
|
+
var nearby = nearbyPoints_1[_b];
|
|
3229
|
+
if (!cluster.points.includes(nearby)) {
|
|
3230
|
+
cluster.points.push(nearby);
|
|
3231
|
+
processedPoints.add(nearby.id);
|
|
3232
|
+
_this.currClusteredEntities.add(nearby.id);
|
|
3233
|
+
}
|
|
3234
|
+
}
|
|
3235
|
+
clusters.push(cluster);
|
|
3159
3236
|
}
|
|
3160
3237
|
}
|
|
3161
|
-
clusters.push(cluster);
|
|
3162
3238
|
}
|
|
3163
|
-
|
|
3239
|
+
if (quad.divided) {
|
|
3240
|
+
processQuad(quad.northwest);
|
|
3241
|
+
processQuad(quad.northeast);
|
|
3242
|
+
processQuad(quad.southwest);
|
|
3243
|
+
processQuad(quad.southeast);
|
|
3244
|
+
}
|
|
3245
|
+
};
|
|
3246
|
+
processQuad(this.quadTree);
|
|
3164
3247
|
// Filter out clusters with only one point.
|
|
3165
3248
|
var validClusters = clusters.filter(function (cluster) { return cluster.points.length > 1; });
|
|
3166
|
-
// Merge adjacent clusters.
|
|
3167
|
-
var mergedClusters = this.mergeClusters(validClusters);
|
|
3168
3249
|
// Get the entity IDs that are no longer clustered
|
|
3169
3250
|
var noLongerClustered = new Set(Array.from(this.prevClusteredEntities).filter(function (id) { return !_this.currClusteredEntities.has(id); }));
|
|
3170
3251
|
// Update the previous clustered entities ref.
|
|
3171
3252
|
this.prevClusteredEntities = new Set(this.currClusteredEntities);
|
|
3172
|
-
return { clusters:
|
|
3173
|
-
};
|
|
3174
|
-
/**
|
|
3175
|
-
* Merges clusters that are nearby based on the distanceBetweenClusters value.
|
|
3176
|
-
* @param clusters
|
|
3177
|
-
* @returns
|
|
3178
|
-
*/
|
|
3179
|
-
PointClustering.prototype.mergeClusters = function (clusters) {
|
|
3180
|
-
var _a;
|
|
3181
|
-
var mergedClusters = [].concat(clusters);
|
|
3182
|
-
// Keep looping while merges keep happening.
|
|
3183
|
-
var mergeOccurred = true;
|
|
3184
|
-
while (mergeOccurred) {
|
|
3185
|
-
mergeOccurred = false;
|
|
3186
|
-
for (var i = 0; i < mergedClusters.length - 1; i++) {
|
|
3187
|
-
for (var j = i + 1; j < mergedClusters.length; j++) {
|
|
3188
|
-
var cluster1 = mergedClusters[i];
|
|
3189
|
-
var cluster2 = mergedClusters[j];
|
|
3190
|
-
var centerDistance = this.calculateDistance(cluster1.center.lon, cluster1.center.lat, cluster2.center.lon, cluster2.center.lat);
|
|
3191
|
-
var distanceThreshold = this.distanceBetweenClusters;
|
|
3192
|
-
if (centerDistance <= distanceThreshold) {
|
|
3193
|
-
// Merge clusters.
|
|
3194
|
-
(_a = cluster1.points).push.apply(_a, cluster2.points);
|
|
3195
|
-
mergedClusters.splice(j, 1);
|
|
3196
|
-
this.removeClusterEntity(cluster2.center.id);
|
|
3197
|
-
mergeOccurred = true;
|
|
3198
|
-
break;
|
|
3199
|
-
}
|
|
3200
|
-
}
|
|
3201
|
-
if (mergeOccurred) {
|
|
3202
|
-
break;
|
|
3203
|
-
}
|
|
3204
|
-
}
|
|
3205
|
-
}
|
|
3206
|
-
return mergedClusters;
|
|
3253
|
+
return { clusters: validClusters, noLongerClustered: noLongerClustered };
|
|
3207
3254
|
};
|
|
3208
3255
|
/**
|
|
3209
3256
|
* Removes Cesium cluster entity.
|
|
@@ -3231,24 +3278,7 @@ var PointClustering = /** @class */ (function () {
|
|
|
3231
3278
|
PointClustering.prototype.addPoint = function (id, cartesian3) {
|
|
3232
3279
|
var point = this.convertCartesianToCartographic(cartesian3);
|
|
3233
3280
|
point.id = id;
|
|
3234
|
-
this.quadTree.Insert(point);
|
|
3235
|
-
};
|
|
3236
|
-
/**
|
|
3237
|
-
* Calculates rough distance across earth between two points.
|
|
3238
|
-
* @param lon1
|
|
3239
|
-
* @param lat1
|
|
3240
|
-
* @param lon2
|
|
3241
|
-
* @param lat2
|
|
3242
|
-
* @returns
|
|
3243
|
-
*/
|
|
3244
|
-
PointClustering.prototype.calculateDistance = function (lon1, lat1, lon2, lat2) {
|
|
3245
|
-
var lonDelta = Math.abs(lon1 - lon2);
|
|
3246
|
-
var latDelta = Math.abs(lat1 - lat2);
|
|
3247
|
-
// Approximate radius of the Earth in kilometers
|
|
3248
|
-
var earthRadius = 6371;
|
|
3249
|
-
var distance = 2 * Math.asin(Math.sqrt(Math.sin(latDelta / 2) * Math.sin(latDelta / 2) +
|
|
3250
|
-
Math.cos(lat1) * Math.cos(lat2) * Math.sin(lonDelta / 2) * Math.sin(lonDelta / 2))) * earthRadius;
|
|
3251
|
-
return distance;
|
|
3281
|
+
return this.quadTree.Insert(point);
|
|
3252
3282
|
};
|
|
3253
3283
|
/**
|
|
3254
3284
|
* Adds entity to clustering logic.
|
|
@@ -3301,8 +3331,11 @@ var PointClustering = /** @class */ (function () {
|
|
|
3301
3331
|
this.iconUrl = iconUrl;
|
|
3302
3332
|
}
|
|
3303
3333
|
}
|
|
3334
|
+
var added = this.addPoint(id, pos3d);
|
|
3335
|
+
if (!added) {
|
|
3336
|
+
return false;
|
|
3337
|
+
}
|
|
3304
3338
|
this.registeredEntityIds.add(id);
|
|
3305
|
-
this.addPoint(id, pos3d);
|
|
3306
3339
|
this.updateQueue.Call();
|
|
3307
3340
|
return true;
|
|
3308
3341
|
};
|
|
@@ -10833,7 +10866,7 @@ var ViewRenderEngine;
|
|
|
10833
10866
|
ViewRenderEngine.Render = Render;
|
|
10834
10867
|
})(ViewRenderEngine || (ViewRenderEngine = {}));
|
|
10835
10868
|
|
|
10836
|
-
var VERSION = "2.
|
|
10869
|
+
var VERSION = "2.2.0";
|
|
10837
10870
|
|
|
10838
10871
|
export { VERSION, CesiumViewMonitor, ViewerUtils, MenuItemManager, EntityRenderEngine, MenuItemCreator, VisualsRegister, RenderManager, EntitiesIdsRenderManager, EntitiesLoadedRenderManager, EntitiesRenderManager, EntityRenderManager, TilesetCadRenderManager, TilesetArbRenderManager, TilesetEntitiesRenderManager, TilesetOsmRenderManager, TilesetPointcloudRenderManager, TilesetGooglePhotosRenderManager, DataSourceStaticKmlManager, RelationsRenderManager, SharedGetters, CesiumParabola, ViewRenderEngine, TileRenderEngine, TilesetRenderEngine, CESIUM_INSPECTOR_KEY, ViewUtils, DrawingUtils, MeasureUtils, EntityUtils };
|
|
10839
10872
|
//# sourceMappingURL=bruce-cesium.es5.js.map
|