BN原理BN原理12-12 00:15

经纬度计算

下面的代码是一个工具类,可直接拿去使用。

package com.framework.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.stereotype.Service;

import com.framework.entity.base.JcZd;
import com.framework.entity.business.YwClxx;
import com.framework.redis.GetRedisPool;
import com.framework.redis.RedisPrefix;
 import com.framework.redis.SerializeUtil;


@Service
public class GpsDistanceUtils {
// 常量定义如下: Crew
// WGS-84 长轴半径
private double EARTH_WGS84_A = 6378137.0000; // WGS-84Semi-major axis in
                                                // meters
// WGS-84 短轴半径
private double EARTH_WGS84_B = 6356752.3142; // WGS-84 Semi-minor axis in
                                                // meters
// WGS-84 偏心率的平方
private double EARTH_WGS84_E2 = 0.00669437999013; // WGS-84 Eccentricity
                                                    // squared
private double EARTH_WGS84_MPM = 1852.0; // meters per nmile
// WGS-84 地球扁率
private double EARTH_WGS84_FLATTENING = 298.257223563; // WGS-84 Flattening
// 圆周率
private double PI = 3.14159265359;

/**
 * 度为单位 返回公里 - 纬度1,经度1,纬度2,经度2
 * @param dLatitude
 * @param dLongitude
 * @param dLatitude1
 * @param dLongitude1
 * @return
 */
public double mileEarthDis(double dLatitude, double dLongitude, double dLatitude1, double dLongitude1) {
    double D, dis;
    double tmpVal;
    double fi1, fi2;
    double drda = dLongitude1 - dLongitude;
    drda = drda * PI / 180.0;// in radians
    fi1 = dLatitude;
    fi2 = dLatitude1;

    fi1 = fi1 * PI / 180.0;// in in radians
    fi2 = fi2 * PI / 180.0;// in in radians

    tmpVal = Math.sin(fi1) * Math.sin(fi2) + Math.cos(fi1) * Math.cos(fi2) * Math.cos(drda);
    if (Math.abs(tmpVal) > 1.0)
        return 0;
    D = Math.acos(tmpVal);// in radians
    if (D == 0)
        return 0;
    double tmp1, tmp2;
    tmp1 = (Math.sin(fi1) + Math.sin(fi2));
    tmp2 = (Math.sin(fi1) - Math.sin(fi2));
    tmpVal = ((3 * Math.sin(D) - D) * tmp1 * tmp1) / (1 + Math.cos(D));
    tmpVal = tmpVal - ((3 * Math.sin(D) + D) * tmp2 * tmp2) / (1 - Math.cos(D));

    dis = EARTH_WGS84_A * D + (EARTH_WGS84_A / (4 * EARTH_WGS84_FLATTENING)) * tmpVal;
    dis = dis / 1000;
    // System.out.println(" Dis is: " + dis);
    return dis;
}

/**
 * 度为单位 返回米 - 纬度1,经度1,纬度2,经度2
 * @param dLatitude
 * @param dLongitude
 * @param dLatitude1
 * @param dLongitude1
 * @return
 */
public double earthDis(double dLatitude, double dLongitude, double dLatitude1, double dLongitude1) {
    double D, dis;
    double tmpVal;
    double fi1, fi2;
    double drda = dLongitude1 - dLongitude;
    drda = drda * PI / 180.0;// in radians
    fi1 = dLatitude;
    fi2 = dLatitude1;

    fi1 = fi1 * PI / 180.0;// in in radians
    fi2 = fi2 * PI / 180.0;// in in radians

    tmpVal = Math.sin(fi1) * Math.sin(fi2) + Math.cos(fi1) * Math.cos(fi2) * Math.cos(drda);
    if (Math.abs(tmpVal) > 1.0)
        return 0;
    D = Math.acos(tmpVal);// in radians
    if (D == 0)
        return 0;
    double tmp1, tmp2;
    tmp1 = (Math.sin(fi1) + Math.sin(fi2));
    tmp2 = (Math.sin(fi1) - Math.sin(fi2));
    tmpVal = ((3 * Math.sin(D) - D) * tmp1 * tmp1) / (1 + Math.cos(D));
    tmpVal = tmpVal - ((3 * Math.sin(D) + D) * tmp2 * tmp2) / (1 - Math.cos(D));

    dis = EARTH_WGS84_A * D + (EARTH_WGS84_A / (4 * EARTH_WGS84_FLATTENING)) * tmpVal;

    // System.out.println(" Dis is: " + dis);
    return dis;
}

/**
 * 分为单位 返回公里 - 纬度1,经度1,纬度2,经度2
 * @param dLatitude_FEN
 * @param dLongitude_FEN
 * @param dLatitude1_FEN
 * @param dLongitude1_FEN
 * @return
 */
public double mileEarthDisFEN(double dLatitude_FEN, double dLongitude_FEN, double dLatitude1_FEN, double dLongitude1_FEN) {
    double dis;
    double dLatitude_DU = dLatitude_FEN / 60;
    double dLongitude_DU = dLongitude_FEN / 60;
    double dLatitude1_DU = dLatitude1_FEN / 60;
    double dLongitude1_DU = dLongitude1_FEN / 60;
    dis = mileEarthDis(dLatitude_DU, dLongitude_DU, dLatitude1_DU, dLongitude1_DU);
    return dis;
}

/**
 * 分为单位 返回米 - 纬度1,经度1,纬度2,经度2
 * @param dLatitude_FEN
 * @param dLongitude_FEN
 * @param dLatitude1_FEN
 * @param dLongitude1_FEN
 * @return
 */
public double earthDisFEN(double dLatitude_FEN, double dLongitude_FEN, double dLatitude1_FEN, double dLongitude1_FEN) {
    double dis;
    double dLatitude_DU = dLatitude_FEN / 60;
    double dLongitude_DU = dLongitude_FEN / 60;
    double dLatitude1_DU = dLatitude1_FEN / 60;
    double dLongitude1_DU = dLongitude1_FEN / 60;
    dis = earthDis(dLatitude_DU, dLongitude_DU, dLatitude1_DU, dLongitude1_DU);
    return dis;
}

/**
 * 分的1000倍为单位 返回公里 - 纬度1,经度1,纬度2,经度2
 * @param dLatitude_ThousandFEN
 * @param dLongitude_ThousandFEN
 * @param dLatitude1_ThousandFEN
 * @param dLongitude1_ThousandFEN
 * @return
 */
public double mileEarthDisThousandFEN(int dLatitude_ThousandFEN, int dLongitude_ThousandFEN, int dLatitude1_ThousandFEN, int dLongitude1_ThousandFEN) {
    double dis;
    double dLatitude_DU = dLatitude_ThousandFEN * 1.00000000 / 60000;
    double dLongitude_DU = dLongitude_ThousandFEN * 1.00000000 / 60000;
    double dLatitude1_DU = dLatitude1_ThousandFEN * 1.00000000 / 60000;
    double dLongitude1_DU = dLongitude1_ThousandFEN * 1.00000000 / 60000;
    dis = mileEarthDis(dLatitude_DU, dLongitude_DU, dLatitude1_DU, dLongitude1_DU);
    return dis;
}

/**
 * 分的1000倍为单位 返回米 - 纬度1,经度1,纬度2,经度2
 * @param dLatitude_ThousandFEN
 * @param dLongitude_ThousandFEN
 * @param dLatitude1_ThousandFEN
 * @param dLongitude1_ThousandFEN
 * @return
 */
public double earthDisThousandFEN(int dLatitude_ThousandFEN, int dLongitude_ThousandFEN, int dLatitude1_ThousandFEN, int dLongitude1_ThousandFEN) {
    double dis;
    double dLatitude_DU = dLatitude_ThousandFEN * 1.00000000 / 60000;
    double dLongitude_DU = dLongitude_ThousandFEN * 1.00000000 / 60000;
    double dLatitude1_DU = dLatitude1_ThousandFEN * 1.00000000 / 60000;
    double dLongitude1_DU = dLongitude1_ThousandFEN * 1.00000000 / 60000;
    dis = earthDis(dLatitude_DU, dLongitude_DU, dLatitude1_DU, dLongitude1_DU);
    return dis;
}

/**
 * 两个角度差 输入值 0~360 ; 返回值 0~360; 
 * @param StationAngle_R
 * @param n_Course
 * @return
 */
public int getCourseDes(int StationAngle_R, int n_Course) {
    int Angle_R_des = 360;

    if (StationAngle_R >= 270 && n_Course <= 90) {
        Angle_R_des = n_Course + 360 - StationAngle_R;
    } else if (n_Course >= 270 && StationAngle_R <= 90) {
        Angle_R_des = StationAngle_R + 360 - n_Course;
    } else {
        Angle_R_des = (StationAngle_R > n_Course) ? (StationAngle_R - n_Course) : (n_Course - StationAngle_R);
    }

    return Angle_R_des;
}

/**
 * z 出发点, 坐标参考点; 1 目标点;
 * @param xz
 * @param yz
 * @param x1
 * @param y1
 * @return
 */
public int get2PtAngle(int xz, int yz, int x1, int y1) {
    int ndx = x1 - xz;
    int ndy = y1 - yz;
    double dAng = 0;
    int nAng = 0;

    if (ndy == 0 && ndx == 0) // 全0 不计算
    {
        return -1;
    } else if (ndy != 0 && ndx == 0) // x0 竖直
    {
        if (ndy > 0) {
            nAng = 0;
        } else {
            nAng = 180;
        }

    } else if (ndy == 0 && ndx != 0) // y0 水平
    {
        if (ndx > 0) {
            nAng = 90;
        } else {
            nAng = 270;
        }

    } else {
        dAng = Math.atan2((double) ndx, (double) ndy);

        nAng = (int) (dAng / PI * 180 + 0.5);

        if (nAng < 0) {
            nAng += 360;
        }
    }

    return nAng;
}

/**
 * 分的1000倍为单位 返回li米 - 纬度1,经度1,纬度2,经度2
 * @param dLatitude_ThousandFEN
 * @param dLongitude_ThousandFEN
 * @param dLatitude1_ThousandFEN
 * @param dLongitude1_ThousandFEN
 * @return
 */
public double earthDisThousandFEN100(int dLatitude_ThousandFEN, int dLongitude_ThousandFEN, int dLatitude1_ThousandFEN, int dLongitude1_ThousandFEN) {
    double dis;
    double dLatitude_DU = dLatitude_ThousandFEN * 1.00000000 / 60000;
    double dLongitude_DU = dLongitude_ThousandFEN * 1.00000000 / 60000;
    double dLatitude1_DU = dLatitude1_ThousandFEN * 1.00000000 / 60000;
    double dLongitude1_DU = dLongitude1_ThousandFEN * 1.00000000 / 60000;
    dis = earthDis(dLatitude_DU, dLongitude_DU, dLatitude1_DU, dLongitude1_DU);
    return dis * 100;
}

/**
 * 根据车辆GPS点位计算出来距离线路站点(第一站)上下行方向的距离大小,返回结果。
 * @param 线路id
 * @return 上行:0  下行:1 
 */
public Short getRunFlag(String clid) {
    Short fxFlag = null;
    // Redis获取车辆信息
    Map<String, String> clInfoMap = GetRedisPool.getHashAll(RedisPrefix.REDIS_PREFIX_BUSRUNINFO + clid);
    if (clInfoMap != null) {
        // 车辆信息对象生成
        YwClxx clInfo = BeanUtil.getMapBean(clInfoMap, YwClxx.class);
        // 经度(最近一条记录)
        int clJd = clInfo.getJd();
        // 纬度(最近一条记录)
        int clWd = clInfo.getWd();

        if (0 == clJd || 0 == clWd) {
            return fxFlag;
        }

        String xlid = clInfo.getYyxl();

        // 查询上行站点信息
        Set<byte[]> sxset = GetRedisPool
                .getSortedSetByte(RedisPrefix.REDIS_PREFIX_STATION + xlid + RedisPrefix.REDIS_PREFIX_LIMIT + RedisPrefix.REDIS_PREFIX_UP, 1);
        Set<byte[]> xxset = GetRedisPool
                .getSortedSetByte(RedisPrefix.REDIS_PREFIX_STATION + xlid + RedisPrefix.REDIS_PREFIX_LIMIT + RedisPrefix.REDIS_PREFIX_DOWN, 1);
        List<byte[]> sxlist = new ArrayList(sxset);
        List<byte[]> xxlist = new ArrayList(xxset);
        JcZd sxjcZd = (JcZd) SerializeUtil.unserizlize(sxlist.get(0));
        JcZd xxjcZd = (JcZd) SerializeUtil.unserizlize(xxlist.get(0));

        // 经度(上行)
        long sxJd = sxjcZd.getZwjd().longValue();
        // 纬度(上行)
        long sxWd = sxjcZd.getZwwd().longValue();

        // 经度(下行)
        long xxJd = xxjcZd.getZwjd().longValue();
        // 纬度(下行)
        long xxWd = xxjcZd.getZwwd().longValue();

        // 取得车辆位置和第一站点之间的距离
        double sxRange = earthDisFEN(clWd / 10000.00, clJd / 10000.00, sxWd / 10000.00, sxJd / 10000.00);
        double xxRange = earthDisFEN(clWd / 10000.00, clJd / 10000.00, xxWd / 10000.00, xxJd / 10000.00);

        if (sxRange < xxRange) {
            fxFlag = 0;
        } else {
            fxFlag = 1;
        }
    }

    return fxFlag;
}

/**
 * 根据车辆GPS点位计算出来距离线路站点(第一站)上下行方向的距离大小,返回结果。
 * @param 线路id
 * @return 上行:0  下行:1 
 */
public double getGPSRunDis(String clid, String xlid, Byte yxfx, long clJd, long clWd) {
    // 方向
    String direction = yxfx == 1 ? RedisPrefix.REDIS_PREFIX_DOWN : RedisPrefix.REDIS_PREFIX_UP;
    // 查询上行站点信息
    Set<byte[]> zdset = GetRedisPool.getSortedSetByte(RedisPrefix.REDIS_PREFIX_STATION + xlid + RedisPrefix.REDIS_PREFIX_LIMIT + direction, 1);
    List<byte[]> zdlist = new ArrayList(zdset);
    JcZd jcZd = (JcZd) SerializeUtil.unserizlize(zdlist.get(0));

    // 经度(上行)
    long jd = jcZd.getZwjd().longValue();
    // 纬度(上行)
    long wd = jcZd.getZwwd().longValue();

    // 取得车辆位置和第一站点之间的距离
    return earthDisFEN(clWd / 10000.00, clJd / 10000.00, wd / 10000.00, jd / 10000.00);
}

}

官场书屋二维码

小额赞赏

000
评论