首页 > 解决方案 > 在 d3 画布地图上绘制弧线的问题

问题描述

假设我们有一些基本设置:

const canvas = document.getElementById("mycanvas");
const projection = d3.geoEquirectangular()
      .fitSize([canvasWidth, canvasWidth/2], {type: 'Sphere'})
      .precision(0.1);
context = canvas.getContext("2d");
const path = d3.geoPath()
      .projection(projection)
      .context(context);
context.drawImage(someImage, 0, 0, canvasWidth, canvasWidth/2)

然后我们有一个坐标对:

longitude = 34.9213213
latitude = -23.8229938

现在,我想根据这个坐标对绘制一个 arc() :

context.beginPath();
context.arc(longitude, latitude, 30, 0, 2*Math.PI);
context.strokeStyle = "green"
context.stroke();
context.closePath() 

在这种情况下,我希望 arc() 放置在精确的地理坐标中,但似乎 arc 不了解经度和纬度,因此它将 X 和 Y 值作为水平和垂直位置。
我怎样才能解决这个问题?

标签: javascripthtmld3.jscanvas

解决方案


投影采用纬度经度对并将其从以度为单位的 3D 坐标空间转换为以像素为单位的 2D 坐标空间。

你有一个投影,我假设你用它来绘制背景特征d3.geoPath()。通过以这种方式使用路径,您可以获取背景要素的纬度/经度对并将它们转换为像素。但是您在绘制弧线时并没有使用它,而是将纬度/经度对视为像素坐标。

context.arc()将提供的 x 和 y 视为像素值;它与选定的d3.geoProjection或没有任何联系d3.geoPath

如果context.arc()确实进行了地理投影,您仍然必须指定投影,以便context.arc()使用与相同的投影d3.geoPath()- 否则您的要素将无法正确重叠。

相反,投影您的纬度经度点以获取其位置(以像素为单位),并将其传递给context.arc()

var point = projection([longitude,latitude]); // project a latitude longitude pair to get [x,y] in pixels
context.arc(point[0], point[1], 30, 0, 2*Math.PI);

推荐阅读