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

基于Overpass API实现建筑多选保存及屋顶真实面积计算问询

针对React OSM建筑可视化项目的修改方案

一、实现多建筑点击选择与数据保存

  1. 添加选中状态管理
    在组件中新增状态变量存储选中的建筑数据:

    const [selectedBuildings, setSelectedBuildings] = useState([]);
    
  2. 修改建筑交互逻辑
    给每个建筑图层绑定点击事件,实现选中/取消选中的切换,并添加视觉反馈:

    // 以Leaflet的GeoJSON组件为例,渲染建筑时绑定交互逻辑
    <GeoJSON
      data={processedBuildings}
      onEachFeature={(feature, layer) => {
        // 点击切换选中状态
        layer.on('click', () => {
          const targetId = feature.id;
          setSelectedBuildings(prev => {
            const isSelected = prev.some(item => item.id === targetId);
            return isSelected 
              ? prev.filter(item => item.id !== targetId) 
              : [...prev, feature];
          });
        });
    
        // 根据选中状态切换样式
        const isSelected = selectedBuildings.some(item => item.id === feature.id);
        layer.setStyle({
          fillColor: isSelected ? '#e74c3c' : '#3498db',
          weight: isSelected ? 2 : 1,
          fillOpacity: isSelected ? 0.7 : 0.5
        });
      }}
    />
    
  3. 数据保存实现
    添加保存/导出功能,可将选中数据存储到本地或导出为文件:

    const saveSelectedData = () => {
      // 存储到localStorage
      localStorage.setItem('selectedOSMBuildings', JSON.stringify(selectedBuildings));
      
      // 可选:导出为JSON文件
      const blob = new Blob([JSON.stringify(selectedBuildings, null, 2)], {type: 'application/json'});
      const downloadUrl = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = downloadUrl;
      a.download = 'selected-buildings.json';
      a.click();
      URL.revokeObjectURL(downloadUrl);
    };
    
    // 在组件中添加保存按钮
    <button onClick={saveSelectedData} style={{margin: '10px'}}>保存选中建筑数据</button>
    

二、获取屋顶角度并计算真实表面积

  1. 修改Overpass API查询语句
    在原有查询中加入roof:angle标签,获取屋顶角度数据:

    const overpassQuery = `
      [out:json][timeout:25];
      (
        way["building"]({{bbox}});
        relation["building"]({{bbox}});
      );
      out body;
      >;
      out skel qt;
      // 补充请求屋顶角度标签
      out tags;
    `;
    
  2. 添加表面积计算工具函数
    基于2D占地面积和屋顶角度计算真实屋顶表面积(公式:真实面积 = 2D面积 / cos(屋顶角度弧度)):

    const calculateRoofArea = (footprintArea, roofAngle) => {
      if (!roofAngle || roofAngle === 0) return footprintArea;
      // 角度转弧度
      const angleRad = (roofAngle * Math.PI) / 180;
      // 边界处理:避免角度接近90度时出现异常值
      if (angleRad > Math.PI / 2 - 0.01) return footprintArea * 10;
      return footprintArea / Math.cos(angleRad);
    };
    
  3. 整合计算逻辑并嵌入数据
    在处理Overpass返回数据时,计算真实表面积并添加到建筑属性中:

    const processBuildingsData = (rawData) => {
      return rawData.features.map(feature => {
        const footprintArea = feature.properties.area; // 原有2D面积字段
        const roofAngle = parseFloat(feature.properties['roof:angle']);
        const roofArea = calculateRoofArea(footprintArea, roofAngle);
        
        return {
          ...feature,
          properties: {
            ...feature.properties,
            roofArea: roofArea.toFixed(2),
            roofAngle: roofAngle || '未记录'
          }
        };
      });
    };
    
  4. 在UI中展示计算结果
    可在悬停弹窗或选中详情中展示真实表面积:

    // 悬停弹窗示例
    layer.bindPopup(`
      <div style={{padding: '8px'}}>
        <p>2D占地面积: ${feature.properties.area} ㎡</p>
        <p>屋顶角度: ${feature.properties.roofAngle}</p>
        <p>屋顶真实面积: ${feature.properties.roofArea} ㎡</p>
      </div>
    `);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 15:13:40