| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- // @ts-check
-
- import Axis from "./Axis.js";
- import Empty3DTileContent from "./Empty3DTileContent.js";
- import RuntimeError from "../Core/RuntimeError.js";
- import UrlTemplate3DTilesDataProvider from "./UrlTemplate3DTilesDataProvider.js";
- import VectorGltf3DTileContent from "./VectorGltf3DTileContent.js";
- import buildVectorGltfFromMVT from "./buildVectorGltfFromMVT.js";
- import decodeMVT from "./decodeMVT.js";
- import oneTimeWarning from "../Core/oneTimeWarning.js";
- import defined from "../Core/defined.js";
-
- /** @import Cesium3DTile from "./Cesium3DTile.js"; */
- /** @import Cesium3DTileset from "./Cesium3DTileset.js"; */
- /** @import Rectangle from "../Core/Rectangle.js"; */
- /** @import Resource from "../Core/Resource.js"; */
-
- /**
- * A Mapbox Vector Tiles (MVT) data provider. Loads .mvt or .pbf tiles, converting tiles
- * dynamically (at runtime) into 3D Tiles.
- *
- * <div class="notice">
- * This object is normally not instantiated directly, use {@link MVTDataProvider.fromUrl}.
- * </div>
- *
- * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
- */
- class MVTDataProvider extends UrlTemplate3DTilesDataProvider {
- /**
- * Creates an MVTDataProvider from the specified URL template and options.
- *
- * @param {Resource|string} url URL template, containing {z}, {x}, and {y} placeholders.
- * @param {object} [options] Provider options.
- * @param {number} [options.minZoom=0] Minimum zoom level represented in the generated tileset.
- * @param {number} [options.maxZoom=14] Maximum zoom level represented in the generated tileset.
- * @param {Rectangle} [options.extent] Optional geographic extent in radians to constrain the generated tile tree.
- * @param {string} [options.featureIdProperty] MVT property name to use as feature ID.
- */
- static async fromUrl(url, options) {
- return /** @type {Promise<MVTDataProvider>} */ (
- super.fromUrl(url, options)
- );
- }
-
- /**
- * @returns {object}
- * @protected
- * @ignore
- */
- _createTilesetLoadOptions() {
- return {
- skipLevelOfDetail: false,
- enablePick: true,
- featureIdLabel: "featureId_0",
- instanceFeatureIdLabel: "instanceFeatureId_0",
- };
- }
-
- /**
- * @param {Cesium3DTileset} tileset
- * @protected
- * @ignore
- */
- _configureTileset(tileset) {
- tileset._modelUpAxis = Axis.Z;
- tileset._modelForwardAxis = Axis.X;
- }
-
- /**
- * @returns {object}
- * @protected
- * @ignore
- */
- _createCodec() {
- const featureIdProperty = this._featureIdProperty;
- return {
- contentType: "mvt",
- missingTilePolicy: { statusCodes: [404, 204] },
-
- /**
- * @param {Cesium3DTileset} tileset
- * @param {Cesium3DTile} tile
- * @param {Resource} resource
- * @param {ArrayBuffer} arrayBuffer
- * @ignore
- */
- createContent: async (tileset, tile, resource, arrayBuffer) => {
- const decodedTile = decodeMVT(arrayBuffer);
- const tileCoordinates = parseTileCoordinates(
- resource.getUrlComponent(true),
- );
- const glb = buildVectorGltfFromMVT(decodedTile, tileCoordinates, {
- featureIdProperty: featureIdProperty,
- });
- if (!defined(glb)) {
- if (!hasAnyDecodedFeatures(decodedTile)) {
- return new Empty3DTileContent(tileset, tile);
- }
- throw new RuntimeError(
- "Decoded MVT tile did not produce vector glTF content.",
- );
- }
- return VectorGltf3DTileContent.fromGltf(tileset, tile, resource, glb);
- },
- };
- }
- }
-
- /**
- * @param {string} url
- * @returns {{tileZ:number, tileX:number, tileY:number}}
- * @ignore
- */
- function parseTileCoordinates(url) {
- const match = url.match(/\/(\d+)\/(\d+)\/(\d+)(?:\.[^/?#]+)?(?:[?#]|$)/i);
- if (!match) {
- oneTimeWarning(
- "MVTDataProvider.parseTileCoordinates",
- `MVT tile URL did not match /{z}/{x}/{y} pattern. Falling back to z/x/y = 0/0/0. URL: ${url}`,
- );
- return { tileZ: 0, tileX: 0, tileY: 0 };
- }
- return {
- tileZ: parseInt(match[1], 10),
- tileX: parseInt(match[2], 10),
- tileY: parseInt(match[3], 10),
- };
- }
-
- /**
- * @param {{layers:Array<{features:Array<*>}>}} decodedTile
- * @returns {boolean}
- * @ignore
- */
- function hasAnyDecodedFeatures(decodedTile) {
- const layers = decodedTile.layers;
- for (let i = 0; i < layers.length; i++) {
- if (layers[i].features.length > 0) {
- return true;
- }
- }
- return false;
- }
-
- MVTDataProvider._parseTileCoordinates = parseTileCoordinates;
-
- export default MVTDataProvider;
|