指向使用角度和半径为3 lat的三角形
我希望得到一条线的距离,并开始使用haversine代码。
private static final double _eQuatorialEarthRadius = 6378.1370D;
private static final double _d2r = (Math.PI / 180D);
private static double PRECISION = 0.001;
// Haversine Algorithm
// source: http://stackoverflow.com/questions/365826/calculate-distance-between-2-gps-coordinates
private static double HaversineInM(double lat1, double long1, double lat2, double long2) {
return (1000D * HaversineInKM(lat1, long1, lat2, long2));
}
private static double HaversineInKM(double lat1, double long1, double lat2, double long2) {
double dlong = (long2 - long1) * _d2r;
double dlat = (lat2 - lat1) * _d2r;
double a = Math.pow(Math.sin(dlat / 2D), 2D) + Math.cos(lat1 * _d2r) * Math.cos(lat2 * _d2r)
* Math.pow(Math.sin(dlong / 2D), 2D);
double c = 2D * Math.atan2(Math.sqrt(a), Math.sqrt(1D - a));
double d = _eQuatorialEarthRadius * c;
return d;
}
// Distance between a point and a line
public static double pointLineDistanceTest(double[] aalatlng,double[] bblatlng,double[] ttlatlng) {
double [] a = aalatlng;
double [] b = bblatlng;
double [] c = ttlatlng;
double[] nearestNode = nearestPointGreatCircle(a, b, c);
// System.out.println("nearest node: " + Double.toString(nearestNode[0]) + "," + Double.toString(nearestNode[1]));
double result = HaversineInM(c[0], c[1], nearestNode[0], nearestNode[1]);
// System.out.println("result: " + Double.toString(result));
return (result);
}
// source: http://stackoverflow.com/questions/1299567/how-to-calculate-distance-from-a-point-to-a-line-segment-on-a-sphere
private static double[] nearestPointGreatCircle(double[] a, double[] b, double c[])
{
double[] a_ = toCartsian(a);
double[] b_ = toCartsian(b);
double[] c_ = toCartsian(c);
double[] G = vectorProduct(a_, b_);
double[] F = vectorProduct(c_, G);
double[] t = vectorProduct(G, F);
return fromCartsian(multiplyByScalar(normalize(t), _eQuatorialEarthRadius));
}
@SuppressWarnings("unused")
private static double[] nearestPointSegment (double[] a, double[] b, double[] c)
{
double[] t= nearestPointGreatCircle(a,b,c);
if (onSegment(a,b,t))
return t;
return (HaversineInKM(a[0], a[1], c[0], c[1]) < HaversineInKM(b[0], b[1], c[0], c[1])) ? a : b;
}
private static boolean onSegment (double[] a, double[] b, double[] t)
{
// should be return distance(a,t)+distance(b,t)==distance(a,b),
// but due to rounding errors, we use:
return Math.abs(HaversineInKM(a[0], a[1], b[0], b[1])-HaversineInKM(a[0], a[1], t[0], t[1])-HaversineInKM(b[0], b[1], t[0], t[1])) < PRECISION;
}
// source: http://stackoverflow.com/questions/1185408/converting-from-longitude-latitude-to-cartesian-coordinates
private static double[] toCartsian(double[] coord) {
double[] result = new double[3];
result[0] = _eQuatorialEarthRadius * Math.cos(Math.toRadians(coord[0])) * Math.cos(Math.toRadians(coord[1]));
result[1] = _eQuatorialEarthRadius * Math.cos(Math.toRadians(coord[0])) * Math.sin(Math.toRadians(coord[1]));
result[2] = _eQuatorialEarthRadius * Math.sin(Math.toRadians(coord[0]));
return result;
}
private static double[] fromCartsian(double[] coord){
double[] result = new double[2];
result[0] = Math.toDegrees(Math.asin(coord[2] / _eQuatorialEarthRadius));
result[1] = Math.toDegrees(Math.atan2(coord[1], coord[0]));
return result;
}
// Basic functions
private static double[] vectorProduct (double[] a, double[] b){
double[] result = new double[3];
result[0] = a[1] * b[2] - a[2] * b[1];
result[1] = a[2] * b[0] - a[0] * b[2];
result[2] = a[0] * b[1] - a[1] * b[0];
return result;
}
private static double[] normalize(double[] t) {
double length = Math.sqrt((t[0] * t[0]) + (t[1] * t[1]) + (t[2] * t[2]));
double[] result = new double[3];
result[0] = t[0]/length;
result[1] = t[1]/length;
result[2] = t[2]/length;
return result;
}
private static double[] multiplyByScalar(double[] normalize, double k) {
double[] result = new double[3];
result[0] = normalize[0]*k;
result[1] = normalize[1]*k;
result[2] = normalize[2]*k;
return result;
}
并有许多错误,所以写这个计算使用轴承来获得角度,然后使用距离(点a,目标)来计算目标(点a,点b)线。 点A和B是线,我想要从目标到线的距离。 没有很大的圈子。 sin角度(方位差)* a点到目标距离=从AB线上的直角到目标为止的直角三角形边的长度。
public double pointlinedistancetest(){
//set latlng location point a
Location apoint=new Location("");
apoint.setLatitude(lata);
apoint.setLongitude(lona);
//set latlng location point b
Location bpoint=new Location("");
bpoint.setLatitude(latb);
bpoint.setLongitude(lonb);
//set latlng location target to get dis to line
Location tpoint=new Location("");
tpoint.setLatitude(lat);
tpoint.setLongitude(lon);
float pbearingf = apoint.bearingTo(bpoint);
float tbearingf= apoint.bearingTo(tpoint);
double tb=tbearingf;
double ab=pbearingf;
//get angle degree difference
float angle= Math.min((pbearingf-tbearingf)<0?pbearingf-tbearingf+360:pbearingf-tbearingf, (tbearingf-pbearingf)<0?tbearingf-pbearingf+360:tbearingf-pbearingf);
// float angle= Math.min((tbearingf-pbearingf)<0?tbearingf-pbearingf+360:tbearingf-pbearingf, (pbearingf-tbearingf)<0?pbearingf-tbearingf+360:pbearingf-tbearingf);
// min((a1-a2)<0?a1-a2+360:a1-a2, (a2-a1)<0?a2-a1+360:a2-a1)
double aabearing=angle;
float atot=apoint.distanceTo(tpoint);
double atotdis=atot;
//right angle triangle formula
dis=(Math.sin(aabearing))*atotdis;
return (dis);
}
现在两者仍然表现出高达30%的巨大误差。 这段代码看起来是否正确,有没有更好的方法来做到这一点,或者是我的错误在哪里。 我的GPS显示精度为4米,我的公式(代码)显示10到20米的误差,似乎并没有太大差异。
您可以使用Google Geometry库查找线的长度及其方位。
从文档
computeDistanceBetween(从:LatLng,到:LatLng,radius?:number)以米为单位的数字返回两个LatLng之间的距离。 半径以米为单位默认为地球半径(6378137)。
computeHeading(from:LatLng,to:LatLng)返回从一个LatLng到另一个LatLng的标题。 标题以[-180,180]范围内的北方顺时针方向表示为数字。
computeOffset(from:LatLng,distance:number,heading:number,radius?:number)返回从指定标题中的原点移动距离(以从北方顺时针表示的度数表示)所得到的LatLng。
首先找到行的开始和结束之间的距离
var spherical = google.maps.geometry.spherical;
var length = google.maps.geometry.spherical.computeDistanceBetween(A,B);
然后找到线的方位
var heading = google.maps.geometry.spherical.computeHeading(A,B);
从图像120度
然后找到A行和C行之间的距离和方位
var length2 = google.maps.geometry.spherical.computeDistanceBetween(A,C);
var heading2 = google.maps.geometry.spherical.computeHeading(A,C);
从图像50度
var angleBAC = heading1-heading2
角度BAC = 120 - 50度= 70度
正如您现在知道角度BAC和从A到C的距离,您可以使用三角法来查找长度CD
sineBAC = opp / Hypotenuese
var CD = Math.sin(angleBAC) * length2;
从图像
opp =正弦70度X长度AC
从图像0.9397 X 5 = 4.6984
链接地址: http://www.djcxy.com/p/85007.html上一篇: point to line using angles and haversine with 3 lat long points
下一篇: Using distance matrix to find coordinate points of set of points