计算距离,包括KmlLinestring的高程/地形数据

时间:2012-12-20 14:50:24

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

Google地球桌面应用程序会显示一行的map lengthground length

在Google地球插件中,我想做类似的事情,即我希望确定考虑地形的曲面细分ground length的{​​{1}}。

我可以这样做,如果是,怎么做?

1 个答案:

答案 0 :(得分:5)

如果使用earth-api-utility-library,您肯定可以轻松获得长度。使用它你可以做到。

var length = (new geo.Path(linestring)).distance(); 

当然,此方法不考虑地形 - 但在尝试使用高程渐变计算距离之前,您应该注意一些警告。

首先,在大多数情况下,地形距离和直接距离之间的任何差异都是最小的。实际上,许多高质量的GPS接收器在计算距离时根本不会考虑任何高度变化。

其次地面高度是最不可靠的碎片数据之一。使用基于高程的梯度来确定距离通常会产生更大的距离测量误差,而不是使用简单的“乌鸦飞行”测量。

考虑到这一点,如果你仍然想要这样做,那么一种方式就像下面那样。

  1. 在某些点(例如每隔10米)对线串进行采样。
  2. 获取每个点的地面高度。
  3. 将每个点转换为笛卡尔坐标
  4. 按顺序计算每个笛卡尔点之间的角距离。
  5. 您可以通过两种方式提高这种方法的精确度,方法是提高采样率(比如每米)或对结果应用平滑程序。

    对于更粗糙的版本,您可以循环遍历KmlLinestring本身的坐标,而不是在某个设定距离重新采样。您可以使用坐标的纬度,经度来获得每个点的地面高度。然后你将根据这个数据(纬度,经度,高度=> X,Y,Z)构建一个笛卡尔坐标,并计算出它与下一个点之间的角距......依此类推。

    类似以下想法的东西应该有效 - 尽管它是在这里写的并且没有经过测试!

    var EARTH_RADIUS = 6378135; // approximate in meters 
    
    var degreestoRadians = function(degrees) {
      return degrees * Math.PI / 180;
    }
    
    var arcLength = function(point1 , point2) {   
      var length = Math.sqrt(Math.pow(point1.X-point2.X, 2) 
                   + Math.pow(point1.Y-point2.Y, 2) 
                   + Math.pow(point1.Z-point2.Z, 2));
      var angle = 2 * Math.asin(length/2/EARTH_RADIUS);
      return EARTH_RADIUS * angle;
    }
    
    var sphericalToCartesian = function(latitude, longitude, altitude) {
      var phi = degreestoRadians(latitude);
      var theta = degreestoRadians(longitude);
      var rho = EARTH_RADIUS + altitude;
      return {
        X: Math.cos(phi) * Math.cos(theta) * rho,
        Y: Math.cos(phi) * Math.sin(theta) * rho,
        Z: Math.sin(phi) * rho
      }
    }
    
    var topographicDistance = function(linestring) {
      var coordinates = linestring.getCoordinates(); //KmlCoordArray
      var last = null;
      var distance = 0;
      for(var i = 0; i < coordinates.length; i++) {
         var coord = coordinates.get(i); //KmlCoord
         var lat = coord.getLatitude();
         var lng = coord.getLongitude();
         var alt  = ge.getGlobe().getGroundAltitude(lat, lng);
         var latest = sphericalToCartesian(lat, lng, alt);
         if(last != null) {
           distance += arcLength(last, latest);
         } 
    
         last = latest;
      }
    
      return distance;
    }
    

    你会像这样使用它......

    var distance = topographicDistance(yourLinestring);