-
Notifications
You must be signed in to change notification settings - Fork 477
/
Position.cs
161 lines (147 loc) · 5.52 KB
/
Position.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace Microsoft.Azure.Cosmos.Spatial
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Runtime.Serialization;
using Converters;
using Newtonsoft.Json;
/// <summary>
/// <para>
/// A position is represented by an array of numbers in the Azure Cosmos DB service. There must be at least two elements, and may be more.
/// </para>
/// <para>
/// The order of elements must follow longitude, latitude, altitude.
/// Any number of additional elements are allowed - interpretation and meaning of additional elements is up to the application.
/// </para>
/// </summary>
[DataContract]
[JsonConverter(typeof(PositionJsonConverter))]
public sealed class Position : IEquatable<Position>
{
/// <summary>
/// Initializes a new instance of the <see cref="Position"/> class in the Azure Cosmos DB service.
/// </summary>
/// <param name="longitude">
/// Longitude value.
/// </param>
/// <param name="latitude">
/// Latitude value.
/// </param>
public Position(double longitude, double latitude)
: this(longitude, latitude, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Position"/> class in the Azure Cosmos DB service.
/// </summary>
/// <param name="longitude">
/// Longitude value.
/// </param>
/// <param name="latitude">
/// Latitude value.
/// </param>
/// <param name="altitude">
/// Optional altitude value.
/// </param>
public Position(double longitude, double latitude, double? altitude)
{
if (altitude != null)
{
this.Coordinates = new ReadOnlyCollection<double>(new[] { longitude, latitude, altitude.Value });
}
else
{
this.Coordinates = new ReadOnlyCollection<double>(new[] { longitude, latitude });
}
}
/// <summary>
/// Initializes a new instance of the <see cref="Position"/> class in the Azure Cosmos DB service.
/// </summary>
/// <param name="coordinates">
/// Position values.
/// </param>
public Position(IList<double> coordinates)
{
if (coordinates.Count < 2)
{
throw new ArgumentException("coordinates");
}
this.Coordinates = new ReadOnlyCollection<double>(coordinates);
}
/// <summary>
/// Gets position coordinates in the Azure Cosmos DB service.
/// </summary>
/// <value>
/// Coordinate values.
/// </value>
[DataMember(Name = "Coordinates")]
public ReadOnlyCollection<double> Coordinates { get; private set; }
/// <summary>
/// Gets longitude in the Azure Cosmos DB service.
/// </summary>
/// <value>
/// Longitude value.
/// </value>
public double Longitude => this.Coordinates[0];
/// <summary>
/// Gets latitude in the Azure Cosmos DB service.
/// </summary>
/// <value>
/// Latitude value.
/// </value>
public double Latitude => this.Coordinates[1];
/// <summary>
/// Gets optional altitude in the Azure Cosmos DB service.
/// </summary>
/// <value>
/// Altitude value.
/// </value>
public double? Altitude => this.Coordinates.Count > 2 ? (double?)this.Coordinates[2] : null;
/// <summary>
/// Determines whether the specified <see cref="Position"/> is equal to the current <see cref="Position"/> in the Azure Cosmos DB service.
/// </summary>
/// <returns>
/// true if the specified <see cref="Position"/> is equal to the current object; otherwise, false.
/// </returns>
/// <param name="obj">The <see cref="Position"/> to compare to the current object. </param>
public override bool Equals(object obj)
{
return this.Equals(obj as Position);
}
/// <summary>
/// Serves as a hash function for the <see cref="Position" /> type in the Azure Cosmos DB service.
/// </summary>
/// <returns>
/// A hash code for the current <see cref="Position"/>.
/// </returns>
public override int GetHashCode()
{
unchecked
{
return this.Coordinates.Aggregate(0, (current, value) => (current * 397) ^ value.GetHashCode());
}
}
/// <summary>
/// Determines if this <see cref="Position"/> is equal to the <paramref name="other" /> in the Azure Cosmos DB service.
/// </summary>
/// <param name="other"><see cref="Position"/> to compare to this <see cref="Position"/>.</param>
/// <returns><c>true</c> if objects are equal. <c>false</c> otherwise.</returns>
public bool Equals(Position other)
{
if (object.ReferenceEquals(null, other))
{
return false;
}
if (object.ReferenceEquals(this, other))
{
return true;
}
return this.Coordinates.SequenceEqual(other.Coordinates);
}
}
}