/// <summary> /// Convert a position in space to a latitude and longitude. /// </summary> /// <param name="relativeToOrigin">A position marking the latitude and longitude of (0,0).</param> /// <param name="location">The position to convert to latitude and longitude.</param> /// <returns>A position indicating the latitude and longitude of the location.</returns> public static Position MetersToLatLon(Position relativeToOrigin, Vector3 location) { var phi = Units.DegreesToRadians(relativeToOrigin.Latitude); var locationX = location.X / Math.Cos(phi); var locationY = location.Y / Math.Cos(phi); var lon = XToLon(locationX) + relativeToOrigin.Longitude; var lat = YToLat(locationY) + relativeToOrigin.Latitude; return(new Position(lat, lon)); }
/// <summary> /// Convert Latitude and Longitude to meters relative to a base position. /// </summary> /// <param name="relativeToOrigin">A position marking the latitude and longitude of (0,0)</param> /// <param name="lat">The latitude in degrees</param> /// <param name="lon">The longitude in degrees</param> /// <returns>A Vector3 in meters specifying the offset from the origin for this location.</returns> public static Vector3 LatLonToMeters(Position relativeToOrigin, double lat, double lon) { var originX = LonToX(relativeToOrigin.Longitude); var originY = LatToY(relativeToOrigin.Latitude); var phi = Units.DegreesToRadians(relativeToOrigin.Latitude); var x = (LonToX(lon) - originX) * Math.Cos(phi); var y = (LatToY(lat) - originY) * Math.Cos(phi); return(new Vector3(x, y)); }
/// <summary> /// Get the y coordinate, in the Mercator projection, of the specified latitude. /// The units will be in meters at the equator, and distorted elsewhere. Utilize LatLonToMeters() for a conversion /// relative to a basepoint. /// </summary> /// <param name="lat">The latitude to convert, within the range [-89.5, 89.5]. Values outside this range will be clamped.</param> /// <returns></returns> public static double LatToY(double lat) { lat = Math.Min(89.5, Math.Max(lat, -89.5)); double phi = Units.DegreesToRadians(lat); double sinphi = Math.Sin(phi); double con = ECCENT * sinphi; con = Math.Pow(((1.0 - con) / (1.0 + con)), COM); double ts = Math.Tan(0.5 * ((Math.PI * 0.5) - phi)) / con; return(0 - R_MAJOR * Math.Log(ts)); }
/// <summary> /// Get the tile size, in meters. /// </summary> /// <param name="lat">The latitude of the tile, in degrees.</param> /// <param name="zoom">The zoom level of the tile.</param> public static double GetTileSizeMeters(double lat, int zoom) { // Circumference of the earth * cos(latitude) divided by 2^zoom return((2 * Math.PI * EARTH_RADIUS * Math.Cos(Units.DegreesToRadians(lat))) / Math.Pow(2, zoom)); }
/// <summary> /// Get the x coordinate, in the Mercator projection, of the specified longitude. /// The units will be in meters at the equator, and distorted elsewhere. Utilize LatLonToMeters() for a conversion /// relative to a basepoint. /// </summary> /// <param name="lon"></param> /// <returns></returns> public static double LonToX(double lon) { return(R_MAJOR * Units.DegreesToRadians(lon)); }