fix: fix simple line err (#1269)

* chore: update version 2.9.18 -> 2.9.19

* chore: 修改引用

* style: lint style

* fix: 修复 simple line 失效

* style: lint style
This commit is contained in:
YiQianYao 2022-08-03 19:08:46 +08:00 committed by GitHub
parent 6f8162fa36
commit 36a228062d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 230 additions and 400 deletions

View File

@ -23,8 +23,8 @@ addParameters({
// automatically import all files ending in *.stories.tsx
// const req = require.context('../stories', true, /\.stories\.tsx$/);
const req = require.context('../stories/layerbuild', true, /\.stories\.tsx$/);
// const req = require.context('../stories/Map', true, /\.stories\.tsx$/);
// const req = require.context('../stories/layerbuild', true, /\.stories\.tsx$/);
const req = require.context('../stories/Map', true, /\.stories\.tsx$/);
// const req = require.context('../stories/MapPerformance', true, /\.stories\.tsx$/);
// const req = require.context('../stories/tile', true, /\.stories\.tsx$/);

View File

@ -147,21 +147,45 @@ export function LineTriangulation(feature: IEncodeFeature) {
}
export function SimpleLineTriangulation(feature: IEncodeFeature) {
const { coordinates } = feature;
const { coordinates, originCoordinates, version } = feature;
const line = new SimpleLine();
let path = coordinates as number[][][] | number[][];
if (path[0] && !Array.isArray(path[0][0])) {
path = [coordinates] as number[][][];
}
path.forEach((item: any) => {
line.simpleExtrude(item as number[][]);
const line = new ExtrudePolyline({
dash: true,
join: 'bevel',
});
if (version === 'GAODE2.x') {
// 处理高德2.0几何体构建
let path1 = coordinates as number[][][] | number[][]; // 计算位置
if (!Array.isArray(path1[0][0])) {
path1 = [coordinates] as number[][][];
}
let path2 = originCoordinates as number[][][] | number[][]; // 计算法线
if (!Array.isArray(path2[0][0])) {
path2 = [originCoordinates] as number[][][];
}
for (let i = 0; i < path1.length; i++) {
// 高德2.0在计算线时,需要使用经纬度计算发现,使用 customCoords.lnglatToCoords 计算的数据来计算顶点的位置
const item1 = path1[i];
const item2 = path2[i];
line.simpleExtrude_gaode2(item1 as number[][], item2 as number[][]);
}
} else {
// 处理非高德2.0的几何体构建
let path = coordinates as number[][][] | number[][];
if (path[0] && !Array.isArray(path[0][0])) {
path = [coordinates] as number[][][];
}
path.forEach((item: any) => {
line.simpleExtrude(item as number[][]);
});
}
const linebuffer = line.complex;
return {
vertices: linebuffer.positions, // [ x,y,z, distance, miter, total ]
indices: linebuffer.indices,
normals: linebuffer.normals,
size: 6,
};
}

View File

@ -91,6 +91,92 @@ export default class ExtrudePolyline {
};
}
public simpleExtrude(points: number[][]) {
const complex = this.complex;
if (points.length <= 1) {
return complex;
}
this.lastFlip = -1;
this.started = false;
this.normal = null;
this.totalDistance = 0;
const total = points.length;
let count = complex.startIndex;
for (let i = 1; i < total; i++) {
const last = points[i - 1] as vec3;
const cur = points[i] as vec3;
const next = i < points.length - 1 ? points[i + 1] : null;
const amt = this.simpleSegment(complex, count, last, cur, next as vec3);
count += amt;
}
if (this.dash) {
for (let i = 0; i < complex.positions.length / 6; i++) {
complex.positions[i * 6 + 5] = this.totalDistance;
}
}
complex.startIndex = complex.positions.length / 6;
return complex;
}
public simpleExtrude_gaode2(points: number[][], originPoints: number[][]) {
const complex = this.complex;
if (points.length <= 1) {
return complex;
}
this.lastFlip = -1;
this.started = false;
this.normal = null;
this.totalDistance = 0;
// 去除数组里重复的点
// points = getArrayUnique(points);
const total = points.length;
let count = complex.startIndex;
for (let i = 1; i < total; i++) {
const last = points[i - 1];
last.push(originPoints[i - 1][2] ?? 0);
// @ts-ignore
const originLast = originPoints[i - 1] as vec3;
const cur = points[i];
cur.push(originPoints[i][2] ?? 0);
// @ts-ignore
const originCur = originPoints[i] as vec3;
const next =
i < points.length - 1
? [...points[i + 1], originPoints[i + 1][2] ?? 0]
: null;
const originNext =
i < originPoints.length - 1 ? originPoints[i + 1] : null;
const amt = this.simpleSegment(
complex,
count,
// @ts-ignore
last as vec3,
// @ts-ignore
cur as vec3,
// @ts-ignore
next as vec3,
// @ts-ignore
originLast,
originCur,
// @ts-ignore
originNext as vec3,
);
count += amt;
}
if (this.dash) {
for (let i = 0; i < complex.positions.length / 6; i++) {
complex.positions[i * 6 + 5] = this.totalDistance;
}
}
complex.startIndex = complex.positions.length / 6;
return complex;
}
public extrude_gaode2(points: number[][], originPoints: number[][]) {
const complex = this.complex;
if (points.length <= 1) {
@ -175,6 +261,112 @@ export default class ExtrudePolyline {
complex.startIndex = complex.positions.length / 6;
return complex;
}
private simpleSegment(
complex: any,
index: number,
last: vec3,
cur: vec3,
next: vec3,
) {
let count = 0;
const indices = complex.indices;
const positions = complex.positions;
const normals = complex.normals;
const flatCur = aProjectFlat([cur[0], cur[1]]) as [number, number];
const flatLast = aProjectFlat([last[0], last[1]]) as [number, number];
// @ts-ignore
direction(lineA, flatCur, flatLast);
let segmentDistance = 0;
if (this.dash) {
// @ts-ignore
segmentDistance = this.lineSegmentDistance(flatCur, flatLast);
this.totalDistance += segmentDistance;
}
if (!this.normal) {
this.normal = vec2.create();
computeNormal(this.normal, lineA);
}
if (!this.started) {
this.started = true;
this.extrusions(
positions,
normals,
last,
this.normal,
this.thickness,
this.totalDistance - segmentDistance,
);
}
indices.push(index + 0, index + 1, index + 2);
if (!next) {
computeNormal(this.normal, lineA);
this.extrusions(
positions,
normals,
cur,
this.normal,
this.thickness,
this.totalDistance,
);
indices.push(
...(this.lastFlip === 1
? [index, index + 2, index + 3]
: [index + 2, index + 1, index + 3]),
);
count += 2;
} else {
const flatNext = aProjectFlat([next[0], next[1]]) as [number, number];
if (isPointEqual(flatCur, flatNext)) {
vec2.add(
flatNext,
flatCur,
vec2.normalize(flatNext, vec2.subtract(flatNext, flatCur, flatLast)),
);
}
direction(lineB, flatNext, flatCur);
// stores tangent & miter
const [miterLen, miter] = computeMiter(
tangent,
vec2.create(),
lineA,
lineB,
this.thickness,
);
// normal(tmp, lineA)
// get orientation
let flip = vec2.dot(tangent, this.normal) < 0 ? -1 : 1;
this.extrusions(
positions,
normals,
cur,
miter,
miterLen,
this.totalDistance,
);
indices.push(
...(this.lastFlip === 1
? [index, index + 2, index + 3]
: [index + 2, index + 1, index + 3]),
);
flip = -1;
// the miter is now the normal for our next join
vec2.copy(this.normal, miter);
count += 2;
this.lastFlip = flip;
}
return count;
}
private segment_gaode2(
complex: any,
index: number,

View File

@ -1,9 +1,6 @@
import { LineLayer, Scene, PointLayer } from '@antv/l7';
import { GaodeMap, GaodeMapV2, Map } from '@antv/l7-maps';
import * as React from 'react';
import { ThreeLayer, ThreeRender } from '@antv/l7-three';
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
function getImageData(img: HTMLImageElement) {
let canvas: HTMLCanvasElement = document.createElement('canvas');
@ -70,15 +67,6 @@ function getR(data: Uint8ClampedArray) {
return arr;
}
function setMaterial(object: any) {
if (object.children && object.children.length && object.children.length > 0) {
object.children.map((child: any) => setMaterial(child));
} else if (object.material) {
object.material.wireframe = true;
object.material.opacity = 0.6;
}
}
export default class GridTile extends React.Component {
// @ts-ignore
private scene: Scene;
@ -100,214 +88,6 @@ export default class GridTile extends React.Component {
}),
});
this.scene = scene;
scene.setBgColor('#000');
const airPorts = [
{
name: '常德桃花源机场',
lng: 111.641101,
lat: 28.91165,
},
{
name: '芷江机场',
lng: 109.709699,
lat: 27.442172,
},
{
name: '铜仁凤凰机场',
lng: 109.313971,
lat: 27.880629,
},
{
name: '永州零陵机场',
lng: 111.616049,
lat: 26.335053,
},
{
name: '桂林两江国际机场',
lng: 110.049256,
lat: 25.210065,
},
{
name: '长沙黄花国际机场',
lng: 113.216412,
lat: 28.183613,
},
{
name: '井冈山机场',
lng: 114.745845,
lat: 26.852646,
},
];
const planeTarget = {
lng2: 111.616049,
lat2: 26.335053,
};
const airLineData = [
{
name: '常德桃花源机场',
lng: 111.641101,
lat: 28.91165,
...planeTarget,
},
{
name: '芷江机场',
lng: 109.709699,
lat: 27.442172,
...planeTarget,
},
{
name: '铜仁凤凰机场',
lng: 109.313971,
lat: 27.880629,
...planeTarget,
},
{
name: '桂林两江国际机场',
lng: 110.049256,
lat: 25.210065,
...planeTarget,
},
{
name: '长沙黄花国际机场',
lng: 113.216412,
lat: 28.183613,
...planeTarget,
},
{
name: '井冈山机场',
lng: 114.745845,
lat: 26.852646,
...planeTarget,
},
];
scene.registerRenderService(ThreeRender);
const threeJSLayer = new ThreeLayer({
enableMultiPassRenderer: false,
// @ts-ignore
onAddMeshes: (threeScene, layer) => {
threeScene.add(new THREE.AmbientLight(0xffffff));
const sunlight = new THREE.DirectionalLight(0xffffff, 0.25);
sunlight.position.set(0, 80000000, 100000000);
sunlight.matrixWorldNeedsUpdate = true;
threeScene.add(sunlight);
// 使用 Three.js glTFLoader 加载模型
const loader = new GLTFLoader();
loader.load(
'https://gw.alipayobjects.com/os/bmw-prod/3ca0a546-92d8-4ba0-a89c-017c218d5bea.gltf',
(gltf) => {
const antModel = gltf.scene;
setMaterial(antModel);
layer.adjustMeshToMap(antModel);
layer.setMeshScale(antModel, 8000, 8000, 8000);
layer.setObjectLngLat(antModel, [113, 29], 0);
const animations = gltf.animations;
if (animations && animations.length) {
const mixer = new THREE.AnimationMixer(antModel);
const animation = animations[1];
const action = mixer.clipAction(animation);
action.timeScale = 5;
action.play();
layer.addAnimateMixer(mixer);
}
antModel.rotation.y = Math.PI;
// 向场景中添加模型
threeScene.add(antModel);
// 重绘图层
layer.render();
return '';
},
);
},
});
scene.addImage(
'plane',
'https://gw.alipayobjects.com/zos/bmw-prod/96327aa6-7fc5-4b5b-b1d8-65771e05afd8.svg',
);
const airPrtsLayer = new PointLayer()
.source(airPorts, {
parser: {
type: 'json',
x: 'lng',
y: 'lat',
},
})
.shape('name', 'text')
.color('rgb(22,119,255)')
.size(10);
const airLineLayer = new LineLayer({ blend: 'normal' })
.source(airLineData, {
parser: {
type: 'json',
x: 'lng',
y: 'lat',
x1: 'lng2',
y1: 'lat2',
},
})
.shape('arc3d')
.size(1)
.color('#f00')
.style({
sourceColor: 'rgb(22,119,255)',
targetColor: 'rgba(242,246,250,0.1)',
});
const airPlaneLayer = new LineLayer({ blend: 'normal', zIndex: 1 })
.source(airLineData, {
parser: {
type: 'json',
x: 'lng2',
y: 'lat2',
x1: 'lng',
y1: 'lat',
},
})
.shape('arc3d')
.texture('plane')
.size(30)
.color('#f00')
.animate({
duration: 0.2,
interval: 0.2,
trailLength: 0.2,
})
.style({
textureBlend: 'replace',
lineTexture: true, // 开启线的贴图功能
iconStep: 6, // 设置贴图纹理的间距
});
fetch(
'https://gw.alipayobjects.com/os/bmw-prod/ec5351c9-d22b-4918-ad6c-1838064d3a64.json',
)
.then((res) => res.json())
.then((data) => {
const layer = new LineLayer({})
.source(data)
.size(30000)
.shape('wall')
.style({
opacity: 0.4,
sourceColor: '#0DCCFF',
targetColor: 'rbga(255,255,255, 0)',
heightfixed: true,
});
scene.addLayer(layer);
const nameLayer = new PointLayer({ zIndex: 3 })
.source(data)
.color('rgb(22,119,255)')
.size(15)
.shape('name', 'text');
scene.addLayer(nameLayer);
});
const img: HTMLImageElement = new Image();
img.crossOrigin = 'none';
@ -344,7 +124,9 @@ export default class GridTile extends React.Component {
.source(geoData)
.size(1)
.shape('simple')
.color('rgb(22, 119, 255)')
// .shape('line')
// .color('rgb(22, 119, 255)')
.color('#f00')
.style({
vertexHeightScale: 2000,
opacity: 0.4,
@ -352,175 +134,7 @@ export default class GridTile extends React.Component {
scene.addLayer(layer);
};
const waveLayer = new PointLayer({ zIndex: 2, blend: 'additive' })
.source(
[
{ lng: 113, lat: 29, size: 10000 },
{ lng: 113.5, lat: 29.5, size: 30000 },
{
lng: 110.23681640625,
lat: 29.64509464986076,
size: 74020.50373907911,
},
{
lng: 115.01586914062499,
lat: 26.88777988202911,
size: 22908.885529976185,
},
{
lng: 111.181640625,
lat: 28.724313406473463,
size: 73359.37302978932,
},
{
lng: 112.686767578125,
lat: 29.257648503615542,
size: 18500.90838085843,
},
{
lng: 114.664306640625,
lat: 28.98892237190413,
size: 20293.183968726793,
},
{
lng: 113.90075683593749,
lat: 28.17855984939698,
size: 18051.412077639496,
},
{
lng: 111.51123046875,
lat: 27.45466493898314,
size: 37645.94186119526,
},
{
lng: 110.67626953125,
lat: 28.004101830368654,
size: 4214.588023703825,
},
{
lng: 114.43359375,
lat: 29.477861195816843,
size: 61722.01580332115,
},
{
lng: 110.445556640625,
lat: 26.96124577052697,
size: 70806.75519747598,
},
{
lng: 113.75244140624999,
lat: 27.88278388425912,
size: 70930.24993464859,
},
],
{
parser: {
type: 'json',
x: 'lng',
y: 'lat',
},
},
)
.shape('circle')
.color('rgb(22, 119, 255)')
.size('size', (v) => v)
.animate(true)
.style({
unit: 'meter',
});
const barLayer = new PointLayer({ zIndex: 2, depth: false })
.source(
[
{ lng: 113, lat: 29, size: 10000 },
{ lng: 113.5, lat: 29.5, size: 30000 },
{
lng: 110.23681640625,
lat: 29.64509464986076,
size: 74020.50373907911,
},
{
lng: 115.01586914062499,
lat: 26.88777988202911,
size: 22908.885529976185,
},
{
lng: 111.181640625,
lat: 28.724313406473463,
size: 73359.37302978932,
},
{
lng: 112.686767578125,
lat: 29.257648503615542,
size: 18500.90838085843,
},
{
lng: 114.664306640625,
lat: 28.98892237190413,
size: 20293.183968726793,
},
{
lng: 113.90075683593749,
lat: 28.17855984939698,
size: 18051.412077639496,
},
{
lng: 111.51123046875,
lat: 27.45466493898314,
size: 37645.94186119526,
},
{
lng: 110.67626953125,
lat: 28.004101830368654,
size: 4214.588023703825,
},
{
lng: 114.43359375,
lat: 29.477861195816843,
size: 61722.01580332115,
},
{
lng: 110.445556640625,
lat: 26.96124577052697,
size: 70806.75519747598,
},
{
lng: 113.75244140624999,
lat: 27.88278388425912,
size: 70930.24993464859,
},
],
{
parser: {
type: 'json',
x: 'lng',
y: 'lat',
},
},
)
.shape('cylinder')
.color('rgb(22, 119, 255)')
.size('size', (v) => [5, 5, v / 350])
.animate(true)
.style({
opacityLinear: {
enable: true, // true - false
dir: 'up', // up - down
},
lightEnable: false,
});
scene.on('loaded', () => {
scene.addLayer(waveLayer);
scene.addLayer(barLayer);
scene.addLayer(threeJSLayer);
scene.addLayer(airPrtsLayer);
scene.addLayer(airLineLayer);
scene.addLayer(airPlaneLayer);
});
scene.on('loaded', () => {});
}
public render() {