mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-04 09:25:41 +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"
|
#include "geometry.hpp"
|
||||||
|
|
||||||
struct point {
|
struct point {
|
||||||
@@ -11,6 +12,10 @@ struct point {
|
|||||||
|
|
||||||
typedef std::pair<point, point> segment;
|
typedef std::pair<point, point> segment;
|
||||||
|
|
||||||
|
bool intersect(std::vector<segment> &segs, size_t s1, size_t s2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
struct scan_transition {
|
struct scan_transition {
|
||||||
double y;
|
double y;
|
||||||
size_t segment;
|
size_t segment;
|
||||||
@@ -38,21 +43,63 @@ std::vector<segment> snap_round(std::vector<segment> segs) {
|
|||||||
// to find the pairs that intersect
|
// to find the pairs that intersect
|
||||||
// while not looking at pairs that can't possibly 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> tops;
|
||||||
std::vector<scan_transition> bottoms;
|
std::vector<scan_transition> bottoms;
|
||||||
|
|
||||||
for (size_t i = 0; i < segs.size(); i++) {
|
for (size_t i = 0; i < segs.size(); i++) {
|
||||||
if (segs[i].first.y < segs[i].second.y) {
|
if (std::round(segs[i].first.y) < std::round(segs[i].second.y)) {
|
||||||
tops.emplace_back(segs[i].first.y, i);
|
tops.emplace_back(std::round(segs[i].first.y), i);
|
||||||
bottoms.emplace_back(segs[i].second.y, i);
|
bottoms.emplace_back(std::round(segs[i].second.y), i);
|
||||||
} else {
|
} else {
|
||||||
tops.emplace_back(segs[i].second.y, i);
|
tops.emplace_back(std::round(segs[i].second.y), i);
|
||||||
bottoms.emplace_back(segs[i].first.y, i);
|
bottoms.emplace_back(std::round(segs[i].first.y), i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(tops.begin(), tops.end());
|
std::sort(tops.begin(), tops.end());
|
||||||
std::sort(bottoms.begin(), bottoms.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;
|
return segs;
|
||||||
@@ -70,7 +117,7 @@ drawvec clean_polygon(drawvec const &geom, int z, int detail) {
|
|||||||
size_t j;
|
size_t j;
|
||||||
|
|
||||||
for (j = i + 1; j < geom.size(); j++) {
|
for (j = i + 1; j < geom.size(); j++) {
|
||||||
if (geom[i].op != VT_LINETO) {
|
if (geom[j].op != VT_LINETO) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
drawvec clean_polygon(drawvec const &geom, int z, int detail);
|
||||||
@@ -43,6 +43,7 @@
|
|||||||
#include "errors.hpp"
|
#include "errors.hpp"
|
||||||
#include "compression.hpp"
|
#include "compression.hpp"
|
||||||
#include "protozero/varint.hpp"
|
#include "protozero/varint.hpp"
|
||||||
|
#include "polygon.hpp"
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "jsonpull/jsonpull.h"
|
#include "jsonpull/jsonpull.h"
|
||||||
@@ -612,6 +613,11 @@ void *partial_feature_worker(void *v) {
|
|||||||
int out_detail = (*partials)[i].extra_detail;
|
int out_detail = (*partials)[i].extra_detail;
|
||||||
|
|
||||||
drawvec geom = (*partials)[i].geoms[0];
|
drawvec geom = (*partials)[i].geoms[0];
|
||||||
|
|
||||||
|
if (t == VT_POLYGON) {
|
||||||
|
clean_polygon(geom, z, out_detail);
|
||||||
|
}
|
||||||
|
|
||||||
to_tile_scale(geom, z, out_detail);
|
to_tile_scale(geom, z, out_detail);
|
||||||
|
|
||||||
if (t == VT_POLYGON) {
|
if (t == VT_POLYGON) {
|
||||||
|
|||||||
Reference in New Issue
Block a user