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
1.3.8-20040913