@antv/l7-layers 2.23.1 → 2.23.3-beta.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.
Files changed (65) hide show
  1. package/es/{citybuliding → citybuilding}/models/build.js +4 -2
  2. package/es/core/BaseLayer.js +3 -3
  3. package/es/core/LayerPickService.js +3 -1
  4. package/es/core/shape/Path.d.ts +2 -1
  5. package/es/core/shape/Path.js +10 -4
  6. package/es/core/triangulation.js +51 -1
  7. package/es/earth/index.js +2 -3
  8. package/es/geometry/index.js +2 -3
  9. package/es/heatmap/index.js +6 -6
  10. package/es/heatmap/models/heatmap.js +2 -3
  11. package/es/index.d.ts +1 -1
  12. package/es/index.js +1 -1
  13. package/es/line/index.js +2 -3
  14. package/es/plugins/DataMappingPlugin.js +30 -10
  15. package/es/plugins/FeatureScalePlugin.js +21 -20
  16. package/es/plugins/ShaderUniformPlugin.js +62 -29
  17. package/es/polygon/index.js +2 -3
  18. package/es/polygon/models/extrude.js +22 -7
  19. package/es/polygon/models/ocean.js +17 -6
  20. package/es/polygon/models/water.js +17 -6
  21. package/es/tile/core/BaseLayer.d.ts +4 -1
  22. package/es/tile/core/BaseLayer.js +19 -11
  23. package/es/tile/service/TileLayerService.d.ts +26 -1
  24. package/es/tile/service/TileLayerService.js +88 -16
  25. package/es/tile/service/TilePickService.js +15 -9
  26. package/es/utils/scale.d.ts +87 -0
  27. package/es/utils/scale.js +588 -0
  28. package/lib/{citybuliding → citybuilding}/models/build.js +4 -2
  29. package/lib/core/BaseLayer.js +3 -3
  30. package/lib/core/LayerPickService.js +3 -1
  31. package/lib/core/shape/Path.d.ts +2 -1
  32. package/lib/core/shape/Path.js +10 -4
  33. package/lib/core/triangulation.js +50 -1
  34. package/lib/earth/index.js +2 -3
  35. package/lib/geometry/index.js +2 -3
  36. package/lib/heatmap/index.js +6 -6
  37. package/lib/heatmap/models/heatmap.js +2 -3
  38. package/lib/index.d.ts +1 -1
  39. package/lib/index.js +1 -1
  40. package/lib/line/index.js +2 -3
  41. package/lib/plugins/DataMappingPlugin.js +30 -10
  42. package/lib/plugins/FeatureScalePlugin.js +22 -23
  43. package/lib/plugins/ShaderUniformPlugin.js +62 -29
  44. package/lib/polygon/index.js +2 -3
  45. package/lib/polygon/models/extrude.js +22 -7
  46. package/lib/polygon/models/ocean.js +17 -6
  47. package/lib/polygon/models/water.js +17 -6
  48. package/lib/tile/core/BaseLayer.d.ts +4 -1
  49. package/lib/tile/core/BaseLayer.js +19 -11
  50. package/lib/tile/service/TileLayerService.d.ts +26 -1
  51. package/lib/tile/service/TileLayerService.js +88 -16
  52. package/lib/tile/service/TilePickService.js +15 -9
  53. package/lib/utils/scale.d.ts +87 -0
  54. package/lib/utils/scale.js +603 -0
  55. package/package.json +6 -17
  56. /package/es/{citybuliding → citybuilding}/building.d.ts +0 -0
  57. /package/es/{citybuliding → citybuilding}/building.js +0 -0
  58. /package/es/{citybuliding → citybuilding}/models/build.d.ts +0 -0
  59. /package/es/{citybuliding → citybuilding}/shaders/build_frag.glsl +0 -0
  60. /package/es/{citybuliding → citybuilding}/shaders/build_vert.glsl +0 -0
  61. /package/lib/{citybuliding → citybuilding}/building.d.ts +0 -0
  62. /package/lib/{citybuliding → citybuilding}/building.js +0 -0
  63. /package/lib/{citybuliding → citybuilding}/models/build.d.ts +0 -0
  64. /package/lib/{citybuliding → citybuilding}/shaders/build_frag.glsl +0 -0
  65. /package/lib/{citybuliding → citybuilding}/shaders/build_vert.glsl +0 -0
@@ -39,12 +39,17 @@ class BaseTileLayer {
39
39
  latLonBounds,
40
40
  zoom
41
41
  } = this.getCurrentView();
42
- if (this.lastViewStates && this.lastViewStates.zoom === zoom && this.lastViewStates.latLonBounds.toString() === latLonBounds.toString()) {
42
+
43
+ // 使用数值比较替代字符串比较,更高效
44
+ if (this.lastViewStates && this.lastViewStates.zoom === zoom && this.lastViewStates.minLng === latLonBounds[0] && this.lastViewStates.minLat === latLonBounds[1] && this.lastViewStates.maxLng === latLonBounds[2] && this.lastViewStates.maxLat === latLonBounds[3]) {
43
45
  return;
44
46
  }
45
47
  this.lastViewStates = {
46
48
  zoom,
47
- latLonBounds
49
+ minLng: latLonBounds[0],
50
+ minLat: latLonBounds[1],
51
+ maxLng: latLonBounds[2],
52
+ maxLat: latLonBounds[3]
48
53
  };
49
54
  (_this$tilesetManager = this.tilesetManager) === null || _this$tilesetManager === void 0 || _this$tilesetManager.throttleUpdate(zoom, latLonBounds);
50
55
  });
@@ -105,7 +110,7 @@ class BaseTileLayer {
105
110
  }
106
111
  bindTilesetEvent() {
107
112
  // 瓦片数据加载成功
108
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
113
+
109
114
  this.tilesetManager.on('tile-loaded', tile => {
110
115
  // 将事件抛出,图层上可以监听使用
111
116
  });
@@ -117,7 +122,7 @@ class BaseTileLayer {
117
122
  });
118
123
 
119
124
  // 瓦片数据加载失败
120
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
125
+
121
126
  this.tilesetManager.on('tile-error', (error, tile) => {
122
127
  // 将事件抛出,图层上可以监听使用
123
128
  this.tileError(error);
@@ -144,7 +149,6 @@ class BaseTileLayer {
144
149
  getTile(key) {
145
150
  return this.tileLayerService.getTile(key);
146
151
  }
147
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
148
152
  tileLoaded(tile) {
149
153
  //
150
154
  }
@@ -180,10 +184,16 @@ class BaseTileLayer {
180
184
  }
181
185
  const minZoom = _this.parent.getMinZoom();
182
186
  const maxZoom = _this.parent.getMaxZoom();
183
- const tiles = _this.tilesetManager.tiles.filter(tile => tile.isLoaded) // 过滤未加载完成的
184
- .filter(tile => tile.isVisibleChange) // 过滤未发生变化的
185
- .filter(tile => tile.data) //
186
- .filter(tile => tile.z >= minZoom && tile.z < maxZoom); // 过滤不可见见
187
+
188
+ // 合并 filter 操作,减少中间数组创建
189
+ const tiles = _this.tilesetManager.tiles.filter(tile => tile.isLoaded &&
190
+ // 过滤未加载完成的
191
+ tile.isVisibleChange &&
192
+ // 过滤未发生变化的
193
+ tile.data &&
194
+ //
195
+ tile.z >= minZoom && tile.z < maxZoom // 过滤不可见层级
196
+ );
187
197
  yield Promise.all(tiles.map( /*#__PURE__*/function () {
188
198
  var _ref = (0, _asyncToGenerator2.default)(function* (tile) {
189
199
  // 未加载瓦片
@@ -214,8 +224,6 @@ class BaseTileLayer {
214
224
  }
215
225
  })();
216
226
  }
217
-
218
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
219
227
  setPickState(layers) {
220
228
  return;
221
229
  }
@@ -13,14 +13,39 @@ export declare class TileLayerService {
13
13
  private rendererService;
14
14
  private layerService;
15
15
  private parent;
16
- private layerTiles;
16
+ /**
17
+ * 使用 Map 存储瓦片实例,查找复杂度从 O(n) 降为 O(1)
18
+ */
19
+ private layerTilesMap;
20
+ /**
21
+ * 待销毁瓦片队列,用于分帧销毁
22
+ */
23
+ private pendingDestroyQueue;
24
+ private maxDestroyPerFrame;
25
+ /**
26
+ * 渲染图层缓存
27
+ */
28
+ private renderLayersCache;
29
+ private renderCacheDirty;
17
30
  constructor({ rendererService, layerService, parent }: ITileLayerServiceOptions);
18
31
  get tiles(): ITile[];
32
+ /**
33
+ * 获取待销毁瓦片数量
34
+ */
35
+ get pendingDestroyCount(): number;
19
36
  hasTile(tileKey: string): boolean;
20
37
  addTile(tile: ITile): void;
21
38
  getTile(tileKey: string): ITile | undefined;
22
39
  getVisibleTileBylngLat(lngLat: ILngLat): ITile | undefined;
23
40
  removeTile(tileKey: string): void;
41
+ /**
42
+ * 分帧销毁待销毁队列中的瓦片
43
+ */
44
+ processPendingDestroys(): void;
45
+ /**
46
+ * 标记渲染缓存为脏
47
+ */
48
+ markRenderCacheDirty(): void;
24
49
  updateTileVisible(sourceTile: SourceTile): void;
25
50
  isParentLoaded(sourceTile: SourceTile): boolean;
26
51
  isChildrenLoaded(sourceTile: SourceTile): boolean;
@@ -20,34 +20,82 @@ class TileLayerService {
20
20
  (0, _defineProperty2.default)(this, "rendererService", void 0);
21
21
  (0, _defineProperty2.default)(this, "layerService", void 0);
22
22
  (0, _defineProperty2.default)(this, "parent", void 0);
23
- (0, _defineProperty2.default)(this, "layerTiles", []);
23
+ /**
24
+ * 使用 Map 存储瓦片实例,查找复杂度从 O(n) 降为 O(1)
25
+ */
26
+ (0, _defineProperty2.default)(this, "layerTilesMap", new Map());
27
+ /**
28
+ * 待销毁瓦片队列,用于分帧销毁
29
+ */
30
+ (0, _defineProperty2.default)(this, "pendingDestroyQueue", []);
31
+ (0, _defineProperty2.default)(this, "maxDestroyPerFrame", 3);
32
+ /**
33
+ * 渲染图层缓存
34
+ */
35
+ (0, _defineProperty2.default)(this, "renderLayersCache", null);
36
+ (0, _defineProperty2.default)(this, "renderCacheDirty", true);
24
37
  this.rendererService = rendererService;
25
38
  this.layerService = layerService;
26
39
  this.parent = parent;
27
40
  }
28
41
  get tiles() {
29
- return this.layerTiles;
42
+ return Array.from(this.layerTilesMap.values());
43
+ }
44
+
45
+ /**
46
+ * 获取待销毁瓦片数量
47
+ */
48
+ get pendingDestroyCount() {
49
+ return this.pendingDestroyQueue.length;
30
50
  }
31
51
  hasTile(tileKey) {
32
- return this.layerTiles.some(tile => tile.key === tileKey);
52
+ return this.layerTilesMap.has(tileKey);
33
53
  }
34
54
  addTile(tile) {
35
- this.layerTiles.push(tile);
55
+ this.layerTilesMap.set(tile.key, tile);
56
+ this.markRenderCacheDirty();
36
57
  }
37
58
  getTile(tileKey) {
38
- return this.layerTiles.find(tile => tile.key === tileKey);
59
+ return this.layerTilesMap.get(tileKey);
39
60
  }
40
61
  getVisibleTileBylngLat(lngLat) {
41
62
  // 加载完成 & 可见 & 鼠标选中
42
- return this.layerTiles.find(tile => tile.isLoaded && tile.visible && tile.lnglatInBounds(lngLat));
63
+ for (const tile of this.layerTilesMap.values()) {
64
+ if (tile.isLoaded && tile.visible && tile.lnglatInBounds(lngLat)) {
65
+ return tile;
66
+ }
67
+ }
68
+ return undefined;
43
69
  }
44
70
  removeTile(tileKey) {
45
- const index = this.layerTiles.findIndex(t => t.key === tileKey);
46
- const tile = this.layerTiles.splice(index, 1);
47
- if (tile[0]) {
48
- tile[0].destroy();
71
+ const tile = this.layerTilesMap.get(tileKey);
72
+ if (tile) {
73
+ this.layerTilesMap.delete(tileKey);
74
+ // 放入待销毁队列,分帧销毁
75
+ this.pendingDestroyQueue.push(tile);
76
+ this.markRenderCacheDirty();
77
+ }
78
+ }
79
+
80
+ /**
81
+ * 分帧销毁待销毁队列中的瓦片
82
+ */
83
+ processPendingDestroys() {
84
+ const count = Math.min(this.pendingDestroyQueue.length, this.maxDestroyPerFrame);
85
+ for (let i = 0; i < count; i++) {
86
+ const tile = this.pendingDestroyQueue.shift();
87
+ if (tile) {
88
+ tile.destroy();
89
+ }
49
90
  }
50
91
  }
92
+
93
+ /**
94
+ * 标记渲染缓存为脏
95
+ */
96
+ markRenderCacheDirty() {
97
+ this.renderCacheDirty = true;
98
+ }
51
99
  updateTileVisible(sourceTile) {
52
100
  const tile = this.getTile(sourceTile.key);
53
101
  if (sourceTile.isVisible) {
@@ -67,6 +115,7 @@ class TileLayerService {
67
115
  tile === null || tile === void 0 || tile.updateVisible(false);
68
116
  }
69
117
  }
118
+ this.markRenderCacheDirty();
70
119
  }
71
120
  isParentLoaded(sourceTile) {
72
121
  const parentTile = sourceTile.parent;
@@ -96,6 +145,8 @@ class TileLayerService {
96
145
  render() {
97
146
  var _this = this;
98
147
  return (0, _asyncToGenerator2.default)(function* () {
148
+ // 每帧处理部分待销毁瓦片
149
+ _this.processPendingDestroys();
99
150
  const layers = _this.getRenderLayers();
100
151
  const renders = layers.map( /*#__PURE__*/function () {
101
152
  var _ref = (0, _asyncToGenerator2.default)(function* (layer) {
@@ -109,22 +160,43 @@ class TileLayerService {
109
160
  })();
110
161
  }
111
162
  getRenderLayers() {
112
- const tileList = this.layerTiles.filter(t => t.visible && t.isLoaded);
163
+ // 使用缓存避免每帧重建
164
+ if (!this.renderCacheDirty && this.renderLayersCache) {
165
+ return this.renderLayersCache;
166
+ }
113
167
  const layers = [];
114
- tileList.map(tile => layers.push(...tile.getLayers()));
168
+ this.layerTilesMap.forEach(tile => {
169
+ if (tile.visible && tile.isLoaded) {
170
+ layers.push(...tile.getLayers());
171
+ }
172
+ });
173
+ this.renderLayersCache = layers;
174
+ this.renderCacheDirty = false;
115
175
  return layers;
116
176
  }
117
177
  getLayers() {
118
- const tileList = this.layerTiles.filter(t => t.isLoaded);
119
178
  const layers = [];
120
- tileList.map(tile => layers.push(...tile.getLayers()));
179
+ this.layerTilesMap.forEach(tile => {
180
+ if (tile.isLoaded) {
181
+ layers.push(...tile.getLayers());
182
+ }
183
+ });
121
184
  return layers;
122
185
  }
123
186
  getTiles() {
124
- return this.layerTiles;
187
+ return Array.from(this.layerTilesMap.values());
125
188
  }
126
189
  destroy() {
127
- this.layerTiles.forEach(t => t.destroy());
190
+ // 先处理待销毁队列中的残留瓦片
191
+ while (this.pendingDestroyQueue.length > 0) {
192
+ const tile = this.pendingDestroyQueue.shift();
193
+ tile === null || tile === void 0 || tile.destroy();
194
+ }
195
+ // 销毁所有已加载的瓦片
196
+ this.layerTilesMap.forEach(t => t.destroy());
197
+ this.layerTilesMap.clear();
198
+ // 清理缓存
199
+ this.renderLayersCache = null;
128
200
  this.tileResource.clear();
129
201
  }
130
202
  }
@@ -68,7 +68,9 @@ class TilePickService {
68
68
  this.updateHighLight(r, g, b, ACTIVE);
69
69
  }
70
70
  updateHighLight(r, g, b, type) {
71
- this.tileLayerService.tiles.map(tile => {
71
+ // 只遍历已加载的瓦片,跳过不可见的
72
+ for (const tile of this.tileLayerService.tiles) {
73
+ if (!tile.isLoaded) continue;
72
74
  const layer = tile.getMainLayer();
73
75
  switch (type) {
74
76
  case SELECT:
@@ -78,7 +80,7 @@ class TilePickService {
78
80
  layer === null || layer === void 0 || layer.hooks.beforeHighlight.call([r, g, b]);
79
81
  break;
80
82
  }
81
- });
83
+ }
82
84
  }
83
85
  setPickState() {
84
86
  const selectColor = this.tilePickID.get(SELECT);
@@ -103,13 +105,17 @@ class TilePickService {
103
105
 
104
106
  /** 从瓦片中根据数据 */
105
107
  getFeatureById(pickedFeatureIdx) {
106
- // 提取当前可见瓦片
107
- const tiles = this.tileLayerService.getTiles().filter(tile => tile.visible);
108
- // 提取当前可见瓦片中匹配 ID 的 feature 列表
108
+ // 提取当前可见瓦片并合并 features
109
109
  const features = [];
110
- tiles.forEach(tile => {
111
- features.push(...tile.getFeatureById(pickedFeatureIdx));
112
- });
110
+ for (const tile of this.tileLayerService.tiles) {
111
+ if (tile.visible && tile.isLoaded) {
112
+ const tileFeatures = tile.getFeatureById(pickedFeatureIdx);
113
+ // 直接 push 而非使用扩展操作符
114
+ for (let i = 0; i < tileFeatures.length; i++) {
115
+ features.push(tileFeatures[i]);
116
+ }
117
+ }
118
+ }
113
119
 
114
120
  // 将 feature 列表合并后返回
115
121
  // 统一返回成 polygon 的格式 点、线、面可以通用
@@ -120,7 +126,7 @@ class TilePickService {
120
126
  }
121
127
 
122
128
  // Tip: for interface define
123
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
129
+
124
130
  pickRasterLayer() {
125
131
  return false;
126
132
  }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * 比例尺工具
3
+ * 用于替代 d3-scale 的功能
4
+ */
5
+ export interface ScaleLinear {
6
+ (x: number): number;
7
+ domain(): number[];
8
+ domain(domain: number[]): ScaleLinear;
9
+ range(): number[];
10
+ range(range: number[]): ScaleLinear;
11
+ invert(y: number): number;
12
+ ticks(count?: number): number[];
13
+ nice(count?: number): ScaleLinear;
14
+ clamp(): boolean;
15
+ clamp(clamp: boolean): ScaleLinear;
16
+ }
17
+ export declare function scaleLinear(): ScaleLinear;
18
+ export interface ScalePow extends ScaleLinear {
19
+ exponent(): number;
20
+ exponent(k: number): ScalePow;
21
+ }
22
+ export declare function scalePow(): ScalePow;
23
+ export interface ScaleLog extends ScaleLinear {
24
+ base(): number;
25
+ base(b: number): ScaleLog;
26
+ }
27
+ export declare function scaleLog(): ScaleLog;
28
+ export interface ScaleOrdinal<T = any> {
29
+ (x: any): T;
30
+ domain(): any[];
31
+ domain(domain: any[]): ScaleOrdinal<T>;
32
+ range(): T[];
33
+ range(range: T[]): ScaleOrdinal<T>;
34
+ unknown(value: T): ScaleOrdinal<T>;
35
+ }
36
+ export declare function scaleOrdinal<T = any>(range?: T[]): ScaleOrdinal<T>;
37
+ export interface ScaleQuantize {
38
+ (x: number): any;
39
+ domain(): number[];
40
+ domain(domain: number[]): ScaleQuantize;
41
+ range(): any[];
42
+ range(range: any[]): ScaleQuantize;
43
+ invertExtent(y: any): [number, number];
44
+ }
45
+ export declare function scaleQuantize(): ScaleQuantize;
46
+ export interface ScaleQuantile {
47
+ (x: number): any;
48
+ domain(): number[];
49
+ domain(domain: number[]): ScaleQuantile;
50
+ range(): any[];
51
+ range(range: any[]): ScaleQuantile;
52
+ invertExtent(y: any): [number, number];
53
+ quantiles(): number[];
54
+ }
55
+ export declare function scaleQuantile(): ScaleQuantile;
56
+ export interface ScaleThreshold {
57
+ (x: number): any;
58
+ domain(): number[];
59
+ domain(domain: number[]): ScaleThreshold;
60
+ range(): any[];
61
+ range(range: any[]): ScaleThreshold;
62
+ invertExtent(y: any): [number | undefined, number | undefined];
63
+ }
64
+ export declare function scaleThreshold(): ScaleThreshold;
65
+ export interface ScaleSequential {
66
+ (x: number): any;
67
+ domain(): number[];
68
+ domain(domain: number[]): ScaleSequential;
69
+ interpolator(): (t: number) => any;
70
+ interpolator(interpolator: (t: number) => any): ScaleSequential;
71
+ clamp(): boolean;
72
+ clamp(clamp: boolean): ScaleSequential;
73
+ }
74
+ export declare function scaleSequential(): ScaleSequential;
75
+ export interface ScaleDiverging {
76
+ (x: number): any;
77
+ domain(): number[];
78
+ domain(domain: number[]): ScaleDiverging;
79
+ interpolator(): (t: number) => any;
80
+ interpolator(interpolator: (t: number) => any): ScaleDiverging;
81
+ clamp(): boolean;
82
+ clamp(clamp: boolean): ScaleDiverging;
83
+ }
84
+ export declare function scaleDiverging(): ScaleDiverging;
85
+ export interface ScaleTime extends ScaleLinear {
86
+ }
87
+ export declare function scaleTime(): ScaleTime;