Skip to content

Commit 0f1982a

Browse files
committed
Add --cluster-maxzoom option
1 parent 18e53cd commit 0f1982a

File tree

4 files changed

+25
-5
lines changed

4 files changed

+25
-5
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,8 @@ the same layer, enclose them in an `all` expression so they will all be evaluate
469469
* `-al` or `--drop-lines`: Let "dot" dropping at lower zooms apply to lines too
470470
* `-ap` or `--drop-polygons`: Let "dot" dropping at lower zooms apply to polygons too
471471
* `-K` _distance_ or `--cluster-distance=`_distance_: Cluster points (as with `--cluster-densest-as-needed`, but without the experimental discovery process) that are approximately within _distance_ of each other. The units are tile coordinates within a nominally 256-pixel tile, so the maximum value of 255 allows only one feature per tile. Values around 10 are probably appropriate for typical marker sizes. See `--cluster-densest-as-needed` below for behavior.
472+
* `-k` _zoom_ or `--cluster-maxzoom=`_zoom_: Max zoom on which to cluster points if clustering is enabled.
473+
* `-kg` or `--cluster-maxzoom=g`: Set `--cluster-maxzoom=` to `maxzoom - 1` so that all features are visible at the maximum zoom level.
472474

473475
### Dropping a fraction of features to keep under tile size limits
474476

main.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ double simplification = 1;
7575
size_t max_tile_size = 500000;
7676
size_t max_tile_features = 200000;
7777
int cluster_distance = 0;
78+
int cluster_maxzoom = MAX_ZOOM;
7879
long justx = -1, justy = -1;
7980
std::string attribute_for_id = "";
8081

@@ -1135,7 +1136,7 @@ void choose_first_zoom(long long *file_bbox, std::vector<struct reader> &readers
11351136
}
11361137
}
11371138

1138-
int read_input(std::vector<source> &sources, char *fname, int maxzoom, int minzoom, int basezoom, double basezoom_marker_width, sqlite3 *outdb, const char *outdir, std::set<std::string> *exclude, std::set<std::string> *include, int exclude_all, json_object *filter, double droprate, int buffer, const char *tmpdir, double gamma, int read_parallel, int forcetable, const char *attribution, bool uses_gamma, long long *file_bbox, const char *prefilter, const char *postfilter, const char *description, bool guess_maxzoom, std::map<std::string, int> const *attribute_types, const char *pgm, std::map<std::string, attribute_op> const *attribute_accum, std::map<std::string, std::string> const &attribute_descriptions, std::string const &commandline) {
1139+
int read_input(std::vector<source> &sources, char *fname, int maxzoom, int minzoom, int basezoom, double basezoom_marker_width, sqlite3 *outdb, const char *outdir, std::set<std::string> *exclude, std::set<std::string> *include, int exclude_all, json_object *filter, double droprate, int buffer, const char *tmpdir, double gamma, int read_parallel, int forcetable, const char *attribution, bool uses_gamma, long long *file_bbox, const char *prefilter, const char *postfilter, const char *description, bool guess_maxzoom, bool guess_cluster_maxzoom, std::map<std::string, int> const *attribute_types, const char *pgm, std::map<std::string, attribute_op> const *attribute_accum, std::map<std::string, std::string> const &attribute_descriptions, std::string const &commandline) {
11391140
int ret = EXIT_SUCCESS;
11401141

11411142
std::vector<struct reader> readers;
@@ -1985,7 +1986,7 @@ int read_input(std::vector<source> &sources, char *fname, int maxzoom, int minzo
19851986
}
19861987

19871988
bool changed = false;
1988-
while (maxzoom < 32 - full_detail && maxzoom < 33 - low_detail && cluster_distance > 0) {
1989+
while (maxzoom < 32 - full_detail && maxzoom < 33 - low_detail && maxzoom < cluster_maxzoom && cluster_distance > 0) {
19891990
unsigned long long zoom_mingap = ((1LL << (32 - maxzoom)) / 256 * cluster_distance) * ((1LL << (32 - maxzoom)) / 256 * cluster_distance);
19901991
if (avg > zoom_mingap) {
19911992
break;
@@ -1995,7 +1996,7 @@ int read_input(std::vector<source> &sources, char *fname, int maxzoom, int minzo
19951996
changed = true;
19961997
}
19971998
if (changed) {
1998-
printf("Choosing a maxzoom of -z%d to keep most features distinct with cluster distance %d\n", maxzoom, cluster_distance);
1999+
printf("Choosing a maxzoom of -z%d to keep most features distinct with cluster distance %d and cluster maxzoom %d\n", maxzoom, cluster_distance, cluster_maxzoom);
19992000
}
20002001
}
20012002

@@ -2033,6 +2034,11 @@ int read_input(std::vector<source> &sources, char *fname, int maxzoom, int minzo
20332034
}
20342035
}
20352036

2037+
if (cluster_maxzoom >= maxzoom && guess_cluster_maxzoom) {
2038+
cluster_maxzoom = maxzoom - 1;
2039+
fprintf(stderr, "Choosing a cluster maxzoom of -k%d to make all features visible at maximum zoom %d\n", cluster_maxzoom, maxzoom);
2040+
}
2041+
20362042
if (basezoom < 0 || droprate < 0) {
20372043
struct tile {
20382044
unsigned x;
@@ -2478,6 +2484,7 @@ int main(int argc, char **argv) {
24782484
const char *prefilter = NULL;
24792485
const char *postfilter = NULL;
24802486
bool guess_maxzoom = false;
2487+
bool guess_cluster_maxzoom = false;
24812488

24822489
std::set<std::string> exclude, include;
24832490
std::map<std::string, int> attribute_types;
@@ -2549,6 +2556,7 @@ int main(int argc, char **argv) {
25492556
{"drop-lines", no_argument, &additional[A_LINE_DROP], 1},
25502557
{"drop-polygons", no_argument, &additional[A_POLYGON_DROP], 1},
25512558
{"cluster-distance", required_argument, 0, 'K'},
2559+
{"cluster-maxzoom", required_argument, 0, 'k'},
25522560

25532561
{"Dropping or merging a fraction of features to keep under tile size limits", 0, 0, 0},
25542562
{"drop-densest-as-needed", no_argument, &additional[A_DROP_DENSEST_AS_NEEDED], 1},
@@ -2795,6 +2803,15 @@ int main(int argc, char **argv) {
27952803
}
27962804
break;
27972805

2806+
case 'k':
2807+
if (strcmp(optarg, "g") == 0) {
2808+
cluster_maxzoom = MAX_ZOOM - 1;
2809+
guess_cluster_maxzoom = true;
2810+
} else {
2811+
cluster_maxzoom = atoi_require(optarg, "Cluster maxzoom");
2812+
}
2813+
break;
2814+
27982815
case 'd':
27992816
full_detail = atoi_require(optarg, "Full detail");
28002817
if (full_detail > 30) {
@@ -3180,7 +3197,7 @@ int main(int argc, char **argv) {
31803197

31813198
long long file_bbox[4] = {UINT_MAX, UINT_MAX, 0, 0};
31823199

3183-
ret = read_input(sources, name ? name : out_mbtiles ? out_mbtiles : out_dir, maxzoom, minzoom, basezoom, basezoom_marker_width, outdb, out_dir, &exclude, &include, exclude_all, filter, droprate, buffer, tmpdir, gamma, read_parallel, forcetable, attribution, gamma != 0, file_bbox, prefilter, postfilter, description, guess_maxzoom, &attribute_types, argv[0], &attribute_accum, attribute_descriptions, commandline);
3200+
ret = read_input(sources, name ? name : out_mbtiles ? out_mbtiles : out_dir, maxzoom, minzoom, basezoom, basezoom_marker_width, outdb, out_dir, &exclude, &include, exclude_all, filter, droprate, buffer, tmpdir, gamma, read_parallel, forcetable, attribution, gamma != 0, file_bbox, prefilter, postfilter, description, guess_maxzoom, guess_cluster_maxzoom, &attribute_types, argv[0], &attribute_accum, attribute_descriptions, commandline);
31843201

31853202
if (outdb != NULL) {
31863203
mbtiles_close(outdb, argv[0]);

main.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ extern size_t TEMP_FILES;
4747
extern size_t max_tile_size;
4848
extern size_t max_tile_features;
4949
extern int cluster_distance;
50+
extern int cluster_maxzoom;
5051
extern std::string attribute_for_id;
5152

5253
int mkstemp_cloexec(char *name);

tile.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1881,7 +1881,7 @@ long long write_tile(FILE *geoms, std::atomic<long long> *geompos_in, char *meta
18811881
}
18821882
}
18831883

1884-
if (additional[A_CLUSTER_DENSEST_AS_NEEDED] || cluster_distance != 0) {
1884+
if (z <= cluster_maxzoom && (additional[A_CLUSTER_DENSEST_AS_NEEDED] || cluster_distance != 0)) {
18851885
indices.push_back(sf.index);
18861886
if ((sf.index < merge_previndex || sf.index - merge_previndex < mingap) && find_partial(partials, sf, which_partial, layer_unmaps)) {
18871887
partials[which_partial].clustered++;

0 commit comments

Comments
 (0)