bool Geometry::buffer(double distance, osg::ref_ptr<Geometry>& output, const BufferParameters& params ) const { #ifdef OSGEARTH_HAVE_GEOS GEOSContext gc; geom::Geometry* inGeom = gc.importGeometry( this ); if ( inGeom ) { buffer::BufferParameters::EndCapStyle geosEndCap = params._capStyle == BufferParameters::CAP_ROUND ? buffer::BufferParameters::CAP_ROUND : params._capStyle == BufferParameters::CAP_SQUARE ? buffer::BufferParameters::CAP_SQUARE : params._capStyle == BufferParameters::CAP_FLAT ? buffer::BufferParameters::CAP_FLAT : buffer::BufferParameters::CAP_SQUARE; buffer::BufferParameters::JoinStyle geosJoinStyle = params._joinStyle == BufferParameters::JOIN_ROUND ? buffer::BufferParameters::JOIN_ROUND : params._joinStyle == BufferParameters::JOIN_MITRE ? buffer::BufferParameters::JOIN_MITRE : params._joinStyle == BufferParameters::JOIN_BEVEL ? buffer::BufferParameters::JOIN_BEVEL : buffer::BufferParameters::JOIN_ROUND; //JB: Referencing buffer::BufferParameters::DEFAULT_QUADRANT_SEGMENTS causes link errors b/c it is defined as a static in the header of BufferParameters.h and not defined in the cpp anywhere. // This seems to only effect the Linux build, Windows works fine int geosQuadSegs = params._cornerSegs > 0 ? params._cornerSegs : 8; //buffer::BufferParameters::DEFAULT_QUADRANT_SEGMENTS; geom::Geometry* outGeom = NULL; buffer::BufferParameters geosBufferParams; geosBufferParams.setQuadrantSegments( geosQuadSegs ); geosBufferParams.setEndCapStyle( geosEndCap ); geosBufferParams.setJoinStyle( geosJoinStyle ); buffer::BufferBuilder bufBuilder( geosBufferParams ); try { if (params._singleSided) { outGeom = bufBuilder.bufferLineSingleSided(inGeom, distance, params._leftSide); } else { outGeom = bufBuilder.buffer(inGeom, distance); } } catch(const geos::util::GEOSException& ex) { OE_NOTICE << LC << "buffer(GEOS): " << (ex.what()? ex.what() : " no error message") << std::endl; outGeom = 0L; } bool sharedFactory = inGeom && outGeom && inGeom->getFactory() == outGeom->getFactory(); if ( outGeom ) { output = gc.exportGeometry( outGeom ); gc.disposeGeometry( outGeom ); } gc.disposeGeometry( inGeom ); } return output.valid(); #else // OSGEARTH_HAVE_GEOS OE_WARN << LC << "Buffer failed - GEOS not available" << std::endl; return false; #endif // OSGEARTH_HAVE_GEOS }
bool Geometry::geounion( const Geometry* other, osg::ref_ptr<Geometry>& output ) const { #ifdef OSGEARTH_HAVE_GEOS bool success = false; output = 0L; GEOSContext gc; //Create the GEOS Geometries geom::Geometry* inGeom = gc.importGeometry( this ); geom::Geometry* otherGeom = gc.importGeometry( other ); if ( inGeom ) { geom::Geometry* outGeom = 0L; try { outGeom = overlay::OverlayOp::overlayOp( inGeom, otherGeom, overlay::OverlayOp::opUNION ); } catch(const geos::util::GEOSException& ex) { OE_NOTICE << LC << "Union(GEOS): " << (ex.what()? ex.what() : " no error message") << std::endl; outGeom = 0L; } if ( outGeom ) { output = gc.exportGeometry( outGeom ); if ( output.valid()) { if ( output->isValid() ) { success = true; } else { // GEOS result is invalid output = 0L; } } else { // set output to empty geometry to indicate the (valid) empty case, // still returning false but allows for check. if (outGeom->getNumPoints() == 0) { output = new osgEarth::Symbology::Geometry(); } } gc.disposeGeometry( outGeom ); } } //Destroy the geometry gc.disposeGeometry( otherGeom ); gc.disposeGeometry( inGeom ); return success; #else // OSGEARTH_HAVE_GEOS OE_WARN << LC << "Union failed - GEOS not available" << std::endl; return false; #endif // OSGEARTH_HAVE_GEOS }