@itwin/core-frontend 4.4.0-dev.9 → 4.5.0-dev.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/CHANGELOG.md +8 -1
  2. package/lib/cjs/DisplayStyleState.d.ts +3 -0
  3. package/lib/cjs/DisplayStyleState.d.ts.map +1 -1
  4. package/lib/cjs/DisplayStyleState.js +10 -0
  5. package/lib/cjs/DisplayStyleState.js.map +1 -1
  6. package/lib/cjs/Viewport.d.ts +5 -0
  7. package/lib/cjs/Viewport.d.ts.map +1 -1
  8. package/lib/cjs/Viewport.js +6 -0
  9. package/lib/cjs/Viewport.js.map +1 -1
  10. package/lib/cjs/common/gltf/GltfSchema.d.ts +20 -3
  11. package/lib/cjs/common/gltf/GltfSchema.d.ts.map +1 -1
  12. package/lib/cjs/common/gltf/GltfSchema.js.map +1 -1
  13. package/lib/cjs/common/imdl/ImdlModel.d.ts +15 -1
  14. package/lib/cjs/common/imdl/ImdlModel.d.ts.map +1 -1
  15. package/lib/cjs/common/imdl/ImdlModel.js +11 -3
  16. package/lib/cjs/common/imdl/ImdlModel.js.map +1 -1
  17. package/lib/cjs/common/imdl/ParseImdlDocument.d.ts +3 -1
  18. package/lib/cjs/common/imdl/ParseImdlDocument.d.ts.map +1 -1
  19. package/lib/cjs/common/imdl/ParseImdlDocument.js +66 -11
  20. package/lib/cjs/common/imdl/ParseImdlDocument.js.map +1 -1
  21. package/lib/cjs/render/GraphicBranch.d.ts +10 -0
  22. package/lib/cjs/render/GraphicBranch.d.ts.map +1 -1
  23. package/lib/cjs/render/GraphicBranch.js.map +1 -1
  24. package/lib/cjs/render/webgl/BranchState.d.ts +2 -0
  25. package/lib/cjs/render/webgl/BranchState.d.ts.map +1 -1
  26. package/lib/cjs/render/webgl/BranchState.js +2 -0
  27. package/lib/cjs/render/webgl/BranchState.js.map +1 -1
  28. package/lib/cjs/render/webgl/Graphic.d.ts.map +1 -1
  29. package/lib/cjs/render/webgl/Graphic.js +3 -0
  30. package/lib/cjs/render/webgl/Graphic.js.map +1 -1
  31. package/lib/cjs/render/webgl/InstancedGeometry.d.ts +1 -0
  32. package/lib/cjs/render/webgl/InstancedGeometry.d.ts.map +1 -1
  33. package/lib/cjs/render/webgl/InstancedGeometry.js +1 -0
  34. package/lib/cjs/render/webgl/InstancedGeometry.js.map +1 -1
  35. package/lib/cjs/render/webgl/RealityMesh.d.ts.map +1 -1
  36. package/lib/cjs/render/webgl/RealityMesh.js +6 -0
  37. package/lib/cjs/render/webgl/RealityMesh.js.map +1 -1
  38. package/lib/cjs/request/utils.d.ts +18 -0
  39. package/lib/cjs/request/utils.d.ts.map +1 -0
  40. package/lib/cjs/request/utils.js +45 -0
  41. package/lib/cjs/request/utils.js.map +1 -0
  42. package/lib/cjs/tile/BatchedTileIdMap.d.ts +1 -2
  43. package/lib/cjs/tile/BatchedTileIdMap.d.ts.map +1 -1
  44. package/lib/cjs/tile/BatchedTileIdMap.js +3 -3
  45. package/lib/cjs/tile/BatchedTileIdMap.js.map +1 -1
  46. package/lib/cjs/tile/GltfReader.d.ts +4 -1
  47. package/lib/cjs/tile/GltfReader.d.ts.map +1 -1
  48. package/lib/cjs/tile/GltfReader.js +125 -26
  49. package/lib/cjs/tile/GltfReader.js.map +1 -1
  50. package/lib/cjs/tile/ImdlDecoder.d.ts +7 -1
  51. package/lib/cjs/tile/ImdlDecoder.d.ts.map +1 -1
  52. package/lib/cjs/tile/ImdlDecoder.js.map +1 -1
  53. package/lib/cjs/tile/ImdlGraphicsCreator.d.ts.map +1 -1
  54. package/lib/cjs/tile/ImdlGraphicsCreator.js +28 -17
  55. package/lib/cjs/tile/ImdlGraphicsCreator.js.map +1 -1
  56. package/lib/cjs/tile/ImdlReader.d.ts +2 -1
  57. package/lib/cjs/tile/ImdlReader.d.ts.map +1 -1
  58. package/lib/cjs/tile/ImdlReader.js +1 -0
  59. package/lib/cjs/tile/ImdlReader.js.map +1 -1
  60. package/lib/cjs/tile/RealityModelTileTree.d.ts.map +1 -1
  61. package/lib/cjs/tile/RealityModelTileTree.js +2 -3
  62. package/lib/cjs/tile/RealityModelTileTree.js.map +1 -1
  63. package/lib/cjs/tile/RealityTileTree.d.ts +31 -0
  64. package/lib/cjs/tile/RealityTileTree.d.ts.map +1 -1
  65. package/lib/cjs/tile/RealityTileTree.js +6 -0
  66. package/lib/cjs/tile/RealityTileTree.js.map +1 -1
  67. package/lib/cjs/tile/TileDrawArgs.d.ts +6 -0
  68. package/lib/cjs/tile/TileDrawArgs.d.ts.map +1 -1
  69. package/lib/cjs/tile/TileDrawArgs.js +7 -0
  70. package/lib/cjs/tile/TileDrawArgs.js.map +1 -1
  71. package/lib/cjs/tile/TileTreeReference.d.ts +2 -0
  72. package/lib/cjs/tile/TileTreeReference.d.ts.map +1 -1
  73. package/lib/cjs/tile/TileTreeReference.js +5 -0
  74. package/lib/cjs/tile/TileTreeReference.js.map +1 -1
  75. package/lib/cjs/tile/map/ArcGISTileMap.d.ts +6 -2
  76. package/lib/cjs/tile/map/ArcGISTileMap.d.ts.map +1 -1
  77. package/lib/cjs/tile/map/ArcGISTileMap.js +127 -69
  78. package/lib/cjs/tile/map/ArcGISTileMap.js.map +1 -1
  79. package/lib/cjs/tile/map/ArcGisUtilities.d.ts.map +1 -1
  80. package/lib/cjs/tile/map/ArcGisUtilities.js +5 -0
  81. package/lib/cjs/tile/map/ArcGisUtilities.js.map +1 -1
  82. package/lib/cjs/tile/map/ImageryProviders/ArcGISImageryProvider.d.ts.map +1 -1
  83. package/lib/cjs/tile/map/ImageryProviders/ArcGISImageryProvider.js +61 -39
  84. package/lib/cjs/tile/map/ImageryProviders/ArcGISImageryProvider.js.map +1 -1
  85. package/lib/cjs/tile/map/ImageryProviders/ArcGISMapLayerImageryProvider.js +1 -1
  86. package/lib/cjs/tile/map/ImageryProviders/ArcGISMapLayerImageryProvider.js.map +1 -1
  87. package/lib/cjs/tile/map/MapLayerImageryProvider.d.ts +6 -0
  88. package/lib/cjs/tile/map/MapLayerImageryProvider.d.ts.map +1 -1
  89. package/lib/cjs/tile/map/MapLayerImageryProvider.js +47 -7
  90. package/lib/cjs/tile/map/MapLayerImageryProvider.js.map +1 -1
  91. package/lib/cjs/tile/map/WmsCapabilities.d.ts.map +1 -1
  92. package/lib/cjs/tile/map/WmsCapabilities.js +1 -15
  93. package/lib/cjs/tile/map/WmsCapabilities.js.map +1 -1
  94. package/lib/cjs/tile/map/WmsUtilities.d.ts +7 -0
  95. package/lib/cjs/tile/map/WmsUtilities.d.ts.map +1 -1
  96. package/lib/cjs/tile/map/WmsUtilities.js +22 -0
  97. package/lib/cjs/tile/map/WmsUtilities.js.map +1 -1
  98. package/lib/cjs/tile/map/WmtsCapabilities.d.ts.map +1 -1
  99. package/lib/cjs/tile/map/WmtsCapabilities.js +2 -16
  100. package/lib/cjs/tile/map/WmtsCapabilities.js.map +1 -1
  101. package/lib/cjs/tools/SelectTool.d.ts +1 -0
  102. package/lib/cjs/tools/SelectTool.d.ts.map +1 -1
  103. package/lib/cjs/tools/SelectTool.js +19 -13
  104. package/lib/cjs/tools/SelectTool.js.map +1 -1
  105. package/lib/esm/DisplayStyleState.d.ts +3 -0
  106. package/lib/esm/DisplayStyleState.d.ts.map +1 -1
  107. package/lib/esm/DisplayStyleState.js +10 -0
  108. package/lib/esm/DisplayStyleState.js.map +1 -1
  109. package/lib/esm/Viewport.d.ts +5 -0
  110. package/lib/esm/Viewport.d.ts.map +1 -1
  111. package/lib/esm/Viewport.js +6 -0
  112. package/lib/esm/Viewport.js.map +1 -1
  113. package/lib/esm/common/gltf/GltfSchema.d.ts +20 -3
  114. package/lib/esm/common/gltf/GltfSchema.d.ts.map +1 -1
  115. package/lib/esm/common/gltf/GltfSchema.js.map +1 -1
  116. package/lib/esm/common/imdl/ImdlModel.d.ts +15 -1
  117. package/lib/esm/common/imdl/ImdlModel.d.ts.map +1 -1
  118. package/lib/esm/common/imdl/ImdlModel.js +11 -3
  119. package/lib/esm/common/imdl/ImdlModel.js.map +1 -1
  120. package/lib/esm/common/imdl/ParseImdlDocument.d.ts +3 -1
  121. package/lib/esm/common/imdl/ParseImdlDocument.d.ts.map +1 -1
  122. package/lib/esm/common/imdl/ParseImdlDocument.js +67 -12
  123. package/lib/esm/common/imdl/ParseImdlDocument.js.map +1 -1
  124. package/lib/esm/render/GraphicBranch.d.ts +10 -0
  125. package/lib/esm/render/GraphicBranch.d.ts.map +1 -1
  126. package/lib/esm/render/GraphicBranch.js.map +1 -1
  127. package/lib/esm/render/webgl/BranchState.d.ts +2 -0
  128. package/lib/esm/render/webgl/BranchState.d.ts.map +1 -1
  129. package/lib/esm/render/webgl/BranchState.js +2 -0
  130. package/lib/esm/render/webgl/BranchState.js.map +1 -1
  131. package/lib/esm/render/webgl/Graphic.d.ts.map +1 -1
  132. package/lib/esm/render/webgl/Graphic.js +3 -0
  133. package/lib/esm/render/webgl/Graphic.js.map +1 -1
  134. package/lib/esm/render/webgl/InstancedGeometry.d.ts +1 -0
  135. package/lib/esm/render/webgl/InstancedGeometry.d.ts.map +1 -1
  136. package/lib/esm/render/webgl/InstancedGeometry.js +1 -0
  137. package/lib/esm/render/webgl/InstancedGeometry.js.map +1 -1
  138. package/lib/esm/render/webgl/RealityMesh.d.ts.map +1 -1
  139. package/lib/esm/render/webgl/RealityMesh.js +6 -0
  140. package/lib/esm/render/webgl/RealityMesh.js.map +1 -1
  141. package/lib/esm/request/utils.d.ts +18 -0
  142. package/lib/esm/request/utils.d.ts.map +1 -0
  143. package/lib/esm/request/utils.js +40 -0
  144. package/lib/esm/request/utils.js.map +1 -0
  145. package/lib/esm/tile/BatchedTileIdMap.d.ts +1 -2
  146. package/lib/esm/tile/BatchedTileIdMap.d.ts.map +1 -1
  147. package/lib/esm/tile/BatchedTileIdMap.js +3 -3
  148. package/lib/esm/tile/BatchedTileIdMap.js.map +1 -1
  149. package/lib/esm/tile/GltfReader.d.ts +4 -1
  150. package/lib/esm/tile/GltfReader.d.ts.map +1 -1
  151. package/lib/esm/tile/GltfReader.js +126 -27
  152. package/lib/esm/tile/GltfReader.js.map +1 -1
  153. package/lib/esm/tile/ImdlDecoder.d.ts +7 -1
  154. package/lib/esm/tile/ImdlDecoder.d.ts.map +1 -1
  155. package/lib/esm/tile/ImdlDecoder.js.map +1 -1
  156. package/lib/esm/tile/ImdlGraphicsCreator.d.ts.map +1 -1
  157. package/lib/esm/tile/ImdlGraphicsCreator.js +28 -17
  158. package/lib/esm/tile/ImdlGraphicsCreator.js.map +1 -1
  159. package/lib/esm/tile/ImdlReader.d.ts +2 -1
  160. package/lib/esm/tile/ImdlReader.d.ts.map +1 -1
  161. package/lib/esm/tile/ImdlReader.js +1 -0
  162. package/lib/esm/tile/ImdlReader.js.map +1 -1
  163. package/lib/esm/tile/RealityModelTileTree.d.ts.map +1 -1
  164. package/lib/esm/tile/RealityModelTileTree.js +2 -3
  165. package/lib/esm/tile/RealityModelTileTree.js.map +1 -1
  166. package/lib/esm/tile/RealityTileTree.d.ts +31 -0
  167. package/lib/esm/tile/RealityTileTree.d.ts.map +1 -1
  168. package/lib/esm/tile/RealityTileTree.js +6 -0
  169. package/lib/esm/tile/RealityTileTree.js.map +1 -1
  170. package/lib/esm/tile/TileDrawArgs.d.ts +6 -0
  171. package/lib/esm/tile/TileDrawArgs.d.ts.map +1 -1
  172. package/lib/esm/tile/TileDrawArgs.js +8 -1
  173. package/lib/esm/tile/TileDrawArgs.js.map +1 -1
  174. package/lib/esm/tile/TileTreeReference.d.ts +2 -0
  175. package/lib/esm/tile/TileTreeReference.d.ts.map +1 -1
  176. package/lib/esm/tile/TileTreeReference.js +5 -0
  177. package/lib/esm/tile/TileTreeReference.js.map +1 -1
  178. package/lib/esm/tile/map/ArcGISTileMap.d.ts +6 -2
  179. package/lib/esm/tile/map/ArcGISTileMap.d.ts.map +1 -1
  180. package/lib/esm/tile/map/ArcGISTileMap.js +130 -71
  181. package/lib/esm/tile/map/ArcGISTileMap.js.map +1 -1
  182. package/lib/esm/tile/map/ArcGisUtilities.d.ts.map +1 -1
  183. package/lib/esm/tile/map/ArcGisUtilities.js +5 -0
  184. package/lib/esm/tile/map/ArcGisUtilities.js.map +1 -1
  185. package/lib/esm/tile/map/ImageryProviders/ArcGISImageryProvider.d.ts.map +1 -1
  186. package/lib/esm/tile/map/ImageryProviders/ArcGISImageryProvider.js +61 -39
  187. package/lib/esm/tile/map/ImageryProviders/ArcGISImageryProvider.js.map +1 -1
  188. package/lib/esm/tile/map/ImageryProviders/ArcGISMapLayerImageryProvider.js +1 -1
  189. package/lib/esm/tile/map/ImageryProviders/ArcGISMapLayerImageryProvider.js.map +1 -1
  190. package/lib/esm/tile/map/MapLayerImageryProvider.d.ts +6 -0
  191. package/lib/esm/tile/map/MapLayerImageryProvider.d.ts.map +1 -1
  192. package/lib/esm/tile/map/MapLayerImageryProvider.js +48 -8
  193. package/lib/esm/tile/map/MapLayerImageryProvider.js.map +1 -1
  194. package/lib/esm/tile/map/WmsCapabilities.d.ts.map +1 -1
  195. package/lib/esm/tile/map/WmsCapabilities.js +1 -15
  196. package/lib/esm/tile/map/WmsCapabilities.js.map +1 -1
  197. package/lib/esm/tile/map/WmsUtilities.d.ts +7 -0
  198. package/lib/esm/tile/map/WmsUtilities.d.ts.map +1 -1
  199. package/lib/esm/tile/map/WmsUtilities.js +22 -0
  200. package/lib/esm/tile/map/WmsUtilities.js.map +1 -1
  201. package/lib/esm/tile/map/WmtsCapabilities.d.ts.map +1 -1
  202. package/lib/esm/tile/map/WmtsCapabilities.js +2 -16
  203. package/lib/esm/tile/map/WmtsCapabilities.js.map +1 -1
  204. package/lib/esm/tools/SelectTool.d.ts +1 -0
  205. package/lib/esm/tools/SelectTool.d.ts.map +1 -1
  206. package/lib/esm/tools/SelectTool.js +19 -13
  207. package/lib/esm/tools/SelectTool.js.map +1 -1
  208. package/lib/public/scripts/parse-imdl-worker.js +1 -1
  209. package/lib/workers/webpack/parse-imdl-worker.js +1 -1
  210. package/package.json +20 -19
@@ -10,19 +10,23 @@ Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.ArcGISTileMap = void 0;
11
11
  const core_bentley_1 = require("@itwin/core-bentley");
12
12
  const internal_1 = require("../internal");
13
+ const loggerCategory = "ArcGISTileMap";
13
14
  const nonVisibleChildren = [false, false, false, false];
14
15
  /** @internal */
15
16
  class ArcGISTileMap {
16
- constructor(restBaseUrl, settings, fetchFunc, nbLods) {
17
- this.tileMapRequestSize = 32;
17
+ // We want to query a tile map that covers an area all around the top-lef missing tile, we offset the top-left corner position of the tilemap.
18
+ // We used to create a 32x32 tiles area around the missing tiles, but this was causing the tilemap top-left position
19
+ // to fall outside the dataset bundle of the remote server, thus giving invalid response.
20
+ get tileMapOffset() { return (this.tileMapRequestSize * 0.5); }
21
+ constructor(restBaseUrl, settings, fetchFunc) {
22
+ // For similar reasons as the corner offset, we need to keep the tile map size not too big to avoid covering multiple bundles.
23
+ this.tileMapRequestSize = 8;
18
24
  this.fallbackTileMapRequestSize = 2;
19
25
  this._tilesCache = new core_bentley_1.Dictionary((lhs, rhs) => (0, core_bentley_1.compareStrings)(lhs, rhs));
20
26
  this._restBaseUrl = restBaseUrl;
21
27
  this._fetchFunc = fetchFunc;
22
28
  this._settings = settings;
23
- if (nbLods !== undefined && nbLods > 0) {
24
- this._callQueues = new Array(nbLods).fill(Promise.resolve(nonVisibleChildren));
25
- }
29
+ this._callQueues = new Array(ArcGISTileMap.maxLod).fill(Promise.resolve(nonVisibleChildren));
26
30
  }
27
31
  async fetchTileMapFromServer(level, row, column, width, height) {
28
32
  const tmpUrl = `${this._restBaseUrl}/tilemap/${level}/${row}/${column}/${width}/${height}?f=json`;
@@ -44,10 +48,12 @@ class ArcGISTileMap {
44
48
  async getChildrenAvailability(childIds) {
45
49
  if (!childIds.length)
46
50
  return [];
47
- // We need to check cache again:
48
- // Tiles we are looking for may have been added to cache while we were waiting in the call queue.
51
+ // Before entering the queue for a backend request,
52
+ // let check if cache doesn't already contain what we are looking for.
49
53
  const cacheInfo = this.getAvailableTilesFromCache(childIds);
50
54
  if (cacheInfo.allTilesFound) {
55
+ if (cacheInfo.available.includes(false))
56
+ return cacheInfo.available;
51
57
  return cacheInfo.available;
52
58
  }
53
59
  // If we never encountered this tile level before, then a tilemap request must be made to get tiles visibility.
@@ -56,48 +62,115 @@ class ArcGISTileMap {
56
62
  // before making another one.
57
63
  const childLevel = childIds[0].level + 1;
58
64
  if (this._callQueues && childLevel < this._callQueues.length) {
59
- const res = this._callQueues[childLevel].then(async () => this.getChildrenAvailabilityFromServer(childIds));
65
+ const res = this._callQueues[childLevel].then(async () => {
66
+ return this.getChildrenAvailabilityFromServer(childIds);
67
+ });
60
68
  this._callQueues[childLevel] = res.catch(() => nonVisibleChildren);
61
69
  return res;
62
70
  }
63
71
  else {
64
72
  // We should not be in this case, probably because server info is missing LODs in the capabilities?!
73
+ core_bentley_1.Logger.logWarning(loggerCategory, `Skipped request queue for child level ${childLevel}`);
65
74
  return this.getChildrenAvailabilityFromServer(childIds);
66
75
  }
67
76
  }
77
+ isCacheMissingTile(level, startRow, startColumn, endRow, endColumn) {
78
+ let missingTileFound = false;
79
+ if (endRow <= startRow || endColumn <= startColumn)
80
+ return missingTileFound;
81
+ for (let j = startColumn; j <= endColumn && !missingTileFound; j++) {
82
+ for (let i = startRow; i <= endRow && !missingTileFound; i++) {
83
+ if (j >= 0 && i >= 0) {
84
+ const contentId = internal_1.QuadId.getTileContentId(level, j, i);
85
+ if (this._tilesCache.get(contentId) === undefined) {
86
+ missingTileFound = true;
87
+ }
88
+ }
89
+ }
90
+ }
91
+ return missingTileFound;
92
+ }
93
+ collectTilesMissingFromCache(missingQueryTiles) {
94
+ const missingTiles = [];
95
+ for (const quad of missingQueryTiles) {
96
+ const contentId = internal_1.QuadId.getTileContentId(quad.level, quad.column, quad.row);
97
+ const avail = this._tilesCache.get(contentId);
98
+ if (avail === undefined)
99
+ missingTiles.push(quad);
100
+ }
101
+ return missingTiles;
102
+ }
68
103
  // Query tiles are tiles that we need to check availability
69
104
  // The array is assumed to be in in row major orientation, i.e.: [TileRow0Col0, TileRow0Col1, TileRow1Col0, TileRow1Col1,]
70
105
  async fetchAndReadTilemap(queryTiles, reqWidth, reqHeight) {
71
- let available = [];
106
+ let available = queryTiles.map(() => false);
72
107
  if (queryTiles.length === 0) {
73
108
  return available;
74
109
  }
75
- const row = queryTiles[0].row;
76
- const column = queryTiles[0].column;
77
- const level = queryTiles[0].level;
78
- let reqRow, reqColumn;
79
- if (reqWidth === this.fallbackTileMapRequestSize && reqHeight === this.fallbackTileMapRequestSize) {
80
- reqRow = row;
81
- reqColumn = column;
82
- }
83
- else {
84
- // If tile map if big enough. create offset that will place the current tile in the middle of the tilemap.
85
- // If we place the first query tile in the top-left corner (i.e. without offset), any query for a tile located above or on the left
86
- // will trigger a new request.
87
- const offsetRow = (reqHeight / 2.0) - 1;
88
- const offsetColumn = (reqWidth / 2.0) - 1;
89
- reqRow = Math.max(row - offsetRow, 0);
90
- reqColumn = Math.max(column - offsetColumn, 0);
91
- }
92
- try {
93
- // console.log(`Tilemap request: ${level},${reqRow},${reqColumn},${reqWidth},${reqHeight}`);
94
- const json = await this.fetchTileMapFromServer(level, reqRow, reqColumn, reqWidth, reqHeight);
110
+ // console.log(`queryTiles: ${queryTiles.map((quad) => quad.contentId)}`);
111
+ // Find the top-left most corner of the extent covering the query tiles.
112
+ const getTopLeftCorner = (tiles) => {
113
+ let row;
114
+ let column;
115
+ for (const quad of tiles) {
116
+ if (row === undefined || quad.row <= row)
117
+ row = quad.row;
118
+ if (column === undefined || quad.column <= column) {
119
+ column = quad.column;
120
+ }
121
+ }
122
+ return { row, column };
123
+ };
124
+ const level = queryTiles[0].level; // We assume all tiles to be on the same level
125
+ let missingQueryTiles = this.collectTilesMissingFromCache(queryTiles);
126
+ let gotAdjusted = false;
127
+ let nbAttempt = 0; // Safety: We should never be making more requests than the number of queries tiles (otherwise something is wrong)
128
+ while (missingQueryTiles.length > 0
129
+ && (nbAttempt++ < queryTiles.length)) {
130
+ const tileMapTopLeft = getTopLeftCorner(missingQueryTiles);
131
+ if (tileMapTopLeft.row === undefined || tileMapTopLeft.column === undefined)
132
+ return available; // Should not occurs since missingQueryTiles is non empty
133
+ let tileMapRow = tileMapTopLeft.row;
134
+ let tileMapColumn = tileMapTopLeft.column;
135
+ const logLocationOffset = (newRow, newCol) => `[Row:${newRow !== tileMapTopLeft.row ? `${tileMapTopLeft.row}->${newRow}` : `${newRow}`} Column:${newCol !== tileMapTopLeft.column ? `${tileMapTopLeft.column}->${newCol}` : `${newCol}`}]`;
136
+ // Position the top-left missing tile in the middle of the tilemap; minimizing requests if sibling tiles are requested right after
137
+ // If previous response got adjusted, don't try to optimize tile map location
138
+ if (queryTiles.length < this.tileMapRequestSize && !gotAdjusted) {
139
+ const tileMapOffset = this.tileMapOffset - Math.floor(Math.sqrt(queryTiles.length) * 0.5);
140
+ const missingTileBufferSize = Math.ceil(tileMapOffset * 0.5);
141
+ if (this.isCacheMissingTile(level, tileMapRow - missingTileBufferSize, tileMapColumn - missingTileBufferSize, tileMapRow - 1, tileMapColumn - 1)) {
142
+ tileMapRow = Math.max(tileMapRow - tileMapOffset, 0);
143
+ tileMapColumn = Math.max(tileMapColumn - tileMapOffset, 0);
144
+ core_bentley_1.Logger.logTrace(loggerCategory, `Offset applied to location in top-left direction: ${logLocationOffset(tileMapRow, tileMapColumn)}`);
145
+ }
146
+ else {
147
+ const leftMissingTiles = this.isCacheMissingTile(level, tileMapRow, tileMapColumn - missingTileBufferSize, tileMapRow + missingTileBufferSize, tileMapColumn - 1);
148
+ const topMissingTiles = this.isCacheMissingTile(level, tileMapRow - missingTileBufferSize, tileMapColumn, tileMapRow - 1, tileMapColumn + missingTileBufferSize);
149
+ if (leftMissingTiles && topMissingTiles) {
150
+ tileMapRow = Math.max(tileMapRow - tileMapOffset, 0);
151
+ tileMapColumn = Math.max(tileMapColumn - tileMapOffset, 0);
152
+ core_bentley_1.Logger.logTrace(loggerCategory, `Offset applied to location in top-left direction. ${logLocationOffset(tileMapRow, tileMapColumn)}`);
153
+ }
154
+ else if (leftMissingTiles) {
155
+ tileMapColumn = Math.max(tileMapColumn - tileMapOffset, 0);
156
+ core_bentley_1.Logger.logTrace(loggerCategory, `Offset applied to location in left direction. ${logLocationOffset(tileMapRow, tileMapColumn)}`);
157
+ }
158
+ else if (topMissingTiles) {
159
+ tileMapRow = Math.max(tileMapRow - tileMapOffset, 0);
160
+ core_bentley_1.Logger.logTrace(loggerCategory, `Offset applied to location in top direction: ${logLocationOffset(tileMapRow, tileMapColumn)}`);
161
+ }
162
+ else
163
+ core_bentley_1.Logger.logTrace(loggerCategory, `No offset applied to location: ${logLocationOffset(tileMapRow, tileMapColumn)}`);
164
+ }
165
+ }
166
+ const json = await this.fetchTileMapFromServer(level, tileMapRow, tileMapColumn, reqWidth, reqHeight);
95
167
  let tileMapWidth = reqWidth;
96
168
  let tileMapHeight = reqHeight;
97
169
  if (Array.isArray(json.data)) {
98
170
  // The response width and height might be different than the requested dimensions.
99
171
  // Ref: https://developers.arcgis.com/rest/services-reference/enterprise/tile-map.htm
100
172
  if (json.adjusted) {
173
+ gotAdjusted = true;
101
174
  // If tilemap size got adjusted, I'm expecting to get adjusted size...
102
175
  // otherwise there is something really odd with this server.
103
176
  (0, core_bentley_1.assert)(json.location?.width !== undefined && json.location?.height !== undefined);
@@ -106,70 +179,55 @@ class ArcGISTileMap {
106
179
  tileMapHeight = json.location?.height;
107
180
  }
108
181
  }
109
- let k = 0;
110
- for (let j = 0; j < tileMapWidth; j++) {
111
- for (let i = 0; i < tileMapHeight; i++) {
182
+ // Build cache from tile map response
183
+ for (let j = 0; j < tileMapHeight; j++) {
184
+ for (let i = 0; i < tileMapWidth; i++) {
112
185
  const avail = json.data[(j * tileMapWidth) + i] !== 0;
113
- const curColumn = reqColumn + i;
114
- const curRow = reqRow + j;
115
- // console.log(`Tilemap tile:: ${level},${curRow},${curColumn} => ${avail}`);
186
+ const curColumn = tileMapColumn + i;
187
+ const curRow = tileMapRow + j;
116
188
  this._tilesCache.set(internal_1.QuadId.getTileContentId(level, curColumn, curRow), avail);
117
- // Check if actual tile is among the children we are looking for, if so update the availability array.
118
- if (curColumn >= queryTiles[0].column && curColumn <= queryTiles[queryTiles.length - 1].column
119
- && curRow >= queryTiles[0].row && curRow <= queryTiles[queryTiles.length - 1].row) {
120
- available[k++] = avail;
121
- }
122
189
  }
123
190
  }
191
+ // Collect tile missing from the cache
192
+ // There are 2 reasons why the tile map response would not cover all the missing tiles:
193
+ // 1. The requested tile map size is not large enough to cover all tiles
194
+ // 2. The tile map size has been adjusted by the server (i.e. data bundle limits)
195
+ missingQueryTiles = this.collectTilesMissingFromCache(missingQueryTiles);
196
+ if (missingQueryTiles.length > 0)
197
+ core_bentley_1.Logger.logTrace(loggerCategory, `There are ${missingQueryTiles.length} missing tiles from previous request`);
124
198
  }
125
199
  else {
126
- // If server returns data (i.e. error 422), thats fine we assume all tiles of tilemap are not available.
127
- available = queryTiles.map(() => false);
128
- // Mark all tilemap tiles to non-available in the cache too
200
+ missingQueryTiles = [];
201
+ // Mark all tilemap tiles to non-available in the cache too.
129
202
  for (let j = 0; j < tileMapWidth; j++) {
130
203
  for (let i = 0; i < tileMapHeight; i++) {
131
- this._tilesCache.set(internal_1.QuadId.getTileContentId(level, reqColumn + i, reqRow + j), false);
204
+ this._tilesCache.set(internal_1.QuadId.getTileContentId(level, tileMapColumn + i, tileMapRow + j), false);
132
205
  }
133
206
  }
134
207
  }
208
+ } // end loop missing tiles
209
+ if (nbAttempt > queryTiles.length) {
210
+ core_bentley_1.Logger.logError(loggerCategory, `Request loop was terminated; unable to get missing tiles; `);
135
211
  }
136
- catch (_error) {
137
- available = queryTiles.map(() => false);
138
- }
212
+ // Create final output array from cache
213
+ available = queryTiles.map((quad) => this._tilesCache.get(quad.contentId) ?? false);
214
+ if (available.includes(false))
215
+ return available;
139
216
  return available;
140
217
  }
141
218
  async getChildrenAvailabilityFromServer(childIds) {
142
- // We need to check cache again:
143
- // Tiles we are looking for may have been added to cache while we were waiting in the call queue.
144
- const cacheInfo = this.getAvailableTilesFromCache(childIds);
145
- if (cacheInfo.allTilesFound) {
146
- return cacheInfo.available;
147
- }
148
219
  let available;
149
220
  try {
150
221
  available = await this.fetchAndReadTilemap(childIds, this.tileMapRequestSize, this.tileMapRequestSize);
151
- if (available.length !== childIds.length) {
152
- if (this.tileMapRequestSize > this.fallbackTileMapRequestSize) {
153
- // Maybe we were unlucky and the tilemap got adjusted our the tiles we are looking for got clipped,
154
- // so let try we a smaller tilemap
155
- available = await this.fetchAndReadTilemap(childIds, this.fallbackTileMapRequestSize, this.fallbackTileMapRequestSize);
156
- }
157
- if (available.length < childIds.length) {
158
- // Could not all tiles children tiles, returns what we got and fill any gaps with false.
159
- const tmpAvail = childIds.map(() => false);
160
- for (let i = 0; i < available.length; i++) {
161
- tmpAvail[i] = available[i];
162
- }
163
- available = tmpAvail;
164
- }
165
- }
166
222
  }
167
- catch (_error) {
223
+ catch (err) {
168
224
  // if any error occurs, we assume tiles not to be visible
225
+ core_bentley_1.Logger.logError(loggerCategory, `Error while fetching tile map data : ${err}`);
169
226
  available = childIds.map(() => false);
170
227
  }
171
228
  return available;
172
229
  }
173
230
  }
231
+ ArcGISTileMap.maxLod = 30;
174
232
  exports.ArcGISTileMap = ArcGISTileMap;
175
233
  //# sourceMappingURL=ArcGISTileMap.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ArcGISTileMap.js","sourceRoot":"","sources":["../../../../src/tile/map/ArcGISTileMap.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Tiles\r\n */\r\n\r\nimport { assert, compareStrings, Dictionary } from \"@itwin/core-bentley\";\r\nimport { QuadId } from \"../internal\";\r\nimport { ImageMapLayerSettings } from \"@itwin/core-common\";\r\n\r\n/** @internal */\r\nexport type FetchFunction = (url: URL, options?: RequestInit) => Promise<Response>;\r\n\r\nconst nonVisibleChildren = [false, false, false, false];\r\n\r\n/** @internal */\r\nexport class ArcGISTileMap {\r\n public tileMapRequestSize = 32;\r\n public fallbackTileMapRequestSize = 2;\r\n\r\n private _callQueues: Array<Promise<boolean[]>> | undefined;\r\n private _tilesCache = new Dictionary<string, boolean>((lhs, rhs) => compareStrings(lhs, rhs));\r\n private _restBaseUrl: string;\r\n private _fetchFunc: FetchFunction;\r\n private _settings: ImageMapLayerSettings;\r\n\r\n constructor(restBaseUrl: string, settings: ImageMapLayerSettings, fetchFunc: FetchFunction, nbLods?: number ){\r\n this._restBaseUrl = restBaseUrl;\r\n this._fetchFunc = fetchFunc;\r\n this._settings = settings;\r\n if (nbLods !== undefined && nbLods > 0) {\r\n this._callQueues = new Array<Promise<boolean[]>>(nbLods).fill(Promise.resolve<boolean[]>(nonVisibleChildren));\r\n }\r\n\r\n }\r\n protected async fetchTileMapFromServer(level: number, row: number, column: number, width: number, height: number): Promise<any> {\r\n const tmpUrl = `${this._restBaseUrl}/tilemap/${level}/${row}/${column}/${width}/${height}?f=json`;\r\n const response = await this._fetchFunc(new URL(tmpUrl));\r\n return response.json();\r\n }\r\n\r\n protected getAvailableTilesFromCache(tiles: QuadId[]): {allTilesFound: boolean, available: boolean[]} {\r\n let allTilesFound = true;\r\n\r\n // Check children visibility from cache\r\n const available = tiles.map((tileId) => {\r\n const avail = this._tilesCache.get(tileId.contentId);\r\n if (undefined === avail) {\r\n allTilesFound = false;\r\n }\r\n return avail ?? false;\r\n });\r\n\r\n return {allTilesFound, available};\r\n }\r\n\r\n public async getChildrenAvailability(childIds: QuadId[]): Promise<boolean[]> {\r\n if (!childIds.length)\r\n return [];\r\n\r\n // We need to check cache again:\r\n // Tiles we are looking for may have been added to cache while we were waiting in the call queue.\r\n const cacheInfo = this.getAvailableTilesFromCache(childIds);\r\n if (cacheInfo.allTilesFound) {\r\n return cacheInfo.available;\r\n }\r\n\r\n // If we never encountered this tile level before, then a tilemap request must be made to get tiles visibility.\r\n // However, we dont want several overlapping large tilemap request being made simultaneously for tiles on the same level.\r\n // To avoid this from happening, we 'serialize' async calls so that we wait until the first tilemap request has completed\r\n // before making another one.\r\n const childLevel = childIds[0].level+1;\r\n if (this._callQueues && childLevel < this._callQueues.length ) {\r\n const res = this._callQueues[childLevel].then(async () => this.getChildrenAvailabilityFromServer(childIds));\r\n this._callQueues[childLevel] = res.catch(() => nonVisibleChildren);\r\n return res;\r\n } else {\r\n // We should not be in this case, probably because server info is missing LODs in the capabilities?!\r\n return this.getChildrenAvailabilityFromServer(childIds);\r\n }\r\n }\r\n\r\n // Query tiles are tiles that we need to check availability\r\n // The array is assumed to be in in row major orientation, i.e.: [TileRow0Col0, TileRow0Col1, TileRow1Col0, TileRow1Col1,]\r\n protected async fetchAndReadTilemap(queryTiles: QuadId[], reqWidth: number, reqHeight: number) {\r\n let available: boolean[] = [];\r\n if (queryTiles.length === 0) {\r\n return available;\r\n }\r\n\r\n const row = queryTiles[0].row;\r\n const column = queryTiles[0].column;\r\n const level = queryTiles[0].level;\r\n\r\n let reqRow, reqColumn;\r\n if (reqWidth === this.fallbackTileMapRequestSize && reqHeight === this.fallbackTileMapRequestSize){\r\n reqRow = row;\r\n reqColumn = column;\r\n } else {\r\n // If tile map if big enough. create offset that will place the current tile in the middle of the tilemap.\r\n // If we place the first query tile in the top-left corner (i.e. without offset), any query for a tile located above or on the left\r\n // will trigger a new request.\r\n const offsetRow = (reqHeight/2.0)-1;\r\n const offsetColumn = (reqWidth/2.0)-1;\r\n reqRow = Math.max(row - offsetRow, 0);\r\n reqColumn = Math.max(column - offsetColumn, 0);\r\n }\r\n\r\n try {\r\n // console.log(`Tilemap request: ${level},${reqRow},${reqColumn},${reqWidth},${reqHeight}`);\r\n const json = await this.fetchTileMapFromServer(level, reqRow, reqColumn, reqWidth, reqHeight);\r\n let tileMapWidth = reqWidth;\r\n let tileMapHeight = reqHeight;\r\n if (Array.isArray(json.data)){\r\n\r\n // The response width and height might be different than the requested dimensions.\r\n // Ref: https://developers.arcgis.com/rest/services-reference/enterprise/tile-map.htm\r\n if (json.adjusted) {\r\n // If tilemap size got adjusted, I'm expecting to get adjusted size...\r\n // otherwise there is something really odd with this server.\r\n assert(json.location?.width !== undefined && json.location?.height !== undefined);\r\n if (json.location?.width !== undefined && json.location?.height !== undefined) {\r\n tileMapWidth = json.location?.width;\r\n tileMapHeight = json.location?.height;\r\n }\r\n }\r\n let k = 0;\r\n for (let j = 0; j < tileMapWidth; j++) {\r\n for (let i = 0; i < tileMapHeight; i++) {\r\n const avail = json.data[(j*tileMapWidth)+i] !== 0;\r\n const curColumn = reqColumn + i;\r\n const curRow = reqRow + j;\r\n // console.log(`Tilemap tile:: ${level},${curRow},${curColumn} => ${avail}`);\r\n this._tilesCache.set(QuadId.getTileContentId(level, curColumn, curRow), avail);\r\n\r\n // Check if actual tile is among the children we are looking for, if so update the availability array.\r\n if ( curColumn >= queryTiles[0].column && curColumn <= queryTiles[queryTiles.length-1].column\r\n && curRow >= queryTiles[0].row && curRow <= queryTiles[queryTiles.length-1].row ) {\r\n available[k++] = avail;\r\n }\r\n\r\n }\r\n }\r\n } else {\r\n // If server returns data (i.e. error 422), thats fine we assume all tiles of tilemap are not available.\r\n available = queryTiles.map(()=>false);\r\n\r\n // Mark all tilemap tiles to non-available in the cache too\r\n for (let j = 0; j < tileMapWidth; j++) {\r\n for (let i = 0; i < tileMapHeight; i++) {\r\n this._tilesCache.set(QuadId.getTileContentId(level, reqColumn + i, reqRow + j), false);\r\n }\r\n }\r\n }\r\n } catch (_error) {\r\n available = queryTiles.map(()=>false);\r\n }\r\n\r\n return available;\r\n }\r\n\r\n protected async getChildrenAvailabilityFromServer(childIds: QuadId[]): Promise<boolean[]> {\r\n // We need to check cache again:\r\n // Tiles we are looking for may have been added to cache while we were waiting in the call queue.\r\n const cacheInfo = this.getAvailableTilesFromCache(childIds);\r\n if (cacheInfo.allTilesFound) {\r\n return cacheInfo.available;\r\n }\r\n\r\n let available;\r\n try {\r\n available = await this.fetchAndReadTilemap(childIds, this.tileMapRequestSize, this.tileMapRequestSize);\r\n if (available.length !== childIds.length) {\r\n if (this.tileMapRequestSize > this.fallbackTileMapRequestSize) {\r\n // Maybe we were unlucky and the tilemap got adjusted our the tiles we are looking for got clipped,\r\n // so let try we a smaller tilemap\r\n available = await this.fetchAndReadTilemap(childIds, this.fallbackTileMapRequestSize, this.fallbackTileMapRequestSize);\r\n }\r\n\r\n if (available.length < childIds.length) {\r\n // Could not all tiles children tiles, returns what we got and fill any gaps with false.\r\n const tmpAvail = childIds.map(()=>false);\r\n for (let i=0; i<available.length;i++ ) {\r\n tmpAvail[i] = available[i];\r\n }\r\n available = tmpAvail;\r\n }\r\n }\r\n } catch (_error) {\r\n // if any error occurs, we assume tiles not to be visible\r\n available = childIds.map(()=>false);\r\n }\r\n\r\n return available;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"ArcGISTileMap.js","sourceRoot":"","sources":["../../../../src/tile/map/ArcGISTileMap.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n/** @packageDocumentation\r\n * @module Tiles\r\n */\r\n\r\nimport { assert, compareStrings, Dictionary, Logger } from \"@itwin/core-bentley\";\r\nimport { QuadId } from \"../internal\";\r\nimport { ImageMapLayerSettings } from \"@itwin/core-common\";\r\nconst loggerCategory = \"ArcGISTileMap\";\r\n\r\n/** @internal */\r\nexport type FetchFunction = (url: URL, options?: RequestInit) => Promise<Response>;\r\n\r\nconst nonVisibleChildren = [false, false, false, false];\r\n\r\n/** @internal */\r\nexport class ArcGISTileMap {\r\n\r\n // For similar reasons as the corner offset, we need to keep the tile map size not too big to avoid covering multiple bundles.\r\n public tileMapRequestSize = 8;\r\n private static maxLod = 30;\r\n\r\n // We want to query a tile map that covers an area all around the top-lef missing tile, we offset the top-left corner position of the tilemap.\r\n // We used to create a 32x32 tiles area around the missing tiles, but this was causing the tilemap top-left position\r\n // to fall outside the dataset bundle of the remote server, thus giving invalid response.\r\n public get tileMapOffset() {return (this.tileMapRequestSize * 0.5);}\r\n\r\n public fallbackTileMapRequestSize = 2;\r\n\r\n private _callQueues: Array<Promise<boolean[]>> | undefined;\r\n private _tilesCache = new Dictionary<string, boolean>((lhs, rhs) => compareStrings(lhs, rhs));\r\n private _restBaseUrl: string;\r\n private _fetchFunc: FetchFunction;\r\n private _settings: ImageMapLayerSettings;\r\n\r\n constructor(restBaseUrl: string, settings: ImageMapLayerSettings, fetchFunc: FetchFunction ){\r\n this._restBaseUrl = restBaseUrl;\r\n this._fetchFunc = fetchFunc;\r\n this._settings = settings;\r\n this._callQueues = new Array<Promise<boolean[]>>(ArcGISTileMap.maxLod).fill(Promise.resolve<boolean[]>(nonVisibleChildren));\r\n\r\n }\r\n protected async fetchTileMapFromServer(level: number, row: number, column: number, width: number, height: number): Promise<any> {\r\n const tmpUrl = `${this._restBaseUrl}/tilemap/${level}/${row}/${column}/${width}/${height}?f=json`;\r\n const response = await this._fetchFunc(new URL(tmpUrl));\r\n return response.json();\r\n }\r\n\r\n protected getAvailableTilesFromCache(tiles: QuadId[]): {allTilesFound: boolean, available: boolean[]} {\r\n let allTilesFound = true;\r\n\r\n // Check children visibility from cache\r\n const available = tiles.map((tileId) => {\r\n const avail = this._tilesCache.get(tileId.contentId);\r\n if (undefined === avail) {\r\n allTilesFound = false;\r\n }\r\n return avail ?? false;\r\n });\r\n\r\n return {allTilesFound, available};\r\n }\r\n\r\n public async getChildrenAvailability(childIds: QuadId[]): Promise<boolean[]> {\r\n if (!childIds.length)\r\n return [];\r\n\r\n // Before entering the queue for a backend request,\r\n // let check if cache doesn't already contain what we are looking for.\r\n const cacheInfo = this.getAvailableTilesFromCache(childIds);\r\n if (cacheInfo.allTilesFound) {\r\n\r\n if (cacheInfo.available.includes(false))\r\n return cacheInfo.available;\r\n\r\n return cacheInfo.available;\r\n }\r\n\r\n // If we never encountered this tile level before, then a tilemap request must be made to get tiles visibility.\r\n // However, we dont want several overlapping large tilemap request being made simultaneously for tiles on the same level.\r\n // To avoid this from happening, we 'serialize' async calls so that we wait until the first tilemap request has completed\r\n // before making another one.\r\n const childLevel = childIds[0].level+1;\r\n if (this._callQueues && childLevel < this._callQueues.length ) {\r\n const res = this._callQueues[childLevel].then(async () => {\r\n return this.getChildrenAvailabilityFromServer(childIds);\r\n });\r\n this._callQueues[childLevel] = res.catch(() => nonVisibleChildren);\r\n return res;\r\n } else {\r\n // We should not be in this case, probably because server info is missing LODs in the capabilities?!\r\n Logger.logWarning(loggerCategory, `Skipped request queue for child level ${childLevel}`);\r\n return this.getChildrenAvailabilityFromServer(childIds);\r\n }\r\n }\r\n\r\n private isCacheMissingTile(level: number, startRow: number, startColumn: number, endRow: number, endColumn: number) {\r\n let missingTileFound = false;\r\n\r\n if (endRow <= startRow || endColumn <= startColumn)\r\n return missingTileFound;\r\n\r\n for (let j = startColumn; j <= endColumn && !missingTileFound; j++) {\r\n for (let i = startRow; i<=endRow && !missingTileFound; i++) {\r\n if (j >= 0 && i >= 0) {\r\n const contentId = QuadId.getTileContentId(level, j, i);\r\n if (this._tilesCache.get(contentId) === undefined) {\r\n missingTileFound = true;\r\n }\r\n }\r\n }\r\n }\r\n return missingTileFound;\r\n }\r\n\r\n private collectTilesMissingFromCache( missingQueryTiles: QuadId[]) {\r\n const missingTiles: QuadId[] = [];\r\n for (const quad of missingQueryTiles) {\r\n const contentId = QuadId.getTileContentId(quad.level, quad.column, quad.row);\r\n const avail = this._tilesCache.get(contentId);\r\n if (avail === undefined)\r\n missingTiles.push(quad);\r\n\r\n }\r\n return missingTiles;\r\n }\r\n\r\n // Query tiles are tiles that we need to check availability\r\n // The array is assumed to be in in row major orientation, i.e.: [TileRow0Col0, TileRow0Col1, TileRow1Col0, TileRow1Col1,]\r\n public async fetchAndReadTilemap(queryTiles: QuadId[], reqWidth: number, reqHeight: number) {\r\n let available = queryTiles.map(()=>false);\r\n if (queryTiles.length === 0 ) {\r\n return available;\r\n }\r\n\r\n // console.log(`queryTiles: ${queryTiles.map((quad) => quad.contentId)}`);\r\n\r\n // Find the top-left most corner of the extent covering the query tiles.\r\n const getTopLeftCorner = (tiles: QuadId[]): {row: number|undefined, column: number|undefined} => {\r\n let row: number|undefined;\r\n let column: number|undefined;\r\n for (const quad of tiles) {\r\n if (row === undefined || quad.row <= row )\r\n row = quad.row;\r\n if (column === undefined || quad.column <= column) {\r\n column = quad.column ;\r\n }\r\n }\r\n return {row, column};\r\n };\r\n\r\n const level = queryTiles[0].level; // We assume all tiles to be on the same level\r\n\r\n let missingQueryTiles = this.collectTilesMissingFromCache(queryTiles);\r\n let gotAdjusted = false;\r\n let nbAttempt = 0; // Safety: We should never be making more requests than the number of queries tiles (otherwise something is wrong)\r\n while (missingQueryTiles.length > 0\r\n && (nbAttempt++ < queryTiles.length) ) {\r\n const tileMapTopLeft = getTopLeftCorner(missingQueryTiles);\r\n if (tileMapTopLeft.row === undefined || tileMapTopLeft.column === undefined)\r\n return available; // Should not occurs since missingQueryTiles is non empty\r\n\r\n let tileMapRow = tileMapTopLeft.row;\r\n let tileMapColumn = tileMapTopLeft.column;\r\n\r\n const logLocationOffset = (newRow: number, newCol: number) => `[Row:${newRow !== tileMapTopLeft.row ? `${tileMapTopLeft.row}->${newRow}` : `${newRow}`} Column:${newCol !== tileMapTopLeft.column ? `${tileMapTopLeft.column}->${newCol}` : `${newCol}`}]`;\r\n\r\n // Position the top-left missing tile in the middle of the tilemap; minimizing requests if sibling tiles are requested right after\r\n // If previous response got adjusted, don't try to optimize tile map location\r\n if (queryTiles.length < this.tileMapRequestSize && !gotAdjusted) {\r\n const tileMapOffset = this.tileMapOffset - Math.floor(Math.sqrt(queryTiles.length) * 0.5);\r\n const missingTileBufferSize = Math.ceil(tileMapOffset * 0.5);\r\n if (this.isCacheMissingTile(level, tileMapRow-missingTileBufferSize, tileMapColumn-missingTileBufferSize, tileMapRow-1, tileMapColumn-1)) {\r\n tileMapRow = Math.max(tileMapRow - tileMapOffset, 0);\r\n tileMapColumn = Math.max(tileMapColumn - tileMapOffset, 0);\r\n Logger.logTrace(loggerCategory, `Offset applied to location in top-left direction: ${logLocationOffset(tileMapRow, tileMapColumn)}`);\r\n } else {\r\n const leftMissingTiles = this.isCacheMissingTile(level, tileMapRow, tileMapColumn-missingTileBufferSize, tileMapRow+missingTileBufferSize, tileMapColumn-1);\r\n const topMissingTiles = this.isCacheMissingTile(level, tileMapRow-missingTileBufferSize, tileMapColumn, tileMapRow-1, tileMapColumn+missingTileBufferSize);\r\n if (leftMissingTiles && topMissingTiles) {\r\n tileMapRow = Math.max(tileMapRow - tileMapOffset, 0);\r\n tileMapColumn = Math.max(tileMapColumn- tileMapOffset, 0);\r\n Logger.logTrace(loggerCategory, `Offset applied to location in top-left direction. ${logLocationOffset(tileMapRow, tileMapColumn)}`);\r\n } else if (leftMissingTiles) {\r\n tileMapColumn = Math.max(tileMapColumn - tileMapOffset, 0);\r\n Logger.logTrace(loggerCategory, `Offset applied to location in left direction. ${logLocationOffset(tileMapRow, tileMapColumn)}`);\r\n } else if (topMissingTiles) {\r\n tileMapRow = Math.max(tileMapRow - tileMapOffset, 0);\r\n Logger.logTrace(loggerCategory, `Offset applied to location in top direction: ${logLocationOffset(tileMapRow, tileMapColumn)}`);\r\n } else\r\n Logger.logTrace(loggerCategory, `No offset applied to location: ${logLocationOffset(tileMapRow, tileMapColumn)}`);\r\n }\r\n }\r\n\r\n const json = await this.fetchTileMapFromServer(level, tileMapRow, tileMapColumn, reqWidth, reqHeight);\r\n let tileMapWidth = reqWidth;\r\n let tileMapHeight = reqHeight;\r\n if (Array.isArray(json.data)) {\r\n // The response width and height might be different than the requested dimensions.\r\n // Ref: https://developers.arcgis.com/rest/services-reference/enterprise/tile-map.htm\r\n if (json.adjusted) {\r\n gotAdjusted = true;\r\n // If tilemap size got adjusted, I'm expecting to get adjusted size...\r\n // otherwise there is something really odd with this server.\r\n assert(json.location?.width !== undefined && json.location?.height !== undefined);\r\n if (json.location?.width !== undefined && json.location?.height !== undefined) {\r\n tileMapWidth = json.location?.width;\r\n tileMapHeight = json.location?.height;\r\n }\r\n }\r\n // Build cache from tile map response\r\n for (let j = 0; j < tileMapHeight; j++) {\r\n for (let i = 0; i < tileMapWidth; i++) {\r\n const avail = json.data[(j*tileMapWidth)+i] !== 0;\r\n const curColumn = tileMapColumn + i;\r\n const curRow = tileMapRow + j;\r\n this._tilesCache.set(QuadId.getTileContentId(level, curColumn, curRow), avail);\r\n }\r\n }\r\n\r\n // Collect tile missing from the cache\r\n // There are 2 reasons why the tile map response would not cover all the missing tiles:\r\n // 1. The requested tile map size is not large enough to cover all tiles\r\n // 2. The tile map size has been adjusted by the server (i.e. data bundle limits)\r\n missingQueryTiles = this.collectTilesMissingFromCache(missingQueryTiles);\r\n if (missingQueryTiles.length > 0)\r\n Logger.logTrace(loggerCategory, `There are ${missingQueryTiles.length} missing tiles from previous request`);\r\n } else {\r\n missingQueryTiles = [];\r\n // Mark all tilemap tiles to non-available in the cache too.\r\n for (let j = 0; j < tileMapWidth; j++) {\r\n for (let i = 0; i < tileMapHeight; i++) {\r\n this._tilesCache.set(QuadId.getTileContentId(level, tileMapColumn + i, tileMapRow + j), false);\r\n }\r\n }\r\n }\r\n } // end loop missing tiles\r\n\r\n if (nbAttempt > queryTiles.length) {\r\n Logger.logError(loggerCategory, `Request loop was terminated; unable to get missing tiles; `);\r\n }\r\n // Create final output array from cache\r\n available = queryTiles.map((quad)=>this._tilesCache.get(quad.contentId) ?? false);\r\n\r\n if (available.includes(false))\r\n return available;\r\n\r\n return available;\r\n }\r\n\r\n protected async getChildrenAvailabilityFromServer(childIds: QuadId[]): Promise<boolean[]> {\r\n\r\n let available;\r\n try {\r\n available = await this.fetchAndReadTilemap(childIds, this.tileMapRequestSize, this.tileMapRequestSize);\r\n } catch (err) {\r\n // if any error occurs, we assume tiles not to be visible\r\n Logger.logError(loggerCategory, `Error while fetching tile map data : ${err}`);\r\n available = childIds.map(()=>false);\r\n }\r\n\r\n return available;\r\n }\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ArcGisUtilities.d.ts","sourceRoot":"","sources":["../../../../src/tile/map/ArcGisUtilities.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,cAAc,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,kBAAkB,EAAC,MAAM,aAAa,CAAC;AAGzM;;GAEG;AAEH;;;GAGG;AACH,oBAAY,eAAe;IACzB,kBAAkB,MAAM;IACxB,YAAY,MAAM;IAClB,aAAa,MAAM;IACnB,YAAY,OAAO;IACnB,cAAc,OAAO;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,oCAAoC;IACpC,OAAO,EAAE,GAAG,CAAC;IAEb,qEAAqE;IACrE,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,wBAAyB,SAAQ,kBAAkB;IAClE,kJAAkJ;IAClJ,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAC,CAAC;IACtC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,qBAAa,eAAe;IAE1B,OAAO,CAAC,MAAM,CAAC,aAAa;WAOR,qBAAqB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;WA4BlD,0BAA0B,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IA4BxG;;;;;OAKG;WACiB,mBAAmB,CAAC,KAAK,CAAC,EAAE,iBAAiB,EAAE,GAAG,SAAqD,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAqBvJ;;;;;OAKG;WACW,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,oBAAoB;IAcjF;;;;MAIE;WACkB,cAAc,CAAC,IAAI,EAAE,wBAAwB,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAkDrG,mGAAmG;WACrF,oBAAoB,CAAC,QAAQ,EAAE,GAAG;IAQhD,OAAO,CAAC,MAAM,CAAC,aAAa,CAAsD;IAElF;;;;;;;;;;;OAWG;WAEiB,cAAc,CAAC,IAAI,EAAE,wBAAwB,GAAG,OAAO,CAAC,qBAAqB,GAAC,SAAS,CAAC;IAiE5G,mFAAmF;WAC/D,yBAAyB,CAAC,QAAQ,EAAE,QAAQ;WAoB5C,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,YAAY,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,yBAAyB,GAAG,OAAO,CAAC,mBAAmB,GAAC,SAAS,CAAC;IAgB3K;;;;;;;;;;OAUG;WACW,uBAAuB,CAAC,SAAS,GAAE,MAAU,EAAE,OAAO,GAAE,MAAW,EAAE,QAAQ,GAAE,MAAU,EAAE,QAAQ,GAAE,MAAY,EAAE,SAAS,SAAK,GAAG;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,EAAE;IAoBrM;;;;;;;OAOG;WACW,mBAAmB,CAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,SAAS,GAAE,MAAU,GAAG;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAC;CA0B7K"}
1
+ {"version":3,"file":"ArcGisUtilities.d.ts","sourceRoot":"","sources":["../../../../src/tile/map/ArcGisUtilities.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,cAAc,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,kBAAkB,EAAC,MAAM,aAAa,CAAC;AAIzM;;GAEG;AAEH;;;GAGG;AACH,oBAAY,eAAe;IACzB,kBAAkB,MAAM;IACxB,YAAY,MAAM;IAClB,aAAa,MAAM;IACnB,YAAY,OAAO;IACnB,cAAc,OAAO;CACtB;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,oCAAoC;IACpC,OAAO,EAAE,GAAG,CAAC;IAEb,qEAAqE;IACrE,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,wBAAyB,SAAQ,kBAAkB;IAClE,kJAAkJ;IAClJ,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAC,CAAC;IACtC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,qBAAa,eAAe;IAE1B,OAAO,CAAC,MAAM,CAAC,aAAa;WAOR,qBAAqB,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;WA4BlD,0BAA0B,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IA4BxG;;;;;OAKG;WACiB,mBAAmB,CAAC,KAAK,CAAC,EAAE,iBAAiB,EAAE,GAAG,SAAqD,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAqBvJ;;;;;OAKG;WACW,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,oBAAoB;IAcjF;;;;MAIE;WACkB,cAAc,CAAC,IAAI,EAAE,wBAAwB,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAkDrG,mGAAmG;WACrF,oBAAoB,CAAC,QAAQ,EAAE,GAAG;IAQhD,OAAO,CAAC,MAAM,CAAC,aAAa,CAAsD;IAElF;;;;;;;;;;;OAWG;WAEiB,cAAc,CAAC,IAAI,EAAE,wBAAwB,GAAG,OAAO,CAAC,qBAAqB,GAAC,SAAS,CAAC;IAqE5G,mFAAmF;WAC/D,yBAAyB,CAAC,QAAQ,EAAE,QAAQ;WAoB5C,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,YAAY,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,yBAAyB,GAAG,OAAO,CAAC,mBAAmB,GAAC,SAAS,CAAC;IAgB3K;;;;;;;;;;OAUG;WACW,uBAAuB,CAAC,SAAS,GAAE,MAAU,EAAE,OAAO,GAAE,MAAW,EAAE,QAAQ,GAAE,MAAU,EAAE,QAAQ,GAAE,MAAY,EAAE,SAAS,SAAK,GAAG;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAC,EAAE;IAoBrM;;;;;;;OAOG;WACW,mBAAmB,CAAE,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,SAAS,GAAE,MAAU,GAAG;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAC;CA0B7K"}
@@ -8,6 +8,7 @@ exports.ArcGisUtilities = exports.ArcGisErrorCode = void 0;
8
8
  const core_geometry_1 = require("@itwin/core-geometry");
9
9
  const internal_1 = require("../internal");
10
10
  const IModelApp_1 = require("../../IModelApp");
11
+ const utils_1 = require("../../request/utils");
11
12
  /** @packageDocumentation
12
13
  * @module Tiles
13
14
  */
@@ -230,6 +231,10 @@ class ArcGisUtilities {
230
231
  }
231
232
  }
232
233
  let response = await fetch(tmpUrl.toString(), { method: "GET" });
234
+ if (response.status === 401 && !requireToken && (0, utils_1.headersIncludeAuthMethod)(response.headers, ["ntlm", "negotiate"])) {
235
+ // We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication)
236
+ response = await fetch(url, { method: "GET", credentials: "include" });
237
+ }
233
238
  // Append security token when corresponding error code is returned by ArcGIS service
234
239
  let errorCode = await ArcGisUtilities.checkForResponseErrorCode(response);
235
240
  if (!accessTokenRequired
@@ -1 +1 @@
1
- {"version":3,"file":"ArcGisUtilities.js","sourceRoot":"","sources":["../../../../src/tile/map/ArcGisUtilities.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport { Angle, Constant } from \"@itwin/core-geometry\";\r\nimport { MapSubLayerProps } from \"@itwin/core-common\";\r\nimport { MapCartoRectangle, MapLayerAccessClient, MapLayerAccessToken, MapLayerAccessTokenParams, MapLayerSource, MapLayerSourceStatus, MapLayerSourceValidation, ValidateSourceArgs} from \"../internal\";\r\nimport { IModelApp } from \"../../IModelApp\";\r\n\r\n/** @packageDocumentation\r\n * @module Tiles\r\n */\r\n\r\n/**\r\n * Class representing an ArcGIS error code.\r\n * @internal\r\n */\r\nexport enum ArcGisErrorCode {\r\n InvalidCredentials = 401,\r\n InvalidToken = 498,\r\n TokenRequired = 499,\r\n UnknownError = 1000,\r\n NoTokenService = 1001,\r\n}\r\n\r\n/**\r\n * Class representing an ArcGIS service metadata.\r\n * @internal\r\n */\r\nexport interface ArcGISServiceMetadata {\r\n /** JSON content from the service */\r\n content: any;\r\n\r\n /** Indicates if an access token is required to access the service */\r\n accessTokenRequired: boolean;\r\n}\r\n\r\n/** Arguments for validating ArcGIS sources\r\n * @internal\r\n */\r\nexport interface ArcGisValidateSourceArgs extends ValidateSourceArgs {\r\n /** List of capabilities 'keyword' that needs to be advertised in the service's metadata in order to be valid. For example: 'Map', 'Query', etc*/\r\n capabilitiesFilter: string[];\r\n}\r\n\r\n/** Arguments for fetching service metadata\r\n * @internal\r\n */\r\nexport interface ArcGisGetServiceJsonArgs {\r\n url: string;\r\n formatId: string;\r\n userName?: string;\r\n password?: string;\r\n queryParams?: {[key: string]: string};\r\n ignoreCache?: boolean;\r\n requireToken?: boolean;\r\n}\r\n\r\n/**\r\n * Class containing utilities relating to ArcGIS services and coordinate systems.\r\n * @internal\r\n */\r\nexport class ArcGisUtilities {\r\n\r\n private static getBBoxString(range?: MapCartoRectangle) {\r\n if (!range)\r\n range = MapCartoRectangle.createMaximum();\r\n\r\n return `${range.low.x * Angle.degreesPerRadian},${range.low.y * Angle.degreesPerRadian},${range.high.x * Angle.degreesPerRadian},${range.high.y * Angle.degreesPerRadian}`;\r\n }\r\n\r\n public static async getNationalMapSources(): Promise<MapLayerSource[]> {\r\n const sources = new Array<MapLayerSource>();\r\n const response = await fetch(\"https://viewer.nationalmap.gov/tnmaccess/api/getMapServiceList\", { method: \"GET\" });\r\n const services = await response.json();\r\n\r\n if (!Array.isArray(services))\r\n return sources;\r\n\r\n for (const service of services) {\r\n if (service.wmsUrl.length === 0) // Exclude Wfs..\r\n continue;\r\n switch (service.serviceType) {\r\n case \"ArcGIS\":\r\n sources.push(MapLayerSource.fromJSON({ name: service.displayName, url: service.serviceLink, formatId: \"ArcGIS\" })!);\r\n break;\r\n default: {\r\n const wmsIndex = service.wmsUrl.lastIndexOf(\"/wms\");\r\n if (wmsIndex > 0) {\r\n const url = service.wmsUrl.slice(0, wmsIndex + 4);\r\n sources.push(MapLayerSource.fromJSON({ name: service.displayName, url, formatId: \"WMS\" })!);\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n return sources;\r\n }\r\n\r\n public static async getServiceDirectorySources(url: string, baseUrl?: string): Promise<MapLayerSource[]> {\r\n if (undefined === baseUrl)\r\n baseUrl = url;\r\n let sources = new Array<MapLayerSource>();\r\n const response = await fetch(`${url}?f=json`, { method: \"GET\" });\r\n const json = await response.json();\r\n if (json !== undefined) {\r\n if (Array.isArray(json.folders)) {\r\n for (const folder of json.folders) {\r\n sources = sources.concat(await ArcGisUtilities.getServiceDirectorySources(`${url}/${folder}`, url));\r\n }\r\n }\r\n if (Array.isArray(json.services)) {\r\n for (const service of json.services) {\r\n let source;\r\n if (service.type === \"MapServer\")\r\n source = MapLayerSource.fromJSON({ name: service.name, url: `${baseUrl}/${service.name}/MapServer`, formatId: \"ArcGIS\" });\r\n else if (service.type === \"ImageServer\")\r\n source = MapLayerSource.fromJSON({ name: service.name, url: `${baseUrl}/${service.name}/ImageServer`, formatId: \"ArcGIS\" });\r\n if (source)\r\n sources.push(source);\r\n }\r\n }\r\n }\r\n\r\n return sources;\r\n }\r\n\r\n /**\r\n * Get map layer sources from an ArcGIS query.\r\n * @param range Range for the query.\r\n * @param url URL for the query.\r\n * @returns List of map layer sources.\r\n */\r\n public static async getSourcesFromQuery(range?: MapCartoRectangle, url = \"https://usgs.maps.arcgis.com/sharing/rest/search\"): Promise<MapLayerSource[]> {\r\n const sources = new Array<MapLayerSource>();\r\n for (let start = 1; start > 0;) {\r\n const response = await fetch(`${url}?f=json&q=(group:9d1199a521334e77a7d15abbc29f8144) AND (type:\"Map Service\")&bbox=${ArcGisUtilities.getBBoxString(range)}&sortOrder=desc&start=${start}&num=100`, { method: \"GET\" });\r\n const json = await response.json();\r\n if (!json)\r\n break;\r\n\r\n start = json.nextStart ? json.nextStart : -1;\r\n if (json !== undefined && Array.isArray(json.results)) {\r\n for (const result of json.results) {\r\n const source = MapLayerSource.fromJSON({ name: result.name ? result.name : result.title, url: result.url, formatId: \"ArcGIS\" });\r\n if (source)\r\n sources.push(source);\r\n }\r\n }\r\n }\r\n\r\n return sources;\r\n }\r\n\r\n /**\r\n * Parse the URL to check if it represents a valid ArcGIS service\r\n * @param url URL to validate.\r\n * @param serviceType Service type to validate (i.e FeatureServer, MapServer)\r\n * @return Validation Status.\r\n */\r\n public static validateUrl(url: string, serviceType: string): MapLayerSourceStatus {\r\n const urlObj = new URL(url.toLowerCase());\r\n if (urlObj.pathname.includes(\"/rest/services/\")) {\r\n // This seem to be an ArcGIS URL, lets check the service type\r\n if (urlObj.pathname.endsWith(`${serviceType.toLowerCase()}`)) {\r\n return MapLayerSourceStatus.Valid;\r\n } else {\r\n return MapLayerSourceStatus.IncompatibleFormat;\r\n }\r\n } else {\r\n return MapLayerSourceStatus.InvalidUrl;\r\n }\r\n }\r\n\r\n /**\r\n * Attempt to access an ArcGIS service, and validate its service metadata.\r\n * @param source Source to validate.\r\n * @param opts Validation options\r\n */\r\n public static async validateSource(args: ArcGisValidateSourceArgs): Promise<MapLayerSourceValidation> {\r\n const {source, ignoreCache, capabilitiesFilter} = args;\r\n const metadata = await this.getServiceJson({url: source.url, formatId: source.formatId, userName: source.userName, password: source.password, queryParams: source.collectQueryParams(), ignoreCache});\r\n const json = metadata?.content;\r\n if (json === undefined) {\r\n return { status: MapLayerSourceStatus.InvalidUrl };\r\n } else if (json.error !== undefined) {\r\n\r\n // If we got a 'Token Required' error, lets check what authentification methods this ESRI service offers\r\n // and return information needed to initiate the authentification process... the end-user\r\n // will have to provide his credentials before we can fully validate this source.\r\n if (json.error.code === ArcGisErrorCode.TokenRequired) {\r\n return (source.userName || source.password) ? {status: MapLayerSourceStatus.InvalidCredentials} : {status: MapLayerSourceStatus.RequireAuth};\r\n } else if (json.error.code === ArcGisErrorCode.InvalidCredentials)\r\n return { status: MapLayerSourceStatus.InvalidCredentials};\r\n }\r\n\r\n // Check this service support the expected queries\r\n let hasCapabilities = false;\r\n let capsArray: string[] = [];\r\n if (json.capabilities && typeof json.capabilities === \"string\" ) {\r\n const capabilities: string = json.capabilities;\r\n capsArray = capabilities.split(\",\").map((entry) => entry.toLowerCase());\r\n\r\n const filtered = capsArray.filter((element, _index, _array) => capabilitiesFilter.includes(element));\r\n hasCapabilities = (filtered.length === capabilitiesFilter.length);\r\n }\r\n if (!hasCapabilities) {\r\n return { status: MapLayerSourceStatus.InvalidFormat};\r\n }\r\n\r\n // Only EPSG:3857 is supported with pre-rendered tiles.\r\n if (json.tileInfo && capsArray.includes(\"tilesonly\") && !ArcGisUtilities.isEpsg3857Compatible(json.tileInfo)) {\r\n return { status: MapLayerSourceStatus.InvalidCoordinateSystem};\r\n }\r\n\r\n let subLayers;\r\n if (json.layers) {\r\n\r\n subLayers = new Array<MapSubLayerProps>();\r\n\r\n for (const layer of json.layers) {\r\n const parent = layer.parentLayerId < 0 ? undefined : layer.parentLayerId;\r\n const children = Array.isArray(layer.subLayerIds) ? layer.subLayerIds : undefined;\r\n subLayers.push({ name: layer.name, visible: layer.defaultVisibility !== false, id: layer.id, parent, children });\r\n }\r\n }\r\n return { status: MapLayerSourceStatus.Valid, subLayers };\r\n }\r\n\r\n /** Validate MapService tiling metadata and checks if the tile tree is 'Google Maps' compatible. */\r\n public static isEpsg3857Compatible(tileInfo: any) {\r\n if (tileInfo.spatialReference?.latestWkid !== 3857 || !Array.isArray(tileInfo.lods))\r\n return false;\r\n\r\n const zeroLod = tileInfo.lods[0];\r\n return zeroLod.level === 0 && Math.abs(zeroLod.resolution - 156543.03392800014) < .001;\r\n }\r\n\r\n private static _serviceCache = new Map<string, ArcGISServiceMetadata|undefined>();\r\n\r\n /**\r\n * Fetches an ArcGIS service metadata, and returns its JSON representation.\r\n * If an access client has been configured for the specified formatId,\r\n * it will be used to apply required security token.\r\n * By default, response for each URL are cached.\r\n * @param url URL of the ArcGIS service\r\n * @param formatId Format ID of the service\r\n * @param userName Username to use for legacy token based security\r\n * @param password Password to use for legacy token based security\r\n * @param ignoreCache Flag to skip cache lookup (i.e. force a new server request)\r\n * @param requireToken Flag to indicate if a token is required\r\n */\r\n\r\n public static async getServiceJson(args: ArcGisGetServiceJsonArgs): Promise<ArcGISServiceMetadata|undefined> {\r\n const {url, formatId, userName, password, queryParams, ignoreCache, requireToken} = args;\r\n if (!ignoreCache) {\r\n const cached = ArcGisUtilities._serviceCache.get(url);\r\n if (cached !== undefined)\r\n return cached;\r\n }\r\n const appendParams = (urlObj: URL, params?: {[key: string]: string}) => {\r\n if (params) {\r\n Object.keys(params).forEach((paramKey) => {\r\n if (!urlObj.searchParams.has(paramKey))\r\n urlObj.searchParams.append(paramKey, params[paramKey]);\r\n });\r\n }\r\n };\r\n\r\n const createUrlObj = () => {\r\n const tmpUrl = new URL(url);\r\n tmpUrl.searchParams.append(\"f\", \"json\");\r\n appendParams(tmpUrl, queryParams);\r\n return tmpUrl;\r\n };\r\n\r\n let accessTokenRequired = false;\r\n try {\r\n let tmpUrl = createUrlObj();\r\n\r\n // In some cases, caller might already know token is required, so append it immediately\r\n if (requireToken) {\r\n const accessClient = IModelApp.mapLayerFormatRegistry.getAccessClient(formatId);\r\n if (accessClient) {\r\n accessTokenRequired = true;\r\n await ArcGisUtilities.appendSecurityToken(tmpUrl, accessClient, {mapLayerUrl: new URL(url), userName, password});\r\n }\r\n }\r\n let response = await fetch(tmpUrl.toString(), { method: \"GET\" });\r\n\r\n // Append security token when corresponding error code is returned by ArcGIS service\r\n let errorCode = await ArcGisUtilities.checkForResponseErrorCode(response);\r\n if (!accessTokenRequired\r\n && errorCode !== undefined\r\n && errorCode === ArcGisErrorCode.TokenRequired ) {\r\n accessTokenRequired = true;\r\n // If token required\r\n const accessClient = IModelApp.mapLayerFormatRegistry.getAccessClient(formatId);\r\n if (accessClient) {\r\n tmpUrl = createUrlObj();\r\n await ArcGisUtilities.appendSecurityToken(tmpUrl, accessClient, {mapLayerUrl: new URL(url), userName, password});\r\n response = await fetch(tmpUrl.toString(), { method: \"GET\" });\r\n errorCode = await ArcGisUtilities.checkForResponseErrorCode(response);\r\n }\r\n }\r\n\r\n const json = await response.json();\r\n const info = {content: json, accessTokenRequired};\r\n // Cache the response only if it doesn't contain any error.\r\n ArcGisUtilities._serviceCache.set(url, (errorCode === undefined ? info : undefined));\r\n return info; // Always return json, even though it contains an error code.\r\n\r\n } catch (_error) {\r\n ArcGisUtilities._serviceCache.set(url, undefined);\r\n return undefined;\r\n }\r\n }\r\n\r\n /** Read a response from ArcGIS server and check for error code in the response. */\r\n public static async checkForResponseErrorCode(response: Response) {\r\n const tmpResponse = response;\r\n if (response.headers && tmpResponse.headers.get(\"content-type\")?.toLowerCase().includes(\"json\")) {\r\n\r\n try {\r\n // Note:\r\n // Since response stream can only be read once (i.e. calls to .json() method)\r\n // we have to clone the response object in order to check for potential error code,\r\n // but still keep the response stream as unread.\r\n const clonedResponse = tmpResponse.clone();\r\n const json = await clonedResponse.json();\r\n if (json?.error?.code !== undefined)\r\n return json?.error?.code as number;\r\n } catch { }\r\n\r\n }\r\n return undefined;\r\n }\r\n\r\n // return the appended access token if available.\r\n public static async appendSecurityToken(url: URL, accessClient: MapLayerAccessClient, accessTokenParams: MapLayerAccessTokenParams): Promise<MapLayerAccessToken|undefined> {\r\n\r\n // Append security token if available\r\n let accessToken: MapLayerAccessToken|undefined;\r\n try {\r\n accessToken = await accessClient.getAccessToken(accessTokenParams);\r\n } catch {}\r\n\r\n if (accessToken?.token) {\r\n url.searchParams.append(\"token\", accessToken.token);\r\n return accessToken;\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Compute scale, resolution values for requested zoom levels (WSG 84)\r\n * Use a scale of 96 dpi for Google Maps scales\r\n * Based on this article: https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Resolution_and_Scale\r\n * @param startZoom Zoom level where scales begins to be computed\r\n * @param endZoom Zoom level where scales ends to be computed\r\n * @param latitude Latitude in degrees to use to compute scales (i.e 0 for Equator)\r\n * @param tileSize Size of a tile in pixels (i.e 256)\r\n * @param screenDpi Monitor resolution in dots per inch (i.e. typically 96dpi is used by Google Maps)\r\n * @returns An array containing resolution and scale values for each requested zoom level\r\n */\r\n public static computeZoomLevelsScales(startZoom: number = 0, endZoom: number = 20, latitude: number = 0, tileSize: number = 256, screenDpi = 96): {zoom: number, resolution: number, scale: number}[] {\r\n // Note: There is probably a more direct way to compute this, but I prefer to go for a simple and well documented approach.\r\n if (startZoom <0 || endZoom < startZoom || tileSize < 0 || screenDpi < 1 || latitude < -90 || latitude > 90)\r\n return [];\r\n\r\n const inchPerMeter = 1 / 0.0254;\r\n const results: {zoom: number, resolution: number, scale: number}[] = [];\r\n const equatorLength = Constant.earthRadiusWGS84.equator * 2 * Math.PI;\r\n const zoom0Resolution = equatorLength / tileSize; // in meters per pixel\r\n\r\n const cosLatitude = Math.cos(latitude);\r\n for (let zoom = startZoom; zoom<= endZoom; zoom++) {\r\n const resolution = zoom0Resolution * cosLatitude / Math.pow(2, zoom);\r\n const scale = screenDpi * inchPerMeter * resolution;\r\n results.push({zoom, resolution, scale});\r\n }\r\n\r\n return results;\r\n }\r\n\r\n /**\r\n * Match the provided minScale, maxScale values to corresponding wgs84 zoom levels\r\n * @param defaultMaxLod Value of the last LOD (i.e 22)\r\n * @param tileSize Size of a tile in pixels (i.e 256)\r\n * @param minScale Minimum scale value that needs to be matched to a LOD level\r\n * @param maxScale Maximum scale value that needs to be matched to a LOD level\r\n * @returns minLod: LOD value matching minScale, maxLod: LOD value matching maxScale\r\n */\r\n public static getZoomLevelsScales( defaultMaxLod: number, tileSize: number, minScale?: number, maxScale?: number, tolerance: number = 0): {minLod?: number, maxLod?: number} {\r\n\r\n let minLod: number|undefined, maxLod: number|undefined;\r\n\r\n const zoomScales = ArcGisUtilities.computeZoomLevelsScales(0, defaultMaxLod, 0 /* latitude 0 = Equator*/, tileSize);\r\n\r\n if (zoomScales.length > 0) {\r\n\r\n if (minScale) {\r\n minLod = 0;\r\n // We are looking for the largest scale value with a scale value smaller than minScale\r\n for (; minLod < zoomScales.length && (zoomScales[minLod].scale > minScale && Math.abs(zoomScales[minLod].scale - minScale) > tolerance); minLod++)\r\n ;\r\n\r\n }\r\n\r\n if (maxScale) {\r\n maxLod = defaultMaxLod;\r\n // We are looking for the smallest scale value with a value greater than maxScale\r\n for (; maxLod >= 0 && zoomScales[maxLod].scale < maxScale && Math.abs(zoomScales[maxLod].scale - maxScale) > tolerance; maxLod--)\r\n ;\r\n }\r\n }\r\n return {minLod, maxLod};\r\n }\r\n\r\n}\r\n"]}
1
+ {"version":3,"file":"ArcGisUtilities.js","sourceRoot":"","sources":["../../../../src/tile/map/ArcGisUtilities.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\nimport { Angle, Constant } from \"@itwin/core-geometry\";\r\nimport { MapSubLayerProps } from \"@itwin/core-common\";\r\nimport { MapCartoRectangle, MapLayerAccessClient, MapLayerAccessToken, MapLayerAccessTokenParams, MapLayerSource, MapLayerSourceStatus, MapLayerSourceValidation, ValidateSourceArgs} from \"../internal\";\r\nimport { IModelApp } from \"../../IModelApp\";\r\nimport { headersIncludeAuthMethod } from \"../../request/utils\";\r\n\r\n/** @packageDocumentation\r\n * @module Tiles\r\n */\r\n\r\n/**\r\n * Class representing an ArcGIS error code.\r\n * @internal\r\n */\r\nexport enum ArcGisErrorCode {\r\n InvalidCredentials = 401,\r\n InvalidToken = 498,\r\n TokenRequired = 499,\r\n UnknownError = 1000,\r\n NoTokenService = 1001,\r\n}\r\n\r\n/**\r\n * Class representing an ArcGIS service metadata.\r\n * @internal\r\n */\r\nexport interface ArcGISServiceMetadata {\r\n /** JSON content from the service */\r\n content: any;\r\n\r\n /** Indicates if an access token is required to access the service */\r\n accessTokenRequired: boolean;\r\n}\r\n\r\n/** Arguments for validating ArcGIS sources\r\n * @internal\r\n */\r\nexport interface ArcGisValidateSourceArgs extends ValidateSourceArgs {\r\n /** List of capabilities 'keyword' that needs to be advertised in the service's metadata in order to be valid. For example: 'Map', 'Query', etc*/\r\n capabilitiesFilter: string[];\r\n}\r\n\r\n/** Arguments for fetching service metadata\r\n * @internal\r\n */\r\nexport interface ArcGisGetServiceJsonArgs {\r\n url: string;\r\n formatId: string;\r\n userName?: string;\r\n password?: string;\r\n queryParams?: {[key: string]: string};\r\n ignoreCache?: boolean;\r\n requireToken?: boolean;\r\n}\r\n\r\n/**\r\n * Class containing utilities relating to ArcGIS services and coordinate systems.\r\n * @internal\r\n */\r\nexport class ArcGisUtilities {\r\n\r\n private static getBBoxString(range?: MapCartoRectangle) {\r\n if (!range)\r\n range = MapCartoRectangle.createMaximum();\r\n\r\n return `${range.low.x * Angle.degreesPerRadian},${range.low.y * Angle.degreesPerRadian},${range.high.x * Angle.degreesPerRadian},${range.high.y * Angle.degreesPerRadian}`;\r\n }\r\n\r\n public static async getNationalMapSources(): Promise<MapLayerSource[]> {\r\n const sources = new Array<MapLayerSource>();\r\n const response = await fetch(\"https://viewer.nationalmap.gov/tnmaccess/api/getMapServiceList\", { method: \"GET\" });\r\n const services = await response.json();\r\n\r\n if (!Array.isArray(services))\r\n return sources;\r\n\r\n for (const service of services) {\r\n if (service.wmsUrl.length === 0) // Exclude Wfs..\r\n continue;\r\n switch (service.serviceType) {\r\n case \"ArcGIS\":\r\n sources.push(MapLayerSource.fromJSON({ name: service.displayName, url: service.serviceLink, formatId: \"ArcGIS\" })!);\r\n break;\r\n default: {\r\n const wmsIndex = service.wmsUrl.lastIndexOf(\"/wms\");\r\n if (wmsIndex > 0) {\r\n const url = service.wmsUrl.slice(0, wmsIndex + 4);\r\n sources.push(MapLayerSource.fromJSON({ name: service.displayName, url, formatId: \"WMS\" })!);\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n return sources;\r\n }\r\n\r\n public static async getServiceDirectorySources(url: string, baseUrl?: string): Promise<MapLayerSource[]> {\r\n if (undefined === baseUrl)\r\n baseUrl = url;\r\n let sources = new Array<MapLayerSource>();\r\n const response = await fetch(`${url}?f=json`, { method: \"GET\" });\r\n const json = await response.json();\r\n if (json !== undefined) {\r\n if (Array.isArray(json.folders)) {\r\n for (const folder of json.folders) {\r\n sources = sources.concat(await ArcGisUtilities.getServiceDirectorySources(`${url}/${folder}`, url));\r\n }\r\n }\r\n if (Array.isArray(json.services)) {\r\n for (const service of json.services) {\r\n let source;\r\n if (service.type === \"MapServer\")\r\n source = MapLayerSource.fromJSON({ name: service.name, url: `${baseUrl}/${service.name}/MapServer`, formatId: \"ArcGIS\" });\r\n else if (service.type === \"ImageServer\")\r\n source = MapLayerSource.fromJSON({ name: service.name, url: `${baseUrl}/${service.name}/ImageServer`, formatId: \"ArcGIS\" });\r\n if (source)\r\n sources.push(source);\r\n }\r\n }\r\n }\r\n\r\n return sources;\r\n }\r\n\r\n /**\r\n * Get map layer sources from an ArcGIS query.\r\n * @param range Range for the query.\r\n * @param url URL for the query.\r\n * @returns List of map layer sources.\r\n */\r\n public static async getSourcesFromQuery(range?: MapCartoRectangle, url = \"https://usgs.maps.arcgis.com/sharing/rest/search\"): Promise<MapLayerSource[]> {\r\n const sources = new Array<MapLayerSource>();\r\n for (let start = 1; start > 0;) {\r\n const response = await fetch(`${url}?f=json&q=(group:9d1199a521334e77a7d15abbc29f8144) AND (type:\"Map Service\")&bbox=${ArcGisUtilities.getBBoxString(range)}&sortOrder=desc&start=${start}&num=100`, { method: \"GET\" });\r\n const json = await response.json();\r\n if (!json)\r\n break;\r\n\r\n start = json.nextStart ? json.nextStart : -1;\r\n if (json !== undefined && Array.isArray(json.results)) {\r\n for (const result of json.results) {\r\n const source = MapLayerSource.fromJSON({ name: result.name ? result.name : result.title, url: result.url, formatId: \"ArcGIS\" });\r\n if (source)\r\n sources.push(source);\r\n }\r\n }\r\n }\r\n\r\n return sources;\r\n }\r\n\r\n /**\r\n * Parse the URL to check if it represents a valid ArcGIS service\r\n * @param url URL to validate.\r\n * @param serviceType Service type to validate (i.e FeatureServer, MapServer)\r\n * @return Validation Status.\r\n */\r\n public static validateUrl(url: string, serviceType: string): MapLayerSourceStatus {\r\n const urlObj = new URL(url.toLowerCase());\r\n if (urlObj.pathname.includes(\"/rest/services/\")) {\r\n // This seem to be an ArcGIS URL, lets check the service type\r\n if (urlObj.pathname.endsWith(`${serviceType.toLowerCase()}`)) {\r\n return MapLayerSourceStatus.Valid;\r\n } else {\r\n return MapLayerSourceStatus.IncompatibleFormat;\r\n }\r\n } else {\r\n return MapLayerSourceStatus.InvalidUrl;\r\n }\r\n }\r\n\r\n /**\r\n * Attempt to access an ArcGIS service, and validate its service metadata.\r\n * @param source Source to validate.\r\n * @param opts Validation options\r\n */\r\n public static async validateSource(args: ArcGisValidateSourceArgs): Promise<MapLayerSourceValidation> {\r\n const {source, ignoreCache, capabilitiesFilter} = args;\r\n const metadata = await this.getServiceJson({url: source.url, formatId: source.formatId, userName: source.userName, password: source.password, queryParams: source.collectQueryParams(), ignoreCache});\r\n const json = metadata?.content;\r\n if (json === undefined) {\r\n return { status: MapLayerSourceStatus.InvalidUrl };\r\n } else if (json.error !== undefined) {\r\n\r\n // If we got a 'Token Required' error, lets check what authentification methods this ESRI service offers\r\n // and return information needed to initiate the authentification process... the end-user\r\n // will have to provide his credentials before we can fully validate this source.\r\n if (json.error.code === ArcGisErrorCode.TokenRequired) {\r\n return (source.userName || source.password) ? {status: MapLayerSourceStatus.InvalidCredentials} : {status: MapLayerSourceStatus.RequireAuth};\r\n } else if (json.error.code === ArcGisErrorCode.InvalidCredentials)\r\n return { status: MapLayerSourceStatus.InvalidCredentials};\r\n }\r\n\r\n // Check this service support the expected queries\r\n let hasCapabilities = false;\r\n let capsArray: string[] = [];\r\n if (json.capabilities && typeof json.capabilities === \"string\" ) {\r\n const capabilities: string = json.capabilities;\r\n capsArray = capabilities.split(\",\").map((entry) => entry.toLowerCase());\r\n\r\n const filtered = capsArray.filter((element, _index, _array) => capabilitiesFilter.includes(element));\r\n hasCapabilities = (filtered.length === capabilitiesFilter.length);\r\n }\r\n if (!hasCapabilities) {\r\n return { status: MapLayerSourceStatus.InvalidFormat};\r\n }\r\n\r\n // Only EPSG:3857 is supported with pre-rendered tiles.\r\n if (json.tileInfo && capsArray.includes(\"tilesonly\") && !ArcGisUtilities.isEpsg3857Compatible(json.tileInfo)) {\r\n return { status: MapLayerSourceStatus.InvalidCoordinateSystem};\r\n }\r\n\r\n let subLayers;\r\n if (json.layers) {\r\n\r\n subLayers = new Array<MapSubLayerProps>();\r\n\r\n for (const layer of json.layers) {\r\n const parent = layer.parentLayerId < 0 ? undefined : layer.parentLayerId;\r\n const children = Array.isArray(layer.subLayerIds) ? layer.subLayerIds : undefined;\r\n subLayers.push({ name: layer.name, visible: layer.defaultVisibility !== false, id: layer.id, parent, children });\r\n }\r\n }\r\n return { status: MapLayerSourceStatus.Valid, subLayers };\r\n }\r\n\r\n /** Validate MapService tiling metadata and checks if the tile tree is 'Google Maps' compatible. */\r\n public static isEpsg3857Compatible(tileInfo: any) {\r\n if (tileInfo.spatialReference?.latestWkid !== 3857 || !Array.isArray(tileInfo.lods))\r\n return false;\r\n\r\n const zeroLod = tileInfo.lods[0];\r\n return zeroLod.level === 0 && Math.abs(zeroLod.resolution - 156543.03392800014) < .001;\r\n }\r\n\r\n private static _serviceCache = new Map<string, ArcGISServiceMetadata|undefined>();\r\n\r\n /**\r\n * Fetches an ArcGIS service metadata, and returns its JSON representation.\r\n * If an access client has been configured for the specified formatId,\r\n * it will be used to apply required security token.\r\n * By default, response for each URL are cached.\r\n * @param url URL of the ArcGIS service\r\n * @param formatId Format ID of the service\r\n * @param userName Username to use for legacy token based security\r\n * @param password Password to use for legacy token based security\r\n * @param ignoreCache Flag to skip cache lookup (i.e. force a new server request)\r\n * @param requireToken Flag to indicate if a token is required\r\n */\r\n\r\n public static async getServiceJson(args: ArcGisGetServiceJsonArgs): Promise<ArcGISServiceMetadata|undefined> {\r\n const {url, formatId, userName, password, queryParams, ignoreCache, requireToken} = args;\r\n if (!ignoreCache) {\r\n const cached = ArcGisUtilities._serviceCache.get(url);\r\n if (cached !== undefined)\r\n return cached;\r\n }\r\n const appendParams = (urlObj: URL, params?: {[key: string]: string}) => {\r\n if (params) {\r\n Object.keys(params).forEach((paramKey) => {\r\n if (!urlObj.searchParams.has(paramKey))\r\n urlObj.searchParams.append(paramKey, params[paramKey]);\r\n });\r\n }\r\n };\r\n\r\n const createUrlObj = () => {\r\n const tmpUrl = new URL(url);\r\n tmpUrl.searchParams.append(\"f\", \"json\");\r\n appendParams(tmpUrl, queryParams);\r\n return tmpUrl;\r\n };\r\n\r\n let accessTokenRequired = false;\r\n try {\r\n let tmpUrl = createUrlObj();\r\n\r\n // In some cases, caller might already know token is required, so append it immediately\r\n if (requireToken) {\r\n const accessClient = IModelApp.mapLayerFormatRegistry.getAccessClient(formatId);\r\n if (accessClient) {\r\n accessTokenRequired = true;\r\n await ArcGisUtilities.appendSecurityToken(tmpUrl, accessClient, {mapLayerUrl: new URL(url), userName, password});\r\n }\r\n }\r\n let response = await fetch(tmpUrl.toString(), { method: \"GET\" });\r\n if (response.status === 401 && !requireToken && headersIncludeAuthMethod(response.headers, [\"ntlm\", \"negotiate\"])) {\r\n // We got a http 401 challenge, lets try again with SSO enabled (i.e. Windows Authentication)\r\n response = await fetch(url, {method: \"GET\", credentials: \"include\" });\r\n }\r\n\r\n // Append security token when corresponding error code is returned by ArcGIS service\r\n let errorCode = await ArcGisUtilities.checkForResponseErrorCode(response);\r\n if (!accessTokenRequired\r\n && errorCode !== undefined\r\n && errorCode === ArcGisErrorCode.TokenRequired ) {\r\n accessTokenRequired = true;\r\n // If token required\r\n const accessClient = IModelApp.mapLayerFormatRegistry.getAccessClient(formatId);\r\n if (accessClient) {\r\n tmpUrl = createUrlObj();\r\n await ArcGisUtilities.appendSecurityToken(tmpUrl, accessClient, {mapLayerUrl: new URL(url), userName, password});\r\n response = await fetch(tmpUrl.toString(), { method: \"GET\" });\r\n errorCode = await ArcGisUtilities.checkForResponseErrorCode(response);\r\n }\r\n }\r\n\r\n const json = await response.json();\r\n const info = {content: json, accessTokenRequired};\r\n // Cache the response only if it doesn't contain any error.\r\n ArcGisUtilities._serviceCache.set(url, (errorCode === undefined ? info : undefined));\r\n return info; // Always return json, even though it contains an error code.\r\n\r\n } catch (_error) {\r\n ArcGisUtilities._serviceCache.set(url, undefined);\r\n return undefined;\r\n }\r\n }\r\n\r\n /** Read a response from ArcGIS server and check for error code in the response. */\r\n public static async checkForResponseErrorCode(response: Response) {\r\n const tmpResponse = response;\r\n if (response.headers && tmpResponse.headers.get(\"content-type\")?.toLowerCase().includes(\"json\")) {\r\n\r\n try {\r\n // Note:\r\n // Since response stream can only be read once (i.e. calls to .json() method)\r\n // we have to clone the response object in order to check for potential error code,\r\n // but still keep the response stream as unread.\r\n const clonedResponse = tmpResponse.clone();\r\n const json = await clonedResponse.json();\r\n if (json?.error?.code !== undefined)\r\n return json?.error?.code as number;\r\n } catch { }\r\n\r\n }\r\n return undefined;\r\n }\r\n\r\n // return the appended access token if available.\r\n public static async appendSecurityToken(url: URL, accessClient: MapLayerAccessClient, accessTokenParams: MapLayerAccessTokenParams): Promise<MapLayerAccessToken|undefined> {\r\n\r\n // Append security token if available\r\n let accessToken: MapLayerAccessToken|undefined;\r\n try {\r\n accessToken = await accessClient.getAccessToken(accessTokenParams);\r\n } catch {}\r\n\r\n if (accessToken?.token) {\r\n url.searchParams.append(\"token\", accessToken.token);\r\n return accessToken;\r\n }\r\n\r\n return undefined;\r\n }\r\n\r\n /**\r\n * Compute scale, resolution values for requested zoom levels (WSG 84)\r\n * Use a scale of 96 dpi for Google Maps scales\r\n * Based on this article: https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Resolution_and_Scale\r\n * @param startZoom Zoom level where scales begins to be computed\r\n * @param endZoom Zoom level where scales ends to be computed\r\n * @param latitude Latitude in degrees to use to compute scales (i.e 0 for Equator)\r\n * @param tileSize Size of a tile in pixels (i.e 256)\r\n * @param screenDpi Monitor resolution in dots per inch (i.e. typically 96dpi is used by Google Maps)\r\n * @returns An array containing resolution and scale values for each requested zoom level\r\n */\r\n public static computeZoomLevelsScales(startZoom: number = 0, endZoom: number = 20, latitude: number = 0, tileSize: number = 256, screenDpi = 96): {zoom: number, resolution: number, scale: number}[] {\r\n // Note: There is probably a more direct way to compute this, but I prefer to go for a simple and well documented approach.\r\n if (startZoom <0 || endZoom < startZoom || tileSize < 0 || screenDpi < 1 || latitude < -90 || latitude > 90)\r\n return [];\r\n\r\n const inchPerMeter = 1 / 0.0254;\r\n const results: {zoom: number, resolution: number, scale: number}[] = [];\r\n const equatorLength = Constant.earthRadiusWGS84.equator * 2 * Math.PI;\r\n const zoom0Resolution = equatorLength / tileSize; // in meters per pixel\r\n\r\n const cosLatitude = Math.cos(latitude);\r\n for (let zoom = startZoom; zoom<= endZoom; zoom++) {\r\n const resolution = zoom0Resolution * cosLatitude / Math.pow(2, zoom);\r\n const scale = screenDpi * inchPerMeter * resolution;\r\n results.push({zoom, resolution, scale});\r\n }\r\n\r\n return results;\r\n }\r\n\r\n /**\r\n * Match the provided minScale, maxScale values to corresponding wgs84 zoom levels\r\n * @param defaultMaxLod Value of the last LOD (i.e 22)\r\n * @param tileSize Size of a tile in pixels (i.e 256)\r\n * @param minScale Minimum scale value that needs to be matched to a LOD level\r\n * @param maxScale Maximum scale value that needs to be matched to a LOD level\r\n * @returns minLod: LOD value matching minScale, maxLod: LOD value matching maxScale\r\n */\r\n public static getZoomLevelsScales( defaultMaxLod: number, tileSize: number, minScale?: number, maxScale?: number, tolerance: number = 0): {minLod?: number, maxLod?: number} {\r\n\r\n let minLod: number|undefined, maxLod: number|undefined;\r\n\r\n const zoomScales = ArcGisUtilities.computeZoomLevelsScales(0, defaultMaxLod, 0 /* latitude 0 = Equator*/, tileSize);\r\n\r\n if (zoomScales.length > 0) {\r\n\r\n if (minScale) {\r\n minLod = 0;\r\n // We are looking for the largest scale value with a scale value smaller than minScale\r\n for (; minLod < zoomScales.length && (zoomScales[minLod].scale > minScale && Math.abs(zoomScales[minLod].scale - minScale) > tolerance); minLod++)\r\n ;\r\n\r\n }\r\n\r\n if (maxScale) {\r\n maxLod = defaultMaxLod;\r\n // We are looking for the smallest scale value with a value greater than maxScale\r\n for (; maxLod >= 0 && zoomScales[maxLod].scale < maxScale && Math.abs(zoomScales[maxLod].scale - maxScale) > tolerance; maxLod--)\r\n ;\r\n }\r\n }\r\n return {minLod, maxLod};\r\n }\r\n\r\n}\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ArcGISImageryProvider.d.ts","sourceRoot":"","sources":["../../../../../src/tile/map/ImageryProviders/ArcGISImageryProvider.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAmB,qBAAqB,EAAmB,oBAAoB,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AAI5L;;;;;;GAMG;AACH,8BAAsB,qBAAsB,SAAQ,uBAAuB;IAEzE,SAAS,CAAC,aAAa,EAAE,oBAAoB,GAAC,SAAS,CAAC;IACxD,SAAS,CAAC,gBAAgB,EAAE,mBAAmB,GAAC,SAAS,CAAC;IAE1D;;MAEE;IACF,SAAS,CAAC,oBAAoB,UAAS;IAEvC,SAAS,CAAC,eAAe,UAAS;IAElC,IAAoB,sBAAsB,YAAkC;gBAEhE,QAAQ,EAAE,qBAAqB,EAAE,eAAe,EAAE,OAAO;IAKrE;;SAEK;cACc,eAAe,CAAC,MAAM,EAAE,6BAA6B;IAaxE;;;MAGE;cACc,cAAc;IAuB9B;;;;;OAKG;cACa,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,WAAW;CAuEtD"}
1
+ {"version":3,"file":"ArcGISImageryProvider.d.ts","sourceRoot":"","sources":["../../../../../src/tile/map/ImageryProviders/ArcGISImageryProvider.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAmB,qBAAqB,EAAmB,oBAAoB,EAAE,mBAAmB,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,MAAM,gBAAgB,CAAC;AAK5L;;;;;;GAMG;AACH,8BAAsB,qBAAsB,SAAQ,uBAAuB;IAEzE,SAAS,CAAC,aAAa,EAAE,oBAAoB,GAAC,SAAS,CAAC;IACxD,SAAS,CAAC,gBAAgB,EAAE,mBAAmB,GAAC,SAAS,CAAC;IAE1D;;MAEE;IACF,SAAS,CAAC,oBAAoB,UAAS;IAEvC,SAAS,CAAC,eAAe,UAAS;IAElC,IAAoB,sBAAsB,YAAkC;gBAEhE,QAAQ,EAAE,qBAAqB,EAAE,eAAe,EAAE,OAAO;IAKrE;;SAEK;cACc,eAAe,CAAC,MAAM,EAAE,6BAA6B;IAaxE;;;MAGE;cACc,cAAc;IAuB9B;;;;;OAKG;cACa,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,WAAW;CA+FtD"}