mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-02 08:25:40 +02:00
Doing the scan line through the segments
This commit is contained in:
+53
-6
@@ -1,3 +1,4 @@
|
||||
#include <stdio.h>
|
||||
#include "geometry.hpp"
|
||||
|
||||
struct point {
|
||||
@@ -11,6 +12,10 @@ struct point {
|
||||
|
||||
typedef std::pair<point, point> segment;
|
||||
|
||||
bool intersect(std::vector<segment> &segs, size_t s1, size_t s2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct scan_transition {
|
||||
double y;
|
||||
size_t segment;
|
||||
@@ -38,21 +43,63 @@ std::vector<segment> snap_round(std::vector<segment> segs) {
|
||||
// to find the pairs that intersect
|
||||
// while not looking at pairs that can't possibly intersect
|
||||
|
||||
// index by rounded y coordinates, since we will be
|
||||
// intersecting with rounded coordinates
|
||||
|
||||
std::vector<scan_transition> tops;
|
||||
std::vector<scan_transition> bottoms;
|
||||
|
||||
for (size_t i = 0; i < segs.size(); i++) {
|
||||
if (segs[i].first.y < segs[i].second.y) {
|
||||
tops.emplace_back(segs[i].first.y, i);
|
||||
bottoms.emplace_back(segs[i].second.y, i);
|
||||
if (std::round(segs[i].first.y) < std::round(segs[i].second.y)) {
|
||||
tops.emplace_back(std::round(segs[i].first.y), i);
|
||||
bottoms.emplace_back(std::round(segs[i].second.y), i);
|
||||
} else {
|
||||
tops.emplace_back(segs[i].second.y, i);
|
||||
bottoms.emplace_back(segs[i].first.y, i);
|
||||
tops.emplace_back(std::round(segs[i].second.y), i);
|
||||
bottoms.emplace_back(std::round(segs[i].first.y), i);
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(tops.begin(), tops.end());
|
||||
std::sort(bottoms.begin(), bottoms.end());
|
||||
|
||||
// do the scan
|
||||
|
||||
std::set<size_t> active;
|
||||
size_t bottom = 0;
|
||||
for (size_t i = 0; i < tops.size(); i++) {
|
||||
// activate anything that is coming into view
|
||||
|
||||
active.insert(tops[i].segment);
|
||||
if (i + 1 < tops.size() && tops[i + 1].y == tops[i].y) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// look at the active segments
|
||||
|
||||
for (size_t s1 : active) {
|
||||
for (size_t s2 : active) {
|
||||
if (s1 < s2) {
|
||||
if (intersect(segs, s1, s2)) {
|
||||
// if the segments intersected,
|
||||
// we need to do another scan,
|
||||
// because introducing a new node
|
||||
// may have caused new intersections
|
||||
again = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// deactivate anything that is going out of view
|
||||
|
||||
if (i + 1 < tops.size()) {
|
||||
while (bottom < bottoms.size() && bottoms[bottom].y < tops[i + 1].y) {
|
||||
auto found = active.find(bottoms[bottom].segment);
|
||||
active.erase(found);
|
||||
bottom++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return segs;
|
||||
@@ -70,7 +117,7 @@ drawvec clean_polygon(drawvec const &geom, int z, int detail) {
|
||||
size_t j;
|
||||
|
||||
for (j = i + 1; j < geom.size(); j++) {
|
||||
if (geom[i].op != VT_LINETO) {
|
||||
if (geom[j].op != VT_LINETO) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
drawvec clean_polygon(drawvec const &geom, int z, int detail);
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "errors.hpp"
|
||||
#include "compression.hpp"
|
||||
#include "protozero/varint.hpp"
|
||||
#include "polygon.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "jsonpull/jsonpull.h"
|
||||
@@ -612,6 +613,11 @@ void *partial_feature_worker(void *v) {
|
||||
int out_detail = (*partials)[i].extra_detail;
|
||||
|
||||
drawvec geom = (*partials)[i].geoms[0];
|
||||
|
||||
if (t == VT_POLYGON) {
|
||||
clean_polygon(geom, z, out_detail);
|
||||
}
|
||||
|
||||
to_tile_scale(geom, z, out_detail);
|
||||
|
||||
if (t == VT_POLYGON) {
|
||||
|
||||
Reference in New Issue
Block a user