Skip to content

Commit

Permalink
Added capabilities for v2.2.0.
Browse files Browse the repository at this point in the history
  • Loading branch information
hakenmt committed Feb 2, 2021
1 parent fc98917 commit 7ea56e3
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 12 deletions.
17 changes: 17 additions & 0 deletions GeoJSON.Tests/GeoJsonUnitTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,29 @@ public void FeatureTestNumberId()
public void FeatureOutOfRangeTest()
{
// ARRANGE
GeoJsonConfig.EnforcePositionValidation();
string content = File.ReadAllText("feature_out_of_range.json").Replace("\r", "").Replace("\n", "").Replace("\t", "").Replace(" ", "");

// ACT & ASSERT
Assert.Throws<ArgumentOutOfRangeException>(() => JsonConvert.DeserializeObject<Feature>(content));
}

[Fact]
public void FeatureOutOfRangeTestIgnoreValidation()
{
// ARRANGE
GeoJsonConfig.IgnorePositionValidation();
string content = File.ReadAllText("feature_out_of_range.json").Replace("\r", "").Replace("\n", "").Replace("\t", "").Replace(" ", "");

// ACT
Feature geo = JsonConvert.DeserializeObject<Feature>(content);
string content2 = JsonConvert.SerializeObject(geo);
Feature geo2 = JsonConvert.DeserializeObject<Feature>(content2);

// ASSERT
Assert.True(geo.Equals(geo2));
}

[Fact]
public void FeatureTestNullGeometry()
{
Expand Down
90 changes: 90 additions & 0 deletions GeoJSON/GeoJsonConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace BAMCIS.GeoJSON
{
/// <summary>
/// Provides global configuration options for GeoJson serialization and
/// deserialization
/// </summary>
public static class GeoJsonConfig
{
#region Private Fields

private static volatile object sync = new object();

private static bool _ignoreLongitudeValidation;
private static bool _ignoreLatitudeValidation;

#endregion

/// <summary>
/// Set to true to ignore the validation applied to longitude
/// coordinates in Position objects
/// </summary>
public static bool IgnoreLongitudeValidation {
get
{
return _ignoreLongitudeValidation;
}
set
{
lock (sync)
{
_ignoreLongitudeValidation = value;
}
}
}

/// <summary>
/// Set to true to ignore the validation applied to latitude
/// coordinates in Position objects
/// </summary>
public static bool IgnoreLatitudeValidation {
get
{
return _ignoreLatitudeValidation;
}
set
{
lock (sync)
{
_ignoreLatitudeValidation = value;
}
}
}

static GeoJsonConfig()
{
IgnoreLongitudeValidation = false;
IgnoreLatitudeValidation = false;
}

/// <summary>
/// Convenience method for ignoring both latitude and longitude
/// validation in Position objects, this operation is thread safe.
/// </summary>
public static void IgnorePositionValidation()
{
lock (sync)
{
IgnoreLatitudeValidation = true;
IgnoreLongitudeValidation = true;
}
}

/// <summary>
/// Convenience method for enforcing both latitude and longitude
/// validation in Position objects, this operation is thread safe.
/// </summary>
public static void EnforcePositionValidation()
{
lock (sync)
{
IgnoreLatitudeValidation = false;
IgnoreLongitudeValidation = false;
}
}
}
}
18 changes: 13 additions & 5 deletions GeoJSON/Position.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ public class Position : IEquatable<Position>, IEqualityComparer<Position>
#region Public Properties

/// <summary>
/// The position's longitude or easting
/// The position's longitude or easting, valid values of
/// -180 to 180. Set IgnorePositionValidation in the GeoJsonConfig
/// class to ignore
/// </summary>
[JsonProperty(PropertyName = "longitude")]
public double Longitude { get; }
Expand Down Expand Up @@ -64,14 +66,20 @@ public Position(double longitude, double latitude, double elevation)
throw new ArgumentOutOfRangeException("longitude", "The longitude cannot be NaN or infinity.");
}

if (longitude < -180 || longitude > 180)
if (!GeoJsonConfig.IgnoreLongitudeValidation)
{
throw new ArgumentOutOfRangeException("longitude", "Longitude must be between -180 and 180 degrees, inclusive.");
if (longitude < -180 || longitude > 180)
{
throw new ArgumentOutOfRangeException("longitude", "Longitude must be between -180 and 180 degrees, inclusive.");
}
}

if (latitude < -90 || latitude > 90)
if (!GeoJsonConfig.IgnoreLatitudeValidation)
{
throw new ArgumentOutOfRangeException("latitude", "Latitude must be between -90 and 90 degrees, inclusive.");
if (latitude < -90 || latitude > 90)
{
throw new ArgumentOutOfRangeException("latitude", "Latitude must be between -90 and 90 degrees, inclusive.");
}
}

if (double.IsInfinity(elevation))
Expand Down
44 changes: 37 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ An implementation of GeoJSON written in .NET Core 2.0. The library complies with
* [Example 2](#example-2)
* [Example 3](#example-3)
* [Usage Notes](#usage-notes)
* [Global Configuration](#global-configuration)
- [Revision History](#revision-history)


Expand Down Expand Up @@ -79,18 +80,47 @@ string json = JsonConvert.Serialize(mp);

### Usage Notes

Each of the 9 GeoJSON types: **Feature**, **FeatureCollection**, **GeometryCollection**, **LineString**, **MultiLineString**, **MultiPoint**, **MultiPolygon**,
**Point**, and **Polygon** all have convenience methods ToJson() and FromJson() to make serialization and deserialization easy.
Each of the 9 GeoJSON types: **Feature**, **FeatureCollection**, **GeometryCollection**, **LineString**, **MultiLineString**, **MultiPoint**, **MultiPolygon**, **Point**, and **Polygon** all have convenience methods ToJson() and FromJson() to make serialization and deserialization easy.

There are two additional types that can be used. A **LinearRing** is a LineString that is connected as the start and end and forms
the basis of a polygon. You can also use the abstract **Geometry** class that encompasses LineString, MultiLineString, MultiPoint, MultiPolygon,
Point, and Polygon.
There are two additional types that can be used. A **LinearRing** is a LineString that is connected as the start and end and forms the basis of a polygon. You can also use the abstract **Geometry** class that encompasses LineString, MultiLineString, MultiPoint, MultiPolygon, Point, and Polygon.

The Feature **'Properties'** property implements an `IDictionary<string, dynamic>` in order to accomodate any type of property structure that may
be sent.
The Feature **'Properties'** property implements an `IDictionary<string, dynamic>` in order to accomodate any type of property structure that may be sent.

### Global Configuration

This library provides a global configuration class, `GeoJsonConfig`. Currently, the config offers a way to ignore the validation of latitude and longitude coordinates. For example, given this input:

```json
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [ 200.0, 65000.5 ]
},
"properties": {
"prop0": "value0"
}
}
```

We would expect this operation to throw an `ArgumentOutOfRangeException` due to the coordinate values.

```csharp
Feature geo = JsonConvert.DeserializeObject<Feature>(content);
```

To ignore the validation, do this:

```csharp
GeoJsonConfig.IgnorePositionValidation();
Feature geo = JsonConvert.DeserializeObject<Feature>(content);
```

## Revision History

### 2.2.0
Added an Id property to in `Feature`. Also added a global config object that can be used to ignore validation of coordinate values.

### 2.1.1
Added validation for latitude and longitude values in `Position`.

Expand Down

0 comments on commit 7ea56e3

Please sign in to comment.