You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Leaflet中通过经纬度获取海拔(不使用Google Elevation)

Leaflet 无Google Elevation获取海拔的可行方案

以下是几个无需依赖Google Elevation的可行方案,可实现你需要的点击地图获取对应经纬度海拔的功能:

1. 免费开源:OpenTopoData API

OpenTopoData提供免费的全球海拔查询接口,支持单点/批量经纬度查询,非商用场景无需API密钥,数据精度可选(如srtm30m、eudem25m等)。

示例代码

// 经纬度转海拔的异步函数
async function getElevation(lat, lng) {
  try {
    const res = await fetch(`https://api.opentopodata.org/v1/eudem25m?locations=${lat},${lng}`);
    const data = await res.json();
    return data.results[0]?.elevation || null;
  } catch (err) {
    console.error('海拔查询失败:', err);
    return null;
  }
}

// 绑定Leaflet地图点击事件
map.on('click', async (e) => {
  const { lat, lng } = e.latlng;
  const elevation = await getElevation(lat, lng);
  
  const popupContent = elevation !== null 
    ? `海拔:${elevation.toFixed(2)} 米` 
    : '无法获取海拔数据';
  
  L.popup()
    .setLatLng(e.latlng)
    .setContent(popupContent)
    .openOn(map);
});

2. 离线/本地部署:NASA SRTM瓦片服务

如果需要避免依赖外部API,可下载NASA的SRTM海拔瓦片,搭建本地瓦片服务后直接解析像素值获取海拔,完全免费且离线可用。

实现步骤&代码

  1. 从USGS渠道下载SRTM瓦片数据,或使用预生成的瓦片集
  2. 用tileserver-gl等工具搭建本地瓦片服务(示例地址:http://localhost:8080/srtm/{z}/{x}/{y}.png)
  3. 解析瓦片像素值转换为海拔:
function getElevationFromLocalTile(lat, lng) {
  return new Promise((resolve, reject) => {
    const zoom = map.getZoom();
    const tileSize = map.getTileSize();
    const point = map.project(L.latLng(lat, lng), zoom);
    const tileX = Math.floor(point.x / tileSize.x);
    const tileY = Math.floor(point.y / tileSize.y);
    const offsetX = Math.floor(point.x % tileSize.x);
    const offsetY = Math.floor(point.y % tileSize.y);

    const img = new Image();
    img.crossOrigin = 'anonymous';
    img.src = `http://localhost:8080/srtm/${zoom}/${tileX}/${tileY}.png`;
    
    img.onload = () => {
      const canvas = document.createElement('canvas');
      canvas.width = tileSize.x;
      canvas.height = tileSize.y;
      const ctx = canvas.getContext('2d');
      ctx.drawImage(img, 0, 0);
      const pixel = ctx.getImageData(offsetX, offsetY, 1, 1).data;
      // SRTM瓦片RGB转海拔公式,需匹配你的瓦片生成规则
      const elevation = (pixel[0] * 256 * 256 + pixel[1] * 256 + pixel[2]) - 10000;
      resolve(elevation);
    };
    img.onerror = () => reject('瓦片加载失败');
  });
}

// 地图点击事件调用
map.on('click', async (e) => {
  try {
    const elevation = await getElevationFromLocalTile(e.latlng.lat, e.latlng.lng);
    L.popup()
      .setLatLng(e.latlng)
      .setContent(`海拔:${elevation.toFixed(2)} 米`)
      .openOn(map);
  } catch (err) {
    L.popup()
      .setLatLng(e.latlng)
      .setContent('无法获取海拔数据')
      .openOn(map);
  }
});

3. 高精度选项:Mapbox Elevation API

如果可以接受非Google的商业免费API,Mapbox提供高精度的海拔数据,免费额度足够个人项目使用,需注册获取免费API密钥。

示例代码

// 替换为你的Mapbox免费API密钥
const MAPBOX_KEY = '你的Mapbox密钥';

async function getElevationByMapbox(lat, lng) {
  try {
    const zoom = map.getZoom();
    const point = map.project(L.latLng(lat, lng), zoom);
    const tileX = Math.floor(point.x / 256);
    const tileY = Math.floor(point.y / 256);
    
    const res = await fetch(`https://api.mapbox.com/v4/mapbox.terrain-rgb/${zoom}/${tileX}/${tileY}.pngraw?access_token=${MAPBOX_KEY}`);
    const buffer = await res.arrayBuffer();
    const data = new Uint8Array(buffer);
    
    const x = Math.floor(point.x % 256);
    const y = Math.floor(point.y % 256);
    const idx = (y * 256 + x) * 4;
    const r = data[idx];
    const g = data[idx + 1];
    const b = data[idx + 2];
    
    // Mapbox地形瓦片的海拔转换公式
    const elevation = (r * 256 * 256 + g * 256 + b) * 0.1 - 10000;
    return elevation;
  } catch (err) {
    console.error('海拔查询失败:', err);
    return null;
  }
}

// 绑定地图点击事件
map.on('click', async (e) => {
  const elevation = await getElevationByMapbox(e.latlng.lat, e.latlng.lng);
  
  const popupContent = elevation !== null 
    ? `海拔:${elevation.toFixed(2)} 米` 
    : '无法获取海拔数据';
  
  L.popup()
    .setLatLng(e.latlng)
    .setContent(popupContent)
    .openOn(map);
});

内容的提问来源于stack exchange,提问作者refa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 09:05:26