region2d.h

Go to the documentation of this file.
00001 /**
00002  * \file region2d.h <mi32/region2d.h>
00003  * \brief Functions and structure for regions
00004  *
00005  * \if NODOC
00006  * $Id: region2d.h_v 1.55 2005/11/11 16:27:49 dfriberg Exp $
00007  *
00008  * $Log: region2d.h_v $
00009  * Revision 1.55  2005/11/11 16:27:49  dfriberg
00010  * GetNumIslands returns 0 if no polylines in subregion2d
00011  *
00012  * Revision 1.54  2005/09/29 20:17:02  scowan
00013  * Added method to generate a point inside a subregion.
00014  *
00015  * Revision 1.53  2005/06/06 17:40:08  scowan
00016  * Added testRegion method that takes a region2d.
00017  *
00018  * Revision 1.52  2005/06/02 20:54:00  scowan
00019  * Added method to sub region to add valid polyline list.
00020  *
00021  * Revision 1.51  2005/03/10 21:56:50  mju
00022  * Add copyfilter and copyTo methods for subregion and region.
00023  *
00024  * Revision 1.50  2005/03/09 15:44:47  mju
00025  * Make binarytoregion2d a friend.
00026  *
00027  * Revision 1.49  2005/03/03 22:16:03  scowan
00028  * Added remove islands method.
00029  *
00030  * Revision 1.48  2004/12/29 17:02:17  scowan
00031  * Added method to append subregion to region for cad drawing.
00032  *
00033  * Revision 1.47  2004/11/16 17:15:04  dwilliss
00034  * Added ConvertToLongTruncate
00035  *
00036  * Revision 1.46  2004/09/21 17:31:30  mju
00037  * Add clearCoordRefSys.
00038  *
00039  * Revision 1.45  2004/08/30 17:01:42  scowan
00040  * Added reverse method.
00041  *
00042  * Revision 1.44  2004/08/17 21:30:43  mju
00043  * Add updateExtentsRect for subregion and region.
00044  *
00045  * Revision 1.43  2004/08/09 23:54:01  scowan
00046  * Added set orientation methods.
00047  *
00048  * Revision 1.42  2004/07/27 15:22:34  scowan
00049  * Added private method.
00050  *
00051  * Revision 1.41  2004/07/20 16:02:18  scowan
00052  * Removed legacy region methods.
00053  *
00054  * Revision 1.40  2004/07/16 17:31:13  scowan
00055  * Added some friends.
00056  *
00057  * Revision 1.39  2004/07/09 22:26:17  scowan
00058  * Updated docs to the changes in the region code.
00059  *
00060  * Revision 1.38  2004/07/08 13:21:19  mju
00061  * Add region2d ctor/op= from subregion2d.
00062  *
00063  * Revision 1.37  2004/06/29 20:58:05  scowan
00064  * Added mem func preventors.
00065  *
00066  * Revision 1.36  2004/06/29 17:03:59  scowan
00067  * Change docs.
00068  *
00069  * Revision 1.35  2004/06/29 16:37:50  scowan
00070  * Added comments about conversion.
00071  *
00072  * Revision 1.34  2004/06/28 20:29:43  scowan
00073  * *** empty log message ***
00074  *
00075  * Revision 1.33  2004/06/28 20:29:02  scowan
00076  * Added convert to method.
00077  *
00078  * Revision 1.32  2004/06/25 21:31:47  mju
00079  * Make serializer a friend.
00080  *
00081  * Revision 1.31  2004/06/25 15:10:12  scowan
00082  * Added deprecated method to get legacy region.
00083  *
00084  * Revision 1.30  2004/06/24 20:18:22  dwilliss
00085  * forward declare COORDOP
00086  *
00087  * Revision 1.29  2004/06/24 16:00:16  scowan
00088  * Added method to set the z range.
00089  *
00090  * Revision 1.28  2004/06/24 14:55:31  scowan
00091  * Added convert methods for coord op.
00092  *
00093  * Revision 1.27  2004/06/23 22:53:39  scowan
00094  * Added coord ref sys to region2d.
00095  *
00096  * Revision 1.26  2004/03/30 22:02:13  scowan
00097  * Added get numislands method.
00098  *
00099  * Revision 1.25  2004/03/02 15:23:10  scowan
00100  * Something.
00101  *
00102  * Revision 1.24  2004/03/02 15:11:46  scowan
00103  * Removed defines when done.
00104  *
00105  * Revision 1.23  2004/03/02 00:24:47  scowan
00106  * Export from geom the class.
00107  *
00108  * Revision 1.22  2003/11/28 16:52:25  scowan
00109  * Added threshold to is equiv to method.
00110  *
00111  * Revision 1.21  2003/11/25 00:30:28  scowan
00112  * Added is equivalent to methods.
00113  *
00114  * Revision 1.20  2003/09/26 21:52:25  scowan
00115  * Added flag to convert legacy region dest to new region.
00116  *
00117  * Revision 1.19  2003/09/15 13:49:56  fileserver!dwilliss
00118  * Doxygen
00119  *
00120  * Revision 1.18  2003/09/09 17:56:39  scowan
00121  * Added another convert to long method.
00122  *
00123  * Revision 1.17  2003/08/27 21:31:04  scowan
00124  * Removed map proj param from assign method.
00125  *
00126  * Revision 1.16  2003/06/12 19:45:15  scowan
00127  * More const.
00128  *
00129  * Revision 1.15  2003/06/11 16:03:36  scowan
00130  * nc.
00131  *
00132  * Revision 1.14  2003/06/06 21:34:56  scowan
00133  * Added methods.
00134  *
00135  * Revision 1.13  2003/05/08 22:27:01  scowan
00136  * Chagned to use a 3d rect.
00137  *
00138  * Revision 1.12  2003/05/07 15:26:22  scowan
00139  * *** empty log message ***
00140  *
00141  * Revision 1.11  2003/05/07 15:24:56  scowan
00142  * Added test and assignment methods.
00143  *
00144  * Revision 1.10  2003/04/23 21:59:00  scowan
00145  * Added methods.
00146  *
00147  * Revision 1.9  2002/12/10 18:16:21  scowan
00148  * Added more friends.
00149  *
00150  * Revision 1.8  2002/11/26 21:30:17  dwilliss
00151  * never mind...
00152  *
00153  * Revision 1.7  2002/11/21 18:59:48  dwilliss
00154  * Added constructor taking MILIST<POLYLINE>&
00155  *
00156  * Revision 1.6  2002/11/13 18:22:28  scowan
00157  * Added begin and end iterators for both classes.
00158  *
00159  * Revision 1.5  2002/10/23 16:27:58  scowan
00160  * Code completed, not tested.
00161  *
00162  * Revision 1.4  2002/10/22 22:24:29  scowan
00163  * Added parameters.
00164  *
00165  * Revision 1.3  2002/10/11 21:47:06  scowan
00166  * Added intersect code.
00167  *
00168  * Revision 1.2  2002/10/11 17:07:41  scowan
00169  * Allowed vector interface class as a friend.
00170  *
00171  * Revision 1.1  2002/10/09 22:32:03  scowan
00172  * Initial revision
00173  *
00174  * \endif
00175 **/
00176 
00177 #ifndef  INC_MI32_REGION2D_H
00178 #define  INC_MI32_REGION2D_H
00179 
00180 #ifndef  INC_MI32_POLYLINE_H
00181    #include <mi32/polyline.h>
00182 #endif
00183 
00184 #ifndef  INC_MI32_RECT_H
00185    #include <mi32/rect.h>
00186 #endif
00187 
00188 #ifndef  INC_MI32_MILIST_H
00189    #include <mi32/milist.h>
00190 #endif
00191 
00192 #ifndef  INC_MI32_SPATREF_H
00193    #include <mi32/spatref.h>
00194 #endif
00195 
00196 #ifdef GEOMDLL
00197    #define GEOMLIBEXPORT MI_DLLEXPORT
00198    #define GEOMLIBCLASSEXPORT MI_DLLCLASSEXPORT
00199 #else
00200    #define GEOMLIBEXPORT MI_DLLIMPORT
00201    #define GEOMLIBCLASSEXPORT MI_DLLCLASSIMPORT
00202 #endif
00203 
00204 #ifndef GENERATING_DOXYGEN_OUTPUT
00205 class TRANS2D_AFFINE;      //!< Forward declarations
00206 class TRANS2D_MAPGEN;
00207 class REGION2D;
00208 class SERIALIZER;
00209 class BINARYTOREGION2D;
00210 namespace RVC {
00211    class VECTOR;
00212    class REGION;
00213    class REGIONHANDLE;
00214    }
00215 namespace SPATREF {
00216    class COORDOP;
00217    }
00218 #endif //!< GENERATING_DOXYGEN_OUTPUT
00219 #pragma warning(disable:4251) // Stop complaining about the need to have a dll interface
00220 
00221 //! SUBREGION2D class - Definitions and methods to support a generic 2D sub-region object in memory.
00222 //! The sub-region can be represented by either a single rectangle or as a polygon and a list of zero
00223 //! or more islands.  All POLYLINE's stored in the SUBREGION are closed.
00224 
00225 class GEOMLIBCLASSEXPORT SUBREGION2D {
00226    public:
00227    
00228       typedef MILIST<POLYLINE>::CONST_ITERATOR CONST_ITERATOR;
00229 
00230       //! Filter for copying subregion.
00231       class GEOMLIBCLASSEXPORT COPYFILTER {
00232          public:
00233             //! Constructor.
00234             COPYFILTER ();
00235             //! Destructor.
00236             virtual ~COPYFILTER () = 0;
00237             //! Determine if island should be included.
00238             bool IsIslandIncluded (
00239                const POLYLINE& island
00240                ) { return (v_IsIslandIncluded(island)); }
00241          private:
00242             //! Override to determine if island should be included.
00243             //! Default implementation always returns true.
00244             virtual bool v_IsIslandIncluded (
00245                const POLYLINE& island
00246                );
00247          };
00248    
00249       //! Default Constructor
00250       SUBREGION2D (
00251          );
00252          
00253       //! Copy Constructor
00254       SUBREGION2D (
00255          const SUBREGION2D& rhs
00256          );
00257          
00258       //! Constructor from DRECT2D
00259       SUBREGION2D (
00260          const DRECT2D& rect
00261          );
00262          
00263       //! Destructor
00264       ~SUBREGION2D (
00265          );
00266          
00267       //! Assignment operator
00268       SUBREGION2D& operator= (
00269          const SUBREGION2D& rhs
00270          );
00271 
00272       //! Assignment operator from rectangle
00273       SUBREGION2D& operator= (
00274          const DRECT2D& rhs
00275          );
00276 
00277       //! Assigns the sub-region to the passed in polygon
00278       //! This will clear any existing information in 'this'
00279       ERRVALUE Assign (
00280          const POLYLINE& Polygon
00281          );
00282 
00283       //! Assigns the sub-region to the passed in polygon.
00284       //! A validated polygon is a polygon that does not intersect itself.
00285       //! This will clear any existing information in 'this'
00286       void AssignValidated (
00287          const POLYLINE& Polygon
00288          );
00289          
00290       //! Assigns the sub-region to the passed in polygon list.  
00291       //! Assumes that the first polygon is the shell and the rest are islands.
00292       //! A validated polygon is a polygon that does not intersect itself.
00293       //! This will clear any existing information in 'this'
00294       void AssignValidated (
00295          const POLYLINELIST& PolygonList
00296          );
00297          
00298       //! Get the beginning of the list of POLYLINE's.
00299       //! The first item is the shell polygon, the rest following are islands.
00300       //! @return Iterator to the beginning of the POLYLINE list
00301       CONST_ITERATOR Begin (
00302          ) const { return (m_ItemList.Begin()); }
00303 
00304       //! Clear the sub-region
00305       void Clear (
00306          );
00307          
00308       //! Clip a polyline to a sub-region, call the ClipTarget for each segment
00309       //! @return TRUE if part of the line is clipped, FALSE if not, < 0 error
00310       int ClipLine (
00311          POLYLINE& PolyLine,
00312          POLYLINE::CLIP& ClipTarget,
00313          CLIPMODE ClipMode = CLIPMODE_Inside
00314          ) const;
00315          
00316       //! Compute the sub-region area in sub-region units
00317       double ComputeArea (
00318          ) const;
00319    
00320       //! Compute the sub-region area in sub-region units but do not exclude islands in the calculation
00321       double ComputeAreaNoIslands (
00322          ) const;
00323    
00324       //! Compute the sub-region perimeter in sub-region units
00325       double ComputePerimeter (
00326          ) const;
00327    
00328       //! Compute the sub-region perimeter in sub-region units but do not include islands in the calculation
00329       double ComputePerimeterNoIslands (
00330          ) const;
00331    
00332       //! Translate the sub-region using an affine transformation
00333       void ConvertForward (
00334          const TRANS2D_AFFINE& taf
00335          );
00336    
00337       //! Translate the sub-region using a mapgen transformation
00338       ERRVALUE ConvertForward (
00339          const TRANS2D_MAPGEN& tmg
00340          );
00341    
00342       //! Translate the subregion using a coordinate operation (SPATREF::COORDOP) transformation
00343       ERRVALUE ConvertForward (
00344          const SPATREF::COORDOP& Op
00345          );
00346    
00347       //! Translate the sub-region using a mapgen transformation with densification
00348       //! If the sub-region is the extents only, this will convert it to a polygon sub-region
00349       //! before doing the transformation
00350       ERRVALUE ConvertForwardDense (
00351          const TRANS2D_MAPGEN& tmg
00352          );
00353    
00354       //! Translate the region using a coordinate operation (SPATREF::COORDOP) transformation with densification
00355       //! If the region is the extents only, this will convert it to a proper sub-region
00356       //! before doing the transformation
00357       ERRVALUE ConvertForwardDense (
00358          const SPATREF::COORDOP& Op,
00359          double tolerance
00360          );
00361 
00362       //! Translate the sub-region using an affine transformation
00363       void ConvertInverse (
00364          const TRANS2D_AFFINE& taf
00365          );
00366    
00367       //! Translate the sub-region using a mapgen transformation
00368       ERRVALUE ConvertInverse (
00369          const TRANS2D_MAPGEN& tmg
00370          );
00371    
00372       //! Translate the sub-region using a mapgen transformation with densification
00373       //! If the sub-region is the extents only, this will convert it to a polygon sub-region
00374       //! before doing the transformation
00375       ERRVALUE ConvertInverseDense (
00376          const TRANS2D_MAPGEN& tmg
00377          );
00378          
00379       //! Translate the subregion using a coordinate operation (SPATREF::COORDOP) transformation
00380       ERRVALUE ConvertReverse (
00381          const SPATREF::COORDOP& Op
00382          );
00383    
00384       //! Translate the subregion using a coordinate operation (SPATREF::COORDOP) transformation with densification
00385       //! If the subregion is the extents only, this will convert it to a proper sub-region
00386       //! before doing the transformation
00387       ERRVALUE ConvertReverseDense (
00388          const SPATREF::COORDOP& Op,
00389          double tolerance
00390          );
00391    
00392       //! Convert subregion from double's to INT32's with rounding, removes duplicate points
00393       ERRVALUE ConvertToLongRound (
00394          SIMPLE_ARRAY<LPOLYGON>& PolygonArray,
00395          SIMPLE_ARRAY<LPOINT2D>& PointArray
00396          ) const;
00397    
00398       //! Convert subregion from double's to INT32's, truncating towards 0, removes duplicate points
00399       ERRVALUE ConvertToLongTruncate (
00400          SIMPLE_ARRAY<LPOLYGON>& PolygonArray,
00401          SIMPLE_ARRAY<LPOINT2D>& PointArray
00402          ) const;
00403 
00404       //! Copy subregion to specified target with filter.
00405       ERRVALUE CopyTo (
00406          SUBREGION2D& target,                      //!< Target subregion
00407          COPYFILTER& filter                        //!< Filter to determine which islands to copy
00408          ) const;
00409    
00410       //! Get the end of the list of POLYLINE's
00411       //! @return End of POLYLINE list, see Begin() for details
00412       CONST_ITERATOR End (
00413          ) const { return (m_ItemList.End()); }
00414 
00415       //! Generate a point inside of the subregion
00416       //! This does deal with the islands of the subregion, the point will not be in an island.
00417       ERRVALUE GeneratePointInside (
00418          DPOINT2D& PointInside
00419          ) const;
00420          
00421       //! Get sub-region extents
00422       //! @return Extents of the sub-region
00423       const DRECT3D& GetExtents (
00424          ) const { return (m_Extents); }
00425    
00426       //! Get sub-region extents
00427       //! @return Extents of the sub-region
00428       const DRECT2D& GetExtents2D (
00429          ) const { return (m_Extents); }
00430    
00431       //! Get number of islands in the sub-region
00432       //! @return Number of islands in the sub-region
00433       INT32 GetNumIslands (
00434          ) const { return (IsEmpty() ? 0 : m_ItemList.GetNumItems()-1); }
00435    
00436       //! Intersect an specified rectangle area with the sub-region
00437       //! If the rectangle does not intersect with the sub-region area, 'this' will be set to empty
00438       ERRVALUE Intersect (
00439          const DRECT2D& Rect,
00440          MILIST<SUBREGION2D>& SubRegionList        //!< Filled in if operation creates more than one sub-region
00441          );
00442 
00443       //! Intersect an specified area against the sub-region
00444       //! If the polygon does not intersect the sub-region area, 'this' will be set to empty
00445       //! If the "PolyLine" passed in is invalid, this method will only use one of the 
00446       //! valid polygons it finds, otherwise the results will be in error.
00447       ERRVALUE Intersect (
00448          const POLYLINE& PolyLine,
00449          MILIST<SUBREGION2D>& SubRegionList        //!< Filled in if operation creates more than one sub-region
00450          );
00451 
00452       //! Intersect an specified area against the sub-region
00453       //! If the "SubRegion" does not intersect with the sub-region area, 'this' will be set to empty
00454       ERRVALUE Intersect (
00455          const SUBREGION2D& SubRegion,
00456          MILIST<SUBREGION2D>& SubRegionList        //!< Filled in if operation creates more than one sub-region
00457          );
00458 
00459       //! Intersect an specified area from the sub-region known to be valid
00460       //! A validated polygon is a polygon that does not intersect itself.
00461       //! If the polygon does not intersect the sub-region area, 'this' will be set to empty
00462       ERRVALUE IntersectValidated (
00463          const POLYLINE& PolyLine,
00464          MILIST<SUBREGION2D>& SubRegionList        //!< Filled in if operation creates more than one sub-region
00465          );
00466          
00467       //! Determine if the two subregions are equivalent 
00468       //! This method uses "Fuzzy" vertex comparisons and the direction and order of the elements are not relevant
00469       //! Specify a different threshold to allow greater distances
00470       //! @return 'True' if they are, 'False' if not
00471       bool IsEquivalentTo (
00472          const SUBREGION2D& rhs,
00473          double threshold = 0.0        //!< Default threshold is max absolute value of rectangle coordinate * 1.0E-13
00474          ) const;
00475    
00476       //! Determine if the point falls inside the sub-region
00477       //! @return 'True' if point is inside the sub-region, 'false' if not
00478       bool IsPointInside (
00479          const DPOINT2D& point
00480          ) const;
00481    
00482       //! Is the sub-region an empty sub-region
00483       bool IsEmpty (
00484          ) const { return (!m_Extents.IsValid()); }
00485 
00486       //! Is the sub-region a simple rectangle region?         
00487       bool IsRectangle (
00488          ) const { return (m_IsRectangle); }
00489 
00490       //! Remove all of the islands from the subregion
00491       void RemoveIslands (
00492          );
00493          
00494       //! Reverse the orientation of the polygons and islands in the subregion
00495       void Reverse (
00496          );
00497 
00498       //! Set subregion orientation
00499       //! Outer shell polygon is set to the orientation specified in respect to itself. 
00500       //! Islands are set in the opposite orientation in respect to themselves
00501       void SetOrientation (
00502          ORIENTATION Orientation
00503          );
00504          
00505       //! Remove an specified area from the sub-region
00506       //! If the island removes the entire sub-region area, 'this' will be set to empty
00507       //! If the "Island" passed in is invalid, this method will only use one of the 
00508       //! valid polygons it finds, otherwise the results will be in error.
00509       ERRVALUE Subtract (
00510          const POLYLINE& Island,
00511          MILIST<SUBREGION2D>& SubRegionList        //!< Filled in if operation creates more than one sub-region
00512          );
00513 
00514       //! Remove an specified area from the sub-region
00515       //! If the "SubRegion" removes the entire sub-region area, 'this' will be set to empty
00516       ERRVALUE Subtract (
00517          const SUBREGION2D& SubRegion,
00518          MILIST<SUBREGION2D>& SubRegionList        //!< Filled in if operation creates more than one sub-region
00519          );
00520 
00521       //! Remove an specified rectangle area from the sub-region
00522       //! If the island removes the entire sub-region area, 'this' will be set to empty
00523       ERRVALUE Subtract (
00524          const DRECT2D& IslandRect,
00525          MILIST<SUBREGION2D>& SubRegionList        //!< Filled in if operation creates more than one sub-region
00526          );
00527 
00528       //! Remove an specified area from the sub-region known to be valid
00529       //! A validated polygon is a polygon that does not intersect itself.
00530       //! If the island removes the entire sub-region area, 'this' will be set to empty
00531       ERRVALUE SubtractValidated (
00532          const POLYLINE& Island,
00533          MILIST<SUBREGION2D>& SubRegionList        //!< Filled in if operation creates more than one sub-region
00534          );
00535          
00536       //! Test the line given the test criteria against the sub-region
00537       //! @return "True" if the line meets the criteria, "false" if not
00538       bool TestLine (
00539          const POLYLINE& PolyLine,
00540          TESTCRITERIA TestCriteria
00541          ) const;
00542 
00543       //! Test the line against the sub-region
00544       //! @return POLYLINE::COMPRESULT
00545       POLYLINE::COMPRESULT TestLine (
00546          const POLYLINE& PolyLine
00547          ) const;
00548 
00549       //! Test the point given the test criteria against the sub-region
00550       //! @return "True" if the point meets the criteria, "false" if not
00551       bool TestPoint (
00552          const DPOINT2D& Point,
00553          TESTCRITERIA TestCriteria
00554          ) const;
00555 
00556       //! Test the polygon given the test criteria against the sub-region
00557       //! @return "True" if the polygon meets the criteria, "false" if not
00558       bool TestPolygon (
00559          const POLYLINE& PolyLine,
00560          TESTCRITERIA TestCriteria
00561          ) const;
00562 
00563       //! Test the polygon against the sub-region
00564       //! @return POLYLINE::COMPRESULT
00565       POLYLINE::COMPRESULT TestPolygon (
00566          const POLYLINE& PolyLine
00567          ) const;
00568 
00569       //! Test the subregion given the test criteria against 'this'
00570       //! @return "True" if the subregion meets the criteria, "false" if not
00571       bool TestSubRegion (
00572          const SUBREGION2D& SubRegion,
00573          TESTCRITERIA TestCriteria
00574          ) const;
00575 
00576       //! Test the subregion against 'this'
00577       //! @return POLYLINE::COMPRESULT
00578       POLYLINE::COMPRESULT TestSubRegion (
00579          const SUBREGION2D& SubRegion
00580          ) const;
00581 
00582       //! Union (ADD) a rectangle to the sub-region
00583       ERRVALUE Union (
00584          const DRECT2D& Rect,
00585          MILIST<SUBREGION2D>& SubRegionList,       //!< Filled in if operation creates more than one sub-region
00586          POLYLINE::COMBINERESULT& CombineResult
00587          );
00588 
00589       //! Union (ADD) a Polygon to the sub-region
00590       ERRVALUE Union (
00591          const POLYLINE& PolyLine,
00592          MILIST<SUBREGION2D>& SubRegionList        //!< Filled in if operation creates more than one sub-region
00593          );
00594 
00595       //! Union (ADD) a sub-region to the sub-region
00596       ERRVALUE Union (
00597          const SUBREGION2D& SubRegion,
00598          MILIST<SUBREGION2D>& SubRegionList,       //!< Filled in if operation creates more than one sub-region
00599          POLYLINE::COMBINERESULT& CombineResult
00600          );
00601 
00602       //! Union (ADD) a polygon to the sub-region
00603       ERRVALUE UnionValidated (
00604          const POLYLINE& PolyLine,
00605          MILIST<SUBREGION2D>& SubRegionList,       //!< Filled in if operation creates more than one sub-region
00606          POLYLINE::COMBINERESULT& CombineResult
00607          );
00608          
00609    private:
00610       #ifndef GENERATING_DOXYGEN_OUTPUT
00611    
00612       POLYLINELIST m_ItemList;
00613       DRECT3D m_Extents;
00614       bool m_IsRectangle;
00615       
00616       void UpdateExtentsRect ();
00617       ERRVALUE UpdateFromShells (MILIST<POLYLINE>& PolyLineList, MILIST<SUBREGION2D>& SubRegionList);
00618    
00619       friend class RVC::VECTOR;        //!< For RVC::VECTOR::ReadSubRegion() and RVC::VECTOR::ReadRegion()
00620       friend class RVC::REGION;        //!< For RVC::REGION::GetRegion() and RVC::REGION::SetRegion()
00621       friend class REGION2D;           //!< For RVC::REGION::Assign()
00622       friend class RVC::REGIONHANDLE;
00623       friend class BINARYTOREGION2D;
00624       friend class SERIALIZER;
00625       #endif // GENERATING_DOXYGEN_OUTPUT
00626    };
00627          
00628 
00629 //! REGION2D class - Definitions and methods to support a generic 2D region object in memory.  
00630 //! The region can be represented by either a single rectangle or as a list of sub-regions.
00631 class GEOMLIBCLASSEXPORT REGION2D {
00632    public:
00633 
00634       typedef MILIST<SUBREGION2D>::CONST_ITERATOR CONST_ITERATOR;
00635       
00636       //! Filter for copying region.
00637       class GEOMLIBCLASSEXPORT COPYFILTER : public SUBREGION2D::COPYFILTER {
00638          public:
00639             //! Constructor.
00640             COPYFILTER ();
00641             //! Destructor.
00642             virtual ~COPYFILTER () = 0;
00643             //! Determine if subregion should be included.
00644             bool IsSubRegionIncluded (
00645                const SUBREGION2D& subregion
00646                ) { return (v_IsSubRegionIncluded(subregion)); }
00647          private:
00648             //! Override to determine if subregion should be included.
00649             //! Default implementation always returns true.
00650             virtual bool v_IsSubRegionIncluded (
00651                const SUBREGION2D& subregion
00652                );
00653          };
00654    
00655       //! Default constructor, initializes to an invalid region      
00656       REGION2D (
00657          );
00658    
00659       //! Copy constructor
00660       REGION2D (
00661          const REGION2D& rhs
00662          );
00663    
00664       //! Constructor from DRECT2D
00665       REGION2D (
00666          const DRECT2D& rhs
00667          );
00668 
00669       //! Constructor from SUBREGION2D.
00670       REGION2D (
00671          const SUBREGION2D& SubRegion
00672          );
00673    
00674       //! Constructor from a list of polylines
00675       REGION2D (
00676          const MILIST<POLYLINE>&
00677          );
00678    
00679       //! Destructor
00680       ~REGION2D (
00681          );
00682          
00683       //! Assignment
00684       REGION2D& operator= (
00685          const REGION2D& rhs
00686          );
00687          
00688       //! Assignment from DRECT2D.
00689       REGION2D& operator= (
00690          const DRECT2D& rhs
00691          );
00692 
00693       //! Assignment from SUBREGION2D.
00694       REGION2D& operator= (
00695          const SUBREGION2D& SubRegion
00696          );
00697          
00698       //! Add a sub-region to the list without validating it.  Used for CAD rendering.
00699       void AddSubRegion (
00700          const SUBREGION2D& SubRegion
00701          );
00702    
00703       //! Assign from a POLYLINE and an index array defining how the polyline is formatted
00704       ERRVALUE Assign (
00705          const POLYLINE& PolyLine,
00706          const SIMPLE_ARRAY<INT32>& Index       //!< Each entry is the number of points >0 is shell <0 is island
00707          );
00708          
00709       //! Get the beginning of the list of SUBREGION's.
00710       //! @return Iterator to the beginning of the subregion list
00711       CONST_ITERATOR Begin (
00712          ) const { return (m_SubList.Begin()); }
00713 
00714       //! Clear the region
00715       void Clear (
00716          );
00717          
00718       //! Clear coordinate reference system.
00719       void ClearCoordRefSys (
00720          );
00721          
00722       //! Clip a polyline to a region, call the ClipTarget for each segment
00723       //! @return TRUE if part of the line is clipped, FALSE if not, < 0 error
00724       int ClipLine (
00725          POLYLINE& PolyLine,
00726          POLYLINE::CLIP& ClipTarget,
00727          CLIPMODE ClipMode = CLIPMODE_Inside
00728          ) const;
00729          
00730       //! Compute the region area in region units
00731       double ComputeArea (
00732          ) const;
00733    
00734       //! Compute the region area in region units but do not exclude islands in the calculation
00735       double ComputeAreaNoIslands (
00736          ) const;
00737    
00738       //! Compute the region perimeter in region units
00739       double ComputePerimeter (
00740          ) const;
00741    
00742       //! Compute the region perimeter in region units but do not include sub-region islands in the calculation
00743       double ComputePerimeterNoIslands (
00744          ) const;
00745    
00746       //! Translate the region using an affine transformation
00747       //! If the COORDREFSYS of 'this' is set, it will be changed to "Undefined"
00748       void ConvertForward (
00749          const TRANS2D_AFFINE& taf
00750          );
00751    
00752       //! Translate the region using a mapgen transformation
00753       //! An error will occur if the COORDREFSYS of 'this' is not local and the TRANS2D_MAPGEN's input transformation is not identity or
00754       //! the COORDREFSYS of 'this' does not match the TRANS2D_MAPGEN's input COORDREFSYS.
00755       //! If the TRANS2D_MAPGEN's output transformation is identity, 'this' COORDREFSYS will be set to the TRANS2D_MAPGEN's output COORDREFSYS.
00756       //! otherwise it will be set to "Undefined".
00757       ERRVALUE ConvertForward (
00758          const TRANS2D_MAPGEN& tmg
00759          );
00760    
00761       //! Translate the region using a coordinate operation (SPATREF::COORDOP) transformation
00762       //! Region coordinate reference system "GetCoordRefSys()' must equate to the Op.GetSourceCRS().
00763       //! The Op.GetTargetCRS() is assigned as the region's COORDREFSYS after the transformation.
00764       ERRVALUE ConvertForward (
00765          const SPATREF::COORDOP& Op
00766          );
00767    
00768       //! Translate the region using a mapgen transformation with densification
00769       //! An error will occur if the COORDREFSYS of 'this' is not local and the TRANS2D_MAPGEN's input transformation is not identity or
00770       //! the COORDREFSYS of 'this' does not match the TRANS2D_MAPGEN's input COORDREFSYS.
00771       //! If the TRANS2D_MAPGEN's output transformation is identity, 'this' COORDREFSYS will be set to the TRANS2D_MAPGEN's output COORDREFSYS.
00772       //! otherwise it will be set to "Undefined".
00773       ERRVALUE ConvertForwardDense (
00774          const TRANS2D_MAPGEN& tmg
00775          );
00776    
00777       //! Translate the region using a coordinate operation (SPATREF::COORDOP) transformation with densification
00778       //! Region coordinate reference system "GetCoordRefSys()' must equate to the Op.GetSourceCRS().
00779       //! The Op.GetTargetCRS() is assigned as the region's COORDREFSYS after the transformation.
00780       ERRVALUE ConvertForwardDense (
00781          const SPATREF::COORDOP& Op,
00782          double tolerance
00783          );
00784    
00785       //! Translate the region using an affine transformation
00786       //! If the COORDREFSYS of 'this' is set, it will be changed to "Undefined"
00787       void ConvertInverse (
00788          const TRANS2D_AFFINE& taf
00789          );
00790    
00791       //! Translate the region using a mapgen transformation
00792       //! An error will occur if the COORDREFSYS of 'this' is not local and the TRANS2D_MAPGEN's output transformation is not identity or
00793       //! the COORDREFSYS of 'this' does not match the TRANS2D_MAPGEN's output COORDREFSYS.
00794       //! If the TRANS2D_MAPGEN's input transformation is identity, 'this' COORDREFSYS will be set to the TRANS2D_MAPGEN's input COORDREFSYS
00795       //! otherwise it will be set to "Undefined".
00796       ERRVALUE ConvertInverse (
00797          const TRANS2D_MAPGEN& tmg
00798          );
00799    
00800       //! Translate the region using a mapgen transformation with densification
00801       //! An error will occur if the COORDREFSYS of 'this' is not local and the TRANS2D_MAPGEN's output transformation is not identity or
00802       //! the COORDREFSYS of 'this' does not match the TRANS2D_MAPGEN's output COORDREFSYS.
00803       //! If the TRANS2D_MAPGEN's input transformation is identity, 'this' COORDREFSYS will be set to the TRANS2D_MAPGEN's input COORDREFSYS.
00804       //! otherwise it will be set to "Undefined".
00805       ERRVALUE ConvertInverseDense (
00806          const TRANS2D_MAPGEN& tmg
00807          );
00808          
00809       //! Translate the region using a coordinate operation (SPATREF::COORDOP) transformation
00810       //! Region coordinate reference system "GetCoordRefSys()' must equate to the Op.GetTargetCRS().
00811       //! The Op.GetSourceCRS() is assigned as the region's COORDREFSYS after the transformation.
00812       ERRVALUE ConvertReverse (
00813          const SPATREF::COORDOP& Op
00814          );
00815    
00816       //! Translate the region using a coordinate operation (SPATREF::COORDOP) transformation with densification
00817       //! Region coordinate reference system "GetCoordRefSys()' must equate to the Op.GetTargetCRS().
00818       //! The Op.GetSourceCRS() is assigned as the region's COORDREFSYS after the transformation.
00819       ERRVALUE ConvertReverseDense (
00820          const SPATREF::COORDOP& Op,
00821          double tolerance
00822          );
00823 
00824       //! Convert 'this' to a different COORDREFSYS.
00825       ERRVALUE ConvertTo (
00826          const SPATREF::COORDREFSYS& DestCoordRefSys,
00827          double tolerance = 0.0
00828          );
00829    
00830       //! Copy region to specified target with filter.
00831       ERRVALUE CopyTo (
00832          REGION2D& target,                         //!< Target subregion
00833          COPYFILTER& filter                        //!< Filter to determine which subregions and islands to copy
00834          ) const;
00835    
00836       //! Get the end of the list of SUBREGION's
00837       //! @return End of SUBREGION list, see Begin() for details
00838       CONST_ITERATOR End (
00839          ) const { return (m_SubList.End()); }
00840 
00841       //! Exclusive Union (XOR) RegionB with 'this'
00842       ERRVALUE ExclusiveUnion (
00843          const REGION2D& RegionB
00844          );
00845          
00846       //! Exclusive Union (XOR) RegionB with RegionA and place in 'this'
00847       //! Will convert 'this' to RegionA's SPATREF::COORDREFSYS
00848       ERRVALUE ExclusiveUnion (
00849          const REGION2D& RegionA,
00850          const REGION2D& RegionB
00851          );
00852          
00853       //! Get the region's coordinate reference system
00854       //! @return SPATREF::COORDREFSYS of the region
00855       const SPATREF::COORDREFSYS& GetCoordRefSys (
00856          ) const { return (m_CoordRefSys); }
00857          
00858       //! Get region extents
00859       //! @return Extents of the entire region
00860       const DRECT3D& GetExtents (
00861          ) const { return (m_Extents); }
00862    
00863       //! Get region extents
00864       //! @return Extents of the entire region
00865       const DRECT2D& GetExtents2D (
00866          ) const { return (m_Extents); }
00867    
00868       //! Get number of sub-regions
00869       //! @return Number of sub-regions
00870       INT32 GetNumSubRegions (
00871          ) const;
00872          
00873       //! Intersect rectangle with 'this'
00874       ERRVALUE Intersect (
00875          const DRECT2D& Rect
00876          );
00877          
00878       //! Intersect a polygon with 'this'
00879       ERRVALUE Intersect (
00880          const POLYLINE& PolyLine
00881          );
00882          
00883       //! Intersect a sub-region with 'this'
00884       ERRVALUE Intersect (
00885          const SUBREGION2D& SubRegion
00886          );
00887          
00888       //! Intersect RegionB with 'this'
00889       ERRVALUE Intersect (
00890          const REGION2D& RegionB
00891          );
00892          
00893       //! Intersect RegionB with RegionA and place in 'this'
00894       //! Will convert 'this' to RegionA's SPATREF::COORDREFSYS
00895       ERRVALUE Intersect (
00896          const REGION2D& RegionA,
00897          const REGION2D& RegionB
00898          );
00899          
00900       //! Intersect a validated polygon with 'this'
00901       ERRVALUE IntersectValidated (
00902          const POLYLINE& PolyLine
00903          );
00904          
00905       //! Is the region an empty region
00906       bool IsEmpty (
00907          ) const { return (!m_Extents.IsValid()); }
00908 
00909       //! Determine if the two regions are equivalent 
00910       //! This method uses "Fuzzy" vertex comparisons and the direction and order of the elements are not relevant
00911       //! Specify a different threshold to allow greater distances
00912       //! @return 'True' if they are, 'False' if not
00913       bool IsEquivalentTo (
00914          const REGION2D& rhs,
00915          double threshold = 0.0        //!< Default threshold is max absolute value of rectangle coordinate * 1.0E-13
00916          ) const;
00917    
00918       //! Determine if the point falls inside the region
00919       //! @return 'True' if point is inside region, 'false' if not
00920       bool IsPointInside (
00921          const DPOINT2D& point
00922          ) const;
00923          
00924       //! Is the region a simple rectangle region?
00925       bool IsRectangle (
00926          ) const { return (m_IsRectangle); }
00927          
00928       //! Remove all of the islands from the region
00929       void RemoveIslands (
00930          );
00931          
00932       //! Reverse the orientation of the subregions in the region
00933       void Reverse (
00934          );
00935 
00936       //! Set the region's coordinate reference system
00937       //! Does not do any transformations of the region, 
00938       //! assumes that the region is in the system specified
00939       void SetCoordRefSys (
00940          const SPATREF::COORDREFSYS& CoordSysRef
00941          ) { m_CoordRefSys = CoordSysRef; }
00942 
00943       //! Set region orientation
00944       //! Each subregion is set using SUBREGION2D::SetOrientation()
00945       void SetOrientation (
00946          ORIENTATION Orientation
00947          );
00948          
00949       //! Set the Z init and Z last fields of the extents box        
00950       void SetZRange (
00951          const DOUBLE_RANGE& range
00952          );
00953          
00954       //! Subtract rectangle from 'this'
00955       ERRVALUE Subtract (
00956          const DRECT2D& Rect
00957          );
00958          
00959       //! Subtract a polygon from 'this'
00960       ERRVALUE Subtract (
00961          const POLYLINE& PolyLine
00962          );
00963          
00964       //! Subtract a sub-region from 'this'
00965       ERRVALUE Subtract (
00966          const SUBREGION2D& SubRegion
00967          );
00968          
00969       //! Subtract RegionB from 'this'
00970       ERRVALUE Subtract (
00971          const REGION2D& RegionB
00972          );
00973          
00974       //! Subtract RegionB from RegionA and place in 'this'
00975       //! Will convert 'this' to RegionA's SPATREF::COORDREFSYS
00976       ERRVALUE Subtract (
00977          const REGION2D& RegionA,
00978          const REGION2D& RegionB
00979          );
00980          
00981       //! Subtract a validated polygon from 'this'
00982       ERRVALUE SubtractValidated (
00983          const POLYLINE& PolyLine
00984          );
00985          
00986       //! Test the line given the test criteria against the region
00987       //! @return "True" if the line meets the criteria, "false" if not
00988       bool TestLine (
00989          const POLYLINE& PolyLine,
00990          TESTCRITERIA TestCriteria
00991          ) const;
00992 
00993       //! Test the point given the test criteria against the sub-region
00994       //! @return "True" if the point meets the criteria, "false" if not
00995       bool TestPoint (
00996          const DPOINT2D& Point,
00997          TESTCRITERIA TestCriteria
00998          ) const;
00999 
01000       //! Test the polygon given the test criteria against the region
01001       //! @return "True" if the polygon meets the criteria, "false" if not
01002       bool TestPolygon (
01003          const POLYLINE& PolyLine,
01004          TESTCRITERIA TestCriteria
01005          ) const;
01006 
01007       //! Test the sub-region given the test criteria against the region
01008       //! @return "True" if the sub-region meets the criteria, "false" if not
01009       bool TestSubRegion (
01010          const SUBREGION2D& SubRegion,
01011          TESTCRITERIA TestCriteria
01012          ) const;
01013 
01014       //! Test the 'Region' region given the test criteria against 'this' region
01015       //! @return "True" if the 'Region' region meets the criteria, "false" if not
01016       bool TestRegion (
01017          const REGION2D& Region,
01018          TESTCRITERIA TestCriteria
01019          ) const;
01020 
01021       //! Union (ADD) rectangle to 'this'
01022       ERRVALUE Union (
01023          const DRECT2D& Rect
01024          );
01025          
01026       //! Union (ADD) a polygon to 'this'
01027       ERRVALUE Union (
01028          const POLYLINE& PolyLine
01029          );
01030          
01031       //! Union (ADD) a sub-region to the region
01032       ERRVALUE Union (
01033          const SUBREGION2D& SubRegion
01034          );
01035          
01036       //! Union (ADD) RegionB to RegionA and place in 'this'
01037       //! Will convert 'this' to RegionA's SPATREF::COORDREFSYS
01038       ERRVALUE Union (
01039          const REGION2D& RegionA,
01040          const REGION2D& RegionB
01041          );
01042          
01043       //! Union (ADD) RegionB to 'this'
01044       ERRVALUE Union (
01045          const REGION2D& RegionB
01046          );
01047          
01048       //! Union (ADD) a validated polygon to 'this'
01049       ERRVALUE UnionValidated (
01050          const POLYLINE& PolyLine
01051          );
01052          
01053    private:
01054       #ifndef GENERATING_DOXYGEN_OUTPUT
01055    
01056       MILIST<SUBREGION2D> m_SubList;
01057       DRECT3D m_Extents;
01058       SPATREF::COORDREFSYS m_CoordRefSys;
01059       bool m_IsRectangle;
01060       
01061       void AppendDisjointRegion (const REGION2D& rhs);
01062       void AppendDisjointSubRegion (const SUBREGION2D& rhs);
01063       bool UnionRectangle (const DRECT2D& Rect);
01064       void UpdateExtentsRect ();
01065    
01066       class INTERSECTREGION;
01067       friend class INTERSECTREGION;
01068       friend class RVC::VECTOR;           //!< For RVC::VECTOR::ReadRegion()
01069       friend class RVC::REGION;           //!< For RVC::REGION::GetRegion() and RVC::REGION::SetRegion()
01070       friend class RVC::REGIONHANDLE;
01071       friend class BINARYTOREGION2D;
01072       friend class SERIALIZER;
01073       #endif // GENERATING_DOXYGEN_OUTPUT
01074    };
01075 
01076 PREVENT_MEMFUNC(SUBREGION2D);
01077 PREVENT_MEMFUNC(REGION2D);
01078    
01079 #pragma warning(default:4251) // Start complaining about the need to have a dll interface
01080 #undef GEOMLIBEXPORT
01081 #undef GEOMLIBCLASSEXPORT
01082 
01083 #endif      //!< INC_MI32_REGION2D_H

Generated on Wed May 31 15:27:03 2006 for TNTsdk by  doxygen 1.3.8-20040913