智慧水务管理系统 - 精河县供水工程综合管理平台

MVTDataProvider.js 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // @ts-check
  2. import Axis from "./Axis.js";
  3. import Empty3DTileContent from "./Empty3DTileContent.js";
  4. import RuntimeError from "../Core/RuntimeError.js";
  5. import UrlTemplate3DTilesDataProvider from "./UrlTemplate3DTilesDataProvider.js";
  6. import VectorGltf3DTileContent from "./VectorGltf3DTileContent.js";
  7. import buildVectorGltfFromMVT from "./buildVectorGltfFromMVT.js";
  8. import decodeMVT from "./decodeMVT.js";
  9. import oneTimeWarning from "../Core/oneTimeWarning.js";
  10. import defined from "../Core/defined.js";
  11. /** @import Cesium3DTile from "./Cesium3DTile.js"; */
  12. /** @import Cesium3DTileset from "./Cesium3DTileset.js"; */
  13. /** @import Rectangle from "../Core/Rectangle.js"; */
  14. /** @import Resource from "../Core/Resource.js"; */
  15. /**
  16. * A Mapbox Vector Tiles (MVT) data provider. Loads .mvt or .pbf tiles, converting tiles
  17. * dynamically (at runtime) into 3D Tiles.
  18. *
  19. * <div class="notice">
  20. * This object is normally not instantiated directly, use {@link MVTDataProvider.fromUrl}.
  21. * </div>
  22. *
  23. * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
  24. */
  25. class MVTDataProvider extends UrlTemplate3DTilesDataProvider {
  26. /**
  27. * Creates an MVTDataProvider from the specified URL template and options.
  28. *
  29. * @param {Resource|string} url URL template, containing {z}, {x}, and {y} placeholders.
  30. * @param {object} [options] Provider options.
  31. * @param {number} [options.minZoom=0] Minimum zoom level represented in the generated tileset.
  32. * @param {number} [options.maxZoom=14] Maximum zoom level represented in the generated tileset.
  33. * @param {Rectangle} [options.extent] Optional geographic extent in radians to constrain the generated tile tree.
  34. * @param {string} [options.featureIdProperty] MVT property name to use as feature ID.
  35. */
  36. static async fromUrl(url, options) {
  37. return /** @type {Promise<MVTDataProvider>} */ (
  38. super.fromUrl(url, options)
  39. );
  40. }
  41. /**
  42. * @returns {object}
  43. * @protected
  44. * @ignore
  45. */
  46. _createTilesetLoadOptions() {
  47. return {
  48. skipLevelOfDetail: false,
  49. enablePick: true,
  50. featureIdLabel: "featureId_0",
  51. instanceFeatureIdLabel: "instanceFeatureId_0",
  52. };
  53. }
  54. /**
  55. * @param {Cesium3DTileset} tileset
  56. * @protected
  57. * @ignore
  58. */
  59. _configureTileset(tileset) {
  60. tileset._modelUpAxis = Axis.Z;
  61. tileset._modelForwardAxis = Axis.X;
  62. }
  63. /**
  64. * @returns {object}
  65. * @protected
  66. * @ignore
  67. */
  68. _createCodec() {
  69. const featureIdProperty = this._featureIdProperty;
  70. return {
  71. contentType: "mvt",
  72. missingTilePolicy: { statusCodes: [404, 204] },
  73. /**
  74. * @param {Cesium3DTileset} tileset
  75. * @param {Cesium3DTile} tile
  76. * @param {Resource} resource
  77. * @param {ArrayBuffer} arrayBuffer
  78. * @ignore
  79. */
  80. createContent: async (tileset, tile, resource, arrayBuffer) => {
  81. const decodedTile = decodeMVT(arrayBuffer);
  82. const tileCoordinates = parseTileCoordinates(
  83. resource.getUrlComponent(true),
  84. );
  85. const glb = buildVectorGltfFromMVT(decodedTile, tileCoordinates, {
  86. featureIdProperty: featureIdProperty,
  87. });
  88. if (!defined(glb)) {
  89. if (!hasAnyDecodedFeatures(decodedTile)) {
  90. return new Empty3DTileContent(tileset, tile);
  91. }
  92. throw new RuntimeError(
  93. "Decoded MVT tile did not produce vector glTF content.",
  94. );
  95. }
  96. return VectorGltf3DTileContent.fromGltf(tileset, tile, resource, glb);
  97. },
  98. };
  99. }
  100. }
  101. /**
  102. * @param {string} url
  103. * @returns {{tileZ:number, tileX:number, tileY:number}}
  104. * @ignore
  105. */
  106. function parseTileCoordinates(url) {
  107. const match = url.match(/\/(\d+)\/(\d+)\/(\d+)(?:\.[^/?#]+)?(?:[?#]|$)/i);
  108. if (!match) {
  109. oneTimeWarning(
  110. "MVTDataProvider.parseTileCoordinates",
  111. `MVT tile URL did not match /{z}/{x}/{y} pattern. Falling back to z/x/y = 0/0/0. URL: ${url}`,
  112. );
  113. return { tileZ: 0, tileX: 0, tileY: 0 };
  114. }
  115. return {
  116. tileZ: parseInt(match[1], 10),
  117. tileX: parseInt(match[2], 10),
  118. tileY: parseInt(match[3], 10),
  119. };
  120. }
  121. /**
  122. * @param {{layers:Array<{features:Array<*>}>}} decodedTile
  123. * @returns {boolean}
  124. * @ignore
  125. */
  126. function hasAnyDecodedFeatures(decodedTile) {
  127. const layers = decodedTile.layers;
  128. for (let i = 0; i < layers.length; i++) {
  129. if (layers[i].features.length > 0) {
  130. return true;
  131. }
  132. }
  133. return false;
  134. }
  135. MVTDataProvider._parseTileCoordinates = parseTileCoordinates;
  136. export default MVTDataProvider;