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