deck.gl icon indicating copy to clipboard operation
deck.gl copied to clipboard

TerrainLayer elevationData does not work with TMS-style tile services (negative Y)

Open giacomoaugello1 opened this issue 1 year ago • 0 comments

Description

When using the TerrainLayer, the elevationData parameter can accept either an image or a URL for a tile service, typically using the {z}/{x}/{y} format. However, when using a TMS-style tile service (where the Y coordinate is flipped or negative), the TerrainLayer fails to render the elevation data correctly because it misinterprets the URL as an image rather than a tile service.

I investigated the code and found that in the file modules/geo-layers/src/terrain-layer/terrain-layer.ts, there is a condition that determines whether the elevationData source is treated as a tile service or as an image. The condition is as follows:

const isTiled =
        elevationData &&
        (Array.isArray(elevationData) ||
          (elevationData.includes('{x}') && elevationData.includes('{y}')))

Since the condition checks for the {y} placeholder in the string, it does not recognize TMS-style URLs where the Y coordinate is negative (e.g., using {-y}), and as a result, it interprets the source as an image instead of a tile service.

Solution

If we update the condition to also check for {-y}, the TerrainLayer will correctly handle TMS-style tile services. By modifying the condition as follows:

const isTiled =
        elevationData &&
        (Array.isArray(elevationData) ||
          (elevationData.includes('{x}') &&
            (elevationData.includes('{y}') || elevationData.includes('{-y}'))))

everything works as expected.

I've cloned the repository and tested it; I can confirm that the following patch works:

diff --git a/modules/geo-layers/src/terrain-layer/terrain-layer.ts b/modules/geo-layers/src/terrain-layer/terrain-layer.ts
index a71f0cd08..d44290286 100644
--- a/modules/geo-layers/src/terrain-layer/terrain-layer.ts
+++ b/modules/geo-layers/src/terrain-layer/terrain-layer.ts
@@ -137,7 +137,7 @@ export default class TerrainLayer<ExtraPropsT extends {} = {}> extends Composite
       const isTiled =
         elevationData &&
         (Array.isArray(elevationData) ||
-          (elevationData.includes('{x}') && elevationData.includes('{y}')));
+          (elevationData.includes('{x}') && (elevationData.includes('{y}') || elevationData.includes('{-y}'))));
       this.setState({isTiled});
     }

Flavors

  • [ ] Script tag
  • [X] React
  • [ ] Python/Jupyter notebook
  • [ ] MapboxOverlay
  • [ ] GoogleMapsOverlay
  • [ ] CartoLayer
  • [ ] ArcGIS

Expected Behavior

The TerrainLayer should correctly interpret the TMS-style URLs, recognizing {-y} as a valid coordinate format, and render the elevation data properly from the tile service.

Steps to Reproduce

To reproduce the bug, simply use any TMS-style tile service (where the Y coordinate is flipped or negative) as elevationData for a TerrainLayer.

Environment

  • Framework version: 9.1.0-alpha.0
  • Browser: Chrome Version 129.0.6668.60
  • OS: macOS Sequoia Version 15.1 Beta

Logs

No response

giacomoaugello1 avatar Sep 29 '24 19:09 giacomoaugello1