示例#1
0
    public WeatherMaps(
        BiomeType biome,
        BiomeType[][] biomeMap,
        ClimateType climate,
        ClimateType[][] climateMap,
        FloatRange[][] seaIceRangeMap)
    {
        XLength = biomeMap.Length;
        if (climateMap.Length != XLength ||
            seaIceRangeMap.Length != XLength)
        {
            throw new ArgumentException("All X lengths must be the same");
        }

        YLength = XLength == 0 ? 0 : biomeMap[0].Length;

        if (XLength != 0 &&
            (climateMap[0].Length != YLength ||
             seaIceRangeMap[0].Length != YLength))
        {
            throw new ArgumentException("All Y lengths must be the same");
        }

        Biome          = biome;
        BiomeMap       = biomeMap;
        Climate        = climate;
        ClimateMap     = climateMap;
        SeaIceRangeMap = seaIceRangeMap;
    }
        /// <summary>
        /// Download the climate file based on region and climate type
        /// </summary>
        /// <param name="region">Name of region to be downloaded</param>
        /// <param name="climateType">Climate type that needs to be downloaded</param>
        /// <returns>Download status</returns>
        public static bool Download(Region region, ClimateType climateType)
        {
            string URL          = getWebURL(region, climateType);
            bool   isDownloaded = false;
            string txtData      = String.Empty;

            try
            {
                using (var webClient = new WebClient())
                {
                    txtData = webClient.DownloadString(URL);
                }

                filename = FileDownloadHelper.getDBFileName(climateType, region);
                File.WriteAllText(filepath + filename, txtData);

                Log.Information($"{filename} got downloaded");
            }
            catch (Exception e)
            {
                Log.Error(e, " : error");
            }

            if (txtData != String.Empty)
            {
                isDownloaded = true;
            }

            return(isDownloaded);
        }
示例#3
0
    public static void spawnWater(Map map, System.Random randomGenerator)
    {
        CriticalResource water = CriticalResource.WATER;
        int waterHexesCount    = map.hexes.Count * water.totalPercent / 100;

        for (int i = 0; i < waterHexesCount; i++)
        {
            int         climateRoll   = randomGenerator.Next(100);
            ClimateType randomClimate = ClimateType.TEMPERATE;
            if (climateRoll < water.colderClimatePercent)
            {
                randomClimate = ClimateType.COOL;
            }
            else if (climateRoll >= water.colderClimatePercent + water.averageClimatePercent)
            {
                randomClimate = ClimateType.WARM;
            }

            List <Region> climateRegions = getRegionsByClimate(map, randomClimate);
            Region        randomRegion   = climateRegions[randomGenerator.Next(climateRegions.Count)];
            List <Hex>    regionHexes    = getRegionHexes(map, randomRegion.id);
            if (regionHexes.Count == 0)
            {
                continue;
            }
            List <Hex> possiblePlacementHexes = new List <Hex>();
            foreach (string priorityTag in water.priorityTags)
            {
                foreach (Hex hex in regionHexes)
                {
                    if (hex.hasTag(priorityTag) && !hex.hasTag(water.name))
                    {
                        possiblePlacementHexes.Add(hex);
                    }
                }
                if (possiblePlacementHexes.Count > 0)
                {
                    break;
                }
            }

            if (possiblePlacementHexes.Count == 0)
            {
                continue;
            }

            Hex randomHex = possiblePlacementHexes[randomGenerator.Next(possiblePlacementHexes.Count)];
            randomHex.addTag(water.name);
            randomHex.removeTag(water.adjacentHexName);
            List <Vector2> waterHexNeighbours = HexMathHelper.getHexNeighbours(new Vector2(randomHex.x, randomHex.y), 1);
            foreach (Vector2 waterHexNeighbourCoords in waterHexNeighbours)
            {
                Hex neighbourHex = getHex(waterHexNeighbourCoords.x, waterHexNeighbourCoords.y, map);
                if (neighbourHex != null && !neighbourHex.hasTag(water.name) && !neighbourHex.hasTag(water.adjacentHexName))
                {
                    neighbourHex.addTag(water.adjacentHexName);
                }
            }
        }
    }
示例#4
0
        /// <summary>
        /// Gets the part of URL based on the climate type.
        /// </summary>
        /// <param name="climateType">Enum type which contain climate tpyes are part of the project</param>
        /// <returns>URL part for the climate</returns>
        public static string getTypeURLPart(ClimateType climateType)
        {
            string climateTypeURLPart = "";

            if (climateType == ClimateType.max)
            {
                climateTypeURLPart = "Tmax";
            }
            else if (climateType == ClimateType.min)
            {
                climateTypeURLPart = "Tmin";
            }
            else if (climateType == ClimateType.mean)
            {
                climateTypeURLPart = "Tmean";
            }
            else if (climateType == ClimateType.rainfall)
            {
                climateTypeURLPart = "Rainfall";
            }
            else if (climateType == ClimateType.sunshine)
            {
                climateTypeURLPart = "Sunshine";
            }

            return(climateTypeURLPart);
        }
        /// <summary>
        /// Generate URL for MetOffice data based on region and climate type.
        /// </summary>
        /// <param name="region">Name of region to be downloaded</param>
        /// <param name="climateType">Climate type that needs to be downloaded</param>
        /// <returns>URL string of the data</returns>
        public static string getWebURL(Region region, ClimateType climateType)
        {
            string climateTypeURL = FileDownloadHelper.getTypeURLPart(climateType);
            string filename       = FileDownloadHelper.getSiteFileName(region);

            return(String.Concat(baseURL, "/" + climateTypeURL, "/date", "/" + filename));
        }
示例#6
0
 public ClimateMap(ClimateType cl_type, GraphicTile.TileLandTypes baseLand, bool hasTop = false, GraphicTile.TileLandTypes secondLand = GraphicTile.TileLandTypes.ASH)
 {
     climateType = cl_type;
     hasTopLayer = hasTop;
     baseLandType = baseLand;
     if (hasTopLayer)
     {
         secondLandType = secondLand;
     }
 }
示例#7
0
    public static void SetClimateType(ClimateType climate, RandomMapType mapType)
    {
        switch (climate)
        {
        case ClimateType.CT_Dry:
//                ClearChance = 80;
//                PartlyCloudyChance = 10;
//                MostlyCloudChance = 10;
//                SprinkleRainChance = 0;
            PeEnv.SetControlRain(NO_RAIN);
            break;

        case ClimateType.CT_Temperate:
//                ClearChance = 60;
//                PartlyCloudyChance = 14;
//                MostlyCloudChance = 12;
//				SprinkleRainChance = 8;
            PeEnv.SetControlRain(LESS_RAIN);
            break;

        case ClimateType.CT_Wet:
//                ClearChance = 60;
//                PartlyCloudyChance = 10;
//                MostlyCloudChance = 5;
//                SprinkleRainChance = 1;
            PeEnv.SetControlRain(FULL_RAIN);
            break;

        case ClimateType.CT_Random:
            switch ((int)Time.time % 3)
            {
            case 0:
                SetClimateType(ClimateType.CT_Dry, mapType);
                break;

            case 1:
                SetClimateType(ClimateType.CT_Temperate, mapType);
                break;

            case 2:
                SetClimateType(ClimateType.CT_Wet, mapType);
                break;
            }
            return;
        }

        if (mapType == RandomMapType.Desert)
        {
            PeEnv.SetControlRain(NO_RAIN);
        }

        WeatherConfig.climate         = climate;
        RandomMapConfig.ScenceClimate = WeatherConfig.climate;
    }
示例#8
0
    public string getClimateTag(ClimateType climateType)
    {
        switch (climateType)
        {
        case ClimateType.COOL: return("cool");

        case ClimateType.WARM: return("warm");

        case ClimateType.TEMPERATE:
        default: return("temperate");
        }
    }
示例#9
0
    public Color32 getColorByClimateType(ClimateType climateType)
    {
        switch (climateType)
        {
        case ClimateType.COOL: return(Color.blue);

        case ClimateType.WARM: return(Color.red);

        case ClimateType.TEMPERATE:
        default: return(Color.green);
        }
    }
示例#10
0
    public static List <Region> getRegionsByClimate(Map map, ClimateType climateType)
    {
        List <Region> regionsWithClimate = new List <Region>();

        foreach (Region region in map.regions)
        {
            if (region.climateType == climateType)
            {
                regionsWithClimate.Add(region);
            }
        }

        return(regionsWithClimate);
    }
    // Use this for initialization
    void Start()
    {
        int c = Mathf.FloorToInt(Random.Range(0, 4));                                                                               // Select a random climate.

        selectedClimate = climates[c];

        astroidCount = Random.Range(100, 500);

        if (Random.Range(0.0f, 1.0f) > 0.5f)
        {
            spawnAstroidBelt(astroidCount, 100, 140, gameObject.transform.position); shouldSpawnAstroids = true;
        }                                                                                                                           // Should we spawn an astroid belt? 50% chance.

        GenerateMeshL();                                                                                                            // Apply perlin noise to the sphere.

        ApplyColours();                                                                                                             // Give the sphere colours depending on climate.

        GenerateFoliage();                                                                                                          // Generate extras (trees, rocks, flowers, etc.)

        ApplyUI();
    }
示例#12
0
        public static string GetClimateTypeString(ClimateType climateType)
        {
            var stringLocalizer = (IStringLocalizer <Helper>)PrismApplicationBase.Current.Container.Resolve(typeof(IStringLocalizer <Helper>));

            switch (climateType)
            {
            case ClimateType.Cold:
                return(stringLocalizer.GetString("cold"));

            case ClimateType.TemperedSubtropical:
                return(stringLocalizer.GetString("tempered"));

            case ClimateType.Tropical:
                return(stringLocalizer.GetString("tropical"));

            case ClimateType.Hybrid:
                return(stringLocalizer.GetString("hybrid"));

            default:
                return("");
            }
        }
示例#13
0
        public void OnSetSelection()
        {
            if (!Manager.IsAwake <GUIManager>())
            {
                return;
            }
            switch (SubSelectionTabs.SelectedTab.ToLower())
            {
            case "arctic":
                SelectedClimate = ClimateType.Arctic;
                break;

            case "temperate":
            default:
                SelectedClimate = ClimateType.Temperate;
                break;

            case "tropical coast":
                SelectedClimate = ClimateType.TropicalCoast;
                break;

            case "desert":
                SelectedClimate = ClimateType.Desert;
                break;

            case "wetlands":
                SelectedClimate = ClimateType.Wetland;
                break;

            case "rainforest":
                SelectedClimate = ClimateType.Rainforest;
                break;
            }

            IEnumerable <Plant> plants = Plants.Get.KnownPlants(SelectedClimate, SelectedSeasonality, SelectedAboveGround, false).AsEnumerable();

            ReceiveFromParentEditor(plants);
        }
示例#14
0
    private void SetTerrainHeight(int terrainHeight, ClimateType scenceClimate)
    {
        if (terrainHeight < 256)
        {
            TerrainHeight             = 128;
            VFDataRTGen.s_noiseHeight = 128;
            VFDataRTGen.s_seaDepth    = 5;
        }
        else if (terrainHeight < 512)
        {
            TerrainHeight             = 256;
            VFDataRTGen.s_noiseHeight = 256;
            VFDataRTGen.s_seaDepth    = 5;
        }
        else
        {
            TerrainHeight             = 512;
            VFDataRTGen.s_noiseHeight = 512;
//			if(scenceClimate==ClimateType.CT_Dry)
//              VFDataRTGen.s_seaDepth = 64;
//			else
            VFDataRTGen.s_seaDepth = 128;
        }
    }
示例#15
0
 /// <summary>
 /// Gets name of the file based on the region and climate which is stored in database.
 /// </summary>
 /// <param name="climateType">Enum type which contain climate tpyes are part of the project</param>
 /// <param name="region">Enum type which contain regions are part of the project</param>
 /// <returns>file name for the region and climate type</returns>
 public static string getDBFileName(ClimateType climateType, Region region)
 {
     return(getTypeURLPart(climateType) + "_" + getSiteFileName(region));
 }
示例#16
0
    /// <summary>
    /// Gets the <see cref="BiomeType"/> associated with the given conditions.
    /// </summary>
    /// <param name="climateType">The climate type of the location.</param>
    /// <param name="humidityType">The humidity type of the location.</param>
    /// <param name="elevation">The elevation of the location above sea level.</param>
    /// <returns>The <see cref="BiomeType"/> associated with the given conditions.</returns>
    public static BiomeType GetBiomeType(ClimateType climateType, HumidityType humidityType, double elevation)
    {
        if (elevation <= 0)
        {
            return(BiomeType.Sea);
        }

        switch (climateType)
        {
        case ClimateType.Polar:
            return(elevation >= 0.15 ? BiomeType.Alpine : BiomeType.Polar);

        case ClimateType.Subpolar:
            return(elevation >= 0.15 ? BiomeType.Subalpine : BiomeType.Tundra);

        case ClimateType.Boreal:
            if (humidityType <= HumidityType.Arid)
            {
                return(BiomeType.LichenWoodland);
            }
            else
            {
                return(BiomeType.ConiferousForest);
            }

        case ClimateType.CoolTemperate:
            if (humidityType <= HumidityType.Perarid)
            {
                return(BiomeType.ColdDesert);
            }
            else if (humidityType == HumidityType.Arid)
            {
                return(BiomeType.Steppe);
            }
            else
            {
                return(BiomeType.MixedForest);
            }

        case ClimateType.WarmTemperate:
            if (humidityType <= HumidityType.Perarid)
            {
                return(BiomeType.HotDesert);
            }
            else if (humidityType <= HumidityType.Arid)
            {
                return(BiomeType.Shrubland);
            }
            else
            {
                return(BiomeType.DeciduousForest);
            }

        case ClimateType.Subtropical:
            if (humidityType <= HumidityType.Perarid)
            {
                return(BiomeType.HotDesert);
            }
            else if (humidityType == HumidityType.Arid)
            {
                return(BiomeType.Savanna);
            }
            else if (humidityType <= HumidityType.Subhumid)
            {
                return(BiomeType.MonsoonForest);
            }
            else
            {
                return(BiomeType.RainForest);
            }

        case ClimateType.Tropical:
            if (humidityType <= HumidityType.Perarid)
            {
                return(BiomeType.HotDesert);
            }
            else if (humidityType <= HumidityType.Semiarid)
            {
                return(BiomeType.Savanna);
            }
            else if (humidityType == HumidityType.Subhumid)
            {
                return(BiomeType.MonsoonForest);
            }
            else
            {
                return(BiomeType.RainForest);
            }

        default:
            return(BiomeType.HotDesert);
        }
    }
        /// <summary>
        /// Format the weather data from text file in class object.
        /// </summary>
        /// <param name="fileName">Name of the file which needs to be formatted</param>
        /// <param name="ct">The climate type filter</param>
        /// <param name="region">The Region filter</param>
        /// <returns>List of data in WeatherDataEntity</returns>
        public static List <WeatherDataEntity> FormatWeatherData(string fileName, ClimateType ct, Region region)
        {
            IEnumerable <string>     TextLines = File.ReadLines(WeatherDownload.filepath + fileName);
            List <WeatherDataEntity> wdeList   = new List <WeatherDataEntity>();

            int count = 0;

            foreach (var line in TextLines)
            {
                count++;
                if (count <= 8)
                {
                    continue;
                }

                string[] lineArr = line.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);

                if (Convert.ToInt32(lineArr[0]) == 2018)
                {
                    WeatherDataEntity wde2018 = new WeatherDataEntity()
                    {
                        Year        = Convert.ToInt32(lineArr[0]),
                        January     = toFloat(lineArr[1]),
                        February    = toFloat(lineArr[2]),
                        Winter      = toFloat(lineArr[3]),
                        ClimateType = ct,
                        Region      = region,
                        TimeStamp   = DateTime.Now
                    };

                    wdeList.Add(wde2018);
                    continue;
                }
                WeatherDataEntity wde = new WeatherDataEntity()
                {
                    Year = Convert.ToInt32(lineArr[0]),

                    January   = toFloat(lineArr[1]),
                    February  = toFloat(lineArr[2]),
                    March     = toFloat(lineArr[3]),
                    April     = toFloat(lineArr[4]),
                    May       = toFloat(lineArr[5]),
                    June      = toFloat(lineArr[6]),
                    July      = toFloat(lineArr[7]),
                    August    = toFloat(lineArr[8]),
                    September = toFloat(lineArr[9]),
                    October   = toFloat(lineArr[10]),
                    November  = toFloat(lineArr[11]),
                    December  = toFloat(lineArr[12]),

                    Winter = toFloat(lineArr[13]),
                    Spring = toFloat(lineArr[14]),
                    Summer = toFloat(lineArr[15]),
                    Autumn = toFloat(lineArr[16]),
                    Annual = toFloat(lineArr[17]),

                    ClimateType = ct,
                    Region      = region,
                    TimeStamp   = DateTime.Now
                };

                wdeList.Add(wde);
            }

            return(wdeList);
        }
示例#18
0
    public static void generateClimate(Map map, System.Random randomGenerator, MapGenerationSettings mapGenerationSettings)
    {
        ClimateType middleClimateType = ClimateType.TEMPERATE;
        ClimateType upperClimateType  = ClimateType.COOL;
        ClimateType bottomClimateType = ClimateType.WARM;

        int minY = 100000;
        int maxY = -100000;

        foreach (Hex hex in map.hexes)
        {
            if (hex.y > maxY)
            {
                maxY = hex.y;
            }

            if (hex.y < minY)
            {
                minY = hex.y;
            }
        }
        int actualMapHeight           = maxY - minY;
        int middleClimateStripeHeight = actualMapHeight * randomGenerator.Next(mapGenerationSettings.middleClimateStripeMinHeightPercent, mapGenerationSettings.middleClimateStripeMaxHeightPercent) / 100;
        int minMiddleClimateY         = minY + (actualMapHeight - middleClimateStripeHeight) / 2;
        int maxMiddleClimateY         = minY + (actualMapHeight + middleClimateStripeHeight) / 2;

        foreach (Region region in map.regions)
        {
            int topHexCount    = 0;
            int middleHexCount = 0;
            int bottomHexCount = 0;

            List <Hex> regionHexes = getRegionHexes(map, region.id);
            foreach (Hex hex in regionHexes)
            {
                if (hex.y < minMiddleClimateY)
                {
                    bottomHexCount++;
                }
                else if (hex.y >= minMiddleClimateY && hex.y <= maxMiddleClimateY)
                {
                    middleHexCount++;
                }
                else if (hex.y > maxMiddleClimateY)
                {
                    topHexCount++;
                }
            }

            ClimateType regionClimateType = middleClimateType;
            if (topHexCount >= (topHexCount + middleHexCount + bottomHexCount) * mapGenerationSettings.marginalClimateThreshold / 100)
            {
                regionClimateType = upperClimateType;
            }
            else if (bottomHexCount >= (topHexCount + middleHexCount + bottomHexCount) * mapGenerationSettings.marginalClimateThreshold / 100)
            {
                regionClimateType = bottomClimateType;
            }

            region.climateType = regionClimateType;
            foreach (Hex hex in regionHexes)
            {
                hex.climateType = regionClimateType;
                hex.addTag(getClimateTag(regionClimateType));
            }
        }
    }
示例#19
0
    /// <summary>
    /// Initializes a new instance of <see cref="WeatherMaps"/>.
    /// </summary>
    /// <param name="planet">The planet being mapped.</param>
    /// <param name="elevationMap">An elevation map.</param>
    /// <param name="winterTemperatureMap">A winter temperature map.</param>
    /// <param name="summerTemperatureMap">A summer temperature map.</param>
    /// <param name="precipitationMap">A precipitation map.</param>
    /// <param name="resolution">The intended vertical resolution of the maps.</param>
    /// <param name="options">
    /// The map projection options to use. All the map images must have been generated using
    /// these same options, or thew results will not be accurate.
    /// </param>
    public WeatherMaps(
        Planetoid planet,
        Image <L16> elevationMap,
        Image <L16> winterTemperatureMap,
        Image <L16> summerTemperatureMap,
        Image <L16> precipitationMap,
        int resolution,
        MapProjectionOptions?options = null)
    {
        var projection = options ?? MapProjectionOptions.Default;

        XLength = (int)Math.Floor(projection.AspectRatio * resolution);
        YLength = resolution;

        BiomeMap   = new BiomeType[XLength][];
        ClimateMap = new ClimateType[XLength][];
        var humidityMap = new HumidityType[XLength][];

        SeaIceRangeMap = new FloatRange[XLength][];

        for (var x = 0; x < XLength; x++)
        {
            BiomeMap[x]       = new BiomeType[YLength];
            ClimateMap[x]     = new ClimateType[YLength];
            humidityMap[x]    = new HumidityType[YLength];
            SeaIceRangeMap[x] = new FloatRange[YLength];
        }

        var scale          = SurfaceMap.GetScale(resolution, projection.Range);
        var stretch        = scale / projection.ScaleFactor;
        var elevationScale = SurfaceMap.GetScale(elevationMap.Height, projection.Range);
        var winterScale    = winterTemperatureMap.Height == elevationMap.Height
            ? elevationScale
            : SurfaceMap.GetScale(winterTemperatureMap.Height, projection.Range);
        var summerScale = summerTemperatureMap.Height == elevationMap.Height
            ? elevationScale
            : SurfaceMap.GetScale(summerTemperatureMap.Height, projection.Range);
        var precipitationScale = precipitationMap.Height == elevationMap.Height
            ? elevationScale
            : SurfaceMap.GetScale(precipitationMap.Height, projection.Range);

        var totalElevation    = 0.0;
        var minTemperature    = 5000.0f;
        var maxTemperature    = 0.0f;
        var totalTemperature  = 0.0f;
        var totalPrecipiation = 0.0;
        var xToEX             = new Dictionary <int, int>();
        var xToWX             = new Dictionary <int, int>();
        var xToSX             = new Dictionary <int, int>();
        var xToPX             = new Dictionary <int, int>();

        for (var y = 0; y < YLength; y++)
        {
            var latitude = projection.EqualArea
                ? SurfaceMap.GetLatitudeOfCylindricalEqualAreaProjection(y, resolution, scale, projection)
                : SurfaceMap.GetLatitudeOfEquirectangularProjection(y, resolution, scale, projection);

            var elevationY = projection.EqualArea
                ? SurfaceMap.GetCylindricalEqualAreaYFromLatWithScale(latitude, elevationMap.Height, elevationScale, projection)
                : SurfaceMap.GetEquirectangularYFromLatWithScale(latitude, elevationMap.Height, elevationScale, projection);
            var elevationSpan = elevationMap.GetPixelRowSpan(elevationY);

            int winterY;
            if (winterTemperatureMap.Height == elevationMap.Height)
            {
                winterY = elevationY;
            }
            else if (projection.EqualArea)
            {
                winterY = SurfaceMap.GetCylindricalEqualAreaYFromLatWithScale(latitude, winterTemperatureMap.Height, winterScale, projection);
            }
            else
            {
                winterY = SurfaceMap.GetEquirectangularYFromLatWithScale(latitude, winterTemperatureMap.Height, winterScale, projection);
            }

            var winterSpan = winterTemperatureMap.GetPixelRowSpan(winterY);

            int summerY;
            if (summerTemperatureMap.Height == elevationMap.Height)
            {
                summerY = elevationY;
            }
            else if (projection.EqualArea)
            {
                summerY = SurfaceMap.GetCylindricalEqualAreaYFromLatWithScale(latitude, summerTemperatureMap.Height, summerScale, projection);
            }
            else
            {
                summerY = SurfaceMap.GetEquirectangularYFromLatWithScale(latitude, summerTemperatureMap.Height, summerScale, projection);
            }

            var summerSpan = summerTemperatureMap.GetPixelRowSpan(summerY);

            int precipitationY;
            if (precipitationMap.Height == elevationMap.Height)
            {
                precipitationY = elevationY;
            }
            else if (projection.EqualArea)
            {
                precipitationY = SurfaceMap.GetCylindricalEqualAreaYFromLatWithScale(latitude, precipitationMap.Height, precipitationScale, projection);
            }
            else
            {
                precipitationY = SurfaceMap.GetEquirectangularYFromLatWithScale(latitude, precipitationMap.Height, precipitationScale, projection);
            }

            var precipitationSpan = precipitationMap.GetPixelRowSpan(precipitationY);

            for (var x = 0; x < XLength; x++)
            {
                if (!xToEX.TryGetValue(x, out var elevationX))
                {
                    var longitude = projection.EqualArea
                        ? SurfaceMap.GetLongitudeOfCylindricalEqualAreaProjection(x, XLength, scale, projection)
                        : SurfaceMap.GetLongitudeOfEquirectangularProjection(x, XLength, stretch, projection);

                    elevationX = projection.EqualArea
                        ? SurfaceMap.GetCylindricalEqualAreaXFromLonWithScale(longitude, elevationMap.Width, elevationScale, projection)
                        : SurfaceMap.GetEquirectangularXFromLonWithScale(longitude, elevationMap.Width, elevationScale, projection);
                    int wX;
                    if (winterTemperatureMap.Width == elevationMap.Width)
                    {
                        wX = elevationX;
                    }
                    else if (projection.EqualArea)
                    {
                        wX = SurfaceMap.GetCylindricalEqualAreaXFromLonWithScale(longitude, winterTemperatureMap.Width, winterScale, projection);
                    }
                    else
                    {
                        wX = SurfaceMap.GetEquirectangularXFromLonWithScale(longitude, winterTemperatureMap.Width, winterScale, projection);
                    }

                    int sX;
                    if (summerTemperatureMap.Width == elevationMap.Width)
                    {
                        sX = elevationX;
                    }
                    else if (projection.EqualArea)
                    {
                        sX = SurfaceMap.GetCylindricalEqualAreaXFromLonWithScale(longitude, summerTemperatureMap.Width, summerScale, projection);
                    }
                    else
                    {
                        sX = SurfaceMap.GetEquirectangularXFromLonWithScale(longitude, summerTemperatureMap.Width, summerScale, projection);
                    }

                    int pX;
                    if (precipitationMap.Width == elevationMap.Width)
                    {
                        pX = elevationX;
                    }
                    else if (projection.EqualArea)
                    {
                        pX = SurfaceMap.GetCylindricalEqualAreaXFromLonWithScale(longitude, precipitationMap.Width, precipitationScale, projection);
                    }
                    else
                    {
                        pX = SurfaceMap.GetEquirectangularXFromLonWithScale(longitude, precipitationMap.Width, precipitationScale, projection);
                    }

                    xToEX.Add(x, elevationX);
                    xToWX.Add(x, wX);
                    xToSX.Add(x, sX);
                    xToPX.Add(x, pX);
                }
                var winterX        = xToWX[x];
                var summerX        = xToSX[x];
                var precipitationX = xToPX[x];

                var normalizedElevation = elevationSpan[elevationX].GetValueFromPixel_PosNeg() - planet.NormalizedSeaLevel;
                totalElevation += normalizedElevation;

                var winterTemperature = (float)(winterSpan[winterX].GetValueFromPixel_Pos() * SurfaceMapImage.TemperatureScaleFactor);
                var summerTemperature = (float)(summerSpan[summerX].GetValueFromPixel_Pos() * SurfaceMapImage.TemperatureScaleFactor);
                minTemperature    = Math.Min(minTemperature, Math.Min(winterTemperature, summerTemperature));
                maxTemperature    = Math.Max(maxTemperature, Math.Max(winterTemperature, summerTemperature));
                totalTemperature += (minTemperature + maxTemperature) / 2;

                var precipValue   = precipitationSpan[precipitationX].GetValueFromPixel_Pos();
                var precipitation = precipValue * planet.Atmosphere.MaxPrecipitation;
                totalPrecipiation += precipValue;

                ClimateMap[x][y] = Universe.Climate.Climate.GetClimateType(new FloatRange(
                                                                               Math.Min(winterTemperature, summerTemperature),
                                                                               Math.Max(winterTemperature, summerTemperature)));
                humidityMap[x][y] = Universe.Climate.Climate.GetHumidityType(precipitation);
                BiomeMap[x][y]    = Universe.Climate.Climate.GetBiomeType(ClimateMap[x][y], humidityMap[x][y], normalizedElevation);

                if (normalizedElevation > 0 ||
                    (summerTemperature >= Substances.All.Seawater.MeltingPoint &&
                     winterTemperature >= Substances.All.Seawater.MeltingPoint))
                {
                    continue;
                }

                if (summerTemperature < Substances.All.Seawater.MeltingPoint &&
                    winterTemperature < Substances.All.Seawater.MeltingPoint)
                {
                    SeaIceRangeMap[x][y] = FloatRange.ZeroToOne;
                    continue;
                }

                var freezeProportion = ((summerTemperature >= winterTemperature
                    ? winterTemperature.InverseLerp(summerTemperature, (float)(Substances.All.Seawater.MeltingPoint ?? 0))
                    : summerTemperature.InverseLerp(winterTemperature, (float)(Substances.All.Seawater.MeltingPoint ?? 0))) * 0.8f) - 0.1f;
                if (freezeProportion <= 0 ||
                    float.IsNaN(freezeProportion))
                {
                    continue;
                }

                var freezeStart   = 1 - (freezeProportion / 4);
                var iceMeltFinish = freezeProportion * 3 / 4;
                if (latitude < 0)
                {
                    freezeStart += 0.5f;
                    if (freezeStart > 1)
                    {
                        freezeStart--;
                    }

                    iceMeltFinish += 0.5f;
                    if (iceMeltFinish > 1)
                    {
                        iceMeltFinish--;
                    }
                }
                SeaIceRangeMap[x][y] = new FloatRange(freezeStart, iceMeltFinish);
            }
        }

        Climate = Universe.Climate.Climate.GetClimateType(new FloatRange(minTemperature, totalTemperature / (XLength * YLength), maxTemperature));
        var humidity = Universe.Climate.Climate.GetHumidityType(totalPrecipiation / (XLength * YLength) * planet.Atmosphere.MaxPrecipitation);

        Biome = Universe.Climate.Climate.GetBiomeType(Climate, humidity, totalElevation / (XLength * YLength) * planet.MaxElevation);
    }