@antv/l7-layers 2.24.0 → 2.24.2
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/es/core/interface.d.ts +1 -0
- package/es/core/triangulation.js +11 -0
- package/es/plugins/index.d.ts +1 -1
- package/es/point/index.d.ts +2 -0
- package/es/point/index.js +10 -0
- package/es/point/models/fill.js +1 -1
- package/es/point/models/image.d.ts +16 -1
- package/es/point/models/image.js +131 -6
- package/es/tile/tile/Tile.d.ts +1 -1
- package/es/tile/tile/index.d.ts +1 -1
- package/lib/core/interface.d.ts +1 -0
- package/lib/core/triangulation.js +11 -0
- package/lib/plugins/index.d.ts +1 -1
- package/lib/point/index.d.ts +2 -0
- package/lib/point/index.js +10 -0
- package/lib/point/models/fill.js +1 -1
- package/lib/point/models/image.d.ts +16 -1
- package/lib/point/models/image.js +131 -6
- package/lib/tile/tile/Tile.d.ts +1 -1
- package/lib/tile/tile/index.d.ts +1 -1
- package/package.json +6 -6
package/es/core/interface.d.ts
CHANGED
package/es/core/triangulation.js
CHANGED
|
@@ -112,6 +112,17 @@ export function PointExtrudeTriangulation(feature) {
|
|
|
112
112
|
* @param feature 映射feature
|
|
113
113
|
*/
|
|
114
114
|
export function PointImageTriangulation(feature) {
|
|
115
|
+
// @ts-ignore
|
|
116
|
+
const that = this;
|
|
117
|
+
const id = feature.id;
|
|
118
|
+
// 当 imageFilterMap 存在且该 feature 未通过碰撞检测时,返回空几何(等效隐藏)
|
|
119
|
+
if (that !== null && that !== void 0 && that.imageFilterMap && !that.imageFilterMap[id]) {
|
|
120
|
+
return {
|
|
121
|
+
vertices: [],
|
|
122
|
+
indices: [],
|
|
123
|
+
size: 3
|
|
124
|
+
};
|
|
125
|
+
}
|
|
115
126
|
const coordinates = calculateCentroid(feature.coordinates);
|
|
116
127
|
return {
|
|
117
128
|
vertices: [...coordinates],
|
package/es/plugins/index.d.ts
CHANGED
|
@@ -12,4 +12,4 @@ import RegisterStyleAttributePlugin from './RegisterStyleAttributePlugin';
|
|
|
12
12
|
import ShaderUniformPlugin from './ShaderUniformPlugin';
|
|
13
13
|
import UpdateModelPlugin from './UpdateModelPlugin';
|
|
14
14
|
import UpdateStyleAttributePlugin from './UpdateStyleAttributePlugin';
|
|
15
|
-
export declare function createPlugins(): (
|
|
15
|
+
export declare function createPlugins(): (DataMappingPlugin | DataSourcePlugin | FeatureScalePlugin | LayerAnimateStylePlugin | LayerMaskPlugin | LayerModelPlugin | LayerStylePlugin | LightingPlugin | MultiPassRendererPlugin | PixelPickingPlugin | RegisterStyleAttributePlugin | ShaderUniformPlugin | UpdateModelPlugin | UpdateStyleAttributePlugin)[];
|
package/es/point/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ILayer, ILayerConfig } from '@antv/l7-core';
|
|
1
2
|
import BaseLayer from '../core/BaseLayer';
|
|
2
3
|
import type { IPointLayerStyleOptions } from '../core/interface';
|
|
3
4
|
import type { PointType } from './models/index';
|
|
@@ -17,6 +18,7 @@ export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
|
|
|
17
18
|
};
|
|
18
19
|
buildModels(): Promise<void>;
|
|
19
20
|
rebuildModels(): Promise<void>;
|
|
21
|
+
style(options: Partial<IPointLayerStyleOptions> & Partial<ILayerConfig>): ILayer;
|
|
20
22
|
/**
|
|
21
23
|
* 在未传入数据的时候判断点图层的 shape 类型
|
|
22
24
|
* @returns
|
package/es/point/index.js
CHANGED
|
@@ -37,6 +37,16 @@ export default class PointLayer extends BaseLayer {
|
|
|
37
37
|
yield _this2.buildModels();
|
|
38
38
|
})();
|
|
39
39
|
}
|
|
40
|
+
style(options) {
|
|
41
|
+
super.style(options);
|
|
42
|
+
// allowOverlap 依赖 needUpdate() 感知变化并重建 model,而 needUpdate() 仅在渲染帧的
|
|
43
|
+
// beforeRender 钩子中被调用。style() 本身不触发渲染,因此在 allowOverlap 出现时
|
|
44
|
+
// 主动触发一次 reRender,确保静止地图下也能即时生效。
|
|
45
|
+
if ('allowOverlap' in options) {
|
|
46
|
+
this.reRender();
|
|
47
|
+
}
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
40
50
|
|
|
41
51
|
/**
|
|
42
52
|
* 在未传入数据的时候判断点图层的 shape 类型
|
package/es/point/models/fill.js
CHANGED
|
@@ -50,7 +50,7 @@ export default class FillModel extends BaseModel {
|
|
|
50
50
|
} = this.layer.getLayerConfig();
|
|
51
51
|
return {
|
|
52
52
|
u_animate: this.animateOption2Array(animateOption),
|
|
53
|
-
u_time: this.layer.getLayerAnimateTime()
|
|
53
|
+
u_time: animateOption.enable ? this.layer.getLayerAnimateTime() : -1.0
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
56
|
getAttribute() {
|
|
@@ -17,6 +17,12 @@ export default class ImageModel extends BaseModel {
|
|
|
17
17
|
UV: number;
|
|
18
18
|
};
|
|
19
19
|
private texture;
|
|
20
|
+
imageFilterMap: {
|
|
21
|
+
[key: number]: boolean;
|
|
22
|
+
} | null;
|
|
23
|
+
private currentZoom;
|
|
24
|
+
private extent;
|
|
25
|
+
private preAllowOverlap;
|
|
20
26
|
getUninforms(): IModelUniform;
|
|
21
27
|
protected getCommonUniformsInfo(): {
|
|
22
28
|
uniformsArray: number[];
|
|
@@ -26,8 +32,17 @@ export default class ImageModel extends BaseModel {
|
|
|
26
32
|
};
|
|
27
33
|
};
|
|
28
34
|
initModels(): Promise<IModel[]>;
|
|
29
|
-
clearModels(): void;
|
|
30
35
|
buildModels(): Promise<IModel[]>;
|
|
36
|
+
needUpdate(): Promise<boolean>;
|
|
37
|
+
clearModels(): void;
|
|
31
38
|
protected registerBuiltinAttributes(): void;
|
|
39
|
+
/**
|
|
40
|
+
* 图标碰撞避让:遍历所有 feature,在屏幕空间做 AABB 碰撞检测,
|
|
41
|
+
* 将通过检测的 feature id 写入 imageFilterMap。
|
|
42
|
+
* PointImageTriangulation 绑定 this 后,会跳过不在 map 中的 feature。
|
|
43
|
+
*/
|
|
44
|
+
private filterImages;
|
|
45
|
+
private imageExtent;
|
|
46
|
+
private reBuildModel;
|
|
32
47
|
private updateTexture;
|
|
33
48
|
}
|
package/es/point/models/image.js
CHANGED
|
@@ -2,8 +2,10 @@ import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
|
2
2
|
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
3
3
|
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
4
4
|
import { AttributeType, gl } from '@antv/l7-core';
|
|
5
|
+
import { boundsContains, calculateCentroid, padBounds } from '@antv/l7-utils';
|
|
5
6
|
import BaseModel from "../../core/BaseModel";
|
|
6
7
|
import { PointImageTriangulation } from "../../core/triangulation";
|
|
8
|
+
import CollisionIndex from "../../utils/collision-index";
|
|
7
9
|
/* babel-plugin-inline-import '../shaders/image/image_frag.glsl' */
|
|
8
10
|
const pointImageFrag = "layout(std140) uniform commonUniforms {\n vec2 u_textSize;\n float u_raisingHeight;\n float u_heightfixed;\n};\n\nuniform sampler2D u_texture;\n\nin vec4 v_color;\nin vec2 v_uv;\nin float v_opacity;\n\n#pragma include \"picking\"\n\nout vec4 outputColor;\n\nvoid main() {\n vec2 pos = v_uv / u_textSize + gl_PointCoord / u_textSize * 64.0;\n vec4 textureColor;\n\n // Y = 0.299R + 0.587G + 0.114B // \u4EAE\u5EA6\u63D0\u53D6\n\n textureColor = texture(SAMPLER_2D(u_texture), pos);\n\n // Tip: \u53BB\u9664\u8FB9\u7F18\u90E8\u5206 mipmap \u5BFC\u81F4\u7684\u6DF7\u5408\u53D8\u6697\n float fragmengTocenter = distance(vec2(0.5), gl_PointCoord);\n if (fragmengTocenter >= 0.5) {\n float luma = 0.299 * textureColor.r + 0.587 * textureColor.g + 0.114 * textureColor.b;\n textureColor.a *= luma;\n }\n\n if (\n all(lessThan(v_color, vec4(1.0 + 0.00001))) && all(greaterThan(v_color, vec4(1.0 - 0.00001))) ||\n v_color == vec4(1.0)\n ) {\n outputColor = textureColor;\n } else {\n outputColor = step(0.01, textureColor.z) * v_color;\n }\n outputColor.a *= v_opacity;\n if (outputColor.a < 0.01) {\n discard;\n }\n outputColor = filterColor(outputColor);\n}\n";
|
|
9
11
|
/* babel-plugin-inline-import '../shaders/image/image_vert.glsl' */
|
|
@@ -12,6 +14,11 @@ export default class ImageModel extends BaseModel {
|
|
|
12
14
|
constructor(...args) {
|
|
13
15
|
super(...args);
|
|
14
16
|
_defineProperty(this, "texture", void 0);
|
|
17
|
+
// 通过碰撞检测的 feature id 集合,由 filterImages() 填充;null 表示不启用过滤(allowOverlap: true)
|
|
18
|
+
_defineProperty(this, "imageFilterMap", null);
|
|
19
|
+
_defineProperty(this, "currentZoom", -1);
|
|
20
|
+
_defineProperty(this, "extent", void 0);
|
|
21
|
+
_defineProperty(this, "preAllowOverlap", true);
|
|
15
22
|
_defineProperty(this, "updateTexture", () => {
|
|
16
23
|
const {
|
|
17
24
|
createTexture2D
|
|
@@ -78,25 +85,35 @@ export default class ImageModel extends BaseModel {
|
|
|
78
85
|
initModels() {
|
|
79
86
|
var _this = this;
|
|
80
87
|
return _asyncToGenerator(function* () {
|
|
88
|
+
const {
|
|
89
|
+
allowOverlap = true
|
|
90
|
+
} = _this.layer.getLayerConfig();
|
|
91
|
+
_this.extent = _this.imageExtent();
|
|
92
|
+
_this.preAllowOverlap = allowOverlap;
|
|
81
93
|
_this.iconService.on('imageUpdate', _this.updateTexture);
|
|
82
94
|
_this.updateTexture();
|
|
83
95
|
return _this.buildModels();
|
|
84
96
|
})();
|
|
85
97
|
}
|
|
86
|
-
clearModels() {
|
|
87
|
-
var _this$texture2;
|
|
88
|
-
(_this$texture2 = this.texture) === null || _this$texture2 === void 0 || _this$texture2.destroy();
|
|
89
|
-
this.iconService.off('imageUpdate', this.updateTexture);
|
|
90
|
-
}
|
|
91
98
|
buildModels() {
|
|
92
99
|
var _this2 = this;
|
|
93
100
|
return _asyncToGenerator(function* () {
|
|
101
|
+
const {
|
|
102
|
+
allowOverlap = true
|
|
103
|
+
} = _this2.layer.getLayerConfig();
|
|
94
104
|
_this2.initUniformsBuffer();
|
|
105
|
+
if (!allowOverlap) {
|
|
106
|
+
_this2.filterImages();
|
|
107
|
+
} else {
|
|
108
|
+
// 允许压盖时置 null,PointImageTriangulation 检测到 null 则跳过过滤
|
|
109
|
+
_this2.imageFilterMap = null;
|
|
110
|
+
}
|
|
95
111
|
const model = yield _this2.layer.buildLayerModel({
|
|
96
112
|
moduleName: 'pointImage',
|
|
97
113
|
vertexShader: pointImageVert,
|
|
98
114
|
fragmentShader: pointImageFrag,
|
|
99
|
-
|
|
115
|
+
// 绑定 this,让 PointImageTriangulation 能读取 imageFilterMap
|
|
116
|
+
triangulation: PointImageTriangulation.bind(_this2),
|
|
100
117
|
defines: _this2.getDefines(),
|
|
101
118
|
inject: _this2.getInject(),
|
|
102
119
|
depth: {
|
|
@@ -107,6 +124,41 @@ export default class ImageModel extends BaseModel {
|
|
|
107
124
|
return [model];
|
|
108
125
|
})();
|
|
109
126
|
}
|
|
127
|
+
needUpdate() {
|
|
128
|
+
var _this3 = this;
|
|
129
|
+
return _asyncToGenerator(function* () {
|
|
130
|
+
const {
|
|
131
|
+
allowOverlap = true
|
|
132
|
+
} = _this3.layer.getLayerConfig();
|
|
133
|
+
|
|
134
|
+
// allowOverlap 开关发生变化时,强制重建
|
|
135
|
+
if (allowOverlap !== _this3.preAllowOverlap) {
|
|
136
|
+
_this3.preAllowOverlap = allowOverlap;
|
|
137
|
+
yield _this3.reBuildModel();
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// 允许压盖时无需每帧检测
|
|
142
|
+
if (allowOverlap) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// 不允许压盖时,zoom 变化 >0.5 或视野超出上次范围则重算碰撞
|
|
147
|
+
const zoom = _this3.mapService.getZoom();
|
|
148
|
+
const extent = _this3.mapService.getBounds();
|
|
149
|
+
const flag = boundsContains(_this3.extent, extent);
|
|
150
|
+
if (Math.abs(_this3.currentZoom - zoom) > 0.5 || !flag) {
|
|
151
|
+
yield _this3.reBuildModel();
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
return false;
|
|
155
|
+
})();
|
|
156
|
+
}
|
|
157
|
+
clearModels() {
|
|
158
|
+
var _this$texture2;
|
|
159
|
+
(_this$texture2 = this.texture) === null || _this$texture2 === void 0 || _this$texture2.destroy();
|
|
160
|
+
this.iconService.off('imageUpdate', this.updateTexture);
|
|
161
|
+
}
|
|
110
162
|
registerBuiltinAttributes() {
|
|
111
163
|
// 注册 Position 属性 64 位地位部分,经纬度数据开启双精度,避免大于 20层级以上出现数据偏移
|
|
112
164
|
this.registerPosition64LowAttribute();
|
|
@@ -165,4 +217,77 @@ export default class ImageModel extends BaseModel {
|
|
|
165
217
|
}
|
|
166
218
|
});
|
|
167
219
|
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* 图标碰撞避让:遍历所有 feature,在屏幕空间做 AABB 碰撞检测,
|
|
223
|
+
* 将通过检测的 feature id 写入 imageFilterMap。
|
|
224
|
+
* PointImageTriangulation 绑定 this 后,会跳过不在 map 中的 feature。
|
|
225
|
+
*/
|
|
226
|
+
filterImages() {
|
|
227
|
+
const {
|
|
228
|
+
padding = [0, 0]
|
|
229
|
+
} = this.layer.getLayerConfig();
|
|
230
|
+
this.imageFilterMap = {};
|
|
231
|
+
this.currentZoom = this.mapService.getZoom();
|
|
232
|
+
this.extent = this.imageExtent();
|
|
233
|
+
const {
|
|
234
|
+
width,
|
|
235
|
+
height
|
|
236
|
+
} = this.rendererService.getViewportSize();
|
|
237
|
+
const collisionIndex = new CollisionIndex(width, height);
|
|
238
|
+
const data = this.layer.getEncodedData();
|
|
239
|
+
data.forEach(feature => {
|
|
240
|
+
const {
|
|
241
|
+
id = 0,
|
|
242
|
+
size = 5
|
|
243
|
+
} = feature;
|
|
244
|
+
const iconSize = Array.isArray(size) ? size[0] : size;
|
|
245
|
+
const centroid = calculateCentroid(feature.coordinates);
|
|
246
|
+
const pixels = this.mapService.lngLatToContainer(centroid);
|
|
247
|
+
const {
|
|
248
|
+
box
|
|
249
|
+
} = collisionIndex.placeCollisionBox({
|
|
250
|
+
x1: -iconSize - padding[0],
|
|
251
|
+
x2: iconSize + padding[0],
|
|
252
|
+
y1: -iconSize - padding[1],
|
|
253
|
+
y2: iconSize + padding[1],
|
|
254
|
+
anchorPointX: pixels.x,
|
|
255
|
+
anchorPointY: pixels.y
|
|
256
|
+
});
|
|
257
|
+
if (box && box.length) {
|
|
258
|
+
collisionIndex.insertCollisionBox(box, id);
|
|
259
|
+
this.imageFilterMap[id] = true;
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
imageExtent() {
|
|
264
|
+
const bounds = this.mapService.getBounds();
|
|
265
|
+
return padBounds(bounds, 0.5);
|
|
266
|
+
}
|
|
267
|
+
reBuildModel() {
|
|
268
|
+
var _this4 = this;
|
|
269
|
+
return _asyncToGenerator(function* () {
|
|
270
|
+
const {
|
|
271
|
+
allowOverlap = true
|
|
272
|
+
} = _this4.layer.getLayerConfig();
|
|
273
|
+
if (!allowOverlap) {
|
|
274
|
+
_this4.filterImages();
|
|
275
|
+
} else {
|
|
276
|
+
_this4.imageFilterMap = null; // 允许压盖:清空过滤表,全量渲染
|
|
277
|
+
}
|
|
278
|
+
const model = yield _this4.layer.buildLayerModel({
|
|
279
|
+
moduleName: 'pointImage',
|
|
280
|
+
vertexShader: pointImageVert,
|
|
281
|
+
fragmentShader: pointImageFrag,
|
|
282
|
+
triangulation: PointImageTriangulation.bind(_this4),
|
|
283
|
+
defines: _this4.getDefines(),
|
|
284
|
+
inject: _this4.getInject(),
|
|
285
|
+
depth: {
|
|
286
|
+
enable: false
|
|
287
|
+
},
|
|
288
|
+
primitive: gl.POINTS
|
|
289
|
+
});
|
|
290
|
+
_this4.layer.models = [model];
|
|
291
|
+
})();
|
|
292
|
+
}
|
|
168
293
|
}
|
package/es/tile/tile/Tile.d.ts
CHANGED
|
@@ -47,7 +47,7 @@ export default abstract class Tile extends EventEmitter implements ITile {
|
|
|
47
47
|
enablePropagation?: boolean | undefined;
|
|
48
48
|
fitBoundsOptions?: unknown;
|
|
49
49
|
name?: string | undefined;
|
|
50
|
-
blend?: "
|
|
50
|
+
blend?: "min" | "max" | "normal" | "additive" | "subtractive" | "none" | undefined;
|
|
51
51
|
depth?: boolean | undefined;
|
|
52
52
|
pickedFeatureID?: number | undefined;
|
|
53
53
|
enableMultiPassRenderer?: boolean | undefined;
|
package/es/tile/tile/index.d.ts
CHANGED
|
@@ -7,6 +7,6 @@ import RasterTerrainRGBTile from './RasterTerrainRGBTile';
|
|
|
7
7
|
import RasterTile from './RasterTile';
|
|
8
8
|
import VectorTile from './VectorTile';
|
|
9
9
|
export type TileType = 'VectorTile' | 'DebugTile' | 'PolygonLayer' | 'PointLayer' | 'LineLayer' | 'RasterLayer' | 'image' | 'MaskLayer' | 'TileDebugLayer';
|
|
10
|
-
export declare function getTileFactory(layer: ILayer): typeof DebugTile | typeof ImageTile | typeof
|
|
10
|
+
export declare function getTileFactory(layer: ILayer): typeof DebugTile | typeof ImageTile | typeof MaskLayer | typeof RasterRGBTile | typeof RasterTerrainRGBTile | typeof RasterTile | typeof VectorTile;
|
|
11
11
|
export * from '../interface';
|
|
12
12
|
export * from './Tile';
|
package/lib/core/interface.d.ts
CHANGED
|
@@ -139,6 +139,17 @@ function PointExtrudeTriangulation(feature) {
|
|
|
139
139
|
* @param feature 映射feature
|
|
140
140
|
*/
|
|
141
141
|
function PointImageTriangulation(feature) {
|
|
142
|
+
// @ts-ignore
|
|
143
|
+
const that = this;
|
|
144
|
+
const id = feature.id;
|
|
145
|
+
// 当 imageFilterMap 存在且该 feature 未通过碰撞检测时,返回空几何(等效隐藏)
|
|
146
|
+
if (that !== null && that !== void 0 && that.imageFilterMap && !that.imageFilterMap[id]) {
|
|
147
|
+
return {
|
|
148
|
+
vertices: [],
|
|
149
|
+
indices: [],
|
|
150
|
+
size: 3
|
|
151
|
+
};
|
|
152
|
+
}
|
|
142
153
|
const coordinates = (0, _l7Utils.calculateCentroid)(feature.coordinates);
|
|
143
154
|
return {
|
|
144
155
|
vertices: [...coordinates],
|
package/lib/plugins/index.d.ts
CHANGED
|
@@ -12,4 +12,4 @@ import RegisterStyleAttributePlugin from './RegisterStyleAttributePlugin';
|
|
|
12
12
|
import ShaderUniformPlugin from './ShaderUniformPlugin';
|
|
13
13
|
import UpdateModelPlugin from './UpdateModelPlugin';
|
|
14
14
|
import UpdateStyleAttributePlugin from './UpdateStyleAttributePlugin';
|
|
15
|
-
export declare function createPlugins(): (
|
|
15
|
+
export declare function createPlugins(): (DataMappingPlugin | DataSourcePlugin | FeatureScalePlugin | LayerAnimateStylePlugin | LayerMaskPlugin | LayerModelPlugin | LayerStylePlugin | LightingPlugin | MultiPassRendererPlugin | PixelPickingPlugin | RegisterStyleAttributePlugin | ShaderUniformPlugin | UpdateModelPlugin | UpdateStyleAttributePlugin)[];
|
package/lib/point/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ILayer, ILayerConfig } from '@antv/l7-core';
|
|
1
2
|
import BaseLayer from '../core/BaseLayer';
|
|
2
3
|
import type { IPointLayerStyleOptions } from '../core/interface';
|
|
3
4
|
import type { PointType } from './models/index';
|
|
@@ -17,6 +18,7 @@ export default class PointLayer extends BaseLayer<IPointLayerStyleOptions> {
|
|
|
17
18
|
};
|
|
18
19
|
buildModels(): Promise<void>;
|
|
19
20
|
rebuildModels(): Promise<void>;
|
|
21
|
+
style(options: Partial<IPointLayerStyleOptions> & Partial<ILayerConfig>): ILayer;
|
|
20
22
|
/**
|
|
21
23
|
* 在未传入数据的时候判断点图层的 shape 类型
|
|
22
24
|
* @returns
|
package/lib/point/index.js
CHANGED
|
@@ -44,6 +44,16 @@ class PointLayer extends _BaseLayer.default {
|
|
|
44
44
|
yield _this2.buildModels();
|
|
45
45
|
})();
|
|
46
46
|
}
|
|
47
|
+
style(options) {
|
|
48
|
+
super.style(options);
|
|
49
|
+
// allowOverlap 依赖 needUpdate() 感知变化并重建 model,而 needUpdate() 仅在渲染帧的
|
|
50
|
+
// beforeRender 钩子中被调用。style() 本身不触发渲染,因此在 allowOverlap 出现时
|
|
51
|
+
// 主动触发一次 reRender,确保静止地图下也能即时生效。
|
|
52
|
+
if ('allowOverlap' in options) {
|
|
53
|
+
this.reRender();
|
|
54
|
+
}
|
|
55
|
+
return this;
|
|
56
|
+
}
|
|
47
57
|
|
|
48
58
|
/**
|
|
49
59
|
* 在未传入数据的时候判断点图层的 shape 类型
|
package/lib/point/models/fill.js
CHANGED
|
@@ -57,7 +57,7 @@ class FillModel extends _BaseModel.default {
|
|
|
57
57
|
} = this.layer.getLayerConfig();
|
|
58
58
|
return {
|
|
59
59
|
u_animate: this.animateOption2Array(animateOption),
|
|
60
|
-
u_time: this.layer.getLayerAnimateTime()
|
|
60
|
+
u_time: animateOption.enable ? this.layer.getLayerAnimateTime() : -1.0
|
|
61
61
|
};
|
|
62
62
|
}
|
|
63
63
|
getAttribute() {
|
|
@@ -17,6 +17,12 @@ export default class ImageModel extends BaseModel {
|
|
|
17
17
|
UV: number;
|
|
18
18
|
};
|
|
19
19
|
private texture;
|
|
20
|
+
imageFilterMap: {
|
|
21
|
+
[key: number]: boolean;
|
|
22
|
+
} | null;
|
|
23
|
+
private currentZoom;
|
|
24
|
+
private extent;
|
|
25
|
+
private preAllowOverlap;
|
|
20
26
|
getUninforms(): IModelUniform;
|
|
21
27
|
protected getCommonUniformsInfo(): {
|
|
22
28
|
uniformsArray: number[];
|
|
@@ -26,8 +32,17 @@ export default class ImageModel extends BaseModel {
|
|
|
26
32
|
};
|
|
27
33
|
};
|
|
28
34
|
initModels(): Promise<IModel[]>;
|
|
29
|
-
clearModels(): void;
|
|
30
35
|
buildModels(): Promise<IModel[]>;
|
|
36
|
+
needUpdate(): Promise<boolean>;
|
|
37
|
+
clearModels(): void;
|
|
31
38
|
protected registerBuiltinAttributes(): void;
|
|
39
|
+
/**
|
|
40
|
+
* 图标碰撞避让:遍历所有 feature,在屏幕空间做 AABB 碰撞检测,
|
|
41
|
+
* 将通过检测的 feature id 写入 imageFilterMap。
|
|
42
|
+
* PointImageTriangulation 绑定 this 后,会跳过不在 map 中的 feature。
|
|
43
|
+
*/
|
|
44
|
+
private filterImages;
|
|
45
|
+
private imageExtent;
|
|
46
|
+
private reBuildModel;
|
|
32
47
|
private updateTexture;
|
|
33
48
|
}
|
|
@@ -9,8 +9,10 @@ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/
|
|
|
9
9
|
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
|
|
10
10
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
11
11
|
var _l7Core = require("@antv/l7-core");
|
|
12
|
+
var _l7Utils = require("@antv/l7-utils");
|
|
12
13
|
var _BaseModel = _interopRequireDefault(require("../../core/BaseModel"));
|
|
13
14
|
var _triangulation = require("../../core/triangulation");
|
|
15
|
+
var _collisionIndex = _interopRequireDefault(require("../../utils/collision-index"));
|
|
14
16
|
/* babel-plugin-inline-import '../shaders/image/image_frag.glsl' */
|
|
15
17
|
const pointImageFrag = "layout(std140) uniform commonUniforms {\n vec2 u_textSize;\n float u_raisingHeight;\n float u_heightfixed;\n};\n\nuniform sampler2D u_texture;\n\nin vec4 v_color;\nin vec2 v_uv;\nin float v_opacity;\n\n#pragma include \"picking\"\n\nout vec4 outputColor;\n\nvoid main() {\n vec2 pos = v_uv / u_textSize + gl_PointCoord / u_textSize * 64.0;\n vec4 textureColor;\n\n // Y = 0.299R + 0.587G + 0.114B // \u4EAE\u5EA6\u63D0\u53D6\n\n textureColor = texture(SAMPLER_2D(u_texture), pos);\n\n // Tip: \u53BB\u9664\u8FB9\u7F18\u90E8\u5206 mipmap \u5BFC\u81F4\u7684\u6DF7\u5408\u53D8\u6697\n float fragmengTocenter = distance(vec2(0.5), gl_PointCoord);\n if (fragmengTocenter >= 0.5) {\n float luma = 0.299 * textureColor.r + 0.587 * textureColor.g + 0.114 * textureColor.b;\n textureColor.a *= luma;\n }\n\n if (\n all(lessThan(v_color, vec4(1.0 + 0.00001))) && all(greaterThan(v_color, vec4(1.0 - 0.00001))) ||\n v_color == vec4(1.0)\n ) {\n outputColor = textureColor;\n } else {\n outputColor = step(0.01, textureColor.z) * v_color;\n }\n outputColor.a *= v_opacity;\n if (outputColor.a < 0.01) {\n discard;\n }\n outputColor = filterColor(outputColor);\n}\n";
|
|
16
18
|
/* babel-plugin-inline-import '../shaders/image/image_vert.glsl' */
|
|
@@ -19,6 +21,11 @@ class ImageModel extends _BaseModel.default {
|
|
|
19
21
|
constructor(...args) {
|
|
20
22
|
super(...args);
|
|
21
23
|
(0, _defineProperty2.default)(this, "texture", void 0);
|
|
24
|
+
// 通过碰撞检测的 feature id 集合,由 filterImages() 填充;null 表示不启用过滤(allowOverlap: true)
|
|
25
|
+
(0, _defineProperty2.default)(this, "imageFilterMap", null);
|
|
26
|
+
(0, _defineProperty2.default)(this, "currentZoom", -1);
|
|
27
|
+
(0, _defineProperty2.default)(this, "extent", void 0);
|
|
28
|
+
(0, _defineProperty2.default)(this, "preAllowOverlap", true);
|
|
22
29
|
(0, _defineProperty2.default)(this, "updateTexture", () => {
|
|
23
30
|
const {
|
|
24
31
|
createTexture2D
|
|
@@ -85,25 +92,35 @@ class ImageModel extends _BaseModel.default {
|
|
|
85
92
|
initModels() {
|
|
86
93
|
var _this = this;
|
|
87
94
|
return (0, _asyncToGenerator2.default)(function* () {
|
|
95
|
+
const {
|
|
96
|
+
allowOverlap = true
|
|
97
|
+
} = _this.layer.getLayerConfig();
|
|
98
|
+
_this.extent = _this.imageExtent();
|
|
99
|
+
_this.preAllowOverlap = allowOverlap;
|
|
88
100
|
_this.iconService.on('imageUpdate', _this.updateTexture);
|
|
89
101
|
_this.updateTexture();
|
|
90
102
|
return _this.buildModels();
|
|
91
103
|
})();
|
|
92
104
|
}
|
|
93
|
-
clearModels() {
|
|
94
|
-
var _this$texture2;
|
|
95
|
-
(_this$texture2 = this.texture) === null || _this$texture2 === void 0 || _this$texture2.destroy();
|
|
96
|
-
this.iconService.off('imageUpdate', this.updateTexture);
|
|
97
|
-
}
|
|
98
105
|
buildModels() {
|
|
99
106
|
var _this2 = this;
|
|
100
107
|
return (0, _asyncToGenerator2.default)(function* () {
|
|
108
|
+
const {
|
|
109
|
+
allowOverlap = true
|
|
110
|
+
} = _this2.layer.getLayerConfig();
|
|
101
111
|
_this2.initUniformsBuffer();
|
|
112
|
+
if (!allowOverlap) {
|
|
113
|
+
_this2.filterImages();
|
|
114
|
+
} else {
|
|
115
|
+
// 允许压盖时置 null,PointImageTriangulation 检测到 null 则跳过过滤
|
|
116
|
+
_this2.imageFilterMap = null;
|
|
117
|
+
}
|
|
102
118
|
const model = yield _this2.layer.buildLayerModel({
|
|
103
119
|
moduleName: 'pointImage',
|
|
104
120
|
vertexShader: pointImageVert,
|
|
105
121
|
fragmentShader: pointImageFrag,
|
|
106
|
-
|
|
122
|
+
// 绑定 this,让 PointImageTriangulation 能读取 imageFilterMap
|
|
123
|
+
triangulation: _triangulation.PointImageTriangulation.bind(_this2),
|
|
107
124
|
defines: _this2.getDefines(),
|
|
108
125
|
inject: _this2.getInject(),
|
|
109
126
|
depth: {
|
|
@@ -114,6 +131,41 @@ class ImageModel extends _BaseModel.default {
|
|
|
114
131
|
return [model];
|
|
115
132
|
})();
|
|
116
133
|
}
|
|
134
|
+
needUpdate() {
|
|
135
|
+
var _this3 = this;
|
|
136
|
+
return (0, _asyncToGenerator2.default)(function* () {
|
|
137
|
+
const {
|
|
138
|
+
allowOverlap = true
|
|
139
|
+
} = _this3.layer.getLayerConfig();
|
|
140
|
+
|
|
141
|
+
// allowOverlap 开关发生变化时,强制重建
|
|
142
|
+
if (allowOverlap !== _this3.preAllowOverlap) {
|
|
143
|
+
_this3.preAllowOverlap = allowOverlap;
|
|
144
|
+
yield _this3.reBuildModel();
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// 允许压盖时无需每帧检测
|
|
149
|
+
if (allowOverlap) {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// 不允许压盖时,zoom 变化 >0.5 或视野超出上次范围则重算碰撞
|
|
154
|
+
const zoom = _this3.mapService.getZoom();
|
|
155
|
+
const extent = _this3.mapService.getBounds();
|
|
156
|
+
const flag = (0, _l7Utils.boundsContains)(_this3.extent, extent);
|
|
157
|
+
if (Math.abs(_this3.currentZoom - zoom) > 0.5 || !flag) {
|
|
158
|
+
yield _this3.reBuildModel();
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
return false;
|
|
162
|
+
})();
|
|
163
|
+
}
|
|
164
|
+
clearModels() {
|
|
165
|
+
var _this$texture2;
|
|
166
|
+
(_this$texture2 = this.texture) === null || _this$texture2 === void 0 || _this$texture2.destroy();
|
|
167
|
+
this.iconService.off('imageUpdate', this.updateTexture);
|
|
168
|
+
}
|
|
117
169
|
registerBuiltinAttributes() {
|
|
118
170
|
// 注册 Position 属性 64 位地位部分,经纬度数据开启双精度,避免大于 20层级以上出现数据偏移
|
|
119
171
|
this.registerPosition64LowAttribute();
|
|
@@ -172,5 +224,78 @@ class ImageModel extends _BaseModel.default {
|
|
|
172
224
|
}
|
|
173
225
|
});
|
|
174
226
|
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* 图标碰撞避让:遍历所有 feature,在屏幕空间做 AABB 碰撞检测,
|
|
230
|
+
* 将通过检测的 feature id 写入 imageFilterMap。
|
|
231
|
+
* PointImageTriangulation 绑定 this 后,会跳过不在 map 中的 feature。
|
|
232
|
+
*/
|
|
233
|
+
filterImages() {
|
|
234
|
+
const {
|
|
235
|
+
padding = [0, 0]
|
|
236
|
+
} = this.layer.getLayerConfig();
|
|
237
|
+
this.imageFilterMap = {};
|
|
238
|
+
this.currentZoom = this.mapService.getZoom();
|
|
239
|
+
this.extent = this.imageExtent();
|
|
240
|
+
const {
|
|
241
|
+
width,
|
|
242
|
+
height
|
|
243
|
+
} = this.rendererService.getViewportSize();
|
|
244
|
+
const collisionIndex = new _collisionIndex.default(width, height);
|
|
245
|
+
const data = this.layer.getEncodedData();
|
|
246
|
+
data.forEach(feature => {
|
|
247
|
+
const {
|
|
248
|
+
id = 0,
|
|
249
|
+
size = 5
|
|
250
|
+
} = feature;
|
|
251
|
+
const iconSize = Array.isArray(size) ? size[0] : size;
|
|
252
|
+
const centroid = (0, _l7Utils.calculateCentroid)(feature.coordinates);
|
|
253
|
+
const pixels = this.mapService.lngLatToContainer(centroid);
|
|
254
|
+
const {
|
|
255
|
+
box
|
|
256
|
+
} = collisionIndex.placeCollisionBox({
|
|
257
|
+
x1: -iconSize - padding[0],
|
|
258
|
+
x2: iconSize + padding[0],
|
|
259
|
+
y1: -iconSize - padding[1],
|
|
260
|
+
y2: iconSize + padding[1],
|
|
261
|
+
anchorPointX: pixels.x,
|
|
262
|
+
anchorPointY: pixels.y
|
|
263
|
+
});
|
|
264
|
+
if (box && box.length) {
|
|
265
|
+
collisionIndex.insertCollisionBox(box, id);
|
|
266
|
+
this.imageFilterMap[id] = true;
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
imageExtent() {
|
|
271
|
+
const bounds = this.mapService.getBounds();
|
|
272
|
+
return (0, _l7Utils.padBounds)(bounds, 0.5);
|
|
273
|
+
}
|
|
274
|
+
reBuildModel() {
|
|
275
|
+
var _this4 = this;
|
|
276
|
+
return (0, _asyncToGenerator2.default)(function* () {
|
|
277
|
+
const {
|
|
278
|
+
allowOverlap = true
|
|
279
|
+
} = _this4.layer.getLayerConfig();
|
|
280
|
+
if (!allowOverlap) {
|
|
281
|
+
_this4.filterImages();
|
|
282
|
+
} else {
|
|
283
|
+
_this4.imageFilterMap = null; // 允许压盖:清空过滤表,全量渲染
|
|
284
|
+
}
|
|
285
|
+
const model = yield _this4.layer.buildLayerModel({
|
|
286
|
+
moduleName: 'pointImage',
|
|
287
|
+
vertexShader: pointImageVert,
|
|
288
|
+
fragmentShader: pointImageFrag,
|
|
289
|
+
triangulation: _triangulation.PointImageTriangulation.bind(_this4),
|
|
290
|
+
defines: _this4.getDefines(),
|
|
291
|
+
inject: _this4.getInject(),
|
|
292
|
+
depth: {
|
|
293
|
+
enable: false
|
|
294
|
+
},
|
|
295
|
+
primitive: _l7Core.gl.POINTS
|
|
296
|
+
});
|
|
297
|
+
_this4.layer.models = [model];
|
|
298
|
+
})();
|
|
299
|
+
}
|
|
175
300
|
}
|
|
176
301
|
exports.default = ImageModel;
|
package/lib/tile/tile/Tile.d.ts
CHANGED
|
@@ -47,7 +47,7 @@ export default abstract class Tile extends EventEmitter implements ITile {
|
|
|
47
47
|
enablePropagation?: boolean | undefined;
|
|
48
48
|
fitBoundsOptions?: unknown;
|
|
49
49
|
name?: string | undefined;
|
|
50
|
-
blend?: "
|
|
50
|
+
blend?: "min" | "max" | "normal" | "additive" | "subtractive" | "none" | undefined;
|
|
51
51
|
depth?: boolean | undefined;
|
|
52
52
|
pickedFeatureID?: number | undefined;
|
|
53
53
|
enableMultiPassRenderer?: boolean | undefined;
|
package/lib/tile/tile/index.d.ts
CHANGED
|
@@ -7,6 +7,6 @@ import RasterTerrainRGBTile from './RasterTerrainRGBTile';
|
|
|
7
7
|
import RasterTile from './RasterTile';
|
|
8
8
|
import VectorTile from './VectorTile';
|
|
9
9
|
export type TileType = 'VectorTile' | 'DebugTile' | 'PolygonLayer' | 'PointLayer' | 'LineLayer' | 'RasterLayer' | 'image' | 'MaskLayer' | 'TileDebugLayer';
|
|
10
|
-
export declare function getTileFactory(layer: ILayer): typeof DebugTile | typeof ImageTile | typeof
|
|
10
|
+
export declare function getTileFactory(layer: ILayer): typeof DebugTile | typeof ImageTile | typeof MaskLayer | typeof RasterRGBTile | typeof RasterTerrainRGBTile | typeof RasterTile | typeof VectorTile;
|
|
11
11
|
export * from '../interface';
|
|
12
12
|
export * from './Tile';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antv/l7-layers",
|
|
3
|
-
"version": "2.24.
|
|
3
|
+
"version": "2.24.2",
|
|
4
4
|
"description": "L7's collection of built-in layers",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "https://github.com/orgs/antvis/people",
|
|
@@ -26,15 +26,15 @@
|
|
|
26
26
|
"earcut": "^2.2.1",
|
|
27
27
|
"eventemitter3": "^4.0.0",
|
|
28
28
|
"gl-matrix": "^3.1.0",
|
|
29
|
-
"@antv/l7-maps": "2.24.
|
|
30
|
-
"@antv/l7-
|
|
31
|
-
"@antv/l7-core": "2.24.
|
|
32
|
-
"@antv/l7-
|
|
29
|
+
"@antv/l7-maps": "2.24.2",
|
|
30
|
+
"@antv/l7-source": "2.24.2",
|
|
31
|
+
"@antv/l7-core": "2.24.2",
|
|
32
|
+
"@antv/l7-utils": "2.24.2"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/earcut": "^2.1.0",
|
|
36
36
|
"@types/gl-matrix": "^2.4.5",
|
|
37
|
-
"@antv/l7-test-utils": "^2.24.
|
|
37
|
+
"@antv/l7-test-utils": "^2.24.2"
|
|
38
38
|
},
|
|
39
39
|
"publishConfig": {
|
|
40
40
|
"access": "public",
|