configure_(sources) {
    let extent;
    let origin;
    let tileSizes;
    let resolutions;
    const samplesPerPixel = new Array(sources.length);
    const nodataValues = new Array(sources.length);
    let minZoom = 0;

    const sourceCount = sources.length;
    for (let sourceIndex = 0; sourceIndex < sourceCount; ++sourceIndex) {
      const images = sources[sourceIndex];
      const imageCount = images.length;

      let sourceExtent;
      let sourceOrigin;
      const sourceTileSizes = new Array(imageCount);
      const sourceResolutions = new Array(imageCount);

      nodataValues[sourceIndex] = new Array(imageCount);

      for (let imageIndex = 0; imageIndex < imageCount; ++imageIndex) {
        const image = images[imageIndex];
        const nodataValue = image.getGDALNoData();
        nodataValues[sourceIndex][imageIndex] =
          nodataValue === null ? NaN : nodataValue;

        const wantedSamples = this.sourceInfo_[sourceIndex].bands;
        samplesPerPixel[sourceIndex] = wantedSamples
          ? wantedSamples.length
          : image.getSamplesPerPixel();
        const level = imageCount - (imageIndex + 1);

        if (!sourceExtent) {
          sourceExtent = getBoundingBox(image);
        }

        if (!sourceOrigin) {
          sourceOrigin = getOrigin(image);
        }

        sourceResolutions[level] = getResolution(image, images[0]);
        sourceTileSizes[level] = [image.getTileWidth(), image.getTileHeight()];
      }

      if (!extent) {
        extent = sourceExtent;
      } else {
        getIntersection(extent, sourceExtent, extent);
      }

      if (!origin) {
        origin = sourceOrigin;
      } else {
        const message = `Origin mismatch for source ${sourceIndex}, got [${sourceOrigin}] but expected [${origin}]`;
        assertEqual(origin, sourceOrigin, 0, message, this.viewRejector);
      }

      if (!resolutions) {
        resolutions = sourceResolutions;
        this.resolutionFactors_[sourceIndex] = 1;
      } else {
        if (resolutions.length - minZoom > sourceResolutions.length) {
          minZoom = resolutions.length - sourceResolutions.length;
        }
        const resolutionFactor =
          resolutions[resolutions.length - 1] /
          sourceResolutions[sourceResolutions.length - 1];
        this.resolutionFactors_[sourceIndex] = resolutionFactor;
        const scaledSourceResolutions = sourceResolutions.map(
          (resolution) => (resolution *= resolutionFactor)
        );
        const message = `Resolution mismatch for source ${sourceIndex}, got [${scaledSourceResolutions}] but expected [${resolutions}]`;
        assertEqual(
          resolutions.slice(minZoom, resolutions.length),
          scaledSourceResolutions,
          0.005,
          message,
          this.viewRejector
        );
      }

      if (!tileSizes) {
        tileSizes = sourceTileSizes;
      } else {
        assertEqual(
          tileSizes.slice(minZoom, tileSizes.length),
          sourceTileSizes,
          0,
          `Tile size mismatch for source ${sourceIndex}`,
          this.viewRejector
        );
      }

      this.sourceImagery_[sourceIndex] = images.reverse();
    }

    for (let i = 0, ii = this.sourceImagery_.length; i < ii; ++i) {
      const sourceImagery = this.sourceImagery_[i];
      while (sourceImagery.length < resolutions.length) {
        sourceImagery.unshift(undefined);
      }
    }

    if (!this.getProjection()) {
      const firstSource = sources[0];
      for (let i = firstSource.length - 1; i >= 0; --i) {
        const image = firstSource[i];
        const projection = getProjection(image);
        if (projection) {
          this.projection = projection;
          break;
        }
      }
    }

    this.samplesPerPixel_ = samplesPerPixel;
    this.nodataValues_ = nodataValues;

    // decide if we need to add an alpha band to handle nodata
    outer: for (let sourceIndex = 0; sourceIndex < sourceCount; ++sourceIndex) {
      // option 1: source is configured with a nodata value
      if (this.sourceInfo_[sourceIndex].nodata !== undefined) {
        this.addAlpha_ = true;
        break;
      }

      const values = nodataValues[sourceIndex];

      // option 2: check image metadata for limited bands
      const bands = this.sourceInfo_[sourceIndex].bands;
      if (bands) {
        for (let i = 0; i < bands.length; ++i) {
          if (!isNaN(values[bands[i] - 1])) {
            this.addAlpha_ = true;
            break outer;
          }
        }
        continue;
      }

      // option 3: check image metadata for all bands
      for (let imageIndex = 0; imageIndex < values.length; ++imageIndex) {
        if (!isNaN(values[imageIndex])) {
          this.addAlpha_ = true;
          break outer;
        }
      }
    }

    const additionalBands = this.addAlpha_ ? 1 : 0;
    this.bandCount =
      samplesPerPixel.reduce((accumulator, value) => {
        accumulator += value;
        return accumulator;
      }, 0) + additionalBands;

    const tileGrid = new TileGrid({
      extent: extent,
      minZoom: minZoom,
      origin: origin,
      resolutions: resolutions,
      tileSizes: tileSizes,
    });

    this.tileGrid = tileGrid;

    this.setLoader(this.loadTile_.bind(this));
    this.setState(State.READY);
    this.viewResolver({
      projection: this.projection,
      resolutions: resolutions,
      center: toUserCoordinate(getCenter(extent), this.projection),
      extent: toUserExtent(extent, this.projection),
      zoom: 0,
    });
  }
/**
   * Configure the tile grid based on images within the source GeoTIFFs.  Each GeoTIFF
   * must have the same internal tiled structure.
   * @param {Array<Array<GeoTIFFImage>>} sources Each source is a list of images
   * from a single GeoTIFF.
   * @private
   */
Configure the tile grid based on images within the source GeoTIFFs.  Each GeoTIFF
must have the same internal tiled structure.
@param {Array>} sources Each source is a list of images
from a single GeoTIFF.
@private
Configure the tile grid based on images within the source GeoTIFFs . Each GeoTIFF must have the same internal tiled structure . @param { Array > } sources Each source is a list of images from a single GeoTIFF . @private
configure_(sources) {
    let extent;
    let origin;
    let tileSizes;
    let resolutions;
    const samplesPerPixel = new Array(sources.length);
    const nodataValues = new Array(sources.length);
    let minZoom = 0;
    const sourceCount = sources.length;
    for (let sourceIndex = 0; sourceIndex < sourceCount; ++sourceIndex) {
      const images = sources[sourceIndex];
      const imageCount = images.length;
      let sourceExtent;
      let sourceOrigin;
      const sourceTileSizes = new Array(imageCount);
      const sourceResolutions = new Array(imageCount);
      nodataValues[sourceIndex] = new Array(imageCount);
      for (let imageIndex = 0; imageIndex < imageCount; ++imageIndex) {
        const image = images[imageIndex];
        const nodataValue = image.getGDALNoData();
        nodataValues[sourceIndex][imageIndex] =
          nodataValue === null ? NaN : nodataValue;
        const wantedSamples = this.sourceInfo_[sourceIndex].bands;
        samplesPerPixel[sourceIndex] = wantedSamples
          ? wantedSamples.length
          : image.getSamplesPerPixel();
        const level = imageCount - (imageIndex + 1);
        if (!sourceExtent) {
          sourceExtent = getBoundingBox(image);
        }
        if (!sourceOrigin) {
          sourceOrigin = getOrigin(image);
        }
        sourceResolutions[level] = getResolution(image, images[0]);
        sourceTileSizes[level] = [image.getTileWidth(), image.getTileHeight()];
      }
      if (!extent) {
        extent = sourceExtent;
      } else {
        getIntersection(extent, sourceExtent, extent);
      }
      if (!origin) {
        origin = sourceOrigin;
      } else {
        const message = `Origin mismatch for source ${sourceIndex}, got [${sourceOrigin}] but expected [${origin}]`;
        assertEqual(origin, sourceOrigin, 0, message, this.viewRejector);
      }
      if (!resolutions) {
        resolutions = sourceResolutions;
        this.resolutionFactors_[sourceIndex] = 1;
      } else {
        if (resolutions.length - minZoom > sourceResolutions.length) {
          minZoom = resolutions.length - sourceResolutions.length;
        }
        const resolutionFactor =
          resolutions[resolutions.length - 1] /
          sourceResolutions[sourceResolutions.length - 1];
        this.resolutionFactors_[sourceIndex] = resolutionFactor;
        const scaledSourceResolutions = sourceResolutions.map(
          (resolution) => (resolution *= resolutionFactor)
        );
        const message = `Resolution mismatch for source ${sourceIndex}, got [${scaledSourceResolutions}] but expected [${resolutions}]`;
        assertEqual(
          resolutions.slice(minZoom, resolutions.length),
          scaledSourceResolutions,
          0.005,
          message,
          this.viewRejector
        );
      }
      if (!tileSizes) {
        tileSizes = sourceTileSizes;
      } else {
        assertEqual(
          tileSizes.slice(minZoom, tileSizes.length),
          sourceTileSizes,
          0,
          `Tile size mismatch for source ${sourceIndex}`,
          this.viewRejector
        );
      }
      this.sourceImagery_[sourceIndex] = images.reverse();
    }
    for (let i = 0, ii = this.sourceImagery_.length; i < ii; ++i) {
      const sourceImagery = this.sourceImagery_[i];
      while (sourceImagery.length < resolutions.length) {
        sourceImagery.unshift(undefined);
      }
    }
    if (!this.getProjection()) {
      const firstSource = sources[0];
      for (let i = firstSource.length - 1; i >= 0; --i) {
        const image = firstSource[i];
        const projection = getProjection(image);
        if (projection) {
          this.projection = projection;
          break;
        }
      }
    }
    this.samplesPerPixel_ = samplesPerPixel;
    this.nodataValues_ = nodataValues;
    outer: for (let sourceIndex = 0; sourceIndex < sourceCount; ++sourceIndex) {
      if (this.sourceInfo_[sourceIndex].nodata !== undefined) {
        this.addAlpha_ = true;
        break;
      }
      const values = nodataValues[sourceIndex];
      const bands = this.sourceInfo_[sourceIndex].bands;
      if (bands) {
        for (let i = 0; i < bands.length; ++i) {
          if (!isNaN(values[bands[i] - 1])) {
            this.addAlpha_ = true;
            break outer;
          }
        }
        continue;
      }
      for (let imageIndex = 0; imageIndex < values.length; ++imageIndex) {
        if (!isNaN(values[imageIndex])) {
          this.addAlpha_ = true;
          break outer;
        }
      }
    }
    const additionalBands = this.addAlpha_ ? 1 : 0;
    this.bandCount =
      samplesPerPixel.reduce((accumulator, value) => {
        accumulator += value;
        return accumulator;
      }, 0) + additionalBands;
    const tileGrid = new TileGrid({
      extent: extent,
      minZoom: minZoom,
      origin: origin,
      resolutions: resolutions,
      tileSizes: tileSizes,
    });
    this.tileGrid = tileGrid;
    this.setLoader(this.loadTile_.bind(this));
    this.setState(State.READY);
    this.viewResolver({
      projection: this.projection,
      resolutions: resolutions,
      center: toUserCoordinate(getCenter(extent), this.projection),
      extent: toUserExtent(extent, this.projection),
      zoom: 0,
    });
  }
configure_ ( sources ) { let extent ; let origin ; let tileSizes ; let resolutions ; const samplesPerPixel = new Array ( sources . length ) ; const nodataValues = new Array ( sources . length ) ; let minZoom = 0 ; const sourceCount = sources . length ; for ( let sourceIndex = 0 ; sourceIndex < sourceCount ; ++ sourceIndex ) { const images = sources [ sourceIndex ] ; const imageCount = images . length ; let sourceExtent ; let sourceOrigin ; const sourceTileSizes = new Array ( imageCount ) ; const sourceResolutions = new Array ( imageCount ) ; nodataValues [ sourceIndex ] = new Array ( imageCount ) ; for ( let imageIndex = 0 ; imageIndex < imageCount ; ++ imageIndex ) { const image = images [ imageIndex ] ; const nodataValue = image . getGDALNoData ( ) ; nodataValues [ sourceIndex ] [ imageIndex ] = nodataValue === null ? NaN : nodataValue ; const wantedSamples = this . sourceInfo_ [ sourceIndex ] . bands ; samplesPerPixel [ sourceIndex ] = wantedSamples ? wantedSamples . length : image . getSamplesPerPixel ( ) ; const level = imageCount - ( imageIndex + 1 ) ; if ( ! sourceExtent ) { sourceExtent = getBoundingBox ( image ) ; } if ( ! sourceOrigin ) { sourceOrigin = getOrigin ( image ) ; } sourceResolutions [ level ] = getResolution ( image , images [ 0 ] ) ; sourceTileSizes [ level ] = [ image . getTileWidth ( ) , image . getTileHeight ( ) ] ; } if ( ! extent ) { extent = sourceExtent ; } else { getIntersection ( extent , sourceExtent , extent ) ; } if ( ! origin ) { origin = sourceOrigin ; } else { const message = ` ${ sourceIndex } ${ sourceOrigin } ${ origin } ` ; assertEqual ( origin , sourceOrigin , 0 , message , this . viewRejector ) ; } if ( ! resolutions ) { resolutions = sourceResolutions ; this . resolutionFactors_ [ sourceIndex ] = 1 ; } else { if ( resolutions . length - minZoom > sourceResolutions . length ) { minZoom = resolutions . length - sourceResolutions . length ; } const resolutionFactor = resolutions [ resolutions . length - 1 ] / sourceResolutions [ sourceResolutions . length - 1 ] ; this . resolutionFactors_ [ sourceIndex ] = resolutionFactor ; const scaledSourceResolutions = sourceResolutions . map ( ( resolution ) => ( resolution *= resolutionFactor ) ) ; const message = ` ${ sourceIndex } ${ scaledSourceResolutions } ${ resolutions } ` ; assertEqual ( resolutions . slice ( minZoom , resolutions . length ) , scaledSourceResolutions , 0.005 , message , this . viewRejector ) ; } if ( ! tileSizes ) { tileSizes = sourceTileSizes ; } else { assertEqual ( tileSizes . slice ( minZoom , tileSizes . length ) , sourceTileSizes , 0 , ` ${ sourceIndex } ` , this . viewRejector ) ; } this . sourceImagery_ [ sourceIndex ] = images . reverse ( ) ; } for ( let i = 0 , ii = this . sourceImagery_ . length ; i < ii ; ++ i ) { const sourceImagery = this . sourceImagery_ [ i ] ; while ( sourceImagery . length < resolutions . length ) { sourceImagery . unshift ( undefined ) ; } } if ( ! this . getProjection ( ) ) { const firstSource = sources [ 0 ] ; for ( let i = firstSource . length - 1 ; i >= 0 ; -- i ) { const image = firstSource [ i ] ; const projection = getProjection ( image ) ; if ( projection ) { this . projection = projection ; break ; } } } this . samplesPerPixel_ = samplesPerPixel ; this . nodataValues_ = nodataValues ; outer : for ( let sourceIndex = 0 ; sourceIndex < sourceCount ; ++ sourceIndex ) { if ( this . sourceInfo_ [ sourceIndex ] . nodata !== undefined ) { this . addAlpha_ = true ; break ; } const values = nodataValues [ sourceIndex ] ; const bands = this . sourceInfo_ [ sourceIndex ] . bands ; if ( bands ) { for ( let i = 0 ; i < bands . length ; ++ i ) { if ( ! isNaN ( values [ bands [ i ] - 1 ] ) ) { this . addAlpha_ = true ; break outer ; } } continue ; } for ( let imageIndex = 0 ; imageIndex < values . length ; ++ imageIndex ) { if ( ! isNaN ( values [ imageIndex ] ) ) { this . addAlpha_ = true ; break outer ; } } } const additionalBands = this . addAlpha_ ? 1 : 0 ; this . bandCount = samplesPerPixel . reduce ( ( accumulator , value ) => { accumulator += value ; return accumulator ; } , 0 ) + additionalBands ; const tileGrid = new TileGrid ( { extent : extent , minZoom : minZoom , origin : origin , resolutions : resolutions , tileSizes : tileSizes , } ) ; this . tileGrid = tileGrid ; this . setLoader ( this . loadTile_ . bind ( this ) ) ; this . setState ( State . READY ) ; this . viewResolver ( { projection : this . projection , resolutions : resolutions , center : toUserCoordinate ( getCenter ( extent ) , this . projection ) , extent : toUserExtent ( extent , this . projection ) , zoom : 0 , } ) ; }
Configure the tile grid based on images within the source GeoTIFFs.
Configure the tile grid based on images within the source GeoTIFFs .
// decide if we need to add an alpha band to handle nodata // option 1: source is configured with a nodata value // option 2: check image metadata for limited bands // option 3: check image metadata for all bands