高德地图CanvasLayer:使用canvas实现层叠圆角多边形热点区域效果

3 篇文章 0 订阅

需求描述:

使用高德地图,实现类似下图中多个圆角多边形热点区域叠加的效果
高德地图多层圆角多边形效果

代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>ImageLayer</title>
    <meta id="viewport" name="viewport" content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0"/>
    <style>
        html,
        body,
        #container {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
        }
    </style>
</head>
<body>
<div id="container"></div>
<script src="//webapi.amap.com/maps?v=2.0&key=您申请的key值"></script>
<script>
    var map = new AMap.Map('container', {
        viewMode:"2D",
        zoom: 14,
      mapStyle: "amap://styles/darkblue",
        center: [116.335183, 39.941735]
    });

    // map.setBounds([116.316279,39.92724,116.354087,39.956227]);

    /*
     * 添加Canvas图层
     */
    var canvas = document.createElement('canvas');
    canvas.width = 871;
    canvas.height = 876;
    var ctx = canvas.getContext("2d");
  
  function draw() {
    const p = [
      [15, 20],
      [20, 200],
      [200, 300],
      [300, 100],
      [200, 20],
    ];
    const p1 = [
      [300,50],
      [400,50],
      [350,150]
    ]
    const test = [
    	[353,236],
      	[676,332],
      	[567,641],
      	[342,758],
      	[159,553],
      	[356,437]
    ]
     // drawRect(p, 30, ctx, 'rgb(0, 0, 0)', 0.6);
    // drawRect(p1, 10, ctx, 'rgb(20, 230, 240)', 0.8);
    drawRect(test, 50, ctx, '#FFB503', 0.3);
  }

  function drawRect(p, radius, ctx, color, alpha) {
    ctx.beginPath();
    const startPoint = [
      (p[0][0] + p[p.length - 1][0]) / 2,
      (p[0][1] + p[p.length - 1][1]) / 2,
    ];
    ctx.moveTo(...startPoint);
    for (let i = 0; i < p.length; i++) {
      if (i === p.length - 1) {
        ctx.arcTo(...p[p.length - 1], ...p[0], radius);
      } else {
        ctx.arcTo(...p[i], ...p[i + 1], radius);
      }
    }
    
    ctx.globalAlpha=alpha;
    ctx.closePath();
    ctx.strokeStyle=color;
    ctx.fillStyle=color;
    ctx.fill();
    ctx.stroke();
  }
  
    var CanvasLayer = new AMap.CanvasLayer({
        canvas: canvas,
        bounds: new AMap.Bounds(
            [116.316279,39.92724],
            [116.354087,39.956227]
        ),
        zooms: [3, 18],
    });
  
   var CanvasLayer1 = new AMap.CanvasLayer({
        canvas: canvas,
        bounds: new AMap.Bounds(
            [116.309255,39.961797],
            [116.360878,39.922309]
        ),
        zooms: [3, 18],
    });
      
   var CanvasLayer2 = new AMap.CanvasLayer({
        canvas: canvas,
        bounds: new AMap.Bounds(
            [116.299684,39.968522],
            [116.370249,39.914605]
        ),
        zooms: [3, 18],
    });

    map.addLayer(CanvasLayer);
    map.addLayer(CanvasLayer1);
      map.addLayer(CanvasLayer2);
      draw();

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

到这里运行看效果:

高德地图Canvas图层示例

稍微先补充两点:

  1. 经实测,在高德地图中添加CanvasLayer后,控制台会不停出现“[Violation] ‘requestAnimationFrame’ handler took XXms”的警告,直到地图崩溃,页面黑屏。。。(因此还在优化ing)
  2. 将任意一组经纬度坐标在地图上显示为层叠圆角多边形热点区域(最好是凸多边形)的大致思路:
    ①确定CanvasLayer的边界(bounds):求出能完全容纳这组经纬度坐标的矩形区域的左上角(lng_min, lat_max)、右下角(lng_max, lat_min)两点对应的经纬度;
    ②确定坐标原点和画布的尺寸:将左上角、右下角的经纬度坐标转换为容器像素坐标,其中左上角相当于坐标原点,右下角与左上角的像素差值即为画布的宽和高;
    ③计算给定经纬度坐标对应的像素坐标:将这组经纬度坐标中每一个点都转换为容器像素坐标,其与左上角(坐标原点)的差值即为这个点(在坐标系中)的像素坐标;
    ④创建canvas节点,使用第③步获得的像素坐标绘制圆角多边形;
    (到此已经实现了一层圆角多边形热点区域)
    ⑤计算放大一定比例后的CanvasLayer的边界:将第②步获得的左上角容器像素坐标减少画布宽高的一定比例、右上角容器像素坐标增加画布宽高的一定比例(缩小CanvasLayer时,左上角增加、右下角减少);将新的左上角、右下角容器像素坐标转换为经纬度;
    ⑥创建多个CanvasLayer,共用第④步的canvas节点,分别设置初始bounds和第⑤步获得的放大/缩小后的边界,添加到地图中即可实现层叠圆角多边形热点区域效果

优化探索-1:使用覆盖物(Marker),将content设为canvas

效果:可以将Marker的content设为canvas绘制多边形,但Marker添加的图像不会随地图的缩放产生变化(由此可以理解为什么CanvasLayer一直报动画相关的警告,因为CanvasLayer绘制的区域会随缩放地图的操作而缩放,即:产生动画);否决
注:禁用地图缩放、拖拽无法消除CanvasLayer的动画相关警告
另: CanvasLayer不支持事件,若需要实现热点区域的交互,可在上方覆盖一个透明多边形(高德地图Polygon文档

实现效果下位替代:

因目前未能找到CanvasLayer导致地图崩溃问题的解决方法,为了尽可能地实现地图上层叠多边形热点区域的效果,可以使用Polygon展示多边形区域,通过给多边形设置较宽的描边、适当调整半透明区域和半透明描边的颜色,能在合适的缩放下呈现理想的层叠多边形热点区域效果……(不足之处:①多边形外廓不圆润…②地图缩放过小或过大时显示效果可能不理想…)

** 先码一哈,有空再扩展~需要实现效果的小伙伴可以参考代码自行领悟一波哈;欢迎补充优化!**

参考文档

[1] canvas绘制圆角多边形
[2] canvas绘制多边形并填充
[3] 高德地图Canvas图层示例
[4] 高德地图经纬度与容器像素坐标互转示例
[5] 高德地图CanvasLayer文档
[6] 高德地图Polygon文档

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值