drawTile_(
    frameState,
    tileRepresentation,
    tileZ,
    gutter,
    extent,
    alphaLookup,
    tileGrid,
  ) {
    if (!tileRepresentation.ready) {
      return;
    }
    const tile = tileRepresentation.tile;
    const tileCoord = tile.tileCoord;
    const tileCoordKey = getTileCoordKey(tileCoord);
    const alpha = tileCoordKey in alphaLookup ? alphaLookup[tileCoordKey] : 1;

    const tileResolution = tileGrid.getResolution(tileZ);
    const tileSize = toSize(tileGrid.getTileSize(tileZ), this.tempSize_);
    const tileOrigin = tileGrid.getOrigin(tileZ);
    const tileExtent = tileGrid.getTileCoordExtent(tileCoord);
    // tiles with alpha are rendered last to allow blending
    const depth = alpha < 1 ? -1 : depthForZ(tileZ);
    if (alpha < 1) {
      frameState.animate = true;
    }

    const viewState = frameState.viewState;
    const centerX = viewState.center[0];
    const centerY = viewState.center[1];

    const tileWidthWithGutter = tileSize[0] + 2 * gutter;
    const tileHeightWithGutter = tileSize[1] + 2 * gutter;

    const aspectRatio = tileWidthWithGutter / tileHeightWithGutter;

    const centerI = (centerX - tileOrigin[0]) / (tileSize[0] * tileResolution);
    const centerJ = (tileOrigin[1] - centerY) / (tileSize[1] * tileResolution);

    const tileScale = viewState.resolution / tileResolution;

    const tileCenterI = tileCoord[1];
    const tileCenterJ = tileCoord[2];

    resetTransform(this.tileTransform_);
    scaleTransform(
      this.tileTransform_,
      2 / ((frameState.size[0] * tileScale) / tileWidthWithGutter),
      -2 / ((frameState.size[1] * tileScale) / tileWidthWithGutter),
    );
    rotateTransform(this.tileTransform_, viewState.rotation);
    scaleTransform(this.tileTransform_, 1, 1 / aspectRatio);
    translateTransform(
      this.tileTransform_,
      (tileSize[0] * (tileCenterI - centerI) - gutter) / tileWidthWithGutter,
      (tileSize[1] * (tileCenterJ - centerJ) - gutter) / tileHeightWithGutter,
    );

    this.renderTile(
      /** @type {TileRepresentation} */ (tileRepresentation),
      this.tileTransform_,
      frameState,
      extent,
      tileResolution,
      tileSize,
      tileOrigin,
      tileExtent,
      depth,
      gutter,
      alpha,
    );
  }
@param {TileRepresentation} tileRepresentation Tile representation
@param {number} tileZ Tile Z
@param {import("../../extent.js").Extent} extent Render extent
@param {number} depth Depth
@protected