GPS以中心點為圓心,指定距離為半徑獲取隨機座標點
阿新 • • 發佈:2019-01-24
最近遇到需要獲取隨機座標的需求,就研究了一下,現在整理成C#和JAVA程式碼,方便有需要的人蔘考。主要功能是實現以指定的座標點為圓心,指定的距離為半徑,在圓內獲取一個隨機座標點。
主要功能:
1、獲取隨機座標點;
2、計算兩點間距離。
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;
}
}