【问题标题】:Drawing on canvas in loop points are off在画布上绘制循环点已关闭
【发布时间】:2014-05-23 04:25:11
【问题描述】:

我试图在画布上绘图,但我绘制的点最终位于错误的位置。我知道这与循环有关(很可能是变量范围和事件序列),因为当我一次绘制每个数据点时,它们会出现在正确的位置。一旦我遍历一个以上元素的数组,这些点就不会出现在正确的位置(我在谷歌地图上绘制它们 - 是的,我已经使用了他们的 javascript api,但我会做比他们的api更自定义的东西。但是使用他们的api来映射点是我如何验证我的点在一次完成一个时绘制在正确的位置,但是当我循环遍历数组时最终出现在错误的位置) .

map.setCenter(new google.maps.LatLng(data[0].location.lat, data[0].location.long));
map.setZoom(15);
var bounds = map.getBounds();
var topLeft = bounds.getNorthEast();
var bottomRight = bounds.getSouthWest();
var left = topLeft.lat();
var top = topLeft.lng();
var right = bottomRight.lat();
var bottom = bottomRight.lng();
var height = Math.abs(top - bottom);
var width = Math.abs(left - right);


canvas = $('#mapCanvas').get(0);
var canvasHeight = canvas.height;
var canvasWidth = canvas.width;

context = canvas.getContext('2d');

var radius = 10;

var fromTop;
var fromLeft;
var ratioTop;
var ratioLeft;
var centerX;
var centerY;

_.each(data, function(point) {
  var latLng = new google.maps.LatLng(point.location.lat, point.location.long);
  if (bounds.contains(latLng)) { // this point lies in the map, plot it on the canvas!
    // calculate distance from top left
    fromTop = Math.abs(top - point.location.long);
    fromLeft = Math.abs(left - point.location.lat);
    ratioTop = fromTop / height;
    ratioLeft = fromLeft / width;

    centerX = Math.floor(ratioLeft * canvasWidth);
    centerY = Math.floor(ratioTop * canvasHeight);

    context.beginPath();
    context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
    context.fillStyle = 'green';
    context.fill();
    context.closePath();
  }
});

注意 - 数据数组包含这样的对象:

{ _id: 5362a54a038a09d66ac9b36d,
location: { lat: 46.368619, long: -109.027793 } }

这里是问题的一个例子:画布上画了绿点,用google的api画了黄色和紫色的点。请注意,绘制的第一个点与正确的位置重叠。此外,如前所述,如果我只是单独绘制第三个点,或者单独绘制其中任何一个点,那么它们会出现在正确的位置。

我还整理了一个jsFiddle

【问题讨论】:

  • (from/ratio)+(Left/Top) 和 centerX/Y 是函数的变量,不要在外面定义。这不是根本原因,但它会更干净。您能否也显示工作代码,并描述或加入“不在正确位置”的图片?
  • 是的 - 完成了。我最初在里面定义了这些,我将其分解以确保这不是问题。

标签: javascript google-maps canvas html5-canvas


【解决方案1】:

在阅读此答案之前,请坐下并保证不要将头撞到墙上! :-)

您的代码非常好,您只是认为纬度与“x”坐标匹配,经度与“y”坐标匹配。
但实际上反过来是正确的:如果有疑问,请再次查看定义。

如果您查看“错误”结果,它只是旋转和缩放的正确结果。

因此,只需 1) 将经度与纬度交换,2) 取经度的对称,您就可以与谷歌的结果完美匹配:

http://jsfiddle.net/gamealchemist/68Gy4/2/

// during the init : 
var bounds = map.getBounds();
var topLeft = bounds.getNorthEast();
var bottomRight = bounds.getSouthWest();
var left = topLeft.lng();
var top = topLeft.lat();
var right = bottomRight.lng();
var bottom = bottomRight.lat();
var height = Math.abs(top - bottom);
var width = Math.abs(left - right);

// and in your each loop : 
var fromTop = Math.abs(top - point.location.lat);
var fromLeft =  Math.abs(left - point.location.long);
var ratioTop = fromTop / height;
var ratioLeft = fromLeft / width;

var centerX = canvasWidth - Math.floor(ratioLeft * canvasWidth);
var centerY = Math.floor(ratioTop * canvasHeight);

完美的结果:

【讨论】:

  • *哦!我不敢相信!我想我现在有点困惑 - 例如, fromTop = Math.abs(left - point.location.lat); ——感觉不对。那应该从左调用吗?你把它除以宽度来确定从顶部开始的比例?请解释
  • 好的,好的 :-) 我花了(终于没那么久)时间来把名字弄好,看看我的编辑。
猜你喜欢
  • 2017-07-27
  • 1970-01-01
  • 2018-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-24
  • 1970-01-01
相关资源
最近更新 更多