data/MapClusterer.h
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #pragma once | ||
| 2 | |||
| 3 | #include <QList> | ||
| 4 | #include <QPointF> | ||
| 5 | #include <QRectF> | ||
| 6 | #include <QString> | ||
| 7 | #include <QStringList> | ||
| 8 | |||
| 9 | // Marker clustering of the world map (Sprint 103 S103.4.4): deterministic | ||
| 10 | // grid clustering per zoom level. Places are grouped by the grid cell of | ||
| 11 | // `cellPixels` logical pixels they fall into at the zoom; a cluster sits at | ||
| 12 | // the mean of its members, its id is the smallest member id (stable while | ||
| 13 | // zooming, used for animation and focus). Pure; the same input gives the same | ||
| 14 | // clusters in the same order (G11): sorted west → east, then north → south. | ||
| 15 | namespace MapClusterer { | ||
| 16 | |||
| 17 | struct Place { | ||
| 18 | QString id; // "<card key>|<kind>|<position>" | ||
| 19 | QPointF world; // MapProjection::project() | ||
| 20 | bool operator==(const Place &) const = default; | ||
| 21 | }; | ||
| 22 | |||
| 23 | struct Cluster { | ||
| 24 | QString id; | ||
| 25 | QPointF world; // mean of the members | ||
| 26 | QRectF bounds; // world bounding box of the members | ||
| 27 | QStringList members; // place ids, sorted | ||
| 28 | bool sameSpot = false; // every member at (nearly) one point | ||
| 29 | 165 | int size() const { return int(members.size()); } | |
| 30 | bool operator==(const Cluster &) const = default; | ||
| 31 | }; | ||
| 32 | |||
| 33 | QList<Cluster> cluster(const QList<Place> &places, double zoom, double cellPixels = 64.0); | ||
| 34 | |||
| 35 | } // namespace MapClusterer | ||
| 36 |