地形渲染

字数统计: 840
阅读时长: 约 2 分钟
当前版本: 4.29

使用高程服务叠加地形底图图层的场景

什么是地形渲染?

地形渲染是在 3D 场景中显示高程的过程。在场景中渲染地形可从数字高程模型开始。将数据集发布为高程服务,并将其作为高程图层加载到应用程序中。

高程图层在 3D 场景中不可见,但可以渲染覆盖在高程图层之上的底图图层。数据图层叠加在高程图层上后,会显示出数据图层的高低起伏。当 3D 场景没有高程图层时,地形将渲染为以零高度(海平面)显示的平面。

如何渲染地形并将数据图层与地形对齐

在场景中通过添加高程图层和底图图层来渲染地形。

js
    const map = new Map({
        ground: {
            layers: [ new ElevationLayer({
                url: "https://links.geoscene.cn/geoscene/rest/services/elevation3d/WorldElevation3D/Terrain3D/ImageServer"
            })]
        },
        basemap: basemap
    });

在大多数应用程序中,需向场景添加其他数据图层。下图显示了用于垂直对齐数据图层的几个选项:

垂直对齐数据图层的选项

例子中的徒步路径图层是相对于地形进行渲染的,偏移量为 3 米:

js
    const trails = new FeatureLayer({
        url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trails/FeatureServer/0",
        elevationInfo: {
            mode: "relative-to-ground",
            offset: 3
        },
        renderer: {
            type: "simple",
            symbol: {
                type: "line-3d",
                symbolLayers: [{
                    type: "line",
                    material: { color: "#FF5500" },
                    size: "2px"
                }]
            }
        }
    });

示例

显示具有高程的场景

还可以使用高程图层和底图图层显示一个简单的场景。底图图层将叠加在高程图层上创建 3D 视图。如果还需要显示其他数据,则可以添加数据图层或图形,然后使用 2D 或 3D 符号渲染要素。

步骤

  1. 创建场景并添加高程图层和底图图层。

  2. 创建场景视图。

  3. 设置照相机位置。

js
    const map = new Map({
        ground: "world-elevation",
        basemap: "tianditu-image"
    });

    const view = new SceneView({
        container: "viewDiv",
        map: map,
        qualityProfile: "high",
        camera: {
            position: [
              116.80714018,
              39.96144206,
              1574.65501
            ],
            heading: 0.51,
            tilt: 78.99
        }
    });

使用夸大显示地形

为了强调地形,有时您可能会发现使用夸张的高程值显示地形很有用。在此示例中,将显示地球上最高的山脉和最低的海洋区域。由于地球的半径太大,因此山脉高程在视觉上并不明显。在这里,数据源将这些高程值夸大到了 70 倍。

js
    const ExaggeratedElevationLayer = BaseElevationLayer.createSubclass({

        properties: {
            exaggeration: null
        },

        // The load() method is called when the layer is added to the map
        // prior to it being rendered in the view.
        load: function () {
            this._elevation = new ElevationLayer({
                url: "https://links.geoscene.cn/geoscene/rest/services/elevation3d/WorldElevation3D/Terrain3D/ImageServer"
            });

            // wait for the elevation layer to load before resolving load()
            this.addResolvingPromise(this._elevation.load());
        },

        // Fetches the tile(s) visible in the view
        fetchTile: function (level, row, col, options) {
            // calls fetchTile() on the elevationlayer for the tiles
            // visible in the view
            return this._elevation.fetchTile(level, row, col, options).then(
                function (data) {
                    var exaggeration = this.exaggeration;
                    // `data` is an object that contains the
                    // the width and the height of the tile in pixels,
                    // and the values of each pixel
                    for (var i = 0; i < data.values.length; i++) {
                        // Multiply the given pixel value
                        // by the exaggeration value
                        data.values[i] = data.values[i] \* exaggeration;
                    }
                    return data;
                }.bind(this)
            );
        }
    });

    const elevationLayer = new ExaggeratedElevationLayer({ exaggeration: 70 });
    const map = new Map({
        basemap: basemap,
        ground: {
            layers: [elevationLayer]
        }
    });