美文网首页webGIS
MapTalks地图滤镜使用

MapTalks地图滤镜使用

作者: polong | 来源:发表于2023-03-04 21:57 被阅读0次

    背景

        最近看到ArcGIS Maps SDK for JavaScript官网有个聚焦效果的例子,于是想在MapTalks上也试试。

    屏幕截图 2023-03-05 102128.png

    原理

        滤镜的原理主要是用的canvas的cssfilter属性,让它整体有模糊或者高亮的功能。另外高亮区域使用的是canvas的裁剪。

    方案一

        使用maptalks原生api,对底图进行模糊和蒙版操作,由于这里要两种滤镜,所以需要有两个底图方便处理,一个进行模糊处理,一个设置蒙版。

    设置模糊滤镜效果

    var map = new maptalks.Map('map', {
      center:     [109.191369116306319, 19.736612649767874],
      zoom:  16,
      pitch : 0,
      dragPitch:false,
      baseLayer :  new maptalks.TileLayer('tile1', {
        urlTemplate: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
        cssFilter : 'blur(10px)  grayscale(1.2)',
      })
    });
    

        设置模蒙版和高亮滤镜效果

    var boundary = [ [ [ 109.191369116306319, 19.736612649767874 ], [ 109.191347658634214, 19.736794423924326 ], [ 109.19259220361711, 19.736531861187487 ], [ 109.195274412632031, 19.735562395035053 ], [ 109.209500849247036, 19.730068642352247 ], [ 109.209565222263379, 19.72653395894347 ], [ 109.209264814853711, 19.726453165265738 ], [ 109.209028780460415, 19.726069394738637 ], [ 109.203707277774839, 19.726089593210407 ], [ 109.203664362430601, 19.726594554174969 ], [ 109.202827513217969, 19.727099513543749 ], [ 109.201840460300488, 19.728028634612741 ], [ 109.2000594735146, 19.728715372799819 ], [ 109.195961058139844, 19.730270621899336 ], [ 109.192656576633482, 19.731401702643819 ], [ 109.192999899387388, 19.731745064856661 ], [ 109.192849695682554, 19.732048030902128 ], [ 109.192163050174742, 19.73196724001286 ], [ 109.191154539585142, 19.732674158908559 ], [ 109.19169098138812, 19.735461408639065 ], [ 109.191369116306319, 19.736612649767874 ] ] ]
    var mask = new maptalks.Polygon(boundary, {
      'symbol' : [
        {
    
          'polygonOpacity': 1,
          'polygonFill': 'rgb(0,0,0)',
          'lineColor': 'rgb(0,0,0)',
          'lineWidth': 1,
        }
      ]
    });
    
    var maskedLayer = new maptalks.TileLayer('tile2', {
      zIndex:100,
      urlTemplate: 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
      cssFilter : 'drop-shadow(0px 0px 20px  black) brightness(1.0)',
    })
      .setMask(mask) // set boundary as the mask to the tilelayer
      .addTo(map);
    

        由于底图的drop-shadow滤镜效果不太明显,需要绘制一个vectorlayer

    var outline = new maptalks.Polygon(boundary, {
      'symbol' : [
        {
          'polygonOpacity': 1,
          'polygonFill': 'rgb(0,0,0)',
          'lineColor': 'rgb(0,0,0)',
          'lineWidth': 1,
        }
      ]
    });
    new maptalks.VectorLayer('v', [outline],{
      enableSimplify:false,
      cssFilter : 'drop-shadow(-6px -6px 16px  black)',
      }
    ).addTo(map);
    

        优点:二三维均可使用,图形绘制简单。缺点:一个图层使用cssfilter影响过大

    方案二

        使用底图监听绘制事件,绘制完成以后,通过canvas上下文获取到图片,对图片进行上述模糊蒙版高亮等处理。

     function onRenderEnd(e) {
       console.time('draw')
     
       // map's canvas context
       var ctx = e.context;
       ctx.filter= 'drop-shadow(-6px -6px 16px black)';
       var c=ctx.canvas;
       var imgData=ctx.getImageData(0,0,c.width,c.height);
       ctx.drawImage(createBg(imgData, c.width,c.height,'blur(10px) '),0,0);
       ctx.drawImage(createMagCircle(imgData,c.width,c.height,boundary), 0, 0);
       console.timeEnd('draw')
     }
    
     map.on('renderend', onRenderEnd);
    

        新建canvas,转换坐标后绘制图形,接着绘制当前底图图片,返回canvas元素

    function createMagCircle(imageData,width,height,coords) {
      var magImg = document.createElement('canvas');
      var magCircle = document.createElement('canvas');
      //console.log(sw,sh)
      magImg.width = magCircle.width =width
      magImg.height =  magCircle.height = height
      magImg.getContext('2d').putImageData(imageData, 0, 0);
      var ctx = magCircle.getContext('2d');
      ctx.beginPath();
      for(let i=0;i<coords[0].length;i++){
        var center = new maptalks.Coordinate(coords[0][i]);
        let  containerPoint = map.coordinateToContainerPoint(center).round();
        let cx = containerPoint.x
        let cy = containerPoint.y
        if(i==0){
          ctx.moveTo(cx,cy);
        }else{
          ctx.lineTo(cx,cy);
        }
      }
      ctx.stroke();
      ctx.clip();
      ctx.drawImage(magImg, 0, 0);
      return magCircle;
    }
    

        新建canvas元素,绘制绘制当前底图图片,进行模糊滤镜处理

    function createBg(imageData, width,height,cssfilter) {
      var magImg = document.createElement('canvas');
      var magCircle = document.createElement('canvas');
    
      magImg.width =width
        magImg.height = height
          magCircle.width = width
            magCircle.height = height;
      magImg.getContext('2d').putImageData(imageData, 0, 0);
    
      var ctx = magCircle.getContext('2d');
      ctx.filter= cssfilter
      ctx.drawImage(magImg, 0, 0);
    
      return magCircle;
    }
    

        优点:只要一个地图并且不用再绘制vectorlayer。缺点:只能二维使用,三维没有处理所以不可用,图形绘制处理比较复杂需要知道一些canvas知识

    效果

    屏幕截图 2023-03-05 101534.png 屏幕截图 2023-03-05 101741.png

    参考资料:

    ArcGIS Maps SDK for JavaScript滤镜例子

    css滤镜使用文档

    滤镜使用文档

    地图放大镜

    相关文章

      网友评论

        本文标题:MapTalks地图滤镜使用

        本文链接:https://www.haomeiwen.com/subject/fhayldtx.html