mirror of
https://github.com/felt/tippecanoe.git
synced 2026-10-04 17:35:42 +02:00
No need for line clipping to have its own source file
This commit is contained in:
@@ -42,7 +42,7 @@ C = $(shell find . '(' -name '*.c' -o -name '*.cpp' ')')
|
|||||||
INCLUDES = -I/usr/local/include -I.
|
INCLUDES = -I/usr/local/include -I.
|
||||||
LIBS = -L/usr/local/lib
|
LIBS = -L/usr/local/lib
|
||||||
|
|
||||||
tippecanoe: geojson.o jsonpull.o tile.o clip.o pool.o mbtiles.o geometry.o projection.o memfile.o clipper/clipper.o mvt.o
|
tippecanoe: geojson.o jsonpull.o tile.o pool.o mbtiles.o geometry.o projection.o memfile.o clipper.o mvt.o
|
||||||
$(CXX) $(PG) $(LIBS) $(FINAL_FLAGS) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) -lm -lz -lsqlite3 -lpthread
|
$(CXX) $(PG) $(LIBS) $(FINAL_FLAGS) $(CXXFLAGS) -o $@ $^ $(LDFLAGS) -lm -lz -lsqlite3 -lpthread
|
||||||
|
|
||||||
tippecanoe-enumerate: enumerate.o
|
tippecanoe-enumerate: enumerate.o
|
||||||
@@ -64,14 +64,15 @@ libjsonpull.a: jsonpull.o
|
|||||||
%.o: %.cpp $(H)
|
%.o: %.cpp $(H)
|
||||||
$(CXX) $(PG) $(INCLUDES) $(FINAL_FLAGS) $(CXXFLAGS) -c $<
|
$(CXX) $(PG) $(INCLUDES) $(FINAL_FLAGS) $(CXXFLAGS) -c $<
|
||||||
|
|
||||||
|
clipper.o: clipper/clipper.cpp $(H)
|
||||||
|
$(CXX) $(PG) $(INCLUDES) $(FINAL_FLAGS) $(CXXFLAGS) -c $<
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f tippecanoe *.o
|
rm -f tippecanoe *.o
|
||||||
|
|
||||||
indent:
|
indent:
|
||||||
clang-format -i -style="{BasedOnStyle: Google, IndentWidth: 8, UseTab: Always, AllowShortIfStatementsOnASingleLine: false, ColumnLimit: 0, ContinuationIndentWidth: 8, SpaceAfterCStyleCast: true, IndentCaseLabels: false, AllowShortBlocksOnASingleLine: false, AllowShortFunctionsOnASingleLine: false}" $(C) $(H)
|
clang-format -i -style="{BasedOnStyle: Google, IndentWidth: 8, UseTab: Always, AllowShortIfStatementsOnASingleLine: false, ColumnLimit: 0, ContinuationIndentWidth: 8, SpaceAfterCStyleCast: true, IndentCaseLabels: false, AllowShortBlocksOnASingleLine: false, AllowShortFunctionsOnASingleLine: false}" $(C) $(H)
|
||||||
|
|
||||||
geometry.o: clipper/clipper.hpp
|
|
||||||
|
|
||||||
TESTS = $(wildcard tests/*/out/*.json)
|
TESTS = $(wildcard tests/*/out/*.json)
|
||||||
SPACE = $(NULL) $(NULL)
|
SPACE = $(NULL) $(NULL)
|
||||||
|
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
#include "clip.h"
|
|
||||||
|
|
||||||
#define INSIDE 0
|
|
||||||
#define LEFT 1
|
|
||||||
#define RIGHT 2
|
|
||||||
#define BOTTOM 4
|
|
||||||
#define TOP 8
|
|
||||||
|
|
||||||
static int computeOutCode(double x, double y, double xmin, double ymin, double xmax, double ymax) {
|
|
||||||
int code = INSIDE;
|
|
||||||
|
|
||||||
if (x < xmin) {
|
|
||||||
code |= LEFT;
|
|
||||||
} else if (x > xmax) {
|
|
||||||
code |= RIGHT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (y < ymin) {
|
|
||||||
code |= BOTTOM;
|
|
||||||
} else if (y > ymax) {
|
|
||||||
code |= TOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
int clip(double *x0, double *y0, double *x1, double *y1, double xmin, double ymin, double xmax, double ymax) {
|
|
||||||
int outcode0 = computeOutCode(*x0, *y0, xmin, ymin, xmax, ymax);
|
|
||||||
int outcode1 = computeOutCode(*x1, *y1, xmin, ymin, xmax, ymax);
|
|
||||||
int accept = 0;
|
|
||||||
int changed = 0;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
if (!(outcode0 | outcode1)) { // Bitwise OR is 0. Trivially accept and get out of loop
|
|
||||||
accept = 1;
|
|
||||||
break;
|
|
||||||
} else if (outcode0 & outcode1) { // Bitwise AND is not 0. Trivially reject and get out of loop
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
// failed both tests, so calculate the line segment to clip
|
|
||||||
// from an outside point to an intersection with clip edge
|
|
||||||
double x = *x0, y = *y0;
|
|
||||||
|
|
||||||
// At least one endpoint is outside the clip rectangle; pick it.
|
|
||||||
int outcodeOut = outcode0 ? outcode0 : outcode1;
|
|
||||||
|
|
||||||
// Now find the intersection point;
|
|
||||||
// use formulas y = y0 + slope * (x - x0), x = x0 + (1 / slope) * (y - y0)
|
|
||||||
if (outcodeOut & TOP) { // point is above the clip rectangle
|
|
||||||
x = *x0 + (*x1 - *x0) * (ymax - *y0) / (*y1 - *y0);
|
|
||||||
y = ymax;
|
|
||||||
} else if (outcodeOut & BOTTOM) { // point is below the clip rectangle
|
|
||||||
x = *x0 + (*x1 - *x0) * (ymin - *y0) / (*y1 - *y0);
|
|
||||||
y = ymin;
|
|
||||||
} else if (outcodeOut & RIGHT) { // point is to the right of clip rectangle
|
|
||||||
y = *y0 + (*y1 - *y0) * (xmax - *x0) / (*x1 - *x0);
|
|
||||||
x = xmax;
|
|
||||||
} else if (outcodeOut & LEFT) { // point is to the left of clip rectangle
|
|
||||||
y = *y0 + (*y1 - *y0) * (xmin - *x0) / (*x1 - *x0);
|
|
||||||
x = xmin;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now we move outside point to intersection point to clip
|
|
||||||
// and get ready for next pass.
|
|
||||||
if (outcodeOut == outcode0) {
|
|
||||||
*x0 = x;
|
|
||||||
*y0 = y;
|
|
||||||
outcode0 = computeOutCode(*x0, *y0, xmin, ymin, xmax, ymax);
|
|
||||||
changed = 1;
|
|
||||||
} else {
|
|
||||||
*x1 = x;
|
|
||||||
*y1 = y;
|
|
||||||
outcode1 = computeOutCode(*x1, *y1, xmin, ymin, xmax, ymax);
|
|
||||||
changed = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (accept == 0) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return changed + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
int clip(double *x0, double *y0, double *x1, double *y1, double xmin, double ymin, double xmax, double ymax);
|
|
||||||
+84
-1
@@ -14,11 +14,11 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
#include "clip.h"
|
|
||||||
#include "projection.h"
|
#include "projection.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pnpoly(drawvec &vert, size_t start, size_t nvert, long long testx, long long testy);
|
static int pnpoly(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, long long *geompos, int z, unsigned tx, unsigned ty, int detail, long long *bbox, unsigned initial_x, unsigned initial_y) {
|
drawvec decode_geometry(FILE *meta, long long *geompos, int z, unsigned tx, unsigned ty, int detail, long long *bbox, unsigned initial_x, unsigned initial_y) {
|
||||||
drawvec out;
|
drawvec out;
|
||||||
@@ -1310,3 +1310,86 @@ std::vector<drawvec> chop_polygon(std::vector<drawvec> &geoms) {
|
|||||||
geoms = out;
|
geoms = out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define INSIDE 0
|
||||||
|
#define LEFT 1
|
||||||
|
#define RIGHT 2
|
||||||
|
#define BOTTOM 4
|
||||||
|
#define TOP 8
|
||||||
|
|
||||||
|
static int computeOutCode(double x, double y, double xmin, double ymin, double xmax, double ymax) {
|
||||||
|
int code = INSIDE;
|
||||||
|
|
||||||
|
if (x < xmin) {
|
||||||
|
code |= LEFT;
|
||||||
|
} else if (x > xmax) {
|
||||||
|
code |= RIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (y < ymin) {
|
||||||
|
code |= BOTTOM;
|
||||||
|
} else if (y > ymax) {
|
||||||
|
code |= TOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int clip(double *x0, double *y0, double *x1, double *y1, double xmin, double ymin, double xmax, double ymax) {
|
||||||
|
int outcode0 = computeOutCode(*x0, *y0, xmin, ymin, xmax, ymax);
|
||||||
|
int outcode1 = computeOutCode(*x1, *y1, xmin, ymin, xmax, ymax);
|
||||||
|
int accept = 0;
|
||||||
|
int changed = 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (!(outcode0 | outcode1)) { // Bitwise OR is 0. Trivially accept and get out of loop
|
||||||
|
accept = 1;
|
||||||
|
break;
|
||||||
|
} else if (outcode0 & outcode1) { // Bitwise AND is not 0. Trivially reject and get out of loop
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// failed both tests, so calculate the line segment to clip
|
||||||
|
// from an outside point to an intersection with clip edge
|
||||||
|
double x = *x0, y = *y0;
|
||||||
|
|
||||||
|
// At least one endpoint is outside the clip rectangle; pick it.
|
||||||
|
int outcodeOut = outcode0 ? outcode0 : outcode1;
|
||||||
|
|
||||||
|
// Now find the intersection point;
|
||||||
|
// use formulas y = y0 + slope * (x - x0), x = x0 + (1 / slope) * (y - y0)
|
||||||
|
if (outcodeOut & TOP) { // point is above the clip rectangle
|
||||||
|
x = *x0 + (*x1 - *x0) * (ymax - *y0) / (*y1 - *y0);
|
||||||
|
y = ymax;
|
||||||
|
} else if (outcodeOut & BOTTOM) { // point is below the clip rectangle
|
||||||
|
x = *x0 + (*x1 - *x0) * (ymin - *y0) / (*y1 - *y0);
|
||||||
|
y = ymin;
|
||||||
|
} else if (outcodeOut & RIGHT) { // point is to the right of clip rectangle
|
||||||
|
y = *y0 + (*y1 - *y0) * (xmax - *x0) / (*x1 - *x0);
|
||||||
|
x = xmax;
|
||||||
|
} else if (outcodeOut & LEFT) { // point is to the left of clip rectangle
|
||||||
|
y = *y0 + (*y1 - *y0) * (xmin - *x0) / (*x1 - *x0);
|
||||||
|
x = xmin;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we move outside point to intersection point to clip
|
||||||
|
// and get ready for next pass.
|
||||||
|
if (outcodeOut == outcode0) {
|
||||||
|
*x0 = x;
|
||||||
|
*y0 = y;
|
||||||
|
outcode0 = computeOutCode(*x0, *y0, xmin, ymin, xmax, ymax);
|
||||||
|
changed = 1;
|
||||||
|
} else {
|
||||||
|
*x1 = x;
|
||||||
|
*y1 = y;
|
||||||
|
outcode1 = computeOutCode(*x1, *y1, xmin, ymin, xmax, ymax);
|
||||||
|
changed = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (accept == 0) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return changed + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user