Leaflet系列:webgl方式加载point

决方案来源于github,基于Leaflet的地图的,使用webgl方式加载了8万多个点,除去互联网上访问数据,渲染的时候没有出现卡顿的情况,缩放也没有卡顿,此方式可以作为一个地图上加载特征图层的方式。

这种方式不同于使用Leaflet的API加载point,这个是在地图的上层覆盖一个canvas对象,使用的是开源的L.CanvasOverlay.js,github上可以搜索到这个,将point绘制在canvas上,在地图范围或级别的动态变化时,计算vertex shader中的变换矩阵,保持和地图上的位置一致。

json坐标数据量:
在这里插入图片描述
关键的shader:

<script id="vshader" type="x-shader/x-vertex">

    uniform mat4 u_matrix;

    attribute vec4 a_vertex;

    attribute float a_pointSize;

    attribute vec4 a_color;

    varying vec4 v_color;



    void main() {

    // Set the size of the point

    gl_PointSize =  a_pointSize; 

    // multiply each vertex by a matrix.

    gl_Position = u_matrix * a_vertex;  

    // pass the color to the fragment shader

    v_color = a_color;

    }

</script>

<!-- fragment shader --> 

<script id="fshader" type="x-shader/x-fragment">

    precision mediump float;

    varying vec4 v_color;

    void main() {



    float border = 0.05;

    float radius = 0.5;

    vec4 color0 = vec4(0.0, 0.0, 0.0, 0.0);

    vec4 color1 = vec4(v_color[0], v_color[1], v_color[2], 0.2);



    vec2 m = gl_PointCoord.xy - vec2(0.5, 0.5);

    float dist = radius - sqrt(m.x * m.x + m.y * m.y);



    float t = 0.0;

    if (dist > border)

    t = 1.0;

    else if (dist > 0.0)

    t = dist / border;



    // float centerDist = length(gl_PointCoord - 0.5);

    // works for overlapping circles if blending is enabled

    gl_FragColor = mix(color0, color1, t);

    

    /*

    // -- another way for circle

    float centerDist = length(gl_PointCoord - 0.5);

    float radius = 0.5;

    // works for overlapping circles if blending is enabled

    gl_FragColor = vec4(v_color[0], v_color[1], v_color[2], 0.2 * step(centerDist, radius));

    */



    /*

    // simple circles

    float d = distance (gl_PointCoord, vec2(0.5,0.5));

    if (d < 0.5 ){

    gl_FragColor =vec4(v_color[0], v_color[1], v_color[2], 0.2);

    }

    else{

    discard;

    }

    */



    // -- squares

    //gl_FragColor = v_color;

    //gl_FragColor =vec4(v_color[0], v_color[1], v_color[2], 0.2); // v_color;



    }



</script>



// -- converts latlon to pixels at zoom level 0 (for 256x256 tile size) , inverts y coord )

    // -- source : http://build-failed.blogspot.cz/2013/02/displaying-webgl-data-on-google-maps.html

//将经纬度转换像素的代码,在第一级别进行转换

    function LatLongToPixelXY(latitude, longitude) {

        var pi_180 = Math.PI / 180.0;

        var pi_4 = Math.PI * 4;

        var sinLatitude = Math.sin(latitude * pi_180);

        var pixelY = (0.5 - Math.log((1 + sinLatitude) / (1 - sinLatitude)) / (pi_4)) * 256;

        var pixelX = ((longitude + 180) / 360) * 256;



        var pixel = { x: pixelX, y: pixelY };



        return pixel;

    }



 //计算转换的矩阵

function drawingOnCanvas(canvasOverlay, params) {

        if (gl == null) return;



        gl.clear(gl.COLOR_BUFFER_BIT);

        

        pixelsToWebGLMatrix.set([2 / canvas.width, 0, 0, 0, 0, -2 / canvas.height, 0, 0, 0, 0, 0, 0, -1, 1, 0, 1]);

        gl.viewport(0, 0, canvas.width, canvas.height);



        var pointSize = Math.max(leafletMap.getZoom() - 4.0, 1.0);

        gl.vertexAttrib1f(gl.aPointSize, pointSize);



        // -- set base matrix to translate canvas pixel coordinates -> webgl coordinates

        mapMatrix.set(pixelsToWebGLMatrix);



        var bounds = leafletMap.getBounds();

        var topLeft = new L.LatLng(bounds.getNorth(), bounds.getWest());

        var offset = LatLongToPixelXY(topLeft.lat, topLeft.lng);



        // -- Scale to current zoom

        var scale = Math.pow(2, leafletMap.getZoom());

        scaleMatrix(mapMatrix, scale, scale);



        translateMatrix(mapMatrix, -offset.x, -offset.y);



        // -- attach matrix value to 'mapMatrix' uniform in shader

        gl.uniformMatrix4fv(u_matLoc, false, mapMatrix);

        gl.drawArrays(gl.POINTS, 0, numPoints);



    }

在这里插入图片描述

关注公众号,查看更多文章!
在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
leaflet是一种用于创建交互式地图的JavaScript库。它支持加载多种地理坐标系的数据,其中epsg:4326是最常用的经纬度坐标系。 在leaflet加载epsg:4326的数据非常简单。首先,我们需要在html文件中引入leaflet的库文件以及相关的样式表。然后,我们创建一个map容器,并指定其宽度和高度。接下来,通过JavaScript代码,我们可以实例化一个L.map对象,并将其绑定到刚刚创建的map容器上。 在加载epsg:4326的数据之前,我们需要创建一个用于显示地图的图层。leaflet提供了不同类型的图层,其中L.tileLayer是用于加载瓦片图层的。我们可以通过指定一个URL模板,将包含地图图像的瓦片加载到地图上。epsg:4326的瓦片图层可以通过以下方式加载: ``` L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: 'Map data © OpenStreetMap contributors', maxZoom: 18 }).addTo(map); ``` 在上述代码的URL模板中,`{s}`代表可用于加载瓦片的服务器,`{z}`代表缩放级别,`{x}`和`{y}`分别代表瓦片的行号和列号。这个URL模板是用于加载OpenStreetMap的epsg:4326瓦片图层的示例。 最后,我们可以在地图上添加其他要素,如标记、矢量图层等,以增强用户体验和功能。 总之,leaflet加载epsg:4326非常简单,我们只需要通过L.tileLayer方法加载相应的瓦片图层即可。这使得我们可以轻松地在leaflet中展示经纬度坐标系的地理数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值