Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
260 changes: 130 additions & 130 deletions src/ProjNet/CoordinateSystems/Projections/ProjectionsRegistry.cs
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
using ProjNet.CoordinateSystems.Transformations;
using System;
using System.Collections.Generic;

namespace ProjNet.CoordinateSystems.Projections
{
/// <summary>
/// Registry class for all known <see cref="MapProjection"/>s.
/// </summary>
public class ProjectionsRegistry
{
private static readonly Dictionary<string, Type> TypeRegistry = new Dictionary<string, Type>();
private static readonly Dictionary<string, Type> ConstructorRegistry = new Dictionary<string, Type>();

private static readonly object RegistryLock = new object();

/// <summary>
/// Static constructor
/// </summary>
static ProjectionsRegistry()
{
Register("mercator", typeof(Mercator));
Register("mercator_1sp", typeof(Mercator));
using ProjNet.CoordinateSystems.Transformations;
using System;
using System.Collections.Generic;
namespace ProjNet.CoordinateSystems.Projections
{
/// <summary>
/// Registry class for all known <see cref="MapProjection"/>s.
/// </summary>
public class ProjectionsRegistry
{
private static readonly Dictionary<string, Type> TypeRegistry = new Dictionary<string, Type>();
private static readonly Dictionary<string, Type> ConstructorRegistry = new Dictionary<string, Type>();
private static readonly object RegistryLock = new object();
/// <summary>
/// Static constructor
/// </summary>
static ProjectionsRegistry()
{
Register("mercator", typeof(Mercator));
Register("mercator_1sp", typeof(Mercator));
Register("mercator_2sp", typeof(Mercator));
Register("mercator_auxiliary_sphere", typeof(MercatorAuxiliarySphere));
Register("pseudo_mercator", typeof(PseudoMercator));
Register("popular_visualisation_pseudo_mercator", typeof(PseudoMercator));
Register("pseudo_mercator", typeof(PseudoMercator));
Register("popular_visualisation_pseudo_mercator", typeof(PseudoMercator));
Register("google_mercator", typeof(PseudoMercator));

Register("transverse_mercator", typeof(TransverseMercator));
Register("gauss_kruger", typeof(TransverseMercator));

Register("transverse_mercator", typeof(TransverseMercator));
Register("gauss_kruger", typeof(TransverseMercator));
Register("albers", typeof(AlbersProjection));
Register("albers_conic_equal_area", typeof(AlbersProjection));

Expand All @@ -39,66 +39,66 @@ static ProjectionsRegistry()

Register("lambert_conformal_conic", typeof(LambertConformalConic2SP));
Register("lambert_conformal_conic_2sp", typeof(LambertConformalConic2SP));
Register("lambert_conic_conformal_(2sp)", typeof(LambertConformalConic2SP));
Register("lambert_tangential_conformal_conic_projection", typeof(LambertConformalConic2SP));

Register("lambert_azimuthal_equal_area", typeof(LambertAzimuthalEqualAreaProjection));

Register("cassini_soldner", typeof(CassiniSoldnerProjection));
Register("hotine_oblique_mercator", typeof(HotineObliqueMercatorProjection));
Register("hotine_oblique_mercator_azimuth_center", typeof(HotineObliqueMercatorProjection));
Register("oblique_mercator", typeof(ObliqueMercatorProjection));
Register("oblique_stereographic", typeof(ObliqueStereographicProjection));
Register("orthographic", typeof(OrthographicProjection));
Register("polar_stereographic", typeof(PolarStereographicProjection));
}

/// <summary>
/// Method to register a new Map
/// </summary>
/// <param name="name"></param>
/// <param name="type"></param>
public static void Register(string name, Type type)
{
if (string.IsNullOrWhiteSpace(name))
throw new ArgumentNullException(nameof(name));

if (type == null)
throw new ArgumentNullException(nameof(type));

if (!typeof(MathTransform).IsAssignableFrom(type))
throw new ArgumentException("The provided type does not implement 'GeoAPI.CoordinateSystems.Transformations.IMathTransform'!", nameof(type));

var ci = CheckConstructor(type);
if (ci == null)
throw new ArgumentException("The provided type is lacking a suitable constructor", nameof(type));

string key = ProjectionNameToRegistryKey(name);
lock (RegistryLock)
{
if (TypeRegistry.ContainsKey(key))
{
var rt = TypeRegistry[key];
if (ReferenceEquals(type, rt))
return;
throw new ArgumentException("A different projection type has been registered with this name", "name");
}

TypeRegistry.Add(key, type);
ConstructorRegistry.Add(key, ci);
}
}

Register("lambert_conic_conformal_(2sp)", typeof(LambertConformalConic2SP));
Register("lambert_tangential_conformal_conic_projection", typeof(LambertConformalConic2SP));
Register("lambert_azimuthal_equal_area", typeof(LambertAzimuthalEqualAreaProjection));
Register("cassini_soldner", typeof(CassiniSoldnerProjection));
Register("hotine_oblique_mercator", typeof(HotineObliqueMercatorProjection));
Register("hotine_oblique_mercator_azimuth_center", typeof(HotineObliqueMercatorProjection));
Register("oblique_mercator", typeof(ObliqueMercatorProjection));
Register("oblique_stereographic", typeof(ObliqueStereographicProjection));
Register("orthographic", typeof(OrthographicProjection));
Register("polar_stereographic", typeof(PolarStereographicProjection));
}
/// <summary>
/// Method to register a new Map
/// </summary>
/// <param name="name"></param>
/// <param name="type"></param>
public static void Register(string name, Type type)
{
if (string.IsNullOrWhiteSpace(name))
throw new ArgumentNullException(nameof(name));
if (type == null)
throw new ArgumentNullException(nameof(type));
if (!typeof(MathTransform).IsAssignableFrom(type))
throw new ArgumentException("The provided type does not implement 'GeoAPI.CoordinateSystems.Transformations.IMathTransform'!", nameof(type));
var ci = CheckConstructor(type);
if (ci == null)
throw new ArgumentException("The provided type is lacking a suitable constructor", nameof(type));
string key = ProjectionNameToRegistryKey(name);
lock (RegistryLock)
{
if (TypeRegistry.ContainsKey(key))
{
var rt = TypeRegistry[key];
if (ReferenceEquals(type, rt))
return;
throw new ArgumentException("A different projection type has been registered with this name", "name");
}
TypeRegistry.Add(key, type);
ConstructorRegistry.Add(key, ci);
}
}
private static string ProjectionNameToRegistryKey(string name)
{
return name.ToLowerInvariant().Replace(' ', '_').Replace("-", "_");
}

}
/// <summary>
/// Register an alias for an existing Map.
/// </summary>
/// <param name="aliasName"></param>
/// <param name="existingName"></param>
/// <param name="existingName"></param>
public static void RegisterAlias(string aliasName, string existingName)
{
lock (RegistryLock)
Expand All @@ -110,52 +110,52 @@ public static void RegisterAlias(string aliasName, string existingName)

Register(aliasName, existingProjectionType);
}
}

private static Type CheckConstructor(Type type)
{
// find a constructor that accepts exactly one parameter that's an
// instance of List<ProjectionParameter>, and then return the exact
// parameter type so that we can create instances of this type with
// minimal copying in the future, when possible.
foreach (var c in type.GetConstructors())
{
var parameters = c.GetParameters();
if (parameters.Length == 1 && parameters[0].ParameterType.IsAssignableFrom(typeof(List<ProjectionParameter>)))
{
return parameters[0].ParameterType;
}
}

return null;
}

internal static MathTransform CreateProjection(string className, IEnumerable<ProjectionParameter> parameters)
{
string key = ProjectionNameToRegistryKey(className);

Type projectionType;
Type ci;

lock (RegistryLock)
{
if (!TypeRegistry.TryGetValue(key, out projectionType))
throw new NotSupportedException($"Projection {className} is not supported.");
ci = ConstructorRegistry[key];
}

if (!ci.IsInstanceOfType(parameters))
{
parameters = new List<ProjectionParameter>(parameters);
}

var res = (MapProjection)Activator.CreateInstance(projectionType, parameters);
if (!res.Name.Equals(className, StringComparison.InvariantCultureIgnoreCase))
{
res.Alias = res.Name;
res.Name = className;
}
return res;
}
}
}
}
private static Type CheckConstructor(Type type)
{
// find a constructor that accepts exactly one parameter that's an
// instance of List<ProjectionParameter>, and then return the exact
// parameter type so that we can create instances of this type with
// minimal copying in the future, when possible.
foreach (var c in type.GetConstructors())
{
var parameters = c.GetParameters();
if (parameters.Length == 1 && parameters[0].ParameterType.IsAssignableFrom(typeof(List<ProjectionParameter>)))
{
return parameters[0].ParameterType;
}
}
return null;
}
internal static MathTransform CreateProjection(string className, IEnumerable<ProjectionParameter> parameters)
{
string key = ProjectionNameToRegistryKey(className);
Type projectionType;
Type ci;
lock (RegistryLock)
{
if (!TypeRegistry.TryGetValue(key, out projectionType))
throw new NotSupportedException($"Projection {className} is not supported.");
ci = ConstructorRegistry[key];
}
if (!ci.IsInstanceOfType(parameters))
{
parameters = new List<ProjectionParameter>(parameters);
}
var res = (MapProjection)Activator.CreateInstance(projectionType, parameters);
if (!res.Name.Equals(className, StringComparison.InvariantCultureIgnoreCase))
{
res.Alias = res.Name;
res.Name = className;
}
return res;
}
}
}
48 changes: 48 additions & 0 deletions src/ProjNet/CoordinateSystems/Wkt2/Wkt2AbridgedTransformation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;

namespace ProjNet.CoordinateSystems.Wkt2
{
/// <summary>
/// Abridged transformation as used in WKT2 <c>BOUNDCRS</c>.
/// </summary>
[Serializable]
public sealed class Wkt2AbridgedTransformation
{
/// <summary>
/// Initializes a new instance.
/// </summary>
/// <param name="name">Transformation name.</param>
/// <param name="methodName">Transformation method name.</param>
public Wkt2AbridgedTransformation(string name, string methodName)
{
Name = name ?? throw new ArgumentNullException(nameof(name));
MethodName = methodName ?? throw new ArgumentNullException(nameof(methodName));
}

/// <summary>
/// Gets the transformation name.
/// </summary>
public string Name { get; }

/// <summary>
/// Gets the transformation method name.
/// </summary>
public string MethodName { get; }

/// <summary>
/// Gets the transformation parameters.
/// </summary>
public List<Wkt2Parameter> Parameters { get; } = new List<Wkt2Parameter>();

/// <summary>
/// Gets or sets the transformation identifier.
/// </summary>
public Wkt2Id Id { get; set; }

/// <summary>
/// Gets or sets an optional remark.
/// </summary>
public string Remark { get; set; }
}
}
47 changes: 47 additions & 0 deletions src/ProjNet/CoordinateSystems/Wkt2/Wkt2Axis.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;

namespace ProjNet.CoordinateSystems.Wkt2
{
/// <summary>
/// Axis element as used in WKT2.
/// </summary>
[Serializable]
public sealed class Wkt2Axis
{
/// <summary>
/// Initializes a new instance.
/// </summary>
/// <param name="name">Axis name.</param>
/// <param name="direction">Axis direction (e.g. <c>north</c>, <c>east</c>).</param>
public Wkt2Axis(string name, string direction)
{
Name = name ?? throw new ArgumentNullException(nameof(name));
Direction = direction ?? throw new ArgumentNullException(nameof(direction));
}

/// <summary>
/// Gets the axis name.
/// </summary>
public string Name { get; }

/// <summary>
/// Gets the axis direction.
/// </summary>
public string Direction { get; }

/// <summary>
/// Gets or sets the axis order.
/// </summary>
public int? Order { get; set; }

/// <summary>
/// Gets or sets an optional axis unit.
/// </summary>
public Wkt2Unit Unit { get; set; }

/// <summary>
/// Gets or sets an optional identifier.
/// </summary>
public Wkt2Id Id { get; set; }
}
}
Loading