mirror of https://gitee.com/antv-l7/antv-l7
Arrow (#1051)
* fix: 修复 GeometryLayer 失效 * feat: 线图层支持箭头样式 * style: lint style * feat: 增加注释 * feat: 变量名替换
This commit is contained in:
parent
791b99035b
commit
d4d2068150
|
@ -111,6 +111,7 @@ export interface IVertexAttributeDescriptor
|
||||||
vertex: number[],
|
vertex: number[],
|
||||||
attributeIdx: number,
|
attributeIdx: number,
|
||||||
normal: number[],
|
normal: number[],
|
||||||
|
vertexIndex?: number,
|
||||||
) => number[];
|
) => number[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,6 +169,7 @@ export type Triangulation = (
|
||||||
indices: number[];
|
indices: number[];
|
||||||
size: number;
|
size: number;
|
||||||
normals?: number[];
|
normals?: number[];
|
||||||
|
indexes?: number[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface IStyleAttributeUpdateOptions {
|
export interface IStyleAttributeUpdateOptions {
|
||||||
|
|
|
@ -53,6 +53,7 @@ export default class StyleAttributeService implements IStyleAttributeService {
|
||||||
vertices: number[];
|
vertices: number[];
|
||||||
normals: number[];
|
normals: number[];
|
||||||
offset: number;
|
offset: number;
|
||||||
|
indexes?: number[];
|
||||||
}>;
|
}>;
|
||||||
} = {
|
} = {
|
||||||
sizePerElement: 0,
|
sizePerElement: 0,
|
||||||
|
@ -218,6 +219,7 @@ export default class StyleAttributeService implements IStyleAttributeService {
|
||||||
vertices: verticesForCurrentFeature,
|
vertices: verticesForCurrentFeature,
|
||||||
normals: normalsForCurrentFeature,
|
normals: normalsForCurrentFeature,
|
||||||
size: vertexSize,
|
size: vertexSize,
|
||||||
|
indexes,
|
||||||
} = this.triangulation(feature, segmentNumber);
|
} = this.triangulation(feature, segmentNumber);
|
||||||
indicesForCurrentFeature.forEach((i) => {
|
indicesForCurrentFeature.forEach((i) => {
|
||||||
indices.push(i + verticesNum);
|
indices.push(i + verticesNum);
|
||||||
|
@ -249,6 +251,12 @@ export default class StyleAttributeService implements IStyleAttributeService {
|
||||||
vertexIdx * vertexSize,
|
vertexIdx * vertexSize,
|
||||||
vertexIdx * vertexSize + vertexSize,
|
vertexIdx * vertexSize + vertexSize,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let vertexIndex = 0;
|
||||||
|
if (indexes && indexes[vertexIdx] !== undefined) {
|
||||||
|
vertexIndex = indexes[vertexIdx];
|
||||||
|
}
|
||||||
|
|
||||||
descriptors.forEach((descriptor, attributeIdx) => {
|
descriptors.forEach((descriptor, attributeIdx) => {
|
||||||
if (descriptor && descriptor.update) {
|
if (descriptor && descriptor.update) {
|
||||||
(descriptor.buffer.data as number[]).push(
|
(descriptor.buffer.data as number[]).push(
|
||||||
|
@ -258,6 +266,7 @@ export default class StyleAttributeService implements IStyleAttributeService {
|
||||||
vertice,
|
vertice,
|
||||||
vertexIdx, // 当前顶点所在feature索引
|
vertexIdx, // 当前顶点所在feature索引
|
||||||
normal,
|
normal,
|
||||||
|
vertexIndex,
|
||||||
// TODO: 传入顶点索引 vertexIdx
|
// TODO: 传入顶点索引 vertexIdx
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -7,6 +7,12 @@ export enum lineStyleType {
|
||||||
'dash' = 1.0,
|
'dash' = 1.0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ILineArrow {
|
||||||
|
enable: boolean;
|
||||||
|
arrowWidth: number;
|
||||||
|
arrowHeight: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface ILineLayerStyleOptions {
|
export interface ILineLayerStyleOptions {
|
||||||
opacity: styleSingle;
|
opacity: styleSingle;
|
||||||
lineType?: keyof typeof lineStyleType; // 可选参数、线类型(all - dash/solid)
|
lineType?: keyof typeof lineStyleType; // 可选参数、线类型(all - dash/solid)
|
||||||
|
@ -34,6 +40,8 @@ export interface ILineLayerStyleOptions {
|
||||||
|
|
||||||
mask?: boolean; // 可选参数 时候允许蒙层
|
mask?: boolean; // 可选参数 时候允许蒙层
|
||||||
maskInside?: boolean; // 可选参数 控制图层是否显示在蒙层的内部
|
maskInside?: boolean; // 可选参数 控制图层是否显示在蒙层的内部
|
||||||
|
|
||||||
|
arrow?: ILineArrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPointLayerStyleOptions {
|
export interface IPointLayerStyleOptions {
|
||||||
|
|
|
@ -139,6 +139,7 @@ export function LineTriangulation(feature: IEncodeFeature) {
|
||||||
vertices: linebuffer.positions, // [ x,y,z, distance, miter,total ]
|
vertices: linebuffer.positions, // [ x,y,z, distance, miter,total ]
|
||||||
indices: linebuffer.indices,
|
indices: linebuffer.indices,
|
||||||
normals: linebuffer.normals,
|
normals: linebuffer.normals,
|
||||||
|
indexes: linebuffer.indexes,
|
||||||
size: 6,
|
size: 6,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,11 @@ export default class LineModel extends BaseModel {
|
||||||
borderColor = '#ccc',
|
borderColor = '#ccc',
|
||||||
raisingHeight = 0,
|
raisingHeight = 0,
|
||||||
heightfixed = false,
|
heightfixed = false,
|
||||||
|
arrow = {
|
||||||
|
enable: false,
|
||||||
|
arrowWidth: 2,
|
||||||
|
arrowHeight: 3,
|
||||||
|
},
|
||||||
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
|
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
|
||||||
if (dashArray.length === 2) {
|
if (dashArray.length === 2) {
|
||||||
dashArray.push(0, 0);
|
dashArray.push(0, 0);
|
||||||
|
@ -124,6 +129,11 @@ export default class LineModel extends BaseModel {
|
||||||
// 顶点高度 scale
|
// 顶点高度 scale
|
||||||
u_vertexScale: vertexHeightScale,
|
u_vertexScale: vertexHeightScale,
|
||||||
u_raisingHeight: Number(raisingHeight),
|
u_raisingHeight: Number(raisingHeight),
|
||||||
|
|
||||||
|
// arrow
|
||||||
|
u_arrow: Number(arrow.enable),
|
||||||
|
u_arrowHeight: arrow.arrowHeight || 3,
|
||||||
|
u_arrowWidth: arrow.arrowWidth || 2,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
public getAnimateUniforms(): IModelUniform {
|
public getAnimateUniforms(): IModelUniform {
|
||||||
|
@ -216,14 +226,18 @@ export default class LineModel extends BaseModel {
|
||||||
data: [],
|
data: [],
|
||||||
type: gl.FLOAT,
|
type: gl.FLOAT,
|
||||||
},
|
},
|
||||||
size: 1,
|
size: 2,
|
||||||
update: (
|
update: (
|
||||||
feature: IEncodeFeature,
|
feature: IEncodeFeature,
|
||||||
featureIdx: number,
|
featureIdx: number,
|
||||||
vertex: number[],
|
vertex: number[],
|
||||||
attributeIdx: number,
|
attributeIdx: number,
|
||||||
|
normal: number[],
|
||||||
|
vertexIndex?: number,
|
||||||
) => {
|
) => {
|
||||||
return [vertex[3]];
|
return vertexIndex === undefined
|
||||||
|
? [vertex[3], 10]
|
||||||
|
: [vertex[3], vertexIndex];
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,7 +11,7 @@ attribute vec2 a_iconMapUV;
|
||||||
|
|
||||||
// dash line
|
// dash line
|
||||||
attribute float a_Total_Distance;
|
attribute float a_Total_Distance;
|
||||||
attribute float a_Distance;
|
attribute vec2 a_Distance;
|
||||||
|
|
||||||
uniform mat4 u_ModelMatrix;
|
uniform mat4 u_ModelMatrix;
|
||||||
uniform mat4 u_Mvp;
|
uniform mat4 u_Mvp;
|
||||||
|
@ -32,6 +32,9 @@ varying vec2 v_iconMapUV;
|
||||||
|
|
||||||
|
|
||||||
uniform float u_linearColor: 0;
|
uniform float u_linearColor: 0;
|
||||||
|
uniform float u_arrow: 0.0;
|
||||||
|
uniform float u_arrowHeight: 3.0;
|
||||||
|
uniform float u_arrowWidth: 2.0;
|
||||||
|
|
||||||
uniform float u_opacity: 1.0;
|
uniform float u_opacity: 1.0;
|
||||||
varying mat4 styleMappingMat; // 用于将在顶点着色器中计算好的样式值传递给片元
|
varying mat4 styleMappingMat; // 用于将在顶点着色器中计算好的样式值传递给片元
|
||||||
|
@ -39,6 +42,48 @@ varying mat4 styleMappingMat; // 用于将在顶点着色器中计算好的样
|
||||||
#pragma include "styleMapping"
|
#pragma include "styleMapping"
|
||||||
#pragma include "styleMappingCalOpacity"
|
#pragma include "styleMappingCalOpacity"
|
||||||
|
|
||||||
|
vec2 calculateArrow(vec2 offset) {
|
||||||
|
/*
|
||||||
|
* 在支持箭头的时候,第二、第三组顶点是额外插入用于构建顶点的
|
||||||
|
*/
|
||||||
|
float arrowFlag = -1.0;
|
||||||
|
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) {
|
||||||
|
// 高德 2.0 的旋转角度不同
|
||||||
|
arrowFlag = 1.0;
|
||||||
|
}
|
||||||
|
float pi = arrowFlag * 3.1415926/2.;
|
||||||
|
if(a_Miter < 0.) {
|
||||||
|
// 根据线的两侧偏移不同、旋转的方向相反
|
||||||
|
pi = -pi;
|
||||||
|
}
|
||||||
|
highp float angle_sin = sin(pi);
|
||||||
|
highp float angle_cos = cos(pi);
|
||||||
|
// 计算垂直与线方向的旋转矩阵
|
||||||
|
mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);
|
||||||
|
float arrowWidth = u_arrowWidth;
|
||||||
|
float arrowHeight = u_arrowHeight;
|
||||||
|
|
||||||
|
vec2 arrowOffset = vec2(0.0);
|
||||||
|
/*
|
||||||
|
* a_Distance.y 用于标记当前顶点属于哪一组(两个顶点一组,构成线的其实是矩形,最简需要四个顶点、两组顶点构成)
|
||||||
|
*/
|
||||||
|
if(a_Distance.y == 0.0) {
|
||||||
|
// 箭头尖部
|
||||||
|
offset = vec2(0.0);
|
||||||
|
} else if(a_Distance.y == 1.0) {
|
||||||
|
// 箭头两侧
|
||||||
|
arrowOffset = rotation_matrix*(offset * arrowHeight);
|
||||||
|
offset += arrowOffset; // 沿线偏移
|
||||||
|
offset = offset * arrowWidth; // 垂直线向外偏移(是构建箭头两侧的顶点)
|
||||||
|
} else if(a_Distance.y == 2.0 || a_Distance.y == 3.0 || a_Distance.y == 4.0) {
|
||||||
|
// 偏移其余的点位(将长度让位给箭头)
|
||||||
|
arrowOffset = rotation_matrix*(offset * arrowHeight) * arrowWidth;
|
||||||
|
offset += arrowOffset;// 沿线偏移
|
||||||
|
}
|
||||||
|
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// cal style mapping - 数据纹理映射部分的计算
|
// cal style mapping - 数据纹理映射部分的计算
|
||||||
styleMappingMat = mat4(
|
styleMappingMat = mat4(
|
||||||
|
@ -79,14 +124,19 @@ void main() {
|
||||||
vec3 size = a_Miter * setPickingSize(a_Size.x) * reverse_offset_normal(a_Normal);
|
vec3 size = a_Miter * setPickingSize(a_Size.x) * reverse_offset_normal(a_Normal);
|
||||||
|
|
||||||
vec2 offset = project_pixel(size.xy);
|
vec2 offset = project_pixel(size.xy);
|
||||||
|
|
||||||
|
if(u_arrow > 0.0) {
|
||||||
|
// 计算箭头
|
||||||
|
offset = calculateArrow(offset);
|
||||||
|
}
|
||||||
|
|
||||||
float lineOffsetWidth = length(offset + offset * sign(a_Miter)); // 线横向偏移的距离(向两侧偏移的和)
|
float lineOffsetWidth = length(offset + offset * sign(a_Miter)); // 线横向偏移的距离(向两侧偏移的和)
|
||||||
float linePixelSize = project_pixel(a_Size.x) * 2.0; // 定点位置偏移,按地图等级缩放后的距离 单侧 * 2
|
float linePixelSize = project_pixel(a_Size.x) * 2.0; // 定点位置偏移,按地图等级缩放后的距离 单侧 * 2
|
||||||
float texV = lineOffsetWidth/linePixelSize; // 线图层贴图部分的 v 坐标值
|
float texV = lineOffsetWidth/linePixelSize; // 线图层贴图部分的 v 坐标值
|
||||||
|
|
||||||
// 设置数据集的参数
|
// 设置数据集的参数
|
||||||
styleMappingMat[3][0] = a_Distance / a_Total_Distance;; // 当前点位距离占线总长的比例
|
styleMappingMat[3][0] = a_Distance.x / a_Total_Distance;; // 当前点位距离占线总长的比例
|
||||||
styleMappingMat[3][1] = a_Distance; // 当前顶点的距离
|
styleMappingMat[3][1] = a_Distance.x; // 当前顶点的距离
|
||||||
styleMappingMat[3][2] = d_texPixelLen; // 贴图的像素长度,根据地图层级缩放
|
styleMappingMat[3][2] = d_texPixelLen; // 贴图的像素长度,根据地图层级缩放
|
||||||
styleMappingMat[3][3] = texV; // 线图层贴图部分的 v 坐标值
|
styleMappingMat[3][3] = texV; // 线图层贴图部分的 v 坐标值
|
||||||
|
|
||||||
|
|
|
@ -9,13 +9,15 @@ import {
|
||||||
IParseDataItem,
|
IParseDataItem,
|
||||||
IStyleAttribute,
|
IStyleAttribute,
|
||||||
IStyleAttributeService,
|
IStyleAttributeService,
|
||||||
|
Position,
|
||||||
TYPES,
|
TYPES,
|
||||||
} from '@antv/l7-core';
|
} from '@antv/l7-core';
|
||||||
import { Version } from '@antv/l7-maps';
|
import { Version } from '@antv/l7-maps';
|
||||||
import { isColor, rgb2arr, unProjectFlat } from '@antv/l7-utils';
|
import { isColor, normalize, rgb2arr, unProjectFlat } from '@antv/l7-utils';
|
||||||
import { inject, injectable } from 'inversify';
|
import { inject, injectable } from 'inversify';
|
||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep } from 'lodash';
|
||||||
import 'reflect-metadata';
|
import 'reflect-metadata';
|
||||||
|
import { ILineLayerStyleOptions } from '../core/interface';
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export default class DataMappingPlugin implements ILayerPlugin {
|
export default class DataMappingPlugin implements ILayerPlugin {
|
||||||
|
@ -54,21 +56,24 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
||||||
const attributes = styleAttributeService.getLayerStyleAttributes() || [];
|
const attributes = styleAttributeService.getLayerStyleAttributes() || [];
|
||||||
const filter = styleAttributeService.getLayerStyleAttribute('filter');
|
const filter = styleAttributeService.getLayerStyleAttribute('filter');
|
||||||
const { dataArray } = layer.getSource().data;
|
const { dataArray } = layer.getSource().data;
|
||||||
|
|
||||||
const attributesToRemapping = attributes.filter(
|
const attributesToRemapping = attributes.filter(
|
||||||
(attribute) => attribute.needRemapping, // 如果filter变化
|
(attribute) => attribute.needRemapping, // 如果filter变化
|
||||||
);
|
);
|
||||||
let filterData = dataArray;
|
let filterData = dataArray;
|
||||||
|
|
||||||
// 数据过滤完 再执行数据映射
|
// 数据过滤完 再执行数据映射
|
||||||
if (filter?.needRemapping && filter?.scale) {
|
if (filter?.needRemapping && filter?.scale) {
|
||||||
filterData = dataArray.filter((record: IParseDataItem) => {
|
filterData = dataArray.filter((record: IParseDataItem) => {
|
||||||
return this.applyAttributeMapping(filter, record, bottomColor)[0];
|
return this.applyAttributeMapping(filter, record, bottomColor)[0];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attributesToRemapping.length) {
|
if (attributesToRemapping.length) {
|
||||||
// 过滤数据
|
// 过滤数据
|
||||||
if (filter?.needRemapping) {
|
if (filter?.needRemapping) {
|
||||||
layer.setEncodedData(
|
layer.setEncodedData(
|
||||||
this.mapping(attributes, filterData, undefined, bottomColor),
|
this.mapping(attributes, filterData, undefined, bottomColor, layer),
|
||||||
);
|
);
|
||||||
filter.needRemapping = false;
|
filter.needRemapping = false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -78,6 +83,7 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
||||||
filterData,
|
filterData,
|
||||||
layer.getEncodedData(),
|
layer.getEncodedData(),
|
||||||
bottomColor,
|
bottomColor,
|
||||||
|
layer,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -104,19 +110,34 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
layer.setEncodedData(
|
layer.setEncodedData(
|
||||||
this.mapping(attributes, filterData, undefined, bottomColor),
|
this.mapping(attributes, filterData, undefined, bottomColor, layer),
|
||||||
);
|
);
|
||||||
// 对外暴露事件
|
// 对外暴露事件
|
||||||
layer.emit('dataUpdate', null);
|
layer.emit('dataUpdate', null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getArrowPoints(p1: Position, p2: Position) {
|
||||||
|
const dir = [p2[0] - p1[0], p2[1] - p1[1]];
|
||||||
|
const normalizeDir = normalize(dir);
|
||||||
|
const arrowPoint = [
|
||||||
|
p1[0] + normalizeDir[0] * 0.0001,
|
||||||
|
p1[1] + normalizeDir[1] * 0.0001,
|
||||||
|
];
|
||||||
|
return arrowPoint;
|
||||||
|
}
|
||||||
|
|
||||||
private mapping(
|
private mapping(
|
||||||
attributes: IStyleAttribute[],
|
attributes: IStyleAttribute[],
|
||||||
data: IParseDataItem[],
|
data: IParseDataItem[],
|
||||||
predata?: IEncodeFeature[],
|
predata?: IEncodeFeature[],
|
||||||
minimumColor?: string,
|
minimumColor?: string,
|
||||||
|
layer?: ILayer,
|
||||||
): IEncodeFeature[] {
|
): IEncodeFeature[] {
|
||||||
// console.log('data', data)
|
const {
|
||||||
|
arrow = {
|
||||||
|
enable: false,
|
||||||
|
},
|
||||||
|
} = layer?.getLayerConfig() as ILineLayerStyleOptions;
|
||||||
const mappedData = data.map((record: IParseDataItem, i) => {
|
const mappedData = data.map((record: IParseDataItem, i) => {
|
||||||
const preRecord = predata ? predata[i] : {};
|
const preRecord = predata ? predata[i] : {};
|
||||||
const encodeRecord: IEncodeFeature = {
|
const encodeRecord: IEncodeFeature = {
|
||||||
|
@ -124,11 +145,9 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
||||||
coordinates: record.coordinates,
|
coordinates: record.coordinates,
|
||||||
...preRecord,
|
...preRecord,
|
||||||
};
|
};
|
||||||
// console.log('attributes', attributes)
|
|
||||||
attributes
|
attributes
|
||||||
.filter((attribute) => attribute.scale !== undefined)
|
.filter((attribute) => attribute.scale !== undefined)
|
||||||
.forEach((attribute: IStyleAttribute) => {
|
.forEach((attribute: IStyleAttribute) => {
|
||||||
// console.log('attribute', attribute)
|
|
||||||
// console.log('record', record)
|
// console.log('record', record)
|
||||||
let values = this.applyAttributeMapping(
|
let values = this.applyAttributeMapping(
|
||||||
attribute,
|
attribute,
|
||||||
|
@ -156,6 +175,13 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (encodeRecord.shape === 'line' && arrow.enable) {
|
||||||
|
// 只有在线图层且支持配置箭头的时候进行插入顶点的处理
|
||||||
|
const coords = encodeRecord.coordinates as Position[];
|
||||||
|
const arrowPoint = this.getArrowPoints(coords[0], coords[1]);
|
||||||
|
encodeRecord.coordinates.splice(1, 0, arrowPoint, arrowPoint);
|
||||||
|
}
|
||||||
return encodeRecord;
|
return encodeRecord;
|
||||||
}) as IEncodeFeature[];
|
}) as IEncodeFeature[];
|
||||||
// console.log('mappedData', mappedData)
|
// console.log('mappedData', mappedData)
|
||||||
|
@ -165,7 +191,7 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
||||||
|
|
||||||
// 调整数据兼容 SimpleCoordinates
|
// 调整数据兼容 SimpleCoordinates
|
||||||
this.adjustData2SimpleCoordinates(mappedData);
|
this.adjustData2SimpleCoordinates(mappedData);
|
||||||
// console.log('mappedData', mappedData)
|
|
||||||
return mappedData;
|
return mappedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,7 @@ export default class ExtrudePolyline {
|
||||||
indices: number[];
|
indices: number[];
|
||||||
normals: number[];
|
normals: number[];
|
||||||
startIndex: number;
|
startIndex: number;
|
||||||
|
indexes: number[];
|
||||||
};
|
};
|
||||||
private join: string;
|
private join: string;
|
||||||
private cap: string;
|
private cap: string;
|
||||||
|
@ -73,6 +74,7 @@ export default class ExtrudePolyline {
|
||||||
private started: boolean = false;
|
private started: boolean = false;
|
||||||
private dash: boolean = false;
|
private dash: boolean = false;
|
||||||
private totalDistance: number = 0;
|
private totalDistance: number = 0;
|
||||||
|
private currentIndex: number = 0;
|
||||||
|
|
||||||
constructor(opts: Partial<IExtrudeLineOption> = {}) {
|
constructor(opts: Partial<IExtrudeLineOption> = {}) {
|
||||||
this.join = opts.join || 'miter';
|
this.join = opts.join || 'miter';
|
||||||
|
@ -85,6 +87,7 @@ export default class ExtrudePolyline {
|
||||||
indices: [],
|
indices: [],
|
||||||
normals: [],
|
normals: [],
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
|
indexes: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,6 +316,7 @@ export default class ExtrudePolyline {
|
||||||
-this.thickness,
|
-this.thickness,
|
||||||
last[2] | 0,
|
last[2] | 0,
|
||||||
);
|
);
|
||||||
|
this.complex.indexes.push(this.currentIndex);
|
||||||
positions.push(
|
positions.push(
|
||||||
last[0],
|
last[0],
|
||||||
last[1],
|
last[1],
|
||||||
|
@ -321,6 +325,8 @@ export default class ExtrudePolyline {
|
||||||
this.thickness,
|
this.thickness,
|
||||||
last[2] | 0,
|
last[2] | 0,
|
||||||
);
|
);
|
||||||
|
this.complex.indexes.push(this.currentIndex);
|
||||||
|
this.currentIndex++;
|
||||||
} else {
|
} else {
|
||||||
this.extrusions(
|
this.extrusions(
|
||||||
positions,
|
positions,
|
||||||
|
@ -354,6 +360,7 @@ export default class ExtrudePolyline {
|
||||||
this.thickness,
|
this.thickness,
|
||||||
cur[2] | 0,
|
cur[2] | 0,
|
||||||
);
|
);
|
||||||
|
this.complex.indexes.push(this.currentIndex);
|
||||||
positions.push(
|
positions.push(
|
||||||
cur[0],
|
cur[0],
|
||||||
cur[1],
|
cur[1],
|
||||||
|
@ -362,6 +369,8 @@ export default class ExtrudePolyline {
|
||||||
this.thickness,
|
this.thickness,
|
||||||
cur[2] | 0,
|
cur[2] | 0,
|
||||||
);
|
);
|
||||||
|
this.complex.indexes.push(this.currentIndex);
|
||||||
|
this.currentIndex++;
|
||||||
} else {
|
} else {
|
||||||
this.extrusions(
|
this.extrusions(
|
||||||
positions,
|
positions,
|
||||||
|
@ -429,6 +438,7 @@ export default class ExtrudePolyline {
|
||||||
-this.thickness * flip,
|
-this.thickness * flip,
|
||||||
cur[2] | 0,
|
cur[2] | 0,
|
||||||
);
|
);
|
||||||
|
this.complex.indexes.push(this.currentIndex);
|
||||||
positions.push(
|
positions.push(
|
||||||
cur[0],
|
cur[0],
|
||||||
cur[1],
|
cur[1],
|
||||||
|
@ -437,6 +447,8 @@ export default class ExtrudePolyline {
|
||||||
this.thickness * flip,
|
this.thickness * flip,
|
||||||
cur[2] | 0,
|
cur[2] | 0,
|
||||||
);
|
);
|
||||||
|
this.complex.indexes.push(this.currentIndex);
|
||||||
|
this.currentIndex++;
|
||||||
indices.push(
|
indices.push(
|
||||||
...(this.lastFlip !== -flip
|
...(this.lastFlip !== -flip
|
||||||
? [index, index + 2, index + 3]
|
? [index, index + 2, index + 3]
|
||||||
|
@ -457,6 +469,8 @@ export default class ExtrudePolyline {
|
||||||
-this.thickness * flip,
|
-this.thickness * flip,
|
||||||
cur[2] | 0,
|
cur[2] | 0,
|
||||||
);
|
);
|
||||||
|
this.complex.indexes.push(this.currentIndex);
|
||||||
|
this.currentIndex++;
|
||||||
count += 3;
|
count += 3;
|
||||||
} else {
|
} else {
|
||||||
this.extrusions(
|
this.extrusions(
|
||||||
|
@ -636,6 +650,7 @@ export default class ExtrudePolyline {
|
||||||
-this.thickness,
|
-this.thickness,
|
||||||
last[2] | 0,
|
last[2] | 0,
|
||||||
);
|
);
|
||||||
|
this.complex.indexes.push(this.currentIndex);
|
||||||
positions.push(
|
positions.push(
|
||||||
last[0],
|
last[0],
|
||||||
last[1],
|
last[1],
|
||||||
|
@ -644,7 +659,8 @@ export default class ExtrudePolyline {
|
||||||
this.thickness,
|
this.thickness,
|
||||||
last[2] | 0,
|
last[2] | 0,
|
||||||
);
|
);
|
||||||
|
this.complex.indexes.push(this.currentIndex);
|
||||||
|
this.currentIndex++;
|
||||||
// this.extrusions(positions, normals, last, out, this.thickness);
|
// this.extrusions(positions, normals, last, out, this.thickness);
|
||||||
// last = capEnd;
|
// last = capEnd;
|
||||||
} else {
|
} else {
|
||||||
|
@ -681,6 +697,7 @@ export default class ExtrudePolyline {
|
||||||
this.thickness,
|
this.thickness,
|
||||||
cur[2] | 0,
|
cur[2] | 0,
|
||||||
);
|
);
|
||||||
|
this.complex.indexes.push(this.currentIndex);
|
||||||
positions.push(
|
positions.push(
|
||||||
cur[0],
|
cur[0],
|
||||||
cur[1],
|
cur[1],
|
||||||
|
@ -689,6 +706,8 @@ export default class ExtrudePolyline {
|
||||||
this.thickness,
|
this.thickness,
|
||||||
cur[2] | 0,
|
cur[2] | 0,
|
||||||
);
|
);
|
||||||
|
this.complex.indexes.push(this.currentIndex);
|
||||||
|
this.currentIndex++;
|
||||||
} else {
|
} else {
|
||||||
this.extrusions(
|
this.extrusions(
|
||||||
positions,
|
positions,
|
||||||
|
@ -750,6 +769,7 @@ export default class ExtrudePolyline {
|
||||||
-this.thickness * flip,
|
-this.thickness * flip,
|
||||||
cur[2] | 0,
|
cur[2] | 0,
|
||||||
);
|
);
|
||||||
|
this.complex.indexes.push(this.currentIndex);
|
||||||
positions.push(
|
positions.push(
|
||||||
cur[0],
|
cur[0],
|
||||||
cur[1],
|
cur[1],
|
||||||
|
@ -758,6 +778,8 @@ export default class ExtrudePolyline {
|
||||||
this.thickness * flip,
|
this.thickness * flip,
|
||||||
cur[2] | 0,
|
cur[2] | 0,
|
||||||
);
|
);
|
||||||
|
this.complex.indexes.push(this.currentIndex);
|
||||||
|
this.currentIndex++;
|
||||||
indices.push(
|
indices.push(
|
||||||
...(this.lastFlip !== -flip
|
...(this.lastFlip !== -flip
|
||||||
? [index, index + 2, index + 3]
|
? [index, index + 2, index + 3]
|
||||||
|
@ -778,6 +800,8 @@ export default class ExtrudePolyline {
|
||||||
-this.thickness * flip,
|
-this.thickness * flip,
|
||||||
cur[2] | 0,
|
cur[2] | 0,
|
||||||
);
|
);
|
||||||
|
this.complex.indexes.push(this.currentIndex);
|
||||||
|
this.currentIndex++;
|
||||||
count += 3;
|
count += 3;
|
||||||
} else {
|
} else {
|
||||||
this.extrusions(
|
this.extrusions(
|
||||||
|
@ -822,6 +846,7 @@ export default class ExtrudePolyline {
|
||||||
-thickness,
|
-thickness,
|
||||||
point[2] | 0,
|
point[2] | 0,
|
||||||
);
|
);
|
||||||
|
this.complex.indexes.push(this.currentIndex);
|
||||||
positions.push(
|
positions.push(
|
||||||
point[0],
|
point[0],
|
||||||
point[1],
|
point[1],
|
||||||
|
@ -830,6 +855,8 @@ export default class ExtrudePolyline {
|
||||||
thickness,
|
thickness,
|
||||||
point[2] | 0,
|
point[2] | 0,
|
||||||
);
|
);
|
||||||
|
this.complex.indexes.push(this.currentIndex);
|
||||||
|
this.currentIndex++;
|
||||||
}
|
}
|
||||||
private lineSegmentDistance(b1: vec3, a1: vec3) {
|
private lineSegmentDistance(b1: vec3, a1: vec3) {
|
||||||
const dx = a1[0] - b1[0];
|
const dx = a1[0] - b1[0];
|
||||||
|
|
|
@ -54,12 +54,21 @@ export default function json(data: IJsonData, cfg: IParserCfg): IParserData {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: 提供默认数据和解析器
|
// TODO: 提供默认数据和解析器
|
||||||
export const defaultData = [];
|
export const defaultData = [
|
||||||
|
{
|
||||||
|
lng1: 100,
|
||||||
|
lat1: 30.0,
|
||||||
|
lng2: 130,
|
||||||
|
lat2: 30,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
export const defaultParser = {
|
export const defaultParser = {
|
||||||
parser: {
|
parser: {
|
||||||
type: 'json',
|
type: 'json',
|
||||||
x: 'lng',
|
x: 'lng1',
|
||||||
y: 'lat',
|
y: 'lat1',
|
||||||
|
x1: 'lng2',
|
||||||
|
y1: 'lat2',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -251,6 +251,11 @@ export function bBoxToBounds(b1: BBox): IBounds {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function normalize(v: Point) {
|
||||||
|
const len = calDistance(v, [0, 0]);
|
||||||
|
return [v[0] / len, v[1] / len];
|
||||||
|
}
|
||||||
|
|
||||||
export function calDistance(p1: Point, p2: Point) {
|
export function calDistance(p1: Point, p2: Point) {
|
||||||
return Math.sqrt(Math.pow(p1[0] - p2[0], 2) + Math.pow(p1[1] - p2[1], 2));
|
return Math.sqrt(Math.pow(p1[0] - p2[0], 2) + Math.pow(p1[1] - p2[1], 2));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
import { GeometryLayer, Scene, LineLayer } from '@antv/l7';
|
||||||
|
import { GaodeMap, GaodeMapV2, Mapbox } from '@antv/l7-maps';
|
||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
export default class Demo 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({
|
||||||
|
// map: new GaodeMapV2({
|
||||||
|
// map: new Mapbox({
|
||||||
|
pitch: 0,
|
||||||
|
// style: 'dark',
|
||||||
|
center: [120, 30],
|
||||||
|
zoom: 3,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
this.scene = scene;
|
||||||
|
|
||||||
|
const layer = new LineLayer()
|
||||||
|
// .source([
|
||||||
|
// {
|
||||||
|
// lng1: 100,
|
||||||
|
// lat1: 30.0,
|
||||||
|
// lng2: 105,
|
||||||
|
// lat2: 30,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// lng1: 105,
|
||||||
|
// lat1: 30.0,
|
||||||
|
// lng2: 130,
|
||||||
|
// lat2: 30,
|
||||||
|
// },
|
||||||
|
// ], {
|
||||||
|
// parser: {
|
||||||
|
// type: 'json',
|
||||||
|
// x: 'lng1',
|
||||||
|
// y: 'lat1',
|
||||||
|
// x1: 'lng2',
|
||||||
|
// y1: 'lat2',
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
.source({
|
||||||
|
type: 'FeatureCollection',
|
||||||
|
features: [
|
||||||
|
{
|
||||||
|
type: 'Feature',
|
||||||
|
properties: {},
|
||||||
|
geometry: {
|
||||||
|
type: 'LineString',
|
||||||
|
coordinates: [
|
||||||
|
[100, 30],
|
||||||
|
[120, 30],
|
||||||
|
[120, 25],
|
||||||
|
[125, 25],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.shape('line')
|
||||||
|
.size(10)
|
||||||
|
// .color('lng1', ['#f00', '#ff0'])
|
||||||
|
.color('#f00')
|
||||||
|
.style({
|
||||||
|
opacity: 0.3,
|
||||||
|
arrow: {
|
||||||
|
enable: true,
|
||||||
|
arrowWidth: 2,
|
||||||
|
arrowHeight: 3,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
scene.on('loaded', () => {
|
||||||
|
scene.addLayer(layer);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
id="map"
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,6 +8,7 @@ import CanvasDemo from './components/canvas';
|
||||||
import Plane from './components/plane';
|
import Plane from './components/plane';
|
||||||
import PlaneTerrain from './components/planeTerrain';
|
import PlaneTerrain from './components/planeTerrain';
|
||||||
import Cursor from './components/cursor';
|
import Cursor from './components/cursor';
|
||||||
|
import Arrow from './components/arrow';
|
||||||
|
|
||||||
storiesOf('Object', module)
|
storiesOf('Object', module)
|
||||||
.add('water', () => <Water />)
|
.add('water', () => <Water />)
|
||||||
|
@ -17,4 +18,5 @@ storiesOf('Object', module)
|
||||||
.add('CanvasDemo', () => <CanvasDemo/>)
|
.add('CanvasDemo', () => <CanvasDemo/>)
|
||||||
.add('Plane', () => <Plane/>)
|
.add('Plane', () => <Plane/>)
|
||||||
.add('PlaneTerrain', () => <PlaneTerrain/>)
|
.add('PlaneTerrain', () => <PlaneTerrain/>)
|
||||||
.add('Cursor', () => <Cursor/>)
|
.add('Cursor', () => <Cursor/>)
|
||||||
|
.add('Arrow', () => <Arrow/>)
|
Loading…
Reference in New Issue