mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-12 03:24:14 +00:00
Hydrology probes on the rivers v2 contract
- Ocean integrity fires on land columns near a mouth; shallow incision and bank continuity are gates - Probe-local centerline and turn helpers replaced by production geometry - v1 checks for ridge bores, endpoint ramps, terminal caps, transition recovery and pool lengths removed
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -28,6 +28,9 @@ public final class HydrologyPlannerProbe {
|
|||||||
private static final long[] DEFAULT_SEEDS = {1L, 19L, 52L, 77L, 331L, 501L, 712L, 992L};
|
private static final long[] DEFAULT_SEEDS = {1L, 19L, 52L, 77L, 331L, 501L, 712L, 992L};
|
||||||
private static final long SURFACE_INLAND_SEED = 7012L;
|
private static final long SURFACE_INLAND_SEED = 7012L;
|
||||||
private static final long UNDERGROUND_INLAND_SEED = 7013L;
|
private static final long UNDERGROUND_INLAND_SEED = 7013L;
|
||||||
|
private static final long COASTAL_SEED = 7014L;
|
||||||
|
static final Set<HydrologyFeatureType> REQUIRED_FEATURE_TYPES =
|
||||||
|
Set.copyOf(EnumSet.complementOf(EnumSet.of(HydrologyFeatureType.RIDGE_BORE)));
|
||||||
private static final HydrologyTileKey ORIGIN = new HydrologyTileKey(0, 0);
|
private static final HydrologyTileKey ORIGIN = new HydrologyTileKey(0, 0);
|
||||||
private static final int WARM_SAMPLES = 2_048;
|
private static final int WARM_SAMPLES = 2_048;
|
||||||
|
|
||||||
@@ -90,6 +93,7 @@ public final class HydrologyPlannerProbe {
|
|||||||
collectAccepted(firstFeatures, surfaceInlandTile());
|
collectAccepted(firstFeatures, surfaceInlandTile());
|
||||||
collectAccepted(firstFeatures, undergroundInlandTile());
|
collectAccepted(firstFeatures, undergroundInlandTile());
|
||||||
collectAccepted(firstFeatures, surfaceMouthTile());
|
collectAccepted(firstFeatures, surfaceMouthTile());
|
||||||
|
collectAccepted(firstFeatures, coastalGrottoTile());
|
||||||
requireCompleteCoverage(firstFeatures.keySet());
|
requireCompleteCoverage(firstFeatures.keySet());
|
||||||
|
|
||||||
for (Map.Entry<HydrologyFeatureType, HydrologyFeatureRef> entry : firstFeatures.entrySet()) {
|
for (Map.Entry<HydrologyFeatureType, HydrologyFeatureRef> entry : firstFeatures.entrySet()) {
|
||||||
@@ -134,6 +138,7 @@ public final class HydrologyPlannerProbe {
|
|||||||
collectAccepted(coverage, surfaceInlandTile());
|
collectAccepted(coverage, surfaceInlandTile());
|
||||||
collectAccepted(coverage, undergroundInlandTile());
|
collectAccepted(coverage, undergroundInlandTile());
|
||||||
collectAccepted(coverage, surfaceMouthTile());
|
collectAccepted(coverage, surfaceMouthTile());
|
||||||
|
collectAccepted(coverage, coastalGrottoTile());
|
||||||
requireCompleteCoverage(coverage.keySet());
|
requireCompleteCoverage(coverage.keySet());
|
||||||
return Map.copyOf(coverage);
|
return Map.copyOf(coverage);
|
||||||
}
|
}
|
||||||
@@ -148,7 +153,7 @@ public final class HydrologyPlannerProbe {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void requireCompleteCoverage(Set<HydrologyFeatureType> observed) {
|
private static void requireCompleteCoverage(Set<HydrologyFeatureType> observed) {
|
||||||
EnumSet<HydrologyFeatureType> missing = EnumSet.allOf(HydrologyFeatureType.class);
|
EnumSet<HydrologyFeatureType> missing = EnumSet.copyOf(REQUIRED_FEATURE_TYPES);
|
||||||
missing.removeAll(observed);
|
missing.removeAll(observed);
|
||||||
if (!missing.isEmpty()) {
|
if (!missing.isEmpty()) {
|
||||||
throw new IllegalStateException("Hydrology accepted-feature coverage is missing " + missing + ".");
|
throw new IllegalStateException("Hydrology accepted-feature coverage is missing " + missing + ".");
|
||||||
@@ -175,9 +180,18 @@ public final class HydrologyPlannerProbe {
|
|||||||
|
|
||||||
private static HydrologyTile surfaceMouthTile() {
|
private static HydrologyTile surfaceMouthTile() {
|
||||||
return new HydrologyPlanner(
|
return new HydrologyPlanner(
|
||||||
DEFAULT_SEEDS[0],
|
COASTAL_SEED,
|
||||||
settings(false),
|
settings(false),
|
||||||
terrain(DEFAULT_SEEDS[0])
|
coastalTerrain(false)
|
||||||
|
).plan(ORIGIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HydrologyTile coastalGrottoTile() {
|
||||||
|
return new HydrologyPlanner(
|
||||||
|
COASTAL_SEED,
|
||||||
|
settings(true),
|
||||||
|
coastalTerrain(true),
|
||||||
|
solidCaveView()
|
||||||
).plan(ORIGIN);
|
).plan(ORIGIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,9 +244,9 @@ public final class HydrologyPlannerProbe {
|
|||||||
8,
|
8,
|
||||||
true,
|
true,
|
||||||
96,
|
96,
|
||||||
8
|
8,
|
||||||
,
|
HydrologyPlannerSettings.Banks.defaults()
|
||||||
HydrologyPlannerSettings.Banks.defaults()),
|
),
|
||||||
new HydrologyPlannerSettings.Hydraulics(12, 28, 1, 3, 8, 4),
|
new HydrologyPlannerSettings.Hydraulics(12, 28, 1, 3, 8, 4),
|
||||||
new HydrologyPlannerSettings.Underground(
|
new HydrologyPlannerSettings.Underground(
|
||||||
undergroundDensity > 0D,
|
undergroundDensity > 0D,
|
||||||
@@ -302,6 +316,57 @@ public final class HydrologyPlannerProbe {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static HydrologyTerrainSampler coastalTerrain(boolean cliffCoast) {
|
||||||
|
return (int x, int z) -> {
|
||||||
|
if (x >= 208) {
|
||||||
|
return oceanTerrain();
|
||||||
|
}
|
||||||
|
int height;
|
||||||
|
double slope;
|
||||||
|
if (x < 104) {
|
||||||
|
height = 100 - Math.floorDiv(x, 8);
|
||||||
|
slope = 1D;
|
||||||
|
} else if (cliffCoast) {
|
||||||
|
height = 84 - Math.floorDiv(x - 104, 26);
|
||||||
|
slope = 1D;
|
||||||
|
} else {
|
||||||
|
height = 79 - Math.floorDiv(x - 104, 12);
|
||||||
|
slope = x < 112 ? 4D : 1D;
|
||||||
|
}
|
||||||
|
boolean surfaceSource = x <= 40;
|
||||||
|
boolean undergroundSource = x <= 64;
|
||||||
|
return new HydrologyTerrainSample(
|
||||||
|
height,
|
||||||
|
slope,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
height - 30,
|
||||||
|
height - 28,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
surfaceSource,
|
||||||
|
surfaceSource,
|
||||||
|
undergroundSource,
|
||||||
|
undergroundSource,
|
||||||
|
0D,
|
||||||
|
surfaceSource ? 1D : 0D,
|
||||||
|
undergroundSource ? 1D : 0D,
|
||||||
|
1D,
|
||||||
|
1D,
|
||||||
|
1D,
|
||||||
|
1D,
|
||||||
|
1D,
|
||||||
|
"parent",
|
||||||
|
"surface",
|
||||||
|
"mouth",
|
||||||
|
"shore",
|
||||||
|
"bank",
|
||||||
|
"flooded",
|
||||||
|
List.of("water")
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private static CaveVoxelView solidCaveView() {
|
private static CaveVoxelView solidCaveView() {
|
||||||
return new CaveVoxelView() {
|
return new CaveVoxelView() {
|
||||||
@Override
|
@Override
|
||||||
@@ -397,9 +462,9 @@ public final class HydrologyPlannerProbe {
|
|||||||
10,
|
10,
|
||||||
true,
|
true,
|
||||||
96,
|
96,
|
||||||
10
|
10,
|
||||||
,
|
HydrologyPlannerSettings.Banks.defaults()
|
||||||
HydrologyPlannerSettings.Banks.defaults()),
|
),
|
||||||
new HydrologyPlannerSettings.Hydraulics(12, 40, 1, 3, 8, 4),
|
new HydrologyPlannerSettings.Hydraulics(12, 40, 1, 3, 8, 4),
|
||||||
new HydrologyPlannerSettings.Underground(
|
new HydrologyPlannerSettings.Underground(
|
||||||
true,
|
true,
|
||||||
|
|||||||
@@ -357,8 +357,7 @@ public final class HydrologyPackProbeTest {
|
|||||||
1337L,
|
1337L,
|
||||||
1L,
|
1L,
|
||||||
centerline,
|
centerline,
|
||||||
thickChannel(centerline, 4, 32),
|
thickChannel(centerline, 4, 32)
|
||||||
false
|
|
||||||
));
|
));
|
||||||
|
|
||||||
assertTrue(result.gridLockedFraction() > 0.9D);
|
assertTrue(result.gridLockedFraction() > 0.9D);
|
||||||
@@ -380,8 +379,7 @@ public final class HydrologyPackProbeTest {
|
|||||||
1337L,
|
1337L,
|
||||||
2L,
|
2L,
|
||||||
centerline,
|
centerline,
|
||||||
thickChannel(centerline, 4, 32),
|
thickChannel(centerline, 4, 32)
|
||||||
false
|
|
||||||
));
|
));
|
||||||
|
|
||||||
assertTrue(result.isolatedTurns() > 0);
|
assertTrue(result.isolatedTurns() > 0);
|
||||||
@@ -390,126 +388,6 @@ public final class HydrologyPackProbeTest {
|
|||||||
assertTrue(result.violations().contains("P95_TURN"));
|
assertTrue(result.violations().contains("P95_TURN"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void gradualSourceWidthRampPassesEndpointGate() {
|
|
||||||
List<HydrologyPoint> centerline = List.of(point(0, 0), point(80, 24));
|
|
||||||
HydrologyPackProbe.CourseMorphologyResult result =
|
|
||||||
HydrologyPackProbe.PublishedMorphologyMetrics.analyzeCourse(courseInput(
|
|
||||||
1337L,
|
|
||||||
3L,
|
|
||||||
centerline,
|
|
||||||
thickChannel(centerline, 4, 32),
|
|
||||||
false
|
|
||||||
));
|
|
||||||
|
|
||||||
assertEquals(0, result.hardEndpointRamps());
|
|
||||||
assertEquals(0, result.unexpectedLeaves());
|
|
||||||
assertFalse(result.violations().contains("HARD_ENDPOINT_RAMP"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void widenedSourceBasinFailsEndpointGate() {
|
|
||||||
List<HydrologyPoint> centerline = List.of(point(0, 0), point(80, 24));
|
|
||||||
HydrologyPackProbe.CourseMorphologyResult result =
|
|
||||||
HydrologyPackProbe.PublishedMorphologyMetrics.analyzeCourse(courseInput(
|
|
||||||
1337L,
|
|
||||||
7L,
|
|
||||||
centerline,
|
|
||||||
widenedSourceBasin(centerline, 4, 7, 32),
|
|
||||||
false
|
|
||||||
));
|
|
||||||
|
|
||||||
assertTrue(result.violations().contains("WIDENED_SOURCE_BASIN"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void fullWidthSourceCapFailsEndpointRampGate() {
|
|
||||||
List<HydrologyPoint> centerline = List.of(point(0, 0), point(80, 24));
|
|
||||||
HydrologyPackProbe.CourseMorphologyResult result =
|
|
||||||
HydrologyPackProbe.PublishedMorphologyMetrics.analyzeCourse(courseInput(
|
|
||||||
1337L,
|
|
||||||
4L,
|
|
||||||
centerline,
|
|
||||||
thickChannel(centerline, 4, 0),
|
|
||||||
false
|
|
||||||
));
|
|
||||||
|
|
||||||
assertTrue(result.hardEndpointRamps() > 0);
|
|
||||||
assertTrue(result.violations().contains("HARD_ENDPOINT_RAMP"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void fullWidthExposedTerminalFailsEndpointRampGate() {
|
|
||||||
List<HydrologyPoint> centerline = List.of(point(0, 0), point(80, 24));
|
|
||||||
HydrologyPackProbe.CourseMorphologyResult result =
|
|
||||||
HydrologyPackProbe.PublishedMorphologyMetrics.analyzeCourse(courseInput(
|
|
||||||
1337L,
|
|
||||||
5L,
|
|
||||||
centerline,
|
|
||||||
thickChannel(centerline, 4, 32),
|
|
||||||
true
|
|
||||||
));
|
|
||||||
|
|
||||||
assertEquals(1, result.hardEndpointRamps());
|
|
||||||
assertTrue(result.violations().contains("HARD_ENDPOINT_RAMP"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void clippedCourseDoesNotInventEndpointRampFailures() {
|
|
||||||
List<HydrologyPoint> centerline = List.of(point(0, 0), point(160, 48));
|
|
||||||
Set<Long> observedCells = thickChannel(
|
|
||||||
List.of(point(40, 12), point(120, 36)),
|
|
||||||
4,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
HydrologyPackProbe.CourseMorphologyResult result =
|
|
||||||
HydrologyPackProbe.PublishedMorphologyMetrics.analyzeCourse(courseInput(
|
|
||||||
1337L,
|
|
||||||
8L,
|
|
||||||
centerline,
|
|
||||||
observedCells,
|
|
||||||
true
|
|
||||||
));
|
|
||||||
|
|
||||||
assertEquals(0, result.hardEndpointRamps());
|
|
||||||
assertFalse(result.violations().contains("HARD_ENDPOINT_RAMP"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void roundedExposedTerminalCapPassesCapGate() {
|
|
||||||
List<HydrologyPoint> centerline = List.of(point(0, 0), point(160, 0));
|
|
||||||
HydrologyPackProbe.CourseMorphologyResult result =
|
|
||||||
HydrologyPackProbe.PublishedMorphologyMetrics.analyzeCourse(courseInput(
|
|
||||||
1337L,
|
|
||||||
9L,
|
|
||||||
centerline,
|
|
||||||
terminalBasinChannel(centerline, 4, 7, 32, false),
|
|
||||||
true
|
|
||||||
));
|
|
||||||
|
|
||||||
assertEquals(0, result.clippedTerminalCaps());
|
|
||||||
assertTrue(result.terminalCapLength() >= 3D);
|
|
||||||
assertFalse(result.violations().contains("CLIPPED_TERMINAL_CAP"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void squareExposedTerminalCapFailsCapGateAfterGradualBasinRamp() {
|
|
||||||
List<HydrologyPoint> centerline = List.of(point(0, 0), point(160, 0));
|
|
||||||
HydrologyPackProbe.CourseMorphologyResult result =
|
|
||||||
HydrologyPackProbe.PublishedMorphologyMetrics.analyzeCourse(courseInput(
|
|
||||||
1337L,
|
|
||||||
10L,
|
|
||||||
centerline,
|
|
||||||
terminalBasinChannel(centerline, 4, 7, 32, true),
|
|
||||||
true
|
|
||||||
));
|
|
||||||
|
|
||||||
assertEquals(0, result.hardEndpointRamps());
|
|
||||||
assertEquals(1, result.clippedTerminalCaps());
|
|
||||||
assertEquals(0D, result.terminalCapLength(), 0D);
|
|
||||||
assertTrue(result.violations().contains("CLIPPED_TERMINAL_CAP"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void configuredMinimumWidthRejectsNarrowOwnedInterior() {
|
public void configuredMinimumWidthRejectsNarrowOwnedInterior() {
|
||||||
List<HydrologyPoint> centerline = List.of(point(0, 0), point(192, 0));
|
List<HydrologyPoint> centerline = List.of(point(0, 0), point(192, 0));
|
||||||
@@ -518,8 +396,7 @@ public final class HydrologyPackProbeTest {
|
|||||||
1337L,
|
1337L,
|
||||||
11L,
|
11L,
|
||||||
centerline,
|
centerline,
|
||||||
thickChannel(centerline, 1, 32),
|
thickChannel(centerline, 1, 32)
|
||||||
false
|
|
||||||
));
|
));
|
||||||
|
|
||||||
assertEquals(3, result.minimumInteriorWidth());
|
assertEquals(3, result.minimumInteriorWidth());
|
||||||
@@ -534,8 +411,7 @@ public final class HydrologyPackProbeTest {
|
|||||||
1337L,
|
1337L,
|
||||||
12L,
|
12L,
|
||||||
centerline,
|
centerline,
|
||||||
thickChannel(centerline, 2, 32),
|
thickChannel(centerline, 2, 32)
|
||||||
false
|
|
||||||
));
|
));
|
||||||
|
|
||||||
assertTrue(result.minimumInteriorWidth() >= 4);
|
assertTrue(result.minimumInteriorWidth() >= 4);
|
||||||
@@ -544,32 +420,6 @@ public final class HydrologyPackProbeTest {
|
|||||||
assertFalse(result.violations().contains("CONCAVE_WIDTH_TROUGH"));
|
assertFalse(result.violations().contains("CONCAVE_WIDTH_TROUGH"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void borePortalRunMarginsAreExcludedFromInteriorWidth() {
|
|
||||||
List<HydrologyPoint> centerline = List.of(point(0, 0), point(320, 0));
|
|
||||||
HashSet<Long> ownedCells = new HashSet<>(thickChannel(
|
|
||||||
List.of(point(0, 0), point(128, 0)),
|
|
||||||
2,
|
|
||||||
32
|
|
||||||
));
|
|
||||||
ownedCells.addAll(thickChannel(
|
|
||||||
List.of(point(192, 0), point(320, 0)),
|
|
||||||
2,
|
|
||||||
32
|
|
||||||
));
|
|
||||||
HydrologyPackProbe.CourseMorphologyResult result =
|
|
||||||
HydrologyPackProbe.PublishedMorphologyMetrics.analyzeCourse(courseInput(
|
|
||||||
1337L,
|
|
||||||
15L,
|
|
||||||
centerline,
|
|
||||||
ownedCells,
|
|
||||||
false
|
|
||||||
));
|
|
||||||
|
|
||||||
assertTrue(result.minimumInteriorWidth() >= 4);
|
|
||||||
assertFalse(result.violations().contains("NARROW_INTERIOR_WIDTH"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void sustainedMidCourseWidthTroughFailsConcavityGate() {
|
public void sustainedMidCourseWidthTroughFailsConcavityGate() {
|
||||||
List<HydrologyPoint> centerline = List.of(point(0, 0), point(256, 0));
|
List<HydrologyPoint> centerline = List.of(point(0, 0), point(256, 0));
|
||||||
@@ -578,8 +428,7 @@ public final class HydrologyPackProbeTest {
|
|||||||
1337L,
|
1337L,
|
||||||
13L,
|
13L,
|
||||||
centerline,
|
centerline,
|
||||||
troughChannel(centerline, 5, 2, 96, 160),
|
troughChannel(centerline, 5, 2, 96, 160)
|
||||||
false
|
|
||||||
));
|
));
|
||||||
|
|
||||||
assertTrue(result.maximumWidthTroughDepthRatio() >= 0.35D);
|
assertTrue(result.maximumWidthTroughDepthRatio() >= 0.35D);
|
||||||
@@ -597,17 +446,14 @@ public final class HydrologyPackProbeTest {
|
|||||||
384,
|
384,
|
||||||
0D,
|
0D,
|
||||||
false,
|
false,
|
||||||
true,
|
|
||||||
centerline,
|
centerline,
|
||||||
terminalBasinChannel(centerline, 1, 2, 32, true)
|
terminalBasinChannel(centerline, 1, 2, 32, true)
|
||||||
);
|
);
|
||||||
HydrologyPackProbe.CourseMorphologyResult result =
|
HydrologyPackProbe.CourseMorphologyResult result =
|
||||||
HydrologyPackProbe.PublishedMorphologyMetrics.analyzeCourse(input);
|
HydrologyPackProbe.PublishedMorphologyMetrics.analyzeCourse(input);
|
||||||
|
|
||||||
assertEquals(0, result.clippedTerminalCaps());
|
|
||||||
assertEquals(0, result.minimumInteriorWidth());
|
assertEquals(0, result.minimumInteriorWidth());
|
||||||
assertEquals(0D, result.maximumWidthTroughDepthRatio(), 0D);
|
assertEquals(0D, result.maximumWidthTroughDepthRatio(), 0D);
|
||||||
assertFalse(result.violations().contains("CLIPPED_TERMINAL_CAP"));
|
|
||||||
assertFalse(result.violations().contains("NARROW_INTERIOR_WIDTH"));
|
assertFalse(result.violations().contains("NARROW_INTERIOR_WIDTH"));
|
||||||
assertFalse(result.violations().contains("CONCAVE_WIDTH_TROUGH"));
|
assertFalse(result.violations().contains("CONCAVE_WIDTH_TROUGH"));
|
||||||
}
|
}
|
||||||
@@ -620,7 +466,7 @@ public final class HydrologyPackProbeTest {
|
|||||||
HydrologyPackProbe.SeedMorphologyResult result =
|
HydrologyPackProbe.SeedMorphologyResult result =
|
||||||
HydrologyPackProbe.PublishedMorphologyMetrics.analyzeSeed(
|
HydrologyPackProbe.PublishedMorphologyMetrics.analyzeSeed(
|
||||||
1337L,
|
1337L,
|
||||||
List.of(courseInput(1337L, 6L, centerline, ownedCells, false))
|
List.of(courseInput(1337L, 6L, centerline, ownedCells))
|
||||||
);
|
);
|
||||||
|
|
||||||
assertTrue(result.unexpectedLeaves() > 0);
|
assertTrue(result.unexpectedLeaves() > 0);
|
||||||
@@ -638,8 +484,192 @@ public final class HydrologyPackProbeTest {
|
|||||||
assertFalse(HydrologyPackProbe.ShapeMetrics.ownsOceanTerrain(apron));
|
assertFalse(HydrologyPackProbe.ShapeMetrics.ownsOceanTerrain(apron));
|
||||||
assertFalse(HydrologyPackProbe.ShapeMetrics.ownsOceanTerrain(inertLayer));
|
assertFalse(HydrologyPackProbe.ShapeMetrics.ownsOceanTerrain(inertLayer));
|
||||||
assertTrue(HydrologyPackProbe.ShapeMetrics.ownsOceanTerrain(ownedTerrain));
|
assertTrue(HydrologyPackProbe.ShapeMetrics.ownsOceanTerrain(ownedTerrain));
|
||||||
|
assertTrue(HydrologyPackProbe.ShapeMetrics.ownsOceanTerrain(gradedLayer(70)));
|
||||||
assertFalse(HydrologyPackProbe.ShapeMetrics.mutatesOceanTerrain(54, 54));
|
assertFalse(HydrologyPackProbe.ShapeMetrics.mutatesOceanTerrain(54, 54));
|
||||||
assertTrue(HydrologyPackProbe.ShapeMetrics.mutatesOceanTerrain(54, 48));
|
assertTrue(HydrologyPackProbe.ShapeMetrics.mutatesOceanTerrain(54, 48));
|
||||||
|
assertFalse(HydrologyPackProbe.ShapeMetrics.mutatesOceanTerrain(54, 60));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void oceanIntegrityFlagsOwningSurfaceLayersAndCutTerrain() {
|
||||||
|
HydrologyColumnSample untouchedOcean = new HydrologyColumnSample(
|
||||||
|
0, 0, 48, 63, true, "parent", List.of(surfaceLayer(true, false)));
|
||||||
|
HydrologyColumnSample cutLand = new HydrologyColumnSample(
|
||||||
|
0, 0, 80, 63, false, "parent", List.of(gradedLayer(74)));
|
||||||
|
|
||||||
|
assertFalse(HydrologyPackProbe.ShapeMetrics.ownsSurfaceTerrain(untouchedOcean));
|
||||||
|
assertTrue(HydrologyPackProbe.ShapeMetrics.carriesOceanApron(untouchedOcean));
|
||||||
|
assertEquals(48, untouchedOcean.terrainHeight());
|
||||||
|
assertFalse(HydrologyPackProbe.ShapeMetrics.mutatesOceanTerrain(
|
||||||
|
untouchedOcean.naturalHeight(), untouchedOcean.terrainHeight()));
|
||||||
|
assertTrue(HydrologyPackProbe.ShapeMetrics.ownsSurfaceTerrain(cutLand));
|
||||||
|
assertTrue(HydrologyPackProbe.ShapeMetrics.mutatesOceanTerrain(
|
||||||
|
cutLand.naturalHeight(), cutLand.terrainHeight()));
|
||||||
|
assertThrows(IllegalArgumentException.class, () -> new HydrologyColumnSample(
|
||||||
|
0, 0, 60, 63, false, "parent", List.of(gradedLayer(55))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void landColumnsCarryingAnOceanApronAreDetected() {
|
||||||
|
HydrologyColumnSample land = new HydrologyColumnSample(
|
||||||
|
0, 0, 80, 63, false, "parent", List.of(surfaceLayer(true, false)));
|
||||||
|
|
||||||
|
assertTrue(HydrologyPackProbe.ShapeMetrics.carriesOceanApron(land));
|
||||||
|
assertFalse(HydrologyPackProbe.ShapeMetrics.ownsSurfaceTerrain(land));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bankContinuityAllowsSingleBlockStepsAndRejectsLedges() {
|
||||||
|
assertEquals(0, HydrologyPackProbe.ShapeMetrics.bankContinuityViolations(
|
||||||
|
gradedRow(70, 71, 72)));
|
||||||
|
assertEquals(1, HydrologyPackProbe.ShapeMetrics.bankContinuityViolations(
|
||||||
|
gradedRow(70, 71, 74)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bankContinuityIgnoresPairsAcrossTheWaterEdge() {
|
||||||
|
HydrologyColumnSample west = gradedColumn(-1, 0, 71);
|
||||||
|
HydrologyColumnSample channel = channelColumn(0, 0, 66, 69);
|
||||||
|
HydrologyColumnSample east = gradedColumn(1, 0, 78);
|
||||||
|
|
||||||
|
assertEquals(0, HydrologyPackProbe.ShapeMetrics.bankContinuityViolations(
|
||||||
|
new RiverFootprint(Map.of(
|
||||||
|
RiverFootprint.pack(west.x(), west.z()), west,
|
||||||
|
RiverFootprint.pack(channel.x(), channel.z()), channel,
|
||||||
|
RiverFootprint.pack(east.x(), east.z()), east
|
||||||
|
))));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shapeMetricsEmitFormattedMachineAndGateLines() {
|
||||||
|
HydrologyPackProbe.ShapeMetrics metrics = new HydrologyPackProbe.ShapeMetrics();
|
||||||
|
|
||||||
|
String machineLine = metrics.machineLine();
|
||||||
|
|
||||||
|
assertTrue(machineLine.startsWith("IRIS_HYDROLOGY_PACK_SHAPE version=15 "));
|
||||||
|
assertTrue(machineLine.contains("shallow_incision_courses=0"));
|
||||||
|
assertTrue(machineLine.contains("ocean_apron_land_columns=0"));
|
||||||
|
assertTrue(machineLine.contains("bank_step_violations=0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void emptyShapeMetricsReportOneLinePerGate() {
|
||||||
|
HydrologyPackProbe.ShapeMetrics metrics = new HydrologyPackProbe.ShapeMetrics();
|
||||||
|
|
||||||
|
List<HydrologyPackProbe.ShapeMetrics.Gate> gates = metrics.gates(List.of());
|
||||||
|
|
||||||
|
List<String> names = new ArrayList<>();
|
||||||
|
for (HydrologyPackProbe.ShapeMetrics.Gate gate : gates) {
|
||||||
|
names.add(gate.name());
|
||||||
|
}
|
||||||
|
assertEquals(
|
||||||
|
List.of(
|
||||||
|
"network_presence",
|
||||||
|
"channel_width",
|
||||||
|
"outlet_groups",
|
||||||
|
"terrain_support",
|
||||||
|
"ocean_integrity",
|
||||||
|
"bank_containment",
|
||||||
|
"bank_continuity",
|
||||||
|
"surface_incision",
|
||||||
|
"head_consistency",
|
||||||
|
"published_morphology"
|
||||||
|
),
|
||||||
|
names
|
||||||
|
);
|
||||||
|
for (HydrologyPackProbe.ShapeMetrics.Gate gate : gates) {
|
||||||
|
assertFalse(gate.counters().isBlank());
|
||||||
|
}
|
||||||
|
assertFalse(gate(gates, "network_presence").passed());
|
||||||
|
assertTrue(gate(gates, "ocean_integrity").passed());
|
||||||
|
assertTrue(gate(gates, "bank_continuity").passed());
|
||||||
|
assertTrue(gate(gates, "surface_incision").passed());
|
||||||
|
assertTrue(gate(gates, "ocean_integrity").counters().contains("ocean_apron_land_columns=0"));
|
||||||
|
assertTrue(gate(gates, "bank_continuity").counters().contains("bank_step_violations=0"));
|
||||||
|
assertTrue(gate(gates, "surface_incision").counters().contains("shallow_incision_courses=0"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void gateFailuresNameEveryFailedGate() {
|
||||||
|
HydrologyPackProbe.ShapeMetrics metrics = new HydrologyPackProbe.ShapeMetrics();
|
||||||
|
|
||||||
|
IllegalStateException failure = assertThrows(
|
||||||
|
IllegalStateException.class,
|
||||||
|
metrics::requireOrganicSurfaceNetwork
|
||||||
|
);
|
||||||
|
|
||||||
|
assertTrue(failure.getMessage().contains("network_presence"));
|
||||||
|
assertTrue(failure.getMessage().contains("published_morphology"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HydrologyPackProbe.ShapeMetrics.Gate gate(
|
||||||
|
List<HydrologyPackProbe.ShapeMetrics.Gate> gates,
|
||||||
|
String name
|
||||||
|
) {
|
||||||
|
for (HydrologyPackProbe.ShapeMetrics.Gate gate : gates) {
|
||||||
|
if (gate.name().equals(name)) {
|
||||||
|
return gate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalStateException("Missing gate " + name + ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void channelIncisionAveragesNaturalMinusTerrainOverChannelColumns() {
|
||||||
|
HydrologyColumnSample deep = channelColumn(0, 0, 74, 77);
|
||||||
|
HydrologyColumnSample shallow = channelColumn(1, 0, 79, 79);
|
||||||
|
HydrologyColumnSample bank = gradedColumn(2, 0, 79);
|
||||||
|
RiverFootprint footprint = new RiverFootprint(Map.of(
|
||||||
|
RiverFootprint.pack(deep.x(), deep.z()), deep,
|
||||||
|
RiverFootprint.pack(shallow.x(), shallow.z()), shallow,
|
||||||
|
RiverFootprint.pack(bank.x(), bank.z()), bank
|
||||||
|
));
|
||||||
|
|
||||||
|
List<HydrologyPackProbe.ShapeMetrics.ChannelIncision> incisions =
|
||||||
|
HydrologyPackProbe.ShapeMetrics.channelIncisions(footprint, Set.of(42L), 2, 10);
|
||||||
|
|
||||||
|
assertEquals(1, incisions.size());
|
||||||
|
HydrologyPackProbe.ShapeMetrics.ChannelIncision incision = incisions.getFirst();
|
||||||
|
assertEquals(42L, incision.courseId());
|
||||||
|
assertEquals(2, incision.columns());
|
||||||
|
assertEquals(3.5D, incision.meanIncision(), 0D);
|
||||||
|
assertEquals(1, incision.shallowColumns());
|
||||||
|
assertEquals(0, incision.excessiveColumns());
|
||||||
|
assertFalse(HydrologyPackProbe.ShapeMetrics.shallowMeanIncision(incision.meanIncision()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void channelIncisionBelowOneBlockFailsTheShallowGate() {
|
||||||
|
HydrologyColumnSample flat = channelColumn(0, 0, 80, 80);
|
||||||
|
RiverFootprint footprint = new RiverFootprint(Map.of(
|
||||||
|
RiverFootprint.pack(flat.x(), flat.z()), flat
|
||||||
|
));
|
||||||
|
|
||||||
|
List<HydrologyPackProbe.ShapeMetrics.ChannelIncision> incisions =
|
||||||
|
HydrologyPackProbe.ShapeMetrics.channelIncisions(footprint, Set.of(42L), 2, 10);
|
||||||
|
|
||||||
|
assertEquals(0D, incisions.getFirst().meanIncision(), 0D);
|
||||||
|
assertTrue(HydrologyPackProbe.ShapeMetrics.shallowMeanIncision(incisions.getFirst().meanIncision()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void channelIncisionIgnoresCoursesOutsideTheScope() {
|
||||||
|
HydrologyColumnSample deep = channelColumn(0, 0, 74, 77);
|
||||||
|
RiverFootprint footprint = new RiverFootprint(Map.of(
|
||||||
|
RiverFootprint.pack(deep.x(), deep.z()), deep
|
||||||
|
));
|
||||||
|
|
||||||
|
assertEquals(
|
||||||
|
List.of(),
|
||||||
|
HydrologyPackProbe.ShapeMetrics.channelIncisions(footprint, Set.of(7L), 2, 10)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shallowMeanIncisionGateRequiresOneBlockOfCut() {
|
||||||
|
assertTrue(HydrologyPackProbe.ShapeMetrics.shallowMeanIncision(0.75D));
|
||||||
|
assertFalse(HydrologyPackProbe.ShapeMetrics.shallowMeanIncision(1D));
|
||||||
|
assertFalse(HydrologyPackProbe.ShapeMetrics.shallowMeanIncision(2.5D));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -673,39 +703,31 @@ public final class HydrologyPackProbeTest {
|
|||||||
public void seedsWithoutSurfaceCoursesDoNotMaskPublishedFailures() {
|
public void seedsWithoutSurfaceCoursesDoNotMaskPublishedFailures() {
|
||||||
HydrologyPackProbe.CourseMorphologyResult acceptedCourse =
|
HydrologyPackProbe.CourseMorphologyResult acceptedCourse =
|
||||||
new HydrologyPackProbe.CourseMorphologyResult(
|
new HydrologyPackProbe.CourseMorphologyResult(
|
||||||
642L, 5L, 20, 80D, 80D, 0, 0D, 0D, 0, 0D, 0,
|
642L, 5L, 20, 80D, 80D, 0, 0D, 0D, 0, 0D, 0, 0D, 0, List.of());
|
||||||
0, 0, 0D, 0, 0, 0D, 0, 0D, 0, 0D, 0, List.of());
|
|
||||||
HydrologyPackProbe.SeedMorphologyResult accepted =
|
HydrologyPackProbe.SeedMorphologyResult accepted =
|
||||||
new HydrologyPackProbe.SeedMorphologyResult(642L, List.of(acceptedCourse), 0, List.of());
|
new HydrologyPackProbe.SeedMorphologyResult(642L, List.of(acceptedCourse), 0, List.of());
|
||||||
HydrologyPackProbe.SeedMorphologyResult empty =
|
HydrologyPackProbe.SeedMorphologyResult empty =
|
||||||
new HydrologyPackProbe.SeedMorphologyResult(1337L, List.of(), 0, List.of());
|
new HydrologyPackProbe.SeedMorphologyResult(1337L, List.of(), 0, List.of());
|
||||||
|
|
||||||
IllegalStateException perSeedFailure = assertThrows(
|
|
||||||
IllegalStateException.class,
|
|
||||||
() -> HydrologyPackProbe.PublishedMorphologyMetrics.requireValidResults(List.of(accepted, empty))
|
|
||||||
);
|
|
||||||
assertTrue(perSeedFailure.getMessage().contains("seed=1337"));
|
|
||||||
IllegalStateException emptyFailure = assertThrows(
|
|
||||||
IllegalStateException.class,
|
|
||||||
() -> HydrologyPackProbe.PublishedMorphologyMetrics.requireValidResults(List.of(empty))
|
|
||||||
);
|
|
||||||
assertTrue(emptyFailure.getMessage().contains("NO_SURFACE_COURSES"));
|
|
||||||
|
|
||||||
HydrologyPackProbe.CourseMorphologyResult rejectedCourse =
|
HydrologyPackProbe.CourseMorphologyResult rejectedCourse =
|
||||||
new HydrologyPackProbe.CourseMorphologyResult(
|
new HydrologyPackProbe.CourseMorphologyResult(
|
||||||
52L, 5L, 20, 80D, 80D, 0, 0D, 0D, 0, 0D, 0,
|
52L, 5L, 20, 80D, 80D, 0, 0D, 0D, 0, 0D, 2, 0D, 0,
|
||||||
0, 0, 0D, 0, 0, 0D, 0, 0D, 2, 0D, 0,
|
|
||||||
List.of("NARROW_INTERIOR_WIDTH"));
|
List.of("NARROW_INTERIOR_WIDTH"));
|
||||||
HydrologyPackProbe.SeedMorphologyResult rejected =
|
HydrologyPackProbe.SeedMorphologyResult rejected =
|
||||||
new HydrologyPackProbe.SeedMorphologyResult(
|
new HydrologyPackProbe.SeedMorphologyResult(
|
||||||
52L, List.of(rejectedCourse), 0, List.of("5:NARROW_INTERIOR_WIDTH"));
|
52L, List.of(rejectedCourse), 0, List.of("5:NARROW_INTERIOR_WIDTH"));
|
||||||
IllegalStateException failure = assertThrows(
|
|
||||||
IllegalStateException.class,
|
|
||||||
() -> HydrologyPackProbe.PublishedMorphologyMetrics.requireValidResults(
|
|
||||||
List.of(accepted, empty, rejected))
|
|
||||||
);
|
|
||||||
|
|
||||||
assertTrue(failure.getMessage().contains("seed=52"));
|
assertEquals(
|
||||||
|
List.of(),
|
||||||
|
HydrologyPackProbe.PublishedMorphologyMetrics.failures(List.of(accepted))
|
||||||
|
);
|
||||||
|
assertTrue(HydrologyPackProbe.PublishedMorphologyMetrics.failures(List.of(accepted, empty))
|
||||||
|
.toString().contains("seed=1337"));
|
||||||
|
assertTrue(HydrologyPackProbe.PublishedMorphologyMetrics.failures(List.of(empty))
|
||||||
|
.toString().contains("NO_SURFACE_COURSES"));
|
||||||
|
assertTrue(HydrologyPackProbe.PublishedMorphologyMetrics.failures(List.of())
|
||||||
|
.toString().contains("NO_SURFACE_COURSES"));
|
||||||
|
assertTrue(HydrologyPackProbe.PublishedMorphologyMetrics
|
||||||
|
.failures(List.of(accepted, empty, rejected)).toString().contains("seed=52"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -722,7 +744,6 @@ public final class HydrologyPackProbeTest {
|
|||||||
384,
|
384,
|
||||||
40D,
|
40D,
|
||||||
true,
|
true,
|
||||||
false,
|
|
||||||
centerline,
|
centerline,
|
||||||
thickChannel(centerline, 4, 24)
|
thickChannel(centerline, 4, 24)
|
||||||
);
|
);
|
||||||
@@ -738,8 +759,7 @@ public final class HydrologyPackProbeTest {
|
|||||||
File reportDirectory = temporaryFolder.newFolder("hydrology-reports");
|
File reportDirectory = temporaryFolder.newFolder("hydrology-reports");
|
||||||
HydrologyPackProbe.CourseMorphologyResult course =
|
HydrologyPackProbe.CourseMorphologyResult course =
|
||||||
new HydrologyPackProbe.CourseMorphologyResult(
|
new HydrologyPackProbe.CourseMorphologyResult(
|
||||||
1337L, 6L, 3, 2D, 2D, 0, 0D, 0D, 0, 0D, 0,
|
1337L, 6L, 3, 2D, 2D, 0, 0D, 0D, 0, 0D, 0, 0D, 0, List.of());
|
||||||
0, 0, 0D, 0, 0, 0D, 0, 0D, 0, 0D, 0, List.of());
|
|
||||||
HydrologyPackProbe.SeedMorphologyResult result =
|
HydrologyPackProbe.SeedMorphologyResult result =
|
||||||
new HydrologyPackProbe.SeedMorphologyResult(1337L, List.of(course), 0, List.of());
|
new HydrologyPackProbe.SeedMorphologyResult(1337L, List.of(course), 0, List.of());
|
||||||
Map<Long, Long> courseByCell = Map.of(
|
Map<Long, Long> courseByCell = Map.of(
|
||||||
@@ -763,7 +783,6 @@ public final class HydrologyPackProbeTest {
|
|||||||
assertEquals(3, image.getWidth());
|
assertEquals(3, image.getWidth());
|
||||||
assertEquals(2, image.getHeight());
|
assertEquals(2, image.getHeight());
|
||||||
assertTrue(metrics.contains("\"seed\": 1337"));
|
assertTrue(metrics.contains("\"seed\": 1337"));
|
||||||
assertTrue(metrics.contains("\"clippedTerminalCaps\": 0"));
|
|
||||||
assertTrue(metrics.contains("\"minimumInteriorWidth\": 0"));
|
assertTrue(metrics.contains("\"minimumInteriorWidth\": 0"));
|
||||||
assertTrue(metrics.contains("\"maximumWidthTroughDepthRatio\": 0.000000"));
|
assertTrue(metrics.contains("\"maximumWidthTroughDepthRatio\": 0.000000"));
|
||||||
assertTrue(metrics.contains("\"unexpectedLeaves\": 0"));
|
assertTrue(metrics.contains("\"unexpectedLeaves\": 0"));
|
||||||
@@ -773,8 +792,7 @@ public final class HydrologyPackProbeTest {
|
|||||||
long seed,
|
long seed,
|
||||||
long courseId,
|
long courseId,
|
||||||
List<HydrologyPoint> centerline,
|
List<HydrologyPoint> centerline,
|
||||||
Set<Long> ownedCells,
|
Set<Long> ownedCells
|
||||||
boolean terminalExposed
|
|
||||||
) {
|
) {
|
||||||
return new HydrologyPackProbe.CourseMorphologyInput(
|
return new HydrologyPackProbe.CourseMorphologyInput(
|
||||||
seed,
|
seed,
|
||||||
@@ -784,7 +802,6 @@ public final class HydrologyPackProbeTest {
|
|||||||
0,
|
0,
|
||||||
0D,
|
0D,
|
||||||
true,
|
true,
|
||||||
terminalExposed,
|
|
||||||
centerline,
|
centerline,
|
||||||
ownedCells
|
ownedCells
|
||||||
);
|
);
|
||||||
@@ -802,22 +819,6 @@ public final class HydrologyPackProbeTest {
|
|||||||
return Set.copyOf(cells);
|
return Set.copyOf(cells);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Set<Long> widenedSourceBasin(
|
|
||||||
List<HydrologyPoint> centerline,
|
|
||||||
int channelRadius,
|
|
||||||
int basinRadius,
|
|
||||||
int taperLength
|
|
||||||
) {
|
|
||||||
List<HydrologyPoint> raster = raster(centerline);
|
|
||||||
HashSet<Long> cells = new HashSet<>();
|
|
||||||
for (int index = 0; index < raster.size(); index++) {
|
|
||||||
double taper = Math.min(1D, index / (double) taperLength);
|
|
||||||
int radius = channelRadius + (int) StrictMath.round((basinRadius - channelRadius) * (1D - taper));
|
|
||||||
addDisc(cells, raster.get(index), radius);
|
|
||||||
}
|
|
||||||
return Set.copyOf(cells);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Set<Long> terminalBasinChannel(
|
private static Set<Long> terminalBasinChannel(
|
||||||
List<HydrologyPoint> centerline,
|
List<HydrologyPoint> centerline,
|
||||||
int channelRadius,
|
int channelRadius,
|
||||||
@@ -955,6 +956,73 @@ public final class HydrologyPackProbeTest {
|
|||||||
return new HydrologyColumnSample(x, z, naturalHeight, 63, false, "parent", List.of());
|
return new HydrologyColumnSample(x, z, naturalHeight, 63, false, "parent", List.of());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static RiverFootprint gradedRow(int westHeight, int centerHeight, int eastHeight) {
|
||||||
|
HydrologyColumnSample west = gradedColumn(-1, 0, westHeight);
|
||||||
|
HydrologyColumnSample center = gradedColumn(0, 0, centerHeight);
|
||||||
|
HydrologyColumnSample east = gradedColumn(1, 0, eastHeight);
|
||||||
|
return new RiverFootprint(Map.of(
|
||||||
|
RiverFootprint.pack(west.x(), west.z()), west,
|
||||||
|
RiverFootprint.pack(center.x(), center.z()), center,
|
||||||
|
RiverFootprint.pack(east.x(), east.z()), east
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HydrologyColumnSample gradedColumn(int x, int z, int height) {
|
||||||
|
return new HydrologyColumnSample(x, z, 80, 63, false, "parent", List.of(gradedLayer(height)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HydrologyColumnSample channelColumn(int x, int z, int bedY, int headY) {
|
||||||
|
return new HydrologyColumnSample(x, z, 80, 63, false, "parent", List.of(new HydrologyColumnLayer(
|
||||||
|
surfaceFeature(),
|
||||||
|
bedY,
|
||||||
|
headY,
|
||||||
|
headY,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
"water",
|
||||||
|
"surface",
|
||||||
|
"mouth",
|
||||||
|
"shore",
|
||||||
|
"bank",
|
||||||
|
"flooded"
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HydrologyColumnLayer gradedLayer(int height) {
|
||||||
|
return new HydrologyColumnLayer(
|
||||||
|
surfaceFeature(),
|
||||||
|
height,
|
||||||
|
height,
|
||||||
|
height,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
"water",
|
||||||
|
"surface",
|
||||||
|
"mouth",
|
||||||
|
"shore",
|
||||||
|
"bank",
|
||||||
|
"flooded"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HydrologyFeatureRef surfaceFeature() {
|
||||||
|
return new HydrologyFeatureRef(41L, HydrologyFeatureType.RIFFLE, 42L, 43L, 0, 70, 0, 1, 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
private static List<HydrologyPoint> raster(List<HydrologyPoint> points) {
|
private static List<HydrologyPoint> raster(List<HydrologyPoint> points) {
|
||||||
ArrayList<HydrologyPoint> raster = new ArrayList<>();
|
ArrayList<HydrologyPoint> raster = new ArrayList<>();
|
||||||
for (int pair = 0; pair < points.size() - 1; pair++) {
|
for (int pair = 0; pair < points.size() - 1; pair++) {
|
||||||
|
|||||||
@@ -8,16 +8,26 @@ import java.util.EnumSet;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
|
||||||
public final class HydrologyPlannerProbeTest {
|
public final class HydrologyPlannerProbeTest {
|
||||||
@Test
|
@Test
|
||||||
public void deterministicAcceptedCoveragePublishesEveryFeatureType() {
|
public void deterministicAcceptedCoveragePublishesEveryReachableFeatureType() {
|
||||||
Map<HydrologyFeatureType, HydrologyFeatureRef> coverage =
|
Map<HydrologyFeatureType, HydrologyFeatureRef> coverage =
|
||||||
HydrologyPlannerProbe.deterministicAcceptedCoverage();
|
HydrologyPlannerProbe.deterministicAcceptedCoverage();
|
||||||
|
|
||||||
assertEquals(EnumSet.allOf(HydrologyFeatureType.class), coverage.keySet());
|
assertEquals(HydrologyPlannerProbe.REQUIRED_FEATURE_TYPES, coverage.keySet());
|
||||||
for (Map.Entry<HydrologyFeatureType, HydrologyFeatureRef> entry : coverage.entrySet()) {
|
for (Map.Entry<HydrologyFeatureType, HydrologyFeatureRef> entry : coverage.entrySet()) {
|
||||||
assertEquals(entry.getKey(), entry.getValue().type());
|
assertEquals(entry.getKey(), entry.getValue().type());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void requiredCoverageExcludesTheRemovedRidgeBore() {
|
||||||
|
assertFalse(HydrologyPlannerProbe.REQUIRED_FEATURE_TYPES.contains(HydrologyFeatureType.RIDGE_BORE));
|
||||||
|
assertEquals(
|
||||||
|
EnumSet.complementOf(EnumSet.of(HydrologyFeatureType.RIDGE_BORE)),
|
||||||
|
HydrologyPlannerProbe.REQUIRED_FEATURE_TYPES
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user