【Openlayers9】Openlayers图层探查

学习郭明强关于Openlayers的书,第二版,尝试里面的示例图层探查,就是裁剪部分上层图层,让下面的图层可见。我用的是目前最新的Openlayers9,按照书上的代码敲好之后发现并不能按照想要的进行显示,但同时控制台不报错!

好像书上使用的是Openlayers 5,于是下载了5对应的js和css,发现可以正常显示。如图:

然后我就在找Openlayers 9实现不了的原因。

以下来自ol 9的API

书上的代码关于图层裁剪的地方是这样写的:

    layerbing.on('precompose',function (event) {
        var ctx =event.context;
        var pixelratio=event.frameState.pixelRatio;
        ctx.save();
        ctx.beginPath();
        if (mousePosition){
            ctx.arc(mousePosition[0]*pixelratio, mousePosition[1]*pixelratio,
                radius*pixelratio,0,2*Math.PI);
            ctx.lineWidth=5*pixelratio;
            ctx.strokeStyle='#000080';
            ctx.stroke();
        }
        ctx.clip();
    });
    layerbing.on('postcompose',function(event){
        var ctx=event.context;
        ctx.restore();
    });

上面ol 9的API说 postcompose是“Only WebGL layers currently dispatch this event.”,虽然不是很懂,但似乎这里不是WebGL。事实上,我也不明白这里为什么使用pre/post-compose,compose的直译是‘组成’。我猜测是之前的版本并不严格区分?

以下是两者的区别(来自chat gpt):

WebGL(Web Graphics Library)和 Canvas 是用于在 Web 上进行图形渲染的两种不同技术。它们都可以用于在浏览器中创建交互式的图形和动画,但它们之间有一些重要的区别:

Canvas:

  • 2D 绘图:Canvas 元素是 HTML5 中的一个标准元素,用于在网页上绘制 2D 图形。
  • API:Canvas 使用 Canvas 2D Context API 来进行绘图操作,提供了诸如绘制路径、文本、图像等功能。
  • 灵活性:Canvas 适用于简单的 2D 图形绘制,如图表、游戏等,但对于复杂的图形和动画可能会有限制。
  • 性能:Canvas 的性能较好,适合处理大量的静态图形和简单动画。

WebGL:

  • 3D 绘图:WebGL 是基于 OpenGL ES 的 JavaScript API,用于在网页上进行高性能的 3D 图形渲染。
  • API:WebGL 提供了底层的 3D 图形渲染功能,开发者可以直接操作 GPU 进行图形计算。
  • 复杂性:WebGL 可以实现复杂的 3D 场景、动画和效果,适合游戏开发、虚拟现实(VR)、数据可视化等领域。
  • 性能:WebGL 的性能非常出色,能够利用 GPU 进行硬件加速,处理复杂的图形和动画效果。

所以解决很简单,把‘postcompose’改为‘postrender’,把‘precompose’改为‘prerender’就能在ol下使用了。

最后附上完整代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>图层探查</title>
<!--    <link rel="stylesheet" href="ol.css">-->
<!--    <script src="ol.js"></script>-->
<!--    这里使用的是Openlayers 9 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v9.0.0/ol.css">
    <script src="https://cdn.jsdelivr.net/npm/ol@v9.0.0/dist/ol.js"></script>
    <style>
        #map{
            width: auto;
            height: 700px;
        }
    </style>

    <script>

    </script>
</head>
<body>
<div id="map"></div>
<script>
    const layerbing=new ol.layer.Tile({
        source: new ol.source.BingMaps({
            key:'你自己的key',
            imagerySet: 'Aerial'
        }) });
    const layerosm=new ol.layer.Tile({
        source: new ol.source.OSM()
    });
    const map8=new ol.Map({
        target: 'map',
        layers:[layerosm,layerbing],
        view: new ol.View({
            center: ol.proj.fromLonLat([-109,46.5]),
            zoom: 6
        })
    });
    // 探查半径
    var radius=75;
    document.addEventListener('keydown',function (event) {
        //通过键盘调节探查的范围,但好像不管用??
        if (event.key==38){
            radius=Math.min(radius+5,150);
            event.preventDefault();
        }else if(event.key==40){
            radius=Math.max(radius-5,25);
            map8.render();
            event.preventDefault();
        }
    });

    var mousePosition=null;
    document.addEventListener('mousemove',function (event) {
        mousePosition=map8.getEventPixel(event);

        map8.render();
    });
    document.addEventListener('mouseout',function () {
        mousePosition=null;
        map8.render();
    })

    //    在渲染之前进行裁剪
//修改的地方在这里
    layerbing.on('prerender',function (event) {
        var ctx =event.context;
        var pixelratio=event.frameState.pixelRatio;
        ctx.save();
        ctx.beginPath();
        if (mousePosition){
            ctx.arc(mousePosition[0]*pixelratio, mousePosition[1]*pixelratio,
                radius*pixelratio,0,2*Math.PI);
            ctx.lineWidth=5*pixelratio;
            ctx.strokeStyle='#000080';
            ctx.stroke();
        }
        ctx.clip();
    });
    layerbing.on('postrender',function(event){
        var ctx=event.context;
        ctx.restore();
    });


</script>
</body>
</html>

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值