csharp-sdk-upm/Storage/Source/Public/AVGeoPoint.cs

108 lines
3.7 KiB
C#

using System;
using System.Collections.Generic;
using LeanCloud.Storage.Internal;
namespace LeanCloud
{
/// <summary>
/// AVGeoPoint represents a latitude / longitude point that may be associated
/// with a key in a AVObject or used as a reference point for geo queries.
/// This allows proximity-based queries on the key.
///
/// Only one key in a class may contain a GeoPoint.
/// </summary>
public struct AVGeoPoint : IJsonConvertible
{
/// <summary>
/// Constructs a AVGeoPoint with the specified latitude and longitude.
/// </summary>
/// <param name="latitude">The point's latitude.</param>
/// <param name="longitude">The point's longitude.</param>
public AVGeoPoint(double latitude, double longitude)
: this()
{
Latitude = latitude;
Longitude = longitude;
}
private double latitude;
/// <summary>
/// Gets or sets the latitude of the GeoPoint. Valid range is [-90, 90].
/// Extremes should not be used.
/// </summary>
public double Latitude
{
get
{
return latitude;
}
set
{
if (value > 90 || value < -90)
{
throw new ArgumentOutOfRangeException("value",
"Latitude must be within the range [-90, 90]");
}
latitude = value;
}
}
private double longitude;
/// <summary>
/// Gets or sets the longitude. Valid range is [-180, 180].
/// Extremes should not be used.
/// </summary>
public double Longitude
{
get
{
return longitude;
}
set
{
if (value > 180 || value < -180)
{
throw new ArgumentOutOfRangeException("value",
"Longitude must be within the range [-180, 180]");
}
longitude = value;
}
}
/// <summary>
/// Get the distance in radians between this point and another GeoPoint. This is the smallest angular
/// distance between the two points.
/// </summary>
/// <param name="point">GeoPoint describing the other point being measured against.</param>
/// <returns>The distance in between the two points.</returns>
public AVGeoDistance DistanceTo(AVGeoPoint point)
{
double d2r = Math.PI / 180; // radian conversion factor
double lat1rad = Latitude * d2r;
double long1rad = longitude * d2r;
double lat2rad = point.Latitude * d2r;
double long2rad = point.Longitude * d2r;
double deltaLat = lat1rad - lat2rad;
double deltaLong = long1rad - long2rad;
double sinDeltaLatDiv2 = Math.Sin(deltaLat / 2);
double sinDeltaLongDiv2 = Math.Sin(deltaLong / 2);
// Square of half the straight line chord distance between both points.
// [0.0, 1.0]
double a = sinDeltaLatDiv2 * sinDeltaLatDiv2 +
Math.Cos(lat1rad) * Math.Cos(lat2rad) * sinDeltaLongDiv2 * sinDeltaLongDiv2;
a = Math.Min(1.0, a);
return new AVGeoDistance(2 * Math.Asin(Math.Sqrt(a)));
}
IDictionary<string, object> IJsonConvertible.ToJSON()
{
return new Dictionary<string, object>
{
{ "__type", "GeoPoint" },
{ "latitude", Latitude },
{ "longitude", Longitude }
};
}
}
}