您的位置:首页 > 其它

根据经纬度判断一个点是否在一个矩形范围内

2015-12-07 23:10 375 查看
在实际应用中经常会遇到这样一种需求,由最大最小的经纬度给出一个矩形范围,然后判断一个点是否在这个范围内部,由于经纬度有负有正,而且经度跨越正负180度后变号并且反向增减,一两步计算不出来,下面给出一种计算方案,其中在经度的处理上,只有劣弧计入范围内部,也就是只有小于半球面的那部分算作区域内部,如果想算超过180的大面积,请求反操作。

下面是主要方法:

/**
     *
     * @param latitue 待测点的纬度
     * @param longitude 待测点的经度
     * @param areaLatitude1 纬度范围限制1
     * @param areaLatitude2 纬度范围限制2
     * @param areaLongitude1 经度限制范围1
     * @param areaLongitude2 经度范围限制2
     * @return
     */
    public static boolean isInArea(double latitue,double longitude,double areaLatitude1,double areaLatitude2,double areaLongitude1,double areaLongitude2){
        if(isInRange(latitue, areaLatitude1, areaLatitude2)){//如果在纬度的范围内
            if(areaLongitude1*areaLongitude2>0){//如果都在东半球或者都在西半球
                if(isInRange(longitude, areaLongitude1, areaLongitude2)){
                    return true;
                }else {
                    return false;
                }
            }else {//如果一个在东半球,一个在西半球
                if(Math.abs(areaLongitude1)+Math.abs(areaLongitude2)<180){//如果跨越0度经线在半圆的范围内
                    if(isInRange(longitude, areaLongitude1, areaLongitude2)){
                        return true;
                    }else {
                        return false;
                    }
                }else{//如果跨越180度经线在半圆范围内
                    double left = Math.max(areaLongitude1, areaLongitude2);//东半球的经度范围left-180
                    double right = Math.min(areaLongitude1, areaLongitude2);//西半球的经度范围right-(-180)
                    if(isInRange(longitude, left, 180)||isInRange(longitude, 0, right)){
                        return true;
                    }else {
                        return false;
                    }
                }
            }
        }else{
            return false;
        }
    }
    
    public static boolean isInRange(double point, double left,double right){
            if(point>=Math.min(left, right)&&point<=Math.max(left, right)){
                return true;
            }else {
                return false;
            }
        
    }


调用方法
</pre><pre name="code" class="java">public static void main(String[] args) {
// TODO Auto-generated method stub
double myLatitude = 36.0;//待测点的纬度
double myLongitude = 120;//待测点的经度
//下面是经纬度的范围
double minLatitude = -60;
double maxLatitude = 40.0;
double minLongitude = 140;
double maxLongitude = 100;

 if(isInArea(myLatitude, myLongitude, minLatitude, maxLatitude, minLongitude, maxLongitude)){
System.out.println("在范围内");
}else{
System.out.println("不在范围内");
}

}


如果使用地图sdk的话会有更简单的方法

以谷歌地图为例,首先生成一个限制对象,然后用这个限制对象测点就行了,如下

final LatLngBounds boundary = new LatLngBounds(new LatLng(minlatitude, minlongitude), new LatLng(maxlatitude, maxlongitude));
boundary.including(new LatLng(36.0,120.0));


下面给出一个很实用的方法:给出一个经纬度点,然后给出一个距离和方向,求出这个点根据这个距离和方向算出的另一个点

//地理常量
private final static double EARTH_RADIUS = 6378138.0;
private final static double PI = 3.14159265;
private final static double Rc = 6378137;  // 赤道半径
private final static double Rj = 6356725;  // 极半径
// The shared path to all app expansion files
private final static String EXP_PATH = "/Android/obb/";
static double DEF_PI = 3.14159265359; // PI
static double DEF_2PI = 6.28318530712; // 2*PI
static double DEF_PI180 = 0.01745329252; // PI/180.0
static double DEF_R = 6370693.5; // radius of earth


public static String[] getGPSLocation(double latitude, double longitude, double distance, double angle) {
String[] result = {"0.0", "0.0"};
double m_Latitude;
double m_RadLo, m_RadLa;
double Ec;
double Ed;

m_Latitude = latitude;
m_RadLo = longitude * PI / 180.0;
m_RadLa = latitude * PI / 180.0;
Ec = Rj + (Rc - Rj) * (90.0 - m_Latitude) / 90.0;
Ed = Ec * Math.cos(m_RadLa);

double dx = distance * 1000 * Math.sin(angle * PI / 180.0);
double dy = distance * 1000 * Math.cos(angle * PI / 180.0);

double BJD = (dx / Ed + m_RadLo) * 180.0 / PI;
double BWD = (dy / Ec + m_RadLa) * 180.0 / PI;

result[0] = BWD + "";
result[1] = BJD + "";
return result;
}


下面是再提供几个比较实用的方法:根据经纬度计算两点间距离

public static double getGPSDistance(double lat_a, double lng_a, double lat_b, double lng_b) {
final double M_PI = 3.14159265358979323846264338327950288;
final double dd = M_PI / 180.0;

double lon2 = lng_b;
double lat2 = lat_b;

double x1 = lat_a * dd, x2 = lat2 * dd;
double y1 = lng_a * dd, y2 = lon2 * dd;
double distance = (2 * EARTH_RADIUS * Math.asin(Math.sqrt(2 - 2 * Math.cos(x1)
* Math.cos(x2) * Math.cos(y1 - y2) - 2 * Math.sin(x1)
* Math.sin(x2)) / 2));

return distance;
}

//适用于近距离
public static double GetShortDistance(double lon1, double lat1, double lon2, double lat2) {
double ew1, ns1, ew2, ns2;
double dx, dy, dew;
double distance;
// 角度转换为弧度
ew1 = lon1 * DEF_PI180;
ns1 = lat1 * DEF_PI180;
ew2 = lon2 * DEF_PI180;
ns2 = lat2 * DEF_PI180;
// 经度差
dew = ew1 - ew2;
// 若跨东经和西经180 度,进行调整
if (dew > DEF_PI)
dew = DEF_2PI - dew;
else if (dew < -DEF_PI)
dew = DEF_2PI + dew;
dx = DEF_R * Math.cos(ns1) * dew; // 东西方向长度(在纬度圈上的投影长度)
dy = DEF_R * (ns1 - ns2); // 南北方向长度(在经度圈上的投影长度)
// 勾股定理求斜边长
distance = Math.sqrt(dx * dx + dy * dy);
return distance;
}

//适用于远距离
public static double GetLongDistance(double lon1, double lat1, double lon2, double lat2) {
double ew1, ns1, ew2, ns2;
double distance;
// 角度转换为弧度
ew1 = lon1 * DEF_PI180;
ns1 = lat1 * DEF_PI180;
ew2 = lon2 * DEF_PI180;
ns2 = lat2 * DEF_PI180;
// 求大圆劣弧与球心所夹的角(弧度)
distance = Math.sin(ns1) * Math.sin(ns2) + Math.cos(ns1) * Math.cos(ns2) * Math.cos(ew1 - ew2);
// 调整到[-1..1]范围内,避免溢出
if (distance > 1.0)
distance = 1.0;
else if (distance < -1.0)
distance = -1.0;
// 求大圆劣弧长度
distance = DEF_R * Math.acos(distance);
return distance;
}

/**
* Unit:M
*/
public static String getGPSDistance(String lat_a, String lng_a, String lat_b, String lng_b) {
double d_lat_a = 0.0;
try {
d_lat_a = Double.parseDouble(lat_a);
} catch (Exception ex) {
ex.printStackTrace();
}

double d_lng_a = 0.0;
try {
d_lng_a = Double.parseDouble(lng_a);
} catch (Exception ex) {
ex.printStackTrace();
}

double d_lat_b = 0.0;
try {
d_lat_b = Double.parseDouble(lat_b);
} catch (Exception ex) {
ex.printStackTrace();
}

double d_lng_b = 0.0;
try {
d_lng_b = Double.parseDouble(lng_b);
} catch (Exception ex) {
ex.printStackTrace();
}

return getGPSDistance(d_lat_a, d_lng_a, d_lat_b, d_lng_b) + "";
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: