Business clustering
editorial(services): rewrite service-business-clustering (Track-B) — confirmed no service-business/service-business-clustering crate in project-editorial's own pointsav-monorepo checkout (consistent with the applications/app-orchestration-gis finding this session); checked project-gis's own divergent checkout and found a real cluster-entities.py, but with materially different thresholds (200m same-chain, 50m cross-brand) than the article's claimed 100m/1km-grid/DBSCAN — none of the specific numbers hold in either tree; genericized per the public-repo-safety-review.md 4-category boundary (proprietary methodology) and the site-selection/ precedent, dropping specific thresholds and internal script filenames while keeping the real parent-child concept; dropped the unconfirmed service-places-filtering cross-reference; register-clean EN+ES
@@ -1,6 +1,6 @@ --- schema: foundry-doc-v1 title: "Business clustering service" title: "Business clustering" slug: service-business-clustering category: services type: topic @@ -9,49 +9,26 @@ quality: complete index_group: specialist-and-domain-services status: active audience: public short_description: "Parent-child spatial schema turning raw retail points into commercial clusters, so the GIS engine receives one entity per physical site instead of overlapping points." short_description: "A parent-child spatial pattern that turns raw retail points into one commercial entity per physical site, so the GIS pipeline reasons about a location once instead of once per co-located tenant." bcsc_class: public-disclosure-safe language_protocol: PROSE-TOPIC last_edited: 2026-05-25 last_edited: 2026-08-22 editor: pointsav-engineering paired_with: service-business-clustering.es.md cites: [] --- **Correction (2026-08-02, verified against canonical `origin/main`):** `service-business-clustering`/`service-business` doesn't exist as a real crate anywhere in the monorepo — already flagged twice this session. The real implementation is a Python pipeline in the separate `project-gis` archive. Unlike the sibling article `service-fs-data-lake.md`, which already hedges this correctly ("not yet built... no dedicated service-business/service-places crates confirmed"), this article presents it with unqualified present-tense claims. **Flagged, not resolved.** Retail data is inherently messy — a single commercial site often contains multiple distinct points, such as a big-box anchor, a nested pharmacy, and a fuel outlet sharing the same parking area. The platform's business-clustering step turns those raw points into commercial clusters using a parent-child pattern, so downstream GIS analysis reasons about one unified commercial entity per physical site rather than several overlapping records. Retail data is inherently messy — a single commercial site often contains multiple distinct points, such as a big-box anchor, a nested pharmacy, and a fuel outlet sharing the same parking area. **`service-business`** turns those raw points into actionable commercial clusters using a parent-child spatial schema, so the GIS engine receives one unified commercial entity per physical site rather than several overlapping records. The service iterates the `service-fs` raw data lake, groups entities that share a footprint within a 100 m proximity threshold, and assigns the highest-weight named anchor as the parent. ## The parent-child pattern ## Key Takeaways Points that plausibly belong to the same physical site are merged in a small number of proximity-based passes, using different distance thresholds depending on whether the points share an identifying signal (the same retail chain, for example) or only a brand-level match. The highest-weight named point at a merged site becomes the parent record; the rest become children. Without this step, several co-located tenants at one site would each count as an independent signal in downstream scoring, overstating that location's commercial weight. - `service-business` uses a grid-based spatial index at roughly 1 km cell resolution to group raw retail points. Points within 100 m of each other are collapsed into one commercial cluster before any tier score is computed. - The parent-child schema assigns the highest-weight named anchor as the parent. Every other operator at the same site becomes a child record. Without this step, co-located fuel outlets and pharmacies would each count as independent tier signals. - Output is `cleansed-clusters.jsonl`, consumed directly by `[[app-orchestration-gis]]` when building the regional co-location index. The clustering step is the boundary between raw POI data and ranked commercial intelligence. - The 100 m proximity threshold is calibrated for large-format retail parks — close enough to capture genuine co-location, far enough to separate adjacent but structurally distinct shopping destinations. ## Where this fits in the pipeline ## The Clustering Logic `service-business` processes raw commercial nodes so that the GIS engine produces a single, unified commercial entity per physical site. ### Grid-Based Spatial Indexing To perform this at scale, the service uses a grid-based spatial index (approximately 1 km cells). It iterates through the `service-fs` raw data lake and groups entities that share a physical footprint within a 100 m proximity threshold. ### Parent-Child Schema - **Parent node:** The primary commercial driver — typically the highest-weight named anchor at the site. - **Children (sub-entities):** Secondary operators located within the same spatial node. ## Cleansed Data Output The output is a refined `cleansed-clusters.jsonl` file. This processed dataset is consumed by the downstream `app-orchestration-gis` to build the regional co-location index. Clustering runs as part of the same Python-based GIS pipeline documented in [[app-orchestration-gis]] — the code that turns raw geographic and business data into the regional co-location index — rather than as a separately deployed service. This article does not restate the pipeline's specific distance thresholds or internal script names; the general pattern (merge co-located points, promote the strongest anchor to parent) is the stable, public-facing part of the design. ## See also - [[app-orchestration-gis]] - [[service-fs-data-lake]] - [[service-places-filtering]] ## References - [DBSCAN](https://en.wikipedia.org/wiki/DBSCAN) — Wikipedia, accessed 2026-06-14 - [[app-orchestration-gis]] — the pipeline this clustering step is part of - [[service-fs-data-lake]] — the raw data this step consumes