00001 /************************************************************************************ 00002 TerraLib - a library for developing GIS applications. 00003 Copyright � 2001-2007 INPE and Tecgraf/PUC-Rio. 00004 00005 This code is part of the TerraLib library. 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Lesser General Public 00008 License as published by the Free Software Foundation; either 00009 version 2.1 of the License, or (at your option) any later version. 00010 00011 You should have received a copy of the GNU Lesser General Public 00012 License along with this library. 00013 00014 The authors reassure the license terms regarding the warranties. 00015 They specifically disclaim any warranties, including, but not limited to, 00016 the implied warranties of merchantability and fitness for a particular purpose. 00017 The library provided hereunder is on an "as is" basis, and the authors have no 00018 obligation to provide maintenance, support, updates, enhancements, or modifications. 00019 In no event shall INPE and Tecgraf / PUC-Rio be held liable to any party for direct, 00020 indirect, special, incidental, or consequential damages arising out of the use 00021 of this library and its documentation. 00022 *************************************************************************************/ 00023 /*! \file TeGeometryAlgorithms.h 00024 \brief This file contains Algorithms for Topological Operations. 00025 \author Gilberto Ribeiro de Queiroz <gribeiro@dpi.inpe.br> 00026 */ 00027 #ifndef __TERRALIB_INTERNAL_GEOMETRYALGORITHMS_H 00028 #define __TERRALIB_INTERNAL_GEOMETRYALGORITHMS_H 00029 00030 #include "TeGeometry.h" 00031 #include "TeMultiGeometry.h" 00032 00033 #include "TePrecision.h" 00034 #include "TeProjection.h" 00035 00036 //! Intersection coordinates of two segments. 00037 typedef vector<TeCoord2D> TeIntersCoordsVec; 00038 00039 /** @defgroup GeometryAlgorithms Geometry algorithms 00040 TerraLib geometry algorithms. 00041 @{ 00042 */ 00043 00044 /** @defgroup TopologicalOperators Topological operators 00045 @ingroup GeometryAlgorithms 00046 Functions that test topologival relation between two objects. 00047 \verbatim 00048 The topological operators are based on the intersection of interior, exterior and boundary of geometries: 00049 ------------------------------------------------------------------------------------------------------------------ 00050 | TeGeometry | INTERIOR | BOUNDARY | EXTERIOR | 00051 ------------------------------------------------------------------------------------------------------------------ 00052 | TePoint | The point itself | Empty | Everything except interior | 00053 | TeLine2D | All points except the end points | The two end points | Everything except interior and boundary | 00054 | TeLinearRing | All points | Empty | Everything except interior and boundary | 00055 | TePolygon | Everything between the external | All rings | Everything except interior and boundary | 00056 | | ring and the inner rings | | | 00057 ------------------------------------------------------------------------------------------------------------------ 00058 00059 We use: 00060 - I: for Interior 00061 - E: for Exterior 00062 - B: for Boundary 00063 - inter: Intersects 00064 - ^: AND 00065 - v: OR 00066 - A = refer to two-dimensional geometries (TePolygon and TePolygonSet) 00067 - L = refer to one-dimensional geometries (TeLine2D and TeLineSet) 00068 - P = refer to 0-dimensional geometries (TePoint and TePointSet) 00069 \endverbatim 00070 @{ 00071 */ 00072 00073 /** @defgroup TeEquals Equals test 00074 @ingroup TopologicalOperators 00075 Check if one object is equal another object. 00076 \verbatim 00077 Applies to: P/P, L/L and A/A. 00078 TeEquals(x, y) => (x inter y = x) ^ (y inter x = y) 00079 (B(x) inter I(y) = false) ^ (B(x) inter E(y) = false) 00080 \endverbatim 00081 @{ 00082 */ 00083 //! If a specialized function is not used, returns false. 00084 template<class T1, class T2> 00085 inline bool TeEquals(const T1& /*o1*/, const T2& /*o2*/) 00086 { 00087 return false; 00088 } 00089 00090 //! Check if coordinate 1 and coordinate 2 are equal 00091 template<> 00092 TL_DLL bool TeEquals(const TeCoord2D& c1, const TeCoord2D& c2); 00093 00094 //! Check if point 1 and point 2 are equal 00095 template<> 00096 TL_DLL bool TeEquals(const TePoint& p1, const TePoint& p2); 00097 00098 //! Check if lineRed and lineBlue are equal 00099 template<> 00100 TL_DLL bool TeEquals(const TeLine2D& redLine, const TeLine2D& blueLine); 00101 00102 //! Check if polygon red and polygon blue are equal 00103 template<> 00104 TL_DLL bool TeEquals(const TePolygon& redPol, const TePolygon& bluePol); 00105 00106 //! Check if polygonset1 and polygonset1 are equal 00107 template<> 00108 TL_DLL bool TeEquals( const TePolygonSet& ps1, const TePolygonSet& ps2 ); 00109 00110 //! Check if box 1 and box 2 are equal 00111 template<> 00112 TL_DLL bool TeEquals(const TeBox& bx1, const TeBox& bx2); 00113 00114 //! Check if cell 1 and cell 2 are equal 00115 template<> 00116 TL_DLL bool TeEquals(const TeCell& cell1, const TeCell& cell2); 00117 /** @} */ 00118 00119 /** @defgroup TeDisjoint Disjoint test 00120 @ingroup TopologicalOperators 00121 Check if two objects are disjoint. 00122 \verbatim 00123 Applies to all geometries. 00124 TeDisjoint(x, y) => (x inter y = false) 00125 (I(x) inter I(y) = false) ^ (I(x) inter B(y) = false) ^ (B(x) inter I(y) = false) ^ (B(x) inter B(y) = false) 00126 \endverbatim 00127 @{ 00128 */ 00129 00130 template<class T1, class T2> 00131 inline bool TeDisjoint(const T1& o1, const T2& o2) 00132 { 00133 return TeDisjoint(o2, o1); 00134 } 00135 00136 //! Check if coordinate cl and coordinate c2 are disjoint 00137 TL_DLL bool TeDisjoint(const TeCoord2D& c1, const TeCoord2D& c2); 00138 00139 //! Check if coordinate and box are disjoint 00140 TL_DLL bool TeDisjoint(const TeCoord2D& c, const TeBox& b); 00141 00142 //! Check if box 1 and box 2 are disjoint 00143 TL_DLL bool TeDisjoint(const TeBox& bx1, const TeBox& bx2); 00144 00145 //! Check if coordinate and line are disjoint 00146 TL_DLL bool TeDisjoint(const TeCoord2D& c, const TeLine2D& l); 00147 00148 //! Check if coordinate and polygon are disjoint 00149 TL_DLL bool TeDisjoint(const TeCoord2D& c, const TePolygon& pol); 00150 00151 //! Check if point l and point 2 are disjoint 00152 TL_DLL bool TeDisjoint(const TePoint& p1, const TePoint& p2); 00153 00154 //! Check if point and object are disjoint 00155 TL_DLL bool TeDisjoint(const TePoint& p, const TeLine2D& l); 00156 00157 //! Check if point and object are disjoint 00158 TL_DLL bool TeDisjoint(const TePoint& p, const TePolygon& pol); 00159 00160 //! Check if lines are disjoint 00161 TL_DLL bool TeDisjoint(const TeLine2D& redLine, const TeLine2D& blueLine); 00162 00163 //! Check if line and polygon are disjoint 00164 TL_DLL bool TeDisjoint(const TeLine2D& l, const TePolygon& pol); 00165 00166 //! Check if polygons are disjoint 00167 TL_DLL bool TeDisjoint(const TePolygon& redPol, const TePolygon& bluePol); 00168 00169 //! Check if cell 1 and cell 2 are disjoint 00170 TL_DLL bool TeDisjoint(const TeCell& cell1, const TeCell& cell2); 00171 00172 //! Check if cell and line are disjoint 00173 TL_DLL bool TeDisjoint(const TeCell& cell, const TeLine2D& line); 00174 00175 //! Check if cell and polygon are disjoint 00176 TL_DLL bool TeDisjoint(const TeCell& cell, const TePolygon& pol); 00177 00178 //! Check if cell and point are disjoint 00179 TL_DLL bool TeDisjoint(const TeCell& cell, const TePoint& point); 00180 /** @} */ 00181 00182 00183 /** @defgroup TeIntersects Intersects test 00184 @ingroup TopologicalOperators 00185 Check if one object intersects another object. 00186 \verbatim 00187 Applies to all geometries. 00188 TeIntersects(x, y) => !TeDisjoint(x, y) 00189 => (I(x) inter I(y) = true) v (I(x) inter B(y) = true) v (B(x) inter I(y) = true) v (B(x) inter B(y) = true) 00190 \endverbatim 00191 @{ 00192 */ 00193 //! If a specialized function is not used, returns the disjoint negation 00194 00195 template<class T1, class T2> 00196 bool TeIntersects(const T1& o1, const T2& o2) 00197 { 00198 return !TeDisjoint(o1, o2); 00199 } 00200 00201 //! Check if coordinate and box intersects 00202 template<> 00203 TL_DLL bool TeIntersects(const TeCoord2D& c, const TeBox& b); 00204 00205 //! Check if point and box intersects 00206 template<> 00207 TL_DLL bool TeIntersects(const TePoint& p, const TeBox& b); 00208 00209 //! Check if boxes intersects 00210 template<> 00211 TL_DLL bool TeIntersects(const TeBox& bx1, const TeBox& bx2); 00212 /** @} */ 00213 00214 00215 /** @defgroup TeTouches Touch test 00216 @ingroup TopologicalOperators 00217 Check if two objects touches. 00218 \verbatim 00219 Applies to A/A, L/L, L/A, P/A, P/L. 00220 TeTouches(x, y) => (I(x) inter I(y) = false) ^ (x inter y = true) 00221 => (I(x) inter I(y) = false) ^ ((B(x) inter I(y) = true) v (I(x) inter B(y) = true) v (B(x) inter B(y) = true)) 00222 \endverbatim 00223 @{ 00224 */ 00225 00226 //! Check if coordinate and line touches 00227 TL_DLL bool TeTouches(const TeCoord2D& c, const TeLine2D& l); 00228 00229 //! Check if coordinate and polygon touches 00230 TL_DLL bool TeTouches(const TeCoord2D& c, const TePolygon& pol); 00231 00232 //! Check if point and object touches 00233 TL_DLL bool TeTouches(const TePoint& p, const TeLine2D& l); 00234 00235 //! Check if point and object touches 00236 TL_DLL bool TeTouches(const TePoint& p, const TePolygon& pol); 00237 00238 //! Check if line and line touches 00239 TL_DLL bool TeTouches(const TeLine2D& redLine, const TeLine2D& blueLine); 00240 00241 //! Check if line and polygon 00242 TL_DLL bool TeTouches(const TeLine2D& l, const TePolygon& pol); 00243 00244 //! Check if polygons touches 00245 TL_DLL bool TeTouches(const TePolygon& redPol, const TePolygon& bluePol); 00246 00247 //! Check if boxes touches 00248 TL_DLL bool TeTouches(const TeBox& bx1, const TeBox& bx2); 00249 00250 //! Check if cells touches 00251 TL_DLL bool TeTouches(const TeCell& c1, const TeCell& c2); 00252 00253 //! Check if cell and line touches 00254 TL_DLL bool TeTouches(const TeLine2D& line, const TeCell& cell); 00255 00256 //! Check if cell and polygon touches 00257 TL_DLL bool TeTouches(const TeCell& c1, const TePolygon& poly); 00258 00259 //! Check if cell and point touches 00260 TL_DLL bool TeTouches( const TePoint& point, const TeCell& c1); 00261 /** @} */ 00262 00263 /** @defgroup TeCrosses Crosses test 00264 @ingroup TopologicalOperators 00265 Check if one object crosses another object. 00266 \verbatim 00267 TeCrosses(x, y) => dim(I(x) inter I(y)) = (max(dim(I(x)), dim(I(y))) - 1) ^ (x inter y != x) ^ (x inter y != y) 00268 Case 1: x = TeLine2D and y = TePolygon 00269 => (I(x) inter I(y) = true) ^ (I(x) inter E(y) = true) 00270 Case 2: x = TeLine2D and y = TeLine2D 00271 => dim(I(x) inter I(y)) = 0 00272 \endverbatim 00273 @{ 00274 */ 00275 00276 //! Check if red line crosses blue line 00277 TL_DLL bool TeCrosses(const TeLine2D& redLine, const TeLine2D& blueLine); 00278 00279 //! Check if line crosses polygon 00280 TL_DLL bool TeCrosses(const TeLine2D& l, const TePolygon& pol); 00281 00282 //! Check if line and cell crosses 00283 TL_DLL bool TeCrosses(const TeLine2D& l, const TeCell& cell); 00284 /** @} */ 00285 00286 00287 /** @defgroup TeWithin Within test 00288 * @ingroup TopologicalOperators 00289 * Check if one object is within another object. 00290 \verbatim 00291 TeWithin(x, y) => (x inter y = x) ^ (I(x) inter I(y) = true) 00292 Case 1: P/P, P/L and P/A 00293 => (I(x) inter I(y) = true) 00294 Case 2: L/L and A/A 00295 => (I(x) inter I(y) = true) ^ (I(x) inter E(y) = false) ^ (B(x) inter E(y) = false) ^ (B(x) inter B(y) = false) 00296 Case 3: L/A 00297 => (I(x) inter I(y) = true) ^ (I(x) inter E(y) = false) ^ (B(x) inter E(y) = false) ^ (B(x) inter B(y) = false) ^ (I(x) inter B(y) = false) 00298 \endverbatim 00299 @{ 00300 */ 00301 00302 //! Check if coordinate 1 is within coordinate 2 00303 TL_DLL bool TeWithin(const TeCoord2D& c1, const TeCoord2D& c2); 00304 00305 //! Check if coordinate is within a box 00306 TL_DLL bool TeWithin(const TeCoord2D& c, const TeBox& b); 00307 00308 //! Check if a cordinate is within a line 00309 TL_DLL bool TeWithin(const TeCoord2D& c, const TeLine2D& l); 00310 00311 //! Check if a cordinate is within a polygon 00312 TL_DLL bool TeWithin(const TeCoord2D& c, const TePolygon& pol); 00313 00314 //! Check if point 1 is within point 2 00315 TL_DLL bool TeWithin(const TePoint& p1, const TePoint& p2); 00316 00317 //! Check if point is within object 00318 TL_DLL bool TeWithin(const TePoint& p, const TeLine2D& l); 00319 00320 //! Check if point is within object 00321 TL_DLL bool TeWithin(const TePoint& p, const TePolygon& pol); 00322 00323 //! Check if red line is within blue line 00324 TL_DLL bool TeWithin(const TeLine2D& redLine, const TeLine2D& blueLine); 00325 00326 //! Check if line is within polygon 00327 TL_DLL bool TeWithin(const TeLine2D& l, const TePolygon& pol); 00328 00329 //! Check if red polygon is within blue polygon 00330 TL_DLL bool TeWithin(const TePolygon& redPol, const TePolygon& bluePol); 00331 00332 //! Check if box1 is within box2 00333 TL_DLL bool TeWithin(const TeBox& bx1, const TeBox& bx2); 00334 00335 //! Check if cell1 is within cell2 00336 TL_DLL bool TeWithin(const TeCell& cell1, const TeCell& cell2); 00337 00338 //! Check if line is within cell 00339 TL_DLL bool TeWithin(const TeLine2D& line, const TeCell& cell); 00340 00341 //! Check if cell is within polygon 00342 TL_DLL bool TeWithin(const TeCell& cell, const TePolygon& poly); 00343 00344 //! Check if point is within cell 00345 TL_DLL bool TeWithin(const TePoint& point, const TeCell& cell); 00346 /** @} */ 00347 00348 /** @defgroup TeContains Contains test 00349 @ingroup TopologicalOperators 00350 Check if one object contains another object. 00351 TeContains(x, y) = TeWithin(y, x) 00352 @{ 00353 */ 00354 00355 //! If a specialized function is not used, returns false 00356 template<class T1, class T2> 00357 inline bool TeContains(const T1& o1, const T2& o2) 00358 { 00359 return TeWithin(o2, o1); 00360 } 00361 /** @} */ 00362 00363 /** @defgroup TeOverlaps Overlaps test 00364 @ingroup TopologicalOperators 00365 Check if one object overlaps another object. 00366 \verbatim 00367 TeOverlaps(x, y) => (dim(I(x)) = dim(I(y)) = dim(I(x) inter I(y))) ^ (x inter y != x) ^ (x inter y != y) 00368 Case 1: (x = TePolygon and y = TePolygon) 00369 => (I(x) inter I(y) = true) ^ (I(x) inter E(y) = true) ^ (E(x) inter I(y) = true) 00370 Case 2: x = TeLine2D and y = TeLine2D 00371 => (dim(I(x) inter I(y)) = 1) ^ (I(x) inter E(y) = true) ^ (E(x) inter I(y) = true) 00372 \endverbatim 00373 @{ 00374 */ 00375 00376 //! Check if red red overlaps blue line 00377 TL_DLL bool TeOverlaps(const TeLine2D& redLine, const TeLine2D& blueLine); 00378 00379 //! Check if red polygon overlaps blue polygon 00380 TL_DLL bool TeOverlaps(const TePolygon& redPol, const TePolygon& bluePol); 00381 00382 //! Check if cell1 overlaps cell2 00383 TL_DLL bool TeOverlaps(const TeCell& cell1, const TeCell& cell2); 00384 00385 //! Check if cell overlaps polygon 00386 TL_DLL bool TeOverlaps(const TeCell& cell, const TePolygon& poly); 00387 /** @} */ 00388 00389 00390 /** @defgroup TeCoveredBy Covered by test 00391 @ingroup TopologicalOperators 00392 Check if one object is covered by another object. 00393 \verbatim 00394 TeCoveredBy(x, y) => (x inter y = x) ^ (I(x) inter I(y) = true) 00395 - Case 1: (x = TePolygon and y = TePolygon) or (x = TeLine2D and y = TeLine2D) 00396 => (I(x) inter I(y) = true) ^ (I(x) inter E(y) = false) ^ (B(x) inter E(y) = false) ^ (B(x) inter B(y) = true) 00397 - Case 2: x = TeLine2D and y = TePolygon 00398 => (I(x) inter I(y) = true) ^ (I(x) inter E(y) = false) ^ (B(x) inter E(y) = false) ^ ((B(x) inter B(y) = true) v (I(x) inter B(y) = true)) 00399 \endverbatim 00400 @{ 00401 */ 00402 00403 //! Check if red line is covered by blue line 00404 TL_DLL bool TeCoveredBy(const TeLine2D& redLine, const TeLine2D& blueLine); 00405 00406 //! Check if line is covered by polygon 00407 TL_DLL bool TeCoveredBy(const TeLine2D& l, const TePolygon& pol); 00408 00409 //! Check if red polygon is covered by blue polygon 00410 TL_DLL bool TeCoveredBy(const TePolygon& redPol, const TePolygon& bluePol); 00411 00412 //! Check if cell1 is covered by cell2 00413 TL_DLL bool TeCoveredBy(const TeCell& cell1, const TeCell& cell2); 00414 00415 //! Check if polygon is covered by cell 00416 TL_DLL bool TeCoveredBy(const TePolygon& poly, const TeCell& cell); 00417 00418 //! Check if line is covered by cell 00419 TL_DLL bool TeCoveredBy(const TeLine2D& line, const TeCell& cell); 00420 /** @} */ 00421 00422 /** @defgroup TeCovers Covers test 00423 @ingroup TopologicalOperators 00424 Check if one object covers another object. 00425 TeCovers(x, y) => TeCoveredBy(y, x) 00426 @{ 00427 */ 00428 //! Check if one object covers another object 00429 template<typename T1, typename T2> 00430 inline bool TeCovers(T1& o1, T2& o2) 00431 { 00432 return TeCoveredBy(o2, o1); 00433 } 00434 /** @} */ 00435 00436 /** @defgroup TeRelation Relation test 00437 * @ingroup TopologicalOperators 00438 * Return the relation between two objects. 00439 * @{ 00440 */ 00441 /** \brief Returns the relation between coordinate c and line l. 00442 \param c The coordinate. 00443 \param l The line. 00444 \return one of the relations: INSIDE, OUTSIDE or BOUNDARY. 00445 \note It doesn't do box elimination, just uses from TeIsOnLine(coordinate, line) elimination 00446 */ 00447 TL_DLL short TeRelation(const TeCoord2D& c, const TeLine2D& l); 00448 00449 /** \brief Point in polygon inside/outside/boundary code. 00450 \param c The coordinate to test. 00451 \param r The simple polygon to test. 00452 \return one of the relations: INSIDE, OUTSIDE or BOUNDARY. 00453 \note The ring is treated as a simple polygon (no holes). Does box elimination. 00454 */ 00455 TL_DLL short TeRelation(const TeCoord2D& c, const TeLinearRing& r); 00456 00457 /** \brief Coordinate in polygon inside/outside/boundary code. 00458 \param c The coordinate to test. 00459 \param pol The polygon to test. 00460 \return one of the relations: INSIDE, OUTSIDE or BOUNDARY. 00461 \note It doesn't do box elimination, just uses from TeRelation(coordinate, line) elimination 00462 */ 00463 TL_DLL short TeRelation(const TeCoord2D& c, const TePolygon& pol); 00464 00465 /** \brief Point in polygon inside/outside/boundary code. 00466 \param p The coordinate to test. 00467 \param pol The polygon to test. 00468 \return one of the relations: INSIDE, OUTSIDE or BOUNDARY. 00469 \note It doesn't do box elimination, just uses from TeRelation(coordinate, line) elimination 00470 */ 00471 TL_DLL short TeRelation(const TePoint& p, const TePolygon& pol); 00472 00473 /** \brief Point in polygon set inside/outside/boundary code. 00474 \param c The coordinate to test. 00475 \param pSet The polygon set to test. 00476 \return one of the relations: INSIDE, OUTSIDE or BOUNDARY. 00477 \note Does box elimination. 00478 */ 00479 TL_DLL short TeRelation(const TeCoord2D& c, const TePolygonSet& pSet); 00480 00481 /** \brief This function returns the relation between two lines. 00482 \param lRed The first line. 00483 \param lBlue The second line. 00484 \param relation To return the relation that stop the search: TeDISJOINT, TeTOUCHES, TeWITHIN, TeCONTAINS, TeCROSSES, TeOVERLAPS, TeCOVEREDBY, TeCOVERS, TeEQUALS 00485 \note Doesn't do box elimination. You must implement the test in your own functions. 00486 */ 00487 TL_DLL short TeRelation(const TeLine2D& lRed, const TeLine2D& lBlue, const short& relation); 00488 00489 /** \brief This function returns the relation between a line and a polygon. 00490 \param line The line. 00491 \param pol The polygon. 00492 \return one of the relations: TeDISJOINT, TeTOUCHES, TeWITHIN (THE LINE IS WITHIN), TeCROSSES, TeCOVEREDBY (THE LINE IS COVERED BY). 00493 \note Doesn't do box elimination. You must implement the test in your own functions. 00494 */ 00495 TL_DLL short TeRelation(const TeLine2D& line, const TePolygon& pol); 00496 00497 /** \brief This function returns the relation between two polygons. 00498 \param pRed The first polygon. 00499 \param pBlue The second polygon. 00500 \return one of the relations: TeEQUALS, TeDISJOINT, TeTOUCHES, TeWITHIN (pRed IS WITHIN pBlue), TeCONTANS (pBlue CONTAINS pRed), TeOVERLAPS, TeCOVEREDBY (pRed IS COVERED BY pBlue) or TeCOVERS (pRed COVERS pBlue). 00501 \note Doesn't do box elimination. You must implement the test in your own functions. 00502 */ 00503 TL_DLL short TeRelation(const TePolygon& pRed, const TePolygon& pBlue); 00504 /** @} */ 00505 /** @} */ 00506 00507 /** @defgroup BoxTests Special box tests 00508 * @ingroup GeometryAlgorithms 00509 * Box tests. 00510 * @{ 00511 */ 00512 //! Check if box1 is DISJOINT or TOUCHes box2 00513 TL_DLL bool TeDisjointOrTouches(const TeBox& bx1, const TeBox& bx2); 00514 00515 //! Check if coordinate c is WITHIN or TOUCHes segments c1 and c2 00516 TL_DLL bool TeWithinOrTouches(const TeCoord2D& c, const TeCoord2D& c1, const TeCoord2D& c2); 00517 /** @} */ 00518 00519 00520 /** @defgroup GeometryTests Special Geometry tests 00521 * @ingroup GeometryAlgorithms 00522 * Geometry tests. 00523 * @{ 00524 */ 00525 //! Check if geom1 is WITHIN, COVERED BY or EQUAL to geom2 00526 00527 00528 template<class T1, class T2> 00529 bool TeWithinOrCoveredByOrEquals(const T1& geom1, const T2& geom2) 00530 { 00531 short rel = TeRelation(geom1, geom2); 00532 00533 if((rel&TeINSIDE) || (rel&TeBOUNDARY)) 00534 return true; 00535 00536 return false; 00537 } 00538 00539 //! Check if box1 is WITHIN, COVERED BY or EQUAL to box2 00540 template<> 00541 TL_DLL bool TeWithinOrCoveredByOrEquals(const TeBox& bx1, const TeBox& bx2); 00542 00543 //! Check if line1 is WITHIN, COVERED BY or EQUAL to line2 00544 template<> 00545 TL_DLL bool TeWithinOrCoveredByOrEquals(const TeLine2D& line1, const TeLine2D& line2); 00546 00547 //! Check if line1 is WITHIN or COVERED BY to pol 00548 template<> 00549 TL_DLL bool TeWithinOrCoveredByOrEquals(const TeLine2D& line1, const TePolygon& pol); 00550 00551 //! Check if pol1 is WITHIN, COVERED BY or EQUAL to pol2 00552 template<> 00553 TL_DLL bool TeWithinOrCoveredByOrEquals(const TePolygon& pol1, const TePolygon& pol2); 00554 /** @} */ 00555 00556 00557 /** @defgroup IntersectionOperators Intersection Operators 00558 * @ingroup GeometryAlgorithms 00559 * Functions that calculate the intersection among objects or do intersection test. 00560 * @{ 00561 */ 00562 00563 /** \brief Performs the intersection between box b1 and b2, returning the resulting box bout. 00564 \param bx1 The first box to do the intersection. 00565 \param bx2 The second box to do the intersection. 00566 \param bout The box formed by the intersection of bx1 and bx2. 00567 */ 00568 TL_DLL bool TeIntersection(const TeBox& bx1, const TeBox& bx2, TeBox& bout); 00569 00570 /** \brief Returns the segments that intersept the poly polygon in the line y. 00571 \param poly A polygon. 00572 \param y The ordinate that cuts the polygons edges. 00573 */ 00574 TL_DLL TeCoordPairVect TeGetIntersections(const TePolygon &poly, const double& y); 00575 /** @} */ 00576 00577 00578 /** @defgroup UnionOperators Union Operators 00579 * @ingroup GeometryAlgorithms 00580 * Functions that compute the union of objects. 00581 * @{ 00582 */ 00583 00584 /** \brief Combine two box, make one that includes both. 00585 \param bx1 The first box to do the union. 00586 \param bx2 The second box to do the union. 00587 */ 00588 TL_DLL TeBox TeUnion(const TeBox& bx1, const TeBox& bx2); 00589 00590 /** @} */ 00591 00592 /** @defgroup TeLocationFunctions Functions that finds the localization of objects. 00593 * @ingroup GeometryAlgorithms 00594 * Functions that finds the localization of objects. 00595 * @{ 00596 */ 00597 /** \brief Point in polygon inside/outside/boundary code. 00598 \param c The coordinate to test. 00599 \param r The simple polygon to test. 00600 00601 \note Check if point is INSIDE of a given ring. 00602 The ring is treated as a simple polygon (no holes). 00603 Adapted from: 00604 Samosky, Joseph, "SectionView: A system for interactively specifying and 00605 visualizing sections through three-dimensional medical image data, 00606 M.S. Thesis, Department of Electrical Engineering and Computer Science, 00607 Massachusetts Institute of Technology, 1993. 00608 Obs: Doesn't do box elimination. 00609 */ 00610 TL_DLL bool TePointInPoly(const TeCoord2D& c, const TeLinearRing& r); 00611 00612 /** \brief Check if coordinate c is on segment (segment is closed). 00613 \param c The coordinate to be tested. 00614 \param c1 The first segment's coordinate. 00615 \param c2 The second segment's coordinate. 00616 */ 00617 TL_DLL bool TeIsOnSegment(const TeCoord2D& c, const TeCoord2D& c1, const TeCoord2D& c2); 00618 00619 /** \brief Check if coordinate c is on line boundary or on line interior (see explanation above for definition of boundary and interior of a line). 00620 \param c The coordinate to be tested. 00621 \param l The line used in the test. 00622 00623 Obs: Do box elimination. 00624 */ 00625 TL_DLL bool TeIsOnLine(const TeCoord2D& c, const TeLine2D& l); 00626 00627 /** \brief Locate the nearest line segment of a coordinate. 00628 \param pin The coordinate. 00629 \param line The line. 00630 \param segment The position of the segment in the line 00631 \param tol Tolerance. 00632 */ 00633 TL_DLL bool TeLocateLineSegment(TeCoord2D& pin, TeLine2D& line, int& segment, double tol = 0.0); 00634 /** @} */ 00635 00636 /** @defgroup TeConvexHull Functions to compute the Convex Hull 00637 * @ingroup GeometryAlgorithms 00638 * Functions that returns the convex hull of a point list. 00639 * @{ 00640 */ 00641 00642 TL_DLL void removeDuplicatedCoords(vector<TeCoord2D>& coordSet); 00643 00644 //! This is a explicit specialization that returns the convex hull of a TeCoord2D set 00645 TL_DLL TePolygon TeConvexHull(std::vector<TeCoord2D>& coordSet); 00646 00647 //! This is a explicit specialization that returns the convex hull of a TePolygon 00648 TL_DLL TePolygon TeConvexHull(const TePolygon& p); 00649 00650 //! This is a explicit specialization that returns the convex hull of a TePolygonSet 00651 TL_DLL TePolygon TeConvexHull(const TePolygonSet& ps); 00652 00653 //! This is a explicit specialization that returns the convex hull of a TePointSet. Must be defined! 00654 TL_DLL TePolygon TeConvexHull(const TePointSet& ps); 00655 00656 /** \brief Returns the convexhull of a given list of coords in counterclockwise. 00657 \param coordSet A list with coordinates without duplicated coordinates. 00658 00659 \note This algorithm is based on the book Computational Geometry 00660 by M. de Berg, M. van Kreveld, M. Overmars and O. Schwarzkopf - Springer Verlag - pp. 6. 00661 It is O(N log N). 00662 */ 00663 template<class T> 00664 TePolygon TeConvexHull(const T& coordSet) 00665 { 00666 // creates an auxiliary line with the points of the ring 00667 vector<TeCoord2D> aux; 00668 00669 typename T::iterator it = coordSet.begin(); 00670 00671 while(it != coordSet.end()) 00672 { 00673 aux.push_back(*it); 00674 ++it; 00675 } 00676 00677 // removes duplicated coords from structs like ring 00678 removeDuplicatedCoords(aux); 00679 00680 return TeConvexHull(aux); 00681 }; 00682 00683 /** @} */ 00684 00685 /** @defgroup TeUtils Utilities functions. 00686 * @ingroup GeometryAlgorithms 00687 * @{ 00688 */ 00689 //! Given a projection "proj" returns a tolerance value in the same unit of projection to be used in geometric operations 00690 TL_DLL double TeGetPrecision(TeProjection* proj); 00691 00692 //! This class implements the Epsilon-tweaking used in calculus. 00693 class TL_DLL TeGeometryAlgorithmsPrecision 00694 { 00695 protected: 00696 00697 //! Constructor 00698 TeGeometryAlgorithmsPrecision(); 00699 00700 public: 00701 00702 //! Tells if d1 is greater than d2 according to tolerance factor. 00703 static bool IsGreater(const double& d1, const double& d2) 00704 { 00705 return ((d1 - d2) > TePrecision::instance().precision()); 00706 } 00707 00708 //! Tells if d1 is greater than or equal to d2 according to tolerance factor. 00709 static bool IsGreaterEqual(const double& d1, const double& d2) 00710 { 00711 return ((d1 - d2) >= (-TePrecision::instance().precision())); 00712 } 00713 00714 //! Tells if d1 is smaller than d2 according to a tolerance factor. 00715 static bool IsSmaller(const double& d1, const double& d2) 00716 { 00717 return ((d1 - d2) < -(TePrecision::instance().precision())); 00718 } 00719 00720 //! Tells if d1 is smaller than or equals to d2 according to a tolerance factor. 00721 static bool IsSmallerEqual(const double& d1, const double& d2) 00722 { 00723 return ((d1 - d2) <= TePrecision::instance().precision()); 00724 } 00725 00726 //! Tells if d1 is equals to d2 according to a tolerance factor. 00727 static bool IsEqual(const double& d1, const double& d2) 00728 { 00729 return (fabs(d1 - d2) <= TePrecision::instance().precision()); 00730 } 00731 00732 //! Tells if d1 is different from d2 according to a tolerance factor. 00733 static bool IsDifferent(const double& d1, const double& d2) 00734 { 00735 return (fabs(d1 - d2) > TePrecision::instance().precision()); 00736 } 00737 }; 00738 00739 //! Removes the duplicate coordinates of a line 00740 inline void TeRemoveDuplicatedCoordinates(TeLine2D& l) 00741 { 00742 for(int i = 0; i < (int)l.size() - 1; ++i) 00743 if(TeEquals(l[i], l[i + 1])) 00744 { 00745 l.erase(l.begin() + i); 00746 --i; 00747 } 00748 00749 return; 00750 } 00751 00752 //! Removes the duplicate coordinates of a polygon 00753 inline void TeRemoveDuplicatedCoordinates(TePolygon& p) 00754 { 00755 for(unsigned int i = 0; i < p.size(); ++i) 00756 TeRemoveDuplicatedCoordinates(p[i]); 00757 00758 return; 00759 } 00760 00761 /** \brief Reverses the orientation of a line. 00762 \param lin The line to be reversed. 00763 */ 00764 inline void TeReverseLine(TeLine2D& lin) 00765 { 00766 for(unsigned int i=0,j=lin.size()-1 ; i<lin.size()/2 ; ++i,--j) 00767 { 00768 TeCoord2D p = lin[i]; 00769 lin[i] = lin[j]; 00770 lin[j] = p; 00771 } 00772 00773 return; 00774 } 00775 00776 00777 /** \brief Verifies if a simple polygon defined as a linear ring is convex or not. 00778 \param ring The polygon to test convexity. 00779 */ 00780 TL_DLL bool TeIsConvex(const TeLinearRing& ring); 00781 00782 /** \brief Returns the orientation of the ring (CLOCKWISE or COUNTERCLOCKWISE); 00783 \param r The ring to be checked. 00784 */ 00785 TL_DLL short TeOrientation(const TeLinearRing& r); 00786 00787 /** @} */ 00788 00789 /** @defgroup MetricOperators Metric operators 00790 * @ingroup GeometryAlgorithms 00791 * Functions that do some usefull metric operations. 00792 * @{ 00793 */ 00794 00795 /** \brief Returns the middle point of a segment. 00796 \param first The first segment's coordinate. 00797 \param last The second segment's coordinate. 00798 \param middle The middle point. 00799 */ 00800 TL_DLL void TeGetMiddlePoint(const TeCoord2D& first, const TeCoord2D& last, TeCoord2D& middle); 00801 00802 /** \brief Calculates the Euclidian distance between two points. 00803 \param c1 First coordinate; 00804 \param c2 Second coordinate; 00805 */ 00806 TL_DLL double TeDistance(const TeCoord2D& c1, const TeCoord2D& c2); 00807 00808 /** \brief Returns the length of a Line 2D. 00809 \param l The line to calculate the length. 00810 */ 00811 TL_DLL double TeLength(const TeLine2D& l); 00812 00813 /** \brief Perpendicular distance from point to segment. 00814 \param first The first segment's coordinate. 00815 \param last The second segment's coordinate. 00816 \param pin The point to get the distance from the segment. 00817 \param pinter The point of intersection on the segment. 00818 */ 00819 TL_DLL double TePerpendicularDistance(const TeCoord2D& first, const TeCoord2D& last, const TeCoord2D& pin, TeCoord2D &pinter); 00820 00821 /** \brief Minimal distance from point to segment. 00822 \param first The first segment's coordinate. 00823 \param last The second segment's coordinate. 00824 \param pin The point to get the minimal distance from the segment. This point is inside the segment 00825 \param pout The nearest segment point of the pin point. 00826 \param tol Numerical tolerance 00827 */ 00828 TL_DLL double TeMinimumDistance (const TeCoord2D& first, const TeCoord2D& last, const TeCoord2D& pin, TeCoord2D& pout, double tol = 0.0); 00829 00830 /** \brief Template class to compute the area of a geometry 00831 \param geom The geometry whose area we want to known. 00832 \note This algorithm is based on the book Spatial Databases with Application to GIS 00833 by Philippe Rigaux, Michel O. Scholl and Agnes Voisard. 00834 00835 */ 00836 00837 template<class T> 00838 double TeGeometryArea(const T& /* geom */) 00839 { 00840 return 0.0; 00841 } 00842 00843 //! This is a explicit specialization that returns the area of a TePolygon 00844 template<> 00845 TL_DLL double TeGeometryArea(const TePolygon& p); 00846 00847 //! This is a explicit specialization that returns the area of a TePolygonSet 00848 template<> 00849 TL_DLL double TeGeometryArea(const TePolygonSet& ps); 00850 00851 //! This is a explicit specialization that returns the area of a Box 00852 template<> 00853 TL_DLL double TeGeometryArea(const TeBox& b); 00854 00855 //! This is a explicit specialization that returns the area of a Box 00856 template<> 00857 TL_DLL double TeGeometryArea(const TeMultiGeometry& mGeom); 00858 /** @} */ 00859 00860 /** @defgroup GeometryFunction Functions that return geometries. 00861 * @ingroup GeometryAlgorithms 00862 * Functions that return geometries. 00863 * @{ 00864 */ 00865 /** \brief Given a box return its polygon representation. 00866 \param b The box to create a polygon. 00867 */ 00868 TL_DLL TePolygon TeMakePolygon(const TeBox& b); 00869 00870 /** \brief Given N points, finds a path that doesn't self-intersects 00871 \note Given N points, finds a path that doesn't self-intersects, visiting all points and returning 00872 to the begginning one. It is based on the book Algorithms by Robert Sedgewick, Addisson-Wesley, 1988; 00873 \param pSet The point set to form a path. 00874 */ 00875 TL_DLL TeLinearRing TeSimpleClosedPath(const TePointSet& pSet); 00876 /** @} */ 00877 00878 00879 /** @defgroup TeFindCentroid Functions to compute the centroid 00880 * @ingroup GeometryAlgorithms 00881 * Functions that return the centroid. 00882 * @{ 00883 */ 00884 00885 /** \brief Calculates the centroid of a multi geometry. 00886 \param p A multi geometry whose centroid we want to known. 00887 */ 00888 TL_DLL TeCoord2D TeFindCentroid(TeMultiGeometry& mGeom); 00889 00890 /** \brief Calculates the centroid of a polygon. 00891 \param p A TePolygon whose centroid we want to known. 00892 */ 00893 TL_DLL TeCoord2D TeFindCentroid(const TePolygon& p); 00894 00895 /** \brief Calculates a reference point. 00896 \param l A TeLine whose centroid we want to known. 00897 */ 00898 TL_DLL TeCoord2D TeFindCentroid(const TeLine2D& l); 00899 00900 /*! \fn TeCoord2D TeFindCentroid(const TeCell& c ); 00901 \brief Calculates the centroid of a cell. 00902 \param c A TeCell whose centroid we want to known. 00903 */ 00904 TL_DLL TeCoord2D TeFindCentroid(const TeCell& c); 00905 00906 /** \brief Calculates the centroid of a point. 00907 \param p A TePoint whose centroid we want to known. 00908 */ 00909 TL_DLL TeCoord2D TeFindCentroid(const TePoint& p); 00910 00911 /** \brief Calculates the centroid of a text. 00912 \param t A TeText whose centroid we want to known. 00913 */ 00914 TL_DLL TeCoord2D TeFindCentroid(const TeText& t); 00915 00916 /** \brief Calculates the centroid of a polygon set. 00917 \param s A TePolygon set whose centroid we want to known. 00918 */ 00919 TL_DLL TeCoord2D TeFindCentroid(const TePolygonSet& s); 00920 00921 /** Calculates the centroid of a line set. 00922 \param s A TeLine set whose centroid we want to known. 00923 */ 00924 TL_DLL TeCoord2D TeFindCentroid(const TeLineSet& s); 00925 00926 /** \brief Calculates the centroid of a cell set. 00927 \param s A TeCell set whose centroid we want to known. 00928 */ 00929 TL_DLL TeCoord2D TeFindCentroid(const TeCellSet& s); 00930 00931 /** \brief Calculates the centroid of a point set. 00932 \param ps A TePointSet set whose centroid we want to known. 00933 */ 00934 TL_DLL TeCoord2D TeFindCentroid(TePointSet& ps); 00935 00936 /** \brief Calculates the centroid of a text set. 00937 \param ts A TeTextSet set whose centroid we want to known. 00938 */ 00939 TL_DLL TeCoord2D TeFindCentroid(TeTextSet& ts); 00940 00941 /** \brief Calculates the center of a triangle. 00942 \param vert0 First triagle's vertex. 00943 \param vert1 Second triagle's vertex. 00944 \param vert2 Third triagle's vertex. 00945 \param pc The triangle center. 00946 */ 00947 TL_DLL bool TeFindTriangleCenter(const TeCoord2D& vert0, const TeCoord2D& vert1, const TeCoord2D& vert2, TeCoord2D& pc); 00948 /** \brief Calculates intersection between two segments. 00949 \param fr0 First point of first segment. 00950 \param to0 Second point of first segment. 00951 \param fr1 First point of second segment. 00952 \param to1 Second point of second segment. 00953 \param pi The intersection point coordinates. 00954 \return true is intersects, false otherwise. 00955 */ 00956 00957 TL_DLL bool TeSegmentsIntersectPoint(const TeCoord2D& fr0, const TeCoord2D& to0, const TeCoord2D& fr1, const TeCoord2D& t1, TeCoord2D& pi); 00958 00959 /** @} */ 00960 00961 00962 /** @defgroup TeNearest Functions to compute the nearest part of an object to a point. 00963 * @ingroup GeometryAlgorithms 00964 * Auxiliary functions. 00965 * @{ 00966 */ 00967 //! Nearest node in set from location pt (i = the node index in the nodeset) 00968 TL_DLL bool TeNearest(TeCoord2D& pt, TeNodeSet& ns , int& i, const double& tol = 0.0); 00969 00970 //! Nearest point in set from location pt (i = the point index in the pointset) 00971 TL_DLL bool TeNearest(TeCoord2D& pt, TePointSet& ps , int& i, const double& tol = 0.0); 00972 00973 //! Nearest text in set from location pt (i = the text index in the textset) 00974 TL_DLL bool TeNearest(TeCoord2D& pt, TeTextSet& ts , int& i, const double& tol = 0.0); 00975 00976 //! Nearest line in set from location pt (i = the line index in the lineset and pi = the closest point) 00977 //! The pi point can be outside a line of the line set 00978 TL_DLL bool TeNearest(TeCoord2D& pt, TeLineSet& ls , int& i, TeCoord2D& pi, const double& tol = 0.0); 00979 00980 //! Nearest line in set from location pt (i = the line index in the lineset and pout = the closest point) 00981 //! The pout point must be inside a line of the line set 00982 TL_DLL bool TeNearest (TeCoord2D& pt,TeLineSet& ls, int& lindex, TeCoord2D& pout, double& dmin, const double& tol = 0.0); 00983 00984 //! Nearest polygon in set from location pt (i = the polygon index in the polygonset). 00985 TL_DLL bool TeNearest(TeCoord2D& pt, TePolygonSet& ps , int& i, const double& tol = 0.0); 00986 00987 //! Nearest line in set from location pt (i = the line index in lineset) calculated by the vertex of the lines 00988 TL_DLL bool TeNearestByPoints(TeCoord2D& pt, TeLineSet& ls , int& i, double& dist, const double& tol = 0.0); 00989 /** @} */ 00990 00991 /** @defgroup CurveFunctions Functions used to deal with smooth curves 00992 * @ingroup GeometryAlgorithms 00993 * @{ 00994 */ 00995 /** \brief Given three points of a circunference, returns its center point. 00996 \param p1 First point. 00997 \param p2 Second point. 00998 \param p3 Third point. 00999 \param center Circunference center. 01000 This algorithm is adapted from http://www.delphiforfun.org/Programs/Math_Topics/circle_from_3_points.htmbook. 01001 */ 01002 TL_DLL bool TeGetCenter(TePoint p1, TePoint p2, TePoint p3, TePoint ¢er); 01003 01004 /** \brief Given three points of a circunference, returns the radius. 01005 \param p1 First point. 01006 \param p2 Second point. 01007 \param p3 Third point. 01008 This algorithm is adapted from http://www.delphiforfun.org/Programs/Math_Topics/circle_from_3_points.htmbook. 01009 */ 01010 TL_DLL double TeGetRadius(TePoint &p1, TePoint &p2, TePoint &p3); 01011 01012 /** \brief Given three points returns a smooth arc as a TeLine2D that contains a given total number of points. 01013 01014 \param p1 First point. 01015 \param p2 Second point. 01016 \param p3 Third point. 01017 \param arcOut The return arc. 01018 \param NPoints Number of arc points. 01019 01020 This algorithm is adapted from http://mathforum.org/dr.math/ 01021 01022 */ 01023 TL_DLL bool TeGenerateArc(TePoint& p1, TePoint& p2, TePoint& p3, TeLine2D& arcOut, const short& NPoints); 01024 01025 /** \brief Given a center point and a radius, returns the circle as a TeLine2D interpolated by a given number of points 01026 \param center Center point of the circle. 01027 \param radius radius of the circle. 01028 \param circle The return circle 01029 \param NPoints Number of circle points. 01030 */ 01031 TL_DLL bool TeGenerateCircle(const TePoint& center, const double& radius, TeLine2D& circle, const short& NPoints); 01032 01033 /** \brief Performs a line simplication 01034 \param line The line to be simplified 01035 \param snap Simplification threshold 01036 \param maxdist The maximum distance between intermediary segments 01037 */ 01038 TL_DLL bool TeLineSimplify(TeLine2D& line, double snap, double maxdist); 01039 01040 /** \brief Adjust Segment to specific distance 01041 \param P0 first coordinate 01042 \param P1 second coordinate 01043 \param d0 distance value to adjust 01044 \param P0out first coordinate adjusted 01045 \param P1out second coordinate adjusted 01046 \return returns true whether possible adjust segment 01047 */ 01048 TL_DLL bool TeAdjustSegment(TeCoord2D P0, TeCoord2D P1, double d0, TeCoord2D &P0out, TeCoord2D &P1out); 01049 01050 /** \brief Get middle line 01051 Method like find Centroid but this method calculate the correct middle point 01052 \param line The Line to calculate the middle point 01053 \param p middle point 01054 \return returns true case possible calculate the middle line 01055 */ 01056 TL_DLL bool TeFindCentroid(const TeLine2D &line, TeCoord2D &p); 01057 01058 /** @} */ 01059 01060 /** @} */ // end of group GeometryAlgorithms 01061 01062 01063 #endif // __TERRALIB_INTERNAL_GEOMETRYALGORITHMS_H
1.5.3