음... 살다보면 GPS가지고 할것이 많은데.. 다음 클래스는 해당 사이트에서 C# 버젼은로 컨버팅한것이다.
(Java도 잘되겠지...)
다음은 기능..
- 두 위치간의 거리
- 두위치간에 간격을 잘라서 위치를 생성하는 것
- 두위치간의 중간 위치를 얻는것
정도다.
public class MovableHelper
{
// Convert from : http://www.movable-type.co.uk/scripts/latlong.html
public static double toRadians(double degree)
{
return degree * Math.PI / 180.0;
}
public static double toDegrees(double radian)
{
return radian * 180.0 / Math.PI;
}
/// <summary>
/// Returns the distance from starting position to destination point (using haversine formula).
/// </summary>
/// <param name="startLat">Starting latitude</param>
/// <param name="startLon">Starting longitude</param>
/// <param name="endLat">Destination latitude</param>
/// <param name="endLon">Destination longitude</param>
/// <returns>Distance between starting point and destination point. The unit is meter.</returns>
public static double getDistance(double startLat, double startLon, double endLat, double endLon)
{
// starting example : 37.275340, 127.081525
// destination example : 37.276202, 127.074272
double R = 6371000.0; // metres
double theta1 = toRadians(startLat);
double theta2 = toRadians(endLat);
double deltatheta = toRadians(endLat - startLat);
double deltaramda = toRadians(endLon - startLon);
double a = Math.Sin(deltatheta / 2.0) * Math.Sin(deltatheta / 2.0) +
Math.Cos(theta1) * Math.Cos(theta2) *
Math.Sin(deltaramda / 2.0) * Math.Sin(deltaramda / 2.0);
double c = 2.0 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1.0 - a));
double d = R * c;
return d;
}
/// <summary>
/// Returns the point at given fraction between starting point and specified point.
/// </summary>
/// <param name="thisLat">Starting latitude</param>
/// <param name="thisLon">Starting longitude</param>
/// <param name="pointLat">Specified latitude</param>
/// <param name="pointLon">Specified longitude</param>
/// <param name="fraction">Fraction between the two points (0 = this point, 1 = specified point).</param>
/// <returns>Intermediate point between this point and destination point.</returns>
public static double[] intermediatePointTo(double thisLat, double thisLon,
double pointLat, double pointLon, double fraction)
{
double phi1 = toRadians(thisLat);
double ramda1 = toRadians(thisLon);
double phi2 = toRadians(pointLat);
double ramda2 = toRadians(pointLon);
double sinTheta1 = Math.Sin(phi1);
double cosTheta1 = Math.Cos(phi1);
double sinRamda1 = Math.Sin(ramda1);
double cosRamda1 = Math.Cos(ramda1);
double sinPhi2 = Math.Sin(phi2);
double cosPhi2 = Math.Cos(phi2);
double sinRamda2 = Math.Sin(ramda2);
double cosRamda2 = Math.Cos(ramda2);
// distance between points
double deltaPhi = phi2 - phi1;
double deltaRamda = ramda2 - ramda1;
double a = Math.Sin(deltaPhi / 2.0) * Math.Sin(deltaPhi / 2.0) + Math.Cos(phi1) *
Math.Cos(phi2) * Math.Sin(deltaRamda / 2.0) * Math.Sin(deltaRamda / 2.0);
double delta = 2.0 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1.0 - a));
double A = Math.Sin((1.0 - fraction) * delta) / Math.Sin(delta);
double B = Math.Sin(fraction * delta) / Math.Sin(delta);
double x = A * cosTheta1 * cosRamda1 + B * cosPhi2 * cosRamda2;
double y = A * cosTheta1 * sinRamda1 + B * cosPhi2 * sinRamda2;
double z = A * sinTheta1 + B * sinPhi2;
double theta3 = Math.Atan2(z, Math.Sqrt(x * x + y * y));
double ramda3 = Math.Atan2(y, x);
return new double[] { toDegrees(theta3), (toDegrees(ramda3) + 540.0) % 360.0 - 180.0 }; // normalise lon to −180..+180°
}
/// <summary>
/// Returns the midpoint between starting point and the supplied point.
/// Could be the same as intermediatePointTo() with fraction 0.5
/// </summary>
/// <param name="thisLat">Starting latitude</param>
/// <param name="thisLon">Starting longitude</param>
/// <param name="pointLat">Supplied latitude</param>
/// <param name="pointLon">Supplied longitude</param>
/// <returns>Midpoint between this point and the supplied point.</returns>
public static double[] midpointTo(double thisLat, double thisLon, double pointLat, double pointLon)
{
// φm = atan2( sinφ1 + sinφ2, √( (cosφ1 + cosφ2⋅cosΔλ) ⋅ (cosφ1 + cosφ2⋅cosΔλ) ) + cos²φ2⋅sin²Δλ )
// λm = λ1 + atan2(cosφ2⋅sinΔλ, cosφ1 + cosφ2⋅cosΔλ)
// see http://mathforum.org/library/drmath/view/51822.html for derivation
double phi1 = toRadians(thisLat);
double ramda1 = toRadians(thisLon);
double phi2 = toRadians(pointLat);
double deltaRamda = toRadians(pointLon - thisLon);
double Bx = Math.Cos(phi2) * Math.Cos(deltaRamda);
double By = Math.Cos(phi2) * Math.Sin(deltaRamda);
double x = Math.Sqrt((Math.Cos(phi1) + Bx) * (Math.Cos(phi1) + Bx) + By * By);
double y = Math.Sin(phi1) + Math.Sin(phi2);
double phi3 = Math.Atan2(y, x);
double ramda3 = ramda1 + Math.Atan2(By, Math.Cos(phi1) + Bx);
return new double[] { toDegrees(phi3), (toDegrees(ramda3) + 540.0) % 360.0 - 180.0 }; // normalise to −180..+180°
}
public static List<double[]> getintermediatePoints(double thisLat, double thisLon, double pointLat, double pointLon,
double movingDistance)
{
List<double[]> ret = new List<double[]>();
// 두지점간의 거리를 얻고 그것을 단위 거리로 나눈 갯수
double fraction = getDistance(thisLat, thisLon, pointLat, pointLon) / movingDistance;
// 나눈지점끼리의 위치를 얻는다.
double fr = (1.0 / fraction);
for (double i = 0.0; i < 1.0; i += fr)
{
double[] pos = intermediatePointTo(thisLat, thisLon, pointLat, pointLon, i);
ret.Add(pos);
}
double[] posLast = intermediatePointTo(thisLat, thisLon, pointLat, pointLon, 1);
ret.Add(posLast);
return ret;
}
/// <summary>
/// Get distance from the speed by a second
/// </summary>
/// <param name="speed">Vehicle speed in km/h unit.</param>
/// <returns>distance (the unit is meter.)</returns>
public static double getDistanceFromSpeedByASeconds(double speed)
{
return speed * 1000.0 / 3600.0;
}
}
'Programming' 카테고리의 다른 글
메쉬멜로 (Android 6)에서 퍼미션문제 간단 해결,,, (0) | 2016.11.01 |
---|---|
MongoDB C++ Driver Window 버젼 Compile 법 (0) | 2016.06.29 |
서버 프로그래밍 링크 (0) | 2016.01.19 |
Android Studio에 Dexguard 사용하기 (0) | 2015.07.29 |
SSL 채널을 통한 WCF 서비스(JSON RESTful Service) 방법 (0) | 2015.06.19 |