getReprojTile_(z, x, y, targetProj, sourceProj) {
    const sourceTileGrid =
      this.tileGrid || this.getTileGridForProjection(sourceProj || targetProj);
    const reprojTilePixelRatio = Math.max.apply(
      null,
      sourceTileGrid.getResolutions().map((r, z) => {
        const tileSize = toSize(sourceTileGrid.getTileSize(z));
        const textureSize = this.getTileSize(z);
        return Math.max(
          textureSize[0] / tileSize[0],
          textureSize[1] / tileSize[1],
        );
      }),
    );

    const targetTileGrid = this.getTileGridForProjection(targetProj);
    const tileCoord = [z, x, y];
    const wrappedTileCoord = this.getTileCoordForTileUrlFunction(
      tileCoord,
      targetProj,
    );

    const options = Object.assign(
      {
        sourceProj: sourceProj || targetProj,
        sourceTileGrid,
        targetProj,
        targetTileGrid,
        tileCoord,
        wrappedTileCoord,
        pixelRatio: reprojTilePixelRatio,
        gutter: this.gutter_,
        getTileFunction: (z, x, y, pixelRatio) =>
          this.getTile(z, x, y, pixelRatio),
        transformMatrix: this.transformMatrix,
      },
      /** @type {import("../reproj/DataTile.js").Options} */ (this.tileOptions),
    );
    const tile = /** @type {TileType} */ (
      /** @type {*} */ (new ReprojDataTile(options))
    );
    tile.key = this.getKey();
    return tile;
  }
@param {number} z Tile coordinate z.
@param {number} x Tile coordinate x.
@param {number} y Tile coordinate y.
@param {import("../proj/Projection.js").default} targetProj The output projection.
@param {import("../proj/Projection.js").default} sourceProj The input projection.
@return {!TileType} Tile.