计算景点间的距离
在原来的工程中,是没有景点间的距离这个概念的。
为了将这一元素添加到工程中,需要以下改动:
1、增加一个数据库表,用来存储景点之间的距离信息。
可以看到有三个字段,分别为景点1的ID号、景点2的ID号以及两者之间的距离。
2、需要在工程中定义“距离”这一数据结构
3、需要增加DAO层,以支持对distance表的读写访问。
DAO层主要的方法有:新增、删除、检索。
新增:在景区管理员增加新景点时,计算新景点与已存在的各个景点之间的距离,然后写入distance表中。
删除:景区管理员删除一个景点时,需要删除该景点跟其他所有景点之间的距离记录。
delete from distance where sight1='a' or sight2 = 'a';
检索:检索某一景点x米范围内的景点。
select * from distance where (sight1='3_d_40' or sight2='3_d_40') and (distance > 150 and distance < 250);
4、编写计算两点间距离的算法
在matlab中测试该算法,在跨度不大的情况下,误差可以控制在50米以内,距离越近误差越小。
matlab函数:
function dis = getDistance(a,b) c = sin(a(1)) * sin(b(1)) * cos(a(2) - b(2)) + cos(a(1))*cos(b(1)); dis= 6370000 * acos(c) * pi / 180;
java函数:
public static int getDistance(LongtitudeAndLatitudeBean s1, LongtitudeAndLatitudeBean s2){ double alt = new Double(s1.getLatitude()); double blt = new Double(s2.getLatitude()); double alg = new Double(s1.getLongitude()); double blg = new Double(s2.getLongitude()); double c = Math.sin(alt) * Math.sin(blt) * Math.cos(alg - blg) + Math.cos(alt)*Math.cos(blt); double dis = 6370000 * Math.acos(c) * 3.1415926 / 180; return (int) Math.round(dis); }
其中,LongtitudeAndLatitudeBean 为定义经纬度的数据结构,包含latitude和longitude属性。
4、更改模型层
模型层负责业务逻辑的实现。又上述内容知,在景点创建和删除时,都需要对distance表进行相应的操作,因此将该操作写入相应的模型层类文件中。
5、计算现有景点的距离信息并导入数据库中
假设现在存在n个景点,那么需要n(n-1)/2条记录来存储它们之间的距离信息。
记录<a,b,distance>和<b,a,distance>是等效的,因此只需要存储其中一个。使用控制的for循环可以保证不会出现重复。
int size = list.size(); for(int i = 0; i < size; i++){ for(int j = i + 1; j < size; j++){ int distance = CalculateDistance.getDistance(list.get(i), list.get(j)); DistanceBean dbean = new DistanceBean(); dbean.setSight1(list.get(i).getSightID()); dbean.setSight2(list.get(j).getSightID()); dbean.setDistance(distance); distanceDAO.add(dbean); } }
6、测试导入的结果
测试语句
select * from distance where (sight1='3_d_20' or sight2='3_d_20') and distance < 50;
结果如下:
后记:
今天为了获得两个景点间的距离可是大费周章。
早上的时候想要使用百度地图API的map的getDistanc函数来获得。所以就找找有没有java版本的这个API可以调用,无奈,百度地图公开的web服务一天只提供1000次访问,作罢。因此,想着能不能用java虚拟调用一个jsp访问,在jsp页面中写入百度地图的js API来获得距离。但是无奈也作罢,因为百度地图的js API是客户端的接口,在tomcat组织完一个网页后,怎么都得用一个客户端来运行那个访问才行,实在是绕得慌,折腾一上午也没测出个可行的方法来。
下午来实验室,觉得要不就直接计算吧……虽然百度的坐标经过了偏移,但是搞不好不影响距离的计算呢。所以开始在网上搜索算法,然后在matlab中测试。觉得误差在可接受范围内,因此移植到工程中,当做距离的计算算法来使用。
测试的结果还算比较满意。明天尝试在客户端显示结果。
折腾了一天都没看成书,晚上回家改完技术报告的图再看看有多少时间看书吧……sigh……