public void SurfaceRegionTest() { var value = new SurfaceRegion( "Test_ID", SurfaceRegion.SurfaceRegionIdItemTypeName, new Sphere <HugeNumber>(new HugeNumber(10)), "Test_Parent_ID", null); var json = JsonSerializer.Serialize(value); Console.WriteLine(); Console.WriteLine(json); var deserialized = JsonSerializer.Deserialize <SurfaceRegion>(json); Assert.AreEqual(value, deserialized); Assert.AreEqual(json, JsonSerializer.Serialize(deserialized)); value = new SurfaceRegion( "Test_ID", SurfaceRegion.SurfaceRegionIdItemTypeName, new Sphere <HugeNumber>(new HugeNumber(10)), "Test_Parent_ID", new Vector3 <HugeNumber>[] { Vector3 <HugeNumber> .Zero, Vector3 <HugeNumber> .UnitX }); json = JsonSerializer.Serialize(value); Console.WriteLine(); Console.WriteLine(json); deserialized = JsonSerializer.Deserialize <SurfaceRegion>(json); Assert.AreEqual(value, deserialized); Assert.AreEqual(json, JsonSerializer.Serialize(deserialized)); }
/// <summary> /// Calculates the latitude and longitude that correspond to a set of coordinates from a map /// projection. /// </summary> /// <param name="region">The region being mapped.</param> /// <param name="planet">The planet being mapped.</param> /// <param name="x"> /// The x coordinate of a point on a map projection, with zero as the westernmost point. /// </param> /// <param name="y"> /// The y coordinate of a point on a map projection, with zero as the northernmost point. /// </param> /// <param name="resolution">The vertical resolution of the projection.</param> /// <param name="equalArea"> /// If <see langword="true"/> the projection will be a cylindrical equal-area projection. /// Otherwise, an equirectangular projection will be used. /// </param> /// <returns> /// The latitude and longitude of the given coordinates, in radians. /// </returns> public static (double latitude, double longitude) GetLatLonFromLocalPosition( this SurfaceRegion region, Planetoid planet, int x, int y, int resolution, bool equalArea = false) => SurfaceMap.GetLatLonForMapProjection(
/// <summary> /// Calculates the approximate area of a point on a map projection with the given /// characteristics, by transforming the point and its nearest neighbors to latitude and /// longitude, calculating the midpoints between them, and calculating the area of the /// region enclosed within those midpoints. /// </summary> /// <param name="region">The mapped region.</param> /// <param name="planet">The mapped planet.</param> /// <param name="x">The x coordinate of a point on a map projection, with zero as the /// westernmost point.</param> /// <param name="y">The y coordinate of a point on a map projection, with zero as the /// northernmost point.</param> /// <param name="resolution">The vertical resolution of the projection.</param> /// <param name="options"> /// The map projection options used to generate the map used. /// </param> /// <returns>The area of the given point, in m².</returns> public static HugeNumber GetAreaOfLocalPoint( this SurfaceRegion region, Planetoid planet, int x, int y, int resolution, MapProjectionOptions options) => SurfaceMap.GetAreaOfPointFromRadiusSquared( planet.RadiusSquared, x, y, (int)Math.Floor(resolution * options.AspectRatio), resolution, region.GetProjection(planet, options.EqualArea));
/// <summary> /// Gets the elevation at the given <paramref name="latitude"/> and <paramref /// name="longitude"/>, in meters. /// </summary> /// <param name="region">The mapped region.</param> /// <param name="planet">The mapped planet.</param> /// <param name="elevationMap">An elevation map.</param> /// <param name="latitude">The latitude at which to determine elevation.</param> /// <param name="longitude">The longitude at which to determine elevation.</param> /// <param name="equalArea"> /// If <see langword="true"/> the projection is a cylindrical equal-area projection. /// Otherwise, an equirectangular projection will be used. /// </param> /// <returns> /// The elevation at the given <paramref name="latitude"/> and <paramref name="longitude"/>, /// in meters. Or <see cref="double.NaN"/> if the given <paramref name="latitude"/> and /// <paramref name="longitude"/> are not contained within this region. /// </returns> public static double GetElevationAt( this SurfaceRegion region, Planetoid planet, Image <L16> elevationMap, double latitude, double longitude, bool equalArea = false) => region.IsPositionWithin(planet, latitude, longitude) ? (elevationMap.GetValueFromImage( latitude, longitude, region.GetProjection(planet, equalArea), true) - planet.NormalizedSeaLevel) * planet.MaxElevation : double.NaN;
/// <summary> /// Gets the elevation at the given <paramref name="position"/>, in meters. /// </summary> /// <param name="region">The mapped region.</param> /// <param name="planet">The mapped planet.</param> /// <param name="elevationMap">An elevation map.</param> /// <param name="position">The position at which to determine elevation.</param> /// <param name="equalArea"> /// If <see langword="true"/> the projection is a cylindrical equal-area projection. /// Otherwise, an equirectangular projection will be used. /// </param> /// <returns> /// The elevation at the given <paramref name="position"/>, in meters. Or <see /// cref="double.NaN"/> if the given <paramref name="position"/> is not contained within /// this region. /// </returns> public static double GetElevationAt( this SurfaceRegion region, Planetoid planet, Image <L16> elevationMap, Vector3 position, bool equalArea = false) { var pos = region.PlanetaryPosition + position; return(region.GetElevationAt( planet, elevationMap, planet.VectorToLatitude(pos), planet.VectorToLongitude(pos), equalArea)); }
/// <summary> /// Determines whether the given <paramref name="moment"/> falls within the range indicated /// for a <paramref name="position"/> in a <paramref name="region"/>. /// </summary> /// <param name="region">The mapped region.</param> /// <param name="planet">The mapped planet.</param> /// <param name="position">A position relative to the center of <paramref /// name="region"/>.</param> /// <param name="ranges">A set of ranges.</param> /// <param name="moment">The time at which the determination is to be performed.</param> /// <param name="equalArea"> /// If <see langword="true"/> the projection will be a cylindrical equal-area projection. /// Otherwise, an equirectangular projection will be used. /// </param> /// <returns><see langword="true"/> if the given <paramref name="moment"/> falls within the /// range indicated for a <paramref name="position"/> in a <paramref name="region"/>; /// otherwise <see langword="false"/>.</returns> public static bool GetAnnualRangeIsPositiveAtTimeAndLocalPosition( this SurfaceRegion region, Planetoid planet, Vector3 position, FloatRange[,] ranges, Instant moment, bool equalArea = false) { var(x, y) = region.GetProjectionFromLocalPosition( planet, position, ranges.GetLength(0), ranges.GetLength(1), equalArea); return(planet.GetAnnualRangeIsPositiveAtTime(ranges[x, y], moment)); }
/// <summary> /// Gets the value for a <paramref name="position"/> in a <paramref name="region"/> at a /// given proportion of the year from a set of ranges. /// </summary> /// <param name="region">The mapped region.</param> /// <param name="planet">The mapped planet.</param> /// <param name="position">A position relative to the center of <paramref /// name="region"/>.</param> /// <param name="ranges">A set of ranges.</param> /// <param name="proportionOfYear"> /// The proportion of the year, starting and ending with midwinter, at which the calculation /// is to be performed. /// </param> /// <param name="equalArea"> /// If <see langword="true"/> the projection will be a cylindrical equal-area projection. /// Otherwise, an equirectangular projection will be used. /// </param> /// <returns>The value for a <paramref name="position"/> in a <paramref name="region"/> at a /// given proportion of the year from a set of ranges.</returns> public static float GetAnnualValueFromLocalPosition( this SurfaceRegion region, Planetoid planet, Vector3 position, FloatRange[,] ranges, float proportionOfYear, bool equalArea = false) { var(x, y) = region.GetProjectionFromLocalPosition( planet, position, ranges.GetLength(0), ranges.GetLength(1), equalArea); return(SurfaceMap.GetAnnualRangeValue( ranges[x, y], proportionOfYear)); }
/// <summary> /// Produces an elevation map projection of this region. /// </summary> /// <param name="region">The mapped region.</param> /// <param name="planet">The planet being mapped.</param> /// <param name="resolution">The vertical resolution of the projection.</param> /// <param name="equalArea"> /// If <see langword="true"/> the projection will be a cylindrical equal-area projection. /// Otherwise, an equirectangular projection will be used. /// </param> /// <returns> /// A projected map of elevation. Pixel luminosity indicates elevation relative to <see /// cref="Planetoid.MaxElevation"/>, with values below the midpoint indicating elevations /// below the mean surface. /// </returns> public static Image <L16> GetElevationMap( this SurfaceRegion region, Planetoid planet, int resolution, bool equalArea = false) => planet.GetElevationMap(resolution, region.GetProjection(planet, equalArea));