Shihuidev (#944)

* feat: pickbox 返回值增加选中id

* style: lint style
This commit is contained in:
YiQianYao 2022-01-20 20:21:39 +08:00 committed by GitHub
parent 985caab0d4
commit 540014e853
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 758 additions and 374 deletions

View File

@ -138,7 +138,11 @@ export default class PickingService implements IPickingService {
const pickedFeatureIdx = decodePickingColor(color);
if (pickedFeatureIdx !== -1 && !featuresIdMap[pickedFeatureIdx]) {
const rawFeature = layer.getSource().getFeatureById(pickedFeatureIdx);
features.push(rawFeature);
features.push({
// @ts-ignore
...rawFeature,
pickedFeatureIdx,
});
featuresIdMap[pickedFeatureIdx] = true;
}
}

View File

@ -250,3 +250,92 @@ export function bBoxToBounds(b1: BBox): IBounds {
[b1[2], b1[3]],
];
}
export function calDistance(p1: Point, p2: Point) {
return Math.sqrt(Math.pow(p1[0] - p2[0], 2) + Math.pow(p1[1] - p2[1], 2));
}
function dotMul(v1: Point, v2: Point) {
return v1[0] * v2[0] + v1[1] * v2[1];
}
function getMod(v: Point) {
return Math.sqrt(v[0] * v[0] + v[1] * v[1]);
}
export function calAngle(v1: Point, v2: Point) {
return (
(Math.acos(dotMul(v1, v2) / (getMod(v1) * getMod(v2))) * 180) / Math.PI
);
}
export function getAngle(v1: Point, v2: Point) {
// if(v2[0] < 0) {
// return calAngle(v1, v2) + 180
// } else {
// return calAngle(v1, v2)
// }
if (v2[0] > 0) {
if (v2[1] > 0) {
// 1
return 90 - (Math.atan(v2[1] / v2[0]) * 180) / Math.PI;
} else {
// 2
return 90 + (Math.atan(-v2[1] / v2[0]) * 180) / Math.PI;
}
} else {
if (v2[1] < 0) {
// 3
return 180 + (90 - (Math.atan(v2[1] / v2[0]) * 180) / Math.PI);
} else {
// 4
return 270 + (Math.atan(v2[1] / -v2[0]) * 180) / Math.PI;
}
}
}
interface IPathPoint {
start: Point;
end: Point;
dis: number;
rotation: number;
duration: number;
}
export function flow(coords: Point[], time: number = 100) {
if (!coords || coords.length < 2) {
return;
}
const originVec2: Point = [0, 1];
let totalDis = 0;
const path: IPathPoint[] = [];
for (let i = 0; i < coords.length - 1; i++) {
const p1: Point = coords[i];
const p2: Point = coords[i + 1];
const dis = calDistance(p1, p2);
totalDis += dis;
const direct: Point = [p1[0] - p2[0], p1[1] - p2[1]];
// const direct: Point = [p2[0] - p1[0], p2[1] - p1[1]];
let rotation = getAngle(originVec2, direct);
if (i > 0) {
const lastRotation = path[i - 1].rotation;
if (lastRotation - rotation > 360 - lastRotation + rotation) {
rotation = rotation + 360;
}
}
path.push({
start: p1,
end: p2,
dis,
rotation,
duration: 0,
});
}
path.map((point) => {
point.duration = time * (point.dis / totalDis);
});
return path;
}

View File

@ -1,7 +1,46 @@
import { LineLayer, Scene, PointLayer } from '@antv/l7';
import {
LineLayer,
Scene,
PointLayer,
flow,
MarkerLayer,
Marker,
} from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import * as React from 'react';
import { animate, linear } from 'popmotion';
interface IObject {
[key: string]: any;
}
function parseCSV(data: string) {
let arr = data.split('\n');
if (arr && arr[0]) {
let columns = arr[0].replace('\r', '').split(',');
let rows = arr.slice(1).map((d: string) => d.split(','));
let json = rows.map((row: string[]) => {
let object: IObject = {};
row.map((e: string, i: number) => {
let str = e.replace('\r', '');
let key = columns[i].replace('\n', '');
// console.log('key', key)
object[key] = str;
return '';
});
return object;
});
return json;
}
return [];
}
function getLngLat(data: any) {
return data.map((d: any) => {
return [+d.lng, +d.lat];
});
}
export default class Amap2demo_road extends React.Component {
// @ts-ignore
private scene: Scene;
@ -14,121 +53,155 @@ export default class Amap2demo_road extends React.Component {
const scene = new Scene({
id: 'map',
map: new GaodeMap({
center: [120.1145, 30.221],
pitch: 50,
zoom: 16.8,
viewMode: '3D',
center: [116.35, 40],
zoom: 12,
// zoom: 3
}),
});
this.scene = scene;
scene.on('loaded', () => {
fetch(
'https://gw.alipayobjects.com/os/bmw-prod/91d27a97-869a-459b-a617-498dcc9c3e7f.json',
'https://gw.alipayobjects.com/os/bmw-prod/89aa8682-2245-448b-be0d-710308cd63a6.csv',
)
.then((res) => res.json())
.then((res) => res.text())
.then((data) => {
scene.addImage(
'road',
'https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*haGlTpW2BQgAAAAAAAAAAAAAARQnAQ',
);
// @ts-ignore
const layer = new LineLayer()
.source(data)
.size(10)
.shape('line')
.texture('road')
.color('rgb(20, 180, 90)')
.animate({
interval: 1, // 间隔
duration: 1, // 持续时间,延时
trailLength: 2, // 流线长度
})
.style({
lineTexture: true, // 开启线的贴图功能
iconStep: 200, // 设置贴图纹理的间距
});
scene.addLayer(layer);
const jsonData = parseCSV(data);
const lnglatData = getLngLat(jsonData);
scene.addImage(
'start',
'https://gw.alipayobjects.com/zos/bmw-prod/ebb0af57-4a8a-46e0-a296-2d51f9fa8007.svg',
);
scene.addImage(
'visitor',
'https://gw.alipayobjects.com/zos/bmw-prod/64db255d-b636-4929-b072-068e75178b23.svg',
);
scene.addImage(
'museum',
'https://gw.alipayobjects.com/zos/bmw-prod/0630591d-64db-4057-a04d-d65f43aebf0f.svg',
);
scene.addImage(
'supermarket',
'https://gw.alipayobjects.com/zos/bmw-prod/ab42799d-dea6-4d37-bd62-3ee3e06bf6c0.svg',
);
scene.addImage(
'tower',
'https://gw.alipayobjects.com/zos/bmw-prod/6d27cf89-638c-432b-a8c4-cac289ee98a8.svg',
);
scene.addImage(
'end',
'https://gw.alipayobjects.com/zos/bmw-prod/59717737-5652-479f-9e6b-e7d2c5441446.svg',
);
const imageLayer = new PointLayer()
.source(
[
{
lng: 120.11025885601617,
lat: 30.22006389085372,
icon: 'start',
},
{
lng: 120.11123578376913,
lat: 30.220443561196277,
icon: 'visitor',
},
{
lng: 120.11408457779198,
lat: 30.22019805564678,
icon: 'museum',
},
{
lng: 120.11683172384723,
lat: 30.21875509667716,
icon: 'supermarket',
},
{
lng: 120.11945546294194,
lat: 30.218724022876376,
icon: 'tower',
},
{
lng: 120.1184189041221,
lat: 30.21783201718256,
icon: 'end',
},
],
const sd = {
type: 'FeatureCollection',
name: 'dl2',
crs: {
type: 'name',
properties: { name: 'urn:ogc:def:crs:OGC:1.3:CRS84' },
},
features: [
{
parser: {
type: 'json',
x: 'lng',
y: 'lat',
type: 'Feature',
properties: {},
geometry: {
type: 'MultiLineString',
coordinates: [
[
// [120.10236740112303, 30.25469303741397],
// [120.104341506958, 30.252542952311455],
// [120.10622978210449, 30.250096246503063],
// [120.10974884033202, 30.248613364842253],
// [120.11017799377441, 30.24661143909856],
// [120.11069297790527, 30.244387029323946],
// [120.11120796203613, 30.24245916678936],
// [120.11404037475586, 30.24156937132543],
// [120.11773109436037, 30.24194012041444],
// [120.12099266052248, 30.241865970708517],
// [120.12073516845703, 30.24053126643564],
// [120.12219429016112, 30.238455023761645],
// [120.12537002563475, 30.240086360983426],
// [120.12837409973145, 30.242533316047716],
// [120.12760162353517, 30.24661143909856],
// [120.12605667114256, 30.249503096524485],
// [120.12639999389648, 30.2540999151896],
// [120.12579917907715, 30.25521201642245],
// [120.12339591979979, 30.25521201642245],
// [120.12219429016112, 30.253729211980726],
// [120.11979103088379, 30.253877493432157],
// [120.11893272399901, 30.251282535717067],
// [120.11773109436037, 30.249280664359304],
// [120.11507034301759, 30.249058231690526],
...lnglatData,
// [
// 120.11507034301759,
// 30.249058231690526
// ],
// [
// 120.12,
// 30.249058231690526
// ]
],
],
},
},
)
.shape('icon', [
'start',
'visitor',
'museum',
'supermarket',
'tower',
'end',
])
.size(35)
],
};
const linelayer = new LineLayer({ blend: 'normal' })
.source(sd)
.size(2)
.shape('line')
.color('#8C1EB2')
// .animate({
// interval: 1, // 间隔
// duration: 1, // 持续时间,延时
// trailLength: 2, // 流线长度
// })
.style({
offsets: [0, 20],
// opacity: 'opacity',
sourceColor: '#f00', // 起点颜色
targetColor: '#0f0', // 终点颜色
});
scene.addLayer(imageLayer);
linelayer.on('inited', () => {
const source = linelayer.getSource();
const coords = source?.data?.dataArray[0]?.coordinates;
const path = flow(coords, 50000);
runPath(path, 0);
// @ts-ignore
function runPath(pathData: any, startIndex: number) {
const path = pathData[startIndex];
if (!path) return;
const { start, end, duration, rotation } = path;
let startRotation = 360 - scene.getRotation();
let timer0 = animate({
from: {
rotation: startRotation,
},
to: {
rotation: rotation,
},
ease: linear,
duration: 600,
onUpdate: (o) => {
scene.setRotation(o.rotation);
},
onComplete: () => {
timer0.stop();
// @ts-ignore
timer0 = null;
let timer = animate({
from: {
lng: start[0],
lat: start[1],
},
to: {
lng: end[0],
lat: end[1],
},
ease: linear,
duration,
onUpdate: (o) => {
scene.setCenter([o.lng, o.lat]);
},
onComplete: () => {
timer.stop();
// @ts-ignore
timer = null;
setTimeout(() => {
runPath(pathData, startIndex + 1);
}, 500);
},
});
},
});
}
});
scene.addLayer(linelayer);
});
});
}

View File

@ -1,4 +1,4 @@
import { LineLayer, Scene, PointLayer } from '@antv/l7';
import { LineLayer, Scene, PointLayer, Marker, MarkerLayer } from '@antv/l7';
import { GaodeMap, GaodeMapV2, Map } from '@antv/l7-maps';
import * as React from 'react';
import { animate, easeInOut } from 'popmotion';
@ -132,138 +132,15 @@ export default class GridTile2 extends React.Component {
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.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';
img.src =
// 'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*UkvYRYS5jTAAAAAAAAAAAAAAARQnAQ';
// 'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*6dzKS42L8_8AAAAAAAAAAAAAARQnAQ'
'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*dPgXQJ9eUtoAAAAAAAAAAAAAARQnAQ';
img.onload = function() {
const data = getImageData(img);
@ -299,73 +176,51 @@ export default class GridTile2 extends React.Component {
.color('rgb(22, 119, 255)')
.style({
vertexHeightScale: 2000,
// opacity: 0.4,
sourceColor: '#f00',
targetColor: '#0f0',
});
scene.addLayer(layer);
};
const waveLayer = new PointLayer({ zIndex: 2, blend: 'additive' })
scene.addImage(
'start',
'https://gw.alipayobjects.com/zos/bmw-prod/ebb0af57-4a8a-46e0-a296-2d51f9fa8007.svg',
);
const imageLayer = new PointLayer()
.source(
[
{ lng: 113, lat: 29, size: 10000 },
{ lng: 113.5, lat: 29.5, size: 30000 },
{
lng: 111.641101,
lat: 28.91165,
cityData: '城市数据',
},
],
{
parser: {
type: 'json',
x: 'lng',
y: 'lat',
},
},
)
.shape('cityData', 'text')
.size(16)
.style({
textAnchor: 'left', // 文本相对锚点的位置 center|left|right|top|bottom|top-left
textOffset: [0, 0], // 文本相对锚点的偏移量 [水平, 垂直]
spacing: 2, // 字符间距
padding: [1, 1], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近
stroke: '#ffffff', // 描边颜色
strokeWidth: 0.3, // 描边宽度
strokeOpacity: 1.0,
});
const pointLayer = new PointLayer()
.source(
[
{
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,
lng: 111.641101,
lat: 28.91165,
},
],
{
@ -377,96 +232,45 @@ export default class GridTile2 extends React.Component {
},
)
.shape('circle')
.color('rgb(22, 119, 255)')
.size('size', (v) => v)
.animate(true)
.style({
unit: 'meter',
});
.size(35)
.color('#fff')
.style({});
const height = 200;
const dom = document.createElement('div');
dom.innerHTML = `
<div style="width:100px;height:${height}px;position:relative;">
<div style="position: absolute;width: 8px;height: 8px;top: 10px;border-radius:5px;background: rgba(150, 238, 150, 1.0);"></div>
<div style="position: absolute;width: 2px;height: 100%;top: 10px;left: 3px;background-image: linear-gradient(rgba(150, 238, 150, 0.4), rgba(150, 238, 150, 0))"></div>
<div style="
position: absolute;
width: 100px;
height: 20px;
left: 15px;top: 5px;
background-image: linear-gradient(to right, rgba(150, 238, 150, 0.4), rgba(150, 238, 150, 0));
color: #fff;
padding-left: 15px;
line-height: 20px;
font-size: 12px;
">
</div>
</div>
`;
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,
});
const markerLayer = new MarkerLayer({});
const marker = new Marker()
.setLnglat({
lng: 111.641101,
lat: 28.91165,
})
.setElement(dom);
markerLayer.addMarker(marker);
scene.on('loaded', () => {
// scene.addLayer(pointLayer);
// scene.addLayer(imageLayer);
scene.addMarkerLayer(markerLayer);
// scene.addLayer(waveLayer);
// scene.addLayer(barLayer);

View File

@ -0,0 +1,204 @@
import {
LineLayer,
Scene,
PointLayer,
flow,
MarkerLayer,
Marker,
} from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import * as React from 'react';
import { cloneDeep } from 'lodash';
interface IObject {
[key: string]: any;
}
function parseCSV(data: string) {
let arr = data.split('\n');
if (arr && arr[0]) {
let columns = arr[0].replace('\r', '').split(',');
let rows = arr.slice(1).map((d: string) => d.split(','));
let json = rows.map((row: string[]) => {
let object: IObject = {};
row.map((e: string, i: number) => {
let str = e.replace('\r', '');
let key = columns[i].replace('\n', '');
object[key] = str;
return '';
});
return object;
});
return json;
}
return [];
}
function getLngLat2(data: any) {
let res = [];
for (let i = 0; i < data.length - 1; i++) {
let start = data[i];
let end = data[i + 1];
res.push({
lng1: start.lng,
lat1: start.lat,
lng2: end.lng,
lat2: end.lat,
opacity: 0.6,
});
}
return res;
}
function createMarker(
lng: number,
lat: number,
time: string,
loc: string,
event: string,
) {
const dom = document.createElement('div');
dom.innerHTML = `
<div class="infoPlane" style="
zIndex: 99;
padding: 5px;
border-radius: 6px;
background: rgba(173,216,230, 0.8);
color: #DC143C;
">
<div style="
font-size: 12px;
font-weight: 800;
border-bottom: 1px #DC143C;
">${time}</div>
<div style="
height: 1px;
width: 95%;
margin: 0 auto;
background: #DC143C;
"></div>
<div style="
font-size: 12px;
">${loc}</div>
<div style="
font-size: 12px;
">${event}</div>
</div>
`;
const marker = new Marker().setLnglat({ lng, lat }).setElement(dom);
return marker;
}
export default class Amap2demo_road 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: [116.35, 40],
zoom: 3,
style: 'dark',
}),
});
this.scene = scene;
scene.on('loaded', () => {
fetch(
'https://gw.alipayobjects.com/os/bmw-prod/89aa8682-2245-448b-be0d-710308cd63a6.csv',
)
.then((res) => res.text())
.then((data) => {
const jsonData = parseCSV(data);
const lnglatData2 = getLngLat2(jsonData);
const pointLayers = new PointLayer()
.source(jsonData, {
parser: {
type: 'json',
x: 'lng',
y: 'lat',
},
})
.shape('circle')
.size(5)
.color('#DC143C');
scene.addLayer(pointLayers);
const linelayer = new LineLayer({ blend: 'normal', autoFit: true })
.source(lnglatData2, {
parser: {
type: 'json',
x: 'lng1',
y: 'lat1',
x1: 'lng2',
y1: 'lat2',
},
})
.size(2)
.shape('arc')
.color('#DC143C')
.animate({
interval: 1, // 间隔
duration: 1, // 持续时间,延时
trailLength: 2, // 流线长度
})
.style({
opacity: 'opacity',
});
scene.addLayer(linelayer);
setTimeout(() => {
addMarker(jsonData, 0);
}, 600);
function addMarker(data: any[], index: number) {
let d = data[index];
if (!d) {
return;
}
setTimeout(() => {
let m = createMarker(d.lng, d.lat, d.time, d.loc, d.do);
scene.addMarker(m);
let lineData = cloneDeep(lnglatData2);
if (lineData[index]) {
lineData[index].opacity = 1;
linelayer.setData(lineData);
}
addMarker(data, index + 1);
}, 400);
}
});
});
}
public render() {
return (
<>
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
</>
);
}
}

View File

@ -0,0 +1,205 @@
import {
LineLayer,
Scene,
PointLayer,
flow,
MarkerLayer,
Marker,
} from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import * as React from 'react';
import { cloneDeep } from 'lodash';
interface IObject {
[key: string]: any;
}
function parseCSV(data: string) {
let arr = data.split('\n');
if (arr && arr[0]) {
let columns = arr[0].replace('\r', '').split(',');
let rows = arr.slice(1).map((d: string) => d.split(','));
let json = rows.map((row: string[]) => {
let object: IObject = {};
row.map((e: string, i: number) => {
let str = e.replace('\r', '');
let key = columns[i].replace('\n', '');
object[key] = str;
return '';
});
return object;
});
return json;
}
return [];
}
function getLngLat2(data: any) {
let res = [];
for (let i = 0; i < data.length - 1; i++) {
let start = data[i];
let end = data[i + 1];
res.push({
lng1: start.lng,
lat1: start.lat,
lng2: end.lng,
lat2: end.lat,
opacity: 0.4,
});
}
return res;
}
export default class Amap2demo_road 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: [116.35, 40],
zoom: 3,
style: 'dark',
}),
});
this.scene = scene;
scene.on('loaded', () => {
fetch(
'https://gw.alipayobjects.com/os/bmw-prod/89aa8682-2245-448b-be0d-710308cd63a6.csv',
)
.then((res) => res.text())
.then((data) => {
const jsonData = parseCSV(data);
jsonData.map((d: any, i: number) => (d.index = i + 1));
const lnglatData2 = getLngLat2(jsonData);
const pointLayers = new PointLayer()
.source([jsonData[0]], {
parser: {
type: 'json',
x: 'lng',
y: 'lat',
},
})
.shape('circle')
.size(5)
.color('#DC143C')
.style({
opacity: 0.5,
});
scene.addLayer(pointLayers);
const pointLayer2 = new PointLayer()
.source([jsonData[0]], {
parser: {
type: 'json',
x: 'lng',
y: 'lat',
},
})
.shape('circle')
.size(14)
.color('rgba(255, 0, 0, 0.01)')
// .color('')
.style({
strokeWidth: 2,
stroke: '#f00',
opacity: 1,
offsets: [21, 2],
});
scene.addLayer(pointLayer2);
const pointText = new PointLayer()
.source([jsonData[0]], {
parser: {
type: 'json',
x: 'lng',
y: 'lat',
},
})
.shape('index', 'text')
.size(18)
.color('#f00')
.style({
textAnchor: 'center',
textOffset: [28, 0],
textAllowOverlap: true,
});
scene.addLayer(pointText);
const linelayer = new LineLayer({ blend: 'normal', autoFit: true })
.source(lnglatData2, {
parser: {
type: 'json',
x: 'lng1',
y: 'lat1',
x1: 'lng2',
y1: 'lat2',
},
})
.size(2)
.shape('arc')
.color('#DC143C')
.animate({
interval: 1, // 间隔
duration: 1, // 持续时间,延时
trailLength: 2, // 流线长度
})
.style({
opacity: 'opacity',
});
scene.addLayer(linelayer);
setTimeout(() => {
addPoint(0);
}, 600);
function addPoint(index: number) {
let d = data[index];
if (!d) {
return;
}
setTimeout(() => {
let pointData = cloneDeep(jsonData);
pointLayers.setData(pointData.slice(0, index + 1));
pointLayer2.setData(pointData.slice(0, index + 1));
pointText.setData(pointData.slice(0, index + 1));
let lineData = cloneDeep(lnglatData2);
if (lineData[index]) {
lineData[index].opacity = 1;
linelayer.setData(lineData);
}
addPoint(index + 1);
}, 400);
}
});
});
}
public render() {
return (
<>
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
</>
);
}
}

View File

@ -1,7 +1,6 @@
import { LineLayer, Scene } from '@antv/l7';
import { LineLayer, Scene, flow } from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import * as React from 'react';
export default class Amap2demo_lineLinear extends React.Component {
// @ts-ignore
private scene: Scene;
@ -75,6 +74,7 @@ export default class Amap2demo_lineLinear extends React.Component {
targetColor: 'rgba(0, 255, 0, 0.2)',
})
.active(true);
scene.addLayer(layer);
});
}

View File

@ -75,6 +75,8 @@ import LineWall from './components/linewall'
import GridTile from './components/gridTile'
import GridTile2 from './components/gridTile2'
import Cluster from './components/cluster'
import Hot from './components/hot'
import Hot2 from './components/hot2'
// @ts-ignore
storiesOf('地图方法', module)
@ -154,3 +156,6 @@ storiesOf('地图方法', module)
.add('GridTile', () => <GridTile/>)
.add('GridTile2', () => <GridTile2/>)
.add('Cluster', () => <Cluster/>)
.add('Hot1', () => <Hot/>)
.add('Hot2', () => <Hot2/>)