Python parser for the Shuttle Radar Topography Mission elevation data
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Sophisticated algorithms for elevation estimation including Inverse Distance Weighted (IDW) interpolation and approximation methods for improved accuracy between data points.
Advanced interpolation method that estimates elevation values by weighting nearby data points based on their inverse distance, providing smoother and more accurate elevation estimates.
Note: These are private methods (indicated by the underscore prefix) intended for internal use, but they can be accessed directly if needed for advanced interpolation control.
class GeoElevationData:
def _IDW(self, latitude: float, longitude: float, radius: float = 1) -> Optional[float]: ...
class GeoElevationFile:
def _InverseDistanceWeighted(self, latitude: float, longitude: float, radius: float = 1) -> Optional[float]: ...Parameters:
latitude (float): Target latitude coordinatelongitude (float): Target longitude coordinateradius (float): Interpolation radius (1 or 2). Default: 1
radius=1: 3x3 matrix of surrounding pointsradius=2: 5x5 matrix of surrounding pointsReturns: Interpolated elevation value in meters, or None if insufficient data
Usage Example:
import srtm
elevation_data = srtm.get_data()
# Standard elevation lookup
standard_elevation = elevation_data.get_elevation(45.8566, 7.8566)
# IDW interpolation with 3x3 matrix (radius=1)
idw_elevation_r1 = elevation_data._IDW(45.8566, 7.8566, radius=1)
# IDW interpolation with 5x5 matrix (radius=2)
idw_elevation_r2 = elevation_data._IDW(45.8566, 7.8566, radius=2)
print(f"Standard elevation: {standard_elevation}m")
print(f"IDW interpolation (r=1): {idw_elevation_r1}m")
print(f"IDW interpolation (r=2): {idw_elevation_r2}m")
# Calculate differences
if all(x is not None for x in [standard_elevation, idw_elevation_r1, idw_elevation_r2]):
diff_r1 = abs(standard_elevation - idw_elevation_r1)
diff_r2 = abs(standard_elevation - idw_elevation_r2)
print(f"Difference (r=1): {diff_r1:.2f}m")
print(f"Difference (r=2): {diff_r2:.2f}m")Simpler approximation method using distance-weighted averaging of nearby elevation points for smoother elevation profiles.
class GeoElevationFile:
def approximation(self, latitude: float, longitude: float) -> Optional[float]: ...Parameters:
latitude (float): Target latitude coordinatelongitude (float): Target longitude coordinateReturns: Approximate elevation value in meters, or None if no data available
Usage Example:
import srtm
elevation_data = srtm.get_data()
# Get specific SRTM file
srtm_file = elevation_data.get_file(45.8566, 7.8566)
if srtm_file:
# Direct elevation lookup
direct_elevation = srtm_file.get_elevation(45.8566, 7.8566)
# Distance-weighted approximation
approx_elevation = srtm_file.approximation(45.8566, 7.8566)
print(f"Direct elevation: {direct_elevation}m")
print(f"Approximated elevation: {approx_elevation}m")
if direct_elevation and approx_elevation:
difference = abs(direct_elevation - approx_elevation)
print(f"Approximation difference: {difference:.2f}m")Compare different interpolation methods to understand their effects on elevation accuracy and smoothness.
Usage Example:
import srtm
import numpy as np
def compare_interpolation_methods(latitude, longitude):
"""Compare different interpolation methods for a given coordinate."""
elevation_data = srtm.get_data()
srtm_file = elevation_data.get_file(latitude, longitude)
results = {}
# Direct lookup (no interpolation)
results['direct'] = elevation_data.get_elevation(latitude, longitude, approximate=False)
# Built-in approximation
results['approximate'] = elevation_data.get_elevation(latitude, longitude, approximate=True)
# IDW with different radii
results['idw_r1'] = elevation_data._IDW(latitude, longitude, radius=1)
results['idw_r2'] = elevation_data._IDW(latitude, longitude, radius=2)
# File-level approximation
if srtm_file:
results['file_approx'] = srtm_file.approximation(latitude, longitude)
results['file_idw'] = srtm_file._InverseDistanceWeighted(latitude, longitude, radius=1)
return results
# Test coordinates in mountainous area
test_coords = [
(45.8566, 7.8566), # Mont Blanc region
(46.5197, 7.9553), # Jungfrau region
(45.9763, 7.6584) # Matterhorn region
]
for lat, lon in test_coords:
print(f"\nInterpolation comparison for ({lat}, {lon}):")
results = compare_interpolation_methods(lat, lon)
for method, elevation in results.items():
if elevation is not None:
print(f" {method:12}: {elevation:7.2f}m")
else:
print(f" {method:12}: No data")
# Calculate variations
valid_results = {k: v for k, v in results.items() if v is not None}
if len(valid_results) > 1:
elevations = list(valid_results.values())
std_dev = np.std(elevations)
range_val = max(elevations) - min(elevations)
print(f" Standard deviation: {std_dev:.2f}m")
print(f" Range: {range_val:.2f}m")Apply interpolation methods to multiple coordinates efficiently for large-scale elevation analysis.
Usage Example:
import srtm
import csv
from typing import List, Tuple
def batch_interpolation(coordinates: List[Tuple[float, float]], method='idw_r1'):
"""Apply interpolation to a batch of coordinates."""
elevation_data = srtm.get_data(batch_mode=True)
results = []
for i, (lat, lon) in enumerate(coordinates):
if i % 100 == 0:
print(f"Processing coordinate {i+1}/{len(coordinates)}")
if method == 'direct':
elevation = elevation_data.get_elevation(lat, lon, approximate=False)
elif method == 'approximate':
elevation = elevation_data.get_elevation(lat, lon, approximate=True)
elif method == 'idw_r1':
elevation = elevation_data._IDW(lat, lon, radius=1)
elif method == 'idw_r2':
elevation = elevation_data._IDW(lat, lon, radius=2)
else:
elevation = elevation_data.get_elevation(lat, lon)
results.append({
'latitude': lat,
'longitude': lon,
'elevation': elevation,
'method': method
})
return results
# Generate test coordinates along a hiking trail
trail_coordinates = []
start_lat, start_lon = 45.8, 7.8
for i in range(50):
lat = start_lat + (i * 0.001) # Move north
lon = start_lon + (i * 0.0005) # Move slightly east
trail_coordinates.append((lat, lon))
# Process with different methods
methods = ['direct', 'approximate', 'idw_r1', 'idw_r2']
for method in methods:
print(f"\nProcessing with method: {method}")
results = batch_interpolation(trail_coordinates, method)
# Save results to CSV
filename = f"elevation_trail_{method}.csv"
with open(filename, 'w', newline='') as csvfile:
fieldnames = ['latitude', 'longitude', 'elevation', 'method']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(results)
# Calculate statistics
valid_elevations = [r['elevation'] for r in results if r['elevation'] is not None]
if valid_elevations:
min_elev = min(valid_elevations)
max_elev = max(valid_elevations)
avg_elev = sum(valid_elevations) / len(valid_elevations)
print(f" Elevation range: {min_elev:.1f}m to {max_elev:.1f}m")
print(f" Average elevation: {avg_elev:.1f}m")
print(f" Valid points: {len(valid_elevations)}/{len(results)}")
print(f" Results saved to {filename}")Evaluate the quality and consistency of different interpolation methods.
Usage Example:
import srtm
import random
import statistics
def assess_interpolation_quality(region_bounds, sample_size=100):
"""Assess quality of interpolation methods over a region."""
lat_min, lat_max, lon_min, lon_max = region_bounds
elevation_data = srtm.get_data()
# Generate random sample points
sample_points = []
for _ in range(sample_size):
lat = random.uniform(lat_min, lat_max)
lon = random.uniform(lon_min, lon_max)
sample_points.append((lat, lon))
# Test each interpolation method
methods = {
'direct': lambda lat, lon: elevation_data.get_elevation(lat, lon, approximate=False),
'approximate': lambda lat, lon: elevation_data.get_elevation(lat, lon, approximate=True),
'idw_r1': lambda lat, lon: elevation_data._IDW(lat, lon, radius=1),
'idw_r2': lambda lat, lon: elevation_data._IDW(lat, lon, radius=2)
}
results = {method: [] for method in methods}
for lat, lon in sample_points:
for method_name, method_func in methods.items():
elevation = method_func(lat, lon)
if elevation is not None:
results[method_name].append(elevation)
# Analyze results
print(f"Interpolation quality assessment over region:")
print(f" Bounds: {lat_min}-{lat_max}°N, {lon_min}-{lon_max}°E")
print(f" Sample size: {sample_size} points")
print()
for method, elevations in results.items():
if elevations:
mean_elev = statistics.mean(elevations)
std_elev = statistics.stdev(elevations) if len(elevations) > 1 else 0
min_elev = min(elevations)
max_elev = max(elevations)
coverage = len(elevations) / sample_size * 100
print(f"{method:12}:")
print(f" Coverage: {coverage:5.1f}%")
print(f" Mean: {mean_elev:7.1f}m")
print(f" Std Dev: {std_elev:7.1f}m")
print(f" Range: {min_elev:7.1f}m - {max_elev:7.1f}m")
print()
return results
# Assess quality over Alpine region
alpine_bounds = (45.5, 46.5, 7.0, 8.0) # (lat_min, lat_max, lon_min, lon_max)
quality_results = assess_interpolation_quality(alpine_bounds, sample_size=200)The Inverse Distance Weighted interpolation uses the formula:
Z(x,y) = Σ(wi * zi) / Σ(wi)Where:
wi = 1/di^p (weight based on inverse distance)di is the distance from point (x,y) to known point izi is the elevation value at known point ip is the power parameter (typically 2)Install with Tessl CLI
npx tessl i tessl/pypi-srtm-py