自定义 TileLayer

尝试一下在线预览

介绍层可扩展性

用于 JavaScript 的 GeoScene API 提供了许多预定义的 图层这些图层从服务器检索图像或数据,并在视图中显示它们。

除了这个示例之外,下面的示例演示了创建自定义图层的基本原理。

当您需要时,创建自定义图层很有用:

  • 显示来自 JavaScript  的 GeoScene  API  不完全支持的来源的数据
  • 在视图中显示之前预处理数据(这可能是因为服务返回二进制数据,需要对其进行处理以生成图像)
  • 创建 API 中不显示支持的自定义可视化
  • 显示合成数据,例如夸张的高程

编写自定义图层使您能够支持绘制新的数据格式。在开始创建自定义图层之前,熟悉以下主题是有帮助的:

创建一个自定义切片图层


此示例演示如何从  Stamen's toner 黑白图块创建自定义 TileLayer 。 切片图层由图像组成,例如卫星图像,这些图像是按列和行拼接在一起的方形切片,使图层看起来像是一张连续的图像。这些图层具有多个细节级别 ( LOD ),允许用户缩放到地图的任何区域并加载更多的切片,这些切片在更大的地图比例下以更高分辨率描绘要素。

要创建自定义切片图层,必须调用 BaseTileLayer 类的  createSubclass()  方法。我们将自定义图层命名为 TintLayer  。


 由于这一图层需要知道从哪里访问预定义的切片,我们将创建一个 urlTemplate 属性。 应用程序将为图层提供 urlTemplate 值,图层将从生成的 URL 中获取切片。然后在显示每个图像之前将 差异 混合操作应用于 Stamen 切片。将在该图层上创建一个 tint  属性,以便应用程序可以指定一种颜色,该颜色将在混合操作中使用。

                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const TintLayer = BaseTileLayer.createSubclass({
  // set up the properties specific to this layer
  properties: {
    // url to the tiles, provided by the application
    urlTemplate: null,
    // tint color that will be used to change
    // stamen's black and white tiles
    // value provided by the application
    tint: {
      value: null,
      type: Color
    }
  }

  // override necessary methods here
});

您可以通过两种不同的方式扩展 BaseTileLayer :

  • 请求切片,因为它们是从数据源预定义的
  • 图像或数据在视图中显示之前需要进行预处理

请求瓦片,因为它们是从一个数据源预定义的

要从数据源中请求预定义的图像,请覆盖  getTileUrl()  方法,以便它在给定的级别、行和列上返回所请求切片的URL。

               
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const MyCustomTileLayer = BaseTileLayer.createSubclass({
  // properties of the custom tile layer
  properties: {
    urlTemplate: null
  },

  // override getTileUrl()
  // generate the tile url for a given level, row and column
  getTileUrl: function(level, row, col) {
    return this.urlTemplate
      .replace("{z}", level)
      .replace("{x}", col)
      .replace("{y}", row);
  }
});

图像或数据在视图中显示之前需要进行预处理

如果数据或切片需要在显示之前进行预处理,那么覆盖 fetchTile() 方法。此示例通过获取 Stamen's toner 切片并将具有给定颜色的 差异 混合操作应用于画布来使用此方法。一旦图像和颜色混合,最终结果将显示在视图中

                                                
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
41
42
43
44
45
46
47
48
// This method fetches tiles for the specified level and size.
// Override this method to process the data returned from the server.
fetchTile: function (level, row, col, options) {

  // call getTileUrl() method to construct the URL to tiles
  // for a given level, row and col provided by the LayerView
  const url = this.getTileUrl(level, row, col);

  // request for tiles based on the generated url
  // the signal option ensures that obsolete requests are aborted
  return geosceneRequest(url, {
    responseType: "image",
    signal: options && options.signal
  })
    .then(function (response) {
      // when esri request resolves successfully
      // get the image from the response
      const image = response.data;
      const width = this.tileInfo.size[0];
      const height = this.tileInfo.size[0];

      // create a canvas with 2D rendering context
      const canvas = document.createElement("canvas");
      const context = canvas.getContext("2d");
      canvas.width = width;
      canvas.height = height;

      // Apply the tint color provided by
      // by the application to the canvas
      if (this.tint) {
        // Get a CSS color string in rgba form
        // representing the tint Color instance.
        context.fillStyle = this.tint.toCss();
        context.fillRect(0, 0, width, height);

        // Applies "difference" blending operation between canvas
        // and steman tiles. Difference blending operation subtracts
        // the bottom layer (canvas) from the top layer (tiles) or the
        // other way round to always get a positive value.
        context.globalCompositeOperation = "difference";
      }

      // Draw the blended image onto the canvas.
      context.drawImage(image, 0, 0, width, height);

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

在 JavaScript 应用程序中使用自定义切片图层

一旦创建了自定义图层,你可以将它 地图 添加到 的各个图层,并将地图添加到 MapViewSceneView 实例中。

                 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Create a new instance of the TintLayer and set its properties.
const stamenTonerLayer = new TintLayer({
  urlTemplate: "https://stamen-tiles.a.ssl.fastly.net/toner/{z}/{x}/{y}.png",
  tint: "#71DE6E", // blue color
  title: "Stamen Toner"
});

const map = new Map({
  layers: [stamenTonerLayer]
});

const view = new SceneView({
  container: "viewDiv",
  map: map,
  center: [0, 30],
  zoom: 3
});

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