Elevation API
Guide to getting elevation data for single and multiple locations
Elevation API
The Elevation API provides terrain elevation data for any location worldwide, useful for outdoor activities, engineering projects, and geographic analysis.
Overview
The Elevation API offers two main functions:
- Get Elevation - Get elevation for a single location
- Get Multi-Elevation - Get elevations for up to 25 locations in one request
Get Elevation
Retrieve elevation data for a specific location.
Basic Usage
const elevation = await client.elevation.getElevation(12.93126, 77.61638);Response Example
{
status: "OK",
results: [
{
elevation: 920.5, // Elevation in meters
location: {
lat: 12.93126,
lng: 77.61638
},
resolution: 30 // Data resolution in meters
}
]
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
lat | number | Yes | Latitude (-90 to 90) |
lng | number | Yes | Longitude (-180 to 180) |
Error Handling
try {
const elevation = await client.elevation.getElevation(12.93126, 77.61638);
console.log(`Elevation: ${elevation.results[0].elevation}m`);
} catch (error) {
if (error.message.includes('must be numbers')) {
console.error('Invalid coordinates - latitude and longitude must be numbers');
} else {
console.error('Elevation API error:', error.message);
}
}Get Multi-Elevation
Retrieve elevation data for multiple locations in a single request.
Basic Usage
const elevations = await client.elevation.getMultiElevation([
'12.93126,77.61638',
'12.89731,77.65136',
'12.95000,77.60000'
]);Response Example
{
status: "OK",
results: [
{
elevation: 920.5,
location: {
lat: 12.93126,
lng: 77.61638
},
resolution: 30
},
{
elevation: 875.2,
location: {
lat: 12.89731,
lng: 77.65136
},
resolution: 30
},
{
elevation: 905.8,
location: {
lat: 12.95000,
lng: 77.60000
},
resolution: 30
}
]
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
locations | array | Yes | Array of "lat,lng" strings (max 25 locations) |
Limitations
- Maximum 25 locations per request
- Each location must be in
"lat,lng"string format - Exceeding the limit will throw an error
// ❌ This will fail - too many locations
const tooMany = await client.elevation.getMultiElevation(
Array(30).fill('12.93,77.61')
);
// ✅ Split into multiple requests
const batch1 = locations.slice(0, 25);
const batch2 = locations.slice(25);
const [results1, results2] = await Promise.all([
client.elevation.getMultiElevation(batch1),
client.elevation.getMultiElevation(batch2)
]);Real-World Examples
Hiking Trail Profile
Create an elevation profile for a hiking trail:
async function createTrailElevationProfile(trailCoordinates) {
// Split into batches of 25
const batches = [];
for (let i = 0; i < trailCoordinates.length; i += 25) {
batches.push(trailCoordinates.slice(i, i + 25));
}
// Get elevation for all batches
const allResults = [];
for (const batch of batches) {
const locations = batch.map(c => `${c.lat},${c.lng}`);
const response = await client.elevation.getMultiElevation(locations);
allResults.push(...response.results);
// Small delay to avoid rate limiting
await new Promise(resolve => setTimeout(resolve, 100));
}
// Calculate statistics
const elevations = allResults.map(r => r.elevation);
const minElevation = Math.min(...elevations);
const maxElevation = Math.max(...elevations);
const totalAscent = calculateTotalAscent(elevations);
const avgGradient = calculateAverageGradient(allResults);
return {
profile: allResults,
statistics: {
minElevation,
maxElevation,
elevationGain: maxElevation - minElevation,
totalAscent,
averageGradient,
distance: calculateTotalDistance(allResults)
}
};
}
function calculateTotalAscent(elevations) {
let ascent = 0;
for (let i = 1; i < elevations.length; i++) {
if (elevations[i] > elevations[i - 1]) {
ascent += elevations[i] - elevations[i - 1];
}
}
return ascent;
}
// Usage
const trailCoords = [
{ lat: 12.93126, lng: 77.61638 },
{ lat: 12.93200, lng: 77.61700 },
{ lat: 12.93300, lng: 77.61800 }
// ... more points
];
createTrailElevationProfile(trailCoords)
.then(profile => console.log('Trail profile:', profile))
.catch(console.error);Construction Site Analysis
Analyze terrain for construction planning:
async function analyzeConstructionSite(boundaryPoints) {
// Get elevations at boundary points
const locations = boundaryPoints.map(p => `${p.lat},${p.lng}`);
const response = await client.elevation.getMultiElevation(locations);
const elevations = response.results.map(r => r.elevation);
const minElev = Math.min(...elevations);
const maxElev = Math.max(...elevations);
const avgElev = elevations.reduce((a, b) => a + b, 0) / elevations.length;
// Calculate earthwork estimation
const area = calculateArea(boundaryPoints); // in square meters
const cutFillVolume = estimateCutFillVolume(avgElev, minElev, maxElev, area);
return {
siteAnalysis: {
averageElevation: avgElev.toFixed(2) + 'm',
elevationRange: {
min: minElev + 'm',
max: maxElev + 'm'
},
terrainVariation: (maxElev - minElev).toFixed(2) + 'm',
estimatedEarthwork: cutFillVolume + ' cubic meters'
},
rawElevations: response.results
};
}
// Usage
const siteBoundary = [
{ lat: 28.7041, lng: 77.1025 },
{ lat: 28.7045, lng: 77.1030 },
{ lat: 28.7043, lng: 77.1035 },
{ lat: 28.7039, lng: 77.1030 }
];
analyzeConstructionSite(siteBoundary)
.then(analysis => console.log('Site analysis:', analysis))
.catch(console.error);Cycling Route Planner
Plan cycling routes with elevation considerations:
class CyclingRoutePlanner {
async getRouteDifficulty(routeCoordinates) {
// Get elevations for route
const locations = routeCoordinates.map(c => `${c.lat},${c.lng}`);
const response = await client.elevation.getMultiElevation(locations);
const elevations = response.results.map(r => r.elevation);
// Calculate difficulty metrics
const totalClimbing = this.calculateTotalClimbing(elevations);
const maxGradient = this.calculateMaxGradient(elevations);
const elevationPoints = this.countElevationPoints(elevations);
// Assign difficulty rating
let difficulty = 'Easy';
if (totalClimbing > 1000 || maxGradient > 10) {
difficulty = 'Hard';
} else if (totalClimbing > 500 || maxGradient > 6) {
difficulty = 'Moderate';
}
return {
difficulty,
metrics: {
totalClimbing: `${totalClimbing}m`,
maxGradient: `${maxGradient}%`,
climbingPoints: elevationPoints,
averageElevation: Math.round(elevations.reduce((a, b) => a + b, 0) / elevations.length) + 'm'
},
elevationProfile: response.results
};
}
calculateTotalClimbing(elevations) {
let climbing = 0;
for (let i = 1; i < elevations.length; i++) {
const diff = elevations[i] - elevations[i - 1];
if (diff > 0) climbing += diff;
}
return Math.round(climbing);
}
calculateMaxGradient(elevations) {
let maxGrad = 0;
for (let i = 1; i < elevations.length; i++) {
const diff = elevations[i] - elevations[i - 1];
const gradient = (diff / 100) * 100; // Assume 100m between points
if (gradient > maxGrad) maxGrad = gradient;
}
return Math.round(maxGrad * 10) / 10;
}
countElevationPoints(elevations) {
return elevations.filter((_, i) => {
if (i === 0 || i === elevations.length - 1) return false;
return elevations[i] > elevations[i - 1] && elevations[i] > elevations[i + 1];
}).length;
}
}
// Usage
const route = [
{ lat: 12.93126, lng: 77.61638 },
{ lat: 12.94000, lng: 77.62000 },
{ lat: 12.95000, lng: 77.63000 }
];
const planner = new CyclingRoutePlanner();
planner.getRouteDifficulty(route)
.then(difficulty => console.log('Route difficulty:', difficulty))
.catch(console.error);Flood Risk Assessment
Assess flood risk based on elevation:
async function assessFloodRisk(areaCoordinates, riverLevel) {
const locations = areaCoordinates.map(c => `${c.lat},${c.lng}`);
const response = await client.elevation.getMultiElevation(locations);
const riskAssessment = response.results.map(point => {
const elevationAboveRiver = point.elevation - riverLevel;
let riskLevel = 'Low';
if (elevationAboveRiver < 2) {
riskLevel = 'Very High';
} else if (elevationAboveRiver < 5) {
riskLevel = 'High';
} else if (elevationAboveRiver < 10) {
riskLevel = 'Moderate';
}
return {
location: point.location,
elevation: point.elevation,
elevationAboveRiver: elevationAboveRiver,
floodRisk: riskLevel
};
});
const highRiskPoints = riskAssessment.filter(p =>
p.floodRisk === 'High' || p.floodRisk === 'Very High'
);
return {
overallRisk: highRiskPoints.length > 0 ? 'High' : 'Low',
highRiskAreas: highRiskPoints,
recommendations: highRiskPoints.length > 0
? 'Implement flood mitigation measures in identified areas'
: 'Area has low flood risk'
};
}
// Usage
const riversideArea = [
{ lat: 26.1151, lng: 91.7032 },
{ lat: 26.1160, lng: 91.7040 },
{ lat: 26.1170, lng: 91.7050 }
];
assessFloodRisk(riversideArea, 45.5) // River level at 45.5m
.then(assessment => console.log('Flood risk assessment:', assessment))
.catch(console.error);Best Practices
1. Batch Requests Efficiently
async function getElevationsForLargeDataset(coordinates) {
const results = [];
const batchSize = 25;
for (let i = 0; i < coordinates.length; i += batchSize) {
const batch = coordinates.slice(i, i + batchSize);
const locations = batch.map(c => `${c.lat},${c.lng}`);
try {
const response = await client.elevation.getMultiElevation(locations);
results.push(...response.results);
} catch (error) {
console.error(`Batch ${i / batchSize} failed:`, error);
}
// Avoid rate limiting
if (i + batchSize < coordinates.length) {
await new Promise(resolve => setTimeout(resolve, 100));
}
}
return results;
}2. Validate Coordinates
function isValidCoordinate(lat, lng) {
return (
typeof lat === 'number' &&
typeof lng === 'number' &&
lat >= -90 && lat <= 90 &&
lng >= -180 && lng <= 180
);
}
async function safeGetElevation(lat, lng) {
if (!isValidCoordinate(lat, lng)) {
throw new Error('Invalid coordinates provided');
}
return await client.elevation.getElevation(lat, lng);
}3. Cache Elevation Data
const elevationCache = new Map();
async function getCachedElevation(lat, lng) {
const key = `${lat.toFixed(5)},${lng.toFixed(5)}`;
if (elevationCache.has(key)) {
return elevationCache.get(key);
}
const result = await client.elevation.getElevation(lat, lng);
elevationCache.set(key, result);
// Cache for 24 hours
setTimeout(() => elevationCache.delete(key), 86400000);
return result;
}4. Handle Edge Cases
async function getElevationWithFallback(lat, lng) {
try {
const result = await client.elevation.getElevation(lat, lng);
if (!result.results || result.results.length === 0) {
console.warn('No elevation data available for this location');
return { elevation: null, reason: 'no_data' };
}
return result.results[0];
} catch (error) {
console.error('Elevation request failed:', error);
throw error;
}
}Use Cases
Outdoor Recreation
- Hiking: Calculate trail difficulty and elevation gain
- Cycling: Plan routes with appropriate climbing
- Running: Analyze course elevation profiles
- Skiing: Determine slope steepness and vertical drop
Engineering & Construction
- Site Planning: Assess terrain for construction feasibility
- Road Design: Calculate gradients and earthwork requirements
- Drainage Analysis: Understand water flow patterns
- Foundation Design: Determine excavation needs
Environmental Studies
- Flood Modeling: Identify flood-prone areas
- Watershed Analysis: Map drainage basins
- Habitat Mapping: Correlate elevation with ecosystems
- Climate Studies: Analyze elevation-temperature relationships
Agriculture
- Irrigation Planning: Design gravity-fed irrigation systems
- Crop Planning: Match crops to elevation zones
- Erosion Control: Identify erosion-prone slopes
- Vineyard Management: Optimize grape growing conditions
Data Resolution
The Elevation API uses data with approximately 30-meter resolution, which means:
- Elevation values represent the average elevation within a 30m × 30m area
- Suitable for most planning and analysis applications
- May not capture very fine terrain features
- For higher precision needs, consider specialized surveying
Next Steps
- Learn about Tiles API for map tiles and static maps
- Explore Map Display to visualize elevation on maps
- Check Examples for more elevation use cases