diff --git a/3d-style/data/bucket/model_bucket.ts b/3d-style/data/bucket/model_bucket.ts index fbe3dd8b481..638693a98c4 100644 --- a/3d-style/data/bucket/model_bucket.ts +++ b/3d-style/data/bucket/model_bucket.ts @@ -342,6 +342,7 @@ class ModelBucket implements Bucket { ): string { const layer = this.layers[0]; const modelIdProperty = layer.layout.get('model-id'); + const modelAllowDensityReductionProperty = layer.layout.get('model-allow-density-reduction'); assert(modelIdProperty); const modelId = modelIdProperty.evaluate(evaluationFeature, {}, this.canonical); @@ -371,14 +372,16 @@ class ModelBucket implements Bucket { if (point.x < 0 || point.x >= EXTENT || point.y < 0 || point.y >= EXTENT) { continue; // Clip on tile borders to prevent duplicates } - // reduce density - const tileToLookup = (this.lookupDim - 1.0) / EXTENT; - const lookupIndex = this.lookupDim * ((point.y * tileToLookup) | 0) + (point.x * tileToLookup) | 0; - if (this.lookup) { - if (this.lookup[lookupIndex] !== 0) { - continue; + if (modelAllowDensityReductionProperty) { + // reduce density + const tileToLookup = (this.lookupDim - 1.0) / EXTENT; + const lookupIndex = this.lookupDim * ((point.y * tileToLookup) | 0) + (point.x * tileToLookup) | 0; + if (this.lookup) { + if (this.lookup[lookupIndex] !== 0) { + continue; + } + this.lookup[lookupIndex] = 1; } - this.lookup[lookupIndex] = 1; } this.instanceCount++; const i = instancedDataArray.length; diff --git a/3d-style/style/style_layer/model_style_layer_properties.ts b/3d-style/style/style_layer/model_style_layer_properties.ts index 23a450dbad3..22bb4518ca0 100644 --- a/3d-style/style/style_layer/model_style_layer_properties.ts +++ b/3d-style/style/style_layer/model_style_layer_properties.ts @@ -19,11 +19,13 @@ import type {StylePropertySpecification} from '../../../src/style-spec/style-spe export type LayoutProps = { "visibility": DataConstantProperty<"visible" | "none">; "model-id": DataDrivenProperty; + "model-allow-density-reduction": DataConstantProperty; }; let layout: Properties; export const getLayoutProperties = (): Properties => layout || (layout = new Properties({ "visibility": new DataConstantProperty(styleSpec["layout_model"]["visibility"]), "model-id": new DataDrivenProperty(styleSpec["layout_model"]["model-id"]), + "model-allow-density-reduction": new DataConstantProperty(styleSpec["layout_model"]["model-allow-density-reduction"]), })); export type PaintProps = { diff --git a/src/style-spec/reference/v8.json b/src/style-spec/reference/v8.json index d1fe597132c..e5d03c1cb7e 100644 --- a/src/style-spec/reference/v8.json +++ b/src/style-spec/reference/v8.json @@ -1578,6 +1578,20 @@ "vector" ] }] + }, + "model-allow-density-reduction": { + "type": "boolean", + "default": true, + "transition": false, + "doc": "If true, the models will be reduced in density based on the zoom level. This is useful for large datasets that may be slow to render.", + "sdk-support": { + "basic functionality": { + "js": "0.10.0", + "android": "2.0.1", + "ios": "2.0.0" + } + }, + "property-type": "data-constant" } }, "layout_clip": { diff --git a/src/style-spec/types.ts b/src/style-spec/types.ts index 4b6b5a62809..727238863e1 100644 --- a/src/style-spec/types.ts +++ b/src/style-spec/types.ts @@ -1065,7 +1065,8 @@ export type ModelLayerSpecification = { "filter"?: FilterSpecification, "layout"?: { "visibility"?: "visible" | "none" | ExpressionSpecification, - "model-id"?: DataDrivenPropertyValueSpecification + "model-id"?: DataDrivenPropertyValueSpecification, + "model-allow-density-reduction"?: boolean }, "paint"?: { "model-opacity"?: DataDrivenPropertyValueSpecification,