经纬度坐标工具类

在开发地图的时候难免会遇到经纬度的一些算法,这里我分享一些经纬度的算法,主要包括,

  • 判断两个经纬度坐标之间的距离
  • 判断一个经纬度坐标是否在一个圆形面中(如共享单车的电子围栏为圆形)
  • 判断一个经纬度坐标是否在一个多边形的中(电子围栏类型为多边形)

    具体算法:

import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;

import com.tbit.uqbike.client.pojo.Point;
import com.tbit.uqbike.client.pojo.PointArray;

/**
* @author Kang
* @date 2018年7月25日 上午8:51:28
* @description 坐标工具类
*/
public class CoordUtils {
    private  static double EARTH_RADIUS = 6371393;//地球半径
    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }
    /**
     * 通过经纬度获取距离(单位:米)
     * @param lat1 用户纬度
     * @param lng1 用户经度
     * @param lat2 用户纬度
     * @param lng2 用户经度
     * @return
     */
    public static double getDistance(double lng1, double lat1, double lng2, double lat2) {
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a = radLat1 - radLat2;
        double b = rad(lng1) - rad(lng2);
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS;
        s = Math.round(s * 10000d) / 10000d;
        return s;

}
     /**
      * 判断一个点是否在圆形区域内
      * @param lon1 经度1
      * @param lat1 纬度1
      * @param lon2 经度2
      * @param lat2 纬度2
      * @param radius 半径 米
      * @return
      */
    public static boolean isInCircle(double lon1, double lat1, double lon2, double lat2, double radius) {
        double distance = getDistance(lon1, lat1, lon2, lat2);
        if (distance > radius) {
            return false;
        } else {
            return true;
        }
    }

     /**
     * 判断是否在多边形区域内
     * @param pointLon 要判断的点的纵坐标 经度
     * @param pointLat 要判断的点的横坐标 纬度
     * @param lon 区域各顶点的纵坐标数组 经度集合
     * @param lat 区域各顶点的横坐标数组 纬度集合
     * @return
     */
    public static boolean isInPolygon(double pointLon, double pointLat, double[] lon,
            double[] lat) {
        // 将要判断的横纵坐标组成一个点
        Point2D.Double point = new Point2D.Double(pointLon, pointLat);
        // 将区域各顶点的横纵坐标放到一个点集合里面
        List<Point2D.Double> pointList = new ArrayList<Point2D.Double>();
        double polygonPoint_x = 0.0, polygonPoint_y = 0.0;
        for (int i = 0; i < lon.length; i++) {
            polygonPoint_x = lon[i];
            polygonPoint_y = lat[i];
            Point2D.Double polygonPoint = new Point2D.Double(polygonPoint_x, polygonPoint_y);
            pointList.add(polygonPoint);
        }
        return check(point, pointList);
    }
    /**
     * 一个点是否在多边形内
     * @param point 要判断的点的横纵坐标
     * @param polygon 组成的顶点坐标集合
     * @return
     */
    private static boolean check(Point2D.Double point, List<Point2D.Double> polygon) {
        java.awt.geom.GeneralPath peneralPath = new java.awt.geom.GeneralPath();
        Point2D.Double first = polygon.get(0);
        // 通过移动到指定坐标(以双精度指定),将一个点添加到路径中
        peneralPath.moveTo(first.x, first.y);
        polygon.remove(0);
        for (Point2D.Double d : polygon) {
            // 通过绘制一条从当前坐标到新指定坐标(以双精度指定)的直线,将一个点添加到路径中。
            peneralPath.lineTo(d.x, d.y);
        }
        // 将几何多边形封闭
        peneralPath.lineTo(first.x, first.y);
        peneralPath.closePath();
        // 测试指定的 Point2D 是否在 Shape 的边界内。
        return peneralPath.contains(point);
    }
    public static void main(String[] args) {
        //验证多边形,先画一个面,然后判断这个点是否在这个面中
        double pointLat=39.946361;
        double pointLon=115.597662;
        double[] lat={40.065737,39.651002,39.645669};//纬度
        double[] lon={116.403694,116.000103,116.924567};//经度
        boolean flag = isInPolygon(pointLon, pointLat, lon, lat);
        System.out.println(flag);
        //验证圆形
        boolean inCircle = isInCircle(113.956187,22.555855, 113.956268,22.555824, 9.1);
        System.out.println(inCircle);
        System.out.println(getDistance(113.956187,22.555855, 113.956268,22.555824));

    }
    /**
     * 返回经纬度坐标数组集合包装类
     * @param points
     * @return
     */
    public static PointArray getPoints(String points){
        String[] latLons = points.split(";");
        double[] lons=new double[latLons.length];
        double[] lats=new double[latLons.length];
        for(int i=0;i<latLons.length;i++){
            String[] latLonArray = latLons[i].split(",");
            double lo=Double.parseDouble(latLonArray[0]);//经度
            lons[i]=lo;
            double la=Double.parseDouble(latLonArray[1]);//纬度
            lats[i]=la;
        }
        return new PointArray(lons,lats);
    }


}

经纬度坐标数组包装类:

/**
* @author Kang
* @date 2018年7月26日 上午9:44:04
* @description 经纬度数组包装
*/
public class PointArray {
    private double[] lons; //经度
    private double[] lats; //纬度
    public PointArray(double[] lons,double[] lats){
        this.lons=lons;
        this.lats=lats;
    }
    public double[] getLons() {
        return lons;
    }
    public void setLons(double[] lons) {
        this.lons = lons;
    }
    public double[] getLats() {
        return lats;
    }
    public void setLats(double[] lats) {
        this.lats = lats;
    }
}
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值