@antv/l7-layers 2.23.2 → 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.
- package/es/{citybuliding → citybuilding}/models/build.js +4 -2
- package/es/core/BaseLayer.js +3 -3
- package/es/core/LayerPickService.js +3 -1
- package/es/core/shape/Path.d.ts +2 -1
- package/es/core/shape/Path.js +10 -4
- package/es/core/triangulation.js +51 -1
- package/es/earth/index.js +2 -3
- package/es/geometry/index.js +2 -3
- package/es/heatmap/index.js +6 -6
- package/es/heatmap/models/heatmap.js +2 -3
- package/es/index.d.ts +1 -1
- package/es/index.js +1 -1
- package/es/line/index.js +2 -3
- package/es/plugins/DataMappingPlugin.js +30 -10
- package/es/plugins/FeatureScalePlugin.js +21 -20
- package/es/plugins/ShaderUniformPlugin.js +62 -29
- package/es/polygon/index.js +2 -3
- package/es/polygon/models/extrude.js +22 -7
- package/es/polygon/models/ocean.js +17 -6
- package/es/polygon/models/water.js +17 -6
- package/es/tile/core/BaseLayer.d.ts +4 -1
- package/es/tile/core/BaseLayer.js +19 -11
- package/es/tile/service/TileLayerService.d.ts +26 -1
- package/es/tile/service/TileLayerService.js +88 -16
- package/es/tile/service/TilePickService.js +15 -9
- package/es/utils/scale.d.ts +87 -0
- package/es/utils/scale.js +588 -0
- package/lib/{citybuliding → citybuilding}/models/build.js +4 -2
- package/lib/core/BaseLayer.js +3 -3
- package/lib/core/LayerPickService.js +3 -1
- package/lib/core/shape/Path.d.ts +2 -1
- package/lib/core/shape/Path.js +10 -4
- package/lib/core/triangulation.js +50 -1
- package/lib/earth/index.js +2 -3
- package/lib/geometry/index.js +2 -3
- package/lib/heatmap/index.js +6 -6
- package/lib/heatmap/models/heatmap.js +2 -3
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/line/index.js +2 -3
- package/lib/plugins/DataMappingPlugin.js +30 -10
- package/lib/plugins/FeatureScalePlugin.js +22 -23
- package/lib/plugins/ShaderUniformPlugin.js +62 -29
- package/lib/polygon/index.js +2 -3
- package/lib/polygon/models/extrude.js +22 -7
- package/lib/polygon/models/ocean.js +17 -6
- package/lib/polygon/models/water.js +17 -6
- package/lib/tile/core/BaseLayer.d.ts +4 -1
- package/lib/tile/core/BaseLayer.js +19 -11
- package/lib/tile/service/TileLayerService.d.ts +26 -1
- package/lib/tile/service/TileLayerService.js +88 -16
- package/lib/tile/service/TilePickService.js +15 -9
- package/lib/utils/scale.d.ts +87 -0
- package/lib/utils/scale.js +603 -0
- package/package.json +6 -17
- /package/es/{citybuliding → citybuilding}/building.d.ts +0 -0
- /package/es/{citybuliding → citybuilding}/building.js +0 -0
- /package/es/{citybuliding → citybuilding}/models/build.d.ts +0 -0
- /package/es/{citybuliding → citybuilding}/shaders/build_frag.glsl +0 -0
- /package/es/{citybuliding → citybuilding}/shaders/build_vert.glsl +0 -0
- /package/lib/{citybuliding → citybuilding}/building.d.ts +0 -0
- /package/lib/{citybuliding → citybuilding}/building.js +0 -0
- /package/lib/{citybuliding → citybuilding}/models/build.d.ts +0 -0
- /package/lib/{citybuliding → citybuilding}/shaders/build_frag.glsl +0 -0
- /package/lib/{citybuliding → citybuilding}/shaders/build_vert.glsl +0 -0
|
@@ -55,8 +55,10 @@ export default class CityBuildModel extends BaseModel {
|
|
|
55
55
|
return commonBufferInfo;
|
|
56
56
|
}
|
|
57
57
|
calCityGeo() {
|
|
58
|
-
//
|
|
59
|
-
const
|
|
58
|
+
// 当启用 enableRelativeCoordinates 时,使用 originalExtent(原始绝对坐标范围)
|
|
59
|
+
const originalExtent = this.layer.getOriginalExtent();
|
|
60
|
+
const extent = originalExtent[0] !== 0 || originalExtent[2] !== 0 ? originalExtent : this.layer.getSource().extent;
|
|
61
|
+
const [minLng, minLat, maxLng, maxLat] = extent;
|
|
60
62
|
const w = maxLng - minLng;
|
|
61
63
|
const h = maxLat - minLat;
|
|
62
64
|
this.cityCenter = [(maxLng + minLng) / 2, (maxLat + minLat) / 2];
|
package/es/core/BaseLayer.js
CHANGED
|
@@ -961,12 +961,12 @@ export default class BaseLayer extends EventEmitter {
|
|
|
961
961
|
return this.styleAttributeService.getLayerAttributeScale(name);
|
|
962
962
|
}
|
|
963
963
|
getLegend(name) {
|
|
964
|
-
var _attribute$scale, _scales$,
|
|
964
|
+
var _attribute$scale, _scales$, _scales$2;
|
|
965
965
|
const attribute = this.styleAttributeService.getLayerStyleAttribute(name);
|
|
966
966
|
const scales = (attribute === null || attribute === void 0 || (_attribute$scale = attribute.scale) === null || _attribute$scale === void 0 ? void 0 : _attribute$scale.scalers) || [];
|
|
967
967
|
return {
|
|
968
968
|
type: (_scales$ = scales[0]) === null || _scales$ === void 0 || (_scales$ = _scales$.option) === null || _scales$ === void 0 ? void 0 : _scales$.type,
|
|
969
|
-
field:
|
|
969
|
+
field: (_scales$2 = scales[0]) === null || _scales$2 === void 0 ? void 0 : _scales$2.field,
|
|
970
970
|
items: this.getLegendItems(name)
|
|
971
971
|
};
|
|
972
972
|
}
|
|
@@ -1210,7 +1210,7 @@ export default class BaseLayer extends EventEmitter {
|
|
|
1210
1210
|
* 继承空方法
|
|
1211
1211
|
* @param time
|
|
1212
1212
|
*/
|
|
1213
|
-
|
|
1213
|
+
|
|
1214
1214
|
setEarthTime(time) {
|
|
1215
1215
|
console.warn('empty fn');
|
|
1216
1216
|
}
|
|
@@ -39,7 +39,9 @@ export default class BaseLayerPickService {
|
|
|
39
39
|
const container = this.layer.getContainer();
|
|
40
40
|
const pickingService = container.pickingService;
|
|
41
41
|
const mapService = container.mapService;
|
|
42
|
-
|
|
42
|
+
// 当启用 enableRelativeCoordinates 时,使用 originalExtent 判断绝对坐标是否在范围内
|
|
43
|
+
const originalExtent = this.layer.getOriginalExtent();
|
|
44
|
+
const extent = originalExtent[0] !== 0 || originalExtent[2] !== 0 ? originalExtent : this.layer.getSource().extent;
|
|
43
45
|
const isPick = lngLatInExtent(target.lngLat, extent);
|
|
44
46
|
const layerTarget = {
|
|
45
47
|
x: target.x,
|
package/es/core/shape/Path.d.ts
CHANGED
|
@@ -18,8 +18,9 @@ export declare enum ShapeType2D {
|
|
|
18
18
|
* 生成规则多边形顶点个数
|
|
19
19
|
* @param pointCount 顶点个数 3 => 三角形
|
|
20
20
|
* @param start 顶点起始角度 调整图形的方向
|
|
21
|
+
* @param angleOffset 额外的角度偏移,用于调整六边形方向
|
|
21
22
|
*/
|
|
22
|
-
export declare function polygonPath(pointCount: number, start?: number): IPath;
|
|
23
|
+
export declare function polygonPath(pointCount: number, start?: number, angleOffset?: number): IPath;
|
|
23
24
|
export declare function circle(): IPath;
|
|
24
25
|
export declare function square(): IPath;
|
|
25
26
|
export declare function triangle(): IPath;
|
package/es/core/shape/Path.js
CHANGED
|
@@ -19,16 +19,17 @@ export let ShapeType2D = /*#__PURE__*/function (ShapeType2D) {
|
|
|
19
19
|
* 生成规则多边形顶点个数
|
|
20
20
|
* @param pointCount 顶点个数 3 => 三角形
|
|
21
21
|
* @param start 顶点起始角度 调整图形的方向
|
|
22
|
+
* @param angleOffset 额外的角度偏移,用于调整六边形方向
|
|
22
23
|
*/
|
|
23
|
-
export function polygonPath(pointCount, start = 0) {
|
|
24
|
+
export function polygonPath(pointCount, start = 0, angleOffset = Math.PI / 4) {
|
|
24
25
|
const step = Math.PI * 2 / pointCount;
|
|
25
26
|
const line = [];
|
|
26
27
|
for (let i = 0; i < pointCount; i++) {
|
|
27
28
|
line.push(step * i + start * Math.PI / 12);
|
|
28
29
|
}
|
|
29
30
|
const path = line.map(t => {
|
|
30
|
-
const x = Math.sin(t +
|
|
31
|
-
const y = Math.cos(t +
|
|
31
|
+
const x = Math.sin(t + angleOffset);
|
|
32
|
+
const y = Math.cos(t + angleOffset);
|
|
32
33
|
return [x, y, 0];
|
|
33
34
|
});
|
|
34
35
|
// path.push(path[0]);
|
|
@@ -44,7 +45,12 @@ export function triangle() {
|
|
|
44
45
|
return polygonPath(3);
|
|
45
46
|
}
|
|
46
47
|
export function hexagon() {
|
|
47
|
-
|
|
48
|
+
// 生成 pointy-top 六边形(尖角朝上)
|
|
49
|
+
// 使用 angleOffset = 0 并翻转 y 方向,以匹配 d3-hexbin 的方向
|
|
50
|
+
// d3-hexbin 在屏幕坐标系中 y 向下为正,使用 y = -cos(angle)
|
|
51
|
+
// 我们需要翻转 y 坐标以确保蜂窝网格闭合
|
|
52
|
+
const path = polygonPath(6, 0, 0);
|
|
53
|
+
return path.map(p => [p[0], -p[1], p[2]]);
|
|
48
54
|
}
|
|
49
55
|
export function pentagon() {
|
|
50
56
|
return polygonPath(5);
|
package/es/core/triangulation.js
CHANGED
|
@@ -7,6 +7,56 @@ import ExtrudePolyline from "../utils/extrude_polyline";
|
|
|
7
7
|
import { geometryShape } from "./shape/Path";
|
|
8
8
|
import extrudePolygon, { extrude_PolygonNormal, fillPolygon } from "./shape/extrude";
|
|
9
9
|
import { getPolygonSurfaceIndices } from "./utils";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 质心计算缓存
|
|
13
|
+
* 避免对相同坐标的重复计算
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const centroidCache = {};
|
|
17
|
+
const CENTROID_CACHE_MAX_SIZE = 500;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 生成坐标的缓存键
|
|
21
|
+
*/
|
|
22
|
+
function getCoordinateKey(coordinates) {
|
|
23
|
+
if (typeof coordinates === 'number') {
|
|
24
|
+
return String(coordinates);
|
|
25
|
+
}
|
|
26
|
+
if (Array.isArray(coordinates)) {
|
|
27
|
+
if (typeof coordinates[0] === 'number') {
|
|
28
|
+
return coordinates.slice(0, 2).join(',');
|
|
29
|
+
}
|
|
30
|
+
// 对于嵌套数组,取第一个点
|
|
31
|
+
return getCoordinateKey(coordinates[0]);
|
|
32
|
+
}
|
|
33
|
+
return '';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* 带缓存的质心计算
|
|
38
|
+
*/
|
|
39
|
+
function cachedCalculateCentroid(coordinates) {
|
|
40
|
+
const key = getCoordinateKey(coordinates);
|
|
41
|
+
if (key && centroidCache[key]) {
|
|
42
|
+
return centroidCache[key].slice();
|
|
43
|
+
}
|
|
44
|
+
const centroid = calculateCentroid(coordinates);
|
|
45
|
+
|
|
46
|
+
// 限制缓存大小
|
|
47
|
+
const keys = Object.keys(centroidCache);
|
|
48
|
+
if (keys.length >= CENTROID_CACHE_MAX_SIZE) {
|
|
49
|
+
// 删除一半的缓存
|
|
50
|
+
const deleteCount = Math.floor(CENTROID_CACHE_MAX_SIZE / 2);
|
|
51
|
+
for (let i = 0; i < deleteCount; i++) {
|
|
52
|
+
delete centroidCache[keys[i]];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (key) {
|
|
56
|
+
centroidCache[key] = centroid.slice();
|
|
57
|
+
}
|
|
58
|
+
return centroid;
|
|
59
|
+
}
|
|
10
60
|
const GeometryCache = {};
|
|
11
61
|
|
|
12
62
|
/**
|
|
@@ -15,7 +65,7 @@ const GeometryCache = {};
|
|
|
15
65
|
*/
|
|
16
66
|
|
|
17
67
|
export function PointFillTriangulation(feature) {
|
|
18
|
-
const coordinates =
|
|
68
|
+
const coordinates = cachedCalculateCentroid(feature.coordinates);
|
|
19
69
|
return {
|
|
20
70
|
vertices: [...coordinates, ...coordinates, ...coordinates, ...coordinates],
|
|
21
71
|
indices: [0, 1, 2, 2, 3, 0],
|
package/es/earth/index.js
CHANGED
|
@@ -44,9 +44,8 @@ export default class EarthLayer extends BaseLayer {
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
getModelType() {
|
|
47
|
-
var
|
|
48
|
-
|
|
49
|
-
let shape = (shapeAttribute === null || shapeAttribute === void 0 || (_shapeAttribute$scale = shapeAttribute.scale) === null || _shapeAttribute$scale === void 0 ? void 0 : _shapeAttribute$scale.field) || 'base';
|
|
47
|
+
var _this$shapeOption;
|
|
48
|
+
let shape = ((_this$shapeOption = this.shapeOption) === null || _this$shapeOption === void 0 ? void 0 : _this$shapeOption.field) || 'base';
|
|
50
49
|
if (earthLayerTypes.indexOf(shape) < 0) {
|
|
51
50
|
shape = 'base';
|
|
52
51
|
}
|
package/es/geometry/index.js
CHANGED
|
@@ -38,9 +38,8 @@ export default class GeometryLayer extends BaseLayer {
|
|
|
38
38
|
return defaultConfig[type];
|
|
39
39
|
}
|
|
40
40
|
getModelType() {
|
|
41
|
-
var
|
|
42
|
-
const
|
|
43
|
-
const shape = shapeAttribute === null || shapeAttribute === void 0 || (_shapeAttribute$scale = shapeAttribute.scale) === null || _shapeAttribute$scale === void 0 ? void 0 : _shapeAttribute$scale.field;
|
|
41
|
+
var _this$shapeOption;
|
|
42
|
+
const shape = (_this$shapeOption = this.shapeOption) === null || _this$shapeOption === void 0 ? void 0 : _this$shapeOption.field;
|
|
44
43
|
if (shape === 'plane') {
|
|
45
44
|
return 'plane';
|
|
46
45
|
} else if (shape === 'sprite') {
|
package/es/heatmap/index.js
CHANGED
|
@@ -52,22 +52,22 @@ export default class HeatMapLayer extends BaseLayer {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
getModelType() {
|
|
55
|
-
var
|
|
56
|
-
const shapeAttribute = this.styleAttributeService.getLayerStyleAttribute('shape');
|
|
55
|
+
var _source$data, _this$shapeOption;
|
|
57
56
|
const {
|
|
58
57
|
shape3d
|
|
59
58
|
} = this.getLayerConfig();
|
|
60
59
|
const source = this.getSource();
|
|
61
|
-
const sourceType = source.data.type;
|
|
62
|
-
const shape = (
|
|
60
|
+
const sourceType = source === null || source === void 0 || (_source$data = source.data) === null || _source$data === void 0 ? void 0 : _source$data.type;
|
|
61
|
+
const shape = ((_this$shapeOption = this.shapeOption) === null || _this$shapeOption === void 0 ? void 0 : _this$shapeOption.field) || 'heatmap';
|
|
62
|
+
const isShape3D = Array.isArray(shape3d) && shape3d.includes(shape);
|
|
63
63
|
if (shape === 'heatmap' || shape === 'heatmap3d') {
|
|
64
64
|
return 'heatmap';
|
|
65
65
|
}
|
|
66
66
|
if (sourceType === 'hexagon') {
|
|
67
|
-
return
|
|
67
|
+
return isShape3D ? 'grid3d' : 'hexagon';
|
|
68
68
|
}
|
|
69
69
|
if (sourceType === 'grid') {
|
|
70
|
-
return
|
|
70
|
+
return isShape3D ? 'grid3d' : 'grid';
|
|
71
71
|
}
|
|
72
72
|
return 'heatmap';
|
|
73
73
|
}
|
|
@@ -75,14 +75,13 @@ export default class HeatMapModel extends BaseModel {
|
|
|
75
75
|
initModels() {
|
|
76
76
|
var _this = this;
|
|
77
77
|
return _asyncToGenerator(function* () {
|
|
78
|
-
var
|
|
78
|
+
var _this$layer$shapeOpti;
|
|
79
79
|
const {
|
|
80
80
|
createFramebuffer,
|
|
81
81
|
getViewportSize,
|
|
82
82
|
createTexture2D
|
|
83
83
|
} = _this.rendererService;
|
|
84
|
-
const
|
|
85
|
-
const shapeType = (shapeAttr === null || shapeAttr === void 0 || (_shapeAttr$scale = shapeAttr.scale) === null || _shapeAttr$scale === void 0 ? void 0 : _shapeAttr$scale.field) || 'heatmap';
|
|
84
|
+
const shapeType = ((_this$layer$shapeOpti = _this.layer.shapeOption) === null || _this$layer$shapeOpti === void 0 ? void 0 : _this$layer$shapeOpti.field) || 'heatmap';
|
|
86
85
|
_this.shapeType = shapeType;
|
|
87
86
|
// 生成热力图密度图
|
|
88
87
|
_this.intensityModel = yield _this.buildHeatMapIntensity();
|
package/es/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import CanvasLayer from './canvas';
|
|
2
|
-
import CityBuildingLayer from './
|
|
2
|
+
import CityBuildingLayer from './citybuilding/building';
|
|
3
3
|
import BaseLayer from './core/BaseLayer';
|
|
4
4
|
import BaseModel from './core/BaseModel';
|
|
5
5
|
import GeometryLayer from './geometry';
|
package/es/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import CanvasLayer from "./canvas";
|
|
2
|
-
import CityBuildingLayer from "./
|
|
2
|
+
import CityBuildingLayer from "./citybuilding/building";
|
|
3
3
|
import BaseLayer from "./core/BaseLayer";
|
|
4
4
|
import BaseModel from "./core/BaseModel";
|
|
5
5
|
import GeometryLayer from "./geometry"; // 逐步替换为 Geometry
|
package/es/line/index.js
CHANGED
|
@@ -60,12 +60,11 @@ export default class LineLayer extends BaseLayer {
|
|
|
60
60
|
return defaultConfig[type];
|
|
61
61
|
}
|
|
62
62
|
getModelType() {
|
|
63
|
-
var
|
|
63
|
+
var _this$shapeOption;
|
|
64
64
|
if (this.layerType) {
|
|
65
65
|
return this.layerType;
|
|
66
66
|
}
|
|
67
|
-
const
|
|
68
|
-
const shape = shapeAttribute === null || shapeAttribute === void 0 || (_shapeAttribute$scale = shapeAttribute.scale) === null || _shapeAttribute$scale === void 0 ? void 0 : _shapeAttribute$scale.field;
|
|
67
|
+
const shape = (_this$shapeOption = this.shapeOption) === null || _this$shapeOption === void 0 ? void 0 : _this$shapeOption.field;
|
|
69
68
|
return shape || 'line';
|
|
70
69
|
}
|
|
71
70
|
processData(filterData) {
|
|
@@ -85,19 +85,39 @@ export default class DataMappingPlugin {
|
|
|
85
85
|
const {
|
|
86
86
|
dataArray
|
|
87
87
|
} = layer.getSource().data;
|
|
88
|
-
|
|
89
|
-
//
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
88
|
+
|
|
89
|
+
// 优化:合并过滤和准备阶段为单次遍历
|
|
90
|
+
const usedAttributes = attributes.filter(attribute => attribute.scale !== undefined).filter(attribute => attribute.name !== 'filter');
|
|
91
|
+
const hasFilter = filter === null || filter === void 0 ? void 0 : filter.scale;
|
|
92
|
+
|
|
93
|
+
// 第一阶段:过滤原始数据(需要在 processData 之前)
|
|
94
|
+
let filterData = [];
|
|
95
|
+
if (hasFilter) {
|
|
96
|
+
for (let i = 0; i < dataArray.length; i++) {
|
|
97
|
+
const record = dataArray[i];
|
|
98
|
+
const filterResult = this.applyAttributeMapping(filter, record);
|
|
99
|
+
if (filterResult[0]) {
|
|
100
|
+
filterData.push(record);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
filterData = dataArray;
|
|
94
105
|
}
|
|
95
|
-
|
|
106
|
+
|
|
107
|
+
// Tip: layer 对数据做处理(需要处理原始数据格式)
|
|
96
108
|
// 数据处理 在数据进行 mapping 生成 encodeData 之前对数据进行处理
|
|
97
|
-
|
|
109
|
+
const processedFilterData = layer.processData(filterData);
|
|
110
|
+
|
|
111
|
+
// 第二阶段:数据映射
|
|
112
|
+
const encodeData = this.mapping(layer, usedAttributes, processedFilterData, undefined);
|
|
98
113
|
|
|
99
|
-
|
|
100
|
-
|
|
114
|
+
// 重置属性状态
|
|
115
|
+
attributes.forEach(attribute => {
|
|
116
|
+
attribute.needRemapping = false;
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// 调整数据兼容 SimpleCoordinates
|
|
120
|
+
this.adjustData2SimpleCoordinates(encodeData);
|
|
101
121
|
layer.setEncodedData(encodeData);
|
|
102
122
|
|
|
103
123
|
// 对外暴露事件
|
|
@@ -2,29 +2,28 @@ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
|
|
|
2
2
|
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
|
|
3
3
|
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
|
|
4
4
|
import { IDebugLog, ILayerStage, ScaleTypes, StyleScaleType } from '@antv/l7-core';
|
|
5
|
-
import { lodashUtil } from '@antv/l7-utils';
|
|
6
|
-
import { extent } from 'd3-array';
|
|
7
|
-
import * as d3interpolate from 'd3-interpolate';
|
|
8
|
-
import * as d3 from 'd3-scale';
|
|
5
|
+
import { interpolateRgbBasis, lodashUtil } from '@antv/l7-utils';
|
|
9
6
|
import identity from "../utils/identityScale";
|
|
7
|
+
import { scaleDiverging, scaleLinear, scaleLog, scaleOrdinal, scalePow, scaleQuantile, scaleQuantize, scaleSequential, scaleThreshold, scaleTime } from "../utils/scale";
|
|
10
8
|
const {
|
|
11
9
|
isNil,
|
|
12
10
|
isString,
|
|
13
|
-
uniq
|
|
11
|
+
uniq,
|
|
12
|
+
extent
|
|
14
13
|
} = lodashUtil;
|
|
15
14
|
const dateRegex = /^(?:(?!0000)[0-9]{4}([-/.]+)(?:(?:0?[1-9]|1[0-2])\1(?:0?[1-9]|1[0-9]|2[0-8])|(?:0?[13-9]|1[0-2])\1(?:29|30)|(?:0?[13578]|1[02])\1(?:31))|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)([-/.]?)0?2\2(?:29))(\s+([01]|([01][0-9]|2[0-3])):([0-9]|[0-5][0-9]):([0-9]|[0-5][0-9]))?$/;
|
|
16
15
|
const scaleMap = {
|
|
17
|
-
[ScaleTypes.LINEAR]:
|
|
18
|
-
[ScaleTypes.POWER]:
|
|
19
|
-
[ScaleTypes.LOG]:
|
|
16
|
+
[ScaleTypes.LINEAR]: scaleLinear,
|
|
17
|
+
[ScaleTypes.POWER]: scalePow,
|
|
18
|
+
[ScaleTypes.LOG]: scaleLog,
|
|
20
19
|
[ScaleTypes.IDENTITY]: identity,
|
|
21
|
-
[ScaleTypes.SEQUENTIAL]:
|
|
22
|
-
[ScaleTypes.TIME]:
|
|
23
|
-
[ScaleTypes.QUANTILE]:
|
|
24
|
-
[ScaleTypes.QUANTIZE]:
|
|
25
|
-
[ScaleTypes.THRESHOLD]:
|
|
26
|
-
[ScaleTypes.CAT]:
|
|
27
|
-
[ScaleTypes.DIVERGING]:
|
|
20
|
+
[ScaleTypes.SEQUENTIAL]: scaleSequential,
|
|
21
|
+
[ScaleTypes.TIME]: scaleTime,
|
|
22
|
+
[ScaleTypes.QUANTILE]: scaleQuantile,
|
|
23
|
+
[ScaleTypes.QUANTIZE]: scaleQuantize,
|
|
24
|
+
[ScaleTypes.THRESHOLD]: scaleThreshold,
|
|
25
|
+
[ScaleTypes.CAT]: scaleOrdinal,
|
|
26
|
+
[ScaleTypes.DIVERGING]: scaleDiverging
|
|
28
27
|
};
|
|
29
28
|
/**
|
|
30
29
|
* 根据 Source 原始数据为指定字段创建 Scale,保存在 StyleAttribute 上,供下游插件使用
|
|
@@ -99,7 +98,6 @@ export default class FeatureScalePlugin {
|
|
|
99
98
|
if (attribute.scale) {
|
|
100
99
|
// 创建Scale
|
|
101
100
|
const attributeScale = attribute.scale;
|
|
102
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
103
101
|
const fieldValue = attribute.scale.field;
|
|
104
102
|
attributeScale.names = this.parseFields(isNil(fieldValue) ? [] : fieldValue);
|
|
105
103
|
const scales = [];
|
|
@@ -141,7 +139,7 @@ export default class FeatureScalePlugin {
|
|
|
141
139
|
case ScaleTypes.SEQUENTIAL:
|
|
142
140
|
scale.scale.interpolator(
|
|
143
141
|
// @ts-ignore
|
|
144
|
-
|
|
142
|
+
interpolateRgbBasis(attributeScale.values));
|
|
145
143
|
break;
|
|
146
144
|
}
|
|
147
145
|
}
|
|
@@ -198,16 +196,15 @@ export default class FeatureScalePlugin {
|
|
|
198
196
|
if (scaleOption && scaleOption.type) {
|
|
199
197
|
styleScale.scale = this.createDefaultScale(scaleOption);
|
|
200
198
|
} else {
|
|
201
|
-
styleScale.scale =
|
|
199
|
+
styleScale.scale = scaleOrdinal([field]);
|
|
202
200
|
styleScale.type = StyleScaleType.CONSTANT;
|
|
203
201
|
}
|
|
204
202
|
return styleScale;
|
|
205
203
|
}
|
|
206
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
207
204
|
const firstValue = (_find = data.find(d => !isNil(d[field]))) === null || _find === void 0 ? void 0 : _find[field];
|
|
208
205
|
// 常量 Scale
|
|
209
206
|
if (this.isNumber(field) || isNil(firstValue) && !scaleOption) {
|
|
210
|
-
styleScale.scale =
|
|
207
|
+
styleScale.scale = scaleOrdinal([field]);
|
|
211
208
|
styleScale.type = StyleScaleType.CONSTANT;
|
|
212
209
|
} else {
|
|
213
210
|
// 根据数据类型判断 默认等分位,时间,和枚举类型
|
|
@@ -219,6 +216,10 @@ export default class FeatureScalePlugin {
|
|
|
219
216
|
if (values === undefined) {
|
|
220
217
|
type = ScaleTypes.IDENTITY;
|
|
221
218
|
}
|
|
219
|
+
if (name === 'color' && Array.isArray(values) && values.length && values.every(value => isString(value)) && (type === ScaleTypes.LINEAR || type === ScaleTypes.POWER || type === ScaleTypes.LOG)) {
|
|
220
|
+
// Color ramps should use interpolated scales to avoid numeric-only ranges.
|
|
221
|
+
type = ScaleTypes.SEQUENTIAL;
|
|
222
|
+
}
|
|
222
223
|
const cfg = this.createScaleConfig(type, field, scaleOption, data);
|
|
223
224
|
styleScale.scale = this.createDefaultScale(cfg);
|
|
224
225
|
styleScale.option = cfg;
|
|
@@ -32,7 +32,7 @@ export default class ShaderUniformPlugin {
|
|
|
32
32
|
let uniformBuffer;
|
|
33
33
|
if (!this.rendererService.uniformBuffers[0]) {
|
|
34
34
|
// Create a Uniform Buffer Object(UBO).
|
|
35
|
-
//
|
|
35
|
+
// Total size: 93 floats, round up to 96 for safety
|
|
36
36
|
uniformBuffer = this.rendererService.createBuffer({
|
|
37
37
|
data: new Float32Array(96),
|
|
38
38
|
isUBO: true,
|
|
@@ -105,34 +105,67 @@ export default class ShaderUniformPlugin {
|
|
|
105
105
|
const u_ViewportSize = [width, height];
|
|
106
106
|
const u_FocalDistance = this.cameraService.getFocalDistance();
|
|
107
107
|
const u_RelativeOrigin = offset && offset.length >= 2 ? [offset[0], offset[1]] : [0, 0];
|
|
108
|
-
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
// 16
|
|
112
|
-
|
|
113
|
-
// 16
|
|
114
|
-
|
|
115
|
-
//
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
// 4
|
|
120
|
-
|
|
121
|
-
//
|
|
122
|
-
|
|
123
|
-
//
|
|
124
|
-
|
|
125
|
-
// 4
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
//
|
|
130
|
-
|
|
131
|
-
//
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
0
|
|
135
|
-
|
|
108
|
+
|
|
109
|
+
// Build UBO data array matching GLSL std140 layout
|
|
110
|
+
// std140 rules:
|
|
111
|
+
// - mat4: 16-byte aligned, size 64 bytes (16 floats)
|
|
112
|
+
// - vec4: 16-byte aligned, size 16 bytes (4 floats)
|
|
113
|
+
// - vec3: 16-byte aligned, size 12 bytes (3 floats) - next member can follow if aligned
|
|
114
|
+
// - vec2: 8-byte aligned, size 8 bytes (2 floats)
|
|
115
|
+
// - float: 4-byte aligned, size 4 bytes (1 float)
|
|
116
|
+
// Key: vec3 only occupies 3 floats, NOT 4. The alignment requirement is for START position.
|
|
117
|
+
const floats = [];
|
|
118
|
+
|
|
119
|
+
// mat4 x 4: each 16 floats, all start at multiples of 4 floats (16-byte aligned)
|
|
120
|
+
floats.push(...u_ViewMatrix); // floats 0-15
|
|
121
|
+
floats.push(...u_ProjectionMatrix); // floats 16-31
|
|
122
|
+
floats.push(...u_ViewProjectionMatrix); // floats 32-47
|
|
123
|
+
floats.push(...u_ModelMatrix); // floats 48-63
|
|
124
|
+
|
|
125
|
+
// vec4: 4 floats, starts at float 64 (64 % 4 = 0 ✓)
|
|
126
|
+
floats.push(...u_ViewportCenterProjection); // floats 64-67
|
|
127
|
+
|
|
128
|
+
// vec3: 3 floats only, starts at float 68 (68 % 4 = 0 ✓)
|
|
129
|
+
floats.push(...u_PixelsPerDegree); // floats 68-70 (NOT 68-71!)
|
|
130
|
+
|
|
131
|
+
// float: starts at float 71, any position is fine for 4-byte alignment
|
|
132
|
+
floats.push(u_Zoom); // float 71
|
|
133
|
+
|
|
134
|
+
// vec3: needs 4-float alignment, 72 % 4 = 0 ✓
|
|
135
|
+
floats.push(...u_PixelsPerDegree2); // floats 72-74
|
|
136
|
+
|
|
137
|
+
// float: starts at float 75
|
|
138
|
+
floats.push(u_ZoomScale); // float 75
|
|
139
|
+
|
|
140
|
+
// vec3: needs 4-float alignment, 76 % 4 = 0 ✓
|
|
141
|
+
floats.push(...u_PixelsPerMeter); // floats 76-78
|
|
142
|
+
|
|
143
|
+
// float: starts at float 79
|
|
144
|
+
floats.push(u_CoordinateSystem); // float 79
|
|
145
|
+
|
|
146
|
+
// vec3: needs 4-float alignment, 80 % 4 = 0 ✓
|
|
147
|
+
floats.push(...u_CameraPosition); // floats 80-82
|
|
148
|
+
|
|
149
|
+
// float: starts at float 83
|
|
150
|
+
floats.push(u_DevicePixelRatio); // float 83
|
|
151
|
+
|
|
152
|
+
// vec2: needs 2-float alignment, 84 % 2 = 0 ✓
|
|
153
|
+
floats.push(...u_ViewportCenter); // floats 84-85
|
|
154
|
+
|
|
155
|
+
// vec2: needs 2-float alignment, 86 % 2 = 0 ✓
|
|
156
|
+
floats.push(...u_ViewportSize); // floats 86-87
|
|
157
|
+
|
|
158
|
+
// float: starts at float 88
|
|
159
|
+
floats.push(u_FocalDistance); // float 88
|
|
160
|
+
|
|
161
|
+
// vec2: needs 2-float alignment, 89 % 2 = 1, NOT aligned!
|
|
162
|
+
floats.push(0); // padding float 89
|
|
163
|
+
floats.push(...u_RelativeOrigin); // floats 90-91
|
|
164
|
+
|
|
165
|
+
// float u_Reserved3
|
|
166
|
+
floats.push(0); // float 92
|
|
167
|
+
|
|
168
|
+
const data = floats;
|
|
136
169
|
return {
|
|
137
170
|
data,
|
|
138
171
|
uniforms: {
|
package/es/polygon/index.js
CHANGED
|
@@ -19,9 +19,8 @@ export default class PolygonLayer extends BaseLayer {
|
|
|
19
19
|
})();
|
|
20
20
|
}
|
|
21
21
|
getModelType() {
|
|
22
|
-
var
|
|
23
|
-
const
|
|
24
|
-
const shape = shapeAttribute === null || shapeAttribute === void 0 || (_shapeAttribute$scale = shapeAttribute.scale) === null || _shapeAttribute$scale === void 0 ? void 0 : _shapeAttribute$scale.field;
|
|
22
|
+
var _this$shapeOption;
|
|
23
|
+
const shape = (_this$shapeOption = this.shapeOption) === null || _this$shapeOption === void 0 ? void 0 : _this$shapeOption.field;
|
|
25
24
|
if (shape === 'fill' || !shape) {
|
|
26
25
|
return 'fill';
|
|
27
26
|
} else if (shape === 'extrude') {
|
|
@@ -137,10 +137,6 @@ export default class ExtrudeModel extends BaseModel {
|
|
|
137
137
|
this.textures = [];
|
|
138
138
|
}
|
|
139
139
|
registerBuiltinAttributes() {
|
|
140
|
-
const bounds = this.layer.getSource().extent;
|
|
141
|
-
const lngLen = bounds[2] - bounds[0];
|
|
142
|
-
const latLen = bounds[3] - bounds[1];
|
|
143
|
-
|
|
144
140
|
// 注册 Position 属性 64 位地位部分,经纬度数据开启双精度,避免大于 22 层级以上出现数据偏移
|
|
145
141
|
this.registerPosition64LowAttribute();
|
|
146
142
|
this.styleAttributeService.registerStyleAttribute({
|
|
@@ -157,10 +153,29 @@ export default class ExtrudeModel extends BaseModel {
|
|
|
157
153
|
},
|
|
158
154
|
size: 3,
|
|
159
155
|
update: (feature, featureIdx, vertex) => {
|
|
160
|
-
|
|
161
|
-
|
|
156
|
+
// 当启用 enableRelativeCoordinates 时:
|
|
157
|
+
// - vertex 是相对坐标(相对于 relativeOrigin 的偏移)
|
|
158
|
+
// - 需要将相对坐标转换回绝对坐标后,用 originalExtent 计算 UV
|
|
159
|
+
const originalExtent = this.layer.getOriginalExtent();
|
|
160
|
+
const relativeOrigin = this.layer.getRelativeOrigin();
|
|
161
|
+
const isRelativeCoordinates = originalExtent[0] !== 0 || originalExtent[2] !== 0;
|
|
162
|
+
let lng, lat;
|
|
163
|
+
let minLng, minLat, maxLng, maxLat;
|
|
164
|
+
if (isRelativeCoordinates && relativeOrigin) {
|
|
165
|
+
// 相对坐标模式:转换回绝对坐标
|
|
166
|
+
lng = vertex[0] + relativeOrigin[0];
|
|
167
|
+
lat = vertex[1] + relativeOrigin[1];
|
|
168
|
+
[minLng, minLat, maxLng, maxLat] = originalExtent;
|
|
169
|
+
} else {
|
|
170
|
+
// 绝对坐标模式
|
|
171
|
+
lng = vertex[0];
|
|
172
|
+
lat = vertex[1];
|
|
173
|
+
[minLng, minLat, maxLng, maxLat] = this.layer.getSource().extent;
|
|
174
|
+
}
|
|
175
|
+
const lngLen = maxLng - minLng;
|
|
176
|
+
const latLen = maxLat - minLat;
|
|
162
177
|
// 临时 兼容高德V2
|
|
163
|
-
return [(lng -
|
|
178
|
+
return [(lng - minLng) / lngLen, (lat - minLat) / latLen, vertex[4]];
|
|
164
179
|
}
|
|
165
180
|
}
|
|
166
181
|
});
|
|
@@ -85,10 +85,6 @@ export default class OceanModel extends BaseModel {
|
|
|
85
85
|
(_this$texture3 = this.texture3) === null || _this$texture3 === void 0 || _this$texture3.destroy();
|
|
86
86
|
}
|
|
87
87
|
registerBuiltinAttributes() {
|
|
88
|
-
const bbox = this.layer.getSource().extent;
|
|
89
|
-
const [minLng, minLat, maxLng, maxLat] = bbox;
|
|
90
|
-
const lngLen = maxLng - minLng;
|
|
91
|
-
const latLen = maxLat - minLat;
|
|
92
88
|
this.styleAttributeService.registerStyleAttribute({
|
|
93
89
|
name: 'oceanUv',
|
|
94
90
|
type: AttributeType.Attribute,
|
|
@@ -96,14 +92,29 @@ export default class OceanModel extends BaseModel {
|
|
|
96
92
|
name: 'a_uv',
|
|
97
93
|
shaderLocation: this.attributeLocation.UV,
|
|
98
94
|
buffer: {
|
|
99
|
-
// give the WebGL driver a hint that this buffer may change
|
|
100
95
|
usage: gl.STATIC_DRAW,
|
|
101
96
|
data: [],
|
|
102
97
|
type: gl.FLOAT
|
|
103
98
|
},
|
|
104
99
|
size: 2,
|
|
105
100
|
update: (feature, featureIdx, vertex) => {
|
|
106
|
-
|
|
101
|
+
// 当启用 enableRelativeCoordinates 时:需要将相对坐标转换回绝对坐标
|
|
102
|
+
const originalExtent = this.layer.getOriginalExtent();
|
|
103
|
+
const relativeOrigin = this.layer.getRelativeOrigin();
|
|
104
|
+
const isRelativeCoordinates = originalExtent[0] !== 0 || originalExtent[2] !== 0;
|
|
105
|
+
let lng, lat;
|
|
106
|
+
let minLng, minLat, maxLng, maxLat;
|
|
107
|
+
if (isRelativeCoordinates && relativeOrigin) {
|
|
108
|
+
lng = vertex[0] + relativeOrigin[0];
|
|
109
|
+
lat = vertex[1] + relativeOrigin[1];
|
|
110
|
+
[minLng, minLat, maxLng, maxLat] = originalExtent;
|
|
111
|
+
} else {
|
|
112
|
+
lng = vertex[0];
|
|
113
|
+
lat = vertex[1];
|
|
114
|
+
[minLng, minLat, maxLng, maxLat] = this.layer.getSource().extent;
|
|
115
|
+
}
|
|
116
|
+
const lngLen = maxLng - minLng;
|
|
117
|
+
const latLen = maxLat - minLat;
|
|
107
118
|
return [(lng - minLng) / lngLen, (lat - minLat) / latLen];
|
|
108
119
|
}
|
|
109
120
|
}
|