当前位置: 首页 >>ASP.NET >>ASP.NET实战 >>C#地图位置开发时根据经纬度判断一个点是否在一个矩形范围内

C#地图位置开发时根据经纬度判断一个点是否在一个矩形范围内

时间:2020/8/15 10:37:00 【网络】

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

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

                        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;

            }

        

    }


调用方法:

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) + "";

    }


相关文章

CopyRight:2007-2018 语言吧 备案ICP:湘ICP备09009000号-15 http://www.yuyanba.com

分享按钮