Ejemplo n.º 1
0
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
}
Ejemplo n.º 2
0
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
}