桩号转经纬度的实现
时间:2009-10-14 javaeye lgx2351
公路中都是以桩号来标识空间位置关系的,这时候很经常用到的就是要把桩号转化为经纬度,以满足定位等要求。如何实现呢?
其实原理就是:用二分法找到离这个桩号最近的两个相邻点,找到后利用相似三角形的算法就可以得到桩号对应的经纬度了。
主要的代码如下:
Java代码
//输入路线的节点List和里程,返回指定里程的相邻点,如果在延长线上则返回起点或终点
private static Point[] getNeighborPoint(List list, double mile) {
Point pt[] = new Point[2];
Point tmp_pt1 = (Point) list.get(0);
Point tmp_pt2 = (Point) list.get(list.size() - 1);
if (mile <= tmp_pt1.getMile()) {
pt[0] = tmp_pt1;
pt[1] = tmp_pt1;
}
else if (mile >= tmp_pt2.getMile()) {
pt[0] = tmp_pt2;
pt[1] = tmp_pt2;
}
else {
int iIndex = 0;
int iStart = 0;
int iEnd = list.size()-1;
while (true) {
iIndex = (iStart + iEnd) / 2;
tmp_pt1 = (Point) list.get(iIndex);
if (tmp_pt1.getMile() > mile) {
tmp_pt2 = (Point) list.get(iIndex - 1);
if (tmp_pt2.getMile() < mile) {
pt[0] = tmp_pt2;
pt[1] = tmp_pt1;
break;
} else {
iEnd = iIndex;
}
}
else if (tmp_pt1.getMile() < mile) {
tmp_pt2 = (Point) list.get(iIndex + 1);
if (tmp_pt2.getMile() > mile) {
pt[0] = tmp_pt1;
pt[1] = tmp_pt2;
break;
} else {
iStart = iIndex;
}
}
else {
pt[0] = tmp_pt1;
pt[1] = tmp_pt1;
break;
}
}
}
return pt;
}
//根据两个节点和里程,找出该里程对应的点,如果两个节点里程相等,则返回第一个点
private static Point getLocation(Point pt1, Point pt2, double mile) {
double difMile = pt2.getMile() - pt1.getMile();
if (difMile == 0) {
return pt1;
} else {
double k = (mile - pt1.getMile()) / difMile;
double difx = pt2.getX() - pt1.getX();
double dify = pt2.getY() - pt1.getY();
double x = pt1.getX() + difx * k;
double y = pt1.getY() + dify * k;
return new Point(x, y, mile);
}
}
这里的桩号转经纬度要与“经纬度转桩号”相区别开来,桩号转经纬度其实就是通过二分法找到相邻的两个点再用相似三角形来得到;而经纬度转桩号是通过点到线的最小距离得到相邻的两个点,再通过求垂足的方法来得到桩号值。这里要注意的是特殊情况的处理! |