mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-02 16:35:40 +02:00
Clip label spirals to the feature bounds
This commit is contained in:
+1
-2
@@ -22,7 +22,6 @@
|
||||
#include "options.hpp"
|
||||
#include "errors.hpp"
|
||||
|
||||
static int pnpoly(const drawvec &vert, size_t start, size_t nvert, long long testx, long long testy);
|
||||
static int clip(double *x0, double *y0, double *x1, double *y1, double xmin, double ymin, double xmax, double ymax);
|
||||
|
||||
drawvec decode_geometry(FILE *meta, std::atomic<long long> *geompos, int z, unsigned tx, unsigned ty, long long *bbox, unsigned initial_x, unsigned initial_y) {
|
||||
@@ -411,7 +410,7 @@ The name of W. Randolph Franklin may not be used to endorse or promote products
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
static int pnpoly(const drawvec &vert, size_t start, size_t nvert, long long testx, long long testy) {
|
||||
int pnpoly(const drawvec &vert, size_t start, size_t nvert, long long testx, long long testy) {
|
||||
size_t i, j;
|
||||
bool c = false;
|
||||
for (i = 0, j = nvert - 1; i < nvert; j = i++) {
|
||||
|
||||
@@ -82,5 +82,6 @@ drawvec simple_clip_poly(drawvec &geom, long long x1, long long y1, long long x2
|
||||
drawvec clip_lines(drawvec &geom, long long x1, long long y1, long long x2, long long y2);
|
||||
drawvec clip_point(drawvec &geom, long long x1, long long y1, long long x2, long long y2);
|
||||
void visvalingam(drawvec &ls, size_t start, size_t end, double threshold, size_t retain);
|
||||
int pnpoly(const drawvec &vert, size_t start, size_t nvert, long long testx, long long testy);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -324,7 +324,7 @@ struct ordercmp {
|
||||
}
|
||||
} ordercmp;
|
||||
|
||||
void rewrite(drawvec &geom, int z, int nextzoom, int maxzoom, long long *bbox, unsigned tx, unsigned ty, int buffer, int *within, std::atomic<long long> *geompos, FILE **geomfile, const char *fname, signed char t, int layer, long long metastart, signed char feature_minzoom, int child_shards, int max_zoom_increment, long long seq, int tippecanoe_minzoom, int tippecanoe_maxzoom, int segment, unsigned *initial_x, unsigned *initial_y, std::vector<long long> &metakeys, std::vector<long long> &metavals, bool has_id, unsigned long long id, unsigned long long index, long long extent) {
|
||||
void rewrite(drawvec &geom, int z, int nextzoom, int maxzoom, long long *bbox, unsigned tx, unsigned ty, int buffer, int *within, std::atomic<long long> *geompos, FILE **geomfile, const char *fname, signed char t, int layer, long long metastart, signed char feature_minzoom, int child_shards, int max_zoom_increment, long long seq, int tippecanoe_minzoom, int tippecanoe_maxzoom, int segment, unsigned *initial_x, unsigned *initial_y, std::vector<long long> &metakeys, std::vector<long long> &metavals, bool has_id, unsigned long long id, unsigned long long index, unsigned long long label_point, long long extent) {
|
||||
if (geom.size() > 0 && (nextzoom <= maxzoom || additional[A_EXTEND_ZOOMS])) {
|
||||
int xo, yo;
|
||||
int span = 1 << (nextzoom - z);
|
||||
@@ -414,6 +414,7 @@ void rewrite(drawvec &geom, int z, int nextzoom, int maxzoom, long long *bbox, u
|
||||
sf.metapos = metastart;
|
||||
sf.geometry = geom2;
|
||||
sf.index = index;
|
||||
sf.label_point = label_point;
|
||||
sf.extent = extent;
|
||||
sf.feature_minzoom = feature_minzoom;
|
||||
|
||||
@@ -1430,7 +1431,7 @@ serial_feature next_feature(FILE *geoms, std::atomic<long long> *geompos_in, cha
|
||||
|
||||
if (*first_time && pass == 1) { /* only write out the next zoom once, even if we retry */
|
||||
if (sf.tippecanoe_maxzoom == -1 || sf.tippecanoe_maxzoom >= nextzoom) {
|
||||
rewrite(sf.geometry, z, nextzoom, maxzoom, sf.bbox, tx, ty, buffer, within, geompos, geomfile, fname, sf.t, sf.layer, sf.metapos, sf.feature_minzoom, child_shards, max_zoom_increment, sf.seq, sf.tippecanoe_minzoom, sf.tippecanoe_maxzoom, sf.segment, initial_x, initial_y, sf.keys, sf.values, sf.has_id, sf.id, sf.index, sf.extent);
|
||||
rewrite(sf.geometry, z, nextzoom, maxzoom, sf.bbox, tx, ty, buffer, within, geompos, geomfile, fname, sf.t, sf.layer, sf.metapos, sf.feature_minzoom, child_shards, max_zoom_increment, sf.seq, sf.tippecanoe_minzoom, sf.tippecanoe_maxzoom, sf.segment, initial_x, initial_y, sf.keys, sf.values, sf.has_id, sf.id, sf.index, sf.label_point, sf.extent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1812,7 +1813,6 @@ drawvec spiral_anchors(drawvec const &geom, int tx, int ty, int z, unsigned long
|
||||
// anchor point in world coordinates
|
||||
unsigned wx, wy;
|
||||
decode_index(label_point, &wx, &wy);
|
||||
printf("point %u,%u\n", wx, wy);
|
||||
|
||||
// upper left of tile in world coordinates
|
||||
long long tx1 = 0, ty1 = 0;
|
||||
@@ -1825,7 +1825,6 @@ drawvec spiral_anchors(drawvec const &geom, int tx, int ty, int z, unsigned long
|
||||
tx2 = (long long) (tx + 1) << (32 - z);
|
||||
ty2 = (long long) (ty + 1) << (32 - z);
|
||||
}
|
||||
printf("tile %lld,%lld to %lld,%lld\n", tx1, ty1, tx2, ty2);
|
||||
|
||||
// min and max distance of corners of this tile from the label point
|
||||
double min_radius, max_radius;
|
||||
@@ -1845,16 +1844,12 @@ drawvec spiral_anchors(drawvec const &geom, int tx, int ty, int z, unsigned long
|
||||
std::max(dist(wx, wy, tx2, ty2),
|
||||
dist(wx, wy, tx1, ty2))));
|
||||
|
||||
printf("radius (world) %f to %f\n", min_radius, max_radius);
|
||||
|
||||
// from world coordinates to tiles
|
||||
min_radius /= 1LL << (32 - z);
|
||||
max_radius /= 1LL << (32 - z);
|
||||
|
||||
printf("radius (tiles) %f to %f\n", min_radius, max_radius);
|
||||
|
||||
// labels complete a circle every 0.02 tiles of radius
|
||||
const double spiral_dist = 0.02;
|
||||
// labels complete a circle every 0.4 tiles of radius
|
||||
const double spiral_dist = 0.4;
|
||||
|
||||
size_t min_i = pow(min_radius / spiral_dist, 2);
|
||||
size_t max_i = pow(max_radius / spiral_dist, 2);
|
||||
@@ -1862,7 +1857,6 @@ drawvec spiral_anchors(drawvec const &geom, int tx, int ty, int z, unsigned long
|
||||
// https://craftofcoding.wordpress.com/tag/sunflower-spiral/
|
||||
double angle = M_PI * (3.0 - sqrt(5.0)); // 137.5 in radians
|
||||
|
||||
printf("making points %zu to %zu\n", min_i, max_i);
|
||||
for (size_t i = min_i; i <= max_i; i++) {
|
||||
double r = sqrt(i) * spiral_dist;
|
||||
double theta = i * angle;
|
||||
@@ -1871,7 +1865,25 @@ drawvec spiral_anchors(drawvec const &geom, int tx, int ty, int z, unsigned long
|
||||
long long y = r * sin(theta) * (1LL << (32 - z)) + wy;
|
||||
|
||||
if (x >= tx1 && x <= tx2 && y >= ty1 && y <= ty2) {
|
||||
out.push_back(draw(VT_MOVETO, x - tx1, y - ty1));
|
||||
// is it actually inside the bounding box of the feature? then keep it.
|
||||
|
||||
for (size_t a = 0; a < geom.size(); a++) {
|
||||
if (geom[a].op == VT_MOVETO) {
|
||||
size_t b;
|
||||
for (b = a + 1; b < geom.size(); b++) {
|
||||
if (geom[b].op != VT_LINETO) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pnpoly(geom, a, b - a, x - tx1, y - ty1)) {
|
||||
out.push_back(draw(VT_MOVETO, x - tx1, y - ty1));
|
||||
break;
|
||||
}
|
||||
|
||||
a = b - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user