从地图点击事件中获取 LngLat 并将其绘制到 mapboxGL 的 canvas 图层上
Taking LngLat from Map click event and drawing it onto a canvas layer for mapboxGL
我正在使用 mapboxGL,但我无法弄清楚...有没有人幸运地从点击事件中获取 lng/lat,然后将其绘制在单独的 canvas 图层上.
示例如下:
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() 或其他东西...
代码太少,我无法理解创建 canvas 和图层的 objective,每次单击地图中的一个点只是为了创建一个圆圈。首先,Mapbox 第二次会报错,因为你总是为图层使用相同的名称。我要做的是在 HTML 中静态创建 canvas 就在地图
上方
<canvas id="canvasID" width="682" height="400" style="overflow:hidden">Canvas not supported</canvas>
<div id="map"></div>
然后创建地图并将 canvas 调整为地图的大小。
var map = new mapboxgl.Map({
container: 'map',
zoom: mapConfig.NYC.zoom,
minZoom: mapConfig.NYC.zoom,
center: mapConfig.NYC.center,
style: 'mapbox://styles/mapbox/streets-v11'
});
map.setMaxBounds([map.getBounds().getSouthWest().toArray(), map.getBounds().getNorthEast().toArray()]);
let width = map.getCanvas().clientWidth;
let height = map.getCanvas().clientHeight;
canvas.width = width;
canvas.height = height;
然后是点击事件前的层和源。
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,基本上使用鼠标指针参数,因为现在 canvas大小和坐标等于 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();
});
我创建了一个 fiddle 解决方案 how to add a custom canvas and draw circles on click
结果是这样的,每次点击都会在canvas层渲染一个新的圆圈。
注意:使用这种方法会有一些局限性,例如限制地图的边界和平移,当然在缩放时您需要重新计算所查看边界内的鼠标单击位置。
我正在使用 mapboxGL,但我无法弄清楚...有没有人幸运地从点击事件中获取 lng/lat,然后将其绘制在单独的 canvas 图层上.
示例如下:
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() 或其他东西...
代码太少,我无法理解创建 canvas 和图层的 objective,每次单击地图中的一个点只是为了创建一个圆圈。首先,Mapbox 第二次会报错,因为你总是为图层使用相同的名称。我要做的是在 HTML 中静态创建 canvas 就在地图
上方<canvas id="canvasID" width="682" height="400" style="overflow:hidden">Canvas not supported</canvas>
<div id="map"></div>
然后创建地图并将 canvas 调整为地图的大小。
var map = new mapboxgl.Map({
container: 'map',
zoom: mapConfig.NYC.zoom,
minZoom: mapConfig.NYC.zoom,
center: mapConfig.NYC.center,
style: 'mapbox://styles/mapbox/streets-v11'
});
map.setMaxBounds([map.getBounds().getSouthWest().toArray(), map.getBounds().getNorthEast().toArray()]);
let width = map.getCanvas().clientWidth;
let height = map.getCanvas().clientHeight;
canvas.width = width;
canvas.height = height;
然后是点击事件前的层和源。
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,基本上使用鼠标指针参数,因为现在 canvas大小和坐标等于 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();
});
我创建了一个 fiddle 解决方案 how to add a custom canvas and draw circles on click
结果是这样的,每次点击都会在canvas层渲染一个新的圆圈。
注意:使用这种方法会有一些局限性,例如限制地图的边界和平移,当然在缩放时您需要重新计算所查看边界内的鼠标单击位置。