worldgen

git clone https://git.godosa.eu/worldgen

master

raw ยท 3840 bytes

# map/tests/test_plateaus.py
import json
import unittest

import numpy as np

from mapgen import plateaus as PL
from mapgen.sphere import east_north, great_circle_point, latlon_to_xyz
from tests.helpers import small_grid

R = 12742.0
P1 = {"name": "east-flank", "center": [-39.9, -18.0], "area_km2": 3.0e6, "elongation": 1.9, "azimuth_deg": 30.0,
      "top_m": [1500.0, 3000.0]}
P2 = {"name": "plateau-02", "center": [-0.4, 176.6], "area_km2": 1.0e6, "top_m": [1000.0, 1500.0], "islands": True}


def at(lat, lon):
    return latlon_to_xyz(lat, lon)[None]


class PlateauGeometryTest(unittest.TestCase):
    def test_centre_inside_and_area_close_to_config(self):
        g = small_grid(4)
        for p in (P1, P2):
            self.assertLess(PL.rho(at(*p["center"]), p, 1296, R)[0], 1e-6)
            area = g.area_km2[PL.rho(g.xyz, p, 1296, R) < 1.0].sum()
            self.assertAlmostEqual(area / p["area_km2"], 1.0, delta=0.2, msg=p["name"])

    def test_long_axis_follows_the_azimuth(self):
        a, b = PL.semi_axes(P1)
        self.assertAlmostEqual(a / b, 1.9)
        self.assertAlmostEqual(np.pi * a * b, P1["area_km2"], delta=1.0)
        c = latlon_to_xyz(*P1["center"])
        e, n = east_north(c[None])
        az = np.radians(30.0)
        along = np.sin(az) * e[0] + np.cos(az) * n[0]
        across = np.cos(az) * e[0] - np.sin(az) * n[0]
        self.assertLess(PL.rho(great_circle_point(c, along, 0.8 * a, R)[None], P1, 1296, R)[0], 1.0)
        self.assertGreater(PL.rho(great_circle_point(c, across, 0.8 * a, R)[None], P1, 1296, R)[0], 1.0)

    def test_features_are_deterministic_inside_and_json_ready(self):
        f = PL.features(P2, 1296, R)
        self.assertEqual(f, PL.features(P2, 1296, R))
        json.dumps(f)
        self.assertTrue(6 <= len(f["cones"]) <= 20)
        self.assertTrue(1 <= len(f["calderas"]) <= 3)
        self.assertTrue(3 <= sum(c["island"] for c in f["cones"]) <= 6)
        for c in f["cones"] + f["calderas"]:
            self.assertLess(PL.rho(at(c["lat"], c["lon"]), P2, 1296, R)[0], 0.86)
        self.assertFalse(any(c["island"] for c in PL.features(P1, 1296, R)["cones"]))
        self.assertEqual(PL.features({**P1, "vent": 0.0}, 1296, R)["cones"], [])

    def test_surface_depth_follows_top_m(self):
        g = small_grid(4)
        inner = g.xyz[PL.rho(g.xyz, P1, 1296, R) < 0.5]
        z = PL.surface(inner, P1, {"cones": [], "calderas": []}, 1296, R, np.full(len(inner), -5900.0))
        self.assertTrue(np.all(z <= -P1["top_m"][0] + PL.RELIEF_M + 1e-6))
        self.assertTrue(np.all(z >= -P1["top_m"][1] - PL.RELIEF_M - 1e-6))

    def test_apply_hidden_clamp_islands_and_nothing_else(self):
        g = small_grid(4)
        plats = [P1, P2]
        ids = PL.cell_ids(g.xyz, plats, 1296, R)
        self.assertGreater((ids == 0).sum(), 100)
        z = PL.apply(g, np.full(g.n, -6000.0), plats, ids, 1296)
        self.assertLessEqual(z[ids == 0].max(), PL.HIDDEN_MAX_M)
        self.assertGreater(z.max(), 0.0, "island plateau: small volcanic islands")
        changed_outside = (ids < 0) & (z != -6000.0)
        self.assertLessEqual(changed_outside.sum(), 6, "only islands' nearest cells may lie outside the outline")

    def test_outline_across_the_antimeridian_and_near_the_pole(self):
        p = {"name": "plateau-11", "center": [77.0, 179.0], "area_km2": 0.9e6, "top_m": [1000.0, 1500.0]}
        self.assertLess(PL.rho(at(77.0, 179.8), p, 1296, R)[0], 0.3)
        self.assertLess(PL.rho(at(77.0, -179.8), p, 1296, R)[0], 0.3)
        q = {"name": "polar", "center": [88.0, 0.0], "area_km2": 1.0e6, "top_m": [1000.0, 1500.0]}
        self.assertLess(PL.rho(at(89.9, 90.0), q, 1296, R)[0], 1.0)
        self.assertLess(PL.rho(at(89.9, -90.0), q, 1296, R)[0], 1.0)
        self.assertTrue(np.all(np.isfinite(PL.rho(small_grid(3).xyz, q, 1296, R))))