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

如何为Mapbox GL JS中queryRenderedFeatures的GeoJSON输出添加高程数据?

给queryRenderedFeatures输出的GeoJSON要素添加高程值

核心思路

先提取GeoJSON中所有的坐标点,批量查询每个点的高程,再将高程值关联回原要素的属性或坐标中。以下是具体实现步骤和代码示例:


1. 提取GeoJSON中的所有坐标点

遍历要素集,根据几何类型(点、线、面)提取所有经纬度坐标,并记录每个坐标对应的要素索引(方便后续关联高程)。

// 提取坐标点并关联要素索引的函数
function extractCoordinates(geoJSON) {
  const pointWithIndices = [];
  
  geoJSON.features.forEach((feat, idx) => {
    switch (feat.geometry.type) {
      case 'Point':
        pointWithIndices.push({
          lon: feat.geometry.coordinates[0],
          lat: feat.geometry.coordinates[1],
          index: idx
        });
        break;
      case 'LineString':
        feat.geometry.coordinates.forEach((coord, coordIdx) => {
          pointWithIndices.push({
            lon: coord[0],
            lat: coord[1],
            index: idx,
            coordIndex: coordIdx
          });
        });
        break;
      case 'Polygon':
        feat.geometry.coordinates.forEach((ring, ringIdx) => {
          ring.forEach((coord, coordIdx) => {
            pointWithIndices.push({
              lon: coord[0],
              lat: coord[1],
              index: idx,
              ringIndex: ringIdx,
              coordIndex: coordIdx
            });
          });
        });
        break;
      // 可扩展支持MultiPoint、MultiLineString等类型
    }
  });
  
  return pointWithIndices;
}

2. 批量查询高程值

基于你已有的单点高程查询能力,封装批量查询逻辑,控制并发数避免请求过于频繁(防止被API限流)。

// 替换为你实际使用的单点高程查询函数
async function getElevation(lon, lat) {
  // 示例:调用高程API(请替换成你的实际接口或本地计算逻辑)
  const res = await fetch(`https://your-elevation-api-endpoint?lon=${lon}&lat=${lat}`);
  const data = await res.json();
  return data.elevation; // 假设返回结果包含elevation字段
}

// 批量查询高程,控制并发批次
async function batchGetElevations(points, batchSize = 5) {
  const results = [];
  
  for (let i = 0; i < points.length; i += batchSize) {
    const batch = points.slice(i, i + batchSize);
    const batchPromises = batch.map(async (point) => {
      const elevation = await getElevation(point.lon, point.lat);
      return {...point, elevation};
    });
    
    results.push(...await Promise.all(batchPromises));
    // 可选:添加延迟降低请求频率
    await new Promise(resolve => setTimeout(resolve, 100));
  }
  
  return results;
}

3. 将高程值写入原GeoJSON

根据之前记录的索引,把高程值写入对应要素的属性中(也可以选择将坐标扩展为[lon, lat, elevation]的三维格式)。

async function addElevationsToGeoJSON(geoJSON) {
  const points = extractCoordinates(geoJSON);
  const elevationResults = await batchGetElevations(points);
  
  elevationResults.forEach(result => {
    const targetFeature = geoJSON.features[result.index];
    
    // 点要素:直接在属性中添加高程
    if (targetFeature.geometry.type === 'Point') {
      targetFeature.properties.elevation = result.elevation;
    }
    // 线要素:按坐标索引存储高程数组
    else if (targetFeature.geometry.type === 'LineString') {
      if (!targetFeature.properties.elevations) {
        targetFeature.properties.elevations = new Array(targetFeature.geometry.coordinates.length);
      }
      targetFeature.properties.elevations[result.coordIndex] = result.elevation;
    }
    // 面要素:按环和坐标索引存储高程
    else if (targetFeature.geometry.type === 'Polygon') {
      if (!targetFeature.properties.elevations) {
        targetFeature.properties.elevations = new Array(targetFeature.geometry.coordinates.length);
      }
      if (!targetFeature.properties.elevations[result.ringIndex]) {
        targetFeature.properties.elevations[result.ringIndex] = new Array(targetFeature.geometry.coordinates[result.ringIndex].length);
      }
      targetFeature.properties.elevations[result.ringIndex][result.coordIndex] = result.elevation;
    }
  });
  
  return geoJSON;
}

4. 调用示例

// 假设renderedGeoJSON是queryRenderedFeatures返回的结果
const renderedGeoJSON = queryRenderedFeatures(...);

addElevationsToGeoJSON(renderedGeoJSON).then(updatedGeoJSON => {
  console.log("已添加高程的GeoJSON:", updatedGeoJSON);
  // 保存到文件(Node.js环境)
  // const fs = require('fs');
  // fs.writeFileSync('elevated-features.geojson', JSON.stringify(updatedGeoJSON));
});

注意事项

  • 如果使用第三方高程API,务必关注其请求配额和限流规则,必要时降低并发数或增加请求间隔
  • 离线场景下,可加载本地DEM数据集进行高程计算,无需依赖网络请求
  • 可根据需求调整高程存储方式:比如将点坐标改为三维格式[lon, lat, elevation],替代属性存储

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 22:36:38