mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-02 08:25:40 +02:00
Add an option to generate label points in place of polygons
This commit is contained in:
@@ -1,3 +1,7 @@
|
||||
## 2.9.0
|
||||
|
||||
* Add an option to generate label points in place of polygons
|
||||
|
||||
## 2.8.1
|
||||
|
||||
* Improve precision of polygon ring area calculations
|
||||
|
||||
@@ -518,6 +518,7 @@ the same layer, enclose them in an `all` expression so they will all be evaluate
|
||||
* `-pw` or `--use-source-polygon-winding`: Instead of respecting GeoJSON polygon ring order, use the original polygon winding in the source data to distinguish inner (clockwise) and outer (counterclockwise) polygon rings.
|
||||
* `-pW` or `--reverse-source-polygon-winding`: Instead of respecting GeoJSON polygon ring order, use the opposite of the original polygon winding in the source data to distinguish inner (counterclockwise) and outer (clockwise) polygon rings.
|
||||
* `--clip-bounding-box=`*minlon*`,`*minlat*`,`*maxlon*`,`*maxlat*: Clip all features to the specified bounding box.
|
||||
* `-aP` or `--convert-polygons-to-label-points`: Replace polygon geometries with a label point or points for the polygon in each tile it intersects.
|
||||
|
||||
### Setting or disabling tile size limits
|
||||
|
||||
|
||||
@@ -1364,3 +1364,65 @@ drawvec stairstep(drawvec &geom, int z, int detail) {
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
struct polygon_label {
|
||||
long long size;
|
||||
draw point;
|
||||
|
||||
bool operator<(const polygon_label &o) const {
|
||||
return size > o.size; // reverse sort, largest first
|
||||
}
|
||||
};
|
||||
|
||||
// Generate a label point for a polygon feature, currently at the centroid of its largest-area
|
||||
// outer ring within the tile.
|
||||
drawvec polygon_to_anchor(const drawvec &geom) {
|
||||
std::vector<polygon_label> labels;
|
||||
drawvec dv;
|
||||
|
||||
for (size_t i = 0; i < geom.size(); i++) {
|
||||
if (geom[i].op == VT_MOVETO) {
|
||||
size_t j;
|
||||
for (j = i + 1; j < geom.size(); j++) {
|
||||
if (geom[j].op != VT_LINETO) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
long long xsum = 0;
|
||||
long long ysum = 0;
|
||||
size_t count = 0;
|
||||
|
||||
double area = get_area(geom, i, j);
|
||||
if (area > 0) { // don't generate anchors for holes
|
||||
// i + 1 to exclude the first point, which is duplicated as the last
|
||||
for (size_t k = i + 1; k < j; k++) {
|
||||
xsum += geom[k].x;
|
||||
ysum += geom[k].y;
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
draw d(VT_MOVETO, xsum / count, ysum / count);
|
||||
|
||||
polygon_label pl;
|
||||
pl.size = area;
|
||||
pl.point = d;
|
||||
|
||||
labels.push_back(pl);
|
||||
}
|
||||
}
|
||||
|
||||
i = j - 1;
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(labels.begin(), labels.end());
|
||||
|
||||
if (labels.size() > 0) {
|
||||
dv.push_back(labels[0].point);
|
||||
}
|
||||
|
||||
return dv;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@ std::vector<drawvec> chop_polygon(std::vector<drawvec> &geoms);
|
||||
void check_polygon(drawvec &geom);
|
||||
double get_area(const drawvec &geom, size_t i, size_t j);
|
||||
double get_mp_area(drawvec &geom);
|
||||
drawvec polygon_to_anchor(const drawvec &geom);
|
||||
|
||||
drawvec simple_clip_poly(drawvec &geom, long long x1, long long y1, long long x2, long long y2);
|
||||
drawvec clip_lines(drawvec &geom, long long x1, long long y1, long long x2, long long y2);
|
||||
|
||||
@@ -2761,6 +2761,7 @@ int main(int argc, char **argv) {
|
||||
{"use-source-polygon-winding", no_argument, &prevent[P_USE_SOURCE_POLYGON_WINDING], 1},
|
||||
{"reverse-source-polygon-winding", no_argument, &prevent[P_REVERSE_SOURCE_POLYGON_WINDING], 1},
|
||||
{"clip-bounding-box", required_argument, 0, '~'},
|
||||
{"convert-polygons-to-label-points", no_argument, &additional[A_GENERATE_POLYGON_LABEL_POINTS], 1},
|
||||
|
||||
{"Filtering tile contents", 0, 0, 0},
|
||||
{"prefilter", required_argument, 0, 'C'},
|
||||
|
||||
@@ -671,6 +671,8 @@ the line or polygon within one tile unit of its proper location. You can probabl
|
||||
\fB\fC\-pW\fR or \fB\fC\-\-reverse\-source\-polygon\-winding\fR: Instead of respecting GeoJSON polygon ring order, use the opposite of the original polygon winding in the source data to distinguish inner (counterclockwise) and outer (clockwise) polygon rings.
|
||||
.IP \(bu 2
|
||||
\fB\fC\-\-clip\-bounding\-box=\fR\fIminlon\fP\fB\fC,\fR\fIminlat\fP\fB\fC,\fR\fImaxlon\fP\fB\fC,\fR\fImaxlat\fP: Clip all features to the specified bounding box.
|
||||
.IP \(bu 2
|
||||
\fB\fC\-aP\fR or \fB\fC\-\-convert\-polygons\-to\-label\-points\fR: Replace polygon geometries with a label point or points for the polygon in each tile it intersects.
|
||||
.RE
|
||||
.SS Setting or disabling tile size limits
|
||||
.RS
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define A_CONVERT_NUMERIC_IDS ((int) 'I')
|
||||
#define A_HILBERT ((int) 'h')
|
||||
#define A_VISVALINGAM ((int) 'v')
|
||||
#define A_GENERATE_POLYGON_LABEL_POINTS ((int) 'P')
|
||||
|
||||
#define P_SIMPLIFY ((int) 's')
|
||||
#define P_SIMPLIFY_LOW ((int) 'S')
|
||||
|
||||
@@ -2076,6 +2076,11 @@ long long write_tile(FILE *geoms, std::atomic<long long> *geompos_in, char *meta
|
||||
}
|
||||
}
|
||||
|
||||
if (sf.t == VT_POLYGON && additional[A_GENERATE_POLYGON_LABEL_POINTS]) {
|
||||
sf.t = VT_POINT;
|
||||
sf.geometry = polygon_to_anchor(sf.geometry);
|
||||
}
|
||||
|
||||
if (sf.geometry.size() > 0) {
|
||||
if (partials.size() > max_tile_size) {
|
||||
// Even being maximally conservative, each feature is still going to be
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#ifndef VERSION_HPP
|
||||
#define VERSION_HPP
|
||||
|
||||
#define VERSION "v2.8.1"
|
||||
#define VERSION "v2.9.0"
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user