【问题标题】:openlayers 3: how to draw sth using canvas.getContext('2d') on top of the mapopenlayers 3:如何在地图上使用 canvas.getContext('2d') 进行绘制
【发布时间】:2016-11-28 08:01:52
【问题描述】:

我想使用 canvas.getContext('2d') 在地图中绘制一些几何图形。但是,我绘制的几何图形只显示了一段时间。当我平移/缩放地图时它消失了。如何通过这种方式绘制永久几何图形?

下面是我的代码:

<html>
<head>
    <title></title>
    <!-- styles -->
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.19.1/ol.css"/>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.19.1/ol.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script type="text/javascript">
        var map;
        function init()
        {
            var raster = new ol.layer.Tile({
                            title:'basemap',
                 source: new ol.source.Stamen({
                   layer: 'toner'
                 })
               });

            map = new ol.Map( {layers:[raster],target:'map',  view: new ol.View({
      center: [113,25],
                projection: 'EPSG:4326',
      zoom: 6
    })} );

        };


        function drawSth(){
            var canvas = $("canvas")[0];
            var context = canvas.getContext('2d');
            // begin custom shape
                  context.beginPath();
                  context.moveTo(170, 80);
                  context.bezierCurveTo(130, 100, 130, 150, 230, 150);
                  context.bezierCurveTo(250, 180, 320, 180, 340, 150);
                  context.bezierCurveTo(420, 150, 420, 120, 390, 100);
                  context.bezierCurveTo(430, 40, 370, 30, 340, 50);
                  context.bezierCurveTo(320, 5, 250, 20, 250, 50);
                  context.bezierCurveTo(200, 5, 150, 20, 170, 80);

                  // complete custom shape
                  context.closePath();
                  context.lineWidth = 5;
                  context.fillStyle = '#8ED6FF';
                  context.fill();
                  context.strokeStyle = 'blue';
                  context.stroke();
        }

    </script>

</head>

<body onload="init()">

    <div id="map"></div>

    <div id="controls">         
        <button onclick="drawSth();">just draw sth</button></br></br>
    </div>

</body>

【问题讨论】:

  • 事实证明,将图形锚定到地图是如此困难。我写了一个函数“canvasOverlay”,它会监听地图的指针拖动和移动事件。虽然成功了,但效果不是那么好。

标签: html canvas openlayers-3


【解决方案1】:

您可以使用 ol.source.ImageCanvas 及其 canvasFunction 来做到这一点。

jsFiddle:https://jsfiddle.net/45oxL7rf/

var map = new ol.Map({
  layers: [
    new ol.layer.Tile({
      title: 'basemap',
      source: new ol.source.Stamen({ layer: 'toner' })
    }),
    new ol.layer.Image({
      source: new ol.source.ImageCanvas({
        canvasFunction: function (extent, resolution, pixelRatio, size, projection) {
          var canvas = document.createElement('canvas');
          canvas.width = size[0];
          canvas.height = size[1];

          var context = canvas.getContext('2d');
          // begin custom shape
          context.beginPath();
          context.moveTo(170, 80);
          context.bezierCurveTo(130, 100, 130, 150, 230, 150);
          context.bezierCurveTo(250, 180, 320, 180, 340, 150);
          context.bezierCurveTo(420, 150, 420, 120, 390, 100);
          context.bezierCurveTo(430, 40, 370, 30, 340, 50);
          context.bezierCurveTo(320, 5, 250, 20, 250, 50);
          context.bezierCurveTo(200, 5, 150, 20, 170, 80);

          // complete custom shape
          context.closePath();
          context.lineWidth = 5;
          context.fillStyle = '#8ED6FF';
          context.fill();
          context.strokeStyle = 'blue';
          context.stroke();

          return canvas;
        },
        projection: 'EPSG:3857'
      })
    })
  ],
  target: 'map',
  view: new ol.View({
    center: ol.proj.fromLonLat([-97, 38]),
    zoom: 4
  })
});

请注意,我只是复制/粘贴了您的画布绘图并保持原样。当您平移地图时,您的图形不会像您预期的那样锚定到地图上,因为您绘制的是静态像素坐标。在您的真实应用中,您可能会根据传递给您的 canvasFunction 的参数计算正确的像素坐标。

【讨论】:

  • 杰夫,非常感谢 canvasFunction 线索。我可以用 openlayers 例子来处理剩下的事情。
  • 很高兴为您提供帮助!如果您认为这是一个很好的答案,您能否将其标记为“已回答”?谢谢你,祝你好运!
  • 抱歉回复晚了。我最近忙于另一个项目。你的回复当然回答了我的问题。谢谢你,享受!
猜你喜欢
  • 2016-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多