Google地球插件API - 如何获取当前地图比例?

时间:2012-03-14 17:42:35

标签: javascript computational-geometry google-earth-plugin

我有一个托管Google地球插件实例的应用程序,我有兴趣获取地图的当前比例并在我的应用程序中使用它。

我知道我可以使用GEOptions并设置缩放图例可见性,但我想在我的应用程序中使用实际缩放值,但我找不到它的API。

有办法做到这一点吗?

如果没有,我如何使用当前视图计算当前比例?

2 个答案:

答案 0 :(得分:5)

我使用以下功能从Google地球插件API获取近似比例。这是根据相机从地面的高度计算出来的。地球的倾斜,平移等不会影响返回的值。这是一个简单的功能,如果您只需要了解相机和地面之间的实际地图比例的一般概念,那么效果很好。即使相机倾斜观察地平线,这仍然会使用计算,就好像相机正在向下看。

当相机倾斜时,没有可以计算的单个刻度,因为刻度在可见地图上的任何给定点处发生变化。距离中的两个点在屏幕上的每个像素的距离与相机附近的两个点之间的距离不同。尺度图例实际上也是近似值,因为距离仅在可见地图的特定部分上是准确的。

function getScale() {
    var camera = ge.getView().copyAsCamera(ge.ALTITUDE_RELATIVE_TO_GROUND),
        eyeAlt,
        scale;
    eyeAlt = camera.getAltitude();

    scale = Math.round(eyeAlt * 10.5);
    return scale;
}

答案 1 :(得分:3)

尺度图例本身非常模糊,因为Google地球是一个3D地球仪,而且透视显然不是保留距离(甚至距离之间的比率)的投影。当直视并且非常接近地球表面时,这不是一个问题,但是一旦视图倾斜,靠近相机的地面将具有与地平线上的地面非常不同的比例。

此时,询问屏幕上某个点的当前比例更有意义。没有直接的API,但您可以随时找到屏幕上任意两点的lat / lng坐标,然后找到它们之间的距离。

GEView.hitTest可能是最简单的方法。您可以指定命中测试应以像素为单位的位置,或者指定插件大小的一小部分,偏离其DOM容器的边缘。例如,如果你想要靠近视图中间的km /像素,你可以:取出插件的宽度和高度,将它们除以2,然后在每个方向上偏移10个像素,做最热门的查询,找到returned coordinates之间的距离,然后最后除以10.你实际上如何偏移这些像素再次达到你想要测量刻度的位置(并注意如果你的命中测试错过了地球,那你就是&#39 ; ll获取null返回值)。

警告:这是一段非常快速的代码(使用this thread中的距离计算)。请在使用之前彻底测试,但它应该是这样的:

function getSomethingResemblingScale() {
  var earthDiv = document.getElementById('map3d');
  var hw = earthDiv.offsetWidth / 2;
  var hh = earthDiv.offsetHeight / 2;
  var view = ge.getView();
  var hitTest1 = view.hitTest(hw - 5, ge.UNITS_PIXELS, hh, ge.UNITS_PIXELS, ge.HIT_TEST_TERRAIN);
  var hitTest2 = view.hitTest(hw + 5, ge.UNITS_PIXELS, hh, ge.UNITS_PIXELS, ge.HIT_TEST_TERRAIN);
  var dist = calcDistance(hitTest1.getLatitude(), hitTest1.getLongitude(), hitTest2.getLatitude(), hitTest2.getLongitude());
  console.log('scale: ' + (dist/10) + ' km/pixel');
}

function calcDistance(lat1, lon1, lat2, lon2) {
  var R = 6371; // Radius of the earth in km
  var dLat = (lat2-lat1) * (Math.PI / 180);
  var dLon = (lon2-lon1) * (Math.PI / 180);
  var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
          Math.cos(lat1*(Math.PI / 180)) * Math.cos(lat2*(Math.PI / 180)) * 
          Math.sin(dLon/2) * Math.sin(dLon/2); 
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
  var d = R * c;
  return d;
}