Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions examples/_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
_MAJOR_WATER = {'river', 'canal'}
_MINOR_WATER = {'stream', 'drain', 'ditch'}


def print_controls():
print("\nControls:")
print(" W/S/A/D or Arrow keys: Move camera")
print(" Q/E or Page Up/Down: Move up/down")
print(" I/J/K/L: Look around")
print(" +/-: Adjust movement speed")
print(" G: Cycle overlay layers")
print(" O: Place observer (for viewshed)")
print(" V: Toggle viewshed (teal glow)")
print(" [/]: Adjust observer height")
print(" T: Toggle shadows")
print(" C: Cycle colormap")
print(" U: Toggle tile overlay")
print(" F: Screenshot")
print(" H: Toggle help overlay")
print(" X: Exit\n")


def classify_water_features(water_data):
"""Split water GeoJSON features into (major, minor, body) lists."""
major = []
minor = []
body = []
for f in water_data.get('features', []):
ww = (f.get('properties') or {}).get('waterway', '')
nat = (f.get('properties') or {}).get('natural', '')
if ww in _MAJOR_WATER:
major.append(f)
elif ww in _MINOR_WATER:
minor.append(f)
elif nat == 'water':
body.append(f)
else:
minor.append(f)
return major, minor, body


def scale_building_heights(bldg_data, elev_scale=0.025, default_height_m=8.0):
"""Scale MS building heights in-place to match terrain elevation scale."""
for feat in bldg_data.get("features", []):
props = feat.get("properties", {})
h = props.get("height", -1)
if not isinstance(h, (int, float)) or h <= 0:
h = default_height_m
props["height"] = h * elev_scale
44 changes: 4 additions & 40 deletions examples/capetown.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@

from rtxpy import fetch_dem, fetch_buildings, fetch_roads, fetch_water, fetch_firms
import rtxpy

# Water feature classification
_MAJOR_WATER = {'river', 'canal'}
_MINOR_WATER = {'stream', 'drain', 'ditch'}
from _utils import print_controls, classify_water_features, scale_building_heights

# Cape Town bounding box (lon_min, lat_min, lon_max, lat_max)
BOUNDS = (18.3, -34.2, 18.7, -33.8)
Expand Down Expand Up @@ -64,21 +61,7 @@ def load_terrain():
# Load terrain data (downloads if needed)
terrain = load_terrain()

print("\nControls:")
print(" W/S/A/D or Arrow keys: Move camera")
print(" Q/E or Page Up/Down: Move up/down")
print(" I/J/K/L: Look around")
print(" +/-: Adjust movement speed")
print(" G: Cycle overlay layers")
print(" O: Place observer (for viewshed)")
print(" V: Toggle viewshed (teal glow)")
print(" [/]: Adjust observer height")
print(" T: Toggle shadows")
print(" C: Cycle colormap")
print(" U: Toggle tile overlay")
print(" F: Screenshot")
print(" H: Toggle help overlay")
print(" X: Exit\n")
print_controls()

# Build Dataset with derived layers
print("Building Dataset with terrain analysis layers...")
Expand All @@ -102,15 +85,9 @@ def load_terrain():
cache_path=bldg_cache,
)

# Scale building heights to match the 0.025× terrain elevation.
elev_scale = 0.025
default_height_m = 8.0
for feat in bldg_data.get("features", []):
props = feat.get("properties", {})
h = props.get("height", -1)
if not isinstance(h, (int, float)) or h <= 0:
h = default_height_m
props["height"] = h * elev_scale
scale_building_heights(bldg_data, elev_scale, default_height_m)

mesh_cache_path = Path(__file__).parent / "capetown_buildings_mesh.npz"
with warnings.catch_warnings():
Expand Down Expand Up @@ -184,20 +161,7 @@ def load_terrain():
cache_path=water_cache,
)

major_features = []
minor_features = []
body_features = []
for f in water_data.get('features', []):
ww = (f.get('properties') or {}).get('waterway', '')
nat = (f.get('properties') or {}).get('natural', '')
if ww in _MAJOR_WATER:
major_features.append(f)
elif ww in _MINOR_WATER:
minor_features.append(f)
elif nat == 'water':
body_features.append(f)
else:
minor_features.append(f)
major_features, minor_features, body_features = classify_water_features(water_data)

if major_features:
major_fc = {"type": "FeatureCollection", "features": major_features}
Expand Down
46 changes: 4 additions & 42 deletions examples/guanajuato.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@
# Import rtxpy to register the .rtx accessor
from rtxpy import fetch_dem, fetch_buildings, fetch_roads, fetch_water, fetch_firms
import rtxpy

# Water feature classification
_MAJOR_WATER = {'river', 'canal'}
_MINOR_WATER = {'stream', 'drain', 'ditch'}
from _utils import print_controls, classify_water_features, scale_building_heights


def load_terrain():
Expand Down Expand Up @@ -69,21 +66,7 @@ def load_terrain():
# Load terrain data (downloads if needed)
terrain = load_terrain()

print("\nControls:")
print(" W/S/A/D or Arrow keys: Move camera")
print(" Q/E or Page Up/Down: Move up/down")
print(" I/J/K/L: Look around")
print(" +/-: Adjust movement speed")
print(" G: Cycle overlay layers")
print(" O: Place observer (for viewshed)")
print(" V: Toggle viewshed (teal glow)")
print(" [/]: Adjust observer height")
print(" T: Toggle shadows")
print(" C: Cycle colormap")
print(" U: Toggle tile overlay")
print(" F: Screenshot")
print(" H: Toggle help overlay")
print(" X: Exit\n")
print_controls()

# Build Dataset with derived layers
print("Building Dataset with terrain analysis layers...")
Expand All @@ -107,17 +90,9 @@ def load_terrain():
cache_path=bldg_cache,
)

# Scale building heights to match the 0.025× terrain elevation.
# MS data has height in metres (-1 = unknown); replace unknowns
# with a reasonable default and apply the same scale factor.
elev_scale = 0.025
default_height_m = 8.0
for feat in bldg_data.get("features", []):
props = feat.get("properties", {})
h = props.get("height", -1)
if not isinstance(h, (int, float)) or h <= 0:
h = default_height_m
props["height"] = h * elev_scale
scale_building_heights(bldg_data, elev_scale, default_height_m)

mesh_cache_path = Path(__file__).parent / "guanajuato_buildings_mesh.npz"
with warnings.catch_warnings():
Expand Down Expand Up @@ -191,20 +166,7 @@ def load_terrain():
cache_path=water_cache,
)

major_features = []
minor_features = []
body_features = []
for f in water_data.get('features', []):
ww = (f.get('properties') or {}).get('waterway', '')
nat = (f.get('properties') or {}).get('natural', '')
if ww in _MAJOR_WATER:
major_features.append(f)
elif ww in _MINOR_WATER:
minor_features.append(f)
elif nat == 'water':
body_features.append(f)
else:
minor_features.append(f)
major_features, minor_features, body_features = classify_water_features(water_data)

if major_features:
major_fc = {"type": "FeatureCollection", "features": major_features}
Expand Down
46 changes: 4 additions & 42 deletions examples/los_angeles.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,7 @@

from rtxpy import fetch_dem, fetch_buildings, fetch_roads, fetch_water, fetch_firms
import rtxpy

# Water feature classification
_MAJOR_WATER = {'river', 'canal'}
_MINOR_WATER = {'stream', 'drain', 'ditch'}
from _utils import print_controls, classify_water_features, scale_building_heights

# Los Angeles bounding box (WGS84)
# Focused area covering DTLA, Echo Park, Silver Lake, Griffith Park,
Expand Down Expand Up @@ -71,21 +68,7 @@ def load_terrain():
# Load terrain data (downloads if needed)
terrain = load_terrain()

print("\nControls:")
print(" W/S/A/D or Arrow keys: Move camera")
print(" Q/E or Page Up/Down: Move up/down")
print(" I/J/K/L: Look around")
print(" +/-: Adjust movement speed")
print(" G: Cycle overlay layers")
print(" O: Place observer (for viewshed)")
print(" V: Toggle viewshed (teal glow)")
print(" [/]: Adjust observer height")
print(" T: Toggle shadows")
print(" C: Cycle colormap")
print(" U: Toggle tile overlay")
print(" F: Screenshot")
print(" H: Toggle help overlay")
print(" X: Exit\n")
print_controls()

# Build Dataset with derived layers
print("Building Dataset with terrain analysis layers...")
Expand All @@ -109,17 +92,9 @@ def load_terrain():
cache_path=bldg_cache,
)

# Scale building heights to match the 0.5× terrain elevation.
# MS data has height in metres (-1 = unknown); replace unknowns
# with a reasonable default and apply the same scale factor.
elev_scale = 0.5
default_height_m = 8.0
for feat in bldg_data.get("features", []):
props = feat.get("properties", {})
h = props.get("height", -1)
if not isinstance(h, (int, float)) or h <= 0:
h = default_height_m
props["height"] = h * elev_scale
scale_building_heights(bldg_data, elev_scale, default_height_m)

mesh_cache_path = Path(__file__).parent / "los_angeles_buildings_mesh.npz"
with warnings.catch_warnings():
Expand Down Expand Up @@ -193,20 +168,7 @@ def load_terrain():
cache_path=water_cache,
)

major_features = []
minor_features = []
body_features = []
for f in water_data.get('features', []):
ww = (f.get('properties') or {}).get('waterway', '')
nat = (f.get('properties') or {}).get('natural', '')
if ww in _MAJOR_WATER:
major_features.append(f)
elif ww in _MINOR_WATER:
minor_features.append(f)
elif nat == 'water':
body_features.append(f)
else:
minor_features.append(f)
major_features, minor_features, body_features = classify_water_features(water_data)

if major_features:
major_fc = {"type": "FeatureCollection", "features": major_features}
Expand Down
36 changes: 3 additions & 33 deletions examples/playground.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@
# Import rtxpy to register the .rtx accessor
from rtxpy import fetch_dem, fetch_roads, fetch_water
import rtxpy

# Water feature classification
_MAJOR_WATER = {'river', 'canal'}
_MINOR_WATER = {'stream', 'drain', 'ditch'}
from _utils import print_controls, classify_water_features


def load_terrain():
Expand Down Expand Up @@ -69,21 +66,7 @@ def load_terrain():
# Load terrain data (downloads if needed)
terrain = load_terrain()

print("\nControls:")
print(" W/S/A/D or Arrow keys: Move camera")
print(" Q/E or Page Up/Down: Move up/down")
print(" I/J/K/L: Look around")
print(" +/-: Adjust movement speed")
print(" G: Cycle overlay layers")
print(" O: Place observer (for viewshed)")
print(" V: Toggle viewshed (teal glow)")
print(" [/]: Adjust observer height")
print(" T: Toggle shadows")
print(" C: Cycle colormap")
print(" U: Toggle tile overlay")
print(" F: Screenshot")
print(" H: Toggle help overlay")
print(" X: Exit\n")
print_controls()

# Build Dataset with derived layers
print("Building Dataset with terrain analysis layers...")
Expand Down Expand Up @@ -236,20 +219,7 @@ def load_terrain():
cache_path=water_cache,
)

major_features = []
minor_features = []
body_features = []
for f in water_data.get('features', []):
ww = (f.get('properties') or {}).get('waterway', '')
nat = (f.get('properties') or {}).get('natural', '')
if ww in _MAJOR_WATER:
major_features.append(f)
elif ww in _MINOR_WATER:
minor_features.append(f)
elif nat == 'water':
body_features.append(f)
else:
minor_features.append(f)
major_features, minor_features, body_features = classify_water_features(water_data)

if major_features:
major_fc = {"type": "FeatureCollection", "features": major_features}
Expand Down
Loading
Loading