Skip to content

Commit

Permalink
refactor: Add common to_geos and from_geos functions
Browse files Browse the repository at this point in the history
  • Loading branch information
eyal0 committed Feb 3, 2021
1 parent 2a83b08 commit 4f613a6
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 51 deletions.
86 changes: 38 additions & 48 deletions bg_helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename T>
std::unique_ptr<geos::geom::Geometry> 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::geom::Geometry> 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<geos::geom::Geometry>& 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);
Expand All @@ -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::geom::Geometry>(
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,
Expand Down Expand Up @@ -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::geom::Geometry> 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::geom::Geometry>(
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,
Expand All @@ -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::geom::Geometry> 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::geom::Geometry>(
geos::operation::buffer::BufferOp::bufferOp(geos_in.get(), expand_by, points_per_circle/4)));
#else
if (expand_by == 0) {
return {};
Expand Down
2 changes: 0 additions & 2 deletions bg_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@
#ifdef GEOS_VERSION
#include <geos/io/WKTReader.h>
#include <geos/io/WKTWriter.h>
#include <geos/operation/buffer/BufferOp.h>
#endif // GEOS_VERSION


namespace bg_helpers {

// The below implementations of buffer are similar to bg::buffer but
Expand Down
2 changes: 1 addition & 1 deletion drill.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<double>() * millr;
if (slot) {
// How much to step down per pass
double zstep = cutter->zwork / stepcount;
Expand Down

0 comments on commit 4f613a6

Please sign in to comment.