SPB Git

spb/ka-maps

Public

Clusters : option valueMinCount — la valeur sous la bulle n'apparaît que pour les bulles significatives (cartes denses)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Simon-Pierre Boucher committed (Aug 26, 2026) parent a901e75 Browse files

2 changed files +23 −3

modified src/core/KaMap.ts +12 −2
@@ -81,7 +81,13 @@ export interface KaMapOptions {
81 /** Clustering tuning. Lou-Ka style per-building geocoding wants 81 /** Clustering tuning. Lou-Ka style per-building geocoding wants
82 * maxZoom 15 so stacked units stay grouped as long as possible. 82 * maxZoom 15 so stacked units stay grouped as long as possible.
83 * `valueClamp` bounds each item's contribution to the bubble mean. */ 83 * `valueClamp` bounds each item's contribution to the bubble mean. */
84− cluster?: { maxZoom?: number; radius?: number; valueClamp?: [number, number] }; 84+ cluster?: {
85+ maxZoom?: number;
86+ radius?: number;
87+ valueClamp?: [number, number];
88+ /** N minimal d'items pour afficher la valeur sous une bulle. */
89+ valueMinCount?: number;
90+ };
85 } 91 }
86 92
87 const EMPTY_FC: GeoJSON.FeatureCollection = { 93 const EMPTY_FC: GeoJSON.FeatureCollection = {
@@ -133,6 +139,7 @@ export class KaMap {
133 maxZoom: number; 139 maxZoom: number;
134 radius: number; 140 radius: number;
135 valueClamp?: [number, number]; 141 valueClamp?: [number, number];
142+ valueMinCount?: number;
136 }; 143 };
137 144
138 /** Mouvement en cours déclenché par le code (fitBounds, easeTo interne) : 145 /** Mouvement en cours déclenché par le code (fitBounds, easeTo interne) :
@@ -166,6 +173,7 @@ export class KaMap {
166 maxZoom: Math.round(options.cluster?.maxZoom ?? 14), 173 maxZoom: Math.round(options.cluster?.maxZoom ?? 14),
167 radius: options.cluster?.radius ?? 46, 174 radius: options.cluster?.radius ?? 46,
168 valueClamp: options.cluster?.valueClamp, 175 valueClamp: options.cluster?.valueClamp,
176+ valueMinCount: options.cluster?.valueMinCount,
169 }; 177 };
170 178
171 this.map = new mapboxgl.Map({ 179 this.map = new mapboxgl.Map({
@@ -296,7 +304,9 @@ export class KaMap {
296 // hachés par propertiesToGeoJSON) 304 // hachés par propertiesToGeoJSON)
297 }); 305 });
298 } 306 }
299− for (const layer of buildPropertyLayers(this.theme, this.sourceId)) { 307+ for (const layer of buildPropertyLayers(this.theme, this.sourceId, {
308+ valueMinCount: this.clusterOptions.valueMinCount,
309+ })) {
300 if (!map.getLayer(layer.id)) map.addLayer(layer); 310 if (!map.getLayer(layer.id)) map.addLayer(layer);
301 } 311 }
302 this.installDrawLayers(); 312 this.installDrawLayers();
modified src/layers/propertyLayer.ts +11 −1
@@ -222,6 +222,11 @@ function familyColorExpressions(theme: KaMapTheme): FamilyColors {
222 export function buildPropertyLayers( 222 export function buildPropertyLayers(
223 theme: KaMapTheme, 223 theme: KaMapTheme,
224 sourceId: string = PROPERTY_SOURCE_ID, 224 sourceId: string = PROPERTY_SOURCE_ID,
225+ opts?: {
226+ /** N minimal d'items pour afficher la valeur sous la bulle — cartes
227+ * denses (Immo-Ka) : éviter un ≈prix sous chaque micro-bulle. */
228+ valueMinCount?: number;
229+ },
225 ): (SymbolLayerSpecification | CircleLayerSpecification)[] { 230 ): (SymbolLayerSpecification | CircleLayerSpecification)[] {
226 const colors = familyColorExpressions(theme); 231 const colors = familyColorExpressions(theme);
227 const dimmed: ExpressionSpecification = ["boolean", ["feature-state", "dimmed"], false]; 232 const dimmed: ExpressionSpecification = ["boolean", ["feature-state", "dimmed"], false];
@@ -307,7 +312,12 @@ export function buildPropertyLayers(
307 slot: "top", 312 slot: "top",
308 type: "symbol", 313 type: "symbol",
309 source: sourceId, 314 source: sourceId,
310− filter: ["all", ["has", "point_count"], [">", ["to-number", ["get", "valueCount"]], 0]], 315+ filter: [
316+ "all",
317+ ["has", "point_count"],
318+ [">", ["to-number", ["get", "valueCount"]], 0],
319+ [">=", ["to-number", ["get", "point_count"]], opts?.valueMinCount ?? 0],
320+ ],
311 minzoom: 9, 321 minzoom: 9,
312 layout: { 322 layout: {
313 "text-field": [ 323 "text-field": [
314 324
Menu

Theme