Verify Ground Zero neighbor edges
This commit is contained in:
@@ -423,7 +423,7 @@ Target deliverable: A small group can join a server, spawn into one biome, gathe
|
|||||||
- [x] Add generated tile metadata record for the MVP tile.
|
- [x] Add generated tile metadata record for the MVP tile.
|
||||||
- [x] Verify terrain scale is 1 km x 1 km in Unreal.
|
- [x] Verify terrain scale is 1 km x 1 km in Unreal.
|
||||||
- [x] Verify terrain tile origin and centered Unreal bounds for the Ground Zero test map.
|
- [x] Verify terrain tile origin and centered Unreal bounds for the Ground Zero test map.
|
||||||
- [ ] Verify neighboring tile edge coordinates against the registry before multi-tile stitching.
|
- [x] Verify neighboring tile edge coordinates against the registry before multi-tile stitching.
|
||||||
- [ ] Add foliage pass.
|
- [ ] Add foliage pass.
|
||||||
- [~] Add resource nodes.
|
- [~] Add resource nodes.
|
||||||
- [ ] Add biome-appropriate natural resources based on Ground Zero.
|
- [ ] Add biome-appropriate natural resources based on Ground Zero.
|
||||||
@@ -1402,4 +1402,4 @@ Next version .01 priorities:
|
|||||||
|
|
||||||
Immediate next item:
|
Immediate next item:
|
||||||
|
|
||||||
- [ ] Verify neighboring tile edge coordinates against the registry before multi-tile stitching.
|
- [ ] Add foliage pass.
|
||||||
|
|||||||
+289
@@ -0,0 +1,289 @@
|
|||||||
|
{
|
||||||
|
"schema_version": 1,
|
||||||
|
"tile_id": "gz_us_ca_pacifica_utm10n_e544_n4160",
|
||||||
|
"registry_path": "Data/Tiles/ground_zero_tiles.json",
|
||||||
|
"grid_scheme": "prototype_utm_1km",
|
||||||
|
"verified_tile_count": 9,
|
||||||
|
"expected_neighbor_count": 8,
|
||||||
|
"found_neighbor_count": 8,
|
||||||
|
"all_passed": true,
|
||||||
|
"missing_neighbors": [],
|
||||||
|
"tile_shape_checks": [
|
||||||
|
{
|
||||||
|
"tile_id": "gz_us_ca_pacifica_utm10n_e544_n4160",
|
||||||
|
"passed": true,
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tile_id": "gz_us_ca_pacifica_utm10n_e543_n4159",
|
||||||
|
"passed": true,
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tile_id": "gz_us_ca_pacifica_utm10n_e544_n4159",
|
||||||
|
"passed": true,
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tile_id": "gz_us_ca_pacifica_utm10n_e545_n4159",
|
||||||
|
"passed": true,
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tile_id": "gz_us_ca_pacifica_utm10n_e543_n4160",
|
||||||
|
"passed": true,
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tile_id": "gz_us_ca_pacifica_utm10n_e545_n4160",
|
||||||
|
"passed": true,
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tile_id": "gz_us_ca_pacifica_utm10n_e543_n4161",
|
||||||
|
"passed": true,
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tile_id": "gz_us_ca_pacifica_utm10n_e544_n4161",
|
||||||
|
"passed": true,
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tile_id": "gz_us_ca_pacifica_utm10n_e545_n4161",
|
||||||
|
"passed": true,
|
||||||
|
"errors": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"neighbor_edge_checks": [
|
||||||
|
{
|
||||||
|
"direction": "n",
|
||||||
|
"neighbor_tile_id": "gz_us_ca_pacifica_utm10n_e544_n4161",
|
||||||
|
"expected_bounds_utm_m": {
|
||||||
|
"easting_min_m": 544000,
|
||||||
|
"northing_min_m": 4161000,
|
||||||
|
"easting_max_m": 545000,
|
||||||
|
"northing_max_m": 4162000
|
||||||
|
},
|
||||||
|
"actual_bounds_utm_m": {
|
||||||
|
"easting_min_m": 544000,
|
||||||
|
"northing_min_m": 4161000,
|
||||||
|
"easting_max_m": 545000,
|
||||||
|
"northing_max_m": 4162000
|
||||||
|
},
|
||||||
|
"shared_edge": {
|
||||||
|
"center_edge": "north",
|
||||||
|
"neighbor_edge": "south",
|
||||||
|
"shared_northing_m": 4161000,
|
||||||
|
"easting_span_m": [
|
||||||
|
544000,
|
||||||
|
545000
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"passed": true,
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"direction": "ne",
|
||||||
|
"neighbor_tile_id": "gz_us_ca_pacifica_utm10n_e545_n4161",
|
||||||
|
"expected_bounds_utm_m": {
|
||||||
|
"easting_min_m": 545000,
|
||||||
|
"northing_min_m": 4161000,
|
||||||
|
"easting_max_m": 546000,
|
||||||
|
"northing_max_m": 4162000
|
||||||
|
},
|
||||||
|
"actual_bounds_utm_m": {
|
||||||
|
"easting_min_m": 545000,
|
||||||
|
"northing_min_m": 4161000,
|
||||||
|
"easting_max_m": 546000,
|
||||||
|
"northing_max_m": 4162000
|
||||||
|
},
|
||||||
|
"shared_edge": {
|
||||||
|
"center_corner_touch": "ne",
|
||||||
|
"corner_touch_only": true,
|
||||||
|
"expected_bounds": {
|
||||||
|
"easting_min_m": 545000,
|
||||||
|
"northing_min_m": 4161000,
|
||||||
|
"easting_max_m": 546000,
|
||||||
|
"northing_max_m": 4162000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"passed": true,
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"direction": "e",
|
||||||
|
"neighbor_tile_id": "gz_us_ca_pacifica_utm10n_e545_n4160",
|
||||||
|
"expected_bounds_utm_m": {
|
||||||
|
"easting_min_m": 545000,
|
||||||
|
"northing_min_m": 4160000,
|
||||||
|
"easting_max_m": 546000,
|
||||||
|
"northing_max_m": 4161000
|
||||||
|
},
|
||||||
|
"actual_bounds_utm_m": {
|
||||||
|
"easting_min_m": 545000,
|
||||||
|
"northing_min_m": 4160000,
|
||||||
|
"easting_max_m": 546000,
|
||||||
|
"northing_max_m": 4161000
|
||||||
|
},
|
||||||
|
"shared_edge": {
|
||||||
|
"center_edge": "east",
|
||||||
|
"neighbor_edge": "west",
|
||||||
|
"shared_easting_m": 545000,
|
||||||
|
"northing_span_m": [
|
||||||
|
4160000,
|
||||||
|
4161000
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"passed": true,
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"direction": "se",
|
||||||
|
"neighbor_tile_id": "gz_us_ca_pacifica_utm10n_e545_n4159",
|
||||||
|
"expected_bounds_utm_m": {
|
||||||
|
"easting_min_m": 545000,
|
||||||
|
"northing_min_m": 4159000,
|
||||||
|
"easting_max_m": 546000,
|
||||||
|
"northing_max_m": 4160000
|
||||||
|
},
|
||||||
|
"actual_bounds_utm_m": {
|
||||||
|
"easting_min_m": 545000,
|
||||||
|
"northing_min_m": 4159000,
|
||||||
|
"easting_max_m": 546000,
|
||||||
|
"northing_max_m": 4160000
|
||||||
|
},
|
||||||
|
"shared_edge": {
|
||||||
|
"center_corner_touch": "se",
|
||||||
|
"corner_touch_only": true,
|
||||||
|
"expected_bounds": {
|
||||||
|
"easting_min_m": 545000,
|
||||||
|
"northing_min_m": 4159000,
|
||||||
|
"easting_max_m": 546000,
|
||||||
|
"northing_max_m": 4160000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"passed": true,
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"direction": "s",
|
||||||
|
"neighbor_tile_id": "gz_us_ca_pacifica_utm10n_e544_n4159",
|
||||||
|
"expected_bounds_utm_m": {
|
||||||
|
"easting_min_m": 544000,
|
||||||
|
"northing_min_m": 4159000,
|
||||||
|
"easting_max_m": 545000,
|
||||||
|
"northing_max_m": 4160000
|
||||||
|
},
|
||||||
|
"actual_bounds_utm_m": {
|
||||||
|
"easting_min_m": 544000,
|
||||||
|
"northing_min_m": 4159000,
|
||||||
|
"easting_max_m": 545000,
|
||||||
|
"northing_max_m": 4160000
|
||||||
|
},
|
||||||
|
"shared_edge": {
|
||||||
|
"center_edge": "south",
|
||||||
|
"neighbor_edge": "north",
|
||||||
|
"shared_northing_m": 4160000,
|
||||||
|
"easting_span_m": [
|
||||||
|
544000,
|
||||||
|
545000
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"passed": true,
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"direction": "sw",
|
||||||
|
"neighbor_tile_id": "gz_us_ca_pacifica_utm10n_e543_n4159",
|
||||||
|
"expected_bounds_utm_m": {
|
||||||
|
"easting_min_m": 543000,
|
||||||
|
"northing_min_m": 4159000,
|
||||||
|
"easting_max_m": 544000,
|
||||||
|
"northing_max_m": 4160000
|
||||||
|
},
|
||||||
|
"actual_bounds_utm_m": {
|
||||||
|
"easting_min_m": 543000,
|
||||||
|
"northing_min_m": 4159000,
|
||||||
|
"easting_max_m": 544000,
|
||||||
|
"northing_max_m": 4160000
|
||||||
|
},
|
||||||
|
"shared_edge": {
|
||||||
|
"center_corner_touch": "sw",
|
||||||
|
"corner_touch_only": true,
|
||||||
|
"expected_bounds": {
|
||||||
|
"easting_min_m": 543000,
|
||||||
|
"northing_min_m": 4159000,
|
||||||
|
"easting_max_m": 544000,
|
||||||
|
"northing_max_m": 4160000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"passed": true,
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"direction": "w",
|
||||||
|
"neighbor_tile_id": "gz_us_ca_pacifica_utm10n_e543_n4160",
|
||||||
|
"expected_bounds_utm_m": {
|
||||||
|
"easting_min_m": 543000,
|
||||||
|
"northing_min_m": 4160000,
|
||||||
|
"easting_max_m": 544000,
|
||||||
|
"northing_max_m": 4161000
|
||||||
|
},
|
||||||
|
"actual_bounds_utm_m": {
|
||||||
|
"easting_min_m": 543000,
|
||||||
|
"northing_min_m": 4160000,
|
||||||
|
"easting_max_m": 544000,
|
||||||
|
"northing_max_m": 4161000
|
||||||
|
},
|
||||||
|
"shared_edge": {
|
||||||
|
"center_edge": "west",
|
||||||
|
"neighbor_edge": "east",
|
||||||
|
"shared_easting_m": 544000,
|
||||||
|
"northing_span_m": [
|
||||||
|
4160000,
|
||||||
|
4161000
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"passed": true,
|
||||||
|
"errors": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"direction": "nw",
|
||||||
|
"neighbor_tile_id": "gz_us_ca_pacifica_utm10n_e543_n4161",
|
||||||
|
"expected_bounds_utm_m": {
|
||||||
|
"easting_min_m": 543000,
|
||||||
|
"northing_min_m": 4161000,
|
||||||
|
"easting_max_m": 544000,
|
||||||
|
"northing_max_m": 4162000
|
||||||
|
},
|
||||||
|
"actual_bounds_utm_m": {
|
||||||
|
"easting_min_m": 543000,
|
||||||
|
"northing_min_m": 4161000,
|
||||||
|
"easting_max_m": 544000,
|
||||||
|
"northing_max_m": 4162000
|
||||||
|
},
|
||||||
|
"shared_edge": {
|
||||||
|
"center_corner_touch": "nw",
|
||||||
|
"corner_touch_only": true,
|
||||||
|
"expected_bounds": {
|
||||||
|
"easting_min_m": 543000,
|
||||||
|
"northing_min_m": 4161000,
|
||||||
|
"easting_max_m": 544000,
|
||||||
|
"northing_max_m": 4162000
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"passed": true,
|
||||||
|
"errors": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stitching_decision": {
|
||||||
|
"ready_for_coordinate_based_neighbor_stitching": true,
|
||||||
|
"notes": [
|
||||||
|
"All Ground Zero neighbor placeholders align on exact 1000m UTM boundaries.",
|
||||||
|
"Cardinal neighbors share full 1km edges with no gap or overlap.",
|
||||||
|
"Diagonal neighbors touch at corners only.",
|
||||||
|
"This verifies registry coordinates, not yet elevation seam continuity."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# Ground Zero Neighbor Edge Verification
|
||||||
|
|
||||||
|
The Ground Zero tile and its eight immediate neighbor placeholders were checked
|
||||||
|
against the tile registry before any multi-tile stitching work.
|
||||||
|
|
||||||
|
## Inputs
|
||||||
|
|
||||||
|
- Registry: `Data/Tiles/ground_zero_tiles.json`
|
||||||
|
- Verification script: `Scripts/verify_ground_zero_neighbor_edges.py`
|
||||||
|
- Output:
|
||||||
|
`Data/Terrain/Analysis/gz_us_ca_pacifica_utm10n_e544_n4160/gz_us_ca_pacifica_utm10n_e544_n4160_neighbor_edge_verification.json`
|
||||||
|
|
||||||
|
## Result
|
||||||
|
|
||||||
|
The registry coordinate pass succeeded.
|
||||||
|
|
||||||
|
- Ground Zero tile:
|
||||||
|
`gz_us_ca_pacifica_utm10n_e544_n4160`
|
||||||
|
- Ground Zero bounds:
|
||||||
|
`544000,4160000 -> 545000,4161000` in EPSG:26910 / UTM zone 10N.
|
||||||
|
- Verified tile count: `9`
|
||||||
|
- Found neighbor count: `8`
|
||||||
|
- All tiles use `1000 m x 1000 m` bounds.
|
||||||
|
- All tile IDs match their minimum UTM kilometer coordinates.
|
||||||
|
- North, south, east, and west neighbors share exact full 1 km edges with the
|
||||||
|
Ground Zero tile.
|
||||||
|
- Northeast, southeast, southwest, and northwest neighbors touch Ground Zero at
|
||||||
|
corners only.
|
||||||
|
|
||||||
|
## Stitching Decision
|
||||||
|
|
||||||
|
The registry is ready for coordinate-based neighbor stitching around Ground
|
||||||
|
Zero. This pass verifies tile bounds and adjacency only; it does not verify
|
||||||
|
elevation seam continuity because neighbor DEM extraction has not been run yet.
|
||||||
|
|
||||||
|
The next terrain stitching pass should extract or generate the relevant
|
||||||
|
neighbor DEMs, compare edge sample elevations, and then choose the seam blending
|
||||||
|
rule.
|
||||||
@@ -0,0 +1,223 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""Verify Ground Zero neighbor tile edges before multi-tile stitching."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
REPO_ROOT = Path(__file__).resolve().parents[1]
|
||||||
|
REGISTRY_PATH = REPO_ROOT / "Data/Tiles/ground_zero_tiles.json"
|
||||||
|
OUTPUT_PATH = (
|
||||||
|
REPO_ROOT
|
||||||
|
/ "Data/Terrain/Analysis/gz_us_ca_pacifica_utm10n_e544_n4160/"
|
||||||
|
/ "gz_us_ca_pacifica_utm10n_e544_n4160_neighbor_edge_verification.json"
|
||||||
|
)
|
||||||
|
|
||||||
|
GROUND_ZERO_TILE_ID = "gz_us_ca_pacifica_utm10n_e544_n4160"
|
||||||
|
TILE_SIZE_M = 1000
|
||||||
|
|
||||||
|
DIRECTION_OFFSETS = {
|
||||||
|
"n": (0, 1),
|
||||||
|
"ne": (1, 1),
|
||||||
|
"e": (1, 0),
|
||||||
|
"se": (1, -1),
|
||||||
|
"s": (0, -1),
|
||||||
|
"sw": (-1, -1),
|
||||||
|
"w": (-1, 0),
|
||||||
|
"nw": (-1, 1),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def load_registry() -> dict:
|
||||||
|
return json.loads(REGISTRY_PATH.read_text())
|
||||||
|
|
||||||
|
|
||||||
|
def grid(tile: dict) -> dict:
|
||||||
|
return tile["grid"]
|
||||||
|
|
||||||
|
|
||||||
|
def expected_tile_id(tile_family: str, easting_min_m: int, northing_min_m: int) -> str:
|
||||||
|
return f"{tile_family}_e{easting_min_m // 1000}_n{northing_min_m // 1000}"
|
||||||
|
|
||||||
|
|
||||||
|
def verify_tile_shape(tile: dict) -> list[str]:
|
||||||
|
errors: list[str] = []
|
||||||
|
g = grid(tile)
|
||||||
|
width = g["easting_max_m"] - g["easting_min_m"]
|
||||||
|
height = g["northing_max_m"] - g["northing_min_m"]
|
||||||
|
|
||||||
|
if width != TILE_SIZE_M:
|
||||||
|
errors.append(f"width is {width}m, expected {TILE_SIZE_M}m")
|
||||||
|
if height != TILE_SIZE_M:
|
||||||
|
errors.append(f"height is {height}m, expected {TILE_SIZE_M}m")
|
||||||
|
if g["tile_size_m"] != TILE_SIZE_M:
|
||||||
|
errors.append(f"tile_size_m is {g['tile_size_m']}, expected {TILE_SIZE_M}")
|
||||||
|
if g["utm_zone"] != "10N":
|
||||||
|
errors.append(f"utm_zone is {g['utm_zone']}, expected 10N")
|
||||||
|
if g["projection"] != "WGS84 / UTM zone 10N":
|
||||||
|
errors.append(f"projection is {g['projection']}, expected WGS84 / UTM zone 10N")
|
||||||
|
|
||||||
|
tile_family = "_".join(tile["tile_id"].split("_")[:-2])
|
||||||
|
expected_id = expected_tile_id(tile_family, g["easting_min_m"], g["northing_min_m"])
|
||||||
|
if tile["tile_id"] != expected_id:
|
||||||
|
errors.append(f"tile_id is {tile['tile_id']}, expected {expected_id}")
|
||||||
|
|
||||||
|
return errors
|
||||||
|
|
||||||
|
|
||||||
|
def expected_bounds(center_grid: dict, dx: int, dy: int) -> dict:
|
||||||
|
easting_min = center_grid["easting_min_m"] + dx * TILE_SIZE_M
|
||||||
|
northing_min = center_grid["northing_min_m"] + dy * TILE_SIZE_M
|
||||||
|
return {
|
||||||
|
"easting_min_m": easting_min,
|
||||||
|
"northing_min_m": northing_min,
|
||||||
|
"easting_max_m": easting_min + TILE_SIZE_M,
|
||||||
|
"northing_max_m": northing_min + TILE_SIZE_M,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def verify_neighbor_edge(direction: str, center: dict, neighbor: dict) -> dict:
|
||||||
|
center_grid = grid(center)
|
||||||
|
neighbor_grid = grid(neighbor)
|
||||||
|
dx, dy = DIRECTION_OFFSETS[direction]
|
||||||
|
expected = expected_bounds(center_grid, dx, dy)
|
||||||
|
|
||||||
|
errors: list[str] = []
|
||||||
|
for key, expected_value in expected.items():
|
||||||
|
actual_value = neighbor_grid[key]
|
||||||
|
if actual_value != expected_value:
|
||||||
|
errors.append(f"{key} is {actual_value}, expected {expected_value}")
|
||||||
|
|
||||||
|
if direction == "n":
|
||||||
|
shared_edge = {
|
||||||
|
"center_edge": "north",
|
||||||
|
"neighbor_edge": "south",
|
||||||
|
"shared_northing_m": center_grid["northing_max_m"],
|
||||||
|
"easting_span_m": [center_grid["easting_min_m"], center_grid["easting_max_m"]],
|
||||||
|
}
|
||||||
|
if neighbor_grid["northing_min_m"] != center_grid["northing_max_m"]:
|
||||||
|
errors.append("north neighbor south edge does not meet Ground Zero north edge")
|
||||||
|
elif direction == "s":
|
||||||
|
shared_edge = {
|
||||||
|
"center_edge": "south",
|
||||||
|
"neighbor_edge": "north",
|
||||||
|
"shared_northing_m": center_grid["northing_min_m"],
|
||||||
|
"easting_span_m": [center_grid["easting_min_m"], center_grid["easting_max_m"]],
|
||||||
|
}
|
||||||
|
if neighbor_grid["northing_max_m"] != center_grid["northing_min_m"]:
|
||||||
|
errors.append("south neighbor north edge does not meet Ground Zero south edge")
|
||||||
|
elif direction == "e":
|
||||||
|
shared_edge = {
|
||||||
|
"center_edge": "east",
|
||||||
|
"neighbor_edge": "west",
|
||||||
|
"shared_easting_m": center_grid["easting_max_m"],
|
||||||
|
"northing_span_m": [center_grid["northing_min_m"], center_grid["northing_max_m"]],
|
||||||
|
}
|
||||||
|
if neighbor_grid["easting_min_m"] != center_grid["easting_max_m"]:
|
||||||
|
errors.append("east neighbor west edge does not meet Ground Zero east edge")
|
||||||
|
elif direction == "w":
|
||||||
|
shared_edge = {
|
||||||
|
"center_edge": "west",
|
||||||
|
"neighbor_edge": "east",
|
||||||
|
"shared_easting_m": center_grid["easting_min_m"],
|
||||||
|
"northing_span_m": [center_grid["northing_min_m"], center_grid["northing_max_m"]],
|
||||||
|
}
|
||||||
|
if neighbor_grid["easting_max_m"] != center_grid["easting_min_m"]:
|
||||||
|
errors.append("west neighbor east edge does not meet Ground Zero west edge")
|
||||||
|
else:
|
||||||
|
shared_edge = {
|
||||||
|
"center_corner_touch": direction,
|
||||||
|
"corner_touch_only": True,
|
||||||
|
"expected_bounds": expected,
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
"direction": direction,
|
||||||
|
"neighbor_tile_id": neighbor["tile_id"],
|
||||||
|
"expected_bounds_utm_m": expected,
|
||||||
|
"actual_bounds_utm_m": {
|
||||||
|
"easting_min_m": neighbor_grid["easting_min_m"],
|
||||||
|
"northing_min_m": neighbor_grid["northing_min_m"],
|
||||||
|
"easting_max_m": neighbor_grid["easting_max_m"],
|
||||||
|
"northing_max_m": neighbor_grid["northing_max_m"],
|
||||||
|
},
|
||||||
|
"shared_edge": shared_edge,
|
||||||
|
"passed": not errors,
|
||||||
|
"errors": errors,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
registry = load_registry()
|
||||||
|
tiles_by_id = {tile["tile_id"]: tile for tile in registry["tiles"]}
|
||||||
|
center = tiles_by_id[GROUND_ZERO_TILE_ID]
|
||||||
|
|
||||||
|
tile_shape_checks = []
|
||||||
|
for tile in registry["tiles"]:
|
||||||
|
errors = verify_tile_shape(tile)
|
||||||
|
tile_shape_checks.append(
|
||||||
|
{
|
||||||
|
"tile_id": tile["tile_id"],
|
||||||
|
"passed": not errors,
|
||||||
|
"errors": errors,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
neighbor_checks = []
|
||||||
|
missing_neighbors = []
|
||||||
|
for direction in ["n", "ne", "e", "se", "s", "sw", "w", "nw"]:
|
||||||
|
neighbor_id = center["neighbors"].get(direction)
|
||||||
|
if not neighbor_id or neighbor_id not in tiles_by_id:
|
||||||
|
missing_neighbors.append({"direction": direction, "neighbor_tile_id": neighbor_id})
|
||||||
|
continue
|
||||||
|
neighbor_checks.append(verify_neighbor_edge(direction, center, tiles_by_id[neighbor_id]))
|
||||||
|
|
||||||
|
passed = (
|
||||||
|
not missing_neighbors
|
||||||
|
and all(check["passed"] for check in neighbor_checks)
|
||||||
|
and all(check["passed"] for check in tile_shape_checks)
|
||||||
|
)
|
||||||
|
|
||||||
|
result = {
|
||||||
|
"schema_version": 1,
|
||||||
|
"tile_id": GROUND_ZERO_TILE_ID,
|
||||||
|
"registry_path": str(REGISTRY_PATH.relative_to(REPO_ROOT)),
|
||||||
|
"grid_scheme": registry["grid_scheme"],
|
||||||
|
"verified_tile_count": len(registry["tiles"]),
|
||||||
|
"expected_neighbor_count": 8,
|
||||||
|
"found_neighbor_count": len(neighbor_checks),
|
||||||
|
"all_passed": passed,
|
||||||
|
"missing_neighbors": missing_neighbors,
|
||||||
|
"tile_shape_checks": tile_shape_checks,
|
||||||
|
"neighbor_edge_checks": neighbor_checks,
|
||||||
|
"stitching_decision": {
|
||||||
|
"ready_for_coordinate_based_neighbor_stitching": passed,
|
||||||
|
"notes": [
|
||||||
|
"All Ground Zero neighbor placeholders align on exact 1000m UTM boundaries.",
|
||||||
|
"Cardinal neighbors share full 1km edges with no gap or overlap.",
|
||||||
|
"Diagonal neighbors touch at corners only.",
|
||||||
|
"This verifies registry coordinates, not yet elevation seam continuity.",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
OUTPUT_PATH.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
OUTPUT_PATH.write_text(json.dumps(result, indent=2) + "\n")
|
||||||
|
print(f"Wrote {OUTPUT_PATH.relative_to(REPO_ROOT)}")
|
||||||
|
print(
|
||||||
|
json.dumps(
|
||||||
|
{
|
||||||
|
"all_passed": result["all_passed"],
|
||||||
|
"verified_tile_count": result["verified_tile_count"],
|
||||||
|
"found_neighbor_count": result["found_neighbor_count"],
|
||||||
|
"missing_neighbors": result["missing_neighbors"],
|
||||||
|
},
|
||||||
|
indent=2,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user