-
-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathLineString.cs
More file actions
171 lines (151 loc) · 5.53 KB
/
LineString.cs
File metadata and controls
171 lines (151 loc) · 5.53 KB
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
162
163
164
165
166
167
168
169
170
171
// Copyright © Joerg Battermann 2014, Matt Hunt 2017
using GeoJSON.Text.Converters;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text.Json.Serialization;
namespace GeoJSON.Text.Geometry
{
/// <summary>
/// Defines the LineString type.
/// </summary>
/// <remarks>
/// See https://tools.ietf.org/html/rfc7946#section-3.1.4
/// </remarks>
public class LineString : GeoJSONObject, IGeometryObject, IEqualityComparer<LineString>, IEquatable<LineString>
{
public LineString()
{
}
/// <summary>
/// Initializes a new <see cref="LineString" /> from a 2-d array of <see cref="double" />s
/// that matches the "coordinates" field in the JSON representation.
/// </summary>
//[JsonConstructor]
public LineString(IEnumerable<IEnumerable<double>> coordinates)
: this(coordinates?.Select(latLongAlt => (IPosition)latLongAlt.ToPosition())
?? throw new ArgumentNullException(nameof(coordinates)))
{
}
/// <summary>
/// Initializes a new instance of the <see cref="LineString" /> class.
/// </summary>
/// <param name="coordinates">The coordinates.</param>
public LineString(IEnumerable<IPosition> coordinates)
{
Coordinates = new ReadOnlyCollection<IPosition>(
coordinates?.ToArray() ?? throw new ArgumentNullException(nameof(coordinates)));
if (Coordinates.Count < 2)
{
throw new ArgumentOutOfRangeException(
nameof(coordinates),
"According to the GeoJSON v1.0 spec a LineString must have at least two or more positions.");
}
}
[JsonPropertyName("type")]
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override GeoJSONObjectType Type => GeoJSONObjectType.LineString;
/// <summary>
/// The positions of the line string.
/// </summary>
[JsonPropertyName("coordinates")]
[JsonConverter(typeof(PositionEnumerableConverter))]
public ReadOnlyCollection<IPosition> Coordinates { get; set; }
/// <summary>
/// Determines whether this instance has its first and last coordinate at the same position and thereby is closed.
/// </summary>
/// <returns>
/// <c>true</c> if this instance is closed; otherwise, <c>false</c>.
/// </returns>
public bool IsClosed()
{
var firstCoordinate = Coordinates[0];
var lastCoordinate = Coordinates[Coordinates.Count - 1];
return firstCoordinate.Longitude.Equals(lastCoordinate.Longitude)
&& firstCoordinate.Latitude.Equals(lastCoordinate.Latitude)
&& Nullable.Equals(firstCoordinate.Altitude, lastCoordinate.Altitude);
}
/// <summary>
/// Determines whether this LineString is a LinearRing.
/// </summary>
/// <remarks>
/// See https://tools.ietf.org/html/rfc7946#section-3.1.1
/// </remarks>
/// <returns>
/// <c>true</c> if it is a linear ring; otherwise, <c>false</c>.
/// </returns>
public bool IsLinearRing()
{
return Coordinates.Count >= 4 && IsClosed();
}
#region IEqualityComparer, IEquatable
/// <summary>
/// Determines whether the specified object is equal to the current object
/// </summary>
public override bool Equals(object obj)
{
return Equals(this, obj as LineString);
}
/// <summary>
/// Determines whether the specified object is equal to the current object
/// </summary>
public bool Equals(LineString other)
{
return Equals(this, other);
}
/// <summary>
/// Determines whether the specified object instances are considered equal
/// </summary>
public bool Equals(LineString left, LineString right)
{
if (base.Equals(left, right))
{
return left.Coordinates.SequenceEqual(right.Coordinates);
}
return false;
}
/// <summary>
/// Determines whether the specified object instances are considered equal
/// </summary>
public static bool operator ==(LineString left, LineString right)
{
if (ReferenceEquals(left, right))
{
return true;
}
if (right is null)
{
return false;
}
return left != null && left.Equals(right);
}
/// <summary>
/// Determines whether the specified object instances are not considered equal
/// </summary>
public static bool operator !=(LineString left, LineString right)
{
return !(left == right);
}
/// <summary>
/// Returns the hash code for this instance
/// </summary>
public override int GetHashCode()
{
int hash = base.GetHashCode();
foreach (var item in Coordinates)
{
hash = (hash * 397) ^ item.GetHashCode();
}
return hash;
}
/// <summary>
/// Returns the hash code for the specified object
/// </summary>
public int GetHashCode(LineString other)
{
return other.GetHashCode();
}
#endregion
}
}