@@ -67,6 +67,11 @@ function EntityCluster(options) {
6767
6868 this . _clusterEvent = new Event ( ) ;
6969
70+ this . _declusteredEvent = new Event ( ) ;
71+ this . _allProcessedEntities = [ ] ;
72+ this . _lastClusteredEntities = [ ] ;
73+ this . _lastDeclusteredEntities = [ ] ;
74+
7075 /**
7176 * Determines if entities in this collection will be shown.
7277 *
@@ -127,6 +132,10 @@ function getBoundingBox(item, coord, pixelRange, entityCluster, result) {
127132function addNonClusteredItem ( item , entityCluster ) {
128133 item . clusterShow = true ;
129134
135+ if ( defined ( item . id ) ) {
136+ entityCluster . _lastDeclusteredEntities . push ( item . id ) ;
137+ }
138+
130139 if (
131140 ! defined ( item . _labelCollection ) &&
132141 defined ( item . id ) &&
@@ -157,7 +166,16 @@ function addCluster(position, numPoints, ids, entityCluster) {
157166 cluster . point . position =
158167 position ;
159168
169+ entityCluster . _lastClusteredEntities =
170+ entityCluster . _lastClusteredEntities . concat ( ids ) ;
171+
160172 entityCluster . _clusterEvent . raiseEvent ( ids , cluster ) ;
173+
174+ entityCluster . _declusteredEvent . raiseEvent ( {
175+ clustered : ids ,
176+ declustered : entityCluster . _lastDeclusteredEntities . slice ( ) ,
177+ cluster : cluster ,
178+ } ) ;
161179}
162180
163181function hasLabelIndex ( entityCluster , entityId ) {
@@ -207,6 +225,10 @@ function getScreenSpacePositions(
207225 continue ;
208226 }
209227
228+ if ( defined ( item . id ) ) {
229+ entityCluster . _allProcessedEntities . push ( item . id ) ;
230+ }
231+
210232 points . push ( {
211233 index : i ,
212234 collection : collection ,
@@ -216,7 +238,7 @@ function getScreenSpacePositions(
216238 }
217239}
218240
219- const pointBoundinRectangleScratch = new BoundingRectangle ( ) ;
241+ const pointBoundingRectangleScratch = new BoundingRectangle ( ) ;
220242const totalBoundingRectangleScratch = new BoundingRectangle ( ) ;
221243const neighborBoundingRectangleScratch = new BoundingRectangle ( ) ;
222244
@@ -226,6 +248,10 @@ function createDeclutterCallback(entityCluster) {
226248 return ;
227249 }
228250
251+ entityCluster . _allProcessedEntities = [ ] ;
252+ entityCluster . _lastClusteredEntities = [ ] ;
253+ entityCluster . _lastDeclusteredEntities = [ ] ;
254+
229255 const scene = entityCluster . _scene ;
230256
231257 const labelCollection = entityCluster . _labelCollection ;
@@ -240,6 +266,11 @@ function createDeclutterCallback(entityCluster) {
240266 ! entityCluster . _clusterLabels &&
241267 ! entityCluster . _clusterPoints )
242268 ) {
269+ entityCluster . _declusteredEvent . raiseEvent ( {
270+ clustered : [ ] ,
271+ declustered : [ ] ,
272+ cluster : null ,
273+ } ) ;
243274 return ;
244275 }
245276
@@ -414,7 +445,7 @@ function createDeclutterCallback(entityCluster) {
414445 point . coord ,
415446 pixelRange ,
416447 entityCluster ,
417- pointBoundinRectangleScratch ,
448+ pointBoundingRectangleScratch ,
418449 ) ;
419450 const totalBBox = BoundingRectangle . clone (
420451 bbox ,
@@ -485,6 +516,18 @@ function createDeclutterCallback(entityCluster) {
485516 }
486517 }
487518
519+ if (
520+ entityCluster . _lastClusteredEntities . length > 0 ||
521+ entityCluster . _lastDeclusteredEntities . length > 0
522+ ) {
523+ entityCluster . _declusteredEvent . raiseEvent ( {
524+ clustered : entityCluster . _lastClusteredEntities . slice ( ) ,
525+ declustered : entityCluster . _lastDeclusteredEntities . slice ( ) ,
526+ cluster : null ,
527+ allProcessed : entityCluster . _allProcessedEntities . slice ( ) ,
528+ } ) ;
529+ }
530+
488531 if ( clusteredLabelCollection . length === 0 ) {
489532 clusteredLabelCollection . destroy ( ) ;
490533 entityCluster . _clusterLabelCollection = undefined ;
@@ -567,6 +610,16 @@ Object.defineProperties(EntityCluster.prototype, {
567610 return this . _clusterEvent ;
568611 } ,
569612 } ,
613+ /**
614+ * Gets the event that will be raised when clustering is processed, including both clustered and declustered entities.
615+ * @memberof EntityCluster.prototype
616+ * @type {Event }
617+ */
618+ declusteredEvent : {
619+ get : function ( ) {
620+ return this . _declusteredEvent ;
621+ } ,
622+ } ,
570623 /**
571624 * Gets or sets whether clustering billboard entities is enabled.
572625 * @memberof EntityCluster.prototype
@@ -852,6 +905,35 @@ function updateEnable(entityCluster) {
852905 return ;
853906 }
854907
908+ const allVisibleEntities = [ ] ;
909+
910+ if ( defined ( entityCluster . _labelCollection ) ) {
911+ for ( let i = 0 ; i < entityCluster . _labelCollection . length ; i ++ ) {
912+ const label = entityCluster . _labelCollection . get ( i ) ;
913+ if ( defined ( label . id ) && label . show ) {
914+ allVisibleEntities . push ( label . id ) ;
915+ }
916+ }
917+ }
918+
919+ if ( defined ( entityCluster . _billboardCollection ) ) {
920+ for ( let i = 0 ; i < entityCluster . _billboardCollection . length ; i ++ ) {
921+ const billboard = entityCluster . _billboardCollection . get ( i ) ;
922+ if ( defined ( billboard . id ) && billboard . show ) {
923+ allVisibleEntities . push ( billboard . id ) ;
924+ }
925+ }
926+ }
927+
928+ if ( defined ( entityCluster . _pointCollection ) ) {
929+ for ( let i = 0 ; i < entityCluster . _pointCollection . length ; i ++ ) {
930+ const point = entityCluster . _pointCollection . get ( i ) ;
931+ if ( defined ( point . id ) && point . show ) {
932+ allVisibleEntities . push ( point . id ) ;
933+ }
934+ }
935+ }
936+
855937 if ( defined ( entityCluster . _clusterLabelCollection ) ) {
856938 entityCluster . _clusterLabelCollection . destroy ( ) ;
857939 }
@@ -869,6 +951,32 @@ function updateEnable(entityCluster) {
869951 disableCollectionClustering ( entityCluster . _labelCollection ) ;
870952 disableCollectionClustering ( entityCluster . _billboardCollection ) ;
871953 disableCollectionClustering ( entityCluster . _pointCollection ) ;
954+
955+ if ( allVisibleEntities . length > 0 ) {
956+ const uniqueEntities = [ ...new Set ( allVisibleEntities ) ] ;
957+
958+ entityCluster . _declusteredEvent . raiseEvent ( {
959+ clustered : [ ] ,
960+ declustered : uniqueEntities ,
961+ cluster : null ,
962+ allProcessed : uniqueEntities ,
963+ } ) ;
964+
965+ entityCluster . _lastClusteredEntities = [ ] ;
966+ entityCluster . _lastDeclusteredEntities = uniqueEntities . slice ( ) ;
967+ entityCluster . _allProcessedEntities = uniqueEntities . slice ( ) ;
968+ } else {
969+ entityCluster . _declusteredEvent . raiseEvent ( {
970+ clustered : [ ] ,
971+ declustered : [ ] ,
972+ cluster : null ,
973+ allProcessed : [ ] ,
974+ } ) ;
975+
976+ entityCluster . _lastClusteredEntities = [ ] ;
977+ entityCluster . _lastDeclusteredEntities = [ ] ;
978+ entityCluster . _allProcessedEntities = [ ] ;
979+ }
872980}
873981
874982/**
@@ -998,9 +1106,37 @@ EntityCluster.prototype.destroy = function () {
9981106 this . _pixelRangeDirty = false ;
9991107 this . _minimumClusterSizeDirty = false ;
10001108
1109+ this . _allProcessedEntities = [ ] ;
1110+ this . _lastClusteredEntities = [ ] ;
1111+ this . _lastDeclusteredEntities = [ ] ;
1112+
10011113 return undefined ;
10021114} ;
10031115
1116+ /**
1117+ * Returns the last set of clustered entities from the most recent clustering operation.
1118+ * @returns {Entity[] } Array of entities that were clustered
1119+ */
1120+ EntityCluster . prototype . getLastClusteredEntities = function ( ) {
1121+ return this . _lastClusteredEntities . slice ( ) ;
1122+ } ;
1123+
1124+ /**
1125+ * Returns the last set of declustered entities from the most recent clustering operation.
1126+ * @returns {Entity[] } Array of entities that were not clustered
1127+ */
1128+ EntityCluster . prototype . getLastDeclusteredEntities = function ( ) {
1129+ return this . _lastDeclusteredEntities . slice ( ) ;
1130+ } ;
1131+
1132+ /**
1133+ * Returns all entities that were processed in the most recent clustering operation.
1134+ * @returns {Entity[] } Array of all processed entities
1135+ */
1136+ EntityCluster . prototype . getAllProcessedEntities = function ( ) {
1137+ return this . _allProcessedEntities . slice ( ) ;
1138+ } ;
1139+
10041140/**
10051141 * A event listener function used to style clusters.
10061142 * @callback EntityCluster.newClusterCallback
@@ -1019,4 +1155,26 @@ EntityCluster.prototype.destroy = function () {
10191155 * cluster.label.text = entities.length.toLocaleString();
10201156 * });
10211157 */
1158+
1159+ /**
1160+ * A event listener function for enhanced clustering information.
1161+ * @callback EntityCluster.declusteredCallback
1162+ *
1163+ * @param {object } clusteringData An object containing clustering information.
1164+ * @param {Entity[] } clusteringData.clustered An array of entities that were clustered.
1165+ * @param {Entity[] } clusteringData.declustered An array of entities that were not clustered.
1166+ * @param {object|null } clusteringData.cluster The cluster object (if this event is for a specific cluster) or null for summary events.
1167+ * @param {Entity[] } [clusteringData.allProcessed] An array of all entities processed (only in summary events).
1168+ *
1169+ * @example
1170+ * // Using the enhanced declusteredEvent to access both clustered and declustered entities
1171+ * dataSource.clustering.declusteredEvent.addEventListener(function(data) {
1172+ * console.log('Clustered entities:', data.clustered.length);
1173+ * console.log('Declustered entities:', data.declustered.length);
1174+ * if (data.allProcessed) {
1175+ * console.log('Total processed entities:', data.allProcessed.length);
1176+ * }
1177+ * });
1178+ */
1179+
10221180export default EntityCluster ;
0 commit comments