Javascript 从Map click事件获取LngLat并将其绘制到mapboxGL的画布层上

Javascript 从Map click事件获取LngLat并将其绘制到mapboxGL的画布层上,javascript,canvas,mapbox,mapbox-gl,Javascript,Canvas,Mapbox,Mapbox Gl,我用的是mapboxGL,我搞不懂这个。。。有没有人从点击事件中获取lng/lat,然后在单独的画布层上绘制 示例如下: map.on('click', (e) => { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); ctx.beginPath(); ctx.arc(e.lngLat.lat, e.lngLat.lng, 10, 0, 2 * Ma

我用的是mapboxGL,我搞不懂这个。。。有没有人从点击事件中获取lng/lat,然后在单独的画布层上绘制

示例如下:

map.on('click', (e) => {
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');

  ctx.beginPath();
  ctx.arc(e.lngLat.lat, e.lngLat.lng, 10, 0, 2 * Math.PI, false);
  ctx.fillStyle = 'green';
  ctx.fill();

  map.addLayer({
    id: 'canvas-layer',
    type: 'raster',
    source: {
      type: 'canvas',
      canvas: canvas,
      coordinates: [
        map.getBounds().getNorthWest().toArray(),
        map.getBounds().getNorthEast().toArray(),
        map.getBounds().getSouthEast().toArray(),
        map.getBounds().getSouthWest().toArray(),
      ],
    },
  });
});

canvas源的坐标看起来是正确的,但实际圆的lng/lat值相差很远,我不知道应该使用x/y坐标还是使用map.project()或者什么…

代码太少,我无法理解每次单击地图上的某个点创建一个圆时创建画布和图层的目的。首先,Mapbox将在第二次出现错误,因为您始终对图层使用相同的名称。我要做的是在地图上用HTML静态创建画布

<canvas id="canvasID" width="682" height="400" style="overflow:hidden">Canvas not supported</canvas>
<div id="map"></div>
然后是单击事件之前的图层和源

map.on('load', function () {
    map.addSource('canvas-source', {
        type: 'canvas',
        canvas: 'canvasID',
        coordinates: [
            map.getBounds().getNorthWest().toArray(),
            map.getBounds().getNorthEast().toArray(),
            map.getBounds().getSouthEast().toArray(),
            map.getBounds().getSouthWest().toArray(),
        ],
        animate: true
    });

    map.addLayer({
        id: 'canvas-layer',
        type: 'raster',
        source: 'canvas-source'
    });
...
});
然后,我将在加载时在地图中添加事件,只是为了绘制一个圆,而不是使用e.lngLat,基本上使用鼠标指针args,因为现在画布大小和坐标等于mapbox初始大小和缩放视图

map.on('click', (e) => {
    color = "#ff0000";
    ctx.beginPath();
    ctx.arc(e.point.x, e.point.y, radius, 0, Math.PI * 2, false);
    ctx.strokeStyle = "#ff0000";
    ctx.stroke();
});
我创造了一个解决方案

结果是这样的,每次你点击一个新的圆圈,它就会在画布层中被渲染。

注意:这种方法会有一些限制,例如限制地图的边界和平移,当然,在缩放时,您需要在查看的边界内重新计算鼠标单击位置

map.on('click', (e) => {
    color = "#ff0000";
    ctx.beginPath();
    ctx.arc(e.point.x, e.point.y, radius, 0, Math.PI * 2, false);
    ctx.strokeStyle = "#ff0000";
    ctx.stroke();
});