osgEarth 2.1.1
Public Types | Public Member Functions | Static Public Member Functions | Protected Member Functions | Protected Attributes

osgEarth::Features::ResampleFilter Class Reference

Inheritance diagram for osgEarth::Features::ResampleFilter:
Collaboration diagram for osgEarth::Features::ResampleFilter:

List of all members.

Public Types

enum  ResampleMode { RESAMPLE_LINEAR, RESAMPLE_GREATCIRCLE, RESAMPLE_RHUMB }

Public Member Functions

 ResampleFilter ()
 ResampleFilter (double minLength, double maxLength)
optional< double > & minLength ()
const optional< double > & minLength () const
optional< double > & maxLength ()
const optional< double > & maxLength () const
optional< double > & perturbationThreshold ()
const optional< double > & perturbationThreshold () const
optional< ResampleMode > & resampleMode ()
const optional< ResampleMode > & resampleMode () const
virtual FilterContext push (FeatureList &input, FilterContext &context)

Static Public Member Functions

static bool isSupported ()

Protected Member Functions

bool push (Feature *input, FilterContext &context)

Protected Attributes

optional< double > _minLen
optional< double > _maxLen
optional< double > _perturbThresh
optional< ResampleMode_resampleMode

Detailed Description

This filter will resample line segments so they are between the min and max specified length.

Definition at line 36 of file ResampleFilter.


Member Enumeration Documentation

Enumerator:
RESAMPLE_LINEAR 
RESAMPLE_GREATCIRCLE 
RESAMPLE_RHUMB 

Definition at line 59 of file ResampleFilter.


Constructor & Destructor Documentation

ResampleFilter::ResampleFilter ( )

Definition at line 36 of file ResampleFilter.cpp.

                               :
_minLen( 0 ),
_maxLen( DBL_MAX ),
_perturbThresh( 0 ),
_resampleMode(RESAMPLE_LINEAR)
{
    //NOP
}
ResampleFilter::ResampleFilter ( double  minLength,
double  maxLength 
)

Definition at line 45 of file ResampleFilter.cpp.

                                                             :
_minLen( minLen ),
_maxLen( maxLen ),
_perturbThresh( 0 ),
_resampleMode(RESAMPLE_LINEAR)
{
    // NOP
}

Member Function Documentation

bool ResampleFilter::isSupported ( ) [static]

Definition at line 31 of file ResampleFilter.cpp.

{
    return true;
}

Here is the caller graph for this function:

optional<double>& osgEarth::Features::ResampleFilter::maxLength ( ) [inline]

Definition at line 51 of file ResampleFilter.

{ return _maxLen; }

Here is the caller graph for this function:

const optional<double>& osgEarth::Features::ResampleFilter::maxLength ( ) const [inline]

Definition at line 52 of file ResampleFilter.

{ return _maxLen; }
optional<double>& osgEarth::Features::ResampleFilter::minLength ( ) [inline]

Definition at line 48 of file ResampleFilter.

{ return _minLen; }

Here is the caller graph for this function:

const optional<double>& osgEarth::Features::ResampleFilter::minLength ( ) const [inline]

Definition at line 49 of file ResampleFilter.

{ return _minLen; }
const optional<double>& osgEarth::Features::ResampleFilter::perturbationThreshold ( ) const [inline]

Definition at line 55 of file ResampleFilter.

{ return _perturbThresh; }
optional<double>& osgEarth::Features::ResampleFilter::perturbationThreshold ( ) [inline]

Definition at line 54 of file ResampleFilter.

{ return _perturbThresh; }

Here is the caller graph for this function:

bool ResampleFilter::push ( Feature input,
FilterContext context 
) [protected]

Definition at line 55 of file ResampleFilter.cpp.

{
    if ( !input || !input->getGeometry() )
        return true;

    bool success = true;

    GeometryIterator i( input->getGeometry() );
    while( i.hasMore() )
    {        
        Geometry* part = i.next();

        if ( part->size() < 2 ) continue;

        unsigned int origSize = part->size();

        // copy the original part to a linked list. use a std::list since insert/erase
        // will not invalidate iterators.
        std::list<osg::Vec3d> plist;
        plist.insert( plist.begin(), part->begin(), part->end() );

        std::list<osg::Vec3d>::iterator v1 = plist.begin(); ++v1;
        std::list<osg::Vec3d>::iterator v0 = plist.begin();
        std::list<osg::Vec3d>::iterator last = plist.end(); --last;

        while( v0 != last )
        {
            bool increment = true;

            osg::Vec3d& p0 = *v0;
            osg::Vec3d& p1 = *v1;
            bool lastSeg = v1 == last;
            osg::Vec3d seg = p1 - p0;

            //OE_NOTICE << "p0=" << p0 << " to " << "p1=" << p1 << std::endl;

            osg::Vec3d p0Rad, p1Rad;

            if (_resampleMode.value() == RESAMPLE_GREATCIRCLE || _resampleMode.value() == RESAMPLE_RHUMB)
            {
                p0Rad = osg::Vec3d(osg::DegreesToRadians(p0.x()), osg::DegreesToRadians(p0.y()), p0.z());
                p1Rad = osg::Vec3d(osg::DegreesToRadians(p1.x()), osg::DegreesToRadians(p1.y()), p1.z());
            }
                       
            //Compute the length of the segment
            double segLen = 0.0;
            switch (_resampleMode.value())
            {
            case RESAMPLE_LINEAR:
                segLen = seg.length();
                break;
            case RESAMPLE_GREATCIRCLE:
                segLen = GeoMath::distance(p0Rad.y(), p0Rad.x(), p1Rad.y(), p1Rad.x());
                break;
            case RESAMPLE_RHUMB:
                segLen = GeoMath::rhumbDistance(p0Rad.y(), p0Rad.x(), p1Rad.y(), p1Rad.x());
                break;
            }

            if ( segLen < _minLen.value() && !lastSeg && plist.size() > 2 )
            {
                v1 = plist.erase( v1 );
                increment = false;
            }
            else if ( segLen > _maxLen.value() )
            {
                //Compute the number of divisions to make
                int numDivs = (1 + (int)(segLen/_maxLen.value()));
                double newSegLen = segLen/(double)numDivs;
                seg.normalize();
                osg::Vec3d newPt;
                double newHeight;
                switch (_resampleMode.value())
                {
                case RESAMPLE_LINEAR:
                    {
                        newPt = p0 + seg * newSegLen;
                    }
                    break;
                case RESAMPLE_GREATCIRCLE:
                    {
                        double bearing = GeoMath::bearing(p0Rad.y(), p0Rad.x(), p1Rad.y(), p1Rad.x());
                        double lat,lon;
                        GeoMath::destination(p0Rad.y(), p0Rad.x(), bearing, newSegLen, lat, lon);
                        newHeight = p0Rad.z() + ( p1Rad.z() - p0Rad.z() ) / (double)numDivs;
                        newPt = osg::Vec3d(osg::RadiansToDegrees(lon), osg::RadiansToDegrees(lat), newHeight);
                    }
                    break;
                case RESAMPLE_RHUMB:
                    {
                        double bearing = GeoMath::rhumbBearing(p0Rad.y(), p0Rad.x(), p1Rad.y(), p1Rad.x());
                        double lat,lon;
                        GeoMath::rhumbDestination(p0Rad.y(), p0Rad.x(), bearing, newSegLen, lat, lon);
                        newHeight = p0Rad.z() + ( p1Rad.z() - p0Rad.z() ) / (double)numDivs;
                        newPt = osg::Vec3d(osg::RadiansToDegrees(lon), osg::RadiansToDegrees(lat), newHeight);
                    }
                    break;
                }
                
                if ( _perturbThresh.value() > 0.0 && _perturbThresh.value() < newSegLen )
                {
                    float r = 0.5 - (float)::rand()/(float)RAND_MAX;
                    newPt.x() += r;
                    newPt.y() += r;
                }
                v1 = plist.insert( v1, newPt );
            }

            if ( increment ) { ++v0; ++v1; }
        }

        part->clear();
        part->reserve( plist.size() );
        part->insert( part->begin(), plist.begin(), plist.end() );

        /*
        if ( origSize != part->size() )
        {
            OE_NOTICE << "Resampled part from " << origSize << " to " << part->size() << " points" << std::endl;
        }
        */
    }
    return success;
}

Here is the call graph for this function:

FilterContext ResampleFilter::push ( FeatureList input,
FilterContext context 
) [virtual]

Implements osgEarth::Features::FeatureFilter.

Definition at line 182 of file ResampleFilter.cpp.

{
    if ( !isSupported() )
    {
        OE_WARN << "ResampleFilter support not enabled" << std::endl;
        return context;
    }

    bool ok = true;
    for( FeatureList::iterator i = input.begin(); i != input.end(); ++i )
        if ( !push( i->get(), context ) )
            ok = false;

    return context;
}

Here is the call graph for this function:

Here is the caller graph for this function:

optional<ResampleMode>& osgEarth::Features::ResampleFilter::resampleMode ( ) [inline]

Definition at line 66 of file ResampleFilter.

{ return _resampleMode;}

Here is the caller graph for this function:

const optional<ResampleMode>& osgEarth::Features::ResampleFilter::resampleMode ( ) const [inline]

Definition at line 67 of file ResampleFilter.

{ return _resampleMode;}

Member Data Documentation

Definition at line 74 of file ResampleFilter.

Definition at line 74 of file ResampleFilter.

Definition at line 74 of file ResampleFilter.

Definition at line 75 of file ResampleFilter.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines