/// <summary> /// Lookup the coordinate and compare it against all known section markers, /// returns the best fit section /// </summary> /// <param name="coordinate"></param> /// <returns></returns> public static DlsSystem?FromLatLongCoordinate(LatLongCoordinate coordinate) { // This method estimates a township that is close to the coordinate. if (!TryInferTownshipForLatLongCoordinate(coordinate, out byte meridian, out byte range, out byte township)) { return(null); } //get all markers in township var markers = DlsSurveyCoordinateProvider.Instance.TownshipMarkers(township, range, meridian); if (markers == null) { return(null); } //each township is numbered as: there are a max of 4 markers per section with 2 floats = 144 coordinates // some markers are empty (that section does not exist) // 31|32|33|34|35|36 // 30|29|28|27|26|25 // 19|20|21|22|23|24 // 18|17|16|15|14|13 // 07|08|09|10|11|12 // 06|05|04|03|02|01 double bestDistance = double.MaxValue; DlsSystem?bestDls = null; //test each section in the town for (byte section = 1; section <= 36; section++) { var dlsBoundary = markers[section - 1]; if (dlsBoundary == null || dlsBoundary.Count == 0) { continue; //invalid section } //find the center for each lsd in the section for (byte legalSubdivision = 1; legalSubdivision <= 16; legalSubdivision++) { double testDistance; switch (dlsBoundary.Count) { case 4: testDistance = coordinate.RelativeDistanceTo(Interpolate4Point(legalSubdivision, dlsBoundary)); break; default: testDistance = double.MaxValue; //should never get here break; } if (testDistance < bestDistance) { bestDistance = testDistance; bestDls = new DlsSystem(legalSubdivision, section, township, range, meridian); } } } return(bestDls); }
/// <summary> /// Return LatLongCoordinate that represents the center of the DlsSystem /// </summary> /// <param name="dls">The input dls location</param> /// <returns></returns> public static LatLongCoordinate ToLatLong(DlsSystem dls) { //ask the boundary provider for a list var dlsBoundary = DlsSurveyCoordinateProvider.Instance.BoundaryMarkers(dls.Section, dls.Township, dls.Range, dls.Meridian); if (dlsBoundary == null || dlsBoundary.Count == 0) { throw new CoordinateConversionException("Invalid dls location for conversion to lat long"); } LatLongCoordinate latLongCoordinate; switch (dlsBoundary.Count) { case 4: latLongCoordinate = Interpolate4Point(dls.LegalSubdivision, dlsBoundary); break; default: throw new CoordinateConversionException($"lookup returned {dlsBoundary.Count} points"); } return(latLongCoordinate); }