00001 /** 00002 * \file region.h <mi32/region.h> 00003 * \brief Functions and structure for regions 00004 * 00005 * \if NODOC 00006 * $Id: region.h_v 1.114 2003/09/15 13:49:56 fileserver!dwilliss Exp $ 00007 * 00008 * $Log: region.h_v $ 00009 * Revision 1.114 2003/09/15 13:49:56 fileserver!dwilliss 00010 * Doxygen 00011 * 00012 * Revision 1.113 2002/12/20 20:42:05 dwilliss 00013 * For some reason, VC6.0 suddenly decided friend operators wern't friends 00014 * any more. Defined public inline methods to do what they needed and made 00015 * the friend operators call those. 00016 * 00017 * Revision 1.112 2002/07/30 19:06:59 dwilliss 00018 * Use 0 instead of NULL. MacOS X seems to have problems declaring NULL 00019 * 00020 * Revision 1.111 2001/12/20 22:13:10 scowan 00021 * Removed deprecated include. 00022 * 00023 * Revision 1.110 2001/10/08 21:01:30 scowan 00024 * Added has dest region method. 00025 * 00026 * Revision 1.109 2001/10/08 20:43:11 scowan 00027 * Made more functions take const regions. 00028 * 00029 * Revision 1.108 2001/02/01 22:20:26 mju 00030 * Fix GEOREGION::operator-=. 00031 * 00032 * Revision 1.107 2000/11/27 18:01:55 mju 00033 * Add comments that intersect, union, subtract and xor APPEND to destination. 00034 * 00035 * Revision 1.106 2000/11/15 15:01:19 mju 00036 * Move region generation defns to rgngen.h. 00037 * 00038 * Revision 1.105 2000/10/26 19:56:52 mju 00039 * Add georegion::Get/SetSource/Dest... methods. 00040 * 00041 * Revision 1.104 2000/09/18 16:58:13 mju 00042 * Make GEOREGION dtor free the region. 00043 * 00044 * Revision 1.103 2000/09/14 17:52:04 msmith 00045 * Added MregionGetStats - calculates area, perimeter, and centroid. 00046 * 00047 * Revision 1.102 2000/09/14 17:47:46 mju 00048 * Use const for TRANSPARN in regionFromVector... 00049 * 00050 * Revision 1.101 2000/08/04 16:47:40 mju 00051 * Change ConvertToLatLon to take maxerror parm. 00052 * 00053 * Revision 1.100 2000/08/03 14:44:43 mju 00054 * Add MregionConvertToLatLon. 00055 * 00056 * Revision 1.99 2000/08/02 22:06:52 mju 00057 * Change georegion:setpolygon to AddSubRegion() and don't clear first. 00058 * 00059 * Revision 1.98 2000/08/02 15:39:10 mju 00060 * Enable use of GEOREGION class. 00061 * 00062 * Revision 1.97 2000/07/18 20:50:22 sparsons 00063 * Genitor documentation. 00064 * 00065 * Revision 1.91 1999/05/12 20:50:26 mju 00066 * Use const for most Mregion functions. 00067 * Add GEOREGION class. 00068 * 00069 * Revision 1.89 1999/04/29 19:33:55 mju 00070 * Move prototypes requiring X stuff to xdefns.h. 00071 * 00072 * Revision 1.88 1999/04/29 16:00:58 mju 00073 * Move DREGION/DSUBREGION definitions here. 00074 * 00075 * Revision 1.87 1999/03/15 15:37:48 mju 00076 * Use const for some source regions and test funcs. 00077 * 00078 * Revision 1.86 1999/01/05 19:12:39 scowan 00079 * Swapped multiple keywords 00080 * 00081 * \endif 00082 **/ 00083 00084 #ifndef INC_MI32_REGION_H 00085 #define INC_MI32_REGION_H 00086 00087 #ifndef INC_MI32_STDDEFNS_H 00088 #include <mi32/stddefns.h> 00089 #endif 00090 00091 #ifndef INC_MI32_MAPPROJ_H 00092 #include <mi32/mapproj.h> 00093 #endif 00094 00095 #ifndef INC_MI32_TRANSGEN_H 00096 #include <mi32/transgen.h> 00097 #endif 00098 00099 #ifndef INC_MI32_TRANS2DC_H 00100 #include <mi32/trans2dc.h> 00101 #endif 00102 00103 #ifndef INC_MI32_RECT_H 00104 #include <mi32/rect.h> 00105 #endif 00106 00107 #ifdef GEOMDLL 00108 #define GEOMLIBEXPORT MI_DLLEXPORT 00109 #else 00110 #define GEOMLIBEXPORT MI_DLLIMPORT 00111 #endif 00112 00113 /*----------------------------------------------------------------------------*/ 00114 /* DREGION - Region structure used by Mr...() functions */ 00115 /*----------------------------------------------------------------------------*/ 00116 00117 /*** !!! The structures DSUBREGION and DREGION cannot be changed without significant alterations to geom.dll !!! */ 00118 00119 struct DSUBREGION { 00120 /* DO NOT CHANGE THIS STRUCTURE UNDER PENALTY OF ILLOP'S */ 00121 DRECT2D Extents; 00122 UINT32 NumPoints; 00123 UINT32 NumIslands; 00124 UINT32 *IsleNumPoints; 00125 DPOINT2D *Points; 00126 }; 00127 00128 struct DREGION { 00129 /* DO NOT CHANGE THIS STRUCTURE UNDER PENALTY OF ILLOP'S */ 00130 UINT32 NumRegions; //!< Number of sub regions 00131 DSUBREGION *RegionList; //!< Original Sub region list 00132 DRECT2D Extents; 00133 DSUBREGION *DestRegionList; //!< Sub region list run through TRANSPARM 00134 DRECT2D DestExtents; 00135 MAPPROJPARM mapparm; //!< Region coordinates if in a projection are implied 00136 TRANSPARM transparm; //!< Transformation object<->region 00137 }; 00138 00139 /** 00140 * This will take a little explanation. The DSUBREGION structure follows the 00141 * same storage format as the CAD Polygon structure. The IsleNumPoints array 00142 * is an array containing the number of points per island. The Points 00143 * array contains both the points for the exterior polygon region and 00144 * the islands. The layout of the points is as follows: first the exterior 00145 * polygon is stored then the points for each island in the order stored 00146 * in the IsleNumPoints array. If no islands exist, then the IsleNumPoints 00147 * array is not allocated. Anything inside an island is considered to be 00148 * "outside" the region. DREGION and DSUBREGION are defined in stddefns.h 00149 **/ 00150 00151 00152 #define REGIONTEST_CompInside 1 //!< Only elements completely inside region 00153 #define REGIONTEST_PartInside 2 //!< All elements that partially or completely fall inside region 00154 #define REGIONTEST_CompOutside 3 //!< Only elements completely outside region 00155 #define REGIONTEST_PartOutside 4 //!< All elements that partially or completely fall outside region 00156 #define REGIONTEST_ClipInside 5 //!< Clip inside, not actual test 00157 #define REGIONTEST_ClipOutside 6 //!< Clip outside, not actual test 00158 00159 #define REGIONCOMP_Outside 1 //!< Element is outside the region 00160 #define REGIONCOMP_Inside 2 //!< Element is inside the region 00161 #define REGIONCOMP_Intersect 3 //!< Element intersects the region 00162 #define REGIONCOMP_Overlap 4 //!< Element overlaps the region, both inside and outside 00163 00164 #define REGIONFLAG_TestAsLines 0x00000001 //!< Test element if possible as line data 00165 00166 00167 /** 00168 * Functions prototypes 00169 **/ 00170 00171 #if defined(__cplusplus) 00172 extern "C" { 00173 #endif 00174 00175 //!:Associate with "Region Functions" 00176 //!\addtogroup Region Region Functions 00177 //!@{ 00178 00179 //! Change the region projection. 00180 //! 00181 //! This function can be used to set/change the projection of the region's 00182 //! coordinates. If the region's projection is arbitrary, then the new 00183 //! projection is set, otherwise the function converts the coordinates 00184 //! to the new projection. This is why MregionInit() needs to be called. 00185 //! If the destination region list exists, it will be recomputed. 00186 GEOMLIBEXPORT ERRVALUE MregionChangeProj ( 00187 DREGION *region, //!< The region to set/change the region projection on 00188 const MAPPROJPARM *mapparm //!< The projection to set the region to 00189 ); 00190 00191 //! Check if extents is outside the entire region. 00192 //! 00193 //! @return REGIONCOMP_Outside if outside, REGIONCOMP_Overlap if not, or error code. 00194 GEOMLIBEXPORT int MregionCheckIfOutside ( 00195 const DRECT2D *extents, //!< Rectangle to check if outside 00196 const DREGION *region //!< The region to check against 00197 ); 00198 00199 //! Clear a region of all sub-regions. 00200 GEOMLIBEXPORT void MregionClear ( 00201 DREGION *region 00202 ); 00203 00204 //! Clip a line to a region. 00205 //! 00206 //! RegionTest values: 00207 //! \li \b REGIONTEST_ClipInside Clip the line to the inside of the region 00208 //! \li \b REGIONTEST_ClipOutside Clip the line to the outside of the region 00209 //! 00210 //! Notes: 00211 //! If clipping to a single non rotated rectangle a faster clipping algorithm is used if 00212 //! the extents are specified in the region and the NumRegions is 0 or the RegionList 00213 //! field is NULL. If there are multiple subregions and some are rectangles then the 00214 //! faster clipping algorithm is used if the extents are specified in the SubRegion and 00215 //! the Points field is set to NULL. 00216 GEOMLIBEXPORT int MregionClipLine ( 00217 const DREGION *region, //!< The region to clip to 00218 const DPOLYGON *line, //!< The line to clip 00219 int (*ClippedLine)(DPOLYGON *retline, void *udata), //! Clipped line callback function 00220 void *udata, //!< User data passed to ClippedLine() 00221 UINT32 RegionTest //!< The type of clip to perform 00222 ); 00223 00224 //! Clip a point to a region. 00225 //! 00226 //! RegionTest values: 00227 //! \li \b REGIONTEST_ClipInside Clip the point to the inside of the region 00228 //! \li \b REGIONTEST_ClipOutside Clip the point to the outside of the region 00229 GEOMLIBEXPORT int MregionClipPoint ( 00230 const DREGION *region, //!< The region to clip to 00231 const DPOINT3D *pt, //!< The point to clip 00232 int (*ClippedPoint)(DPOINT3D *pt, void *udata), //! Clipped line callback function 00233 void *udata, //!< User data passed to ClippedPoint() 00234 UINT32 RegionTest //!< The type of clip to perform 00235 ); 00236 00237 //! Clip a polygon to a region. 00238 //! 00239 //! RegionTest values: 00240 //! \li \b REGIONTEST_ClipInside Clip the polygon to the inside of the region 00241 //! \li \b REGIONTEST_ClipOutside Clip the polygon to the outside of the region 00242 GEOMLIBEXPORT int MregionClipPolygon ( 00243 const DREGION *region, //!< The region to clip to 00244 const DPOLYGON *IPolygon, //!< The polygon to clip 00245 DPOLYGON **OPolyList, //!< List of clipped polygons RETURNED, free with MmFree() 00246 UINT32 *ONumPolys, //!< Number of clipped polygons RETURNED 00247 UINT32 RegionTest //!< The type of clip to perform 00248 ); 00249 00250 //! Clip a list of polygons to a region and place in a LPOLYGON array. 00251 //! 00252 //! RegionTest values: 00253 //! \li \b REGIONTEST_ClipInside Clip the polygon to the inside of the region 00254 //! \li \b REGIONTEST_ClipOutside Clip the polygon to the outside of the region 00255 GEOMLIBEXPORT int MregionClipPolygonsL ( 00256 const DREGION *region, //!< The region to clip to 00257 const DPOLYGON *IPolyList, //!< The list of polygons to clip 00258 UINT32 INumPolys, //!< Number of polygons in the IPolyList array 00259 LPOLYGON **OPolyList, //!< List of clipped polygons RETURNED, free with MmFree() 00260 UINT32 *ONumPolys, //!< Number of clipped polygons RETURNED 00261 UINT32 RegionTest //!< The type of clip to perform 00262 ); 00263 00264 //! Compares a region to a given line. 00265 //! 00266 //! Returns error or one of the values below. 00267 //! 00268 //! <pre> 00269 //! #define REGIONCOMP_Outside 1 //!< Element is outside the region 00270 //! #define REGIONCOMP_Inside 2 //!< Element is inside the region 00271 //! #define REGIONCOMP_Intersect 3 //!< Element intersects the region 00272 //! #define REGIONCOMP_Overlap 4 //!< Element overlaps the region, both inside and outside 00273 //! </pre> 00274 //! 00275 //! The "INT32 *SubRegion" returns which sub region the line intersected with. 00276 GEOMLIBEXPORT int MregionCompareLine ( 00277 const DPOLYGON *line, 00278 const DREGION *region, 00279 INT32 *SubRegion 00280 ); 00281 00282 //! Convert region to Latitude-Longitude WGS84 coordinates 00283 GEOMLIBEXPORT ERRVALUE MregionConvertToLatLon ( 00284 DREGION *region, //!< Region to convert 00285 double maxerror = 0.0 //!< Maximum error for inserting points, 0.0 to not insert additional points 00286 ); 00287 00288 //! Copy one region to another. 00289 GEOMLIBEXPORT ERRVALUE MregionCopy ( 00290 DREGION *DestRegion, //!< Region to copy to 00291 const DREGION *SrcRegion //!< Region to copy from 00292 ); 00293 00294 //! Convert destination portion of region to LPOLYGON array. 00295 GEOMLIBEXPORT int MregionDestToPolygonsL ( 00296 DREGION *region, //!< Region 00297 LPOLYGON **polys, //!< Polygon array allocated and returned 00298 INT32 *numpolys //!< Number of polygons returned 00299 ); 00300 00301 //! Exclusive Or two regions together and append result to destination region. 00302 //! 00303 //! NOTES: DestRegion will have the same map projection and transparm as RegionB. If the return value 00304 //! is ERgnTooCompToComb and RegionB == NULL, DestRegion will be reset to its original region. 00305 GEOMLIBEXPORT int MregionExclusiveOr ( 00306 DREGION *DestRegion, //!< Region to store result 00307 const DREGION *RegionA, //!< Region to "exclusive or" with RegionB 00308 const DREGION *RegionB //!< Region to intersect with RegionA (can be 'NULL' or '== DestRegion') 00309 ); 00310 00311 //! Free all data associated with a region. 00312 GEOMLIBEXPORT void MregionFree ( 00313 DREGION *region //!< Region to free 00314 ); 00315 00316 //! Generate the destination region. 00317 //! 00318 //! This function generates the 'DestRegionList' field in the region 00319 //! based on the inverse of the 'transparm' field in the region. 00320 GEOMLIBEXPORT ERRVALUE MregionGenerateDest ( 00321 DREGION *region //!< The region 00322 ); 00323 00324 //! Generate point inside specified subregion. 00325 GEOMLIBEXPORT int MregionGenPointInSub ( 00326 const DREGION *region, 00327 INT32 SubIndex, 00328 DPOINT2D *retpt 00329 ); 00330 00331 //! Determine if region has 'destination' coordinate region. 00332 inline bool MregionHasDest ( 00333 const DREGION *region 00334 ) { 00335 return (region->DestRegionList != 0); 00336 } 00337 00338 00339 //! Initialize the region structure. 00340 GEOMLIBEXPORT void MregionInit ( 00341 DREGION *region //!< Region to initialize 00342 ); 00343 00344 //! Intersect two regions together and append result to destination region. 00345 //! 00346 //! NOTES: DestRegion will have the same map projection and transparm as RegionB. If the return value 00347 //! is ERgnTooCompToComb and RegionB == NULL, DestRegion will be reset to its original region. 00348 GEOMLIBEXPORT int MregionIntersect ( 00349 DREGION *DestRegion, 00350 const DREGION *RegionA, 00351 const DREGION *RegionB 00352 ); 00353 00354 //! Determine if specified point is inside given subregion. 00355 //! 00356 //! @return TRUE if point inside, FALSE if not, < 0 if error. 00357 GEOMLIBEXPORT int MregionIsPointInSub ( 00358 const DSUBREGION *subregion, //!< Subregion to check point against 00359 const DPOINT2D *point //!< Point to test in subregion's coordinates 00360 ); 00361 00362 //! Set input side of the region's TRANSPARM. 00363 //! 00364 //! This function copies the input parameters from the 'transparm' to the 00365 //! 'region'. The input parameters determine either the computation of 00366 //! the DestRegionList or the conversion of test data (points, lines, etc...) 00367 //! to the region coordinates. 00368 GEOMLIBEXPORT ERRVALUE MregionSetTransParm ( 00369 DREGION *region, //!< Region to set input coordinate TRANSPARM info on 00370 const TRANSPARM *transparm //!< TRANSPARM to get input transformation settings from 00371 ); 00372 00373 //! Subtract region B from region A and append result to destination region. 00374 //! 00375 //! NOTES: DestRegion will have the same map projection and transparm as RegionB. If the return value 00376 //! is ERgnTooCompToComb and RegionB == NULL, DestRegion will be reset to its original region. 00377 GEOMLIBEXPORT int MregionSubtract ( 00378 DREGION *DestRegion, 00379 const DREGION *RegionA, 00380 const DREGION *RegionB 00381 ); 00382 00383 //! Test a line against the region. 00384 //! 00385 //! @return 1 if successful, 0 if not, < 0 error. 00386 //! 00387 //! RegionTest values: 00388 //! \li\b REGIONTEST_CompInside Is the line completely inside the region 00389 //! \li\b REGIONTEST_PartInside Is the line partially inside the region 00390 //! \li\b REGIONTEST_CompOutside Is the line completely outside the region 00391 //! \li\b REGIONTEST_PartOutside Is the line partially outside the region 00392 GEOMLIBEXPORT int MregionTestLine ( 00393 const DPOLYGON *line, //!< The line to test 00394 const DREGION *region, //!< The region to test against 00395 UINT32 RegionTest //!< The type of test to perform 00396 ); 00397 00398 //! Test a point against the region. 00399 //! 00400 //! @return 1 if successful, 0 if not, < 0 error. 00401 //! 00402 //! RegionTest values: 00403 //! \li\b REGIONTEST_CompInside Is the point completely inside the region 00404 //! \li\b REGIONTEST_PartInside Is the point partially inside the region 00405 //! \li\b REGIONTEST_CompOutside Is the point completely outside the region 00406 //! \li\b REGIONTEST_PartOutside Is the point partially outside the region 00407 GEOMLIBEXPORT int MregionTestPoint ( 00408 const DPOINT2D *pt, //!< The point to test 00409 const DREGION *region, //!< The region to test against 00410 UINT32 RegionTest //!< The type of test to perform 00411 ); 00412 00413 //! Test a simple polygon against the region. 00414 //! 00415 //! @return 1 if successful, 0 if not, < 0 error. 00416 //! 00417 //! RegionTest values: 00418 //! \li\b REGIONTEST_CompInside Is the polygon completely inside the region 00419 //! \li\b REGIONTEST_PartInside Is the polygon partially inside the region 00420 //! \li\b REGIONTEST_CompOutside Is the polygon completely outside the region 00421 //! \li\b REGIONTEST_PartOutside Is the polygon partially outside the region 00422 GEOMLIBEXPORT int MregionTestPolygon ( 00423 const DPOLYGON *poly, //!< The simple polygon to test 00424 const DREGION *region, //!< The region to test against 00425 UINT32 RegionTest //!< The type of test to perform 00426 ); 00427 00428 //! Test a complex polygon (polygon with islands) against the region. 00429 //! 00430 //! @return 1 if successful, 0 if not, < 0 error. 00431 //! 00432 //! RegionTest values: 00433 //! \li\b REGIONTEST_CompInside Is the sub-region completely inside the region 00434 //! \li\b REGIONTEST_PartInside Is the sub-region partially inside the region 00435 //! \li\b REGIONTEST_CompOutside Is the sub-region completely outside the region 00436 //! \li\b REGIONTEST_PartOutside Is the sub-region partially outside the region 00437 GEOMLIBEXPORT int MregionTestSubRegion ( 00438 const DSUBREGION *subregion, //!< The sub-region (complex polygon) to test 00439 const DREGION *region, //!< The region to test against 00440 UINT32 RegionTest //!< The type of test to perform 00441 ); 00442 00443 //! Copy sub-regions to another. 00444 GEOMLIBEXPORT ERRVALUE MregionTransfer ( 00445 DREGION *DestRegion, 00446 const DREGION *SrcRegion 00447 ); 00448 00449 //! Convert a region to a new coordinate system using a TRANSPARM. 00450 GEOMLIBEXPORT ERRVALUE MregionTranslate ( 00451 DREGION *region, //!< Region to translate to a new coordinate system 00452 const TRANSPARM *tp //!< TransParm to use in the translation 00453 ); 00454 00455 //! Union two regions together and append result to destination region. 00456 //! 00457 //! NOTES: DestRegion will have the same map projection and transparm as RegionB. If the return 00458 //! value is ERgnTooCompToComb and RegionB == NULL, DestRegion will be reset to its original region. 00459 GEOMLIBEXPORT int MregionUnion ( 00460 DREGION *DestRegion, //!< Region to store result 00461 const DREGION *RegionA, //!< Region to union with RegionB 00462 const DREGION *RegionB //!< Region to union with RegionA (can be 'NULL' or '== DestRegion') 00463 ); 00464 00465 //! Update the extents and orientation of a region. 00466 GEOMLIBEXPORT ERRVALUE MregionUpdate ( 00467 DREGION *region //!< Region to update extents and check orientation 00468 ); 00469 00470 //! Append region to vector object as vector polygons. 00471 int MregionAppendToVector ( 00472 int vid, //!< Open handle to RVC vector object to append to 00473 void *vvinfo, //!< Pointer to vector header, it will be updated 00474 DREGION *region //!< The region to append to the vector 00475 ); 00476 00477 //! Read polygon convert to screen coords and clip. 00478 int MregionClipVectPolygon ( 00479 DREGION *region, 00480 int vid, //!< ID of opened vector object 00481 INT32 PolyNum, //!< Polygon number to read 00482 LPOLYGON **rpolygons, 00483 INT32 *rnumpolys, 00484 UINT32 flags 00485 ); 00486 00487 //! Get area, perimeter, and centroid with and with islands for the given region. 00488 ERRVALUE MregionGetStats ( 00489 const DREGION& region, //!< Region to calculate from 00490 double *Area, //!< Area passed / returned 00491 double *Perimeter, //!< Perimeter passed / returned 00492 DPOINT2D *Centroid, //!< Centroid passed / returned 00493 double *AreaNotIsle, //!< Area without islands passed / returned 00494 double *PerimeterNotIsle, //!< Perimeter without islands passed / returned 00495 DPOINT2D *CentroidNotIsle //!< Centroid without islands passed / returned 00496 ); 00497 00498 //! Test a CAD element against the region. 00499 //! 00500 //! @return 1 if successful, 0 if not. 00501 //! 00502 //! RegionTest values: 00503 //! \li\b REGIONTEST_CompInside Is the element completely inside the region 00504 //! \li\b REGIONTEST_PartInside Is the element partially inside the region 00505 //! \li\b REGIONTEST_CompOutside Is the element completely outside the region 00506 //! \li\b REGIONTEST_PartOutside Is the element partially outside the region 00507 //! 00508 //! Flags: 00509 //! \li\b REGIONFLAG_TestAsLines Test polygon type elements as lines rather than polygons 00510 int MregionTestCADElement ( 00511 void *velem, //!< CADELEMENT to test with 00512 const DREGION *region, //!< The region to test against 00513 UINT32 RegionTest, //!< The type of test to perform 00514 UINT32 flags //!< Flags 00515 ); 00516 00517 //! Test a TIN element against the region. 00518 //! 00519 //! @return 1 if successful, 0 if not. 00520 //! 00521 //! RegionTest values: 00522 //! \li\b REGIONTEST_CompInside Is the element completely inside the region 00523 //! \li\b REGIONTEST_PartInside Is the element partially inside the region 00524 //! \li\b REGIONTEST_CompOutside Is the element completely outside the region 00525 //! \li\b REGIONTEST_PartOutside Is the element partially outside the region 00526 int MregionTestTINElement ( 00527 int tid, //!< Handle to open TIN object 00528 int ElemType, //!< Element type ELEMTYPE_... 00529 INT32 ElemNum, //!< Element number to test 00530 const DREGION *region, //!< The region to test against 00531 UINT32 RegionTest //!< The type of test to perform 00532 ); 00533 00534 //! Test a vector element against the region. 00535 //! 00536 //! @return 1 if successful, 0 if not. 00537 //! 00538 //! RegionTest values: 00539 //! \li\b REGIONTEST_CompInside Is the element completely inside the region 00540 //! \li\b REGIONTEST_PartInside Is the element partially inside the region 00541 //! \li\b REGIONTEST_CompOutside Is the element completely outside the region 00542 //! \li\b REGIONTEST_PartOutside Is the element partially outside the region 00543 int MregionTestVectorElement ( 00544 int vid, //!< Handle to open vector object 00545 int ElemType, //!< Element type ELEMTYPE_... 00546 INT32 ElemNum, //!< Element number to test 00547 const DREGION *region, //!< The region to test against 00548 UINT32 RegionTest //!< The type of test to perform 00549 ); 00550 00551 //!@} 00552 00553 #if defined(__cplusplus) 00554 } 00555 #endif 00556 00557 00558 //----------------------------------------------------------------------------- 00559 // GEOREGION class 00560 //----------------------------------------------------------------------------- 00561 00562 //! 00563 class GEOREGION { 00564 public: 00565 00566 enum TESTMODE { 00567 TESTMODE_FullOutside = REGIONTEST_CompOutside, //!< Test if fully outside region 00568 TESTMODE_PartOutside = REGIONTEST_PartOutside, //!< Test if any part is outside region 00569 TESTMODE_FullInside = REGIONTEST_CompInside, //!< Test if fully inside region 00570 TESTMODE_PartInside = REGIONTEST_PartInside //!< Test if any part is inside region 00571 }; 00572 00573 enum CLIPMODE { 00574 CLIPMODE_Inside = REGIONTEST_ClipInside, //!< Clip to inside of region 00575 CLIPMODE_Outside = REGIONTEST_ClipOutside //!< Clip to outside of region 00576 }; 00577 00578 // CONSTRUCTION / DESTRUCTION 00579 00580 //! Default constructor, create empty region. 00581 GEOREGION ( 00582 ) { 00583 MregionInit(&m_region); 00584 } 00585 00586 //! Copy constructor. 00587 GEOREGION ( 00588 const GEOREGION& rhs 00589 ) { 00590 MregionInit(&m_region); 00591 MregionCopy(&m_region,&rhs.m_region); 00592 } 00593 00594 //! Construct from DREGION (implicit). 00595 GEOREGION ( 00596 const DREGION& rhs 00597 ) { 00598 MregionInit(&m_region); 00599 MregionCopy(&m_region,&rhs); 00600 } 00601 00602 //! Destructor. 00603 ~GEOREGION ( 00604 ) { 00605 MregionFree(&m_region); 00606 } 00607 00608 // OPERATORS 00609 00610 //! Assignment from GEOREGION. 00611 GEOREGION& operator= ( 00612 const GEOREGION& rhs 00613 ) { 00614 if (this != &rhs) { 00615 MregionCopy(&m_region,&rhs.m_region); 00616 } 00617 return (*this); 00618 } 00619 00620 //! Assignment from DREGION. 00621 GEOREGION& operator= ( 00622 const DREGION& rhs 00623 ) { 00624 MregionCopy(&m_region,&rhs); 00625 return (*this); 00626 } 00627 00628 //! Intersection. 00629 GEOREGION& operator&= ( 00630 const GEOREGION& rhs 00631 ) { 00632 if (this != &rhs) { 00633 MregionIntersect(&m_region,&rhs.m_region,0); 00634 } 00635 return (*this); 00636 } 00637 00638 //! Union. 00639 GEOREGION& operator|= ( 00640 const GEOREGION& rhs 00641 ) { 00642 if (this != &rhs) { 00643 MregionUnion(&m_region,&rhs.m_region,0); 00644 } 00645 return (*this); 00646 } 00647 00648 //! Sum (same as union). 00649 GEOREGION& operator+= ( 00650 const GEOREGION& rhs 00651 ) { 00652 return (operator|=(rhs)); 00653 } 00654 00655 //! Subtract one region from another. 00656 GEOREGION& operator-= ( 00657 const GEOREGION& rhs 00658 ) { 00659 DREGION TempRegion; 00660 MregionInit(&TempRegion); 00661 MregionCopy(&TempRegion,&m_region); 00662 MregionClear(&m_region); 00663 MregionSubtract(&m_region,&TempRegion,&rhs.m_region); 00664 MregionFree(&TempRegion); 00665 return (*this); 00666 } 00667 00668 //! Exclusive-or. 00669 GEOREGION& operator^= ( 00670 const GEOREGION& rhs 00671 ) { 00672 MregionExclusiveOr(&m_region,&rhs.m_region,0); 00673 return (*this); 00674 } 00675 00676 // METHODS 00677 00678 //! Add polygon to region as new subregion. 00679 ERRVALUE AddSubRegion ( 00680 const DPOLYGON& poly //!< Polygon in region 'source' coordinates 00681 ) { 00682 if (poly.numpts < 3) return (0); 00683 int err; 00684 if ((err = MmReallocC((void**)&m_region.RegionList,(m_region.NumRegions+1)*sizeof(DSUBREGION),m_region.NumRegions*sizeof(DSUBREGION))) < 0) return (err); 00685 DSUBREGION *srp = &m_region.RegionList[m_region.NumRegions++]; 00686 if ((err = MmAlloc((void**)&srp->Points,(poly.numpts+1)*sizeof(DPOINT2D))) < 0) return (err); 00687 memcpy(srp->Points,poly.point,poly.numpts*sizeof(DPOINT2D)); 00688 srp->NumPoints = poly.numpts; 00689 if (srp->Points[0] != srp->Points[poly.numpts-1]) { 00690 srp->Points[srp->NumPoints++] = srp->Points[0]; 00691 } 00692 srp->Extents.SetInvalid(); 00693 for (int i = 0; (i < poly.numpts); ++i) { 00694 srp->Extents.Extend(poly.point[i]); 00695 } 00696 m_region.Extents.Extend(srp->Extents); 00697 return (0); 00698 } 00699 00700 //! Clear region. 00701 void Clear ( 00702 ) { 00703 MregionClear(&m_region); 00704 return; 00705 } 00706 00707 //! Clip DPOLYLINE to region. 00708 bool ClipLine ( 00709 const DPOLYLINE& line, //!< Line to clip in region 'destination' coordinates 00710 CLIPMODE clipmode, //!< Clipping mode (CLIPMODE_Inside or CLIPMODE_Outside) 00711 int (*ClipOutputFunc)( //! Function to output clipped sections to 00712 const DPOLYLINE *clippedline, //!< Clipped line section 00713 void *funcdata //!< Data passed from ClipLine 00714 ), //! Returns < 0 if error to stop clipping 00715 void *ClipOutputData //!< Data to pass on to clipping output function 00716 ) const { //! Returns false if line was outside region, true if inside or clipped 00717 return (MregionClipLine(&m_region,&line,reinterpret_cast<int(*)(DPOLYLINE*,void*)>(ClipOutputFunc),ClipOutputData,clipmode) > 0); 00718 } 00719 00720 //! Clip DPOINT3D to region. 00721 bool ClipPoint ( 00722 const DPOINT3D& point, //!< Point to clip in region 'destination' coordinates 00723 CLIPMODE clipmode, //!< Clipping mode (CLIPMODE_Inside or CLIPMODE_Outside) 00724 int (*ClipOutputFunc)( //! Function to output clipped point to 00725 const DPOINT3D* point, //!< Point if was clipped 00726 void *funcdata //!< Data passed from ClipPoint 00727 ), //! Returns < 0 if error to stop clipping 00728 void *ClipOutputData //!< Data to pass on to clipping output function 00729 ) const { //! Returns false if point was outside region, true if inside 00730 return (MregionClipPoint(&m_region,&point,reinterpret_cast<int(*)(DPOINT3D*,void*)>(ClipOutputFunc),ClipOutputData,clipmode) > 0); 00731 } 00732 00733 //! Convert region to Latitude-Longitude WGS84 coordinates 00734 ERRVALUE ConvertToLatLon ( 00735 double maxerror = 0.0 //!< Maximum error for point insertion, 0.0 to not insert points 00736 ) { 00737 return (MregionConvertToLatLon(&m_region,maxerror)); 00738 } 00739 00740 //! Generate 'destination' coordinates. 00741 ERRVALUE GenerateDest ( 00742 ) { 00743 return (MregionGenerateDest(&m_region)); 00744 } 00745 00746 //! Get extents in 'destination' coordinates. 00747 const DRECT2D& GetDestExtents ( 00748 ) const { 00749 MregionGenerateDest(const_cast<DREGION*>(&m_region)); 00750 return (m_region.DestExtents); 00751 } 00752 00753 //! Get extents in region 'source' coordinates. 00754 const DRECT2D& GetExtents ( 00755 ) const { 00756 return (m_region.Extents); 00757 } 00758 00759 //! Get number of sub-regions. 00760 int GetNumSubRegions ( 00761 ) const { 00762 return (m_region.NumRegions); 00763 } 00764 00765 //! Get region 'source' projection. 00766 const MAPPROJPARM& GetProjection ( 00767 ) const { 00768 return (m_region.mapparm); 00769 } 00770 00771 const DREGION& GetRegion ( 00772 ) const { 00773 return (m_region); 00774 } 00775 00776 DREGION& GetRegion ( 00777 ) { 00778 return (m_region); 00779 } 00780 00781 //! Get extents in 'source' coordinates. 00782 const DRECT2D& GetSourceExtents ( 00783 ) const { 00784 return (m_region.Extents); 00785 } 00786 00787 //! Get 'source' projection. 00788 const MAPPROJPARM& GetSourceProjection ( 00789 ) const { 00790 return (m_region.mapparm); 00791 } 00792 00793 //! Get region's TRANSPARM. 00794 //! Note that the "input" side of the transparm corresponds to the region's 'destination' 00795 //! coordinates and the "output" side corresponds to the region's 'source' coordinates. 00796 const TRANSPARM& GetTransParm ( 00797 ) const { 00798 return (m_region.transparm); 00799 } 00800 00801 bool HasDestRegion ( 00802 ) const { 00803 return (MregionHasDest(&m_region)); 00804 } 00805 00806 //! Sets the region to the intersection of two other regions 00807 void Intersect ( 00808 const GEOREGION& lhs, 00809 const GEOREGION& rhs 00810 ) { 00811 MregionIntersect(&m_region,&lhs.m_region,&rhs.m_region); 00812 } 00813 00814 //! Determine if region is "empty". 00815 bool IsEmpty ( 00816 ) const { 00817 return (!m_region.Extents.IsValid()); 00818 } 00819 00820 //! Set 'destination' projection. 00821 void SetDestProjection ( 00822 const MAPPROJPARM& proj 00823 ) { 00824 TransGenSetInputProj(&m_region.transparm,&proj); 00825 UpdateDest(); 00826 return; 00827 } 00828 00829 //! Set 'destination' transformation as affine. 00830 void SetDestTrans ( 00831 const MAT3X3 fwd, 00832 const MAT3X3 inv 00833 ) { 00834 TransGenSetInputTransAffine(&m_region.transparm,fwd,inv); 00835 UpdateDest(); 00836 return; 00837 } 00838 00839 //! Set 'destination' transformation to identity (default). 00840 void SetDestTransIdentity ( 00841 ) { 00842 TransGenSetInputTransIdentity(&m_region.transparm); 00843 return; 00844 } 00845 00846 //! Set region to be specified rectangle. 00847 void SetRectangle ( 00848 const DRECT2D& extents //!< Rectangle in region 'source' coordinate. 00849 ) { 00850 Clear(); 00851 m_region.Extents = extents; 00852 return; 00853 } 00854 00855 //! Set region 'source' projection. 00856 void SetSourceProjection ( 00857 const MAPPROJPARM& proj 00858 ) { 00859 MregionChangeProj(&m_region,&proj); 00860 return; 00861 } 00862 00863 //! Set 'source' transformation as affine. 00864 void SetSourceTrans ( 00865 const MAT3X3 fwd, //!< Source to SourceProj transformation 00866 const MAT3X3 inv //!< SourceProj to Source transformation 00867 ) { 00868 TransGenSetOutputTransAffine(&m_region.transparm,fwd,inv); 00869 return; 00870 } 00871 00872 //! Set 'source' transformation to identity (default). 00873 void SetSourceTransIdentity ( 00874 ) { 00875 TransGenSetOutputTransIdentity(&m_region.transparm); 00876 UpdateDest(); 00877 return; 00878 } 00879 00880 //! Set region's TRANSPARM. 00881 //! Note that the "input" side of the transparm corresponds to the region's 'destination' 00882 //! coordinates and the "output" side corresponds to the region's 'source' coordinates. 00883 void SetTransParm ( 00884 const TRANSPARM& transparm 00885 ) { 00886 TransGenCopy(&m_region.transparm,&transparm); 00887 UpdateDest(); 00888 return; 00889 } 00890 00891 //! Set region's TRANSPARM. 00892 //! Note that the "input" side of the transparm corresponds to the region's 'destination' 00893 //! coordinates and the "output" side corresponds to the region's 'source' coordinates. 00894 void SetTransParm ( 00895 const TRANS2D_MAPGEN& transgen 00896 ) { 00897 TransGenCopy(&m_region.transparm,&transgen.GetTransParm()); 00898 return; 00899 } 00900 00901 //! Sets the region to the result of lhs - rhs 00902 void Subtract ( 00903 const GEOREGION& lhs, 00904 const GEOREGION& rhs 00905 ) { 00906 MregionSubtract(&m_region,&lhs.m_region,&rhs.m_region); 00907 } 00908 00909 //! Test line against region. 00910 bool TestLine ( 00911 const DPOLYLINE& line, //!< Line in region 'destination' coordinates 00912 TESTMODE testmode 00913 ) const { 00914 return (MregionTestLine(&line,&m_region,testmode) > 0); 00915 } 00916 00917 //! Test point against region. 00918 bool TestPoint ( 00919 const DPOINT2D& point, //!< Point in region 'destination' coordinates 00920 TESTMODE testmode 00921 ) const { 00922 return (MregionTestPoint(&point,&m_region,testmode) > 0); 00923 } 00924 00925 //! Test polygon against region. 00926 bool TestPolygon ( 00927 const DPOLYGON& polygon, //!< Polygon in region 'destination' coordinates 00928 TESTMODE testmode 00929 ) const { 00930 return (MregionTestPolygon(&polygon,&m_region,testmode) > 0); 00931 } 00932 00933 //! Sets the region to the union of two other regions 00934 void Union ( 00935 const GEOREGION& lhs, 00936 const GEOREGION& rhs 00937 ) { 00938 MregionUnion(&m_region,&lhs.m_region,&rhs.m_region); 00939 } 00940 00941 //! Update destination region if exists. 00942 void UpdateDest ( 00943 ) { 00944 if (m_region.DestRegionList != 0) MregionGenerateDest(&m_region); 00945 return; 00946 } 00947 00948 private: 00949 #ifndef GENERATING_DOXYGEN_OUTPUT 00950 00951 // MEMBERS 00952 00953 DREGION m_region; 00954 00955 // FRIENDS 00956 friend GEOREGION operator& (const GEOREGION& lhs, const GEOREGION& rhs); 00957 friend GEOREGION operator| (const GEOREGION& lhs, const GEOREGION& rhs); 00958 friend GEOREGION operator- (const GEOREGION& lhs, const GEOREGION& rhs); 00959 friend GEOREGION operator^ (const GEOREGION& lhs, const GEOREGION& rhs); 00960 #endif // GENERATING_DOXYGEN_OUTPUT 00961 }; 00962 00963 //! Intersection. 00964 inline GEOREGION operator& ( 00965 const GEOREGION& lhs, 00966 const GEOREGION& rhs 00967 ) { 00968 GEOREGION result; 00969 result.Intersect(lhs, rhs); 00970 return (result); 00971 } 00972 00973 //! Union. 00974 inline GEOREGION operator| ( 00975 const GEOREGION& lhs, 00976 const GEOREGION& rhs 00977 ) { 00978 GEOREGION result; 00979 result.Union(lhs, rhs); 00980 return (result); 00981 } 00982 00983 //! Sum (same as union). 00984 inline GEOREGION operator+ ( 00985 const GEOREGION& lhs, 00986 const GEOREGION& rhs 00987 ) { 00988 return (lhs | rhs); 00989 } 00990 00991 //! Subtract one region from another. 00992 inline GEOREGION operator- ( 00993 const GEOREGION& lhs, 00994 const GEOREGION& rhs 00995 ) { 00996 GEOREGION result; 00997 result.Subtract(lhs, rhs); 00998 return (result); 00999 } 01000 01001 //! Exclusive-or. 01002 inline GEOREGION operator^ ( 01003 const GEOREGION& lhs, 01004 const GEOREGION& rhs 01005 ) { 01006 GEOREGION result; 01007 MregionExclusiveOr(&result.m_region,&lhs.m_region,&rhs.m_region); 01008 return (result); 01009 } 01010 01011 01012 #endif //!< INC_MI32_REGION_H
1.3.4-20031026