TeGeometryAlgorithms.h

Go to the documentation of this file.
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 &center);
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

Generated on Sun Jul 29 04:01:21 2012 for TerraLib - Development Source by  doxygen 1.5.3