osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarthFeatures/CropFilter.cpp

Go to the documentation of this file.
00001 /* -*-c++-*- */
00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
00003  * Copyright 2008-2010 Pelican Mapping
00004  * http://osgearth.org
00005  *
00006  * osgEarth is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU Lesser General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses/>
00018  */
00019 #include <osgEarthFeatures/CropFilter>
00020 
00021 #define LC "[CropFilter] "
00022 
00023 using namespace osgEarth;
00024 using namespace osgEarth::Features;
00025 using namespace osgEarth::Symbology;
00026 
00027 CropFilter::CropFilter( CropFilter::Method method ) :
00028 _method( method )
00029 {
00030     //nop
00031 }
00032 
00033 FilterContext
00034 CropFilter::push( FeatureList& input, FilterContext& context )
00035 {
00036     if ( !context.extent().isSet() )
00037     {
00038         OE_WARN << LC << "Extent is not set (and is required)" << std::endl;
00039         return context;
00040     }
00041 
00042     const GeoExtent& extent = *context.extent();
00043 
00044     GeoExtent newExtent( extent.getSRS() );
00045 
00046     if ( _method == METHOD_CENTROID )
00047     {
00048         for( FeatureList::iterator i = input.begin(); i != input.end();  )
00049         {
00050             bool keepFeature = false;
00051 
00052             Feature* feature = i->get();
00053             Geometry* featureGeom = feature->getGeometry();
00054 
00055             if ( featureGeom && featureGeom->isValid() )
00056             {
00057                 Bounds bounds = featureGeom->getBounds();
00058                 if ( bounds.isValid() )
00059                 {
00060                     osg::Vec3d centroid = bounds.center();
00061                     if ( extent.contains( centroid.x(), centroid.y() ) )
00062                     {
00063                         keepFeature = true;
00064                         newExtent.expandToInclude( bounds );
00065                     }
00066                 }
00067             }
00068 
00069             if ( keepFeature )
00070                 ++i;
00071             else
00072                 i = input.erase( i );
00073         }
00074     }
00075 
00076     else // METHOD_CROPPING (requires GEOS)
00077     {
00078 #ifdef OSGEARTH_HAVE_GEOS
00079 
00080         // create the intersection polygon:
00081         osg::ref_ptr<Symbology::Polygon> poly;
00082         
00083         for( FeatureList::iterator i = input.begin(); i != input.end();  )
00084         {
00085             bool keepFeature = false;
00086 
00087             Feature* feature = i->get();
00088             Symbology::Geometry* featureGeom = feature->getGeometry();
00089             if ( featureGeom && featureGeom->isValid() )
00090             {
00091                 // test for trivial acceptance:
00092                 const Bounds bounds = featureGeom->getBounds();
00093                 if ( !bounds.isValid() )
00094                 {
00095                     //nop
00096                 }
00097 
00098                 else if ( extent.contains( bounds ) )
00099                 {
00100                     keepFeature = true;
00101                     newExtent.expandToInclude( bounds );
00102                 }
00103 
00104                 // then move on to the cropping operation:
00105                 else
00106                 {
00107                     if ( !poly.valid() )
00108                     {
00109                         poly = new Symbology::Polygon();
00110                         poly->push_back( osg::Vec3d( extent.xMin(), extent.yMin(), 0 ));
00111                         poly->push_back( osg::Vec3d( extent.xMax(), extent.yMin(), 0 ));
00112                         poly->push_back( osg::Vec3d( extent.xMax(), extent.yMax(), 0 ));
00113                         poly->push_back( osg::Vec3d( extent.xMin(), extent.yMax(), 0 ));
00114                     }
00115 
00116                     osg::ref_ptr<Geometry> croppedGeometry;
00117                     if ( featureGeom->crop( poly.get(), croppedGeometry ) )
00118                     {
00119                         if ( croppedGeometry->isValid() )
00120                         {
00121                             feature->setGeometry( croppedGeometry.get() );
00122                             keepFeature = true;
00123                             newExtent.expandToInclude( croppedGeometry->getBounds() );
00124                         }
00125                     }
00126                 }
00127             }
00128 
00129             if ( keepFeature )
00130                 ++i;
00131             else
00132                 i = input.erase( i );
00133         }  
00134 
00135 #else // OSGEARTH_HAVE_GEOS
00136 
00137         OE_WARN << "CropFilter - METHOD_CROPPING not available - please compile osgEarth with GEOS" << std::endl;
00138         return context;
00139 
00140 #endif
00141     }
00142 
00143     FilterContext newContext = context;
00144     newContext.extent() = newExtent;
00145 
00146     return newContext;
00147 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines