diff --git a/bg_helpers.cpp b/bg_helpers.cpp index e66ef6ac5..5a66e7d75 100644 --- a/bg_helpers.cpp +++ b/bg_helpers.cpp @@ -9,26 +9,20 @@ #include "bg_operators.hpp" #include "bg_helpers.hpp" -namespace bg_helpers { - -// The below implementations of buffer are similar to bg::buffer but -// always convert to floating-point before doing work, if needed, and -// convert back afterward, if needed. Also, they work if expand_by is -// 0, unlike bg::buffer. -const int points_per_circle = 32; - -multi_polygon_type_fp buffer(multi_polygon_type_fp const & geometry_in, coordinate_type_fp expand_by) { - if (expand_by == 0 || geometry_in.size() == 0) { - return geometry_in; - } #ifdef GEOS_VERSION +template +std::unique_ptr to_geos(const T& mp) { geos::io::WKTReader reader; std::stringstream ss; - ss << bg::wkt(geometry_in); - auto geos_in = reader.read(ss.str()); - std::unique_ptr geos_out(geos::operation::buffer::BufferOp::bufferOp(geos_in.get(), expand_by, points_per_circle/4)); + ss << bg::wkt(mp); + return reader.read(ss.str()); +} + +multi_polygon_type_fp from_geos(const std::unique_ptr& g) { geos::io::WKTWriter writer; - auto geos_wkt = writer.write(geos_out.get()); + std::string geos_wkt = writer.write(g.get()); + boost::replace_all(geos_wkt, "EMPTY, ", ""); + boost::replace_all(geos_wkt, ", EMPTY", ""); multi_polygon_type_fp ret; if (strncmp(geos_wkt.c_str(), "MULTIPOLYGON", 12) == 0) { bg::read_wkt(geos_wkt, ret); @@ -38,6 +32,26 @@ multi_polygon_type_fp buffer(multi_polygon_type_fp const & geometry_in, coordina ret.push_back(poly); } return ret; +} +#endif //GEOS_VERSION + +namespace bg_helpers { + +// The below implementations of buffer are similar to bg::buffer but +// always convert to floating-point before doing work, if needed, and +// convert back afterward, if needed. Also, they work if expand_by is +// 0, unlike bg::buffer. +const int points_per_circle = 32; + +multi_polygon_type_fp buffer(multi_polygon_type_fp const & geometry_in, coordinate_type_fp expand_by) { + if (expand_by == 0 || geometry_in.size() == 0) { + return geometry_in; + } +#ifdef GEOS_VERSION + auto geos_in = to_geos(geometry_in); + return from_geos( + std::unique_ptr( + geos::operation::buffer::BufferOp::bufferOp(geos_in.get(), expand_by, points_per_circle/4))); #else multi_polygon_type_fp geometry_out; bg::buffer(geometry_in, geometry_out, @@ -83,22 +97,10 @@ multi_polygon_type_fp buffer(linestring_type_fp const & geometry_in, CoordinateT return {}; } #ifdef GEOS_VERSION - geos::io::WKTReader reader; - std::stringstream ss; - ss << bg::wkt(geometry_in); - auto geos_in = reader.read(ss.str()); - std::unique_ptr geos_out(geos::operation::buffer::BufferOp::bufferOp(geos_in.get(), expand_by, points_per_circle/4)); - geos::io::WKTWriter writer; - auto geos_wkt = writer.write(geos_out.get()); - multi_polygon_type_fp ret; - if (strncmp(geos_wkt.c_str(), "MULTIPOLYGON", 12) == 0) { - bg::read_wkt(geos_wkt, ret); - } else { - polygon_type_fp poly; - bg::read_wkt(geos_wkt, poly); - ret.push_back(poly); - } - return ret; + auto geos_in = to_geos(geometry_in); + return from_geos( + std::unique_ptr( + geos::operation::buffer::BufferOp::bufferOp(geos_in.get(), expand_by, points_per_circle/4))); #else multi_polygon_type_fp geometry_out; bg::buffer(geometry_in, geometry_out, @@ -120,22 +122,10 @@ multi_polygon_type_fp buffer(multi_linestring_type_fp const & geometry_in, Coord // multilinestring to non-intersecting paths seems to help. multi_linestring_type_fp mls = eulerian_paths::make_eulerian_paths(geometry_in, true, true); #ifdef GEOS_VERSION - geos::io::WKTReader reader; - std::stringstream ss; - ss << bg::wkt(mls); - auto geos_in = reader.read(ss.str()); - std::unique_ptr geos_out(geos::operation::buffer::BufferOp::bufferOp(geos_in.get(), expand_by, points_per_circle/4)); - geos::io::WKTWriter writer; - auto geos_wkt = writer.write(geos_out.get()); - multi_polygon_type_fp ret; - if (strncmp(geos_wkt.c_str(), "MULTIPOLYGON", 12) == 0) { - bg::read_wkt(geos_wkt, ret); - } else { - polygon_type_fp poly; - bg::read_wkt(geos_wkt, poly); - ret.push_back(poly); - } - return ret; + auto geos_in = to_geos(mls); + return from_geos( + std::unique_ptr( + geos::operation::buffer::BufferOp::bufferOp(geos_in.get(), expand_by, points_per_circle/4))); #else if (expand_by == 0) { return {}; diff --git a/bg_helpers.hpp b/bg_helpers.hpp index f01b5350c..89308eea6 100644 --- a/bg_helpers.hpp +++ b/bg_helpers.hpp @@ -6,10 +6,8 @@ #ifdef GEOS_VERSION #include #include -#include #endif // GEOS_VERSION - namespace bg_helpers { // The below implementations of buffer are similar to bg::buffer but diff --git a/drill.cpp b/drill.cpp index 6036bb40a..09761dc1d 100644 --- a/drill.cpp +++ b/drill.cpp @@ -471,7 +471,7 @@ bool ExcellonProcessor::millhole(std::ofstream &of, double start_x, double start double zdiff_line1 = 0; double zdiff_hcircle2 = 0; // Distance traveled by one half circle - double dist_hcircle = M_PI * millr; + double dist_hcircle = boost::math::constants::pi() * millr; if (slot) { // How much to step down per pass double zstep = cutter->zwork / stepcount;