All files / engine/Source/Scene OpenStreetMapImageryProvider.js

100% Statements 23/23
95% Branches 19/20
100% Functions 1/1
100% Lines 23/23

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129                  1x                                                                                                   14x   14x     14x 14x       14x       14x 14x   14x 14x   14x         14x       14x         14x   14x 1x           13x 13x 1x     13x                       1x 1x     1x          
import Credit from "../Core/Credit.js";
import Frozen from "../Core/Frozen.js";
import defined from "../Core/defined.js";
import DeveloperError from "../Core/DeveloperError.js";
import Rectangle from "../Core/Rectangle.js";
import Resource from "../Core/Resource.js";
import WebMercatorTilingScheme from "../Core/WebMercatorTilingScheme.js";
import UrlTemplateImageryProvider from "./UrlTemplateImageryProvider.js";
 
const defaultCredit = new Credit(
  "MapQuest, Open Street Map and contributors, CC-BY-SA",
);
 
/**
 * @typedef {object} OpenStreetMapImageryProvider.ConstructorOptions
 *
 * Initialization options for the OpenStreetMapImageryProvider constructor
 *
 * @property {string} [url='https://tile.openstreetmap.org'] The OpenStreetMap server url.
 * @property {string} [fileExtension='png'] The file extension for images on the server.
 * @property {boolean} [retinaTiles=false] When true, request tiles at the 2x resolution for retina displays.
 * @property {Rectangle} [rectangle=Rectangle.MAX_VALUE] The rectangle of the layer.
 * @property {number} [minimumLevel=0] The minimum level-of-detail supported by the imagery provider.
 * @property {number} [maximumLevel] The maximum level-of-detail supported by the imagery provider, or undefined if there is no limit.
 * @property {Ellipsoid} [ellipsoid] The ellipsoid.  If not specified, the WGS84 ellipsoid is used.
 * @property {Credit|string} [credit='MapQuest, Open Street Map and contributors, CC-BY-SA'] A credit for the data source, which is displayed on the canvas.
 */
 
/**
 * An imagery provider that provides tiled imagery hosted by OpenStreetMap
 * or another provider of Slippy tiles.  The default url connects to OpenStreetMap's volunteer-run
 * servers, so you must conform to their
 * {@link http://wiki.openstreetmap.org/wiki/Tile_usage_policy|Tile Usage Policy}.
 *
 * @alias OpenStreetMapImageryProvider
 * @constructor
 * @extends UrlTemplateImageryProvider
 *
 * @param {OpenStreetMapImageryProvider.ConstructorOptions} options Object describing initialization options
 * @exception {DeveloperError} The rectangle and minimumLevel indicate that there are more than four tiles at the minimum level. Imagery providers with more than four tiles at the minimum level are not supported.
 *
 * @see ArcGisMapServerImageryProvider
 * @see BingMapsImageryProvider
 * @see GoogleEarthEnterpriseMapsProvider
 * @see SingleTileImageryProvider
 * @see TileMapServiceImageryProvider
 * @see WebMapServiceImageryProvider
 * @see WebMapTileServiceImageryProvider
 * @see UrlTemplateImageryProvider
 *
 * @example
 * const osm = new Cesium.OpenStreetMapImageryProvider({
 *     url : 'https://tile.openstreetmap.org/'
 * });
 *
 * @see {@link http://wiki.openstreetmap.org/wiki/Main_Page|OpenStreetMap Wiki}
 * @see {@link http://www.w3.org/TR/cors/|Cross-Origin Resource Sharing}
 */
function OpenStreetMapImageryProvider(options) {
  options = options ?? Frozen.EMPTY_OBJECT;
 
  const resource = Resource.createIfNeeded(
    options.url ?? "https://tile.openstreetmap.org/",
  );
  resource.appendForwardSlash();
  resource.url += `{z}/{x}/{y}${
    options.retinaTiles ? "@2x" : ""
  }.${options.fileExtension ?? "png"}`;
 
  const tilingScheme = new WebMercatorTilingScheme({
    ellipsoid: options.ellipsoid,
  });
 
  const tileWidth = 256;
  const tileHeight = 256;
 
  const minimumLevel = options.minimumLevel ?? 0;
  const maximumLevel = options.maximumLevel;
 
  const rectangle = options.rectangle ?? tilingScheme.rectangle;
 
  // 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 = tilingScheme.positionToTileXY(
    Rectangle.southwest(rectangle),
    minimumLevel,
  );
  const neTile = tilingScheme.positionToTileXY(
    Rectangle.northeast(rectangle),
    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 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');
 
  let credit = options.credit ?? defaultCredit;
  if (typeof credit === "string") {
    credit = new Credit(credit);
  }
 
  UrlTemplateImageryProvider.call(this, {
    url: resource,
    credit: credit,
    tilingScheme: tilingScheme,
    tileWidth: tileWidth,
    tileHeight: tileHeight,
    minimumLevel: minimumLevel,
    maximumLevel: maximumLevel,
    rectangle: rectangle,
  });
}
 
Eif (defined(Object.create)) {
  OpenStreetMapImageryProvider.prototype = Object.create(
    UrlTemplateImageryProvider.prototype,
  );
  OpenStreetMapImageryProvider.prototype.constructor =
    OpenStreetMapImageryProvider;
}
 
export default OpenStreetMapImageryProvider;