mirror of https://gitee.com/antv-l7/antv-l7
Shihuidev (#864)
* feat: 扩展点图层圆柱效果 * feat: 增加几何体的径向渐变配置 * style: lint style
This commit is contained in:
parent
3edf34aaa5
commit
6320fa87e9
|
@ -43,6 +43,8 @@ export default class PickingService implements IPickingService {
|
||||||
|
|
||||||
private pickBufferScale: number = 1.0;
|
private pickBufferScale: number = 1.0;
|
||||||
|
|
||||||
|
private lastPickTime: number = new Date().getTime();
|
||||||
|
|
||||||
public init(id: string) {
|
public init(id: string) {
|
||||||
const {
|
const {
|
||||||
createTexture2D,
|
createTexture2D,
|
||||||
|
@ -168,7 +170,14 @@ export default class PickingService implements IPickingService {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.alreadyInPicking = true;
|
this.alreadyInPicking = true;
|
||||||
await this.pickingLayers(target);
|
const t = new Date().getTime();
|
||||||
|
// @ts-ignore
|
||||||
|
if (t - this.lastPickTime > 10) {
|
||||||
|
await this.pickingLayers(target);
|
||||||
|
}
|
||||||
|
// await this.pickingLayers(target);
|
||||||
|
// @ts-ignore
|
||||||
|
this.lastPickTime = t;
|
||||||
this.layerService.renderLayers();
|
this.layerService.renderLayers();
|
||||||
this.alreadyInPicking = false;
|
this.alreadyInPicking = false;
|
||||||
}
|
}
|
||||||
|
@ -253,6 +262,14 @@ export default class PickingService implements IPickingService {
|
||||||
data: new Uint8Array(1 * 1 * 4),
|
data: new Uint8Array(1 * 1 * 4),
|
||||||
framebuffer: this.pickingFBO,
|
framebuffer: this.pickingFBO,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// let pickedColors = new Uint8Array(4)
|
||||||
|
// this.rendererService.getGLContext().readPixels(
|
||||||
|
// Math.floor(xInDevicePixel / this.pickBufferScale),
|
||||||
|
// Math.floor((height - (y + 1) * DOM.DPR) / this.pickBufferScale),
|
||||||
|
// 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pickedColors)
|
||||||
|
// console.log(pickedColors[0] == pixels[0] && pickedColors[1] == pixels[1] && pickedColors[2] == pixels[2])
|
||||||
|
|
||||||
if (
|
if (
|
||||||
pickedColors[0] !== 0 ||
|
pickedColors[0] !== 0 ||
|
||||||
pickedColors[1] !== 0 ||
|
pickedColors[1] !== 0 ||
|
||||||
|
|
|
@ -315,6 +315,7 @@ export interface ILayerConfig {
|
||||||
fitBoundsOptions?: unknown;
|
fitBoundsOptions?: unknown;
|
||||||
name: string; //
|
name: string; //
|
||||||
blend: keyof typeof BlendType;
|
blend: keyof typeof BlendType;
|
||||||
|
depth: boolean;
|
||||||
pickedFeatureID: number;
|
pickedFeatureID: number;
|
||||||
enableMultiPassRenderer: boolean;
|
enableMultiPassRenderer: boolean;
|
||||||
passes: Array<string | [string, { [key: string]: unknown }]>;
|
passes: Array<string | [string, { [key: string]: unknown }]>;
|
||||||
|
|
|
@ -11,7 +11,10 @@ import {
|
||||||
primitiveSphere,
|
primitiveSphere,
|
||||||
} from '../earth/utils';
|
} from '../earth/utils';
|
||||||
import ExtrudePolyline from '../utils/extrude_polyline';
|
import ExtrudePolyline from '../utils/extrude_polyline';
|
||||||
import { calculateCentroid } from '../utils/geo';
|
import {
|
||||||
|
calculateCentroid,
|
||||||
|
calculatePointsCenterAndRadius,
|
||||||
|
} from '../utils/geo';
|
||||||
import extrudePolygon, {
|
import extrudePolygon, {
|
||||||
extrude_PolygonNormal,
|
extrude_PolygonNormal,
|
||||||
fillPolygon,
|
fillPolygon,
|
||||||
|
@ -151,6 +154,30 @@ export function polygonTriangulation(feature: IEncodeFeature) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO:构建几何图形(带有中心点和大小)
|
||||||
|
export function polygonTriangulationWithCenter(feature: IEncodeFeature) {
|
||||||
|
const { coordinates } = feature;
|
||||||
|
const flattengeo = earcut.flatten(coordinates as number[][][]);
|
||||||
|
const { vertices, dimensions, holes } = flattengeo;
|
||||||
|
|
||||||
|
return {
|
||||||
|
indices: earcut(vertices, holes, dimensions),
|
||||||
|
vertices: getVerticesWithCenter(vertices),
|
||||||
|
size: dimensions + 4,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getVerticesWithCenter(vertices: number[]) {
|
||||||
|
const verticesWithCenter = [];
|
||||||
|
const { center, radius } = calculatePointsCenterAndRadius(vertices);
|
||||||
|
for (let i = 0; i < vertices.length; i += 2) {
|
||||||
|
const lng = vertices[i];
|
||||||
|
const lat = vertices[i + 1];
|
||||||
|
verticesWithCenter.push(lng, lat, 0, ...center, radius);
|
||||||
|
}
|
||||||
|
return verticesWithCenter;
|
||||||
|
}
|
||||||
|
|
||||||
export function PolygonExtrudeTriangulation(feature: IEncodeFeature) {
|
export function PolygonExtrudeTriangulation(feature: IEncodeFeature) {
|
||||||
const coordinates = feature.coordinates as IPosition[][];
|
const coordinates = feature.coordinates as IPosition[][];
|
||||||
const { positions, index, normals } = extrude_PolygonNormal(
|
const { positions, index, normals } = extrude_PolygonNormal(
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { AttributeType, gl, IEncodeFeature, IModel } from '@antv/l7-core';
|
import { AttributeType, gl, IEncodeFeature, IModel } from '@antv/l7-core';
|
||||||
|
import { rgb2arr } from '@antv/l7-utils';
|
||||||
import { isNumber } from 'lodash';
|
import { isNumber } from 'lodash';
|
||||||
import BaseModel, { styleOffset, styleSingle } from '../../core/BaseModel';
|
import BaseModel, { styleOffset, styleSingle } from '../../core/BaseModel';
|
||||||
import { PointExtrudeTriangulation } from '../../core/triangulation';
|
import { PointExtrudeTriangulation } from '../../core/triangulation';
|
||||||
|
@ -7,13 +8,33 @@ import { calculateCentroid } from '../../utils/geo';
|
||||||
import pointExtrudeFrag from '../shaders/extrude_frag.glsl';
|
import pointExtrudeFrag from '../shaders/extrude_frag.glsl';
|
||||||
import pointExtrudeVert from '../shaders/extrude_vert.glsl';
|
import pointExtrudeVert from '../shaders/extrude_vert.glsl';
|
||||||
interface IPointLayerStyleOptions {
|
interface IPointLayerStyleOptions {
|
||||||
|
depth: boolean;
|
||||||
opacity: styleSingle;
|
opacity: styleSingle;
|
||||||
offsets: styleOffset;
|
offsets: styleOffset;
|
||||||
|
|
||||||
|
sourceColor?: string; // 可选参数、设置渐变色的起始颜色(all)
|
||||||
|
targetColor?: string; // 可选参数、设置渐变色的终点颜色(all)
|
||||||
|
opacityLinear?: {
|
||||||
|
enable: boolean;
|
||||||
|
dir: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
lightEnable: boolean;
|
||||||
}
|
}
|
||||||
export default class ExtrudeModel extends BaseModel {
|
export default class ExtrudeModel extends BaseModel {
|
||||||
public getUninforms() {
|
public getUninforms() {
|
||||||
const {
|
const {
|
||||||
opacity = 1,
|
opacity = 1,
|
||||||
|
|
||||||
|
sourceColor,
|
||||||
|
targetColor,
|
||||||
|
|
||||||
|
opacityLinear = {
|
||||||
|
enable: false,
|
||||||
|
dir: 'up',
|
||||||
|
},
|
||||||
|
|
||||||
|
lightEnable = true,
|
||||||
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||||
if (
|
if (
|
||||||
this.dataTextureTest &&
|
this.dataTextureTest &&
|
||||||
|
@ -51,6 +72,17 @@ export default class ExtrudeModel extends BaseModel {
|
||||||
height: 1,
|
height: 1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 转化渐变色
|
||||||
|
let useLinearColor = 0; // 默认不生效
|
||||||
|
let sourceColorArr = [0, 0, 0, 0];
|
||||||
|
let targetColorArr = [0, 0, 0, 0];
|
||||||
|
if (sourceColor && targetColor) {
|
||||||
|
sourceColorArr = rgb2arr(sourceColor);
|
||||||
|
targetColorArr = rgb2arr(targetColor);
|
||||||
|
useLinearColor = 1;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// TODO: 判断当前的点图层的模型是普通地图模式还是地球模式
|
// TODO: 判断当前的点图层的模型是普通地图模式还是地球模式
|
||||||
u_globel: this.mapService.version === 'GLOBEL' ? 1 : 0,
|
u_globel: this.mapService.version === 'GLOBEL' ? 1 : 0,
|
||||||
|
@ -60,6 +92,18 @@ export default class ExtrudeModel extends BaseModel {
|
||||||
// u_opacity: opacity || 1.0,
|
// u_opacity: opacity || 1.0,
|
||||||
// u_offsets: offsets || [0, 0],
|
// u_offsets: offsets || [0, 0],
|
||||||
u_opacity: isNumber(opacity) ? opacity : 1.0,
|
u_opacity: isNumber(opacity) ? opacity : 1.0,
|
||||||
|
|
||||||
|
// 渐变色支持参数
|
||||||
|
u_linearColor: useLinearColor,
|
||||||
|
u_sourceColor: sourceColorArr,
|
||||||
|
u_targetColor: targetColorArr,
|
||||||
|
|
||||||
|
// 透明度渐变
|
||||||
|
u_opacitylinear: Number(opacityLinear.enable),
|
||||||
|
u_opacitylinear_dir: opacityLinear.dir === 'up' ? 1.0 : 0.0,
|
||||||
|
|
||||||
|
// 光照计算开关
|
||||||
|
u_lightEnable: Number(lightEnable),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
public initModels(): IModel[] {
|
public initModels(): IModel[] {
|
||||||
|
@ -67,6 +111,9 @@ export default class ExtrudeModel extends BaseModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public buildModels(): IModel[] {
|
public buildModels(): IModel[] {
|
||||||
|
const {
|
||||||
|
depth = true,
|
||||||
|
} = this.layer.getLayerConfig() as IPointLayerStyleOptions;
|
||||||
return [
|
return [
|
||||||
this.layer.buildLayerModel({
|
this.layer.buildLayerModel({
|
||||||
moduleName: 'pointExtrude2',
|
moduleName: 'pointExtrude2',
|
||||||
|
@ -74,6 +121,13 @@ export default class ExtrudeModel extends BaseModel {
|
||||||
fragmentShader: pointExtrudeFrag,
|
fragmentShader: pointExtrudeFrag,
|
||||||
triangulation: PointExtrudeTriangulation,
|
triangulation: PointExtrudeTriangulation,
|
||||||
blend: this.getBlend(),
|
blend: this.getBlend(),
|
||||||
|
cull: {
|
||||||
|
enable: true,
|
||||||
|
face: gl.BACK,
|
||||||
|
},
|
||||||
|
depth: {
|
||||||
|
enable: depth,
|
||||||
|
},
|
||||||
// primitive: gl.POINTS,
|
// primitive: gl.POINTS,
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,14 +1,39 @@
|
||||||
varying vec4 v_color;
|
varying vec4 v_color;
|
||||||
uniform float u_opacity: 1.0;
|
uniform float u_opacity: 1.0;
|
||||||
|
|
||||||
|
varying float v_z;
|
||||||
|
varying float v_lightWeight;
|
||||||
|
|
||||||
#pragma include "picking"
|
#pragma include "picking"
|
||||||
|
|
||||||
varying mat4 styleMappingMat; // 传递从片元中传递的映射数据
|
varying mat4 styleMappingMat; // 传递从片元中传递的映射数据
|
||||||
|
|
||||||
|
uniform float u_linearColor: 0;
|
||||||
|
uniform vec4 u_sourceColor;
|
||||||
|
uniform vec4 u_targetColor;
|
||||||
|
|
||||||
|
uniform float u_opacitylinear: 0.0;
|
||||||
|
uniform float u_opacitylinear_dir: 1.0;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
float opacity = styleMappingMat[0][0];
|
float opacity = styleMappingMat[0][0];
|
||||||
gl_FragColor = v_color;
|
|
||||||
// gl_FragColor.a *= u_opacity;
|
// 设置圆柱的底色
|
||||||
|
if(u_linearColor == 1.0) { // 使用渐变颜色
|
||||||
|
gl_FragColor = mix(u_sourceColor, u_targetColor, v_z);
|
||||||
|
gl_FragColor.rgb *= v_lightWeight;
|
||||||
|
} else { // 使用 color 方法传入的颜色
|
||||||
|
gl_FragColor = v_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 应用透明度
|
||||||
gl_FragColor.a *= opacity;
|
gl_FragColor.a *= opacity;
|
||||||
|
|
||||||
|
// 开启透明度渐变
|
||||||
|
if(u_opacitylinear > 0.0) {
|
||||||
|
gl_FragColor.a *= u_opacitylinear_dir > 0.0 ? (1.0 - v_z): v_z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// picking
|
||||||
gl_FragColor = filterColor(gl_FragColor);
|
gl_FragColor = filterColor(gl_FragColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,13 @@ uniform mat4 u_Mvp;
|
||||||
varying vec4 v_color;
|
varying vec4 v_color;
|
||||||
|
|
||||||
uniform float u_opacity : 1;
|
uniform float u_opacity : 1;
|
||||||
|
uniform float u_lightEnable: 1;
|
||||||
|
|
||||||
varying mat4 styleMappingMat; // 用于将在顶点着色器中计算好的样式值传递给片元
|
varying mat4 styleMappingMat; // 用于将在顶点着色器中计算好的样式值传递给片元
|
||||||
|
|
||||||
|
varying float v_z;
|
||||||
|
varying float v_lightWeight;
|
||||||
|
|
||||||
#pragma include "styleMapping"
|
#pragma include "styleMapping"
|
||||||
#pragma include "styleMappingCalOpacity"
|
#pragma include "styleMappingCalOpacity"
|
||||||
|
|
||||||
|
@ -72,13 +76,17 @@ void main() {
|
||||||
// cal style mapping - 数据纹理映射部分的计算
|
// cal style mapping - 数据纹理映射部分的计算
|
||||||
vec3 size = a_Size * a_Position;
|
vec3 size = a_Size * a_Position;
|
||||||
|
|
||||||
|
// a_Position.z 是在构建网格的时候传入的标准值 0 - 1,在插值器插值可以获取 0~1 线性渐变的值
|
||||||
|
v_z = a_Position.z;
|
||||||
|
|
||||||
vec2 offset = project_pixel(size.xy);
|
vec2 offset = project_pixel(size.xy);
|
||||||
|
|
||||||
vec4 project_pos = project_position(vec4(a_Pos.xy, 0., 1.0));
|
vec4 project_pos = project_position(vec4(a_Pos.xy, 0., 1.0));
|
||||||
|
|
||||||
vec4 pos = vec4(project_pos.xy + offset, project_pixel(size.z), 1.0);
|
vec4 pos = vec4(project_pos.xy + offset, project_pixel(size.z), 1.0);
|
||||||
|
|
||||||
float lightWeight = calc_lighting(pos);
|
float lightWeight = u_lightEnable > 0.0 ? calc_lighting(pos): 1.0;
|
||||||
|
v_lightWeight = lightWeight;
|
||||||
v_color =vec4(a_Color.rgb * lightWeight, a_Color.w);
|
v_color =vec4(a_Color.rgb * lightWeight, a_Color.w);
|
||||||
|
|
||||||
// gl_Position = project_common_position_to_clipspace(pos);
|
// gl_Position = project_common_position_to_clipspace(pos);
|
||||||
|
|
|
@ -12,17 +12,31 @@ import {
|
||||||
} from '@antv/l7-core';
|
} from '@antv/l7-core';
|
||||||
import { isNumber } from 'lodash';
|
import { isNumber } from 'lodash';
|
||||||
import BaseModel, { styleSingle } from '../../core/BaseModel';
|
import BaseModel, { styleSingle } from '../../core/BaseModel';
|
||||||
import { polygonTriangulation } from '../../core/triangulation';
|
import {
|
||||||
|
polygonTriangulation,
|
||||||
|
polygonTriangulationWithCenter,
|
||||||
|
} from '../../core/triangulation';
|
||||||
import polygon_frag from '../shaders/polygon_frag.glsl';
|
import polygon_frag from '../shaders/polygon_frag.glsl';
|
||||||
|
import polygon_linear_frag from '../shaders/polygon_linear_frag.glsl';
|
||||||
|
import polygon_linear_vert from '../shaders/polygon_linear_vert.glsl';
|
||||||
import polygon_vert from '../shaders/polygon_vert.glsl';
|
import polygon_vert from '../shaders/polygon_vert.glsl';
|
||||||
|
|
||||||
interface IPolygonLayerStyleOptions {
|
interface IPolygonLayerStyleOptions {
|
||||||
opacity: styleSingle;
|
opacity: styleSingle;
|
||||||
|
|
||||||
|
opacityLinear: {
|
||||||
|
enable: boolean;
|
||||||
|
dir: string;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
export default class FillModel extends BaseModel {
|
export default class FillModel extends BaseModel {
|
||||||
public getUninforms() {
|
public getUninforms() {
|
||||||
const {
|
const {
|
||||||
opacity = 1,
|
opacity = 1,
|
||||||
|
opacityLinear = {
|
||||||
|
enable: false,
|
||||||
|
dir: 'in',
|
||||||
|
},
|
||||||
} = this.layer.getLayerConfig() as IPolygonLayerStyleOptions;
|
} = this.layer.getLayerConfig() as IPolygonLayerStyleOptions;
|
||||||
if (this.dataTextureTest && this.dataTextureNeedUpdate({ opacity })) {
|
if (this.dataTextureTest && this.dataTextureNeedUpdate({ opacity })) {
|
||||||
this.judgeStyleAttributes({ opacity });
|
this.judgeStyleAttributes({ opacity });
|
||||||
|
@ -58,6 +72,9 @@ export default class FillModel extends BaseModel {
|
||||||
u_cellTypeLayout: this.getCellTypeLayout(),
|
u_cellTypeLayout: this.getCellTypeLayout(),
|
||||||
// u_opacity: opacity,
|
// u_opacity: opacity,
|
||||||
u_opacity: isNumber(opacity) ? opacity : 1.0,
|
u_opacity: isNumber(opacity) ? opacity : 1.0,
|
||||||
|
|
||||||
|
u_opacitylinear: Number(opacityLinear.enable),
|
||||||
|
u_dir: opacityLinear.dir === 'in' ? 1.0 : 0.0,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,12 +83,23 @@ export default class FillModel extends BaseModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public buildModels(): IModel[] {
|
public buildModels(): IModel[] {
|
||||||
|
const {
|
||||||
|
opacityLinear = {
|
||||||
|
enable: false,
|
||||||
|
dir: 'in',
|
||||||
|
},
|
||||||
|
} = this.layer.getLayerConfig() as IPolygonLayerStyleOptions;
|
||||||
return [
|
return [
|
||||||
this.layer.buildLayerModel({
|
this.layer.buildLayerModel({
|
||||||
moduleName: 'polygon',
|
moduleName: 'polygon',
|
||||||
vertexShader: polygon_vert,
|
vertexShader: opacityLinear.enable ? polygon_linear_vert : polygon_vert,
|
||||||
fragmentShader: polygon_frag,
|
fragmentShader: opacityLinear.enable
|
||||||
triangulation: polygonTriangulation,
|
? polygon_linear_frag
|
||||||
|
: polygon_frag,
|
||||||
|
// triangulation: polygonTriangulation,
|
||||||
|
triangulation: opacityLinear.enable
|
||||||
|
? polygonTriangulationWithCenter
|
||||||
|
: polygonTriangulation,
|
||||||
blend: this.getBlend(),
|
blend: this.getBlend(),
|
||||||
depth: { enable: false },
|
depth: { enable: false },
|
||||||
}),
|
}),
|
||||||
|
@ -83,6 +111,37 @@ export default class FillModel extends BaseModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected registerBuiltinAttributes() {
|
protected registerBuiltinAttributes() {
|
||||||
// point layer size;
|
const {
|
||||||
|
opacityLinear = {
|
||||||
|
enable: false,
|
||||||
|
dir: 'in',
|
||||||
|
},
|
||||||
|
} = this.layer.getLayerConfig() as IPolygonLayerStyleOptions;
|
||||||
|
if (opacityLinear.enable) {
|
||||||
|
this.styleAttributeService.registerStyleAttribute({
|
||||||
|
name: 'linear',
|
||||||
|
type: AttributeType.Attribute,
|
||||||
|
descriptor: {
|
||||||
|
name: 'a_linear',
|
||||||
|
buffer: {
|
||||||
|
// give the WebGL driver a hint that this buffer may change
|
||||||
|
usage: gl.STATIC_DRAW,
|
||||||
|
data: [],
|
||||||
|
type: gl.FLOAT,
|
||||||
|
},
|
||||||
|
size: 3,
|
||||||
|
update: (
|
||||||
|
feature: IEncodeFeature,
|
||||||
|
featureIdx: number,
|
||||||
|
vertex: number[],
|
||||||
|
attributeIdx: number,
|
||||||
|
normal: number[],
|
||||||
|
) => {
|
||||||
|
// center[0] center[1] radius
|
||||||
|
return [vertex[3], vertex[4], vertex[5]];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ varying mat4 styleMappingMat; // 传递从片元中传递的映射数据
|
||||||
void main() {
|
void main() {
|
||||||
float opacity = styleMappingMat[0][0];
|
float opacity = styleMappingMat[0][0];
|
||||||
gl_FragColor = v_Color;
|
gl_FragColor = v_Color;
|
||||||
// gl_FragColor.a *= u_opacity;
|
|
||||||
gl_FragColor.a *= opacity;
|
gl_FragColor.a *= opacity;
|
||||||
gl_FragColor = filterColor(gl_FragColor);
|
gl_FragColor = filterColor(gl_FragColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
uniform float u_opacity: 1.0;
|
||||||
|
varying vec4 v_Color;
|
||||||
|
varying mat4 styleMappingMat; // 传递从片元中传递的映射数据
|
||||||
|
|
||||||
|
#pragma include "picking"
|
||||||
|
uniform float u_opacitylinear: 0.0;
|
||||||
|
uniform float u_dir: 1.0;
|
||||||
|
varying vec3 v_linear;
|
||||||
|
varying vec2 v_pos;
|
||||||
|
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
float opacity = styleMappingMat[0][0];
|
||||||
|
gl_FragColor = v_Color;
|
||||||
|
|
||||||
|
if(u_opacitylinear > 0.0) {
|
||||||
|
gl_FragColor.a *= u_dir == 1.0 ? 1.0 - length(v_pos - v_linear.xy)/v_linear.z : length(v_pos - v_linear.xy)/v_linear.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_FragColor.a *= opacity;
|
||||||
|
gl_FragColor = filterColor(gl_FragColor);
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
attribute vec4 a_Color;
|
||||||
|
attribute vec3 a_Position;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uniform mat4 u_ModelMatrix;
|
||||||
|
uniform mat4 u_Mvp;
|
||||||
|
|
||||||
|
varying vec4 v_Color;
|
||||||
|
uniform float u_opacity: 1.0;
|
||||||
|
varying mat4 styleMappingMat; // 用于将在顶点着色器中计算好的样式值传递给片元
|
||||||
|
|
||||||
|
#pragma include "styleMapping"
|
||||||
|
#pragma include "styleMappingCalOpacity"
|
||||||
|
|
||||||
|
#pragma include "projection"
|
||||||
|
#pragma include "picking"
|
||||||
|
|
||||||
|
uniform float u_opacitylinear: 0.0;
|
||||||
|
|
||||||
|
attribute vec3 a_linear;
|
||||||
|
varying vec3 v_linear;
|
||||||
|
varying vec2 v_pos;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
if(u_opacitylinear > 0.0) {
|
||||||
|
v_linear = a_linear;
|
||||||
|
v_pos = a_Position.xy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cal style mapping - 数据纹理映射部分的计算
|
||||||
|
styleMappingMat = mat4(
|
||||||
|
0.0, 0.0, 0.0, 0.0, // opacity - strokeOpacity - strokeWidth - empty
|
||||||
|
0.0, 0.0, 0.0, 0.0, // strokeR - strokeG - strokeB - strokeA
|
||||||
|
0.0, 0.0, 0.0, 0.0, // offsets[0] - offsets[1]
|
||||||
|
0.0, 0.0, 0.0, 0.0
|
||||||
|
);
|
||||||
|
|
||||||
|
float rowCount = u_cellTypeLayout[0][0]; // 当前的数据纹理有几行
|
||||||
|
float columnCount = u_cellTypeLayout[0][1]; // 当看到数据纹理有几列
|
||||||
|
float columnWidth = 1.0/columnCount; // 列宽
|
||||||
|
float rowHeight = 1.0/rowCount; // 行高
|
||||||
|
float cellCount = calCellCount(); // opacity - strokeOpacity - strokeWidth - stroke - offsets
|
||||||
|
float id = a_vertexId; // 第n个顶点
|
||||||
|
float cellCurrentRow = floor(id * cellCount / columnCount) + 1.0; // 起始点在第几行
|
||||||
|
float cellCurrentColumn = mod(id * cellCount, columnCount) + 1.0; // 起始点在第几列
|
||||||
|
|
||||||
|
// cell 固定顺序 opacity -> strokeOpacity -> strokeWidth -> stroke ...
|
||||||
|
// 按顺序从 cell 中取值、若没有则自动往下取值
|
||||||
|
float textureOffset = 0.0; // 在 cell 中取值的偏移量
|
||||||
|
|
||||||
|
vec2 opacityAndOffset = calOpacityAndOffset(cellCurrentRow, cellCurrentColumn, columnCount, textureOffset, columnWidth, rowHeight);
|
||||||
|
styleMappingMat[0][0] = opacityAndOffset.r;
|
||||||
|
textureOffset = opacityAndOffset.g;
|
||||||
|
// cal style mapping - 数据纹理映射部分的计算
|
||||||
|
|
||||||
|
v_Color = a_Color;
|
||||||
|
vec4 project_pos = project_position(vec4(a_Position, 1.0));
|
||||||
|
// gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0));
|
||||||
|
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||||
|
gl_Position = u_Mvp * (vec4(project_pos.xyz, 1.0));
|
||||||
|
} else {
|
||||||
|
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xyz, 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
setPickingColor(a_PickingColor);
|
||||||
|
}
|
|
@ -1,7 +1,5 @@
|
||||||
attribute vec4 a_Color;
|
attribute vec4 a_Color;
|
||||||
attribute vec3 a_Position;
|
attribute vec3 a_Position;
|
||||||
attribute vec3 a_Normal;
|
|
||||||
attribute float a_Size;
|
|
||||||
uniform mat4 u_ModelMatrix;
|
uniform mat4 u_ModelMatrix;
|
||||||
uniform mat4 u_Mvp;
|
uniform mat4 u_Mvp;
|
||||||
|
|
||||||
|
|
|
@ -25,3 +25,36 @@ export function calculateCentroid(
|
||||||
throw new Error('当前数据不支持标注');
|
throw new Error('当前数据不支持标注');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算
|
||||||
|
* @param points
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function calculatePointsCenterAndRadius(points: number[]) {
|
||||||
|
let maxX = points[0];
|
||||||
|
let maxY = points[1];
|
||||||
|
let minX = points[0];
|
||||||
|
let minY = points[1];
|
||||||
|
let xCount = 0;
|
||||||
|
let yCount = 0;
|
||||||
|
let pCount = 0;
|
||||||
|
|
||||||
|
for (let i = 0; i < points.length; i += 2) {
|
||||||
|
const x = points[i];
|
||||||
|
const y = points[i + 1];
|
||||||
|
if (x && y) {
|
||||||
|
maxX = Math.max(x, maxX);
|
||||||
|
maxY = Math.max(y, maxY);
|
||||||
|
minX = Math.min(x, minX);
|
||||||
|
minY = Math.min(y, minY);
|
||||||
|
xCount += x;
|
||||||
|
yCount += y;
|
||||||
|
pCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
center: [xCount / pCount, yCount / pCount],
|
||||||
|
radius: Math.sqrt(Math.pow(maxX - minX, 2) + Math.pow(maxY - minY, 2)) / 2,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,88 @@
|
||||||
|
// @ts-ignore
|
||||||
|
import { PointLayer, Scene } from '@antv/l7';
|
||||||
|
import { GaodeMap } from '@antv/l7-maps';
|
||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
export default class PointUV extends React.Component {
|
||||||
|
// @ts-ignore
|
||||||
|
private scene: Scene;
|
||||||
|
|
||||||
|
public componentWillUnmount() {
|
||||||
|
this.scene.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async componentDidMount() {
|
||||||
|
const scene = new Scene({
|
||||||
|
id: 'map',
|
||||||
|
map: new GaodeMap({
|
||||||
|
center: [121.107846, 30.267069],
|
||||||
|
pitch: 40,
|
||||||
|
// style: 'normal',
|
||||||
|
zoom: 20,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
// normal = 'normal',
|
||||||
|
// additive = 'additive',
|
||||||
|
// subtractive = 'subtractive',
|
||||||
|
// min = 'min',
|
||||||
|
// max = 'max',
|
||||||
|
// none = 'none',
|
||||||
|
const layer = new PointLayer({ depth: false })
|
||||||
|
.source(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
lng: 121.107846,
|
||||||
|
lat: 30.267069,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
lng: 121.107,
|
||||||
|
lat: 30.267069,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
{
|
||||||
|
parser: {
|
||||||
|
type: 'json',
|
||||||
|
x: 'lng',
|
||||||
|
y: 'lat',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.shape('cylinder')
|
||||||
|
.color('#0ff')
|
||||||
|
.size([5, 5, 100])
|
||||||
|
.style({
|
||||||
|
opacity: 0.6,
|
||||||
|
|
||||||
|
sourceColor: 'red',
|
||||||
|
targetColor: 'yellow',
|
||||||
|
|
||||||
|
opacityLinear: {
|
||||||
|
enable: true, // true - false
|
||||||
|
dir: 'up', // up - down
|
||||||
|
},
|
||||||
|
|
||||||
|
lightEnable: false,
|
||||||
|
});
|
||||||
|
layer.on('click', () => console.log('click'));
|
||||||
|
scene.addLayer(layer);
|
||||||
|
scene.render();
|
||||||
|
this.scene = scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
id="map"
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -64,6 +64,7 @@ import Amap2demo_textOffset from "./components/amap2demo_textOffset"
|
||||||
|
|
||||||
import ShapeUpdate from './components/shapeUpdate'
|
import ShapeUpdate from './components/shapeUpdate'
|
||||||
import AmapPlugin from './components/plugin'
|
import AmapPlugin from './components/plugin'
|
||||||
|
import PointUV from './components/pointUV'
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
storiesOf('地图方法', module)
|
storiesOf('地图方法', module)
|
||||||
|
@ -131,3 +132,4 @@ storiesOf('地图方法', module)
|
||||||
|
|
||||||
.add('ShapeUpdate', () => <ShapeUpdate/>)
|
.add('ShapeUpdate', () => <ShapeUpdate/>)
|
||||||
.add('AmapPlugin', () => <AmapPlugin/>)
|
.add('AmapPlugin', () => <AmapPlugin/>)
|
||||||
|
.add('PointUV', () => <PointUV/>)
|
||||||
|
|
|
@ -21,7 +21,7 @@ export default class PointTest extends React.Component {
|
||||||
zoom: 5,
|
zoom: 5,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
scene.diasbleShaderPick();
|
// scene.diasbleShaderPick();
|
||||||
let address =
|
let address =
|
||||||
'https://gw.alipayobjects.com/os/bmw-prod/3f2f9284-3fb1-4838-8baa-6ffd06738fcd.csv';
|
'https://gw.alipayobjects.com/os/bmw-prod/3f2f9284-3fb1-4838-8baa-6ffd06738fcd.csv';
|
||||||
fetch(address)
|
fetch(address)
|
||||||
|
@ -40,52 +40,19 @@ export default class PointTest extends React.Component {
|
||||||
y1: 't_lat',
|
y1: 't_lat',
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.shape('arcmini')
|
// .shape('arcmini')
|
||||||
.size(2)
|
|
||||||
.color('rgb(13,64,140)')
|
|
||||||
.style({
|
|
||||||
segmentNumber: 30,
|
|
||||||
});
|
|
||||||
|
|
||||||
// lineLayer2
|
|
||||||
const lineLayer2 = new LineLayer({
|
|
||||||
// autoFit: true,
|
|
||||||
blend: 'normal',
|
|
||||||
})
|
|
||||||
.source(data, {
|
|
||||||
parser: {
|
|
||||||
type: 'csv',
|
|
||||||
x: 'f_lon',
|
|
||||||
y: 'f_lat',
|
|
||||||
x1: 't_lon',
|
|
||||||
y1: 't_lat',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.shape('arc')
|
.shape('arc')
|
||||||
|
// .shape('line')
|
||||||
.size(2)
|
.size(2)
|
||||||
.color('rgb(13,64,140)')
|
.color('rgb(13,64,140)')
|
||||||
.style({
|
|
||||||
segmentNumber: 30,
|
|
||||||
})
|
|
||||||
.select({
|
|
||||||
color: '#ff0',
|
|
||||||
})
|
|
||||||
.active({
|
.active({
|
||||||
color: '#ff0',
|
color: '#ff0',
|
||||||
|
})
|
||||||
|
.style({
|
||||||
|
segmentNumber: 30,
|
||||||
});
|
});
|
||||||
lineLayer2.hide();
|
|
||||||
// scene.addLayer(lineLayer2);
|
|
||||||
|
|
||||||
scene.addLayer(lineLayer);
|
scene.addLayer(lineLayer);
|
||||||
|
|
||||||
window.onmousedown = () => {
|
|
||||||
// lineLayer2.hide()
|
|
||||||
lineLayer.show();
|
|
||||||
};
|
|
||||||
window.onmouseup = () => {
|
|
||||||
// lineLayer2.show()
|
|
||||||
lineLayer.hide();
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,110 +5,24 @@ import { Scene, PolygonLayer, PointLayer, Map } from '@antv/l7-mini';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
export default class ScaleComponent extends React.Component {
|
export default class ScaleComponent extends React.Component {
|
||||||
private scene: Scene;
|
|
||||||
private el: HTMLCanvasElement;
|
|
||||||
|
|
||||||
public componentWillUnmount() {
|
|
||||||
this.scene.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
public setCanvas() {
|
|
||||||
this.el.width = 400;
|
|
||||||
this.el.height = 300;
|
|
||||||
this.el.style.width = '300px';
|
|
||||||
this.el.style.height = '150px';
|
|
||||||
this.el.style.zIndex = '10';
|
|
||||||
this.el.style.position = 'absolute';
|
|
||||||
this.el.style.top = '0';
|
|
||||||
this.el.style.left = '0';
|
|
||||||
this.el.style.border = '1px solid';
|
|
||||||
}
|
|
||||||
|
|
||||||
public async componentDidMount() {
|
public async componentDidMount() {
|
||||||
this.setCanvas();
|
|
||||||
|
|
||||||
const scene = new Scene({
|
const scene = new Scene({
|
||||||
id: 'map',
|
id: 'map',
|
||||||
// canvas: this.el,
|
|
||||||
map: new Map({
|
map: new Map({
|
||||||
hash: true,
|
hash: true,
|
||||||
center: [122.2215, 29.8325],
|
center: [105, 32],
|
||||||
pitch: 0,
|
pitch: 0,
|
||||||
zoom: 22,
|
zoom: 3,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
scene.addImage(
|
scene.setBgColor('#000');
|
||||||
'00',
|
|
||||||
'https://gw.alipayobjects.com/zos/basement_prod/604b5e7f-309e-40db-b95b-4fac746c5153.svg',
|
|
||||||
);
|
|
||||||
let imageLayer = new PointLayer({
|
|
||||||
blend: 'normal',
|
|
||||||
zIndex: 2,
|
|
||||||
})
|
|
||||||
.source(
|
|
||||||
[
|
|
||||||
{
|
|
||||||
id: '5011000000404',
|
|
||||||
name: '铁路新村(华池路)',
|
|
||||||
longitude: 121.4216962,
|
|
||||||
latitude: 31.26082325,
|
|
||||||
unit_price: 71469.4,
|
|
||||||
count: 2,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
{
|
|
||||||
parser: {
|
|
||||||
type: 'json',
|
|
||||||
x: 'longitude',
|
|
||||||
y: 'latitude',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.shape('name', ['00'])
|
|
||||||
.size(20);
|
|
||||||
fetch(
|
fetch(
|
||||||
'https://gw.alipayobjects.com/os/basement_prod/d2e0e930-fd44-4fca-8872-c1037b0fee7b.json',
|
'https://gw.alipayobjects.com/os/basement_prod/d2e0e930-fd44-4fca-8872-c1037b0fee7b.json',
|
||||||
)
|
)
|
||||||
.then((res) => res.json())
|
.then((res) => res.json())
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
const textLayer = new PointLayer({})
|
const layer = new PolygonLayer({ blend: 'normal' })
|
||||||
.source(
|
|
||||||
[
|
|
||||||
{
|
|
||||||
lng: 120.5,
|
|
||||||
lat: 31.3,
|
|
||||||
iconType: 'cloud',
|
|
||||||
iconColor: '#F0F8FF',
|
|
||||||
weather: '多云 - 今日适宜出门',
|
|
||||||
textOffset: [-40, 0],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
{
|
|
||||||
parser: {
|
|
||||||
type: 'json',
|
|
||||||
x: 'lng',
|
|
||||||
y: 'lat',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.shape('weather', 'text')
|
|
||||||
.size(16)
|
|
||||||
.color('#f00')
|
|
||||||
.style({
|
|
||||||
textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left
|
|
||||||
textOffset: [0, 0], // 文本相对锚点的偏移量 [水平, 垂直]
|
|
||||||
spacing: 2, // 字符间距
|
|
||||||
padding: [1, 1], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近
|
|
||||||
fontFamily: 'Times New Roman',
|
|
||||||
textAllowOverlap: true,
|
|
||||||
})
|
|
||||||
.active(true);
|
|
||||||
scene.addLayer(textLayer);
|
|
||||||
|
|
||||||
const layer = new PolygonLayer({
|
|
||||||
name: '01',
|
|
||||||
autoFit: true,
|
|
||||||
})
|
|
||||||
.source(data)
|
.source(data)
|
||||||
.size('name', [0, 10000, 50000, 30000, 100000])
|
.size('name', [0, 10000, 50000, 30000, 100000])
|
||||||
.color('name', [
|
.color('name', [
|
||||||
|
@ -122,16 +36,32 @@ export default class ScaleComponent extends React.Component {
|
||||||
.shape('fill')
|
.shape('fill')
|
||||||
.select(true)
|
.select(true)
|
||||||
.style({
|
.style({
|
||||||
opacity: 1.0,
|
opacity: 0.8,
|
||||||
|
opacityLinear: {
|
||||||
|
enable: true,
|
||||||
|
dir: 'in', // in - out
|
||||||
|
},
|
||||||
});
|
});
|
||||||
scene.addLayer(layer);
|
scene.addLayer(layer);
|
||||||
|
|
||||||
window.onresize = () => layer.fitBounds();
|
const layer2 = new PolygonLayer({ blend: 'normal' })
|
||||||
|
.source(data)
|
||||||
|
.size(1)
|
||||||
|
.color('name', [
|
||||||
|
'#2E8AE6',
|
||||||
|
'#69D1AB',
|
||||||
|
'#DAF291',
|
||||||
|
'#FFD591',
|
||||||
|
'#FF7A45',
|
||||||
|
'#CF1D49',
|
||||||
|
])
|
||||||
|
.shape('line')
|
||||||
|
.select(true)
|
||||||
|
.style({
|
||||||
|
opacity: 1.0,
|
||||||
|
});
|
||||||
|
scene.addLayer(layer2);
|
||||||
});
|
});
|
||||||
|
|
||||||
scene.on('loaded', () => {
|
|
||||||
scene.addLayer(imageLayer);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
|
@ -145,9 +75,7 @@ export default class ScaleComponent extends React.Component {
|
||||||
right: 0,
|
right: 0,
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
}}
|
}}
|
||||||
>
|
></div>
|
||||||
<canvas ref={(el) => (this.el = el as HTMLCanvasElement)}></canvas>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue