GridImageryProvider.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  1. import Color from "../Core/Color.js";
  2. import defaultValue from "../Core/defaultValue.js";
  3. import defined from "../Core/defined.js";
  4. import Event from "../Core/Event.js";
  5. import GeographicTilingScheme from "../Core/GeographicTilingScheme.js";
  6. const defaultColor = new Color(1.0, 1.0, 1.0, 0.4);
  7. const defaultGlowColor = new Color(0.0, 1.0, 0.0, 0.05);
  8. const defaultBackgroundColor = new Color(0.0, 0.5, 0.0, 0.2);
  9. /**
  10. * @typedef {Object} GridImageryProvider.ConstructorOptions
  11. *
  12. * Initialization options for the GridImageryProvider constructor
  13. *
  14. * @property {TilingScheme} [tilingScheme=new GeographicTilingScheme()] The tiling scheme for which to draw tiles.
  15. * @property {Ellipsoid} [ellipsoid] The ellipsoid. If the tilingScheme is specified,
  16. * this parameter is ignored and the tiling scheme's ellipsoid is used instead. If neither
  17. * parameter is specified, the WGS84 ellipsoid is used.
  18. * @property {Number} [cells=8] The number of grids cells.
  19. * @property {Color} [color=Color(1.0, 1.0, 1.0, 0.4)] The color to draw grid lines.
  20. * @property {Color} [glowColor=Color(0.0, 1.0, 0.0, 0.05)] The color to draw glow for grid lines.
  21. * @property {Number} [glowWidth=6] The width of lines used for rendering the line glow effect.
  22. * @property {Color} [backgroundColor=Color(0.0, 0.5, 0.0, 0.2)] Background fill color.
  23. * @property {Number} [tileWidth=256] The width of the tile for level-of-detail selection purposes.
  24. * @property {Number} [tileHeight=256] The height of the tile for level-of-detail selection purposes.
  25. * @property {Number} [canvasSize=256] The size of the canvas used for rendering.
  26. */
  27. /**
  28. * An {@link ImageryProvider} that draws a wireframe grid on every tile with controllable background and glow.
  29. * May be useful for custom rendering effects or debugging terrain.
  30. *
  31. * @alias GridImageryProvider
  32. * @constructor
  33. * @param {GridImageryProvider.ConstructorOptions} options Object describing initialization options
  34. *
  35. */
  36. function GridImageryProvider(options) {
  37. options = defaultValue(options, defaultValue.EMPTY_OBJECT);
  38. /**
  39. * The default alpha blending value of this provider, with 0.0 representing fully transparent and
  40. * 1.0 representing fully opaque.
  41. *
  42. * @type {Number|undefined}
  43. * @default undefined
  44. */
  45. this.defaultAlpha = undefined;
  46. /**
  47. * The default alpha blending value on the night side of the globe of this provider, with 0.0 representing fully transparent and
  48. * 1.0 representing fully opaque.
  49. *
  50. * @type {Number|undefined}
  51. * @default undefined
  52. */
  53. this.defaultNightAlpha = undefined;
  54. /**
  55. * The default alpha blending value on the day side of the globe of this provider, with 0.0 representing fully transparent and
  56. * 1.0 representing fully opaque.
  57. *
  58. * @type {Number|undefined}
  59. * @default undefined
  60. */
  61. this.defaultDayAlpha = undefined;
  62. /**
  63. * The default brightness of this provider. 1.0 uses the unmodified imagery color. Less than 1.0
  64. * makes the imagery darker while greater than 1.0 makes it brighter.
  65. *
  66. * @type {Number|undefined}
  67. * @default undefined
  68. */
  69. this.defaultBrightness = undefined;
  70. /**
  71. * The default contrast of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces
  72. * the contrast while greater than 1.0 increases it.
  73. *
  74. * @type {Number|undefined}
  75. * @default undefined
  76. */
  77. this.defaultContrast = undefined;
  78. /**
  79. * The default hue of this provider in radians. 0.0 uses the unmodified imagery color.
  80. *
  81. * @type {Number|undefined}
  82. * @default undefined
  83. */
  84. this.defaultHue = undefined;
  85. /**
  86. * The default saturation of this provider. 1.0 uses the unmodified imagery color. Less than 1.0 reduces the
  87. * saturation while greater than 1.0 increases it.
  88. *
  89. * @type {Number|undefined}
  90. * @default undefined
  91. */
  92. this.defaultSaturation = undefined;
  93. /**
  94. * The default gamma correction to apply to this provider. 1.0 uses the unmodified imagery color.
  95. *
  96. * @type {Number|undefined}
  97. * @default undefined
  98. */
  99. this.defaultGamma = undefined;
  100. /**
  101. * The default texture minification filter to apply to this provider.
  102. *
  103. * @type {TextureMinificationFilter}
  104. * @default undefined
  105. */
  106. this.defaultMinificationFilter = undefined;
  107. /**
  108. * The default texture magnification filter to apply to this provider.
  109. *
  110. * @type {TextureMagnificationFilter}
  111. * @default undefined
  112. */
  113. this.defaultMagnificationFilter = undefined;
  114. this._tilingScheme = defined(options.tilingScheme)
  115. ? options.tilingScheme
  116. : new GeographicTilingScheme({ ellipsoid: options.ellipsoid });
  117. this._cells = defaultValue(options.cells, 8);
  118. this._color = defaultValue(options.color, defaultColor);
  119. this._glowColor = defaultValue(options.glowColor, defaultGlowColor);
  120. this._glowWidth = defaultValue(options.glowWidth, 6);
  121. this._backgroundColor = defaultValue(
  122. options.backgroundColor,
  123. defaultBackgroundColor
  124. );
  125. this._errorEvent = new Event();
  126. this._tileWidth = defaultValue(options.tileWidth, 256);
  127. this._tileHeight = defaultValue(options.tileHeight, 256);
  128. // A little larger than tile size so lines are sharper
  129. // Note: can't be too much difference otherwise texture blowout
  130. this._canvasSize = defaultValue(options.canvasSize, 256);
  131. // We only need a single canvas since all tiles will be the same
  132. this._canvas = this._createGridCanvas();
  133. this._readyPromise = Promise.resolve(true);
  134. }
  135. Object.defineProperties(GridImageryProvider.prototype, {
  136. /**
  137. * Gets the proxy used by this provider.
  138. * @memberof GridImageryProvider.prototype
  139. * @type {Proxy}
  140. * @readonly
  141. */
  142. proxy: {
  143. get: function () {
  144. return undefined;
  145. },
  146. },
  147. /**
  148. * Gets the width of each tile, in pixels. This function should
  149. * not be called before {@link GridImageryProvider#ready} returns true.
  150. * @memberof GridImageryProvider.prototype
  151. * @type {Number}
  152. * @readonly
  153. */
  154. tileWidth: {
  155. get: function () {
  156. return this._tileWidth;
  157. },
  158. },
  159. /**
  160. * Gets the height of each tile, in pixels. This function should
  161. * not be called before {@link GridImageryProvider#ready} returns true.
  162. * @memberof GridImageryProvider.prototype
  163. * @type {Number}
  164. * @readonly
  165. */
  166. tileHeight: {
  167. get: function () {
  168. return this._tileHeight;
  169. },
  170. },
  171. /**
  172. * Gets the maximum level-of-detail that can be requested. This function should
  173. * not be called before {@link GridImageryProvider#ready} returns true.
  174. * @memberof GridImageryProvider.prototype
  175. * @type {Number|undefined}
  176. * @readonly
  177. */
  178. maximumLevel: {
  179. get: function () {
  180. return undefined;
  181. },
  182. },
  183. /**
  184. * Gets the minimum level-of-detail that can be requested. This function should
  185. * not be called before {@link GridImageryProvider#ready} returns true.
  186. * @memberof GridImageryProvider.prototype
  187. * @type {Number}
  188. * @readonly
  189. */
  190. minimumLevel: {
  191. get: function () {
  192. return undefined;
  193. },
  194. },
  195. /**
  196. * Gets the tiling scheme used by this provider. This function should
  197. * not be called before {@link GridImageryProvider#ready} returns true.
  198. * @memberof GridImageryProvider.prototype
  199. * @type {TilingScheme}
  200. * @readonly
  201. */
  202. tilingScheme: {
  203. get: function () {
  204. return this._tilingScheme;
  205. },
  206. },
  207. /**
  208. * Gets the rectangle, in radians, of the imagery provided by this instance. This function should
  209. * not be called before {@link GridImageryProvider#ready} returns true.
  210. * @memberof GridImageryProvider.prototype
  211. * @type {Rectangle}
  212. * @readonly
  213. */
  214. rectangle: {
  215. get: function () {
  216. return this._tilingScheme.rectangle;
  217. },
  218. },
  219. /**
  220. * Gets the tile discard policy. If not undefined, the discard policy is responsible
  221. * for filtering out "missing" tiles via its shouldDiscardImage function. If this function
  222. * returns undefined, no tiles are filtered. This function should
  223. * not be called before {@link GridImageryProvider#ready} returns true.
  224. * @memberof GridImageryProvider.prototype
  225. * @type {TileDiscardPolicy}
  226. * @readonly
  227. */
  228. tileDiscardPolicy: {
  229. get: function () {
  230. return undefined;
  231. },
  232. },
  233. /**
  234. * Gets an event that is raised when the imagery provider encounters an asynchronous error. By subscribing
  235. * to the event, you will be notified of the error and can potentially recover from it. Event listeners
  236. * are passed an instance of {@link TileProviderError}.
  237. * @memberof GridImageryProvider.prototype
  238. * @type {Event}
  239. * @readonly
  240. */
  241. errorEvent: {
  242. get: function () {
  243. return this._errorEvent;
  244. },
  245. },
  246. /**
  247. * Gets a value indicating whether or not the provider is ready for use.
  248. * @memberof GridImageryProvider.prototype
  249. * @type {Boolean}
  250. * @readonly
  251. */
  252. ready: {
  253. get: function () {
  254. return true;
  255. },
  256. },
  257. /**
  258. * Gets a promise that resolves to true when the provider is ready for use.
  259. * @memberof GridImageryProvider.prototype
  260. * @type {Promise.<Boolean>}
  261. * @readonly
  262. */
  263. readyPromise: {
  264. get: function () {
  265. return this._readyPromise;
  266. },
  267. },
  268. /**
  269. * Gets the credit to display when this imagery provider is active. Typically this is used to credit
  270. * the source of the imagery. This function should not be called before {@link GridImageryProvider#ready} returns true.
  271. * @memberof GridImageryProvider.prototype
  272. * @type {Credit}
  273. * @readonly
  274. */
  275. credit: {
  276. get: function () {
  277. return undefined;
  278. },
  279. },
  280. /**
  281. * Gets a value indicating whether or not the images provided by this imagery provider
  282. * include an alpha channel. If this property is false, an alpha channel, if present, will
  283. * be ignored. If this property is true, any images without an alpha channel will be treated
  284. * as if their alpha is 1.0 everywhere. When this property is false, memory usage
  285. * and texture upload time are reduced.
  286. * @memberof GridImageryProvider.prototype
  287. * @type {Boolean}
  288. * @readonly
  289. */
  290. hasAlphaChannel: {
  291. get: function () {
  292. return true;
  293. },
  294. },
  295. });
  296. /**
  297. * Draws a grid of lines into a canvas.
  298. */
  299. GridImageryProvider.prototype._drawGrid = function (context) {
  300. const minPixel = 0;
  301. const maxPixel = this._canvasSize;
  302. for (let x = 0; x <= this._cells; ++x) {
  303. const nx = x / this._cells;
  304. const val = 1 + nx * (maxPixel - 1);
  305. context.moveTo(val, minPixel);
  306. context.lineTo(val, maxPixel);
  307. context.moveTo(minPixel, val);
  308. context.lineTo(maxPixel, val);
  309. }
  310. context.stroke();
  311. };
  312. /**
  313. * Render a grid into a canvas with background and glow
  314. */
  315. GridImageryProvider.prototype._createGridCanvas = function () {
  316. const canvas = document.createElement("canvas");
  317. canvas.width = this._canvasSize;
  318. canvas.height = this._canvasSize;
  319. const minPixel = 0;
  320. const maxPixel = this._canvasSize;
  321. const context = canvas.getContext("2d");
  322. // Fill the background
  323. const cssBackgroundColor = this._backgroundColor.toCssColorString();
  324. context.fillStyle = cssBackgroundColor;
  325. context.fillRect(minPixel, minPixel, maxPixel, maxPixel);
  326. // Glow for grid lines
  327. const cssGlowColor = this._glowColor.toCssColorString();
  328. context.strokeStyle = cssGlowColor;
  329. // Wide
  330. context.lineWidth = this._glowWidth;
  331. context.strokeRect(minPixel, minPixel, maxPixel, maxPixel);
  332. this._drawGrid(context);
  333. // Narrow
  334. context.lineWidth = this._glowWidth * 0.5;
  335. context.strokeRect(minPixel, minPixel, maxPixel, maxPixel);
  336. this._drawGrid(context);
  337. // Grid lines
  338. const cssColor = this._color.toCssColorString();
  339. // Border
  340. context.strokeStyle = cssColor;
  341. context.lineWidth = 2;
  342. context.strokeRect(minPixel, minPixel, maxPixel, maxPixel);
  343. // Inner
  344. context.lineWidth = 1;
  345. this._drawGrid(context);
  346. return canvas;
  347. };
  348. /**
  349. * Gets the credits to be displayed when a given tile is displayed.
  350. *
  351. * @param {Number} x The tile X coordinate.
  352. * @param {Number} y The tile Y coordinate.
  353. * @param {Number} level The tile level;
  354. * @returns {Credit[]} The credits to be displayed when the tile is displayed.
  355. *
  356. * @exception {DeveloperError} <code>getTileCredits</code> must not be called before the imagery provider is ready.
  357. */
  358. GridImageryProvider.prototype.getTileCredits = function (x, y, level) {
  359. return undefined;
  360. };
  361. /**
  362. * Requests the image for a given tile. This function should
  363. * not be called before {@link GridImageryProvider#ready} returns true.
  364. *
  365. * @param {Number} x The tile X coordinate.
  366. * @param {Number} y The tile Y coordinate.
  367. * @param {Number} level The tile level.
  368. * @param {Request} [request] The request object. Intended for internal use only.
  369. * @returns {Promise.<HTMLCanvasElement>} The resolved image as a Canvas DOM object.
  370. */
  371. GridImageryProvider.prototype.requestImage = function (x, y, level, request) {
  372. return Promise.resolve(this._canvas);
  373. };
  374. /**
  375. * Picking features is not currently supported by this imagery provider, so this function simply returns
  376. * undefined.
  377. *
  378. * @param {Number} x The tile X coordinate.
  379. * @param {Number} y The tile Y coordinate.
  380. * @param {Number} level The tile level.
  381. * @param {Number} longitude The longitude at which to pick features.
  382. * @param {Number} latitude The latitude at which to pick features.
  383. * @return {undefined} Undefined since picking is not supported.
  384. */
  385. GridImageryProvider.prototype.pickFeatures = function (
  386. x,
  387. y,
  388. level,
  389. longitude,
  390. latitude
  391. ) {
  392. return undefined;
  393. };
  394. export default GridImageryProvider;