基于已知的经纬度点,在图像上放置一个点的尝试失败了。

3

非常抱歉标题比较含糊,我真的无法想到更好的总结方法。欢迎提出建议。

我正在开发一个项目,这个项目并不需要谷歌地图,但是如果使用它会增加额外的开销。但是,我目前还没找到一种不使用谷歌地图的方法……

如果我在谷歌地图上放置了一个楼层平面图的图形叠加,则可以使用浏览器位置来近似用户的位置。对于这个非常大的场所来说,精度还有很大的提升空间。

现在我要做的是,在知道覆盖物的范围之后,将图像放到一个div中,然后根据用户的浏览器经纬度计算其在div中的位置。

通过使用具有水平和垂直上边缘的正方形图像(因为它们创建了我的区域),我能够接近实现该目标。但由于世界上没有任何东西是这样的,所以我需要一个不正方形的区域来看起来像是正方形。我遇到了数学上的难题。

这就是我要做的事情!

这里有一个测试我的概念的链接,但是没有考虑需要在地图上旋转的图像:http://www.freeptools.com/mapster/singlerun/maptest.php

就像我说的那样,我相信这是可以做到的,但我还没有找到正确的数学方法。这让我很疯狂。

这是执行此操作的代码。一个函数获取浏览器坐标并将它们发送到初始化函数。然后根据之前自己绘制的地图,我有了我要映射的图像的边界。我使用haversine公式尝试在用户位置处得到高度和宽度(因为地图曲线,其它任何位置都会不准确),然后从最左侧和最上方的点的距离中取出左端距离和上端距离,再将左/上距离除以宽度/高度,以得到他们离左侧/顶部的距离所占的百分比,以定位点的位置。这个想法,虽然我无法超级精确,但在这个例子中起作用,因为图像在地图上水平对齐。我的问题是如果该图像在地图上被旋转,我该如何计算这些距离?我无法找到那个数学方法。

function initialize(y3, x3) { //lat, lon

//var overlayBounds = new google.maps.LatLngBounds(new google.maps.LatLng(41.11246878918085, -90.5712890625), new google.maps.LatLng(47.68652571374621, -82.001953125));
var box = $("#map_canvas");

//image bounds
var x1 = -82.001953125;
var x2 = -90.5712890625;
var y1 = 41.11246878918085;
var y2 = 47.68652571374621;

var boxWidth = x2 - x1;
var boxHeight = y2 - y1;

//now we need to figure out where this rests, first we get the percentage
//var posLeft = haversine(y3, x1, y3, x3); //(x3 - x1);
var posLeft = (x3 - x1);
var posLeftPct = (posLeft/boxWidth)*100;

//var posTop = haversine(y2, x3, y3, x3); //(y2 - y3);
var posTop = (y2 - y3);
var posTopPct = (posTop/boxHeight)*100;

box.append('<img src="http://www.freeptools.com/mapster/icons/icon23.png" style="position:absolute; z-index:200; right:'+posLeftPct+'%; top:'+posTopPct+'%">');

}


你的代码是什么样子?(请在问题本身中发布一个最小、完整、可测试和易读的示例,而不仅仅是外部链接) - geocodezip
我刚刚添加了代码。我现在遇到的问题不是代码本身,而是它背后的概念。如我在编辑中所述,我目前拥有的代码仅在图像方向为上下时才能正常工作。如果图像被旋转,这个概念就完全失效了,这也是我真正苦恼的地方。 - John Sly
你从哪里获取图像(边界和旋转)的数据? - Dr.Molle
在这种情况下,我从谷歌地图开始,并自己定位,然后使用该边界数据进行此示例。至于我想尝试的下一个示例,我还没有找到那个边界数据,但我已经在地图上看了足够多的内容,知道我想处理的建筑物不是垂直的,而是旋转的,因此边界框将无法与我想要在独立div中显示的图像对齐。 - John Sly
我不确定这篇Stack Overflow帖子是否有所帮助,但球形墨卡托投影背后的数学(假设地球是一个球体),就像谷歌地图使用的那样,实际上非常简单。在大范围内,地图上直边的东西在现实世界中是弯曲的,但对于小范围来说,这不应该是个问题。如果您知道自己的方向轴,可以使用基本三角函数来旋转对象。 - John Powell
1个回答

5
假设该区域是一个平行四边形,您需要知道该区域的3个顶点以及您想要绘制针(例如楼层平面图像)的宽度/高度。
以下内容将使用http://www.movable-type.co.uk/scripts/latlong.html中的GeoLatLon库。
更好地理解该问题的图片:enter image description here 首先计算一些值:
  • 使用LatLon.bearingTo计算方位角(从nw到sw和从nw到ne)
  • 使用LatLon.distanceTo计算距离(从sw到nw和从ne到nw)
现在通过LatLon.intersection计算交点(在图像中标记为intersection-x和intersection-y)。 计算过程如下:
  • 交点x:
    LatLon.intersection(ne, bearingNWtoSW, target, bearingNWtoNE)
  • 交点y:
    LatLon.intersection(sw, bearingNWtoNE, target,bearingNWtoSW)

现在计算边界北到目标和边界西到目标的百分比值:

  • 边界北到目标:
    ((distanceNWtoNE-(target.distanceTo(intersection-x)))*100)/distanceNWtoNE
  • 边界西到目标:
    ((distanceNWtoSW-(target.distanceTo(intersection-y)))*100)/distanceNWtoSW

最后根据给定平面图的宽度/高度和先前计算的结果计算坐标

x=((width*distanceBorderNorthToTargetInPercent)/100);
y=((height*distanceBorderWestToTargetInPercent)/100);

一种方法(扩展了提到的LatLon库),可以执行所有这些计算:
/**
  *@param w int width of the drawing
  *@param h int height of the drawing
  *@param sw object LatLon of southwest of the drawing     
  *@param nw object LatLon of northwest of the drawing     
  *@param ne object LatLon of northeast of the drawing
  *@return mixed object with x/y-coordinates or null when LatLon is outside of the area        
  **/  
LatLon.prototype.translate = function(w,h,sw,nw,ne) {
    var x = {distance:nw.distanceTo(ne),bearing:nw.bearingTo(ne)},
        y = {distance:nw.distanceTo(sw),bearing:nw.bearingTo(sw)},
        intersectionY = LatLon.intersection(sw, x.bearing, this, y.bearing),
        intersectionX = LatLon.intersection(ne, y.bearing, this, x.bearing),
        distanceX,distanceY; 

    if(intersectionX && intersectionY){
       distanceX=((x.distance-(this.distanceTo(intersectionX)))*100)/x.distance,
       distanceY=((y.distance-(this.distanceTo(intersectionY)))*100)/y.distance;
       return {x:((w*distanceX)/100),y:((h*distanceY)/100)};
    }
    return null;
};

演示:http://jsfiddle.net/doktormolle/nsbqpcvg/embedded/result/
在谷歌地图上悬停高亮显示的楼层平面图,以查看计算结果(谷歌地图API仅用于演示,计算将不使用Maps-API)


看起来在我的测试区域内工作了。哈哈,现在看看我是否能够获得足够准确的GPS信号以便有所用!谢谢! - John Sly

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接