osgEarth 2.1.1
|
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 #ifndef OSGEARTHSYMBOLOGY_GEOMETRY_H 00020 #define OSGEARTHSYMBOLOGY_GEOMETRY_H 1 00021 00022 #include <osgEarthSymbology/Common> 00023 #include <osgEarth/GeoData> 00024 #include <osgEarth/Utils> 00025 #include <vector> 00026 #include <stack> 00027 00028 namespace osgEarth { namespace Symbology 00029 { 00030 using namespace osgEarth; 00031 00033 class BufferParameters 00034 { 00035 public: 00036 enum CapStyle { CAP_DEFAULT, CAP_SQUARE, CAP_ROUND, CAP_FLAT }; 00037 enum JoinStyle { JOIN_ROUND, JOIN_MITRE, JOIN_BEVEL}; 00038 BufferParameters( CapStyle capStyle =CAP_DEFAULT, JoinStyle joinStyle = JOIN_ROUND, int cornerSegs =0, bool singleSided=false, bool leftSide=false ) 00039 : _capStyle(capStyle), _joinStyle(joinStyle),_cornerSegs(cornerSegs), _singleSided(singleSided), _leftSide(leftSide) { } 00040 CapStyle _capStyle; 00041 JoinStyle _joinStyle; 00042 int _cornerSegs; // # of line segment making up a rounded corner 00043 bool _singleSided; //Whether or not to do a single sided buffer 00044 bool _leftSide; //If doing a single sided buffer are we buffering to the left? If false, buffer to the right 00045 }; 00046 00047 typedef std::vector<osg::Vec3d> Vec3dVector; 00048 00053 class OSGEARTHSYMBOLOGY_EXPORT Geometry : public osgEarth::MixinVector<osg::Vec3d,osg::Referenced> 00054 { 00055 public: 00056 Geometry( const Vec3dVector* toCopy ); 00057 00058 public: 00059 enum Type { 00060 TYPE_UNKNOWN, 00061 TYPE_POINTSET, 00062 TYPE_LINESTRING, 00063 TYPE_RING, 00064 TYPE_POLYGON, 00065 TYPE_MULTI 00066 }; 00067 00068 static std::string toString( Type t ) { 00069 return 00070 t == TYPE_POINTSET ? "pointset" : 00071 t == TYPE_LINESTRING ? "linestring" : 00072 t == TYPE_RING ? "ring" : 00073 t == TYPE_POLYGON ? "polygon" : 00074 t == TYPE_MULTI ? "multi" : 00075 "unknown"; 00076 } 00077 00078 static Geometry* create( Type type, const Vec3dVector* toCopy ); 00079 00080 // true if osgEarth is compiled for buffering 00081 static bool hasBufferOperation(); 00082 00083 public: 00087 virtual int getTotalPointCount() const; 00088 00092 virtual unsigned getNumComponents() const { return 1; } 00093 00099 virtual unsigned getNumGeometries() const { return 1; } 00100 00105 virtual Geometry* cloneAs( const Geometry::Type& newType ) const; 00106 00111 osg::Vec3Array* toVec3Array() const; 00112 00117 osg::Vec3dArray* toVec3dArray() const; 00118 00122 virtual Bounds getBounds() const; 00123 00127 bool isLinear() const { return getComponentType() == TYPE_LINESTRING || getComponentType() == TYPE_RING; } 00128 00133 bool buffer( 00134 double distance, 00135 osg::ref_ptr<Geometry>& output, 00136 const BufferParameters& bp =BufferParameters() ) const; 00137 00142 bool crop( 00143 const class Polygon* cropPolygon, 00144 osg::ref_ptr<Geometry>& output ) const; 00145 00150 bool difference( 00151 const class Polygon* diffPolygon, 00152 osg::ref_ptr<Geometry>& output ) const; 00153 00158 osg::Vec3d localize(); 00159 00163 void delocalize( const osg::Vec3d& offset ); 00164 00165 public: 00166 virtual Type getType() const =0; 00167 virtual Type getComponentType() const { return getType(); } 00168 virtual bool isValid() const { return size() >= 1; } 00169 00170 virtual Geometry* clone() const { return cloneAs(getType()); } 00171 00172 protected: 00173 Geometry( int capacity =0 ); 00174 Geometry( const Geometry& rhs ); 00175 00176 Vec3dVector _data; 00177 }; 00178 00179 typedef std::vector< osg::ref_ptr<Geometry> > GeometryCollection; 00180 00184 class OSGEARTHSYMBOLOGY_EXPORT PointSet : public Geometry 00185 { 00186 public: 00187 PointSet( int capacity =0 ) : Geometry( capacity ) { } 00188 PointSet( const Vec3dVector* toCopy ) : Geometry( toCopy ) { } 00189 PointSet( const PointSet& rhs ); 00190 00191 public: 00192 virtual Type getType() const { return Geometry::TYPE_POINTSET; } 00193 }; 00194 00198 class OSGEARTHSYMBOLOGY_EXPORT LineString : public Geometry 00199 { 00200 public: 00201 LineString( int capacity =0 ) : Geometry( capacity ) { } 00202 LineString( const LineString& rhs ); 00203 LineString( const Vec3dVector* toCopy ); 00204 00205 double getLength() const; 00206 bool getSegment(double length, osg::Vec3d& start, osg::Vec3d& end); 00207 00208 public: 00209 virtual Type getType() const { return Geometry::TYPE_LINESTRING; } 00210 virtual bool isValid() const { return size() >= 2; } 00211 }; 00212 00218 class OSGEARTHSYMBOLOGY_EXPORT Ring : public Geometry 00219 { 00220 public: 00221 enum Orientation { 00222 ORIENTATION_CCW, 00223 ORIENTATION_CW, 00224 ORIENTATION_DEGENERATE 00225 }; 00226 00227 public: 00228 Ring( int capacity =0 ) : Geometry( capacity ) { } 00229 Ring( const Ring& ring ); 00230 Ring( const Vec3dVector* toCopy ); 00231 00232 // override 00233 virtual Geometry* cloneAs( const Geometry::Type& newType ) const; 00234 00235 // gets the ring's orientation 00236 Orientation getOrientation() const; 00237 00238 // tests whether the point falls withing the ring 00239 virtual bool contains2D( double x, double y ) const; 00240 00241 // gets the signed area of a part that is known to be open. 00242 virtual double getSignedArea2D() const; 00243 00244 // ensures that the first and last points are not idential. 00245 virtual void open(); 00246 00247 // opens and rewinds the ring to the specified orientation. 00248 void rewind( Orientation ori ); 00249 00250 public: 00251 virtual Type getType() const { return Geometry::TYPE_RING; } 00252 virtual bool isValid() const { return size() >= 3; } 00253 }; 00254 00255 typedef std::vector<osg::ref_ptr<Ring> > RingCollection; 00256 00262 class OSGEARTHSYMBOLOGY_EXPORT Polygon : public Ring 00263 { 00264 public: 00265 Polygon( int capacity =0 ) : Ring( capacity ) { } 00266 Polygon( const Polygon& rhs ); 00267 Polygon( const Vec3dVector* toCopy ); 00268 00269 public: 00270 virtual Type getType() const { return Geometry::TYPE_POLYGON; } 00271 virtual int getTotalPointCount() const; 00272 00273 virtual unsigned getNumGeometries() const { return 1 + _holes.size(); } 00274 00275 // tests whether the point falls withing the polygon (but not its holes) 00276 virtual bool contains2D( double x, double y ) const; 00277 00278 virtual void open(); 00279 00280 public: 00281 RingCollection& getHoles() { return _holes; } 00282 const RingCollection& getHoles() const { return _holes; } 00283 00284 protected: 00285 RingCollection _holes; 00286 }; 00287 00291 class OSGEARTHSYMBOLOGY_EXPORT MultiGeometry : public Geometry 00292 { 00293 public: 00294 MultiGeometry() { } 00295 MultiGeometry( const GeometryCollection& parts ); 00296 MultiGeometry( const MultiGeometry& rhs ); 00297 00298 public: 00299 virtual Type getType() const { return Geometry::TYPE_MULTI; } 00300 virtual Type getComponentType() const; 00301 virtual int getTotalPointCount() const; 00302 virtual unsigned getNumComponents() const { return _parts.size(); } 00303 00304 virtual unsigned getNumGeometries() const; 00305 00306 // override 00307 virtual Geometry* cloneAs( const Geometry::Type& newType ) const; 00308 virtual bool isValid() const; 00309 virtual Bounds getBounds() const; 00310 00311 public: 00312 GeometryCollection& getComponents() { return _parts; } 00313 const GeometryCollection& getComponents() const { return _parts; } 00314 00315 protected: 00316 GeometryCollection _parts; 00317 }; 00318 00325 class OSGEARTHSYMBOLOGY_EXPORT GeometryIterator 00326 { 00327 public: 00337 GeometryIterator( 00338 Geometry* geom, 00339 bool traversePolygonHoles =true ); 00340 00341 bool hasMore() const; 00342 Geometry* next(); 00343 00344 private: 00345 Geometry* _next; 00346 std::stack<Geometry*> _stack; 00347 bool _traverseMulti; 00348 bool _traversePolyHoles; 00349 00350 void fetchNext(); 00351 }; 00352 00353 class OSGEARTHSYMBOLOGY_EXPORT ConstGeometryIterator 00354 { 00355 public: 00365 ConstGeometryIterator( 00366 const Geometry* geom, 00367 bool traversePolygonHoles =true ); 00368 00369 bool hasMore() const; 00370 const Geometry* next(); 00371 00372 private: 00373 const Geometry* _next; 00374 std::stack<const Geometry*> _stack; 00375 bool _traverseMulti; 00376 bool _traversePolyHoles; 00377 00378 void fetchNext(); 00379 }; 00380 00381 typedef std::pair<osg::Vec3d, osg::Vec3d> Segment; 00382 00383 class OSGEARTHSYMBOLOGY_EXPORT ConstSegmentIterator 00384 { 00385 public: 00386 ConstSegmentIterator( const Geometry* verts, bool closedLoop ); 00387 bool hasMore() const { return !_done; } 00388 Segment next(); 00389 00390 private: 00391 const Vec3dVector* _verts; 00392 Vec3dVector::const_iterator _iter; 00393 bool _done; 00394 bool _closeLoop; 00395 }; 00396 00397 typedef std::vector<osg::ref_ptr<Geometry> > GeometryList; 00398 00399 } } // namespace osgEarth::Symbology 00400 00401 00402 #endif // OSGEARTHSYMBOLOGY_GEOMETRY_H 00403