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

jph*_*oon 2 javascript google-earth-plugin computational-geometry

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

在谷歌地球插件中,我想做一个类似的事情,那就是我希望确定ground length一个镶嵌细分KmlLineString的地形.

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

Fra*_*ser 5

如果你使用earth-api-utility-library,你肯定可以很容易地获得长度.使用它你可以做到.

var length = (new geo.Path(linestring)).distance(); 
Run Code Online (Sandbox Code Playgroud)

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

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

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

记住,如果你仍然想要这样做,那么一种方式将是如下.

  1. 在某些点(例如每10米)对线串进行采样.
  2. 获取每个点的地面高度.
  3. 将每个点转换为笛卡尔坐标
  4. 按顺序计算每个笛卡尔点之间的角距离.

您可以通过两种方式提高这种方法的精度,可以通过提高采样率(比如每米)或对结果应用平滑程序.

对于更粗糙的版本,您可以循环遍历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;
}
Run Code Online (Sandbox Code Playgroud)

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

var distance = topographicDistance(yourLinestring);
Run Code Online (Sandbox Code Playgroud)