【发布时间】:2017-09-06 02:38:13
【问题描述】:
Google 地球桌面应用程序显示一行的map length 和ground length。
在 Google 地球插件中我想做类似的事情,即我希望在考虑地形的情况下确定镶嵌的KmlLineString 的ground length。
我可以这样做吗?如果可以,怎么做?
【问题讨论】:
标签: javascript computational-geometry google-earth-plugin
Google 地球桌面应用程序显示一行的map length 和ground length。
在 Google 地球插件中我想做类似的事情,即我希望在考虑地形的情况下确定镶嵌的KmlLineString 的ground length。
我可以这样做吗?如果可以,怎么做?
【问题讨论】:
标签: javascript computational-geometry google-earth-plugin
如果您使用earth-api-utility-library,您当然可以很容易地获得长度。使用它你可以做到。
var length = (new geo.Path(linestring)).distance();
当然,此方法不考虑地形 - 但在尝试使用高程梯度计算距离之前,您应该注意一些注意事项。
首先,在大多数情况下,地形距离和直接距离之间的差异很小。事实上,许多优质 GPS 接收器在计算距离时根本不会考虑任何海拔变化。
其次,地面高度是最不可靠的数据之一。使用基于高程的梯度来确定距离通常会在距离测量中产生更大的不准确性,而不是使用简单的“如乌鸦飞”的测量。
考虑到这一点,如果您仍然想这样做,那么一种方法将类似于以下内容。
您可以通过两种方式提高这种方法的精度,一种是提高采样率(比如每米),另一种是对结果应用平滑程序。
对于更粗略的版本,您可以循环遍历 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);
【讨论】: