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
|
## 2.8.1
|
||||||
|
|
||||||
* Improve precision of polygon ring area calculations
|
* 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 `--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.
|
* `-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.
|
* `--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
|
### Setting or disabling tile size limits
|
||||||
|
|
||||||
|
|||||||
@@ -1364,3 +1364,65 @@ drawvec stairstep(drawvec &geom, int z, int detail) {
|
|||||||
|
|
||||||
return out;
|
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);
|
void check_polygon(drawvec &geom);
|
||||||
double get_area(const drawvec &geom, size_t i, size_t j);
|
double get_area(const drawvec &geom, size_t i, size_t j);
|
||||||
double get_mp_area(drawvec &geom);
|
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 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);
|
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},
|
{"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},
|
{"reverse-source-polygon-winding", no_argument, &prevent[P_REVERSE_SOURCE_POLYGON_WINDING], 1},
|
||||||
{"clip-bounding-box", required_argument, 0, '~'},
|
{"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},
|
{"Filtering tile contents", 0, 0, 0},
|
||||||
{"prefilter", required_argument, 0, 'C'},
|
{"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.
|
\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
|
.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.
|
\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
|
.RE
|
||||||
.SS Setting or disabling tile size limits
|
.SS Setting or disabling tile size limits
|
||||||
.RS
|
.RS
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#define A_CONVERT_NUMERIC_IDS ((int) 'I')
|
#define A_CONVERT_NUMERIC_IDS ((int) 'I')
|
||||||
#define A_HILBERT ((int) 'h')
|
#define A_HILBERT ((int) 'h')
|
||||||
#define A_VISVALINGAM ((int) 'v')
|
#define A_VISVALINGAM ((int) 'v')
|
||||||
|
#define A_GENERATE_POLYGON_LABEL_POINTS ((int) 'P')
|
||||||
|
|
||||||
#define P_SIMPLIFY ((int) 's')
|
#define P_SIMPLIFY ((int) 's')
|
||||||
#define P_SIMPLIFY_LOW ((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 (sf.geometry.size() > 0) {
|
||||||
if (partials.size() > max_tile_size) {
|
if (partials.size() > max_tile_size) {
|
||||||
// Even being maximally conservative, each feature is still going to be
|
// Even being maximally conservative, each feature is still going to be
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
#ifndef VERSION_HPP
|
#ifndef VERSION_HPP
|
||||||
#define VERSION_HPP
|
#define VERSION_HPP
|
||||||
|
|
||||||
#define VERSION "v2.8.1"
|
#define VERSION "v2.9.0"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user