This commit is contained in:
lzxue 2022-01-13 19:42:24 +08:00
commit b961aab783
57 changed files with 2832 additions and 399 deletions

View File

@ -0,0 +1,6 @@
---
title: Label
order: 4
---
`markdown:docs/api/point_layer/iconfont.zh.md`

View File

@ -0,0 +1,88 @@
---
title: iconfont 标注
order: 4
---
`markdown:docs/common/style.md`
可以认为 iconfont 标注就是特殊的文本标注,它允许用户以绘制文字的方式绘制简单的图标。
## 使用
iconfont 支持绘制 unicode 图标,在使用的时候需要提前指定对应的 unicode 映射文件。
```javascript
import { PointLayer } from '@antv/l7';
```
<img width="60%" style="display: block;margin: 0 auto;" alt="案例" src='https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*WdOfSI_uyxIAAAAAAAAAAAAAARQnAQ'>
```javascript
// 指定 iconfont 映射为字体样式的名称
const fontFamily = 'iconfont';
// 指定 iconfont 字体文件
const fontPath =
'//at.alicdn.com/t/font_2534097_fcae9o2mxbv.woff2?t=1622200439140';
// 全局添加资源
scene.addFontFace(fontFamily, fontPath);
// 全局添加 iconfont 字段的映射
scene.addIconFont('icon1', '&#xe6d4;');
scene.on('loaded', () => {
fetch(
'https://gw.alipayobjects.com/os/bmw-prod/70408903-80db-4278-a318-461604acb2df.json',
)
.then((res) => res.json())
.then((data) => {
const pointLayer = new PointLayer({})
.source(data.list, {
parser: {
type: 'json',
x: 'j',
y: 'w',
},
})
.shape('icon', 'text') // 指定需要映射字段为 icon、shape 类型和普通的文字标注一样为 text
.size(20)
.color('w', ['#a6cee3', '#1f78b4', '#b2df8a', '#33a02c', '#fb9a99'])
.style({
textAnchor: 'center', // 文本相对锚点的位置 center|left|right|top|bottom|top-left
textOffset: [40, 0], // 文本相对锚点的偏移量 [水平, 垂直]
padding: [0, 0], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近
stroke: '#ffffff', // 描边颜色
fontFamily,
iconfont: true, // 开启 iconfont 映射
textAllowOverlap: true,
});
scene.addLayer(pointLayer);
});
});
```
🌟 关于 iconfont 资源使用可以前往 iconfont 官网 [官网传送门](https://iconfont.cn/)
<img width="60%" style="display: block;margin: 0 auto;" alt="案例" src='https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*PMuES7vfcKEAAAAAAAAAAAAAARQnAQ'>
### shape
- field 标注的字段名称
- shapeType 'text'
```javascript
layer.shape('iconfontField', 'text');
```
🌟 iconfont 就是特殊的文本标注,也属于文本标注,所以在 shape 使用上和普通的文本标注保持一致。
### style
- iconfont `boolean` 需要设为 true (默认为 false
✨ iconfont 其他 style 参数的使用和普通的文本标注的参数保持一致
[在线案例](../../../examples/point/text#iconfont)
`markdown:docs/common/layer/base.md`

View File

@ -1,6 +1,6 @@
---
title: Control
order: 2
order: 12
---
How to use the map control

View File

@ -1,6 +1,6 @@
---
title: 组件
order: 2
order: 12
---
如何使用组件

View File

@ -1,6 +1,6 @@
---
title: Layer
order: 2
order: 12
---
Layer init and interaction

View File

@ -1,6 +1,6 @@
---
title: 图层
order: 2
order: 12
---
图层初始化与交互

View File

@ -1,6 +1,6 @@
---
title: Map
order: 0
order: 12
---
how to use L7 Initialize third-party maps

View File

@ -1,6 +1,6 @@
---
title: 地图
order: 0
order: 12
---
介绍如何初始化一个第三方底图

View File

@ -1,6 +1,6 @@
---
title: Marker
order: 2
order: 12
---
add Rich text annotation to scene

View File

@ -1,6 +1,6 @@
---
title: Marker
order: 2
order: 12
---
通过添加dom实现富文本地图标注

View File

@ -9,11 +9,6 @@
"title": "高德地图",
"screenshot":"https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*1_W2SIR8swwAAAAAAAAAAAAAARQnAQ"
},
{
"filename": "amap_car.js",
"title": "高德地图 car",
"screenshot":"https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*C3JRTI_qlxEAAAAAAAAAAAAAARQnAQ"
},
{
"filename": "mapbox_ant.js",
"title": "mapbox 地图",

View File

@ -1,4 +1,4 @@
import { Scene, PolygonLayer } from '@antv/l7';
import { Scene, PolygonLayer, LineLayer, PointLayer } from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import { ThreeLayer, ThreeRender } from '@antv/l7-three';
import * as THREE from 'three';
@ -60,10 +60,10 @@ function travel(
const scene = new Scene({
id: 'map',
map: new GaodeMap({
center: [ 112, 35.39847 ],
pitch: 45,
rotation: 30,
zoom: 5
center: [ 110, 35.39847 ],
pitch: 20,
style: 'dark',
zoom: 3
})
});
@ -75,28 +75,46 @@ scene.on('loaded', () => {
)
.then(d => d.json())
.then(data => {
const polygonlayer = new PolygonLayer({
name: '01',
zIndex: -1
})
const textLayer = new PointLayer({ zIndex: 1 })
.source(data)
.color('name', [
'#2E8AE6',
'#69D1AB',
'#DAF291',
'#FFD591',
'#FF7A45',
'#CF1D49'
])
.color('rgb(22,119,255)')
.size(12)
.shape('name', 'text');
const polygonlayer = new PolygonLayer({})
.source(data)
.color('rgb(22,119,255)')
.shape('fill')
.select(true)
.active({
enable: true,
blend: 0.5
})
.style({
opacity: 1.0
opacity: 0.6,
opacityLinear: {
enable: true,
dir: 'out' // in - out
}
});
const linelayer = new LineLayer({ })
.source(data)
.color('rgb(72,169,255)')
.shape('line')
.size(0.5)
.style({
opacity: 0.6
});
scene.addLayer(polygonlayer);
scene.addLayer(textLayer);
scene.addLayer(linelayer);
});
const threeJSLayer = new ThreeLayer({
zIndex: 2,
enableMultiPassRenderer: false,
onAddMeshes: (threeScene, layer) => {
// 添加光
@ -149,7 +167,7 @@ scene.on('loaded', () => {
const points = curve.getPoints(200);
const geometry = new THREE.BufferGeometry().setFromPoints(points);
const material = new THREE.LineBasicMaterial({ color: 0xff0000 });
const material = new THREE.LineBasicMaterial({ color: new THREE.Color('rgb(22,119,255)') });
const line = new THREE.LineLoop(geometry, material);
threeScene.add(line);
@ -162,7 +180,7 @@ scene.on('loaded', () => {
gltf => {
// 根据 GeoJSON 数据放置模型
const gltfScene = gltf.scene.clone();
setDouble(gltfScene);
setMaterial(gltfScene);
layer.getSource().data.dataArray.forEach(() => {
layer.adjustMeshToMap(gltfScene);
gltfScene.scale.set(500000, 500000, 500000);
@ -217,9 +235,9 @@ scene.on('loaded', () => {
scene.addLayer(threeJSLayer);
});
function setDouble(object) {
function setMaterial(object) {
if (object.children && object.children.length && object.children.length > 0) {
object.children.map(child => setDouble(child));
object.children.map(child => setMaterial(child));
} else if (object.material) {
object.material.side = THREE.DoubleSide;
}

View File

@ -1,31 +0,0 @@
import { Scene, LineLayer } from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
const scene = new Scene({
id: 'map',
map: new GaodeMap({
center: [ 120.19382669582967, 30.258134 ],
pitch: 0,
zoom: 16,
style: 'dark'
})
});
scene.on('loaded', () => {
fetch(
'https://gw.alipayobjects.com/os/basement_prod/40ef2173-df66-4154-a8c0-785e93a5f18e.json'
)
.then(res => res.json())
.then(data => {
const layer = new LineLayer()
.source(data)
.size(1.5)
.shape('line')
.color('#25d8b7')
.animate({
interval: 1, // 间隔
duration: 1, // 持续时间,延时
trailLength: 2 // 流线长度
});
scene.addLayer(layer);
});
});

View File

@ -1,4 +1,4 @@
import { Scene, PolygonLayer, PointLayer, LineLayer } from '@antv/l7';
import { Scene, PolygonLayer, LineLayer } from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
const scene = new Scene({
@ -14,55 +14,14 @@ const scene = new Scene({
});
scene.on('loaded', () => {
scene.addImage(
'westLakeBuilding',
'https://gw.alipayobjects.com/zos/bmw-prod/8c3f6415-c1ca-4f7e-8ac6-89571ac75309.svg'
);
scene.addImage(
'arrow',
'https://gw.alipayobjects.com/zos/bmw-prod/ce83fc30-701f-415b-9750-4b146f4b3dd6.svg'
);
scene.addImage(
'shop',
'https://gw.alipayobjects.com/zos/bmw-prod/238e7c7c-c26c-454c-9341-35d466c4b991.svg'
);
scene.addImage(
'hospital',
'https://gw.alipayobjects.com/zos/bmw-prod/fd08bf28-f73e-4b9c-ba8d-2c73d4fca6dc.svg'
);
scene.addImage(
'westlake',
'https://gw.alipayobjects.com/zos/bmw-prod/7b011298-454d-431b-9637-ab23a752e731.svg'
);
scene.addImage(
'ship',
'https://gw.alipayobjects.com/zos/bmw-prod/104cfca2-f3c5-49e8-b084-d339f4ba1adc.svg'
);
scene.addImage(
'travel',
'https://gw.alipayobjects.com/zos/bmw-prod/904d047a-16a5-461b-a921-98fa537fc04a.svg'
);
scene.addImage(
'pavilion',
'https://gw.alipayobjects.com/zos/bmw-prod/8839795d-43d9-46c5-a5b1-95bf9a1146a0.svg'
);
scene.addImage(
'museum',
'https://gw.alipayobjects.com/zos/bmw-prod/5436a335-8ec3-40e4-9c93-16d0f844b0e7.svg'
);
scene.addImage(
'bridge',
'https://gw.alipayobjects.com/zos/bmw-prod/b88e6f2f-ad12-4980-969e-3849cbcd28c6.svg'
);
scene.addImage(
'school',
'https://gw.alipayobjects.com/zos/bmw-prod/948e665d-ab1e-4010-b75a-236057837bec.svg'
);
fetch('https://gw.alipayobjects.com/os/bmw-prod/67130c6c-7f49-4680-915c-54e69730861d.json')
.then(data => data.json())
.then(({ lakeBorderData, lakeData, landData, westLakePoiData, poiData }) => {
.then(({ lakeBorderData, lakeData, landData }) => {
const lakeLayer = new PolygonLayer()
.source(lakeData)
.shape('fill')
@ -98,34 +57,10 @@ scene.on('loaded', () => {
}
});
const westLakePoiLayer = new PointLayer({ zIndex: 1 })
.source(westLakePoiData, {
parser: {
type: 'json',
x: 'lng',
y: 'lat'
}
})
.shape('type', v => v)
.size(40);
const poiLayer = new PointLayer({ zIndex: 1 })
.source(
poiData, {
parser: {
type: 'json',
x: 'lng',
y: 'lat'
}
})
.shape('type', v => v)
.size(10);
scene.addLayer(lakeLayer);
scene.addLayer(lakeBorderLayer);
scene.addLayer(landLayer);
scene.addLayer(westLakePoiLayer);
scene.addLayer(poiLayer);
});
@ -135,20 +70,12 @@ scene.on('loaded', () => {
.then(res => res.json())
.then(data => {
const colors = [
'#66c2a4',
'#2ca25f',
'#006d2c'
];
// @ts-ignore
const layer = new LineLayer({})
.source(data)
.size(2.5)
.size(3)
.shape('line')
.texture('arrow')
.color('', () => {
return colors[Math.floor(Math.random() * colors.length)];
})
.color('rgb(22,119,255)')
.animate({
interval: 1, // 间隔
duration: 1, // 持续时间,延时
@ -157,7 +84,7 @@ scene.on('loaded', () => {
.style({
opacity: 0.6,
lineTexture: true, // 开启线的贴图功能
iconStep: 20, // 设置贴图纹理的间距
iconStep: 10, // 设置贴图纹理的间距
borderWidth: 0.4, // 默认文 0最大有效值为 0.5
borderColor: '#fff' // 默认为 #ccc
});

View File

@ -1,63 +0,0 @@
import { Scene, CityBuildingLayer, LineLayer } from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
const scene = new Scene({
id: 'map',
map: new GaodeMap({
style: 'dark',
center: [ 120.173104, 30.244072 ],
pitch: 70.41138037735848,
zoom: 17.18,
rotation: 2.24, // 358.7459759480504
minZoom: 14
})
});
scene.on('loaded', () => {
fetch(
'https://gw.alipayobjects.com/os/rmsportal/ggFwDClGjjvpSMBIrcEx.json'
)
.then(res => res.json())
.then(data => {
const layer = new CityBuildingLayer(
{
zIndex: 0
}
);
layer
.source(data)
.size('floor', [ 100, 500 ])
.color('rgba(242,246,250,0.5)')
.animate({
enable: true
})
.style({
opacity: 1.0,
baseColor: 'rgba(36,16,63,0.3)',
windowColor: '#0e0220',
brightColor: '#08faee'
});
scene.addLayer(layer);
});
fetch(
'https://gw.alipayobjects.com/os/basement_prod/40ef2173-df66-4154-a8c0-785e93a5f18e.json'
)
.then(res => res.json())
.then(data => {
const layer = new LineLayer({
zIndex: 0
})
.source(data)
.size(1)
.shape('line')
.color('#ff893a')
.animate({
interval: 1, // 间隔
duration: 2, // 持续时间,延时
trailLength: 2 // 流线长度
});
scene.addLayer(layer);
});
});

View File

@ -1,14 +1,13 @@
import { Scene, CityBuildingLayer, LineLayer } from '@antv/l7';
import { Scene, CityBuildingLayer, LineLayer, PolygonLayer } from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
const scene = new Scene({
id: 'map',
map: new GaodeMap({
style: 'dark',
center: [ 120.145319, 30.238915 ],
pitch: 45,
zoom: 12.91,
viewMode: '3D'
center: [ 120.145, 30.238915 ],
pitch: 60,
zoom: 13.2
})
});
fetch(
@ -42,6 +41,57 @@ fetch(
scene.addLayer(pointLayer);
});
fetch(
'https://gw.alipayobjects.com/os/bmw-prod/67130c6c-7f49-4680-915c-54e69730861d.json'
)
.then(data => data.json())
.then(
({
lakeBorderData,
lakeData,
landData
}) => {
const lakeLayer = new PolygonLayer()
.source(lakeData)
.shape('fill')
.color('#1E90FF')
.style({
opacity: 0.4,
opacityLinear: {
enable: true,
dir: 'out' // in - out
}
});
const landLayer = new PolygonLayer()
.source(landData)
.shape('fill')
.color('#3CB371')
.style({
opacity: 0.4,
opacityLinear: {
enable: true,
dir: 'in' // in - out
}
});
const lakeBorderLayer = new PolygonLayer()
.source(lakeBorderData)
.shape('fill')
.color('#ccc')
.style({
opacity: 0.5,
opacityLinear: {
enable: true,
dir: 'in' // in - out
}
});
scene.addLayer(lakeLayer);
scene.addLayer(lakeBorderLayer);
scene.addLayer(landLayer);
}
);
fetch(
'https://gw.alipayobjects.com/os/basement_prod/40ef2173-df66-4154-a8c0-785e93a5f18e.json'
)

View File

@ -0,0 +1,320 @@
import { Scene, PointLayer, EarthLayer } from '@antv/l7';
import { Earth } from '@antv/l7-maps';
const scene = new Scene({
id: 'map',
map: new Earth({})
});
const d = [
{ lng: 121.61865234375, lat: 25.29437116258816 },
{ lng: 121.058349609375, lat: 25.015928763367857 },
{ lng: 120.7177734375, lat: 24.587090339209634 },
{ lng: 120.28930664062499, lat: 23.936054914599815 },
{ lng: 120.12451171875, lat: 23.553916518321625 },
{ lng: 120.08056640625, lat: 23.120153621695614 },
{ lng: 120.234375, lat: 22.867317960075614 },
{ lng: 120.43212890625, lat: 22.52270570348246 },
{ lng: 120.65185546875, lat: 22.370396344320053 },
{ lng: 120.750732421875, lat: 21.922663209325922 },
{ lng: 120.948486328125, lat: 22.268764039073968 },
{ lng: 121.124267578125, lat: 22.806567100271522 },
{ lng: 121.56372070312499, lat: 23.915970370510227 },
{ lng: 121.88232421875, lat: 24.557116164309626 },
{ lng: 121.95922851562501, lat: 25.075648445630527 },
{ lng: 109.97314453125, lat: 20.076570104545173 },
{ lng: 108.896484375, lat: 19.663280219987662 },
{ lng: 108.61083984375, lat: 18.979025953255267 },
{ lng: 108.80859375, lat: 18.47960905583197 },
{ lng: 109.599609375, lat: 18.35452552912664 },
{ lng: 110.32470703125, lat: 18.771115062337024 },
{ lng: 111.005859375, lat: 19.78738018198621 },
{ lng: 127.657407, lat: 49.76027 },
{ lng: 129.397818, lat: 49.4406 },
{ lng: 130.582293, lat: 48.729687 },
{ lng: 130.987282, lat: 47.790132 },
{ lng: 132.506672, lat: 47.78897 },
{ lng: 133.373596, lat: 48.183442 },
{ lng: 135.026311, lat: 48.47823 },
{ lng: 134.500814, lat: 47.57844 },
{ lng: 134.112362, lat: 47.212467 },
{ lng: 133.769644, lat: 46.116927 },
{ lng: 133.097127, lat: 45.144066 },
{ lng: 131.883454, lat: 45.321162 },
{ lng: 131.025212, lat: 44.967953 },
{ lng: 131.288555, lat: 44.11152 },
{ lng: 131.144688, lat: 42.92999 },
{ lng: 130.633866, lat: 42.903015 },
{ lng: 130.640016, lat: 42.395009 },
{ lng: 129.994267, lat: 42.985387 },
{ lng: 129.596669, lat: 42.424982 },
{ lng: 128.052215, lat: 41.994285 },
{ lng: 128.208433, lat: 41.466772 },
{ lng: 127.343783, lat: 41.503152 },
{ lng: 126.869083, lat: 41.816569 },
{ lng: 126.182045, lat: 41.107336 },
{ lng: 125.079942, lat: 40.569824 },
{ lng: 124.265625, lat: 39.928493 },
{ lng: 122.86757, lat: 39.637788 },
{ lng: 122.131388, lat: 39.170452 },
{ lng: 121.054554, lat: 38.897471 },
{ lng: 121.585995, lat: 39.360854 },
{ lng: 121.376757, lat: 39.750261 },
{ lng: 122.168595, lat: 40.422443 },
{ lng: 121.640359, lat: 40.94639 },
{ lng: 120.768629, lat: 40.593388 },
{ lng: 119.639602, lat: 39.898056 },
{ lng: 119.023464, lat: 39.252333 },
{ lng: 118.042749, lat: 39.204274 },
{ lng: 117.532702, lat: 38.737636 },
{ lng: 118.059699, lat: 38.061476 },
{ lng: 118.87815, lat: 37.897325 },
{ lng: 118.911636, lat: 37.448464 },
{ lng: 119.702802, lat: 37.156389 },
{ lng: 120.823457, lat: 37.870428 },
{ lng: 121.711259, lat: 37.481123 },
{ lng: 122.357937, lat: 37.454484 },
{ lng: 122.519995, lat: 36.930614 },
{ lng: 121.104164, lat: 36.651329 },
{ lng: 120.637009, lat: 36.11144 },
{ lng: 119.664562, lat: 35.609791 },
{ lng: 119.151208, lat: 34.909859 },
{ lng: 120.227525, lat: 34.360332 },
{ lng: 120.620369, lat: 33.376723 },
{ lng: 121.229014, lat: 32.460319 },
{ lng: 121.908146, lat: 31.692174 },
{ lng: 121.891919, lat: 30.949352 },
{ lng: 121.264257, lat: 30.676267 },
{ lng: 121.503519, lat: 30.142915 },
{ lng: 122.092114, lat: 29.83252 },
{ lng: 121.938428, lat: 29.018022 },
{ lng: 121.684439, lat: 28.225513 },
{ lng: 121.125661, lat: 28.135673 },
{ lng: 120.395473, lat: 27.053207 },
{ lng: 119.585497, lat: 25.740781 },
{ lng: 118.656871, lat: 24.547391 },
{ lng: 117.281606, lat: 23.624501 },
{ lng: 115.890735, lat: 22.782873 },
{ lng: 114.763827, lat: 22.668074 },
{ lng: 114.152547, lat: 22.22376 },
{ lng: 113.80678, lat: 22.54834 },
{ lng: 113.241078, lat: 22.051367 },
{ lng: 111.843592, lat: 21.550494 },
{ lng: 110.785466, lat: 21.397144 },
{ lng: 110.444039, lat: 20.341033 },
{ lng: 109.889861, lat: 20.282457 },
{ lng: 109.627655, lat: 21.008227 },
{ lng: 109.864488, lat: 21.395051 },
{ lng: 108.522813, lat: 21.715212 },
{ lng: 108.05018, lat: 21.55238 },
{ lng: 107.04342, lat: 21.811899 },
{ lng: 106.567273, lat: 22.218205 },
{ lng: 106.725403, lat: 22.794268 },
{ lng: 105.811247, lat: 22.976892 },
{ lng: 105.329209, lat: 23.352063 },
{ lng: 104.476858, lat: 22.81915 },
{ lng: 103.504515, lat: 22.703757 },
{ lng: 102.706992, lat: 22.708795 },
{ lng: 102.170436, lat: 22.464753 },
{ lng: 101.652018, lat: 22.318199 },
{ lng: 101.80312, lat: 21.174367 },
{ lng: 101.270026, lat: 21.201652 },
{ lng: 101.180005, lat: 21.436573 },
{ lng: 101.150033, lat: 21.849984 },
{ lng: 100.416538, lat: 21.558839 },
{ lng: 99.983489, lat: 21.742937 },
{ lng: 99.240899, lat: 22.118314 },
{ lng: 99.531992, lat: 22.949039 },
{ lng: 98.898749, lat: 23.142722 },
{ lng: 98.660262, lat: 24.063286 },
{ lng: 97.60472, lat: 23.897405 },
{ lng: 97.724609, lat: 25.083637 },
{ lng: 98.671838, lat: 25.918703 },
{ lng: 98.712094, lat: 26.743536 },
{ lng: 98.68269, lat: 27.508812 },
{ lng: 98.246231, lat: 27.747221 },
{ lng: 97.911988, lat: 28.335945 },
{ lng: 97.327114, lat: 28.261583 },
{ lng: 96.248833, lat: 28.411031 },
{ lng: 96.586591, lat: 28.83098 },
{ lng: 96.117679, lat: 29.452802 },
{ lng: 95.404802, lat: 29.031717 },
{ lng: 94.56599, lat: 29.277438 },
{ lng: 93.413348, lat: 28.640629 },
{ lng: 92.503119, lat: 27.896876 },
{ lng: 91.696657, lat: 27.771742 },
{ lng: 91.258854, lat: 28.040614 },
{ lng: 90.730514, lat: 28.064954 },
{ lng: 90.015829, lat: 28.296439 },
{ lng: 89.47581, lat: 28.042759 },
{ lng: 88.814248, lat: 27.299316 },
{ lng: 88.730326, lat: 28.086865 },
{ lng: 88.120441, lat: 27.876542 },
{ lng: 86.954517, lat: 27.974262 },
{ lng: 85.82332, lat: 28.203576 },
{ lng: 85.011638, lat: 28.642774 },
{ lng: 84.23458, lat: 28.839894 },
{ lng: 83.898993, lat: 29.320226 },
{ lng: 83.337115, lat: 29.463732 },
{ lng: 82.327513, lat: 30.115268 },
{ lng: 81.525804, lat: 30.422717 },
{ lng: 81.111256, lat: 30.183481 },
{ lng: 79.721367, lat: 30.882715 },
{ lng: 78.738894, lat: 31.515906 },
{ lng: 78.458446, lat: 32.618164 },
{ lng: 79.176129, lat: 32.48378 },
{ lng: 79.208892, lat: 32.994395 },
{ lng: 78.811086, lat: 33.506198 },
{ lng: 78.912269, lat: 34.321936 },
{ lng: 77.837451, lat: 35.49401 },
{ lng: 76.192848, lat: 35.898403 },
{ lng: 75.896897, lat: 36.666806 },
{ lng: 75.158028, lat: 37.133031 },
{ lng: 74.980002, lat: 37.41999 },
{ lng: 74.829986, lat: 37.990007 },
{ lng: 74.864816, lat: 38.378846 },
{ lng: 74.257514, lat: 38.606507 },
{ lng: 73.928852, lat: 38.505815 },
{ lng: 73.675379, lat: 39.431237 },
{ lng: 73.960013, lat: 39.660008 },
{ lng: 73.822244, lat: 39.893973 },
{ lng: 74.776862, lat: 40.366425 },
{ lng: 75.467828, lat: 40.562072 },
{ lng: 76.526368, lat: 40.427946 },
{ lng: 76.904484, lat: 41.066486 },
{ lng: 78.187197, lat: 41.185316 },
{ lng: 78.543661, lat: 41.582243 },
{ lng: 80.11943, lat: 42.123941 },
{ lng: 80.25999, lat: 42.349999 },
{ lng: 80.18015, lat: 42.920068 },
{ lng: 80.866206, lat: 43.180362 },
{ lng: 79.966106, lat: 44.917517 },
{ lng: 81.947071, lat: 45.317027 },
{ lng: 82.458926, lat: 45.53965 },
{ lng: 83.180484, lat: 47.330031 },
{ lng: 85.16429, lat: 47.000956 },
{ lng: 85.720484, lat: 47.452969 },
{ lng: 85.768233, lat: 48.455751 },
{ lng: 86.598776, lat: 48.549182 },
{ lng: 87.35997, lat: 49.214981 },
{ lng: 87.751264, lat: 49.297198 },
{ lng: 88.013832, lat: 48.599463 },
{ lng: 88.854298, lat: 48.069082 },
{ lng: 90.280826, lat: 47.693549 },
{ lng: 90.970809, lat: 46.888146 },
{ lng: 90.585768, lat: 45.719716 },
{ lng: 90.94554, lat: 45.286073 },
{ lng: 92.133891, lat: 45.115076 },
{ lng: 93.480734, lat: 44.975472 },
{ lng: 94.688929, lat: 44.352332 },
{ lng: 95.306875, lat: 44.241331 },
{ lng: 95.762455, lat: 43.319449 },
{ lng: 96.349396, lat: 42.725635 },
{ lng: 97.451757, lat: 42.74889 },
{ lng: 99.515817, lat: 42.524691 },
{ lng: 100.845866, lat: 42.663804 },
{ lng: 101.83304, lat: 42.514873 },
{ lng: 103.312278, lat: 41.907468 },
{ lng: 104.522282, lat: 41.908347 },
{ lng: 104.964994, lat: 41.59741 },
{ lng: 106.129316, lat: 42.134328 },
{ lng: 107.744773, lat: 42.481516 },
{ lng: 109.243596, lat: 42.519446 },
{ lng: 110.412103, lat: 42.871234 },
{ lng: 111.129682, lat: 43.406834 },
{ lng: 111.829588, lat: 43.743118 },
{ lng: 111.667737, lat: 44.073176 },
{ lng: 111.348377, lat: 44.457442 },
{ lng: 111.873306, lat: 45.102079 },
{ lng: 112.436062, lat: 45.011646 },
{ lng: 113.463907, lat: 44.808893 },
{ lng: 114.460332, lat: 45.339817 },
{ lng: 115.985096, lat: 45.727235 },
{ lng: 116.717868, lat: 46.388202 },
{ lng: 117.421701, lat: 46.672733 },
{ lng: 118.874326, lat: 46.805412 },
{ lng: 119.66327, lat: 46.69268 },
{ lng: 119.772824, lat: 47.048059 },
{ lng: 118.866574, lat: 47.74706 },
{ lng: 118.064143, lat: 48.06673 },
{ lng: 117.295507, lat: 47.697709 },
{ lng: 116.308953, lat: 47.85341 },
{ lng: 115.742837, lat: 47.726545 },
{ lng: 115.485282, lat: 48.135383 },
{ lng: 116.191802, lat: 49.134598 },
{ lng: 116.678801, lat: 49.888531 },
{ lng: 117.879244, lat: 49.510983 },
{ lng: 119.288461, lat: 50.142883 },
{ lng: 119.279366, lat: 50.582908 },
{ lng: 120.18205, lat: 51.643566 },
{ lng: 120.738191, lat: 51.964115 },
{ lng: 120.725789, lat: 52.516226 },
{ lng: 120.177089, lat: 52.753886 },
{ lng: 121.003085, lat: 53.251401 },
{ lng: 122.245748, lat: 53.431726 },
{ lng: 123.571507, lat: 53.458804 },
{ lng: 125.068211, lat: 53.161045 },
{ lng: 125.946349, lat: 52.792799 },
{ lng: 126.564399, lat: 51.784255 },
{ lng: 126.939157, lat: 51.353894 },
{ lng: 127.287456, lat: 50.739797 },
{ lng: 127.657407, lat: 49.76027 }
];
const pointlayer = new PointLayer()
.source(
d,
{
parser: {
type: 'json',
x: 'lng',
y: 'lat'
}
}
)
.shape('cylinder')
.color('#f00')
.size('', () => [ 1, 1, 10 ])
.active(true);
const earthlayer = new EarthLayer()
.source(
'https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*3-3NSpqRqUoAAAAAAAAAAAAAARQnAQ',
{
parser: {
type: 'image'
}
}
)
.shape('fill')
.style({
opacity: 1.0,
radius: 40,
globelOtions: {
ambientRatio: 0.6, // 环境光
diffuseRatio: 0.4, // 漫反射
specularRatio: 0.1 // 高光反射
}
})
.animate(true);
const atomLayer = new EarthLayer()
.color('#2E8AE6')
.shape('atomSphere')
.style({
opacity: 1
});
const bloomLayer = new EarthLayer().color('#fff').shape('bloomSphere')
.style({
opacity: 0.6
});
scene.on('loaded', () => {
scene.addLayer(earthlayer);
scene.addLayer(pointlayer);
scene.addLayer(atomLayer);
scene.addLayer(bloomLayer);
earthlayer.setEarthTime(4.0);
});

View File

@ -0,0 +1,410 @@
import { Scene, LineLayer, PointLayer } from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
import { ThreeLayer, ThreeRender } from '@antv/l7-three';
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
function getImageData(img) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const { width, height } = img;
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
const imageData = ctx.getImageData(0, 0, width, height);
return imageData;
}
function getLatData(data) {
const size = Math.floor(Math.sqrt(data.length));
const arr = [];
const startLng = 110,
lngStep = 5 / (size - 1);
const startLat = 30,
latStep = -5 / (size - 1);
for (let i = 0; i < size; i++) {
const arr2 = [];
for (let j = 0; j < size; j++) {
const index = i + j * size;
const x = startLng + lngStep * i;
const y = startLat + latStep * j;
arr2.push([ x, y, data[index] ]);
}
arr.push(arr2);
}
return arr;
}
function getLngData(data) {
const size = Math.floor(Math.sqrt(data.length));
const arr = [];
const startLng = 110,
lngStep = 5 / (size - 1);
const startLat = 30,
latStep = -5 / (size - 1);
for (let i = 0; i < size; i++) {
const arr2 = [];
for (let j = 0; j < size; j++) {
const index = i * size + j;
const x = startLng + lngStep * j;
const y = startLat + latStep * i;
arr2.push([ x, y, data[index] ]);
}
arr.push(arr2);
}
return arr;
}
function getR(data) {
const arr = [];
for (let i = 0; i < data.length; i += 4) {
arr.push(data[i]);
}
return arr;
}
function setMaterial(object) {
if (object.children && object.children.length && object.children.length > 0) {
object.children.map(child => setMaterial(child));
} else if (object.material) {
object.material.wireframe = true;
object.material.opacity = 0.6;
}
}
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
}
];
const scene = new Scene({
id: 'map',
map: new GaodeMap({
center: [ 113, 29 ],
pitch: 70,
zoom: 8.5,
rotation: 160,
style: 'blank'
})
});
scene.setBgColor('#000');
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 = new Image();
img.crossOrigin = 'none';
img.src =
'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*UkvYRYS5jTAAAAAAAAAAAAAAARQnAQ';
img.onload = function() {
const data = getImageData(img);
const rData = getR(data.data);
const d1 = getLngData(rData);
const d2 = getLatData(rData);
const geoData = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {},
geometry: {
type: 'LineString',
coordinates: d1
}
},
{
type: 'Feature',
properties: {},
geometry: {
type: 'LineString',
coordinates: d2
}
}
]
};
const layer = new LineLayer({})
.source(geoData)
.size(1)
.shape('simpleline')
.color('rgb(22, 119, 255)')
.style({
vertexHeightScale: 2000,
opacity: 0.4
});
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);
});

View File

@ -5,54 +5,44 @@
},
"demos": [
{
"filename": "animate_path_texture.js",
"title": "路径贴图",
"screenshot":"https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*0UrUTakTFQsAAAAAAAAAAAAAARQnAQ"
},
{
"filename": "animate_path.js",
"title": "路径动画",
"screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*VJX5Qo7ufaAAAAAAAAAAAABkARQnAQ"
},
{
"filename": "world.js",
"title": "流向图",
"screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*Sbx4S4w7nL8AAAAAAAAAAABkARQnAQ"
},
{
"filename": "world2.js",
"title": "流向图",
"screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*u5BsQbn30pkAAAAAAAAAAABkARQnAQ"
},
{
"filename": "plane_animate.js",
"title": "航向图",
"screenshot":"https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*2anhRaQX3DsAAAAAAAAAAAAAARQnAQ"
},
{
"filename": "plane_animate2.js",
"title": "航向图(平面)",
"screenshot":"https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*OGcHSYSbDz4AAAAAAAAAAAAAARQnAQ"
},
{
"filename": "route_line.js",
"title": "航线图",
"screenshot":"https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*i6d6SqQgjAwAAAAAAAAAAAAAARQnAQ"
},
{
"filename": "build.js",
"title": "点亮城市",
"screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*7XkWTYQMfPMAAAAAAAAAAABkARQnAQ"
"filename": "grid.js",
"title": "网格地图",
"screenshot":"https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*HulgSKEJAKMAAAAAAAAAAAAAARQnAQ"
},
{
"filename": "build_sweep.js",
"title": "圆形扫光城市",
"screenshot":"https://gw.alipayobjects.com/mdn/rms_e7e1c6/afts/img/A*LoxeSZHuqXwAAAAAAAAAAAAAARQnAQ"
"screenshot":"https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*KiwgTLrn0OkAAAAAAAAAAAAAARQnAQ"
},
{
"filename": "animate_line.js",
"title": "轨迹动画",
"screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*jLo0RY0sDG4AAAAAAAAAAABkARQnAQ"
"filename": "wind.js",
"title": "风场图层",
"screenshot":"https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*Kp0XTrOMu8wAAAAAAAAAAAAAARQnAQ"
},
{
"filename": "amap_car.js",
"title": "旅行轨迹",
"screenshot":"https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*d7EtTpdsScIAAAAAAAAAAAAAARQnAQ"
},
{
"filename": "animate_path_texture.js",
"title": "路径贴图",
"screenshot":"https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*KEupSZ_p0pYAAAAAAAAAAAAAARQnAQ"
},
{
"filename": "plane_animate.js",
"title": "航向图",
"screenshot":"https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*B645Q4K9PxYAAAAAAAAAAAAAARQnAQ"
},
{
"filename": "turin.js",
"title": "都灵道路图",
"screenshot":"https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*mo_7Q6sTqOIAAAAAAAAAAAAAARQnAQ"
},
{
"filename": "cylinder.js",
"title": "地球圆柱",
"screenshot":"https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*xjRPRJU5CKUAAAAAAAAAAAAAARQnAQ"
}
]
}

View File

@ -1,5 +1,5 @@
/* eslint-disable no-eval */
import { Scene, LineLayer, PointLayer } from '@antv/l7';
import { Scene, LineLayer, PointLayer, PolygonLayer } from '@antv/l7';
import { Mapbox } from '@antv/l7-maps';
const scene = new Scene({
@ -23,13 +23,14 @@ const scene = new Scene({
]
},
center: [ 3.438, 40.16797 ],
zoom: 0.51329
zoom: 1
})
});
scene.setBgColor('#000');
scene.on('loaded', () => {
scene.addImage(
'plane',
'https://gw.alipayobjects.com/zos/bmw-prod/0ca1668e-38c2-4010-8568-b57cb33839b9.svg'
'https://gw.alipayobjects.com/zos/bmw-prod/96327aa6-7fc5-4b5b-b1d8-65771e05afd8.svg'
);
Promise.all([
fetch(
@ -58,12 +59,24 @@ scene.on('loaded', () => {
const worldLine = new LineLayer()
.source(world)
.color('#41fc9d')
.color('rgb(22,119,255)')
.size(0.5)
.style({
opacity: 0.4
});
const dotPoint = new PointLayer()
const worldPolygon = new PolygonLayer()
.source(world)
.shape('fill')
.color('rgb(22,119,255)')
.size(0.5)
.style({
opacity: 0.4,
opacityLinear: {
enable: true,
dir: 'in' // in - out
}
});
const dotPoint = new PointLayer({ bland: 'additive' })
.source(dotData, {
parser: {
type: 'json',
@ -72,32 +85,32 @@ scene.on('loaded', () => {
}
})
.shape('circle')
.color('#ffed11')
.color('rgb(22,119,255)')
.animate(true)
.size(40)
.style({
opacity: 1.0
});
const flyLine = new LineLayer({ blend: 'normal' })
const flyLine = new LineLayer({ blend: 'additive', zIndex: 2 })
.source(flydata, {
parser: {
type: 'json',
coordinates: 'coord'
}
})
.color('#ff6b34')
.color('rgb(22,119,255)')
.texture('plane')
.shape('arc3d')
.size(20)
.size(25)
.animate({
duration: 1,
interval: 0.2,
interval: 0.5,
trailLength: 0.05
})
.style({
textureBlend: 'replace',
lineTexture: true, // 开启线的贴图功能
iconStep: 6, // 设置贴图纹理的间距
iconStep: 8, // 设置贴图纹理的间距
opacity: 1
});
@ -108,7 +121,7 @@ scene.on('loaded', () => {
coordinates: 'coord'
}
})
.color('#ff6b34')
.color('rgb(22,119,255)')
.shape('arc3d')
.size(1)
.style({
@ -117,6 +130,7 @@ scene.on('loaded', () => {
opacity: 0.5
});
scene.addLayer(worldLine);
scene.addLayer(worldPolygon);
scene.addLayer(dotPoint);
scene.addLayer(flyLine2);
scene.addLayer(flyLine);

View File

@ -44,7 +44,7 @@ scene.on('loaded', () => {
case 'pedestrian':
return '#FFF89A';
case 'residential':
return '#348498';
return 'rgba(22, 119, 255, .5)';
case 'road':
return '#93FFD8';
case 'path':
@ -68,6 +68,11 @@ scene.on('loaded', () => {
})
.style({
opacity: 1
})
.animate({
interval: 1, // 间隔
duration: 1, // 持续时间,延时
trailLength: 2 // 流线长度
});
scene.addLayer(layer);
});

View File

@ -0,0 +1,46 @@
import { Scene, WindLayer } from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
const scene = new Scene({
id: 'map',
map: new GaodeMap({
center: [ 105.732421875, 32.24997445586331 ],
pitch: 0,
style: 'dark',
zoom: 2,
viewMode: '3D'
})
});
scene.on('loaded', () => {
const layer = new WindLayer({});
layer
.source(
'https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*wcU8S5xMEDYAAAAAAAAAAAAAARQnAQ',
{
parser: {
type: 'image',
extent: [ -180, -85, 180, 85 ]
}
}
)
.animate(true)
.style({
uMin: -21.32,
uMax: 26.8,
vMin: -21.57,
vMax: 21.42,
numParticles: 35535,
fadeOpacity: 0.996,
sizeScale: 1.2,
rampColors: {
0.0: '#c6dbef',
0.1: '#9ecae1',
0.2: '#6baed6',
0.3: '#4292c6',
0.4: '#2171b5',
0.5: '#084594'
}
});
scene.addLayer(layer);
});

View File

@ -14,6 +14,11 @@
"title": "直线动画",
"screenshot": "https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*z5sLS4Tpl3kAAAAAAAAAAAAAARQnAQ"
},
{
"filename": "plane_animate2.js",
"title": "航向图(平面)",
"screenshot":"https://gw.alipayobjects.com/mdn/rms_23a451/afts/img/A*OGcHSYSbDz4AAAAAAAAAAAAAARQnAQ"
},
{
"filename": "trip_animate.js",
"title": "3D 弧线动画-亮",
@ -23,6 +28,21 @@
"filename": "trip_animate_dark.js",
"title": "3D 弧线动画-暗",
"screenshot": "https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*w-gDQra4KGMAAAAAAAAAAAAAARQnAQ"
},
{
"filename": "animate_line.js",
"title": "轨迹动画",
"screenshot": "https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*jLo0RY0sDG4AAAAAAAAAAABkARQnAQ"
},
{
"filename": "world.js",
"title": "流向图",
"screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*Sbx4S4w7nL8AAAAAAAAAAABkARQnAQ"
},
{
"filename": "world2.js",
"title": "流向图",
"screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*u5BsQbn30pkAAAAAAAAAAABkARQnAQ"
}
]
}

View File

@ -35,9 +35,9 @@
"screenshot":"https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*cGw3T4LPx7YAAAAAAAAAAABkARQnAQ"
},
{
"filename": "turin.js",
"title": "都灵道路图",
"screenshot":"https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*CNzqRJDMh-oAAAAAAAAAAAAAARQnAQ"
"filename": "route_line.js",
"title": "航线图",
"screenshot":"https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*i6d6SqQgjAwAAAAAAAAAAAAAARQnAQ"
}
]
}

View File

@ -91,7 +91,7 @@ module.exports = {
order: 4
},
{
slug: 'tutorial/examples',
slug: 'tutorial/demo',
icon: 'map',
title: {
zh: '教程示例',
@ -263,13 +263,15 @@ module.exports = {
}
],
examples: [
{
slug: 'gallery',
icon: 'gallery',
title: {
zh: '官方精品库',
en: 'Featured'
}
},
order: 0
},
{
slug: 'point',
@ -277,7 +279,8 @@ module.exports = {
title: {
zh: '点图层',
en: 'Point Layer'
}
},
order: 1
},
{
slug: 'line',
@ -285,7 +288,8 @@ module.exports = {
title: {
zh: '线图层',
en: 'Line Layer'
}
},
order: 2
},
{
slug: 'polygon',
@ -293,7 +297,26 @@ module.exports = {
title: {
zh: '面图层',
en: 'Polygon Layer'
}
},
order: 3
},
{
slug: 'earth',
icon: 'map',
title: {
zh: '地球模式',
en: 'Earth Mode'
},
order: 4
},
{
slug: 'wind',
icon: 'raster',
title: {
zh: '风场图层',
en: 'Wind Layer'
},
order: 5
},
{
slug: 'heatmap',
@ -302,7 +325,7 @@ module.exports = {
zh: '热力图',
en: 'HeatMap Layer'
},
order: 5
order: 6
},
{
slug: 'raster',
@ -310,7 +333,8 @@ module.exports = {
title: {
zh: '栅格图层',
en: 'Raster Layer'
}
},
order: 7
},
{
slug: 'engine',
@ -318,7 +342,8 @@ module.exports = {
title: {
zh: '第三方引擎',
en: 'other engine'
}
},
order: 8
},
{
slug: 'react',
@ -326,7 +351,8 @@ module.exports = {
title: {
zh: 'React 组件',
en: 'React Demo'
}
},
order: 9
},
{
slug: 'amapPlugin',
@ -334,31 +360,18 @@ module.exports = {
title: {
zh: '高德地图插件',
en: 'amapPlugin'
}
},
{
slug: 'earth',
icon: 'map',
title: {
zh: '地球模式',
en: 'Earth Mode'
}
},
{
slug: 'wind',
icon: 'raster',
title: {
zh: '风场图层',
en: 'Wind Layer'
}
},
order: 10
},
{
slug: 'district',
icon: 'map',
title: {
zh: '行政区划',
en: 'L7 District'
}
},
order: 11
},
{
slug: 'draw',
@ -366,7 +379,8 @@ module.exports = {
title: {
zh: '绘制组件',
en: 'L7 Draw'
}
},
order: 12
},
{
slug: 'tutorial',

View File

@ -14,7 +14,7 @@
"message": "chore: publish"
}
},
"version": "2.6.33",
"version": "2.6.34",
"npmClient": "yarn",
"useWorkspaces": true,
"publishConfig": {

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-component",
"version": "2.6.33",
"version": "2.6.34",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -25,8 +25,8 @@
"author": "lzxue",
"license": "ISC",
"dependencies": {
"@antv/l7-core": "^2.6.33",
"@antv/l7-utils": "^2.6.33",
"@antv/l7-core": "^2.6.34",
"@antv/l7-utils": "^2.6.34",
"@babel/runtime": "^7.7.7",
"eventemitter3": "^4.0.0",
"inversify": "^5.0.1",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-core",
"version": "2.6.33",
"version": "2.6.34",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -24,7 +24,7 @@
"license": "ISC",
"dependencies": {
"@antv/async-hook": "^2.1.0",
"@antv/l7-utils": "^2.6.33",
"@antv/l7-utils": "^2.6.34",
"@babel/runtime": "^7.7.7",
"ajv": "^6.10.2",
"element-resize-event": "^3.0.3",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7",
"version": "2.6.33",
"version": "2.6.34",
"description": "A Large-scale WebGL-powered Geospatial Data Visualization",
"main": "lib/index.js",
"module": "es/index.js",
@ -25,13 +25,13 @@
"author": "antv",
"license": "MIT",
"dependencies": {
"@antv/l7-component": "^2.6.33",
"@antv/l7-core": "^2.6.33",
"@antv/l7-layers": "^2.6.33",
"@antv/l7-maps": "^2.6.33",
"@antv/l7-scene": "^2.6.33",
"@antv/l7-source": "^2.6.33",
"@antv/l7-utils": "^2.6.33",
"@antv/l7-component": "^2.6.34",
"@antv/l7-core": "^2.6.34",
"@antv/l7-layers": "^2.6.34",
"@antv/l7-maps": "^2.6.34",
"@antv/l7-scene": "^2.6.34",
"@antv/l7-source": "^2.6.34",
"@antv/l7-utils": "^2.6.34",
"@babel/runtime": "^7.7.7"
},
"gitHead": "684ba4eb806a798713496d3fc0b4d1e17517dc31",

View File

@ -1,2 +1,2 @@
const version = '2.6.33';
const version = '2.6.34';
export { version };

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-layers",
"version": "2.6.33",
"version": "2.6.34",
"description": "L7's collection of built-in layers",
"main": "lib/index.js",
"module": "es/index.js",
@ -24,9 +24,9 @@
"license": "ISC",
"dependencies": {
"@antv/geo-coord": "^1.0.8",
"@antv/l7-core": "^2.6.33",
"@antv/l7-source": "^2.6.33",
"@antv/l7-utils": "^2.6.33",
"@antv/l7-core": "^2.6.34",
"@antv/l7-source": "^2.6.34",
"@antv/l7-utils": "^2.6.34",
"@babel/runtime": "^7.7.7",
"@mapbox/martini": "^0.2.0",
"@turf/meta": "^6.0.2",

View File

@ -143,6 +143,51 @@ export function LineTriangulation(feature: IEncodeFeature) {
};
}
export function SimpleLineTriangulation(feature: IEncodeFeature) {
const { coordinates, originCoordinates, version } = feature;
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 (!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,
};
}
export function polygonTriangulation(feature: IEncodeFeature) {
const { coordinates } = feature;
const flattengeo = earcut.flatten(coordinates as number[][][]);

View File

@ -29,6 +29,7 @@ export default class LineLayer extends BaseLayer<ILineLayerStyleOptions> {
const type = this.getModelType();
const defaultConfig = {
line: {},
simpleline: {},
wall: {},
arc3d: { blend: 'additive' },
arc: { blend: 'additive' },

View File

@ -3,6 +3,7 @@ import Arc3DModel from './arc_3d';
import ArcMiniModel from './arcmini';
import GreatCircleModel from './great_circle';
import LineModel from './line';
import SimpleLineModel from './simpleLine';
import LineWallModel from './wall';
export type LineModelType =
@ -11,6 +12,7 @@ export type LineModelType =
| 'arc3d'
| 'greatcircle'
| 'wall'
| 'simpleline'
| 'line';
const LineModels: { [key in LineModelType]: any } = {
@ -20,6 +22,7 @@ const LineModels: { [key in LineModelType]: any } = {
greatcircle: GreatCircleModel,
wall: LineWallModel,
line: LineModel,
simpleline: SimpleLineModel,
};
export default LineModels;

View File

@ -148,12 +148,6 @@ export default class LineModel extends BaseModel {
];
}
protected registerBuiltinAttributes() {
// const lineType = this
// point layer size;
const {
lineType = 'solid',
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
// if (lineType === 'dash') {
this.styleAttributeService.registerStyleAttribute({
name: 'distance',
type: AttributeType.Attribute,
@ -198,7 +192,7 @@ export default class LineModel extends BaseModel {
},
},
});
// }
this.styleAttributeService.registerStyleAttribute({
name: 'size',
type: AttributeType.Attribute,
@ -299,24 +293,6 @@ export default class LineModel extends BaseModel {
});
}
private loadImage(url: IImage) {
return new Promise((resolve, reject) => {
if (url instanceof HTMLImageElement) {
resolve(url);
return;
}
const image = new Image();
image.crossOrigin = 'anonymous';
image.onload = () => {
resolve(image);
};
image.onerror = () => {
reject(new Error('Could not load image at ' + url));
};
image.src = url instanceof File ? URL.createObjectURL(url) : url;
});
}
private updateTexture = () => {
const { createTexture2D } = this.rendererService;
if (this.texture) {

View File

@ -0,0 +1,229 @@
import {
AttributeType,
gl,
IAnimateOption,
IEncodeFeature,
ILayerConfig,
IModel,
IModelUniform,
} from '@antv/l7-core';
import { rgb2arr } from '@antv/l7-utils';
import { isNumber } from 'lodash';
import BaseModel from '../../core/BaseModel';
import { ILineLayerStyleOptions } from '../../core/interface';
import { SimpleLineTriangulation } from '../../core/triangulation';
import line_frag from '../shaders/simpleline_frag.glsl';
import line_vert from '../shaders/simpleline_vert.glsl';
export default class SimpleLineModel extends BaseModel {
public getUninforms(): IModelUniform {
const {
opacity,
sourceColor,
targetColor,
vertexHeightScale = 20.0,
} = this.layer.getLayerConfig() as ILineLayerStyleOptions;
// 转化渐变色
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;
}
if (this.dataTextureTest && this.dataTextureNeedUpdate({ opacity })) {
this.judgeStyleAttributes({ opacity });
const encodeData = this.layer.getEncodedData();
const { data, width, height } = this.calDataFrame(
this.cellLength,
encodeData,
this.cellProperties,
);
this.rowCount = height; // 当前数据纹理有多少行
this.dataTexture =
this.cellLength > 0 && data.length > 0
? this.createTexture2D({
flipY: true,
data,
format: gl.LUMINANCE,
type: gl.FLOAT,
width,
height,
})
: this.createTexture2D({
flipY: true,
data: [1],
format: gl.LUMINANCE,
type: gl.FLOAT,
width: 1,
height: 1,
});
}
return {
u_dataTexture: this.dataTexture, // 数据纹理 - 有数据映射的时候纹理中带数据,若没有任何数据映射时纹理是 [1]
u_cellTypeLayout: this.getCellTypeLayout(),
u_opacity: isNumber(opacity) ? opacity : 1.0,
// 渐变色支持参数
u_linearColor: useLinearColor,
u_sourceColor: sourceColorArr,
u_targetColor: targetColorArr,
// 顶点高度 scale
u_vertexScale: vertexHeightScale,
};
}
public getAnimateUniforms(): IModelUniform {
const { animateOption } = this.layer.getLayerConfig() as ILayerConfig;
return {
u_aimate: this.animateOption2Array(animateOption as IAnimateOption),
u_time: this.layer.getLayerAnimateTime(),
};
}
public initModels(): IModel[] {
return this.buildModels();
}
public clearModels() {
this.dataTexture?.destroy();
}
public buildModels(): IModel[] {
return [
this.layer.buildLayerModel({
moduleName: 'line',
vertexShader: line_vert,
fragmentShader: line_frag,
triangulation: SimpleLineTriangulation,
primitive: gl.LINES, // gl.LINES gl.TRIANGLES
blend: this.getBlend(),
depth: { enable: false },
}),
];
}
protected registerBuiltinAttributes() {
this.styleAttributeService.registerStyleAttribute({
name: 'distance',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Distance',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.STATIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 1,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
) => {
return [vertex[3]];
},
},
});
this.styleAttributeService.registerStyleAttribute({
name: 'total_distance',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Total_Distance',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.STATIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 1,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
) => {
return [vertex[5]];
},
},
});
this.styleAttributeService.registerStyleAttribute({
name: 'size',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Size',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.DYNAMIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 2,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
) => {
const { size = 1 } = feature;
return Array.isArray(size) ? [size[0], size[1]] : [size as number, 0];
},
},
});
// point layer size;
this.styleAttributeService.registerStyleAttribute({
name: 'normal',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Normal',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.STATIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 3,
// @ts-ignore
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
normal: number[],
) => {
return normal;
},
},
});
this.styleAttributeService.registerStyleAttribute({
name: 'miter',
type: AttributeType.Attribute,
descriptor: {
name: 'a_Miter',
buffer: {
// give the WebGL driver a hint that this buffer may change
usage: gl.STATIC_DRAW,
data: [],
type: gl.FLOAT,
},
size: 1,
update: (
feature: IEncodeFeature,
featureIdx: number,
vertex: number[],
attributeIdx: number,
) => {
return [vertex[4]];
},
},
});
}
}

View File

@ -0,0 +1,31 @@
uniform float u_blur : 0.99;
uniform float u_line_type: 0.0;
uniform float u_opacity : 1.0;
uniform float u_borderWidth: 0.0;
uniform vec4 u_borderColor;
varying vec4 v_color;
uniform float u_linearColor: 0;
uniform vec4 u_sourceColor;
uniform vec4 u_targetColor;
uniform float u_time;
uniform vec4 u_aimate: [ 0, 2., 1.0, 0.2 ]; // 控制运动
varying mat4 styleMappingMat;
void main() {
float opacity = styleMappingMat[0][0];
float d_distance_ratio = styleMappingMat[3].r; // 当前点位距离占线总长的比例
if(u_linearColor == 1.0) { // 使用渐变颜色
gl_FragColor = mix(u_sourceColor, u_targetColor, d_distance_ratio);
} else { // 使用 color 方法传入的颜色
gl_FragColor = v_color;
}
// anti-alias
// float blur = 1.0 - smoothstep(u_blur, 1., length(v_normal.xy));
gl_FragColor.a *= opacity; // 全局透明度
}

View File

@ -0,0 +1,84 @@
attribute vec4 a_Color;
attribute vec2 a_Size;
attribute vec3 a_Position;
// dash line
attribute float a_Total_Distance;
attribute float a_Distance;
uniform mat4 u_ModelMatrix;
uniform mat4 u_Mvp;
uniform float u_vertexScale: 1.0;
#pragma include "projection"
varying vec4 v_color;
uniform float u_opacity: 1.0;
varying mat4 styleMappingMat; // 用于将在顶点着色器中计算好的样式值传递给片元
#pragma include "styleMapping"
#pragma include "styleMappingCalOpacity"
void main() {
// 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 // distance_ratio/distance/pixelLen/texV
);
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 - 数据纹理映射部分的计算
float d_distance_ratio; // 当前点位距离占线总长的比例
v_color = a_Color;
// 设置数据集的参数
styleMappingMat[3][0] = a_Distance / a_Total_Distance; // 当前点位距离占线总长的比例
vec4 project_pos = project_position(vec4(a_Position.xy, 0, 1.0));
float h = float(a_Position.z) * u_vertexScale; // 线顶点的高度 - 兼容不存在第三个数值的情况
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
gl_Position = u_Mvp * (vec4(project_pos.xy, project_pixel(a_Size.y) + h * 0.2, 1.0));
} else {
float lineHeight = a_Size.y;
// 兼容 mapbox 在线高度上的效果表现基本一致
if(u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT || u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) {
// 保持高度相对不变
h *= 2.0/pow(2.0, 20.0 - u_Zoom);
}
// #define COORDINATE_SYSTEM_P20 5.0
// #define COORDINATE_SYSTEM_P20_OFFSET 6.0
// amap1.x
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
// 保持高度相对不变
lineHeight *= pow(2.0, 20.0 - u_Zoom);
}
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy, lineHeight + h, 1.0));
}
}

View File

@ -162,6 +162,10 @@ export default class FillModel extends BaseModel {
maxLat === minLat ? minLat + 0.1 : maxLat,
]);
this.meter2coord = (m1 + m2) / 2;
if (!Boolean(this.meter2coord)) {
// Tip: 兼容单个数据导致的 m1、m2 为 NaN
this.meter2coord = 7.70681090738883;
}
}
public buildModels(): IModel[] {

View File

@ -144,6 +144,62 @@ export default class ExtrudePolyline {
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(points: number[][]) {
const complex = this.complex;
if (points.length <= 1) {
@ -172,6 +228,34 @@ export default class ExtrudePolyline {
complex.startIndex = complex.positions.length / 6;
return complex;
}
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;
}
private segment_gaode2(
complex: any,
index: number,
@ -399,6 +483,111 @@ export default class ExtrudePolyline {
}
return count;
}
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(
complex: any,
index: number,

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-map",
"version": "2.6.33",
"version": "2.6.34",
"description": "l7 map",
"keywords": [],
"author": "thinkinggis <lzx199065@gmail.com>",
@ -37,7 +37,7 @@
},
"homepage": "https://github.com/antvis/L7#readme",
"dependencies": {
"@antv/l7-utils": "^2.6.33",
"@antv/l7-utils": "^2.6.34",
"@babel/runtime": "^7.7.7",
"@mapbox/point-geometry": "^0.1.0",
"@mapbox/unitbezier": "^0.0.0",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-maps",
"version": "2.6.33",
"version": "2.6.34",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -27,9 +27,9 @@
"license": "ISC",
"dependencies": {
"@amap/amap-jsapi-loader": "^0.0.3",
"@antv/l7-core": "^2.6.33",
"@antv/l7-map": "^2.6.33",
"@antv/l7-utils": "^2.6.33",
"@antv/l7-core": "^2.6.34",
"@antv/l7-map": "^2.6.34",
"@antv/l7-utils": "^2.6.34",
"@babel/runtime": "^7.7.7",
"@types/amap-js-api": "^1.4.6",
"@types/mapbox-gl": "^1.11.2",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-mini",
"version": "2.6.33",
"version": "2.6.34",
"description": "A Large-scale WebGL-powered Geospatial Data Visualization",
"main": "lib/index.js",
"module": "es/index.js",
@ -25,11 +25,11 @@
"author": "antv",
"license": "MIT",
"dependencies": {
"@antv/l7-core": "^2.6.33",
"@antv/l7-layers": "^2.6.33",
"@antv/l7-maps": "^2.6.33",
"@antv/l7-scene": "^2.6.33",
"@antv/l7-utils": "^2.6.33",
"@antv/l7-core": "^2.6.34",
"@antv/l7-layers": "^2.6.34",
"@antv/l7-maps": "^2.6.34",
"@antv/l7-scene": "^2.6.34",
"@antv/l7-utils": "^2.6.34",
"@babel/runtime": "^7.7.7"
},
"gitHead": "684ba4eb806a798713496d3fc0b4d1e17517dc31",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-renderer",
"version": "2.6.33",
"version": "2.6.34",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -26,7 +26,7 @@
"gl": "^4.4.0"
},
"dependencies": {
"@antv/l7-core": "^2.6.33",
"@antv/l7-core": "^2.6.34",
"@babel/runtime": "^7.7.7",
"inversify": "^5.0.1",
"l7regl": "^0.0.16",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-scene",
"version": "2.6.33",
"version": "2.6.34",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -23,12 +23,12 @@
"author": "xiaoiver",
"license": "ISC",
"dependencies": {
"@antv/l7-component": "^2.6.33",
"@antv/l7-core": "^2.6.33",
"@antv/l7-layers": "^2.6.33",
"@antv/l7-maps": "^2.6.33",
"@antv/l7-renderer": "^2.6.33",
"@antv/l7-utils": "^2.6.33",
"@antv/l7-component": "^2.6.34",
"@antv/l7-core": "^2.6.34",
"@antv/l7-layers": "^2.6.34",
"@antv/l7-maps": "^2.6.34",
"@antv/l7-renderer": "^2.6.34",
"@antv/l7-utils": "^2.6.34",
"@babel/runtime": "^7.7.7",
"inversify": "^5.0.1",
"mapbox-gl": "^1.2.1",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-source",
"version": "2.6.33",
"version": "2.6.34",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",
@ -26,8 +26,8 @@
"license": "ISC",
"dependencies": {
"@antv/async-hook": "^2.1.0",
"@antv/l7-core": "^2.6.33",
"@antv/l7-utils": "^2.6.33",
"@antv/l7-core": "^2.6.34",
"@antv/l7-utils": "^2.6.34",
"@babel/runtime": "^7.7.7",
"@mapbox/geojson-rewind": "^0.4.0",
"@turf/helpers": "^6.1.4",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-three",
"version": "2.6.33",
"version": "2.6.34",
"description": "three for L7 ",
"keywords": [
"3D",
@ -44,9 +44,9 @@
},
"homepage": "https://github.com/antvis/L7#readme",
"dependencies": {
"@antv/l7-core": "^2.6.33",
"@antv/l7-layers": "^2.6.33",
"@antv/l7-scene": "^2.6.33",
"@antv/l7-core": "^2.6.34",
"@antv/l7-layers": "^2.6.34",
"@antv/l7-scene": "^2.6.34",
"@babel/runtime": "^7.7.7",
"inversify": "^5.0.1",
"reflect-metadata": "^0.1.13",

View File

@ -1,6 +1,6 @@
{
"name": "@antv/l7-utils",
"version": "2.6.33",
"version": "2.6.34",
"description": "",
"main": "lib/index.js",
"module": "es/index.js",

View File

@ -0,0 +1,542 @@
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');
let ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
const { width, height } = img;
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
const imageData = ctx.getImageData(0, 0, width, height);
return imageData;
}
function getLatData(data: number[]) {
const size = Math.floor(Math.sqrt(data.length));
const arr = [];
let startLng = 110,
lngStep = 5 / (size - 1);
let startLat = 30,
latStep = -5 / (size - 1);
for (let i = 0; i < size; i++) {
let arr2 = [];
for (let j = 0; j < size; j++) {
let index = i + j * size;
let x = startLng + lngStep * i;
let y = startLat + latStep * j;
arr2.push([x, y, data[index]]);
}
arr.push(arr2);
}
return arr;
}
function getLngData(data: number[]) {
const size = Math.floor(Math.sqrt(data.length));
const arr = [];
let startLng = 110,
lngStep = 5 / (size - 1);
let startLat = 30,
latStep = -5 / (size - 1);
for (let i = 0; i < size; i++) {
let arr2 = [];
for (let j = 0; j < size; j++) {
let index = i * size + j;
let x = startLng + lngStep * j;
let y = startLat + latStep * i;
arr2.push([x, y, data[index]]);
}
arr.push(arr2);
}
return arr;
}
function getR(data: Uint8ClampedArray) {
const arr = [];
for (let i = 0; i < data.length; i += 4) {
arr.push(data[i]);
}
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;
public componentWillUnmount() {
this.scene.destroy();
}
public async componentDidMount() {
const scene = new Scene({
id: 'map',
map: new GaodeMap({
center: [113, 29],
pitch: 70,
zoom: 9,
rotation: 180,
style: 'blank',
// style: 'dark',
}),
});
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';
img.src =
'https://gw.alipayobjects.com/mdn/rms_816329/afts/img/A*UkvYRYS5jTAAAAAAAAAAAAAAARQnAQ';
img.onload = function() {
const data = getImageData(img);
const rData = getR(data.data);
let d1 = getLngData(rData);
let d2 = getLatData(rData);
const geoData = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {},
geometry: {
type: 'LineString',
coordinates: d1,
},
},
{
type: 'Feature',
properties: {},
geometry: {
type: 'LineString',
coordinates: d2,
},
},
],
};
const layer = new LineLayer({})
.source(geoData)
.size(1)
.shape('simpleline')
.color('rgb(22, 119, 255)')
.style({
vertexHeightScale: 2000,
opacity: 0.4,
});
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);
});
}
public render() {
return (
<>
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
</>
);
}
}

View File

@ -0,0 +1,516 @@
import { LineLayer, Scene, PointLayer } from '@antv/l7';
import { GaodeMap, GaodeMapV2, Map } from '@antv/l7-maps';
import * as React from 'react';
import { animate, easeInOut } from 'popmotion';
function getImageData(img: HTMLImageElement) {
let canvas: HTMLCanvasElement = document.createElement('canvas');
let ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
const { width, height } = img;
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
const imageData = ctx.getImageData(0, 0, width, height);
return imageData;
}
function getLatData(data: number[]) {
const size = Math.floor(Math.sqrt(data.length));
const arr = [];
let startLng = 110,
lngStep = 5 / (size - 1);
let startLat = 30,
latStep = -5 / (size - 1);
for (let i = 0; i < size; i++) {
let arr2 = [];
for (let j = 0; j < size; j++) {
let index = i + j * size;
let x = startLng + lngStep * i;
let y = startLat + latStep * j;
arr2.push([x, y, data[index]]);
}
arr.push(arr2);
}
return arr;
}
function getLngData(data: number[]) {
const size = Math.floor(Math.sqrt(data.length));
const arr = [];
let startLng = 110,
lngStep = 5 / (size - 1);
let startLat = 30,
latStep = -5 / (size - 1);
for (let i = 0; i < size; i++) {
let arr2 = [];
for (let j = 0; j < size; j++) {
let index = i * size + j;
let x = startLng + lngStep * j;
let y = startLat + latStep * i;
arr2.push([x, y, data[index]]);
}
arr.push(arr2);
}
return arr;
}
function getR(data: Uint8ClampedArray) {
const arr = [];
for (let i = 0; i < data.length; i += 4) {
if (data[i] < 25) {
// console.log(data[i])
arr.push(20);
} else {
arr.push(data[i]);
}
}
return arr;
}
export default class GridTile2 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: [112, 27.5],
// pitch: 75,
// zoom: 8.2,
// rotation: -30,
style: 'blank',
}),
});
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.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);
const rData = getR(data.data);
let d1 = getLngData(rData);
let d2 = getLatData(rData);
const geoData = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {},
geometry: {
type: 'LineString',
coordinates: d1,
},
},
{
type: 'Feature',
properties: {},
geometry: {
type: 'LineString',
coordinates: d2,
},
},
],
};
const layer = new LineLayer({})
.source(geoData)
.size(1)
.shape('simpleline')
.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' })
.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(airPrtsLayer);
// scene.addLayer(airLineLayer);
// scene.addLayer(airPlaneLayer);
animate({
from: {
pitch: 0,
rotation: 0,
zoom: 6,
},
to: {
pitch: 75,
rotation: -30,
zoom: 8.2,
},
ease: easeInOut,
duration: 1000,
onUpdate: ({ pitch, rotation, zoom }) => {
scene.setPitch(pitch);
scene.setRotation(rotation);
scene.setZoom(zoom);
},
onComplete: () => {},
});
});
}
public render() {
return (
<>
<div
id="map"
style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
}}
/>
</>
);
}
}

View File

@ -31,24 +31,24 @@ export default class GaodeMapComponent extends React.Component {
// additive = 'additive',
// cylinder circle
// blend: 'additive'
var circleRadius = 100;
var radius = circleRadius;
var data = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {},
geometry: {
type: 'Polygon',
coordinates: turf.circle(aspaceLnglat, radius, {
steps: 10,
units: 'meters',
}).geometry.coordinates,
},
},
],
};
// var circleRadius = 100;
// var radius = circleRadius;
// var data = {
// type: 'FeatureCollection',
// features: [
// {
// type: 'Feature',
// properties: {},
// geometry: {
// type: 'Polygon',
// coordinates: turf.circle(aspaceLnglat, radius, {
// steps: 10,
// units: 'meters',
// }).geometry.coordinates,
// },
// },
// ],
// };
// let trufCircle = new PolygonLayer()
// .size('name', [0, 10000, 50000, 30000, 100000])
// .source(data)
@ -59,7 +59,7 @@ export default class GaodeMapComponent extends React.Component {
.source(
[
{
lng: 121.107846,
lng: 120,
lat: 30.267069,
},
{
@ -85,7 +85,7 @@ export default class GaodeMapComponent extends React.Component {
// strokeWidth: 10,
strokeWidth: 0,
strokeOpacity: 1,
// unit: 'meter',
unit: 'meter',
});
// .animate(true)
// .animate({
@ -109,12 +109,12 @@ export default class GaodeMapComponent extends React.Component {
// scene.on('zoomend', e => console.log('e', e))
// scene.on('mousedown', e => console.log('e', e))
});
let c = 1;
layer.on('click', () => {
// @ts-ignore
c == 1 ? scene.setEnableRender(false) : scene.setEnableRender(true);
c = 0;
});
// let c = 1;
// layer.on('click', () => {
// // @ts-ignore
// c == 1 ? scene.setEnableRender(false) : scene.setEnableRender(true);
// c = 0;
// });
// layer.on('contextmenu', () => console.log('contextmenu'));
// layer.on('destroy', (e) => console.log('destroy', e));
// layer.on('remove', (e) => {

View File

@ -72,6 +72,8 @@ import Slider from './components/slider'
import WindMap from './components/amap2demo_wind'
import SimplePoint from './components/simplePoint';
import LineWall from './components/linewall'
import GridTile from './components/gridTile'
import GridTile2 from './components/gridTile2'
// @ts-ignore
storiesOf('地图方法', module)
@ -148,3 +150,5 @@ storiesOf('地图方法', module)
.add('SimplePoint', () => <SimplePoint/>)
.add('LineWall', () => <LineWall/>)
.add('BusLine', () => <BusLine/>)
.add('GridTile', () => <GridTile/>)
.add('GridTile2', () => <GridTile2/>)