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