Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add --cluster-maxzoom option #33

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,8 @@ the same layer, enclose them in an `all` expression so they will all be evaluate
* `-al` or `--drop-lines`: Let "dot" dropping at lower zooms apply to lines too
* `-ap` or `--drop-polygons`: Let "dot" dropping at lower zooms apply to polygons too
* `-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.
* `-k` _zoom_ or `--cluster-maxzoom=`_zoom_: Max zoom on which to cluster points if clustering is enabled.
* `-kg` or `--cluster-maxzoom=g`: Set `--cluster-maxzoom=` to `maxzoom - 1` so that all features are visible at the maximum zoom level.

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

Expand Down
25 changes: 21 additions & 4 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ double simplification = 1;
size_t max_tile_size = 500000;
size_t max_tile_features = 200000;
int cluster_distance = 0;
int cluster_maxzoom = MAX_ZOOM;
long justx = -1, justy = -1;
std::string attribute_for_id = "";

Expand Down Expand Up @@ -1135,7 +1136,7 @@ void choose_first_zoom(long long *file_bbox, std::vector<struct reader> &readers
}
}

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) {
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) {
int ret = EXIT_SUCCESS;

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

bool changed = false;
while (maxzoom < 32 - full_detail && maxzoom < 33 - low_detail && cluster_distance > 0) {
while (maxzoom < 32 - full_detail && maxzoom < 33 - low_detail && maxzoom < cluster_maxzoom && cluster_distance > 0) {
unsigned long long zoom_mingap = ((1LL << (32 - maxzoom)) / 256 * cluster_distance) * ((1LL << (32 - maxzoom)) / 256 * cluster_distance);
if (avg > zoom_mingap) {
break;
Expand All @@ -1995,7 +1996,7 @@ int read_input(std::vector<source> &sources, char *fname, int maxzoom, int minzo
changed = true;
}
if (changed) {
printf("Choosing a maxzoom of -z%d to keep most features distinct with cluster distance %d\n", maxzoom, cluster_distance);
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);
}
}

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

if (cluster_maxzoom >= maxzoom && guess_cluster_maxzoom) {
cluster_maxzoom = maxzoom - 1;
fprintf(stderr, "Choosing a cluster maxzoom of -k%d to make all features visible at maximum zoom %d\n", cluster_maxzoom, maxzoom);
}

if (basezoom < 0 || droprate < 0) {
struct tile {
unsigned x;
Expand Down Expand Up @@ -2478,6 +2484,7 @@ int main(int argc, char **argv) {
const char *prefilter = NULL;
const char *postfilter = NULL;
bool guess_maxzoom = false;
bool guess_cluster_maxzoom = false;

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

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

case 'k':
if (strcmp(optarg, "g") == 0) {
cluster_maxzoom = MAX_ZOOM - 1;
guess_cluster_maxzoom = true;
} else {
cluster_maxzoom = atoi_require(optarg, "Cluster maxzoom");
}
break;

case 'd':
full_detail = atoi_require(optarg, "Full detail");
if (full_detail > 30) {
Expand Down Expand Up @@ -3180,7 +3197,7 @@ int main(int argc, char **argv) {

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

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);
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);

if (outdb != NULL) {
mbtiles_close(outdb, argv[0]);
Expand Down
1 change: 1 addition & 0 deletions main.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ extern size_t TEMP_FILES;
extern size_t max_tile_size;
extern size_t max_tile_features;
extern int cluster_distance;
extern int cluster_maxzoom;
extern std::string attribute_for_id;

int mkstemp_cloexec(char *name);
Expand Down
2 changes: 1 addition & 1 deletion tile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1881,7 +1881,7 @@ long long write_tile(FILE *geoms, std::atomic<long long> *geompos_in, char *meta
}
}

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