四十六、openlayers官网示例Icon Sprites with WebGL解析——使用WebGLPoints加载海量点数据。普通矢量图层加载点数据和webgl加载点数据性能对比

OpenLayers基础教程——使用WebGLPoints加载海量点数据 最近遇到一个问题:如何在OpenLayers中高效加载海量的场强点?由于项目中的一些要求,不能使用聚合的方法加载。OpenLayers中有一个类,使用该类可以轻松应对几十万的数据量,下面开始介绍。WebGL由于使用GPU加速渲染,因此绘图效率较高。在OpenLayers的开发中,如果遇到加载海量数据点的需求,不妨考虑使用实现。 阅读详情

官网demo地址:

Icon Sprites with WebGL

这篇讲的是使用webgl加载海量的数据点。

首先忘地图上添加了底图。

const rasterLayer = new Tile({
      source: new OGCMapTile({
        url: "https://maps.gnosis.earth/ogcapi/collections/NaturalEarth:raster:HYP_HR_SR_OB_DR/map/tiles/WebMercatorQuad",
        crossOrigin: "",
      }),
    });
    const map = new Map({
      layers: [rasterLayer],
      target: document.getElementById("map"),
      view: new View({
        center: [0, 4000000],
        zoom: 2,
      }),
    });

然后请求一个文件,获取点数据。 

 const client = new XMLHttpRequest();
    client.open(
      "GET",
      "https://openlayers.org/en/latest/examples/data/csv/ufo_sighting_data.csv"
    );
    client.addEventListener("load", function () {
      const csv = client.responseText;
      
    });
    client.send();

 请求回来的数据是这样的。

 所以要对数据进行一些切割处理,最终生成feature

const shapeTypes = {};
      const features = [];

      let prevIndex = csv.indexOf("\n") + 1;
      let curIndex;
      while ((curIndex = csv.indexOf("\n", prevIndex)) !== -1) {
        const line = csv.substring(prevIndex, curIndex).split(",");
        prevIndex = curIndex + 1;

        const coords = [parseFloat(line[5]), parseFloat(line[4])];
        const shape = line[2];
        shapeTypes[shape] = (shapeTypes[shape] || 0) + 1;

        features.push(
          new Feature({
            datetime: line[0],
            year: parseInt(/[0-9]{4}/.exec(line[0])[0], 10),
            shape: shape,
            duration: line[3],
            geometry: new Point(fromLonLat(coords)),
          })
        );
      }
      shapeTypes["all"] = features.length;

然后使用WebGLPointsLayer类构建一个图层并添加到地图上

 map.addLayer(
        new WebGLPointsLayer({
          source: new VectorSource({
            features: features,
            attributions: "National UFO Reporting Center",
          }),
          style: style,
        })
      );

 将不同类型的数据筛选条件添加进下拉框。

    fillShapeSelect(shapeTypes);
    function fillShapeSelect(shapeTypes) {
      Object.keys(shapeTypes)
        .sort(function (a, b) {
          return shapeTypes[b] - shapeTypes[a];
        })
        .forEach(function (shape) {
          const option = document.createElement("option");
          const sightings = shapeTypes[shape];
          option.text = `${shape} (${sightings} sighting${
            sightings === 1 ? "" : "s"
          })`;
          option.value = shape;
          shapeSelect.appendChild(option);
        });
    }

 下拉框的筛选效果是通过在style中定义变量filterShape、feature中添加自定义属性shape、以及下拉框中的value值结合实现的。下拉框的改变会更改style.variables.filterShape的值,然后调用地图的render方法来更新地图。

 const style = {
      variables: {
        filterShape: "all",
      },
      filter: [
        "any",
        ["==", ["var", "filterShape"], "all"],
        ["==", ["var", "filterShape"], ["get", "shape"]],
      ],
      "icon-src":
        "https://openlayers.org/en/latest/examples/data/ufo_shapes.png",
      "icon-width": 128,
      "icon-height": 64,
      "icon-color": [
        "interpolate",
        ["linear"],
        ["get", "year"],
        1950,
        oldColor,
        2013,
        newColor,
      ],
      "icon-offset": [
        "match",
        ["get", "shape"],
        "light",
        [0, 0],
        "sphere",
        [32, 0],
        "circle",
        [32, 0],
        "disc",
        [64, 0],
        "oval",
        [64, 0],
        "triangle",
        [96, 0],
        "fireball",
        [0, 32],
        [96, 32],
      ],
      "icon-size": [32, 32],
      "icon-scale": 0.5,
    };

图层渲染出来之后,可以看到,放大缩小、筛选操作地图的表现是非常流畅的,基本没有卡顿。

接下来,咱们来看看使用普通矢量图层加载海量数据点的表现。原本的style中的变量定义是WebGLPointsLayer的一些固定写法,和普通的矢量图层接受的style不一样。所以我们这里精简一下样式。

const style_common = {
      "icon-src":
        "https://openlayers.org/en/latest/examples/data/ufo_shapes.png",
      "icon-width": 128,
      "icon-height": 64,
      "icon-color": newColor,
      "icon-size": [32, 32],
      "icon-scale": 0.5,
    };

 map.addLayer(
        new VectorLayer({
        source: new VectorSource({
             features: features,
             attributions: "National UFO Reporting Center",
        }),
        style: style_common,
       })
 );

 加载上去之后,地图操作会有一些卡顿,我这里录屏可能看的不是很明显,但基本每个操作都有延迟。

总的来说,使用WebGLPointsLayer加载海量点数据性能会好很多。 但是webgl相关的api都还处于调试状态,官网api的api文档都没更新,大家如果日常项目中要使用的话可能还需要斟酌一下。

完整代码:

<template>
  <div class="box">
    <h1>Icon Sprites with WebGL</h1>
    <div id="map" class="map"></div>
    <div>Current sighting: <span id="info"></span></div>
    <div>
      <label for="shape-filter">Filter by UFO shape:</label>
      <select id="shape-filter"></select>
    </div>
  </div>
</template>

<script>
import Feature from "ol/Feature.js";
import Map from "ol/Map.js";
import Point from "ol/geom/Point.js";
import TileLayer from "ol/layer/WebGLTile.js";
import View from "ol/View.js";
import WebGLPointsLayer from "ol/layer/WebGLPoints.js";
import XYZ from "ol/source/XYZ.js";
import { fromLonLat } from "ol/proj.js";
import { OGCMapTile, Vector as VectorSource } from "ol/source.js";
import { Tile, Vector as VectorLayer } from "ol/layer.js";
export default {
  name: "",
  components: {},
  data() {
    return {
      map: null,
      extentData: "",
      message: {
        name: "",
        color: "",
      },
    };
  },
  computed: {},
  created() {},
  mounted() {
    const rasterLayer = new Tile({
      source: new OGCMapTile({
        url: "https://maps.gnosis.earth/ogcapi/collections/NaturalEarth:raster:HYP_HR_SR_OB_DR/map/tiles/WebMercatorQuad",
        crossOrigin: "",
      }),
    });
    const map = new Map({
      layers: [rasterLayer],
      target: document.getElementById("map"),
      view: new View({
        center: [0, 4000000],
        zoom: 2,
      }),
    });

    const oldColor = [255, 160, 110];
    const newColor = [180, 255, 200];

    const style = {
      variables: {
        filterShape: "all",
      },
      filter: [
        "any",
        ["==", ["var", "filterShape"], "all"],
        ["==", ["var", "filterShape"], ["get", "shape"]],
      ],
      "icon-src":
        "https://openlayers.org/en/latest/examples/data/ufo_shapes.png",
      "icon-width": 128,
      "icon-height": 64,
      "icon-color": [
        "interpolate",
        ["linear"],
        ["get", "year"],
        1950,
        oldColor,
        2013,
        newColor,
      ],
      "icon-offset": [
        "match",
        ["get", "shape"],
        "light",
        [0, 0],
        "sphere",
        [32, 0],
        "circle",
        [32, 0],
        "disc",
        [64, 0],
        "oval",
        [64, 0],
        "triangle",
        [96, 0],
        "fireball",
        [0, 32],
        [96, 32],
      ],
      "icon-size": [32, 32],
      "icon-scale": 0.5,
    };

    const style_common = {
      "icon-src":
        "https://openlayers.org/en/latest/examples/data/ufo_shapes.png",
      "icon-width": 128,
      "icon-height": 64,
      "icon-color": newColor,
      "icon-size": [32, 32],
      "icon-scale": 0.5,
    };

    const shapeSelect = document.getElementById("shape-filter");
    shapeSelect.addEventListener("input", function () {
      style.variables.filterShape = shapeSelect.value;
      map.render();
    });
    function fillShapeSelect(shapeTypes) {
      Object.keys(shapeTypes)
        .sort(function (a, b) {
          return shapeTypes[b] - shapeTypes[a];
        })
        .forEach(function (shape) {
          const option = document.createElement("option");
          const sightings = shapeTypes[shape];
          option.text = `${shape} (${sightings} sighting${
            sightings === 1 ? "" : "s"
          })`;
          option.value = shape;
          shapeSelect.appendChild(option);
        });
    }

    const client = new XMLHttpRequest();
    client.open(
      "GET",
      "https://openlayers.org/en/latest/examples/data/csv/ufo_sighting_data.csv"
    );
    client.addEventListener("load", function () {
      const csv = client.responseText;
      const shapeTypes = {};
      const features = [];

      let prevIndex = csv.indexOf("\n") + 1;
      let curIndex;
      while ((curIndex = csv.indexOf("\n", prevIndex)) !== -1) {
        const line = csv.substring(prevIndex, curIndex).split(",");
        prevIndex = curIndex + 1;

        const coords = [parseFloat(line[5]), parseFloat(line[4])];
        const shape = line[2];
        shapeTypes[shape] = (shapeTypes[shape] || 0) + 1;

        features.push(
          new Feature({
            datetime: line[0],
            year: parseInt(/[0-9]{4}/.exec(line[0])[0], 10),
            shape: shape,
            duration: line[3],
            geometry: new Point(fromLonLat(coords)),
          })
        );
      }
      shapeTypes["all"] = features.length;
        map.addLayer(
            new WebGLPointsLayer({
            source: new VectorSource({
                features: features,
                attributions: "National UFO Reporting Center",
            }),
            style: style,
            })
        );
      fillShapeSelect(shapeTypes);
    });
    client.send();

    const info = document.getElementById("info");
    map.on("pointermove", function (evt) {
      if (map.getView().getInteracting() || map.getView().getAnimating()) {
        return;
      }
      const text = map.forEachFeatureAtPixel(evt.pixel, function (feature) {
        const datetime = feature.get("datetime");
        const duration = feature.get("duration");
        const shape = feature.get("shape");
        return `On ${datetime}, lasted ${duration} seconds and had a "${shape}" shape.`;
      });
      info.innerText = text || "";
    });
  },
  methods: {
  },
};
</script>

<style lang="scss" scoped>
#map {
  width: 100%;
  height: 500px;
}
.box {
  height: 100%;
}
</style>

openlayers海量点渲染(2w点左右) 效果图 此处用到了openlayers的webgl属性 import GeoJSON from 'ol/format/GeoJSON'; //用来加载矢量数据 import WebGLPointsLayer from 'ol/layer/WebGLPoints'; //使用webgl渲染 初始化矢量图层,从文件加载点的地理信息 this.vectorSource = new Vector({ url: 'http://localhost:9528/data.ge 阅读详情

相关推荐

Openlayers实战:显示海量数据

Openlayers地图中通常的加载方式是canvas,另外还一种加载方式是webGL,在绘制海量数据时,使用GPU进行绘制可有效减少CPU的负载,提升绘制时的速度在浏览器中,可以使用WebGL的方式与GPU交互。在本实战中,使用WebGLPoints显示海量数据。

大剑师兰特的GIS世界 1446

Openlayers加载海量数据之WebGL

openlayer中使用webGL渲染海量点或面图层基本方法(提示:openlayer 6 以上的版本才支持webGL渲染)

qq_41283814的博客 5328

OpenLayers6入门,OpenLayers如何加载百万数据量的GeoJson点数据并叠加到webgl渲染图层上,百万海量点数据叠加不卡

上一章中《OpenLayers入门,OpenLayers如何加载GeoJson数据并叠加到OpenLayers矢量图层上》,我们讲解了少量数据加载并叠加到OpenLayers矢量图层上,如果数量特别大,浏览器就会很卡,所以需要用到webgl图层进行加载,本章就讲解使用webgl图层叠加海量GeoJson点数据。

GIS技术方向,GIS地图技术分享(GIS入门、Openlayers教程、Leaflet教程),做最好的GIS地图开发教程。关注博主公众号:eguid 2368

OpenLayers基础教程——WebGLPoints图层样式的设置方法

前一篇博客介绍了如何在中使用加载海量数据点的方法,这篇博客就来介绍一下图层的样式设置问题。在图层中,我们只需要创建一个对象即可,则不同,它并不是基于进行绘制,因此其样式渲染不能直接使用,取而代之的是使用样式运算符进行渲染。 2.2、数学运算符 2.3、变换运算符 2.4、逻辑运算符 2.5、转换运算符 3、简单渲染 简单颜色渲染很简单,只需要使用即可,第一个参数为固定值,后面的参数依次为红、绿、蓝、透明度。下面的代码会将要素渲染为红色点: 运行结果如下图所示:测试数据中的字段将要素分成了类,即:。现

HerryDong的博客 4057

049:vue+openlayers 鼠标pointermove显示城市名片

本示例的目的是介绍演示如何在vue+openlayers中采用overlay实现城市名片的效果,移动鼠标到相应的位置点,出现城市的信息。

大剑师兰特的GIS世界 2959

OpenLayers6入门,使用webgl图层叠加超大量Point点要素,解决叠加超过一百万数据量点位导致浏览器卡住变慢的问题

OpenLayers地图中当叠加超过几千以上要素点就开始变慢,一万以上的要素点的时候,浏览器页面就开始卡顿或直接卡死,甚至浏览器会弹出是否等待页面加载的提示。这时候要怎么优化?OpenLayers官方是推荐使用webgl图层方式对这种大量点渲染进行优化。当然webgl图层并不是没有缺点,使用webgl图层优点是渲染大量点很快,缺点就是style风格样式不能根据要素(Feature)的风格样式(style)自定义设置,只能用图层(layer)的风格样式(style)。

GIS技术方向,GIS地图技术分享(GIS入门、Openlayers教程、Leaflet教程),做最好的GIS地图开发教程。关注博主公众号:eguid 3989

Openlayers使用WebGL加载多种自定义图标矢量点

使用OpenLayers的WebGLPointsLayer加载海量矢量点(100W),并使用多种自定义图标样式。

无可言喻的博客 4643

OpenLayers6入门,OpenLayers6的WebGLPointsLayer图层样式和运算符详解,四种symbolType类型案例

本章讲解使用OpenLayers6的WebGL图层显示大量点情况下,列举出所有WebGLPointsLayer图层所支持的所有样式运算符大全。

GIS技术方向,GIS地图技术分享(GIS入门、Openlayers教程、Leaflet教程),做最好的GIS地图开发教程。关注博主公众号:eguid 1646

OpenLayers基础教程——WebGLPoints设置不同图标样式的方法

在中,与设置不同图标样式的方法有所不同。本文就来介绍一下如何在图层中根据要素类型设置不同的图标样式。设置不同图标的样式很简单,直接上代码: 运行结果如下图所示:采用样式表达式的方法来渲染要素,所以很多同志都会想到:用表达式来做不就行了吗?所以有如下错误代码: 运行结果如下图所示: 很明显,通过表达式无法得到我们想要的结果,此时就需要使用属性了。之前的代码使用张图片来分别表示不同的要素类型,如下图所示: 现在将这张图片拼接成张大图,这张大图的尺寸就是,如下图所示: 第个图标占据的位置可表示为:,也就是,以此类

HerryDong的博客 1408

使用Vue和OpenLayers在WebGLPoints上显示数据,并根据某一属性值的不同阈值来显示不同颜色的点。

在Vue组件中,你可以创建一个OpenLayers的地图容器。请确保在项目中正确引入所需的OpenLayers依赖,并根据你的实际需求修改代码中的数据和样式函数以适应你的应用程序。这样,当你在Vue应用中使用这个组件时,它将显示一个OpenLayers地图,并在地图上以不同的颜色显示数据点,根据它们的属性值和阈值来确定颜色。方法会根据你的数据数组创建一个OpenLayers的数据源,并将每个数据点转换为一个。方法中,我们创建了一个OpenLayers的地图实例,并设置了初始的视图。接下来,我们创建了一个。

ByteZenith的博客 508

OpenLayers入门,webgl图层叠加大量Icon图片到地图,解决叠加超大数据量图片导致浏览器卡住变慢的问题

上一章中《OpenLayers入门,使用webgl图层叠加大量点要素,解决OpenLayers地图中叠加大量点导致浏览器卡住变慢的问题》已经讲了如何地图中如何添加大量点到webgl图层优化大量点浏览器页面卡顿的问题,本章补充一下叠加图片图标到地图的情况下。

GIS技术方向,GIS地图技术分享(GIS入门、Openlayers教程、Leaflet教程),做最好的GIS地图开发教程。关注博主公众号:eguid 2083

Openlayers7的WebGLPointsLayer图层textureCoord生成工具

小工具(TypeScript+Vue3),可生成openlayers7的WebGLPointsLayer图层textureCoord属性对应的match表达式数据。

无可言喻的博客 1030

Openlayers扩展H5绘制10W+数据

NULL 博文链接:https://jjxliu306.iteye.com/blog/2317352

webgl入门系列(1)——画点

1、将画点写在顶点着色器里 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>点</title> <script src="base.js">&lt

niuge8905的博客 582

国内外主流嵌入式GUI汇总

随着MCU资源增多,处理能力也强了,同时市场需求也增多了GUI功能也越来越丰富了,很多的嵌入式图形库都可以做出绚丽的界面。

m0_69914734的博客 3290

国产系统迁移实战:在银河麒麟V10上搞定Wine32位支持,让老Windows软件跑起来

本文详细介绍了在银河麒麟V10操作系统上构建Wine32位支持的全过程,帮助用户解决Windows应用迁移难题。从系统架构差异分析到Wine环境配置,再到实战应用部署与优化,提供了一套完整的解决方案,确保老Windows软件在国产系统上稳定运行。

weixin_32288959的博客 649

动态加载feature样式

[Bindable] [Embed(source="assets/1_24x24.png")] public var fireClass:Class;                  private function createPtStyle(myclass:Class):Style         {             var style:Style = new Styl

wxljmy的专栏 1393

Sharding-JDBC 系列专题 - 第九篇:高可用性与集群管理

高可用性是指系统在面对故障(如数据库宕机、网络中断)时,能够快速恢复并继续提供服务。Sharding-JDBC 和 Sharding-Proxy 提供了多种机制支持高可用性,同时需要结合底层数据库的高可用方案(如 MySQL 主从复制、MHA)来实现。高可用性和集群管理是 Sharding-JDBC 和 Sharding-Proxy 在生产环境中成功应用的关键。本篇详细介绍了数据库高可用方案、Sharding-JDBC 的故障切换机制、Sharding-Proxy 的集群部署,以及分布式治理功能。

资深架构师分享:深入剖析软件架构,探讨云计算、微服务、大数据等前沿技术。分享实践经验,促进技术交流,共同构建卓越系统。 1393

7openlayers海量点加载

在map上注册鼠标移动事件,使用map的forEachFeatureAtPixel方法,获取到鼠标位置的feature,将属性name取出来进行展示。这里介绍两种方式加载,一种是使用ol/layer/Vector,一种是使用ol/layer/WebGLPoints。当需要把数据量相对较大的点在地图上展示的时候,方案总的来说就两种,一种是后端,一种是前端。同样的方法,模拟10万个点,加载到vectorSource2中,拖动地图不再有卡顿,比较流程。模拟10万个点,使用iconStyle进行渲染。

见路不走的博客 922

Unity性能优化 - 动态图集

Unity 动态图集是 Unity 引擎中用于处理游戏纹理优化的一种技术。本文介绍了什么是动态图集,动态图集的优缺点,以及提供了一套完整的代码供大家参考。

qq_33808037的博客 4840

Codesys.运动控制修改凸轮点

通过改凸轮曲线的主从轴缩放比例或者偏置。 新建多个凸轮曲线,对CAM曲线进行切换。 程序中动态修改,仅修改中间的关键点(凸轮末点修改or凸轮曲线运行中修改)。 程序中动态修改,修改首未关键点及关键点个数,需要重新触发MC_TableSelect。 使用程序新建凸轮表代码,实现电子凸轮基本运动。 我们讲的凸轮表切换、关键点修改、程序新建电子凸轮,这些方法没有本质区别,总之都是“趁曲线不注意,把凸轮表改了。

傻响雨 6828

openlayers+geoserver+postgre加载海量数据的办法

geoserver+postgre加载海量数据的办法 最近在开发GIS系统,碰巧遇到了海量数据加载的问题。特以博客以记之 1.openlayers解决点的海量数据加载 openlayers加载海量点数据openlayer在官网提供了支持,主要是通过聚合来实现: https://openlayers.org/en/latest/examples/cluster.html 2.openlayers加载非点状海量数据 主要是通过postgreSql来过滤掉一部分数据,过滤通过缩放级别zoom来限制,当缩

bool的博客 3213

halcon 检测直线

图中后三个对象既是检测出的图像;

qq_59062726的博客 666
上一篇: 四十五、openlayers官网示例Icon modification解析——在地图上添加标记图形并随意移动它的位置
下一篇: 四十七、openlayers官网示例Image Filters——给地图添加锐化、浮雕、边缘等滤镜效果
卷新心菜
博客等级 码龄4年 720粉丝 65原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值