L7 2.8 2022 新版本首发!

简介: 导读L7 是由蚂蚁金服 AntV 数据可视化团队推出的基于 WebGL 的开源大规模地理空间数据可视分析开发框架。L7 专注于空间数据的可视化表达。图形符号学为理论基础,将抽象复杂的空间数据转化成 2D、3D 符号,通过颜色、大小、体积、纹理等视觉变量实现丰富的可视化表达。欢迎关注和 star 我们的 GitHub:https://github.com/antvis/L7官网:https://l7

导读

L7 是由蚂蚁金服 AntV 数据可视化团队推出的基于 WebGL 的开源大规模地理空间数据可视分析开发框架。L7 专注于空间数据的可视化表达。图形符号学为理论基础,将抽象复杂的空间数据转化成 2D、3D 符号,通过颜色、大小、体积、纹理等视觉变量实现丰富的可视化表达。

欢迎关注和 star 我们的 GitHub:https://github.com/antvis/L7

官网:https://l7.antv.vision/zh

2022 年伊始,我们为 L7 补全了后处理相关的模块,在提供多种默认后处理的同时,支持用户自定义后处理,为传统的地图可视效果增添了更多的大屏元素。除此之外,L7 对原有的点图层、面图层以及热力图层等都升级了可视化的能力和效果,提供了图片图层的全新实现。最后,L7 在 2.7.x 版本中修复了许多移动端的兼容性问题,让 L7 在移动端的开发体验更加丝滑。

本次发布重点包括:

  • 提供单独的后处理模块,让现有的可视化效果更加炫酷
  • 点图层、面图层能力升级
  • 热力图层效果优化,热力效果更加细腻
  • 对图层底层的 shader 实现进行了升级,能为用户带来更好的性能
  • 修复许多移动端兼容性问题,让移动端开发体验更加丝滑

后处理模块

通过设置 enableMultiRenderer 的参数为 true,以及 传入对应的 passes 参数,用户很容易为 L7 的图层加上后处理效果。

const layer = new PolygonLayer({
      enableMultiPassRenderer: true,
      passes: [
        [
          'bloom',
          {
            bloomBaseRadio: 0.5,
            bloomRadius: 20,
            bloomIntensity: 1,
          },
        ],
      ],
    })

普通效果

bloom 效果

L7 的后处理模块基础能力:

  • 以单个图层为粒度进行后处理,而非是全局后处理(这让用户能更加自由的设计效果)。

飞机单独加后处理效果

点图层单独加后处理效果

  • L7 本身预置了一部分后处理

  • L7 支持用户自定义后处理效果,并提供了相关的规范

import { BasePostProcessingPass, PolygonLayer, Scene } from '@antv/l7';
interface IDotScreenEffectConfig {
  center: [number, number]; // pattern 圆心
  angle: number; // dot 旋转角度
  size: number; // dot 尺寸
}
class DotScreenEffect extends BasePostProcessingPass {
  protected setupShaders() {
    this.shaderModuleService.registerModule('dotScreenEffect', {
      vs: this.quad,
      fs: `
      varying vec2 v_UV;

      uniform sampler2D u_Texture;
      uniform vec2 u_ViewportSize : [1.0, 1.0];
      uniform vec2 u_Center : [0.5, 0.5];
      uniform float u_Angle : 1;
      uniform float u_Size : 3;

      float pattern(vec2 texSize, vec2 texCoord) {
        float scale = 3.1415 / u_Size;
        float s = sin(u_Angle), c = cos(u_Angle);
        vec2 tex = texCoord * texSize - u_Center * texSize;
        vec2 point = vec2(
          c * tex.x - s * tex.y,
          s * tex.x + c * tex.y
        ) * scale;
        return (sin(point.x) * sin(point.y)) * 4.0;
      }
      vec4 dotScreen_filterColor(vec4 color, vec2 texSize, vec2 texCoord) {
        float average = (color.r + color.g + color.b) / 3.0;
        return vec4(vec3(average * 10.0 - 5.0 + pattern(texSize, texCoord)), color.a);
      }

      void main() {
        gl_FragColor = vec4(texture2D(u_Texture, v_UV));
        gl_FragColor = dotScreen_filterColor(gl_FragColor, u_ViewportSize, v_UV);
      }
      `,
    });
    const { vs, fs, uniforms } = this.shaderModuleService.getModule(
      'dotScreenEffect',
    );
    const { width, height } = this.rendererService.getViewportSize();

    return {
      vs,
      fs,
      uniforms: {
        ...uniforms,
        u_ViewportSize: [width, height],
      },
    };
  }
}
    // 注册自定义后处理效果
    scene.registerPostProcessingPass(DotScreenEffect, 'dotScreenEffect');
    const layer = new PolygonLayer({
      enableMultiPassRenderer: true,
      passes: [
        [
          'dotScreenEffect',
          {
            size: 8,
            angle: 1,
          },
        ],
      ],
    });
  • L7 提供了动态图层后处理方法 setMultiPass

let selectLayer = null;
    for (let i = 0; i < 10; i++) {
      let pointLayer = new PointLayer({
        zIndex: 1,
        enableMultiPassRenderer: false,
        passes: [
          [
            'bloom',
            {
              bloomBaseRadio: 0.95,
              bloomRadius: 4,
              bloomIntensity: 1.1,
            },
          ],
        ],
      })
        .source(
          [{ lng: 120 + Math.random() * 10, lat: 20 + Math.random() * 10 }],
          {
            parser: {
              type: 'json',
              x: 'lng',
              y: 'lat',
            },
          },
        )
        .shape('circle')
        .size(20)
        .color('red');
      scene.addLayer(pointLayer);
    }
    scene.on('loaded', () => {
      scene.getLayers().map((layer) => {
        layer.on('click', () => {
          if (selectLayer) {
            selectLayer.setMultiPass(false);
          }
          selectLayer = layer;
          layer.setMultiPass(true);
        });
      });
    });

图层能力升级

点图层

  • 点图层圆柱体支持固定高度配置 heightfixed

经典效果

新增效果

  • 点图层圆柱体支持拾取高亮颜色的光照计算

优化前

优化后

  • 补全 mapbox 模式下等面积点
  • 点图层新增 fillimage 模式,图标的大小不再受限制,同时至此自定义旋转角度

普通 image 模式(大小受限,角度固定)

fillimage 模式(大小不受限,角度自由调节)

 const imageLayer = new PointLayer({ layerType: 'fillImage' })
        .source(data)
        .shape('s', (s) => s)
        .size(100)
        .active({
          color: '#f00',
          mix: 0.5,
        })
        .style({
          rotation: 90	// 图标顺时针旋转 90 度、默认保持上方向
        })

面图层

  • 面图层挤出几何体支持固定高度

经典效果

新增效果

热力图效果优化

优化前

优化后(效果更加细腻)

新增图层方法

  • 新增 setAutoFit 方法,让用户可以主动设置图层的 autoFit 参数
  • 设置完该方法后会在图层发生更新的时候生效,如在 setData 之后触发
// 使用方法
layer.setAutoFit(true);
// 内部实现
public setAutoFit(autoFit: boolean): ILayer {
    this.updateLayerConfig({
      autoFit,
    });
    return this;
  }
  • 修改 setBlend 方法、返回当前的 layer 对象,方便用户链式调用
  • 新增 layer 的 getScale 方法,支持单独获取某个图形经过 scale 计算后的值
  • 满足用户获取图层某些 feature 值的需求
const data = [
  {lng: 120, lat: 30, name: 'n1'},
  {lng: 120, lat: 30, name: 'n2'}
]
const layer = new PointLayer()
	.source(data, {
		parser: {
    	x: 'lng',
      y: 'lat',
      type: 'json'
    }
  })
	.shape('circle')
	.color('name', ['#f00', '#ff0'])
	.size('name', [20, 40])

scene.addLayer(layer)


// 此时在 scene 上绘制两个点
// 一个颜色为黄色,大小为 40 的点,对应 name 为 n1
// 一个颜色为红色,大小为 20 的点,对应 name 为 n2

const colorScale = layer.getScale('color'); // 获取 color 方法产生的 scale
const color1 = colorScale('n1'); // '#ff0'
const color1 = colorScale('n2'); // '#f00'

const sizeScale = layer.getScale('size'); // 获取 size 方法产生的 scale
const size1 = sizeScale('n1'); // 40
const size2 = sizeScale('n2'); // 20

周边生态

Dipper

  • 对整体布局进行改造,支持用户自定义地图应用布局。
  • 移动端兼容性适配,同时新增了移动端地图应用基础样式。
  • 新增Marker图层、Image图层和Point图层。
  • 完善 开发文档

尾声

最后想对用过或者还没有用过 L7 的同学,听说过或者还未听说过 L7 的同学说,2022 新的一年,L7 始终会保持热情,为大家提供更专业、更好用、更炫酷的地理可视化!

同时也欢迎感兴趣的同学一起参加到 L7 的建设,无论是提出更好的需求,还是参与到实际的编码,我们都欢迎大家!

欢迎大家点点 star ✨  Github

官方钉钉群号:32292906

相关文章
|
4月前
|
人工智能 安全 数据可视化
低代码项目管理平台:2025年最具性价比的解决方案指南
低代码项目管理平台结合可视化编程与自动化工具,助力企业快速搭建个性化管理系统,无需深入编码知识。其核心理念是“最少代码,最大灵活性”,支持拖拽组件、配置流程,显著提升开发效率与协作能力。
177 1
|
10月前
|
编解码 前端开发 算法
实时云渲染方案为虚拟仿真教学搭建共享平台
实时云渲染技术的应用也日益重要,平行云作为唯一提供云渲染技术服务的企业,参与制定《虚拟仿真实验教学课程建设与共享应用规范(试用版·2020)》,有效解决下载、算力和盗版等痛点,实现随时随地的在线访问,保护知识产权,降低终端硬件要求,兼容性强,助力学校构建统一入口云平台。
|
11月前
|
人工智能 编解码 机器人
NVILA:英伟达开源视觉语言大模型,高效处理高分辨率图像和长视频
NVILA是英伟达推出的视觉语言大模型,旨在高效处理高分辨率图像和长视频,同时保持高准确性。该模型通过“扩展-压缩”策略和多种优化技术,在多个领域如机器人导航和医疗成像中展现出广泛的应用潜力。
457 13
NVILA:英伟达开源视觉语言大模型,高效处理高分辨率图像和长视频
|
存储 缓存 监控
网站的图片资源是否需要设置缓存?
【10月更文挑战第18天】网站的图片资源一般是需要设置缓存的,但要根据图片的具体特点和网站的需求,合理设置缓存时间和缓存策略,在提高网站性能和用户体验的同时,确保用户能够获取到准确、及时的图片信息。
|
缓存 前端开发 UED
React Suspense 懒加载详解
【10月更文挑战第18天】React Suspense 是 React 16.6 引入的新特性,主要用于处理异步数据获取和组件懒加载。本文从 Suspense 的基本概念出发,介绍了其在代码分割和数据获取中的应用,通过具体代码示例展示了如何使用 `React.lazy` 和 `Suspense` 实现组件的懒加载,并探讨了实践中常见的问题及解决方法,帮助开发者提升应用性能和用户体验。
641 2
|
缓存 JavaScript 前端开发
【开发规范系列】(四)前端开发规范(四)
【开发规范系列】(四)前端开发规范(四)
|
数据可视化 定位技术 数据处理
MapboxGL可视化之千里江山图
本文记录了作者在Mapbox GL中实现山峰等值面效果的过程,灵感来源于百度地图的山峰展示方式。作者通过下载和处理DEM数据,使用QGIS生成等值面,并通过Mapbox GL的fill图层实现分段渲染,最终效果宛如“千里江山图”,美不胜收。
245 0
代码设置ConstraintLayout的layout_constraintDimensionRatio
代码设置ConstraintLayout的layout_constraintDimensionRatio
|
机器学习/深度学习 Python
【初窥CBAM】实操版即插即用的注意力机制模块
【初窥CBAM】实操版即插即用的注意力机制模块
581 0
【初窥CBAM】实操版即插即用的注意力机制模块
|
算法 小程序 API
uniapp显示当前位置与所传入位置的距离
uniapp显示当前位置与所传入位置的距离
701 0