123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777 |
- import Cartesian3 from "../Core/Cartesian3.js";
- import defaultValue from "../Core/defaultValue.js";
- import defer from "../Core/defer.js";
- import defined from "../Core/defined.js";
- import destroyObject from "../Core/destroyObject.js";
- import DeveloperError from "../Core/DeveloperError.js";
- import Ellipsoid from "../Core/Ellipsoid.js";
- import getJsonFromTypedArray from "../Core/getJsonFromTypedArray.js";
- import ComponentDatatype from "../Core/ComponentDatatype.js";
- import CesiumMath from "../Core/Math.js";
- import Matrix4 from "../Core/Matrix4.js";
- import Rectangle from "../Core/Rectangle.js";
- import RuntimeError from "../Core/RuntimeError.js";
- import Cesium3DTileBatchTable from "./Cesium3DTileBatchTable.js";
- import Cesium3DTileFeatureTable from "./Cesium3DTileFeatureTable.js";
- import Vector3DTilePoints from "./Vector3DTilePoints.js";
- import Vector3DTilePolygons from "./Vector3DTilePolygons.js";
- import Vector3DTilePolylines from "./Vector3DTilePolylines.js";
- import Vector3DTileClampedPolylines from "./Vector3DTileClampedPolylines.js";
- import decodeVectorPolylinePositions from "../Core/decodeVectorPolylinePositions.js";
- /**
- * Represents the contents of a
- * {@link https://github.com/CesiumGS/3d-tiles/tree/vctr/TileFormats/VectorData|Vector}
- * tile in a {@link https://github.com/CesiumGS/3d-tiles/tree/main/specification|3D Tiles} tileset.
- * <p>
- * Implements the {@link Cesium3DTileContent} interface.
- * </p>
- *
- * @alias Vector3DTileContent
- * @constructor
- *
- * @private
- */
- function Vector3DTileContent(tileset, tile, resource, arrayBuffer, byteOffset) {
- this._tileset = tileset;
- this._tile = tile;
- this._resource = resource;
- this._polygons = undefined;
- this._polylines = undefined;
- this._points = undefined;
- this._contentReadyPromise = undefined;
- this._readyPromise = defer();
- this._metadata = undefined;
- this._batchTable = undefined;
- this._features = undefined;
- /**
- * Part of the {@link Cesium3DTileContent} interface.
- */
- this.featurePropertiesDirty = false;
- this._group = undefined;
- initialize(this, arrayBuffer, byteOffset);
- }
- Object.defineProperties(Vector3DTileContent.prototype, {
- featuresLength: {
- get: function () {
- return defined(this._batchTable) ? this._batchTable.featuresLength : 0;
- },
- },
- pointsLength: {
- get: function () {
- if (defined(this._points)) {
- return this._points.pointsLength;
- }
- return 0;
- },
- },
- trianglesLength: {
- get: function () {
- let trianglesLength = 0;
- if (defined(this._polygons)) {
- trianglesLength += this._polygons.trianglesLength;
- }
- if (defined(this._polylines)) {
- trianglesLength += this._polylines.trianglesLength;
- }
- return trianglesLength;
- },
- },
- geometryByteLength: {
- get: function () {
- let geometryByteLength = 0;
- if (defined(this._polygons)) {
- geometryByteLength += this._polygons.geometryByteLength;
- }
- if (defined(this._polylines)) {
- geometryByteLength += this._polylines.geometryByteLength;
- }
- return geometryByteLength;
- },
- },
- texturesByteLength: {
- get: function () {
- if (defined(this._points)) {
- return this._points.texturesByteLength;
- }
- return 0;
- },
- },
- batchTableByteLength: {
- get: function () {
- return defined(this._batchTable) ? this._batchTable.memorySizeInBytes : 0;
- },
- },
- innerContents: {
- get: function () {
- return undefined;
- },
- },
- readyPromise: {
- get: function () {
- return this._readyPromise.promise;
- },
- },
- tileset: {
- get: function () {
- return this._tileset;
- },
- },
- tile: {
- get: function () {
- return this._tile;
- },
- },
- url: {
- get: function () {
- return this._resource.getUrlComponent(true);
- },
- },
- metadata: {
- get: function () {
- return this._metadata;
- },
- set: function (value) {
- this._metadata = value;
- },
- },
- batchTable: {
- get: function () {
- return this._batchTable;
- },
- },
- group: {
- get: function () {
- return this._group;
- },
- set: function (value) {
- this._group = value;
- },
- },
- });
- function createColorChangedCallback(content) {
- return function (batchId, color) {
- if (defined(content._polygons)) {
- content._polygons.updateCommands(batchId, color);
- }
- };
- }
- function getBatchIds(featureTableJson, featureTableBinary) {
- let polygonBatchIds;
- let polylineBatchIds;
- let pointBatchIds;
- let i;
- const numberOfPolygons = defaultValue(featureTableJson.POLYGONS_LENGTH, 0);
- const numberOfPolylines = defaultValue(featureTableJson.POLYLINES_LENGTH, 0);
- const numberOfPoints = defaultValue(featureTableJson.POINTS_LENGTH, 0);
- if (numberOfPolygons > 0 && defined(featureTableJson.POLYGON_BATCH_IDS)) {
- const polygonBatchIdsByteOffset =
- featureTableBinary.byteOffset +
- featureTableJson.POLYGON_BATCH_IDS.byteOffset;
- polygonBatchIds = new Uint16Array(
- featureTableBinary.buffer,
- polygonBatchIdsByteOffset,
- numberOfPolygons
- );
- }
- if (numberOfPolylines > 0 && defined(featureTableJson.POLYLINE_BATCH_IDS)) {
- const polylineBatchIdsByteOffset =
- featureTableBinary.byteOffset +
- featureTableJson.POLYLINE_BATCH_IDS.byteOffset;
- polylineBatchIds = new Uint16Array(
- featureTableBinary.buffer,
- polylineBatchIdsByteOffset,
- numberOfPolylines
- );
- }
- if (numberOfPoints > 0 && defined(featureTableJson.POINT_BATCH_IDS)) {
- const pointBatchIdsByteOffset =
- featureTableBinary.byteOffset +
- featureTableJson.POINT_BATCH_IDS.byteOffset;
- pointBatchIds = new Uint16Array(
- featureTableBinary.buffer,
- pointBatchIdsByteOffset,
- numberOfPoints
- );
- }
- const atLeastOneDefined =
- defined(polygonBatchIds) ||
- defined(polylineBatchIds) ||
- defined(pointBatchIds);
- const atLeastOneUndefined =
- (numberOfPolygons > 0 && !defined(polygonBatchIds)) ||
- (numberOfPolylines > 0 && !defined(polylineBatchIds)) ||
- (numberOfPoints > 0 && !defined(pointBatchIds));
- if (atLeastOneDefined && atLeastOneUndefined) {
- throw new RuntimeError(
- "If one group of batch ids is defined, then all batch ids must be defined."
- );
- }
- const allUndefinedBatchIds =
- !defined(polygonBatchIds) &&
- !defined(polylineBatchIds) &&
- !defined(pointBatchIds);
- if (allUndefinedBatchIds) {
- let id = 0;
- if (!defined(polygonBatchIds) && numberOfPolygons > 0) {
- polygonBatchIds = new Uint16Array(numberOfPolygons);
- for (i = 0; i < numberOfPolygons; ++i) {
- polygonBatchIds[i] = id++;
- }
- }
- if (!defined(polylineBatchIds) && numberOfPolylines > 0) {
- polylineBatchIds = new Uint16Array(numberOfPolylines);
- for (i = 0; i < numberOfPolylines; ++i) {
- polylineBatchIds[i] = id++;
- }
- }
- if (!defined(pointBatchIds) && numberOfPoints > 0) {
- pointBatchIds = new Uint16Array(numberOfPoints);
- for (i = 0; i < numberOfPoints; ++i) {
- pointBatchIds[i] = id++;
- }
- }
- }
- return {
- polygons: polygonBatchIds,
- polylines: polylineBatchIds,
- points: pointBatchIds,
- };
- }
- const sizeOfUint32 = Uint32Array.BYTES_PER_ELEMENT;
- function createFloatingPolylines(options) {
- return new Vector3DTilePolylines(options);
- }
- function createClampedPolylines(options) {
- return new Vector3DTileClampedPolylines(options);
- }
- function initialize(content, arrayBuffer, byteOffset) {
- byteOffset = defaultValue(byteOffset, 0);
- const uint8Array = new Uint8Array(arrayBuffer);
- const view = new DataView(arrayBuffer);
- byteOffset += sizeOfUint32; // Skip magic number
- const version = view.getUint32(byteOffset, true);
- if (version !== 1) {
- throw new RuntimeError(
- `Only Vector tile version 1 is supported. Version ${version} is not.`
- );
- }
- byteOffset += sizeOfUint32;
- const byteLength = view.getUint32(byteOffset, true);
- byteOffset += sizeOfUint32;
- if (byteLength === 0) {
- content._readyPromise.resolve(content);
- return;
- }
- const featureTableJSONByteLength = view.getUint32(byteOffset, true);
- byteOffset += sizeOfUint32;
- if (featureTableJSONByteLength === 0) {
- throw new RuntimeError(
- "Feature table must have a byte length greater than zero"
- );
- }
- const featureTableBinaryByteLength = view.getUint32(byteOffset, true);
- byteOffset += sizeOfUint32;
- const batchTableJSONByteLength = view.getUint32(byteOffset, true);
- byteOffset += sizeOfUint32;
- const batchTableBinaryByteLength = view.getUint32(byteOffset, true);
- byteOffset += sizeOfUint32;
- const indicesByteLength = view.getUint32(byteOffset, true);
- byteOffset += sizeOfUint32;
- const positionByteLength = view.getUint32(byteOffset, true);
- byteOffset += sizeOfUint32;
- const polylinePositionByteLength = view.getUint32(byteOffset, true);
- byteOffset += sizeOfUint32;
- const pointsPositionByteLength = view.getUint32(byteOffset, true);
- byteOffset += sizeOfUint32;
- const featureTableJson = getJsonFromTypedArray(
- uint8Array,
- byteOffset,
- featureTableJSONByteLength
- );
- byteOffset += featureTableJSONByteLength;
- const featureTableBinary = new Uint8Array(
- arrayBuffer,
- byteOffset,
- featureTableBinaryByteLength
- );
- byteOffset += featureTableBinaryByteLength;
- let batchTableJson;
- let batchTableBinary;
- if (batchTableJSONByteLength > 0) {
- // PERFORMANCE_IDEA: is it possible to allocate this on-demand? Perhaps keep the
- // arraybuffer/string compressed in memory and then decompress it when it is first accessed.
- //
- // We could also make another request for it, but that would make the property set/get
- // API async, and would double the number of numbers in some cases.
- batchTableJson = getJsonFromTypedArray(
- uint8Array,
- byteOffset,
- batchTableJSONByteLength
- );
- byteOffset += batchTableJSONByteLength;
- if (batchTableBinaryByteLength > 0) {
- // Has a batch table binary
- batchTableBinary = new Uint8Array(
- arrayBuffer,
- byteOffset,
- batchTableBinaryByteLength
- );
- // Copy the batchTableBinary section and let the underlying ArrayBuffer be freed
- batchTableBinary = new Uint8Array(batchTableBinary);
- byteOffset += batchTableBinaryByteLength;
- }
- }
- const numberOfPolygons = defaultValue(featureTableJson.POLYGONS_LENGTH, 0);
- const numberOfPolylines = defaultValue(featureTableJson.POLYLINES_LENGTH, 0);
- const numberOfPoints = defaultValue(featureTableJson.POINTS_LENGTH, 0);
- const totalPrimitives = numberOfPolygons + numberOfPolylines + numberOfPoints;
- const batchTable = new Cesium3DTileBatchTable(
- content,
- totalPrimitives,
- batchTableJson,
- batchTableBinary,
- createColorChangedCallback(content)
- );
- content._batchTable = batchTable;
- if (totalPrimitives === 0) {
- return;
- }
- const featureTable = new Cesium3DTileFeatureTable(
- featureTableJson,
- featureTableBinary
- );
- const region = featureTable.getGlobalProperty("REGION");
- if (!defined(region)) {
- throw new RuntimeError(
- "Feature table global property: REGION must be defined"
- );
- }
- const rectangle = Rectangle.unpack(region);
- const minHeight = region[4];
- const maxHeight = region[5];
- const modelMatrix = content._tile.computedTransform;
- let center = featureTable.getGlobalProperty(
- "RTC_CENTER",
- ComponentDatatype.FLOAT,
- 3
- );
- if (defined(center)) {
- center = Cartesian3.unpack(center);
- Matrix4.multiplyByPoint(modelMatrix, center, center);
- } else {
- center = Rectangle.center(rectangle);
- center.height = CesiumMath.lerp(minHeight, maxHeight, 0.5);
- center = Ellipsoid.WGS84.cartographicToCartesian(center);
- }
- const batchIds = getBatchIds(featureTableJson, featureTableBinary);
- byteOffset += (4 - (byteOffset % 4)) % 4;
- if (numberOfPolygons > 0) {
- featureTable.featuresLength = numberOfPolygons;
- const polygonCounts = defaultValue(
- featureTable.getPropertyArray(
- "POLYGON_COUNTS",
- ComponentDatatype.UNSIGNED_INT,
- 1
- ),
- featureTable.getPropertyArray(
- "POLYGON_COUNT",
- ComponentDatatype.UNSIGNED_INT,
- 1
- ) // Workaround for old vector tilesets using the non-plural name
- );
- if (!defined(polygonCounts)) {
- throw new RuntimeError(
- "Feature table property: POLYGON_COUNTS must be defined when POLYGONS_LENGTH is greater than 0"
- );
- }
- const polygonIndexCounts = defaultValue(
- featureTable.getPropertyArray(
- "POLYGON_INDEX_COUNTS",
- ComponentDatatype.UNSIGNED_INT,
- 1
- ),
- featureTable.getPropertyArray(
- "POLYGON_INDEX_COUNT",
- ComponentDatatype.UNSIGNED_INT,
- 1
- ) // Workaround for old vector tilesets using the non-plural name
- );
- if (!defined(polygonIndexCounts)) {
- throw new RuntimeError(
- "Feature table property: POLYGON_INDEX_COUNTS must be defined when POLYGONS_LENGTH is greater than 0"
- );
- }
- // Use the counts array to determine how many position values we want. If we used the byte length then
- // zero padding values would be included and cause the delta zig-zag decoding to fail
- const numPolygonPositions = polygonCounts.reduce(function (total, count) {
- return total + count * 2;
- }, 0);
- const numPolygonIndices = polygonIndexCounts.reduce(function (
- total,
- count
- ) {
- return total + count;
- },
- 0);
- const indices = new Uint32Array(arrayBuffer, byteOffset, numPolygonIndices);
- byteOffset += indicesByteLength;
- const polygonPositions = new Uint16Array(
- arrayBuffer,
- byteOffset,
- numPolygonPositions
- );
- byteOffset += positionByteLength;
- let polygonMinimumHeights;
- let polygonMaximumHeights;
- if (
- defined(featureTableJson.POLYGON_MINIMUM_HEIGHTS) &&
- defined(featureTableJson.POLYGON_MAXIMUM_HEIGHTS)
- ) {
- polygonMinimumHeights = featureTable.getPropertyArray(
- "POLYGON_MINIMUM_HEIGHTS",
- ComponentDatatype.FLOAT,
- 1
- );
- polygonMaximumHeights = featureTable.getPropertyArray(
- "POLYGON_MAXIMUM_HEIGHTS",
- ComponentDatatype.FLOAT,
- 1
- );
- }
- content._polygons = new Vector3DTilePolygons({
- positions: polygonPositions,
- counts: polygonCounts,
- indexCounts: polygonIndexCounts,
- indices: indices,
- minimumHeight: minHeight,
- maximumHeight: maxHeight,
- polygonMinimumHeights: polygonMinimumHeights,
- polygonMaximumHeights: polygonMaximumHeights,
- center: center,
- rectangle: rectangle,
- boundingVolume: content.tile.boundingVolume.boundingVolume,
- batchTable: batchTable,
- batchIds: batchIds.polygons,
- modelMatrix: modelMatrix,
- });
- }
- if (numberOfPolylines > 0) {
- featureTable.featuresLength = numberOfPolylines;
- const polylineCounts = defaultValue(
- featureTable.getPropertyArray(
- "POLYLINE_COUNTS",
- ComponentDatatype.UNSIGNED_INT,
- 1
- ),
- featureTable.getPropertyArray(
- "POLYLINE_COUNT",
- ComponentDatatype.UNSIGNED_INT,
- 1
- ) // Workaround for old vector tilesets using the non-plural name
- );
- if (!defined(polylineCounts)) {
- throw new RuntimeError(
- "Feature table property: POLYLINE_COUNTS must be defined when POLYLINES_LENGTH is greater than 0"
- );
- }
- let widths = featureTable.getPropertyArray(
- "POLYLINE_WIDTHS",
- ComponentDatatype.UNSIGNED_SHORT,
- 1
- );
- if (!defined(widths)) {
- widths = new Uint16Array(numberOfPolylines);
- for (let i = 0; i < numberOfPolylines; ++i) {
- widths[i] = 2.0;
- }
- }
- // Use the counts array to determine how many position values we want. If we used the byte length then
- // zero padding values would be included and cause the delta zig-zag decoding to fail
- const numPolylinePositions = polylineCounts.reduce(function (total, count) {
- return total + count * 3;
- }, 0);
- const polylinePositions = new Uint16Array(
- arrayBuffer,
- byteOffset,
- numPolylinePositions
- );
- byteOffset += polylinePositionByteLength;
- const tileset = content._tileset;
- const examineVectorLinesFunction = tileset.examineVectorLinesFunction;
- if (defined(examineVectorLinesFunction)) {
- const decodedPositions = decodeVectorPolylinePositions(
- new Uint16Array(polylinePositions),
- rectangle,
- minHeight,
- maxHeight,
- Ellipsoid.WGS84
- );
- examineVectorLines(
- decodedPositions,
- polylineCounts,
- batchIds.polylines,
- batchTable,
- content.url,
- examineVectorLinesFunction
- );
- }
- let createPolylines = createFloatingPolylines;
- if (defined(tileset.classificationType)) {
- createPolylines = createClampedPolylines;
- }
- content._polylines = createPolylines({
- positions: polylinePositions,
- widths: widths,
- counts: polylineCounts,
- batchIds: batchIds.polylines,
- minimumHeight: minHeight,
- maximumHeight: maxHeight,
- center: center,
- rectangle: rectangle,
- boundingVolume: content.tile.boundingVolume.boundingVolume,
- batchTable: batchTable,
- classificationType: tileset.classificationType,
- keepDecodedPositions: tileset.vectorKeepDecodedPositions,
- });
- }
- if (numberOfPoints > 0) {
- const pointPositions = new Uint16Array(
- arrayBuffer,
- byteOffset,
- numberOfPoints * 3
- );
- byteOffset += pointsPositionByteLength;
- content._points = new Vector3DTilePoints({
- positions: pointPositions,
- batchIds: batchIds.points,
- minimumHeight: minHeight,
- maximumHeight: maxHeight,
- rectangle: rectangle,
- batchTable: batchTable,
- });
- }
- }
- function createFeatures(content) {
- const featuresLength = content.featuresLength;
- if (!defined(content._features) && featuresLength > 0) {
- const features = new Array(featuresLength);
- if (defined(content._polygons)) {
- content._polygons.createFeatures(content, features);
- }
- if (defined(content._polylines)) {
- content._polylines.createFeatures(content, features);
- }
- if (defined(content._points)) {
- content._points.createFeatures(content, features);
- }
- content._features = features;
- }
- }
- Vector3DTileContent.prototype.hasProperty = function (batchId, name) {
- return this._batchTable.hasProperty(batchId, name);
- };
- Vector3DTileContent.prototype.getFeature = function (batchId) {
- //>>includeStart('debug', pragmas.debug);
- const featuresLength = this.featuresLength;
- if (!defined(batchId) || batchId < 0 || batchId >= featuresLength) {
- throw new DeveloperError(
- `batchId is required and between zero and featuresLength - 1 (${
- featuresLength - 1
- }).`
- );
- }
- //>>includeEnd('debug');
- createFeatures(this);
- return this._features[batchId];
- };
- Vector3DTileContent.prototype.applyDebugSettings = function (enabled, color) {
- if (defined(this._polygons)) {
- this._polygons.applyDebugSettings(enabled, color);
- }
- if (defined(this._polylines)) {
- this._polylines.applyDebugSettings(enabled, color);
- }
- if (defined(this._points)) {
- this._points.applyDebugSettings(enabled, color);
- }
- };
- Vector3DTileContent.prototype.applyStyle = function (style) {
- createFeatures(this);
- if (defined(this._polygons)) {
- this._polygons.applyStyle(style, this._features);
- }
- if (defined(this._polylines)) {
- this._polylines.applyStyle(style, this._features);
- }
- if (defined(this._points)) {
- this._points.applyStyle(style, this._features);
- }
- };
- Vector3DTileContent.prototype.update = function (tileset, frameState) {
- let ready = true;
- if (defined(this._polygons)) {
- this._polygons.classificationType = this._tileset.classificationType;
- this._polygons.debugWireframe = this._tileset.debugWireframe;
- this._polygons.update(frameState);
- ready = ready && this._polygons._ready;
- }
- if (defined(this._polylines)) {
- this._polylines.update(frameState);
- ready = ready && this._polylines._ready;
- }
- if (defined(this._points)) {
- this._points.update(frameState);
- ready = ready && this._points._ready;
- }
- if (defined(this._batchTable) && ready) {
- this._batchTable.update(tileset, frameState);
- }
- if (!defined(this._contentReadyPromise)) {
- const pointsPromise = defined(this._points)
- ? this._points.readyPromise
- : undefined;
- const polygonPromise = defined(this._polygons)
- ? this._polygons.readyPromise
- : undefined;
- const polylinePromise = defined(this._polylines)
- ? this._polylines.readyPromise
- : undefined;
- const that = this;
- this._contentReadyPromise = Promise.all([
- pointsPromise,
- polygonPromise,
- polylinePromise,
- ])
- .then(function () {
- that._readyPromise.resolve(that);
- })
- .catch(function (error) {
- that._readyPromise.reject(error);
- });
- }
- };
- Vector3DTileContent.prototype.getPolylinePositions = function (batchId) {
- const polylines = this._polylines;
- if (!defined(polylines)) {
- return undefined;
- }
- return polylines.getPositions(batchId);
- };
- Vector3DTileContent.prototype.isDestroyed = function () {
- return false;
- };
- Vector3DTileContent.prototype.destroy = function () {
- this._polygons = this._polygons && this._polygons.destroy();
- this._polylines = this._polylines && this._polylines.destroy();
- this._points = this._points && this._points.destroy();
- this._batchTable = this._batchTable && this._batchTable.destroy();
- return destroyObject(this);
- };
- function examineVectorLines(
- positions,
- counts,
- batchIds,
- batchTable,
- url,
- callback
- ) {
- const countsLength = counts.length;
- let polylineStart = 0;
- for (let i = 0; i < countsLength; i++) {
- const count = counts[i] * 3;
- const linePositions = positions.slice(polylineStart, polylineStart + count);
- polylineStart += count;
- callback(linePositions, batchIds[i], url, batchTable);
- }
- }
- export default Vector3DTileContent;
|