自定义 ElevationLayer - 夸大高程

尝试一下在线预览

概览

这个例子演示了如何通过创建一个 BaseElevationLayer 的子类来创建一个自定义的 ElevationLayer 在某些情况下,你可能想要在 SceneView  中夸大抬高,使它在较小的尺度上更明显。

不夸张( TopoBathy3D 高程服务)

default-elevation

高度夸张70倍与自定义图层

exaggerated-elevation

创建一个自定义立面图层

要创建一个自定义的  ElevationLayer  ,你必须在 BaseElevationLayer 上调用  createSubclass()  我们将命名自定义图层 ExaggeratedElevationLayer  。

由于这个示例夸大了现有的高程值,我们需要 ElevationLayer 并加载默认的 GeoScene TopoBathy3D service 作为自定义图层的依赖项。这是在 load() 方法中完成的,因为它是一个 可加载的 资源。

我们还将创建一个 exaggeration 属性来指定夸大仰角的因素。

                         
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const ExaggeratedElevationLayer = BaseElevationLayer.createSubclass({
  properties: {
    // exaggerates the actual elevations by 70x
    exaggeration: 70
  },

  load: function() {
    this._elevation = new ElevationLayer({
      url: "//elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/TopoBathy3D/ImageServer"
    });

    // wait for the elevation layer to load before resolving load()
    this.addResolvingPromise(
      this._elevation.load().then(() => {
        // get tileInfo, spatialReference and fullExtent from the elevation service
        // this is required for elevation services with a custom spatialReference
        this.tileInfo = this._elevation.tileInfo;
        this.spatialReference = this._elevation.spatialReference;
        this.fullExtent = this._elevation.fullExtent;
      })
    );

    return this;
  }
});

然后我们必须操作 ExaggeratedElevationLayer 的  fetchTile() 方法,以便它为每个像素返回正确的值。我们可以使用  ElevationLayer.fetchTile()  获取实际高程值,将它们乘以 exaggeration 值,然后将它们返回给  fetchTile  , 因为 ElevationLayer  中  fetchTile() 的数据对象规范与  BaseElevationLayer 相同。最终的自定义立高程代码应该如下所示。

                                        
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
const ExaggeratedElevationLayer = BaseElevationLayer.createSubclass({
  properties: {
    // exaggerates the actual elevations by 70x
    exaggeration: 70
  },

  load: function() {
    this._elevation = new ElevationLayer({
      url: "//elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/TopoBathy3D/ImageServer"
    });

    // wait for the elevation layer to load before resolving load()
    this.addResolvingPromise(
      this._elevation.load().then(() => {
        // get tileInfo, spatialReference and fullExtent from the elevation service
        // this is required for elevation services with a custom spatialReference
        this.tileInfo = this._elevation.tileInfo;
        this.spatialReference = this._elevation.spatialReference;
        this.fullExtent = this._elevation.fullExtent;
      })
    );

    return this;

  },

  // Fetches the tile(s) visible in the view
  fetchTile: function(level, row, col, options) {
    return this._elevation.fetchTile(level, row, col, options).then(
      function(data) {
        const exaggeration = this.exaggeration;
        for (let i = 0; i < data.values.length; i++) {
          data.values[i] = data.values[i] * exaggeration;
        }

        return data;
      }.bind(this)
    );
  }
});

创建图层后,您必须将其添加到 Map.ground  属性的图层并将地图添加到  SceneView  实例。

       
1
2
3
4
5
6
7
const map = new Map({
  basemap: basemap,
  ground: {
    layers: [new ExaggeratedElevationLayer()]
  }
});
sceneView.map = map;

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.