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

启用Mapbox地形图层后fill-extrusion-height视觉变化原因咨询

Mapbox地形图层启用后fill-extrusion视觉异常问题

我在Mapbox地图上绘制了一个立方体,启用在线地形服务添加地形图层后,发现fill-extrusion-height的视觉效果出现变化——和未应用地形图层时相比,立方体看起来更厚。

import React, { useEffect, useRef, useState } from "react";
import mapboxgl from "mapbox-gl";

import "mapbox-gl/dist/mapbox-gl.css";

const MapboxExample = () => {
  const mapContainerRef = useRef();
  const mapRef = useRef();
  const [terrainEnabled, setTerrainEnabled] = useState(true);

  useEffect(() => {
    // TO MAKE THE MAP APPEAR YOU MUST
    // ADD YOUR ACCESS TOKEN FROM
    // https://account.mapbox.com
    mapboxgl.accessToken = "accessToken";

    mapRef.current = new mapboxgl.Map({
      container: "map",
      zoom: 16,
      center: [10.896002, 48.36508], // Centered on the specified coordinates
      pitch: 60,
      bearing: -20,
      style: "mapbox://styles/mapbox/satellite-streets-v12",
    });

    mapRef.current.on("style.load", () => {
      // Add German terrain source
      mapRef.current.addSource("terrainSource", {
        type: "raster-dem",
        url: "https://sgx.geodatenzentrum.de/gdz_basemapde_3d_gelaende/dgm5_3857_rgb.json",
        tileSize: 256,
      });

      // Enable terrain by default
      mapRef.current.setTerrain({ source: "terrainSource", exaggeration: 1.5 });

      // Add cube GeoJSON source
      mapRef.current.addSource("cube", {
        type: "geojson",
        data: {
          type: "FeatureCollection",
          features: [
            {
              type: "Feature",
              properties: {
                height: 0.5,
              },
              geometry: {
                type: "Polygon",
                coordinates: [
                  [
                    [10.894002, 48.36708],
                    [10.898002, 48.36708],
                    [10.898002, 48.36308],
                    [10.894002, 48.36308],
                    [10.894002, 48.36708],
                  ],
                ],
              },
            },
          ],
        },
      });

      // Add 3D cube layer
      mapRef.current.addLayer({
        id: "3d-cube",
        source: "cube",
        type: "fill-extrusion",
        paint: {
          "fill-extrusion-color": "#ff4757",
          "fill-extrusion-height": ["get", "height"],
          "fill-extrusion-base": 0,
          "fill-extrusion-opacity": 0.8,
        },
      });
    });

    // Cleanup function
    return () => {
      if (mapRef.current) {
        mapRef.current.remove();
      }
    };
  }, []);

  const toggleTerrain = () => {
    if (mapRef.current && mapRef.current.isStyleLoaded()) {
      if (terrainEnabled) {
        // Disable terrain
        mapRef.current.setTerrain(null);
      } else {
        // Enable terrain
        mapRef.current.setTerrain({
          source: "terrainSource",
          exaggeration: 1.5,
        });
      }
      setTerrainEnabled(!terrainEnabled);
    }
  };

  return (
    <div style={{ position: "relative", height: "100%" }}>
      <div id="map" ref={mapContainerRef} style={{ height: "100%" }}></div>

      {/* Terrain Toggle Button */}
      <button
        onClick={toggleTerrain}
        style={{
          position: "absolute",
          top: "10px",
          right: "10px",
          zIndex: 1000,
          padding: "8px 12px",
          backgroundColor: terrainEnabled ? "#4CAF50" : "#f44336",
          color: "white",
          border: "none",
          borderRadius: "4px",
          cursor: "pointer",
          fontSize: "14px",
          fontWeight: "bold",
          boxShadow: "0 2px 4px rgba(0,0,0,0.2)",
          transition: "background-color 0.3s ease",
        }}
        onMouseOver={(e) => {
          e.target.style.opacity = "0.8";
        }}
        onMouseOut={(e) => {
          e.target.style.opacity = "1";
        }}
      >
        {terrainEnabled ? "Terrain ON" : "Terrain OFF"}
      </button>

      {/* Info Panel */}
      <div
        style={{
          position: "absolute",
          bottom: "10px",
          left: "10px",
          zIndex: 1000,
          padding: "10px",
          backgroundColor: "rgba(0, 0, 0, 0.7)",
          color: "white",
          borderRadius: "4px",
          fontSize: "12px",
          maxWidth: "200px",
        }}
      >
        <div>
          <strong>Features:</strong>
        </div>
        <div>• Large 3D Red Cube (1000m height)</div>
        <div>• German terrain with 1.5x exaggeration</div>
        <div>• Toggle terrain on/off</div>
        <div>• Custom GeoJSON extrusion</div>
      </div>
    </div>
  );
};

export default MapboxExample;

效果对比截图

  • 无地形图层时:
    无地形图层

  • 有地形图层时:
    有地形图层

复现说明

可通过在线沙箱复现该问题

内容的提问来源于stack exchange,提问作者Ala Eddine Menai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 09:14:54