Skip to content

Commit d7778b3

Browse files
committed
Optimize the logic of maxClusterZoom
1 parent dd4cdeb commit d7778b3

2 files changed

Lines changed: 67 additions & 24 deletions

File tree

index.js

Lines changed: 66 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,7 @@ export class TileClusterLayer extends maptalks.VectorLayer {
9191

9292
constructor(id, options) {
9393
super(id, options);
94-
this._tileCache = {};
95-
this._currentTileCache = {};
94+
this._initTileCache();
9695
this.merc = new SphericalMercator({
9796
size: 256
9897
// antimeridian: true
@@ -110,10 +109,15 @@ export class TileClusterLayer extends maptalks.VectorLayer {
110109
return this.globalPoints.length === 0;
111110
}
112111

113-
_init() {
114-
this.clear();
112+
_initTileCache() {
115113
this._tileCache = {};
114+
this._clusterTileCache = {};
116115
this._currentTileCache = {};
116+
}
117+
118+
_init() {
119+
this.clear();
120+
this._initTileCache();
117121
this._viewChange();
118122
return this;
119123
}
@@ -192,26 +196,40 @@ export class TileClusterLayer extends maptalks.VectorLayer {
192196
if (this._isEmpty()) {
193197
return this;
194198
}
195-
const currentTileCache = this._currentTileCache, tileCache = this._tileCache, merc = this.merc, kdbush = this.kdbush;
199+
const currentTileCache = this._currentTileCache,
200+
merc = this.merc, kdbush = this.kdbush;
196201
const cache = {};
197202
const mapZoom = this.getMap().getZoom();
198-
const zoom = Math.floor(mapZoom);
203+
const isCluster = mapZoom <= this.options.maxClusterZoom;
204+
// const zoom = Math.ceil(mapZoom);
199205
const addMarkers = [], removeMarkers = [];
206+
const globalCache = this._getGlobalCache(isCluster);
200207
for (let i = 0, len = tiles.length; i < len; i++) {
201208
const tile = tiles[i];
202209
const [x, y, z] = tile;
203210
const key = [x, y, z].join('_').toString();
204211
cache[key] = 1;
205-
if (currentTileCache[key]) {
206-
continue;
212+
let tileCache = currentTileCache[key];
213+
if (tileCache) {
214+
if (tileCache.clustering === isCluster) {
215+
continue;
216+
} else {
217+
if (tileCache.markers.length) {
218+
tileCache.markers.forEach(marker => {
219+
removeMarkers.push(marker);
220+
});
221+
}
222+
delete currentTileCache[key];
223+
}
207224
}
208225
let clusterResult;
209-
if (!tileCache[key]) {
226+
tileCache = this._getTileCache(key, isCluster);
227+
if (!tileCache) {
210228
const bbox = merc.bbox(x, y, z);
211229
const ids = kdbush.range(bbox[0], bbox[1], bbox[2], bbox[3]);
212-
clusterResult = this._tileCluster(key, ids, zoom);
230+
clusterResult = this._tileCluster(key, ids, mapZoom, isCluster);
213231
} else {
214-
clusterResult = tileCache[key];
232+
clusterResult = globalCache[key];
215233
}
216234
if (!currentTileCache[key] && clusterResult.markers.length) {
217235
clusterResult.markers.forEach(marker => {
@@ -238,36 +256,60 @@ export class TileClusterLayer extends maptalks.VectorLayer {
238256
}
239257
}
240258

241-
_tileCluster(key, ids, zoom) {
242-
const tileCache = this._tileCache, globalPoints = this.globalPoints, globalFeatures = this.globalFeatures,
259+
_getGlobalCache(isCluster) {
260+
const tileCache = this._tileCache, clusterTileCache = this._clusterTileCache;
261+
if (isCluster) {
262+
return clusterTileCache;
263+
}
264+
return tileCache;
265+
}
266+
267+
_getTileCache(key, isCluster) {
268+
const globalCache = this._getGlobalCache(isCluster);
269+
const tileCache = globalCache[key];
270+
if (tileCache) {
271+
if (globalCache.clustering === isCluster) {
272+
return tileCache;
273+
} else {
274+
delete globalCache[key];
275+
}
276+
}
277+
}
278+
279+
_tileCluster(key, ids, zoom, isCluster) {
280+
const globalPoints = this.globalPoints, globalFeatures = this.globalFeatures,
243281
maxZoom = this.options.maxClusterZoom;
244-
if (!tileCache[key]) {
245-
tileCache[key] = {
282+
const globalCache = this._getGlobalCache(isCluster);
283+
const tileCache = this._getTileCache(key, isCluster);
284+
if (!tileCache) {
285+
globalCache[key] = {
246286
points: [],
247287
features: [],
248288
coordinate: null,
249-
markers: []
289+
markers: [],
290+
clustering: true
250291
};
251292
if (ids.length) {
252293
const { x, y, points, features } = this._getClusterResult(globalPoints, ids);
253-
tileCache[key].coordinates = [x, y];
254-
if (zoom > (maxZoom - 1) || ids.length < this.options.minClusterCount) {
255-
tileCache[key].markers = ids.map(id => {
294+
globalCache[key].coordinates = [x, y];
295+
if (zoom > maxZoom || ids.length < this.options.minClusterCount) {
296+
globalCache[key].markers = ids.map(id => {
256297
const feature = globalFeatures[id];
257298
return new maptalks.Marker(globalPoints[id], {
258299
symbol: feature.symbol,
259300
properties: feature.properties || {}
260301
});
261302
});
303+
globalCache[key].clustering = false;
262304
} else {
263-
tileCache[key].markers = [this._getClusterMarker(tileCache[key].coordinates, ids.length, features)];
305+
globalCache[key].markers = [this._getClusterMarker(globalCache[key].coordinates, ids.length, features)];
264306
}
265-
this._bindMarkersEvents(tileCache[key].markers);
266-
tileCache[key].points = points;
267-
tileCache[key].features = features;
307+
this._bindMarkersEvents(globalCache[key].markers);
308+
globalCache[key].points = points;
309+
globalCache[key].features = features;
268310
}
269311
}
270-
return tileCache[key];
312+
return globalCache[key];
271313
}
272314

273315
_bindMarkersEvents(markers = []) {

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"jsnext:main": "dist/maptalks.tileclusterlayer.mjs",
88
"scripts": {
99
"lint": "eslint ./*.js",
10+
"dev": "npm run lint && cross-env NODE_ENV=dev rollup -c -w",
1011
"build": "npm run lint && cross-env NODE_ENV=dev rollup -c",
1112
"test": "echo \"Error: no test specified\" && exit 1"
1213
},

0 commit comments

Comments
 (0)