GPS以中心点为圆心,指定距离为半径获取随机坐标点

    最近遇到需要获取随机坐标的需求,就研究了一下,现在整理成C#和JAVA代码,方便有需要的人参考。主要功能是实现以指定的坐标点为圆心,指定的距离为半径,在圆内获取一个随机坐标点。

主要功能:

    1、获取随机坐标点;

    2、计算两点间距离。

算法参考了如下网站:http://www.geomidpoint.com/random/calculation.html,整理后的代码详见以下章节:


C#代码如下:

    /// <summary>
    /// GPS坐标
    /// </summary>
    public class GPSLocation
    {
        /// <summary>
        /// 纬度
        /// </summary>
        public double Latitude { get; set; }
        /// <summary>
        /// 经度
        /// </summary>
        public double Longitude { get; set; }
    }

    /// <summary>
    /// GPS工具类
    /// </summary>
    public class LocationUtils
    {
        const double EARTH_RADIUS = 6372.796924; // km
        const double PI = 3.1415926535898;

        /// <summary>
        /// 根据中心坐标获取指定距离的随机坐标点
        /// </summary>
        /// <param name="center">中心坐标</param>
        /// <param name="distance">离中心坐标距离(单位:米)</param>
        /// <returns></returns>
        public static GPSLocation GetRandomLocation(GPSLocation center, double distance = 50)
        {
            if (distance <= 0) distance = 50;
            double lat, lon, brg;
            distance = distance / 1000;
            GPSLocation location = new GPSLocation();
            double maxdist = distance;
            maxdist = maxdist / EARTH_RADIUS;
            double startlat = rad(center.Latitude);
            double startlon = rad(center.Longitude);
            var cosdif = Math.Cos(maxdist) - 1;
            var sinstartlat = Math.Sin(startlat);
            var cosstartlat = Math.Cos(startlat);
            double dist = 0;
            var rad360 = 2 * PI;
            dist = Math.Acos((new Random().NextDouble() * cosdif + 1));
            brg = rad360 * new Random().NextDouble();
            lat = Math.Asin(sinstartlat * Math.Cos(dist) + cosstartlat * Math.Sin(dist) * Math.Cos(brg));
            lon = deg(normalizeLongitude(startlon * 1 + Math.Atan2(Math.Sin(brg) * Math.Sin(dist) * cosstartlat, Math.Cos(dist) - sinstartlat * Math.Sin(lat))));
            lat = deg(lat);
            location.Latitude = padZeroRight(lat);
            location.Longitude = padZeroRight(lon);
            return location;
        }

        /// <summary>
        /// 获取两点间的距离(单位:米)
        /// </summary>
        /// <param name="start">起始坐标</param>
        /// <param name="end">结束坐标</param>
        /// <returns></returns>
        public static double GetDistance(GPSLocation start, GPSLocation end)
        {
            double radLat1 = rad(start.Latitude);
            double radLat2 = rad(end.Latitude);
            double a = radLat1 - radLat2;
            double b = rad(start.Longitude) - rad(end.Longitude);
            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 = (int)(s * 10000000) / 10000;
            return s;
        }

        /// <summary>
        /// 弧度
        /// </summary>
        /// <param name="d"></param>
        /// <returns></returns>
        static double rad(double d)
        {
            return d * PI / 180.0;
        }

        /// <summary>
        /// 角度
        /// </summary>
        /// <param name="rd"></param>
        /// <returns></returns>
        static double deg(double rd)
        {
            return (rd * 180 / Math.PI);
        }

        static double normalizeLongitude(double lon)
        {
            var n = PI;
            if (lon > n)
            {
                lon = lon - 2 * n;
            }
            else if (lon < -n)
            {
                lon = lon + 2 * n;
            }
            return lon;
        }

        static double padZeroRight(double s)
        {
            double sigDigits = 8;
            s = Math.Round(s * Math.Pow(10, sigDigits)) / Math.Pow(10, sigDigits);
            return s;
        }
    }

JAVA代码如下:

public class GPSLocation {
	private double latitude;
	private double longitude;

	public double getLatitude() {
		return latitude;
	}

	public void setLatitude(double latitude) {
		this.latitude = latitude;
	}

	public double getLongitude() {
		return longitude;
	}

	public void setLongitude(double longitude) {
		this.longitude = longitude;
	}
}

public class LocationUtils {
	static final double EARTH_RADIUS = 6372.796924;
	static final double PI = 3.1415926535898;

	/**
	 * 根据中心坐标获取指定距离的随机坐标点
	 * 
	 * @param center
	 *            中心坐标
	 * @param distance
	 *            离中心坐标距离(单位:米)
	 * @return 随机坐标
	 */
	public static GPSLocation GetRandomLocation(GPSLocation center, double distance) {
		if (distance <= 0) distance = 50;
		double lat, lon, brg;
		double dist = 0;
		double rad360 = 2 * PI;
		distance = distance / 1000;
		GPSLocation location = new GPSLocation();
		double maxdist = distance;
		maxdist = maxdist / EARTH_RADIUS;
		double startlat = rad(center.getLatitude());
		double startlon = rad(center.getLongitude());
		double cosdif = Math.cos(maxdist) - 1;
		double sinstartlat = Math.sin(startlat);
		double cosstartlat = Math.cos(startlat);
		dist = Math.acos((new Random().nextDouble() * cosdif + 1));
		brg = rad360 * new Random().nextDouble();
		lat = Math.asin(sinstartlat * Math.cos(dist) + cosstartlat * Math.sin(dist) * Math.cos(brg));
		lon = deg(normalizeLongitude(startlon * 1 + Math.atan2(Math.sin(brg) * Math.sin(dist) * cosstartlat, Math.cos(dist) - sinstartlat * Math.sin(lat))));
		lat = deg(lat);
		location.setLatitude(padZeroRight(lat));
		location.setLongitude(padZeroRight(lon));
		return location;
	}

	/**
	 * 获取两点间的距离(单位:米)
	 * 
	 * @param start
	 *            起始坐标
	 * @param end
	 *            结束坐标
	 * @return 距离
	 */
	public static double GetDistance(GPSLocation start, GPSLocation end) {
		double radLat1 = rad(start.getLatitude());
		double radLat2 = rad(end.getLatitude());
		double a = radLat1 - radLat2;
		double b = rad(start.getLongitude()) - rad(end.getLongitude());
		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 = (int) (s * 10000000) / 10000;
		return s;
	}

	/**
	 * 弧度
	 * 
	 * @param d
	 * @return
	 */
	static double rad(double d) {
		return d * PI / 180.0;
	}

	/**
	 * 角度
	 * 
	 * @param rd
	 * @return
	 */
	static double deg(double rd) {
		return (rd * 180 / Math.PI);
	}

	static double normalizeLongitude(double lon) {
		double n = PI;
		if (lon > n) {
			lon = lon - 2 * n;
		} else if (lon < -n) {
			lon = lon + 2 * n;
		}
		return lon;
	}

	static double padZeroRight(double s) {
		double sigDigits = 8;
		s = Math.round(s * Math.pow(10, sigDigits)) / Math.pow(10, sigDigits);
		return s;
	}
}


  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值