1 /* -*-c++-*- */
2 /* osgEarth - Geospatial SDK for OpenSceneGraph
3  * Copyright 2019 Pelican Mapping
4  * http://osgearth.org
5  *
6  * osgEarth is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>
18  */
19 #include <osgEarthFeatures/BufferFilter>
20 #include <osgEarthFeatures/FilterContext>
21 
22 #define LC "[BufferFilter] "
23 
24 using namespace osgEarth;
25 using namespace osgEarth::Features;
26 using namespace osgEarth::Symbology;
27 
28 bool
isSupported()29 BufferFilter::isSupported()
30 {
31 #ifdef OSGEARTH_HAVE_GEOS
32     static bool s_isSupported = true;
33 #else
34     static bool s_isSupported = false;
35 #endif
36 
37     return s_isSupported;
38 }
39 
40 #define ASSERT_SUPPORT() \
41     if ( !BufferFilter::isSupported() ) { \
42         OE_NOTICE << "BufferFilter NOT SUPPORTED - please compile osgEarth with GEOS" << std::endl; }
43 
44 OSGEARTH_REGISTER_SIMPLE_FEATUREFILTER(buffer, BufferFilter );
45 
BufferFilter()46 BufferFilter::BufferFilter() :
47 _distance   ( 1.0 ),
48 _numQuadSegs( 0 ),
49 _capStyle   ( Stroke::LINECAP_SQUARE )
50 {
51     //NOP
52 }
53 
BufferFilter(const BufferFilter & rhs)54 BufferFilter::BufferFilter( const BufferFilter& rhs ) :
55 _distance   ( rhs._distance ),
56 _numQuadSegs( rhs._numQuadSegs ),
57 _capStyle   ( rhs._capStyle )
58 {
59     //NOP
60 }
61 
BufferFilter(const Config & conf)62 BufferFilter::BufferFilter( const Config& conf ) :
63 _distance   ( 1.0 ),
64 _numQuadSegs( 0 ),
65 _capStyle   ( Stroke::LINECAP_SQUARE )
66 {
67     if (conf.key() == "buffer")
68     {
69         conf.get( "distance", _distance );
70     }
71 }
72 
getConfig() const73 Config BufferFilter::getConfig() const
74 {
75     Config config( "buffer" );
76     config.set( "distance", _distance);
77     return config;
78 }
79 
80 FilterContext
push(FeatureList & input,FilterContext & context)81 BufferFilter::push( FeatureList& input, FilterContext& context )
82 {
83     if ( !isSupported() )
84     {
85         OE_WARN << "BufferFilter support not enabled - please compile osgEarth with GEOS" << std::endl;
86         return context;
87     }
88 
89     //OE_NOTICE << "Buffer: input = " << input.size() << " features" << std::endl;
90     for( FeatureList::iterator i = input.begin(); i != input.end(); )
91     {
92         Feature* feature = i->get();
93         if ( !feature || !feature->getGeometry() )
94             continue;
95 
96         osg::ref_ptr<Symbology::Geometry> output;
97 
98         Symbology::BufferParameters params;
99 
100         params._capStyle =
101                 _capStyle == Stroke::LINECAP_ROUND  ? Symbology::BufferParameters::CAP_ROUND :
102                 _capStyle == Stroke::LINECAP_SQUARE ? Symbology::BufferParameters::CAP_SQUARE :
103                 _capStyle == Stroke::LINECAP_FLAT   ? Symbology::BufferParameters::CAP_FLAT :
104                                                       Symbology::BufferParameters::CAP_SQUARE;
105 
106         params._cornerSegs = _numQuadSegs;
107 
108         if ( feature->getGeometry()->buffer( _distance.value(), output, params ) )
109         {
110             feature->setGeometry( output.get() );
111             ++i;
112         }
113         else
114         {
115             i = input.erase( i );
116             OE_DEBUG << LC << "feature " << feature->getFID() << " yielded no geometry" << std::endl;
117         }
118     }
119 
120     return context;
121 }
122