constructor(tileSource, opt_options) {
    super();

    // Public options required by the Maps API.

    var options = opt_options || {};
    this.minZoom = options.minZoom || 0;
    this.maxZoom = options.maxZoom || 20;
    if (!window['google'] || !window['google']['maps']) {
      throw Error('Google Maps API hasn\'t been initialized.');
    }
    this.tileSize = options.tileSize ||
        new google.maps.Size(
            ee.layers.AbstractOverlay.DEFAULT_TILE_EDGE_LENGTH,
            ee.layers.AbstractOverlay.DEFAULT_TILE_EDGE_LENGTH);
    this.isPng = 'isPng' in options ? options.isPng : true;
    this.name = options.name;
    this.opacity = 'opacity' in options ? options.opacity : 1;

    // Protected internal members.

    /** @protected {!ee.layers.AbstractOverlayStats} */
    this.stats = new ee.layers.AbstractOverlayStats(tileSource.getUniqueId());

    /** @protected {goog.structs.Map<string, ee.layers.AbstractTile>} */
    this.tilesById = new goog.structs.Map();

    /** @protected {number} The count of tiles that have been requested. */
    this.tileCounter = 0;

    /** @protected {ee.layers.AbstractTileSource} The overlay's tile source. */
    this.tileSource = tileSource;

    /** @protected {goog.events.EventHandler} The overlay's event handler. */
    this.handler = new goog.events.EventHandler(this);

    // MapType options required by the compiler but which we don't support.

    /** @type {?} */
    this.projection;
    /** @type {?} */
    this.alt;
    this.radius = 0;
  }
@param {!ee.layers.AbstractTileSource} tileSource The source of tiles
    for this map layer.
@param {Object=} opt_options Initialization options, of the same form as a
    google.maps.ImageMapTypeOptions object.