0
# Advanced Interpolation
1
2
Sophisticated algorithms for elevation estimation including Inverse Distance Weighted (IDW) interpolation and approximation methods for improved accuracy between data points.
3
4
## Capabilities
5
6
### Inverse Distance Weighted (IDW) Interpolation
7
8
Advanced interpolation method that estimates elevation values by weighting nearby data points based on their inverse distance, providing smoother and more accurate elevation estimates.
9
10
**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.
11
12
```python { .api }
13
class GeoElevationData:
14
def _IDW(self, latitude: float, longitude: float, radius: float = 1) -> Optional[float]: ...
15
16
class GeoElevationFile:
17
def _InverseDistanceWeighted(self, latitude: float, longitude: float, radius: float = 1) -> Optional[float]: ...
18
```
19
20
**Parameters:**
21
- `latitude` (float): Target latitude coordinate
22
- `longitude` (float): Target longitude coordinate
23
- `radius` (float): Interpolation radius (1 or 2). Default: 1
24
- `radius=1`: 3x3 matrix of surrounding points
25
- `radius=2`: 5x5 matrix of surrounding points
26
27
**Returns:** Interpolated elevation value in meters, or None if insufficient data
28
29
**Usage Example:**
30
```python
31
import srtm
32
33
elevation_data = srtm.get_data()
34
35
# Standard elevation lookup
36
standard_elevation = elevation_data.get_elevation(45.8566, 7.8566)
37
38
# IDW interpolation with 3x3 matrix (radius=1)
39
idw_elevation_r1 = elevation_data._IDW(45.8566, 7.8566, radius=1)
40
41
# IDW interpolation with 5x5 matrix (radius=2)
42
idw_elevation_r2 = elevation_data._IDW(45.8566, 7.8566, radius=2)
43
44
print(f"Standard elevation: {standard_elevation}m")
45
print(f"IDW interpolation (r=1): {idw_elevation_r1}m")
46
print(f"IDW interpolation (r=2): {idw_elevation_r2}m")
47
48
# Calculate differences
49
if all(x is not None for x in [standard_elevation, idw_elevation_r1, idw_elevation_r2]):
50
diff_r1 = abs(standard_elevation - idw_elevation_r1)
51
diff_r2 = abs(standard_elevation - idw_elevation_r2)
52
print(f"Difference (r=1): {diff_r1:.2f}m")
53
print(f"Difference (r=2): {diff_r2:.2f}m")
54
```
55
56
### Distance-Weighted Approximation
57
58
Simpler approximation method using distance-weighted averaging of nearby elevation points for smoother elevation profiles.
59
60
```python { .api }
61
class GeoElevationFile:
62
def approximation(self, latitude: float, longitude: float) -> Optional[float]: ...
63
```
64
65
**Parameters:**
66
- `latitude` (float): Target latitude coordinate
67
- `longitude` (float): Target longitude coordinate
68
69
**Returns:** Approximate elevation value in meters, or None if no data available
70
71
**Usage Example:**
72
```python
73
import srtm
74
75
elevation_data = srtm.get_data()
76
77
# Get specific SRTM file
78
srtm_file = elevation_data.get_file(45.8566, 7.8566)
79
80
if srtm_file:
81
# Direct elevation lookup
82
direct_elevation = srtm_file.get_elevation(45.8566, 7.8566)
83
84
# Distance-weighted approximation
85
approx_elevation = srtm_file.approximation(45.8566, 7.8566)
86
87
print(f"Direct elevation: {direct_elevation}m")
88
print(f"Approximated elevation: {approx_elevation}m")
89
90
if direct_elevation and approx_elevation:
91
difference = abs(direct_elevation - approx_elevation)
92
print(f"Approximation difference: {difference:.2f}m")
93
```
94
95
### Comparative Interpolation Analysis
96
97
Compare different interpolation methods to understand their effects on elevation accuracy and smoothness.
98
99
**Usage Example:**
100
```python
101
import srtm
102
import numpy as np
103
104
def compare_interpolation_methods(latitude, longitude):
105
"""Compare different interpolation methods for a given coordinate."""
106
elevation_data = srtm.get_data()
107
srtm_file = elevation_data.get_file(latitude, longitude)
108
109
results = {}
110
111
# Direct lookup (no interpolation)
112
results['direct'] = elevation_data.get_elevation(latitude, longitude, approximate=False)
113
114
# Built-in approximation
115
results['approximate'] = elevation_data.get_elevation(latitude, longitude, approximate=True)
116
117
# IDW with different radii
118
results['idw_r1'] = elevation_data._IDW(latitude, longitude, radius=1)
119
results['idw_r2'] = elevation_data._IDW(latitude, longitude, radius=2)
120
121
# File-level approximation
122
if srtm_file:
123
results['file_approx'] = srtm_file.approximation(latitude, longitude)
124
results['file_idw'] = srtm_file._InverseDistanceWeighted(latitude, longitude, radius=1)
125
126
return results
127
128
# Test coordinates in mountainous area
129
test_coords = [
130
(45.8566, 7.8566), # Mont Blanc region
131
(46.5197, 7.9553), # Jungfrau region
132
(45.9763, 7.6584) # Matterhorn region
133
]
134
135
for lat, lon in test_coords:
136
print(f"\nInterpolation comparison for ({lat}, {lon}):")
137
results = compare_interpolation_methods(lat, lon)
138
139
for method, elevation in results.items():
140
if elevation is not None:
141
print(f" {method:12}: {elevation:7.2f}m")
142
else:
143
print(f" {method:12}: No data")
144
145
# Calculate variations
146
valid_results = {k: v for k, v in results.items() if v is not None}
147
if len(valid_results) > 1:
148
elevations = list(valid_results.values())
149
std_dev = np.std(elevations)
150
range_val = max(elevations) - min(elevations)
151
print(f" Standard deviation: {std_dev:.2f}m")
152
print(f" Range: {range_val:.2f}m")
153
```
154
155
### Batch Interpolation Processing
156
157
Apply interpolation methods to multiple coordinates efficiently for large-scale elevation analysis.
158
159
**Usage Example:**
160
```python
161
import srtm
162
import csv
163
from typing import List, Tuple
164
165
def batch_interpolation(coordinates: List[Tuple[float, float]], method='idw_r1'):
166
"""Apply interpolation to a batch of coordinates."""
167
elevation_data = srtm.get_data(batch_mode=True)
168
169
results = []
170
171
for i, (lat, lon) in enumerate(coordinates):
172
if i % 100 == 0:
173
print(f"Processing coordinate {i+1}/{len(coordinates)}")
174
175
if method == 'direct':
176
elevation = elevation_data.get_elevation(lat, lon, approximate=False)
177
elif method == 'approximate':
178
elevation = elevation_data.get_elevation(lat, lon, approximate=True)
179
elif method == 'idw_r1':
180
elevation = elevation_data._IDW(lat, lon, radius=1)
181
elif method == 'idw_r2':
182
elevation = elevation_data._IDW(lat, lon, radius=2)
183
else:
184
elevation = elevation_data.get_elevation(lat, lon)
185
186
results.append({
187
'latitude': lat,
188
'longitude': lon,
189
'elevation': elevation,
190
'method': method
191
})
192
193
return results
194
195
# Generate test coordinates along a hiking trail
196
trail_coordinates = []
197
start_lat, start_lon = 45.8, 7.8
198
for i in range(50):
199
lat = start_lat + (i * 0.001) # Move north
200
lon = start_lon + (i * 0.0005) # Move slightly east
201
trail_coordinates.append((lat, lon))
202
203
# Process with different methods
204
methods = ['direct', 'approximate', 'idw_r1', 'idw_r2']
205
206
for method in methods:
207
print(f"\nProcessing with method: {method}")
208
results = batch_interpolation(trail_coordinates, method)
209
210
# Save results to CSV
211
filename = f"elevation_trail_{method}.csv"
212
with open(filename, 'w', newline='') as csvfile:
213
fieldnames = ['latitude', 'longitude', 'elevation', 'method']
214
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
215
writer.writeheader()
216
writer.writerows(results)
217
218
# Calculate statistics
219
valid_elevations = [r['elevation'] for r in results if r['elevation'] is not None]
220
if valid_elevations:
221
min_elev = min(valid_elevations)
222
max_elev = max(valid_elevations)
223
avg_elev = sum(valid_elevations) / len(valid_elevations)
224
print(f" Elevation range: {min_elev:.1f}m to {max_elev:.1f}m")
225
print(f" Average elevation: {avg_elev:.1f}m")
226
print(f" Valid points: {len(valid_elevations)}/{len(results)}")
227
228
print(f" Results saved to {filename}")
229
```
230
231
### Interpolation Quality Assessment
232
233
Evaluate the quality and consistency of different interpolation methods.
234
235
**Usage Example:**
236
```python
237
import srtm
238
import random
239
import statistics
240
241
def assess_interpolation_quality(region_bounds, sample_size=100):
242
"""Assess quality of interpolation methods over a region."""
243
lat_min, lat_max, lon_min, lon_max = region_bounds
244
elevation_data = srtm.get_data()
245
246
# Generate random sample points
247
sample_points = []
248
for _ in range(sample_size):
249
lat = random.uniform(lat_min, lat_max)
250
lon = random.uniform(lon_min, lon_max)
251
sample_points.append((lat, lon))
252
253
# Test each interpolation method
254
methods = {
255
'direct': lambda lat, lon: elevation_data.get_elevation(lat, lon, approximate=False),
256
'approximate': lambda lat, lon: elevation_data.get_elevation(lat, lon, approximate=True),
257
'idw_r1': lambda lat, lon: elevation_data._IDW(lat, lon, radius=1),
258
'idw_r2': lambda lat, lon: elevation_data._IDW(lat, lon, radius=2)
259
}
260
261
results = {method: [] for method in methods}
262
263
for lat, lon in sample_points:
264
for method_name, method_func in methods.items():
265
elevation = method_func(lat, lon)
266
if elevation is not None:
267
results[method_name].append(elevation)
268
269
# Analyze results
270
print(f"Interpolation quality assessment over region:")
271
print(f" Bounds: {lat_min}-{lat_max}°N, {lon_min}-{lon_max}°E")
272
print(f" Sample size: {sample_size} points")
273
print()
274
275
for method, elevations in results.items():
276
if elevations:
277
mean_elev = statistics.mean(elevations)
278
std_elev = statistics.stdev(elevations) if len(elevations) > 1 else 0
279
min_elev = min(elevations)
280
max_elev = max(elevations)
281
coverage = len(elevations) / sample_size * 100
282
283
print(f"{method:12}:")
284
print(f" Coverage: {coverage:5.1f}%")
285
print(f" Mean: {mean_elev:7.1f}m")
286
print(f" Std Dev: {std_elev:7.1f}m")
287
print(f" Range: {min_elev:7.1f}m - {max_elev:7.1f}m")
288
print()
289
290
return results
291
292
# Assess quality over Alpine region
293
alpine_bounds = (45.5, 46.5, 7.0, 8.0) # (lat_min, lat_max, lon_min, lon_max)
294
quality_results = assess_interpolation_quality(alpine_bounds, sample_size=200)
295
```
296
297
## Algorithm Details
298
299
### IDW Algorithm
300
The Inverse Distance Weighted interpolation uses the formula:
301
302
```
303
Z(x,y) = Σ(wi * zi) / Σ(wi)
304
```
305
306
Where:
307
- `wi = 1/di^p` (weight based on inverse distance)
308
- `di` is the distance from point (x,y) to known point i
309
- `zi` is the elevation value at known point i
310
- `p` is the power parameter (typically 2)
311
312
### Performance Considerations
313
314
- **Computational Cost**: IDW with larger radius requires more calculations
315
- **Accuracy Trade-off**: Higher radius generally provides smoother results but may lose local detail
316
- **Memory Usage**: Larger interpolation matrices require more memory
317
- **Data Availability**: Interpolation quality depends on density of available SRTM data points
318
319
### When to Use Each Method
320
321
- **Direct Lookup**: Fastest, use when exact SRTM grid values are sufficient
322
- **Built-in Approximation**: Good balance of speed and accuracy for most applications
323
- **IDW (radius=1)**: Better accuracy with moderate computational cost
324
- **IDW (radius=2)**: Smoothest results, highest computational cost
325
- **File Approximation**: Use when working directly with GeoElevationFile objects