Skip to content

Commit

Permalink
Bring over more vertex logic
Browse files Browse the repository at this point in the history
  • Loading branch information
e-n-f committed Sep 29, 2023
1 parent acf4859 commit 4e5de66
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 15 deletions.
3 changes: 3 additions & 0 deletions geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,9 @@ drawvec fix_polygon(drawvec &geom) {
ring = tmp;
}

// Now we are rotating the ring to make the first/last point
// one that would be unlikely to be simplified away.

// calculate centroid
// a + 1 < size() because point 0 is duplicated at the end
long long xtotal = 0;
Expand Down
8 changes: 3 additions & 5 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ void checkdisk(std::vector<struct reader> *r) {
for (size_t i = 0; i < r->size(); i++) {
// Pool and tree are used once.
// Geometry and index will be duplicated during sorting and tiling.
used += 2 * (*r)[i].geompos + 2 * (*r)[i].indexpos + (*r)[i].poolfile->off + (*r)[i].treefile->off;
// XXX vertex
used += 2 * (*r)[i].geompos + 2 * (*r)[i].indexpos + (*r)[i].poolfile->off + (*r)[i].treefile->off +
(*r)[i].vertexpos + (*r)[i].nodepos;
}

static int warned = 0;
Expand Down Expand Up @@ -2050,9 +2050,7 @@ std::pair<int, metadata> read_input(std::vector<source> &sources, char *fname, i

vertex prev, v;
while (fread((void *) &v, sizeof(vertex), 1, vertex_out)) {
if (v < prev) {
printf("bad: %lld,%lld vs %lld,%lld\n", prev.mid.x, prev.mid.y, v.mid.x, v.mid.y);
} else {
if (v.mid == prev.mid && (v.p1 != prev.p1 || v.p2 != prev.p2)) {
printf(" %lld,%lld vs %lld,%lld\n", prev.mid.x, prev.mid.y, v.mid.x, v.mid.y);
}
prev = v;
Expand Down
74 changes: 64 additions & 10 deletions serial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,16 @@ static std::string strip_zeroes(std::string s) {
return s;
}

static void add_scaled_node(struct reader *r, serialization_state *sst, draw g) {
long long x = SHIFT_LEFT(g.x);
long long y = SHIFT_LEFT(g.y);

struct node n;
n.index = encode_quadkey((unsigned) x, (unsigned) y);

fwrite_check((char *) &n, sizeof(struct node), 1, r->nodefile, &r->nodepos, sst->fname);
}

// called from frontends
int serialize_feature(struct serialization_state *sst, serial_feature &sf) {
struct reader *r = &(*sst->readers)[sst->segment];
Expand Down Expand Up @@ -485,13 +495,7 @@ int serialize_feature(struct serialization_state *sst, serial_feature &sf) {

if (sf.t == VT_LINE) {
for (auto &g : scaled_geometry) {
long long x = SHIFT_LEFT(g.x);
long long y = SHIFT_LEFT(g.y);

struct node n;
n.index = encode_quadkey((unsigned) x, (unsigned) y);

fwrite_check((char *) &n, sizeof(struct node), 1, r->nodefile, &r->nodepos, sst->fname);
add_scaled_node(r, sst, g);
}
} else if (sf.t == VT_POLYGON) {
for (size_t i = 0; i < scaled_geometry.size(); i++) {
Expand All @@ -507,13 +511,63 @@ int serialize_feature(struct serialization_state *sst, serial_feature &sf) {
for (size_t k = i; k < j - 1; k++) {
struct vertex v;

v.p1 = scaled_geometry[(k - i + 0) % (j - 1 - 1) + i];
v.mid = scaled_geometry[(k - i + 1) % (j - 1 - 1) + i];
v.p2 = scaled_geometry[(k - i + 2) % (j - 1 - 1) + i];
// % (j - i - 1) because we don't want the duplicate last point
v.p1 = scaled_geometry[(k - i + 0) % (j - i - 1) + i];
v.mid = scaled_geometry[(k - i + 1) % (j - i - 1) + i];
v.p2 = scaled_geometry[(k - i + 2) % (j - i - 1) + i];

fwrite_check((char *) &v, sizeof(struct vertex), 1, r->vertexfile, &r->vertexpos, sst->fname);
}

// since the starting point is never simplified away,
// don't let it be simplified away in any other polygons either.
// Needs to appear twice here so that the check below will see
// it as appearing in multiple features.
add_scaled_node(r, sst, scaled_geometry[i]);
add_scaled_node(r, sst, scaled_geometry[i]); // duplicate

// To avoid letting polygons get simplified away to nothing,
// also keep the furthest-away point from the initial point
// (which Douglas-Peucker simplification would keep anyway,
// if its search weren't being split up by polygon side).

double far = 0;
size_t which = i;
for (size_t k = i + 1; k < j - 1; k++) {
double xd = scaled_geometry[k].x - scaled_geometry[i].x;
double yd = scaled_geometry[k].y - scaled_geometry[i].y;
double d = xd * xd + yd * yd;
if (d > far ||
((d == far) && (scaled_geometry[k] < scaled_geometry[which]))) {
far = d;
which = k;
}
}

add_scaled_node(r, sst, scaled_geometry[which]);
add_scaled_node(r, sst, scaled_geometry[which]); // duplicate

// And, likewise, the point most distant from those two points,
// which probably would also be the one that Douglas-Peucker
// would keep next.

far = 0;
size_t which2 = i;

for (size_t k = i + 1; k < j - 1; k++) {
double d = distance_from_line(scaled_geometry[k].x, scaled_geometry[k].y,
scaled_geometry[i].x, scaled_geometry[i].y,
scaled_geometry[which].x, scaled_geometry[which].y);
if ((d > far) ||
((d == far) && (scaled_geometry[k] < scaled_geometry[which2]))) {
far = d;
which2 = k;
}
}

add_scaled_node(r, sst, scaled_geometry[which2]);
add_scaled_node(r, sst, scaled_geometry[which2]); // duplicate

i = j - 1;
}
}
Expand Down
3 changes: 3 additions & 0 deletions serial.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ struct serialization_state {
};

struct vertex {
// these are scaled geometry,
// but because scaling is disabled if P_SHARED_NODES is set,
// they are effectively also world coordinates
draw p1;
draw mid;
draw p2;
Expand Down

0 comments on commit 4e5de66

Please sign in to comment.