Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions packages/vt/src/layer/vector/Vector3DLayerRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@ const EMPTY_ARRAY = [];
class Vector3DLayerRenderer extends CanvasCompatible(LayerAbstractRenderer) {
constructor(...args) {
super(...args);
this.features = {};
//使用array结构,更好的遍历的性能,遍历时注意null和空洞的情况
this.features = [];
Copy link
Member

@fuzhenn fuzhenn Nov 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

有个潜在的问题,geometry的uid生成是全局性,而且全局不会重复。
如果存在多个点线面图层:

  • 第一个图层的uid会从0开始,uid 等于所有图层中 geometries 数量
  • 后续图层的uid都不从0开始
  • 因为uid不从0开始,后续图层的features数组开头会存在undefined对象
  • 如果某个图层新增了Geometry,因为uid是全局的,新Geometry的uid可能比当前features中最大的uid要大很多,新增Geometry和前一个Geometry之间会产生大量的undefined对象

我感觉可以这么改进:

  • this.features改回{}
  • checkVisible 逻辑改为遍历 Object.values(this.features)
  • 如果 Object.values 存在性能瓶颈,可以把values缓存为属性,新增一个 this.featureValues = Object.values(this.features)
  • 每次this.features发生变化时,也更新 this.featureValues

//记录空洞的feature index
this.featuresNullIndex = [];
this._geometries = {};
this._counter = 0;
this._allFeatures = {};
Expand Down Expand Up @@ -105,8 +108,11 @@ class Vector3DLayerRenderer extends CanvasCompatible(LayerAbstractRenderer) {
return this;
}
//实时检测feature的visible变化
for (const id in features) {
let feats = features[id] || [];
for (let m = 0, len = features.length; m < len; m++) {
let feats = features[m];
if (!feats) {
continue;
}
if (!Array.isArray(feats)) {
feats = [feats];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里会创建新的array对象,建议在循环外创建一个临时array,每次用 array[0] = feats; 赋值,以减少创建的临时数组对象数量

}
Expand Down Expand Up @@ -1075,7 +1081,12 @@ class Vector3DLayerRenderer extends CanvasCompatible(LayerAbstractRenderer) {

_convertGeo(geo) {
if (geo[ID_PROP] === undefined) {
geo[ID_PROP] = this._counter++;
//优先利用空洞的索引,防止features数组越来越长
if (this.featuresNullIndex.length) {
geo[ID_PROP] = this.featuresNullIndex.shift();
} else {
geo[ID_PROP] = this._counter++;
}
}
const uid = geo[ID_PROP];
if (this.features[uid]) {
Expand Down Expand Up @@ -1270,7 +1281,11 @@ class Vector3DLayerRenderer extends CanvasCompatible(LayerAbstractRenderer) {
if (uid !== undefined) {
delete this._geometries[uid];
this._removeFeatures(uid);
delete this.features[uid];
// delete this.features[uid];
this.features[uid] = null;
if (this.featuresNullIndex.indexOf(uid) === -1) {
this.featuresNullIndex.push(uid);
}
}
}
this.markRebuild();
Expand Down
14 changes: 12 additions & 2 deletions packages/vt/src/layer/vector/util/convert_to_feature.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { extend, hasOwn } from '../../../common/Util';
import { extend, hasOwn, isNil } from '../../../common/Util';
import * as maptalks from 'maptalks';
import { KEY_IDX } from '../../../common/Constant';
import { LINE_GRADIENT_PROP_KEY } from './symbols';
Expand All @@ -12,9 +12,19 @@ const GRADIENT_PROP_KEY = (LINE_GRADIENT_PROP_KEY + '').trim();

function watchGeoVisible(featue, symbol, geo) {
//geo 的visible受options.visible 和style控制
const styleFn = maptalks.MapboxUtil.loadGeoSymbol(symbol, geo);
//symbol里是否有visible和opacity
let hasVisibleProp = !isNil(symbol.visible), hasOpacityProp = !isNil(symbol.opacity);
let styleFn = symbol;
if (hasVisibleProp || hasOpacityProp) {
styleFn = maptalks.MapboxUtil.loadGeoSymbol(symbol, geo);
}
Object.defineProperty(featue, 'getVisible', {
get: function () {
//样式里没有visible和opacity
if (!hasVisibleProp && (!hasOpacityProp)) {
const visible = geo.options.visible;
return visible;
}
//实时检测geo的可见性,feature上的值是静态值,不应该检测其值
const isVisible = geo.isVisible();
if (!isVisible) {
Expand Down