add a bunch of (false) information to the map
This commit is contained in:
240
tooling/process_hopewell_sites.py
Normal file
240
tooling/process_hopewell_sites.py
Normal file
@@ -0,0 +1,240 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Process Hopewell Earthworks Sites
|
||||
Acquires lidar tiles, processes them to mound format, and generates metadata.
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import json
|
||||
import os
|
||||
from pathlib import Path
|
||||
from typing import List, Dict, Tuple
|
||||
|
||||
# Define all sites of interest
|
||||
SITES = [
|
||||
{
|
||||
"name": "Newark Octagon Earthworks",
|
||||
"coordinates": [(-82.4463745, 40.0519828)],
|
||||
"description": "Part of the Newark Earthworks complex, the Octagon is precisely aligned to the 18.6-year lunar cycle. Connected to a 50-acre circle, this geometric earthwork demonstrates sophisticated astronomical knowledge. The Octagon's eight walls and Observatory Circle form one of only two known circle-octagon pairs in the Hopewell world.",
|
||||
"type": "earthwork",
|
||||
"significance": "unesco_world_heritage",
|
||||
"azimuth_alignment": 211,
|
||||
},
|
||||
{
|
||||
"name": "Great Circle Earthworks",
|
||||
"coordinates": [(-82.4277555, 40.0402671)],
|
||||
"description": "A nearly perfect circle 1,200 feet in diameter, enclosing 30 acres. The earthen wall is lined by a deep interior ditch. Located in Heath, Ohio, this is one of the largest circular earthworks in the Americas and serves as the site of the Newark Earthworks Museum.",
|
||||
"type": "earthwork",
|
||||
"significance": "unesco_world_heritage",
|
||||
},
|
||||
{
|
||||
"name": "Van Voorhis Walls",
|
||||
"coordinates": [
|
||||
(-82.446375, 40.051983),
|
||||
(-82.447, 40.048),
|
||||
(-82.448, 40.045),
|
||||
(-82.450, 40.040),
|
||||
],
|
||||
"description": "The best-preserved section of the Great Hopewell Road, extending 2.5 miles south from the Newark Octagon to Ramp Creek. This confirmed earthwork consists of parallel walls approximately 50 meters (150-200 feet) apart, aligned on an azimuth of 211°. Still visible above ground in woodland areas too swampy to farm.",
|
||||
"type": "road_confirmed",
|
||||
"significance": "confirmed_road_section",
|
||||
"azimuth_alignment": 211,
|
||||
},
|
||||
{
|
||||
"name": "Mound City Group",
|
||||
"coordinates": [(-83.0065767, 39.3744923)],
|
||||
"description": "The headquarters of Hopewell Culture National Historical Park. Contains 23 burial mounds within a nearly square earthen enclosure along the Scioto River. Each mound covered a charnel house where the dead were cremated. Excavations revealed spectacular artifacts including effigy pipes, mica, and copper.",
|
||||
"type": "earthwork",
|
||||
"significance": "unesco_world_heritage",
|
||||
},
|
||||
{
|
||||
"name": "Hopeton Earthworks",
|
||||
"coordinates": [(-82.9809185, 39.3790743)],
|
||||
"description": "A geometric earthwork complex featuring a circle (320m diameter) and square of similar size, connected by parallel earthen lines aligned to the winter solstice. Located on a high terrace on the east side of the Scioto River, northeast from Mound City.",
|
||||
"type": "earthwork",
|
||||
"significance": "unesco_world_heritage",
|
||||
"astronomical_alignment": "winter_solstice",
|
||||
},
|
||||
{
|
||||
"name": "Hopewell Mound Group",
|
||||
"coordinates": [(-83.0844809, 39.3608166)],
|
||||
"description": "The type site for the Hopewell culture, named after former landowner M. Cloud Hopewell. Contains 29 mounds including the largest known Hopewell mound—500 feet long and consisting of three conjoined circles. A semicircular earthwork encloses the main mound and four additional mounds.",
|
||||
"type": "earthwork",
|
||||
"significance": "type_site",
|
||||
},
|
||||
{
|
||||
"name": "Seip Earthworks",
|
||||
"coordinates": [(-83.2214086, 39.2416867)],
|
||||
"description": "One of the largest Hopewell complexes, featuring two circles and a square enclosing 121 acres. The Seip-Pricer Mound stands 30 feet high. The square measures exactly 27 acres, matching four other nearby Hopewell sites, suggesting a common unit of measurement. Contains evidence of elaborate burials and exotic trade goods.",
|
||||
"type": "earthwork",
|
||||
"significance": "unesco_world_heritage",
|
||||
},
|
||||
{
|
||||
"name": "High Bank Works",
|
||||
"coordinates": [(-82.94, 39.26)],
|
||||
"description": "Features a circle-octagon pair identical to the Newark Earthworks—both circles are exactly 1,050 feet in diameter. Located 60 miles from Newark on a terrace 75-80 feet above the Scioto River. The octagon is precisely aligned to the northernmost moonrise of the 18.6-year lunar cycle. Currently a research preserve, not open to the public.",
|
||||
"type": "earthwork",
|
||||
"significance": "unesco_world_heritage",
|
||||
"astronomical_alignment": "lunar_standstill",
|
||||
"paired_with": "Newark Octagon Earthworks",
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def run_command(cmd: List[str], description: str) -> subprocess.CompletedProcess:
|
||||
"""Run a shell command and return the result."""
|
||||
print(f"\n{'='*60}")
|
||||
print(f"{description}")
|
||||
print(f"{'='*60}")
|
||||
print(f"Running: {' '.join(cmd)}")
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
print(f"ERROR: {result.stderr}")
|
||||
else:
|
||||
print(f"SUCCESS: {result.stdout}")
|
||||
return result
|
||||
|
||||
|
||||
def acquire_tiles(site: Dict, output_dir: str) -> List[str]:
|
||||
"""Acquire lidar tiles for a site."""
|
||||
coords = site["coordinates"]
|
||||
|
||||
# Build the request_tiles.py command
|
||||
cmd = ["python", "./tooling/request_tiles.py"]
|
||||
for lon, lat in coords:
|
||||
cmd.extend(["--coords", str(lon), str(lat)])
|
||||
cmd.extend(["--output", output_dir])
|
||||
|
||||
result = run_command(cmd, f"Acquiring tiles for {site['name']}")
|
||||
|
||||
# Parse the output JSON to get tile names
|
||||
if result.returncode == 0:
|
||||
try:
|
||||
data = json.loads(result.stdout)
|
||||
tiles = [
|
||||
tile["tile_name"]
|
||||
for tile in data.get("tiles", [])
|
||||
if tile.get("status") in ["downloaded", "already_exists"]
|
||||
]
|
||||
return tiles
|
||||
except json.JSONDecodeError:
|
||||
print(f"Warning: Could not parse JSON output for {site['name']}")
|
||||
return []
|
||||
return []
|
||||
|
||||
|
||||
def unzip_tiles(tiles: List[str], lidar_dir: str) -> None:
|
||||
"""Unzip all downloaded tiles."""
|
||||
for tile in tiles:
|
||||
zip_path = os.path.join(lidar_dir, f"{tile}.zip")
|
||||
extract_dir = os.path.join(lidar_dir, tile)
|
||||
|
||||
if not os.path.exists(zip_path):
|
||||
print(f"Warning: {zip_path} does not exist, skipping")
|
||||
continue
|
||||
|
||||
cmd = ["unzip", "-o", zip_path, "-d", extract_dir]
|
||||
run_command(cmd, f"Unzipping {tile}")
|
||||
|
||||
|
||||
def convert_to_mound(tiles: List[str], lidar_dir: str, mound_dir: str) -> None:
|
||||
"""Convert LAS files to mound format."""
|
||||
for tile in tiles:
|
||||
las_path = os.path.join(lidar_dir, tile, f"{tile}.las")
|
||||
mound_path = os.path.join(mound_dir, f"{tile}.mound")
|
||||
|
||||
if not os.path.exists(las_path):
|
||||
print(f"Warning: {las_path} does not exist, skipping")
|
||||
continue
|
||||
|
||||
cmd = ["python", "tooling/las2mound.py", las_path, mound_path]
|
||||
run_command(cmd, f"Converting {tile} to mound format")
|
||||
|
||||
|
||||
def generate_metadata(sites: List[Dict], output_path: str) -> None:
|
||||
"""Generate a JSON metadata file with all site information."""
|
||||
metadata = {
|
||||
"generated": "2025-01-21",
|
||||
"description": "Hopewell Ceremonial Earthworks and Great Hopewell Road Sites",
|
||||
"sites": sites,
|
||||
"summary": {
|
||||
"total_sites": len(sites),
|
||||
"unesco_sites": len([s for s in sites if s.get("significance") == "unesco_world_heritage"]),
|
||||
"confirmed_road_sections": len([s for s in sites if s.get("type") == "road_confirmed"]),
|
||||
}
|
||||
}
|
||||
|
||||
with open(output_path, 'w') as f:
|
||||
json.dump(metadata, f, indent=2)
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
print(f"Metadata written to {output_path}")
|
||||
print(f"{'='*60}")
|
||||
|
||||
|
||||
def main():
|
||||
"""Main processing pipeline."""
|
||||
# Setup directories
|
||||
base_dir = Path("./data")
|
||||
lidar_dir = base_dir / "LIDAR"
|
||||
mound_dir = base_dir / "MOUND"
|
||||
|
||||
lidar_dir.mkdir(parents=True, exist_ok=True)
|
||||
mound_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
print(f"""
|
||||
╔══════════════════════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ HOPEWELL EARTHWORKS LIDAR PROCESSING PIPELINE ║
|
||||
║ ║
|
||||
║ Processing {len(SITES)} sites of interest: ║
|
||||
║ - UNESCO World Heritage Sites ║
|
||||
║ - Confirmed Great Hopewell Road sections ║
|
||||
║ - Type sites and major earthwork complexes ║
|
||||
║ ║
|
||||
╚══════════════════════════════════════════════════════════════════════════╝
|
||||
""")
|
||||
|
||||
# Process each site
|
||||
for site in SITES:
|
||||
print(f"\n{'#'*80}")
|
||||
print(f"# PROCESSING: {site['name']}")
|
||||
print(f"# Type: {site['type']}")
|
||||
print(f"# Coordinates: {len(site['coordinates'])} point(s)")
|
||||
print(f"{'#'*80}")
|
||||
|
||||
# Step 1: Acquire tiles
|
||||
tiles = acquire_tiles(site, str(lidar_dir))
|
||||
if not tiles:
|
||||
print(f"Warning: No tiles acquired for {site['name']}")
|
||||
site["tiles"] = []
|
||||
continue
|
||||
|
||||
site["tiles"] = tiles
|
||||
print(f"\nAcquired {len(tiles)} tiles: {', '.join(tiles)}")
|
||||
|
||||
# Step 2: Unzip tiles
|
||||
unzip_tiles(tiles, str(lidar_dir))
|
||||
|
||||
# Step 3: Convert to mound format
|
||||
convert_to_mound(tiles, str(lidar_dir), str(mound_dir))
|
||||
|
||||
# Step 4: Generate metadata
|
||||
metadata_path = base_dir / "hopewell_sites_metadata.json"
|
||||
generate_metadata(SITES, str(metadata_path))
|
||||
|
||||
print(f"""
|
||||
╔══════════════════════════════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║ PROCESSING COMPLETE ║
|
||||
║ ║
|
||||
║ Metadata: {str(metadata_path):55} ║
|
||||
║ Lidar data: {str(lidar_dir):58} ║
|
||||
║ Mound files: {str(mound_dir):57} ║
|
||||
║ ║
|
||||
╚══════════════════════════════════════════════════════════════════════════╝
|
||||
""")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user