function WebMapTileServiceImageryProvider(options) {
  options = options ?? Frozen.EMPTY_OBJECT;

  //>>includeStart('debug', pragmas.debug);
  if (!defined(options.url)) {
    throw new DeveloperError("options.url is required.");
  }
  if (!defined(options.layer)) {
    throw new DeveloperError("options.layer is required.");
  }
  if (!defined(options.style)) {
    throw new DeveloperError("options.style is required.");
  }
  if (!defined(options.tileMatrixSetID)) {
    throw new DeveloperError("options.tileMatrixSetID is required.");
  }
  if (defined(options.times) && !defined(options.clock)) {
    throw new DeveloperError(
      "options.times was specified, so options.clock is required.",
    );
  }
  //>>includeEnd('debug');

  this._defaultAlpha = undefined;
  this._defaultNightAlpha = undefined;
  this._defaultDayAlpha = undefined;
  this._defaultBrightness = undefined;
  this._defaultContrast = undefined;
  this._defaultHue = undefined;
  this._defaultSaturation = undefined;
  this._defaultGamma = undefined;
  this._defaultMinificationFilter = undefined;
  this._defaultMagnificationFilter = undefined;

  const resource = Resource.createIfNeeded(options.url);

  const style = options.style;
  const tileMatrixSetID = options.tileMatrixSetID;
  const url = resource.url;

  const bracketMatch = url.match(/{/g);
  if (
    !defined(bracketMatch) ||
    (bracketMatch.length === 1 && /{s}/.test(url))
  ) {
    resource.setQueryParameters(defaultParameters);
    this._useKvp = true;
  } else {
    const templateValues = {
      style: style,
      Style: style,
      TileMatrixSet: tileMatrixSetID,
    };

    resource.setTemplateValues(templateValues);
    this._useKvp = false;
  }

  this._resource = resource;
  this._layer = options.layer;
  this._style = style;
  this._tileMatrixSetID = tileMatrixSetID;
  this._tileMatrixLabels = options.tileMatrixLabels;
  this._format = options.format ?? "image/jpeg";
  this._tileDiscardPolicy = options.tileDiscardPolicy;

  this._tilingScheme = defined(options.tilingScheme)
    ? options.tilingScheme
    : new WebMercatorTilingScheme({ ellipsoid: options.ellipsoid });
  this._tileWidth = options.tileWidth ?? 256;
  this._tileHeight = options.tileHeight ?? 256;

  this._minimumLevel = options.minimumLevel ?? 0;
  this._maximumLevel = options.maximumLevel;

  this._rectangle = options.rectangle ?? this._tilingScheme.rectangle;
  this._dimensions = options.dimensions;

  const that = this;
  this._reload = undefined;
  if (defined(options.times)) {
    this._timeDynamicImagery = new TimeDynamicImagery({
      clock: options.clock,
      times: options.times,
      requestImageFunction: function (x, y, level, request, interval) {
        return requestImage(that, x, y, level, request, interval);
      },
      reloadFunction: function () {
        if (defined(that._reload)) {
          that._reload();
        }
      },
    });
  }

  // Check the number of tiles at the minimum level.  If it's more than four,
  // throw an exception, because starting at the higher minimum
  // level will cause too many tiles to be downloaded and rendered.
  const swTile = this._tilingScheme.positionToTileXY(
    Rectangle.southwest(this._rectangle),
    this._minimumLevel,
  );
  const neTile = this._tilingScheme.positionToTileXY(
    Rectangle.northeast(this._rectangle),
    this._minimumLevel,
  );
  const tileCount =
    (Math.abs(neTile.x - swTile.x) + 1) * (Math.abs(neTile.y - swTile.y) + 1);
  //>>includeStart('debug', pragmas.debug);
  if (tileCount > 4) {
    throw new DeveloperError(
      `The imagery provider's rectangle and minimumLevel indicate that there are ${tileCount} tiles at the minimum level. Imagery providers with more than four tiles at the minimum level are not supported.`,
    );
  }
  //>>includeEnd('debug');

  this._errorEvent = new Event();

  const credit = options.credit;
  this._credit = typeof credit === "string" ? new Credit(credit) : credit;

  this._subdomains = options.subdomains;
  if (Array.isArray(this._subdomains)) {
    this._subdomains = this._subdomains.slice();
  } else if (defined(this._subdomains) && this._subdomains.length > 0) {
    this._subdomains = this._subdomains.split("");
  } else {
    this._subdomains = ["a", "b", "c"];
  }
}
Provides tiled imagery served by {@link http://www.opengeospatial.org/standards/wmts|WMTS 1.0.0} compliant servers.
This provider supports HTTP KVP-encoded and RESTful GetTile requests, but does not yet support the SOAP encoding.

@alias WebMapTileServiceImageryProvider
@constructor

@param {WebMapTileServiceImageryProvider.ConstructorOptions} options Object describing initialization options

@demo {@link https://sandcastle.cesium.com/index.html?src=Web%20Map%20Tile%20Service%20with%20Time.html|Cesium Sandcastle Web Map Tile Service with Time Demo}

@example
// Example 1. USGS shaded relief tiles (KVP)
const shadedRelief1 = new Cesium.WebMapTileServiceImageryProvider({
    url : 'https://basemap.nationalmap.gov/arcgis/rest/services/USGSShadedReliefOnly/MapServer/WMTS',
    layer : 'USGSShadedReliefOnly',
    style : 'default',
    format : 'image/jpeg',
    tileMatrixSetID : 'default028mm',
    // tileMatrixLabels : ['default028mm:0', 'default028mm:1', 'default028mm:2' ...],
    maximumLevel: 19,
    credit : new Cesium.Credit('U. S. Geological Survey')
});
viewer.imageryLayers.addImageryProvider(shadedRelief1);

@example
// Example 2. USGS shaded relief tiles (RESTful)
const shadedRelief2 = new Cesium.WebMapTileServiceImageryProvider({
    url : 'https://basemap.nationalmap.gov/arcgis/rest/services/USGSShadedReliefOnly/MapServer/WMTS/tile/1.0.0/USGSShadedReliefOnly/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg',
    layer : 'USGSShadedReliefOnly',
    style : 'default',
    format : 'image/jpeg',
    tileMatrixSetID : 'default028mm',
    maximumLevel: 19,
    credit : new Cesium.Credit('U. S. Geological Survey')
});
viewer.imageryLayers.addImageryProvider(shadedRelief2);

@example
// Example 3. NASA time dynamic weather data (RESTful)
const times = Cesium.TimeIntervalCollection.fromIso8601({
    iso8601: '2015-07-30/2017-06-16/P1D',
    dataCallback: function dataCallback(interval, index) {
        return {
            Time: Cesium.JulianDate.toIso8601(interval.start)
        };
    }
});
const weather = new Cesium.WebMapTileServiceImageryProvider({
    url : 'https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/AMSR2_Snow_Water_Equivalent/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png',
    layer : 'AMSR2_Snow_Water_Equivalent',
    style : 'default',
    tileMatrixSetID : '2km',
    maximumLevel : 5,
    format : 'image/png',
    clock: clock,
    times: times,
    credit : new Cesium.Credit('NASA Global Imagery Browse Services for EOSDIS')
});
viewer.imageryLayers.addImageryProvider(weather);

@see ArcGisMapServerImageryProvider
@see BingMapsImageryProvider
@see GoogleEarthEnterpriseMapsProvider
@see OpenStreetMapImageryProvider
@see SingleTileImageryProvider
@see TileMapServiceImageryProvider
@see WebMapServiceImageryProvider
@see UrlTemplateImageryProvider