计算景点间的距离

在原来的工程中,是没有景点间的距离这个概念的。

为了将这一元素添加到工程中,需要以下改动:

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……

 

转载于:https://www.cnblogs.com/elaron/archive/2012/10/24/2737662.html