AntVL7-上手流程
简介
基于 WebGL 的开源大规模地理空间数据可化视分析开发框架。
L7 中的 L 代表 Location,7 代表世界七大洲。专注数据可视化表达,通过颜色、大小、纹理,方向,体积等视觉变量设置实现从数据到信息清晰,有效的表达。
L7 能够满足常见的地图图表,BI 系统的可视化分析、以及 GIS,交通,电力,国土,农业,城市等领域的空间信息管理,分析等应用系统开发需求。
教程
- 100+套大数据可视化模板
https://gitee.com/iGaoWei/big-data-view - antv&L7 github
https://github.com/antvis/L7 - 使用教程
快速上手 | L7 - API文档
场景 Scene | L7 - 图表演示
所有图表 | L7
特点
- 数据驱动可视化展示
数据驱动,灵活数据映射,从数到形,支持丰富的地图可视化类型,更好洞察数据。 - 2D,3D 一体化的海量数据高性能渲染
海量空间数据实时,可交互,动态渲染, - 简单灵活的数据接入
支持 CSV,JSON,GeoJSON 等数据格式接入,可以根据需求自定义数据格式,无需复杂的空间数据转换。 - 多地图底图支持,支持离线内网部署
屏蔽不同底图之间的差异,用户只需要关注数据层表达,交互。高德地图国内合法合规的地理底图,Mapbox 满足国际化业务需求。
快速上手
安装
- npm引入
// 安装L7 依赖
npm install --save @antv/l7
// 安装第三方底图依赖
npm install @antv/l7-maps
// 地理绘制库
npm install @antv/l7-draw
使用:
<script src="./node_modules/@antv/l7/dist/l7.js"></script>
const scene = new L7.Scene({
id: 'map',
map: new L7.GaodeMap({
style: 'dark',
center: [110.770672, 34.159869],
pitch: 45,
}),
});
模块内:
import { Scene } from '@antv/l7';
import { GaodeMap } from '@antv/l7-maps';
- cnd引入
<!-- 引入最新版的L7 -->
<script src="https://unpkg.com/@antv/l7"></script>
<!-- 指定版本号引入L7 -->
<script src="https://unpkg.com/@antv/l7@2.0.11"></script>
<!-- 地理绘制库 -->
<script src="https://unpkg.com/@antv/l7-draw@3.0.28/dist/l7-draw.min.js"></script>
const { Scene, GaodeMap } = L7
const scene = new Scene({
id: 'map',
map: new GaodeMap({
style: 'dark', // 样式
center: [104.288144, 31.239692], // 中心坐标点
zoom: 4.4, // 缩放比例
}),
})
初始化地图
- 引入L7相关的库文件
- 准备地图容器
- 创建场景实例
<!-- 1. 引入L7 -->
<script src="https://unpkg.com/@antv/l7"></script>
<body>
<!-- 2. 准备地图容器 -->
<div id="map"></div>
<script>
// 3. 初始化对象
const { Scene, GaodeMap } = L7
const scene = new Scene({
id: 'map',
map: new GaodeMap({
style: 'dark', // 样式
center: [104.288144, 31.239692], // 中心坐标点
zoom: 4.4, // 缩放比例
}),
})
</script>
</body>
- 场景Scene: 包含地图, 控件, 组件, 加载资源的全局对象. 通过scene可以获取到操作地图需要的所有内容
- 地图: 支持
Mapbox
和Gaode
地图
添加图层
- 面图层
const { Scene, GaodeMap, PolygonLayer } = L7
const scene = new Scene({
id: 'map',
map: new GaodeMap({
style: 'normal',
center: [114.3, 30.5],
zoom: 5,
// token: '',
}),
})
// 通过fetch获取数据
fetch('./data/province.json')
.then((res) => res.json())
.then((data) => {
// 创建面图层
const chinaPolygonLayer = new PolygonLayer({
autoFit: true,
})
.source(data)
.color('name', [
'rgb(239,243,255)',
'rgb(189,215,231)',
'rgb(107,174,214)',
'rgb(49,130,189)',
'rgb(8,81,156)',
])
// 添加图层
scene.addLayer(chinaPolygonLayer)
})
- 线图层
// 3. 初始化对象
const { Scene, GaodeMap, PolygonLayer, LineLayer } = L7
const scene = new Scene({
id: 'map',
map: new GaodeMap({
style: 'dark', // 样式
center: [104.288144, 31.239692], // 中心坐标点
zoom: 4.4, // 缩放比较
}),
})
scene.on('loaded', () => {
fetch('./data/province.json')
.then((res) => res.json())
.then((data) => {
const chinaPolygonLayer = new PolygonLayer({
autoFit: true,
})
.source(data)
.color('name', [
'rgb(239,243,255)',
'rgb(189,215,231)',
'rgb(107,174,214)',
'rgb(49,130,189)',
'rgb(8,81,156)',
])
scene.addLayer(chinaPolygonLayer)
// 设置省边界线图层
const layer2 = new LineLayer({
zIndex: 2,
})
.source(data)
.color('rgb(93,112,146)')
.size(0.6)
.style({
opacity: 1,
})
scene.addLayer(layer2)
})
})
- 标注文本
fetch(
"https://gw.alipayobjects.com/os/bmw-prod/c4a6aa9d-8923-4193-a695-455fd8f6638c.json" // 标注数据
)
.then(res => res.json())
.then(data => {
const labelLayer = new PointLayer({
zIndex: 5
})
.source(data, {
parser: {
type: "json",
coordinates: "center"
}
})
.color("#fff")
.shape("name", "text")
.size(12)
.style({
opacity: 1,
stroke: "#fff",
strokeWidth: 0,
padding: [5, 5],
textAllowOverlap: false
});
scene.addLayer(labelLayer);
});
L7组件
L7 中的 Component 主要包含以下三种类型:
- Control 控件类型:指的是悬停在地图四周,可以对地图以及图层等元素进行信息呈现或交互的组件。
- Popup 气泡类型:用于在地图上指定经纬度位置展示气泡,气泡内容完全交由开发者自定义。
- Marker 类型:与 Popup 相似,不同的是 Marker 展示的内容不会在气泡内展示,而是完全交由开发者自定义。
Control
- Logo
const { Scene, GaodeMap, Logo } = L7
// 3. 初始化对象
const scene = new Scene({
id: 'map',
map: new GaodeMap({
style: 'dark', // 样式
center: [104.288144, 31.239692], // 中心坐标点
zoom: 4.4, // 缩放比较
logo: true,
}),
logoVisible: false, // 关闭L7 默认logo
})
// 4. 添加组件
// logo组件
scene.on('loaded', () => {
const logo = new Logo({
// 图片 url
img: 'https://img.gejiba.com/images/dfdb6db1623eb881e724f58d9a366af8.png',
// 跳转地址
href: 'http://www.x-zd.com/',
})
scene.addControl(logo)
})
- Zoom
const { Zoom } = L7;
scene.on('loaded', () => {
const zoom = new Zoom({
position: 'bottomright',
zoomInTitle: '放大',
zoomOutTitle: '缩小',
});
scene.addControl(zoom);
});
- Scale
const { Scale } = L7;
scene.on('loaded', () => {
const scale = new Scale({
position: 'bottomleft',
metric: true,
imperial: false,
maxWidth: 100,
})
scene.addControl(scale)
})
- Fullscreen
const { Fullscreen } = L7
scene.on('loaded', () => {
const fullscreen = new Fullscreen({
btnText: '全屏',
exitBtnText: '退出全屏',
});
scene.addControl(fullscreen)
});
- ExportImage
const { ExportImage } = L7
scene.on('loaded', () => {
const exportImage = new ExportImage({
onExport: (base64) => {
alert(base64)
},
})
scene.addControl(exportImage)
})
- 图层切换
const { PointLayer, LayerSwitch } = L7
scene.on('loaded', () => {
const layer = new PointLayer({
name: '点图层',
})
layer
.source({
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [114.3, 30.5],
},
},
],
})
.shape('circle')
.color('#333')
.style({
opacity: 0.5,
strokeWidth: 1,
})
.size(20)
.active(true)
scene.addLayer(layer)
const layerSwitch = new LayerSwitch({
layers: [layer],
})
scene.addControl(layerSwitch)
})
- MouseLocation
const { MouseLocation } = L7
scene.on('loaded', () => {
const mouseLocation = new MouseLocation({
transform: (position) => {
return position
},
})
scene.addControl(mouseLocation)
})
- 地图主题
const { MapTheme } = L7;
scene.on('loaded', () => {
const mapTheme = new MapTheme({});
scene.addControl(mapTheme);
});
Marker
- 基本示例
<div id="map"></div>
<script>
const { Scene, GaodeMap, Marker } = L7
const scene = new Scene({
id: 'map',
map: new GaodeMap({
style: 'normal',
center: [114.3, 30.5],
zoom: 5,
}),
})
scene.on('loaded', () => {
const marker = new Marker()
// console.log(marker)
marker.setLnglat([114.3, 30.5])
scene.addMarker(marker)
})
</script>
</body>
</html>
- marker结合popup
<script>
const { Scene, GaodeMap, Marker, Popup } = L7
const scene = new Scene({
id: 'map',
map: new GaodeMap({
style: 'normal',
center: [114.3, 30.5],
zoom: 5,
}),
})
scene.on('loaded', () => {
const marker = new Marker()
marker.setLnglat([114.3, 30.5])
const popup = new Popup({
offsets: [0, 50],
}).setText('武汉')
marker.setPopup(popup)
scene.addMarker(marker)
})
</script>
- 自定义marker
#marker {
text-align: center;
background-color: #652e8092;
line-height: 50px;
color: #fff;
width: 50px;
height: 50px;
border-radius: 50%;
cursor: pointer;
}
// 创建DOM元素
const element = document.createElement('div')
element.id = 'marker'
// 基于DOM元素创建Marker标注
const marker = new Marker({
element: element,
})
marker.setLnglat([114.3, 30.5])
scene.addMarker(marker)
- Marker图层
<style>
* {
margin: 0;
padding: 0;
}
.marker {
text-align: center;
background-color: #652e8092;
line-height: 50px;
color: #fff;
width: 50px;
height: 50px;
border-radius: 50%;
cursor: pointer;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
const { Scene, GaodeMap, Marker, MarkerLayer } = L7
const scene = new Scene({
id: 'map',
map: new GaodeMap({
style: 'normal',
center: [114.3, 30.5],
zoom: 5,
}),
})
// 定义数据
const data = [
{
lng: 114.3,
lat: 30.5,
name: '武汉',
},
{
lng: 112.59,
lat: 28.12,
name: '长沙',
},
]
scene.on('loaded', () => {
// 创建标注图层
const markerLayer = new MarkerLayer({})
for (const city of data) {
const { lng, lat, name } = city
// 创建标注对象
const element = document.createElement('div')
element.className = 'marker'
element.innerHTML = name
const marker = new Marker({
element: element,
})
marker.setLnglat([lng, lat])
markerLayer.addMarker(marker)
}
// 将标注图层添加到场景上
scene.addMarkerLayer(markerLayer)
})
</script>
</body>
</html>
图层
点图层
-
点图层(PointLayer) 由点对象(Point)组成
-
点对象可以由
图片
或者文本
描述
- 符号点
const { Scene, GaodeMap, PointLayer } = L7
const scene = new Scene({
id: 'map',
map: new GaodeMap({
style: 'normal',
center: [114.3, 30.5],
zoom: 10,
}),
})
const data = [
{
lng: 114.3,
lat: 30.5,
name: '白沙洲',
},
{
lng: 114.4,
lat: 30.45,
name: '中南路',
},
]
scene.on('loaded', () => {
scene.addImage('police', './images/avatar.png')
const policeLayer = new PointLayer()
.source(data, {
parser: {
type: 'json',
x: 'lng',
y: 'lat',
},
})
.shape('police') // 形状: 使用police图片
.size(16) // 大小: 单位px
scene.addLayer(policeLayer)
})
- 圆环动图
const data = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [114.3, 30.5],
},
},
],
}
scene.on('loaded', () => {
const pointLayer = new PointLayer()
.source(data) // 设置数据源
.animate(true) // 开启动画
.color('#ff0000') // 设置颜色
.shape('circle') // 设置形状
.size(100) // 设置大小 px
.active(true) // 选中状态
scene.addLayer(pointLayer)
})
- 雷达图
scene.on('loaded', () => {
const pointLayer = new PointLayer()
.source(data) // 设置数据源
.animate(true) // 开启动画, 设置雷达图, 必须开启动画
.color('#ff0000') // 设置颜色
.shape('radar') // 设置形状
.size(100) // 设置大小 px
.active(true) // 选中状态
scene.addLayer(pointLayer)
})
线图层
- 流线动图
const { Scene, GaodeMap, LineLayer } = L7
const scene = new Scene({
id: 'map',
map: new GaodeMap({
style: 'normal',
center: [114.3, 30.5],
zoom: 10,
}),
})
const data = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'LineString',
coordinates: [
[114.292975, 30.488542],
[114.29292, 30.493947],
[114.293779, 30.498206],
[114.299404, 30.498046],
[114.302326, 30.497993],
],
},
},
],
}
scene.on('loaded', () => {
const layer = new LineLayer()
.source(data)
.shape('line')
.size(2)
.color('#f00')
.animate({
trailLength: 1, // 流线长度
interval: 0.5, // 实现流线的间隔,分两段执行完流线
duration: 2, // 每段轨迹执行的时间
})
scene.addLayer(layer)
})
- 3D弧线图
scene.on('loaded', () => {
scene.setRotation(30)
const layer = new LineLayer({
blend: 'normal',
})
.source(data)
.shape('arc3d')
.size(2)
.color('#f00')
.animate({
trailLength: 1,
interval: 0.5,
duration: 2,
})
scene.addLayer(layer)
})
面图层
- 深圳智慧城市
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<!-- 引入库文件 -->
<link
href="https://api.mapbox.com/mapbox-gl-js/v2.9.1/mapbox-gl.css"
rel="stylesheet"
/>
<script src="https://api.mapbox.com/mapbox-gl-js/v2.9.1/mapbox-gl.js"></script>
<script src="https://unpkg.com/@antv/l7"></script>
<style>
* {
margin: 0;
padding: 0;
}
body {
overflow: hidden;
}
#map {
height: 100vh;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
// 创建mapbox地图对象
mapboxgl.accessToken = ''
const map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/dark-v10',
pitch: 50,
center: [114.050008, 22.529272],
zoom: 14,
})
// 创建L7的场景
const { Scene, Mapbox, PolygonLayer } = L7
const scene = new Scene({
id: 'map',
map: new Mapbox({
mapInstance: map,
}),
})
scene.on('loaded', () => {
fetch('https://gw.alipayobjects.com/os/basement_prod/972566c5-a2b9-4a7e-8da1-bae9d0eb0117.json'
)
.then((res) => res.json())
.then((data) => {
// console.log(data)
const layer = new PolygonLayer()
.source(data)
.shape('extrude')
.size('h10', [100, 120, 160, 200, 260, 500])
.color('h10', [
'#816CAD',
'#A67FB5',
'#C997C7',
'#DEB8D4',
'#F5D4E6',
'#FAE4F1',
'#FFF3FC',
])
.active(true)
scene.addLayer(layer)
})
})
</script>
</body>
</html>
- 水体
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<!-- 1. 引入L7库 -->
<script src="https://unpkg.com/@antv/l7"></script>
<style>
* {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<!-- 2. 准备地图容器 -->
<div id="map"></div>
<!-- 3. 创建场景和地图对象 -->
<script>
const { Scene, GaodeMap, PolygonLayer } = L7
const scene = new Scene({
id: 'map',
map: new GaodeMap({
style: 'normal',
center: [120.144689, 30.250433],
zoom: 14,
token: 'bda17043c3dfbbbfd24900155b3fa909',
pitch: 45,
}),
})
scene.on('loaded', () => {
fetch(
'https://gw.alipayobjects.com/os/bmw-prod/67130c6c-7f49-4680-915c-54e69730861d.json'
)
.then((data) => data.json())
.then((data) => {
const { lakeData } = data
const lakeLayer = new PolygonLayer()
.source(lakeData)
.shape('ocean')
.color('#1E90FF')
.style({ speed: 0.4 })
.animate(true)
scene.addLayer(lakeLayer)
})
})
</script>
</body>
</html>
图形绘制
绘制点
DrawPoint
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<!-- 1. 引入L7库 -->
<script src="https://unpkg.com/@antv/l7"></script>
<script src="./node_modules/@antv/l7-draw/dist/l7-draw.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
.btn {
padding: 5px;
}
.enable {
position: absolute;
top: 0;
left: 0;
z-index: 99;
}
.exit {
position: absolute;
top: 0;
left: 100px;
z-index: 99;
}
</style>
</head>
<body>
<button onclick="addPoint()" class="btn enable">开启点绘制</button>
<button onclick="exit()" class="btn exit">退出</button>
<div id="map"></div>
<script>
const { Scene, GaodeMap } = L7
const { DrawPoint, DrawEvent } = L7.Draw
const scene = new Scene({
id: 'map',
map: new GaodeMap({
style: 'normal',
center: [114.3, 30.5],
zoom: 10,
}),
})
let draw = null
scene.on('loaded', () => {
// 创建绘制点的工具
draw = new DrawPoint(scene, {})
})
function addPoint() {
draw.enable()
}
function exit() {
draw.disable()
}
</script>
</body>
</html>
绘制线
DrawLine
const { Scene, GaodeMap } = L7
const { DrawLine, DrawEvent } = L7.Draw
const scene = new Scene({
id: 'map',
map: new GaodeMap({
style: 'normal',
center: [114.3, 30.5],
zoom: 10,
}),
})
scene.on('loaded', () => {
const drawLine = new DrawLine(scene, {
// 测量距离的参数
distanceOptions: {
showTotalDistance: false, // 不显示总长度
showDashDistance: true, // 显示分段长度
format: (meters) => {
if (meters >= 1000) {
return +(meters / 1000).toFixed(2) + 'km'
} else {
return +meters.toFixed(2) + 'm'
}
},
},
})
drawLine.enable()
})
绘制面
DrawPolygon
const { DrawPolygon, DrawEvent } = L7.Draw
scene.on('loaded', () => {
const drawPolygon = new DrawPolygon(scene, {
areaOptions: {
format: (squareMeters) => {
return squareMeters > 1000000
? `${+(squareMeters / 1000000).toFixed(2)}km²`
: `${+squareMeters.toFixed(2)}m²`
},
},
})
drawPolygon.enable()
})
绘制矩形
DrawRect
const { DrawEvent, DrawRect } = L7.Draw
scene.on('loaded', () => {
const drawRect = new DrawRect(scene, {});
drawRect.enable();
drawRect.on(DrawEvent.Change, (allFeatures) => {
console.log(allFeatures);
});
});
绘制图
DrawCircle
const { DrawEvent, DrawCircle } = L7.Draw
scene.on('loaded', () => {
const drawCircle = new DrawCircle(scene, {});
drawCircle.enable();
drawCircle.on(DrawEvent.Change, (allFeatures) => {
console.log(allFeatures);
});
});