Coordinates/CoordinateSharp/Coordinate.Assistant.cs
2019-12-09 14:46:34 +01:00

235 lines
7.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
namespace CoordinateSharp {
/// <summary>
/// Used for UTM/MGRS Conversions
/// </summary>
[Serializable]
internal class LatZones {
public static List<String> longZongLetters = new List<String>(new String[]{"C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T",
"U", "V", "W", "X"});
}
/// <summary>
/// Used for handling diagraph determination
/// </summary>
[Serializable]
internal class Digraphs {
private readonly List<Digraph> digraph1;
private readonly List<Digraph> digraph2;
private readonly String[] digraph1Array = { "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" };
private readonly String[] digraph2Array = { "V", "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V" };
public Digraphs() {
this.digraph1 = new List<Digraph>();
this.digraph2 = new List<Digraph>();
this.digraph1.Add(new Digraph() { Zone = 1, Letter = "A" });
this.digraph1.Add(new Digraph() { Zone = 2, Letter = "B" });
this.digraph1.Add(new Digraph() { Zone = 3, Letter = "C" });
this.digraph1.Add(new Digraph() { Zone = 4, Letter = "D" });
this.digraph1.Add(new Digraph() { Zone = 5, Letter = "E" });
this.digraph1.Add(new Digraph() { Zone = 6, Letter = "F" });
this.digraph1.Add(new Digraph() { Zone = 7, Letter = "G" });
this.digraph1.Add(new Digraph() { Zone = 8, Letter = "H" });
this.digraph1.Add(new Digraph() { Zone = 9, Letter = "J" });
this.digraph1.Add(new Digraph() { Zone = 10, Letter = "K" });
this.digraph1.Add(new Digraph() { Zone = 11, Letter = "L" });
this.digraph1.Add(new Digraph() { Zone = 12, Letter = "M" });
this.digraph1.Add(new Digraph() { Zone = 13, Letter = "N" });
this.digraph1.Add(new Digraph() { Zone = 14, Letter = "P" });
this.digraph1.Add(new Digraph() { Zone = 15, Letter = "Q" });
this.digraph1.Add(new Digraph() { Zone = 16, Letter = "R" });
this.digraph1.Add(new Digraph() { Zone = 17, Letter = "S" });
this.digraph1.Add(new Digraph() { Zone = 18, Letter = "T" });
this.digraph1.Add(new Digraph() { Zone = 19, Letter = "U" });
this.digraph1.Add(new Digraph() { Zone = 20, Letter = "V" });
this.digraph1.Add(new Digraph() { Zone = 21, Letter = "W" });
this.digraph1.Add(new Digraph() { Zone = 22, Letter = "X" });
this.digraph1.Add(new Digraph() { Zone = 23, Letter = "Y" });
this.digraph1.Add(new Digraph() { Zone = 24, Letter = "Z" });
this.digraph1.Add(new Digraph() { Zone = 1, Letter = "A" });
this.digraph2.Add(new Digraph() { Zone = 0, Letter = "V" });
this.digraph2.Add(new Digraph() { Zone = 1, Letter = "A" });
this.digraph2.Add(new Digraph() { Zone = 2, Letter = "B" });
this.digraph2.Add(new Digraph() { Zone = 3, Letter = "C" });
this.digraph2.Add(new Digraph() { Zone = 4, Letter = "D" });
this.digraph2.Add(new Digraph() { Zone = 5, Letter = "E" });
this.digraph2.Add(new Digraph() { Zone = 6, Letter = "F" });
this.digraph2.Add(new Digraph() { Zone = 7, Letter = "G" });
this.digraph2.Add(new Digraph() { Zone = 8, Letter = "H" });
this.digraph2.Add(new Digraph() { Zone = 9, Letter = "J" });
this.digraph2.Add(new Digraph() { Zone = 10, Letter = "K" });
this.digraph2.Add(new Digraph() { Zone = 11, Letter = "L" });
this.digraph2.Add(new Digraph() { Zone = 12, Letter = "M" });
this.digraph2.Add(new Digraph() { Zone = 13, Letter = "N" });
this.digraph2.Add(new Digraph() { Zone = 14, Letter = "P" });
this.digraph2.Add(new Digraph() { Zone = 15, Letter = "Q" });
this.digraph2.Add(new Digraph() { Zone = 16, Letter = "R" });
this.digraph2.Add(new Digraph() { Zone = 17, Letter = "S" });
this.digraph2.Add(new Digraph() { Zone = 18, Letter = "T" });
this.digraph2.Add(new Digraph() { Zone = 19, Letter = "U" });
this.digraph2.Add(new Digraph() { Zone = 20, Letter = "V" });
}
internal Int32 GetDigraph1Index(String letter) {
for (Int32 i = 0; i < this.digraph1Array.Length; i++) {
if (this.digraph1Array[i].Equals(letter)) {
return i + 1;
}
}
return -1;
}
internal Int32 GetDigraph2Index(String letter) {
for (Int32 i = 0; i < this.digraph2Array.Length; i++) {
if (this.digraph2Array[i].Equals(letter)) {
return i;
}
}
return -1;
}
internal String GetDigraph1(Int32 longZone, Double easting) {
Int32 a1 = longZone;
Double a2 = 8 * ((a1 - 1) % 3) + 1;
Double a3 = easting;
Double a4 = a2 + (Int32)(a3 / 100000) - 1;
return this.digraph1.Where(x => x.Zone == Math.Floor(a4)).FirstOrDefault().Letter;
}
internal String GetDigraph2(Int32 longZone, Double northing) {
Int32 a1 = longZone;
Double a2 = 1 + 5 * ((a1 - 1) % 2);
Double a3 = northing;
Double a4 = a2 + (Int32)(a3 / 100000);
a4 = (a2 + (Int32)(a3 / 100000.0)) % 20;
a4 = Math.Floor(a4);
if (a4 < 0) {
a4 += 19;
}
return this.digraph2.Where(x => x.Zone == Math.Floor(a4)).FirstOrDefault().Letter;
}
}
/// <summary>
/// Diagraph model
/// </summary>
[Serializable]
internal class Digraph {
public Int32 Zone { get; set; }
public String Letter { get; set; }
}
/// <summary>
/// Used for setting whether a coordinate part is latitudinal or longitudinal.
/// </summary>
[Serializable]
public enum CoordinateType {
/// <summary>
/// Latitude
/// </summary>
Lat,
/// <summary>
/// Longitude
/// </summary>
Long
}
/// <summary>
/// Used to set a coordinate part position.
/// </summary>
[Serializable]
public enum CoordinatesPosition : Int32 {
/// <summary>
/// North
/// </summary>
N,
/// <summary>
/// East
/// </summary>
E,
/// <summary>
/// South
/// </summary>
S,
/// <summary>
/// West
/// </summary>
W
}
/// <summary>
/// Coordinate type datum specification
/// </summary>
[Serializable]
[Flags]
public enum Coordinate_Datum {
/// <summary>
/// Lat Long GeoDetic
/// </summary>
LAT_LONG = 1,
/// <summary>
/// UTM and MGRS
/// </summary>
UTM_MGRS = 2,
/// <summary>
/// ECEF
/// </summary>
ECEF = 4,
}
/// <summary>
/// Cartesian Coordinate Type
/// </summary>
public enum CartesianType {
/// <summary>
/// Spherical Cartesian
/// </summary>
Cartesian,
/// <summary>
/// Earth Centered Earth Fixed
/// </summary>
ECEF,
}
/// <summary>
/// Used for easy read math functions
/// </summary>
[Serializable]
internal static class ModM {
public static Double Mod(Double x, Double y) => x - y * Math.Floor(x / y);
public static Double ModLon(Double x) => Mod(x + Math.PI, 2 * Math.PI) - Math.PI;
public static Double ModCrs(Double x) => Mod(x, 2 * Math.PI);
public static Double ModLat(Double x) => Mod(x + Math.PI / 2, 2 * Math.PI) - Math.PI / 2;
}
/// <summary>
/// Earth Shape for Calculations.
/// </summary>
[Serializable]
public enum Shape {
/// <summary>
/// Calculate as sphere (less accurate, more efficient).
/// </summary>
Sphere,
/// <summary>
/// Calculate as ellipsoid (more accurate, less efficient).
/// </summary>
Ellipsoid
}
}