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

在实际应用中经常会遇到这样一种需求,由最大最小的经纬度给出一个矩形范围,然后判断一个点是否在这个范围内部,由于经纬度有负有正,而且经度跨越正负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) + "";
    }




你可能感兴趣的:(java,gps,地图)