Skip to content

Commit

Permalink
Added offsetCurve function to Geometry
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonbeverage committed Feb 5, 2025
1 parent b33f680 commit 7b044a2
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 3 deletions.
17 changes: 14 additions & 3 deletions src/osgEarth/Geometry
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,12 @@ namespace osgEarth
public:
enum CapStyle { CAP_DEFAULT, CAP_SQUARE, CAP_ROUND, CAP_FLAT };
enum JoinStyle { JOIN_ROUND, JOIN_MITRE, JOIN_BEVEL};
BufferParameters( CapStyle capStyle =CAP_DEFAULT, JoinStyle joinStyle = JOIN_ROUND, int cornerSegs =0, bool singleSided=false, bool leftSide=false )
: _capStyle(capStyle), _joinStyle(joinStyle),_cornerSegs(cornerSegs), _singleSided(singleSided), _leftSide(leftSide) { }
BufferParameters( CapStyle capStyle =CAP_DEFAULT, JoinStyle joinStyle = JOIN_ROUND, int cornerSegs =0, bool singleSided=false )
: _capStyle(capStyle), _joinStyle(joinStyle),_cornerSegs(cornerSegs), _singleSided(singleSided) { }
CapStyle _capStyle;
JoinStyle _joinStyle;
int _cornerSegs; // # of line segment making up a rounded corner
bool _singleSided; //Whether or not to do a single sided buffer
bool _leftSide; //If doing a single sided buffer are we buffering to the left? If false, buffer to the right
};

typedef std::vector<osg::Vec3d> Vec3dVector;
Expand Down Expand Up @@ -156,6 +155,18 @@ namespace osgEarth
osg::ref_ptr<Geometry>& output,
const BufferParameters& bp =BufferParameters() ) const;

/**
* Runs an offset curve operation on this geometry and returns the
* result in the output parameter. Returns true if the op succeeded.
*/
bool offsetCurve(
double distance,
int quadSegs,
BufferParameters::JoinStyle joinStyle,
double mitreLimit,
osg::ref_ptr<Geometry>& output
) const;

/**
* Crops this geometry to the region represented by the crop polygon, returning
* the result in the output parameter. Returns true if the op succeeded.
Expand Down
51 changes: 51 additions & 0 deletions src/osgEarth/Geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,57 @@ Geometry::buffer(double distance,
#endif // OSGEARTH_HAVE_GEOS
}

bool
Geometry::offsetCurve(
double distance,
int quadSegs,
BufferParameters::JoinStyle joinStyle,
double mitreLimit,
osg::ref_ptr<Geometry>& output
) const
{
#ifdef OSGEARTH_HAVE_GEOS

GEOSContextHandle_t handle = initGEOS_r(OSGEARTH_WarningHandler, OSGEARTH_GEOSErrorHandler);

GEOSGeometry* inGeom = GEOS::importGeometry(handle, this);
if (inGeom)
{
int geosJoinStyle =
joinStyle == BufferParameters::JOIN_ROUND ? GEOSBufJoinStyles::GEOSBUF_JOIN_ROUND :
joinStyle == BufferParameters::JOIN_MITRE ? GEOSBufJoinStyles::GEOSBUF_JOIN_MITRE :
joinStyle == BufferParameters::JOIN_BEVEL ? GEOSBufJoinStyles::GEOSBUF_JOIN_BEVEL :
GEOSBufJoinStyles::GEOSBUF_JOIN_ROUND;

GEOSGeometry* outGeom = NULL;
outGeom = GEOSOffsetCurve_r(handle, inGeom, distance, quadSegs, geosJoinStyle, mitreLimit);
if (outGeom)
{
output = GEOS::exportGeometry(handle, outGeom);
// If the z value of the geometry is nan set it to 0
for (auto& p : output->asVector())
{
if (std::isnan(p.z()))
p.z() = 0.0;
}
GEOSGeom_destroy_r(handle, outGeom);
}

GEOSGeom_destroy_r(handle, inGeom);
}

finishGEOS_r(handle);

return output.valid();

#else // OSGEARTH_HAVE_GEOS

OE_WARN << LC << "Offset Curve failed - GEOS not available" << std::endl;
return false;

#endif // OSGEARTH_HAVE_GEOS
}

namespace
{
// Function to check if a point is inside the clipping edge
Expand Down

0 comments on commit 7b044a2

Please sign in to comment.