/// <summary> /// Gets the standard zone. /// </summary> /// <param name="lat">latitude (degrees).</param> /// <param name="lon">longitude (degrees).</param> /// <param name="setzone"> /// zone override (optional). If omitted, use the standard rules for picking the zone. /// If setzone is given then use that zone if it is non-negative, otherwise apply the rules given in <see cref="ZoneSpec"/>. /// </param> /// <returns></returns> /// <remarks> /// This is exact. /// </remarks> public static int StandardZone(double lat, double lon, int setzone = (int)ZoneSpec.Standard) { if (!(setzone >= (int)ZoneSpec.MinPseudoZone && setzone <= (int)ZoneSpec.MaxZone)) { throw new GeographicException($"Illegal zone requested {setzone}"); } if (setzone >= (int)ZoneSpec.MinZone || setzone == (int)ZoneSpec.Invalid) { return(setzone); } if (double.IsNaN(lat) || double.IsNaN(lon)) // Check if lat or lon is a NaN { return((int)ZoneSpec.Invalid); } if (setzone == (int)ZoneSpec.UTM || (lat >= -80 && lat < 84)) { int ilon = (int)Floor(AngNormalize(lon)); if (ilon == 180) { ilon = -180; // ilon now in [-180,180) } int zone = (ilon + 186) / 6; int band = MGRS.LatitudeBand(lat); if (band == 7 && zone == 31 && ilon >= 3) // The Norway exception { zone = 32; } else if (band == 9 && ilon >= 0 && ilon < 42) // The Svalbard exception { zone = 2 * ((ilon + 183) / 12) + 1; } return(zone); } else { return((int)ZoneSpec.UPS); } }