polyline.h

Go to the documentation of this file.
00001 /**
00002  * \file polyline.h <mi32/polyline.h>
00003  * \brief Definitions for 2D and/or 3D poly lines
00004  *
00005  * \if NODOC
00006  * $Id: polyline.h_v 1.83 2004/11/24 21:04:27 scowan Exp $
00007  *
00008  * $Log: polyline.h_v $
00009  * Revision 1.83  2004/11/24 21:04:27  scowan
00010  * Update comments.
00011  *
00012  * Revision 1.82  2004/11/24 18:45:06  scowan
00013  * Major update of find intersections and combine methods.
00014  *
00015  * Revision 1.81  2004/11/16 21:55:24  scowan
00016  * Fixed unix issue of convewrt to long.
00017  *
00018  * Revision 1.80  2004/11/16 17:14:24  dwilliss
00019  * Added variation of ConvertToLong that just takes an LPOINT2D array so taht
00020  * region2d's new ConvertToLongTruncate can call it.
00021  *
00022  * Revision 1.79  2004/10/27 21:25:57  scowan
00023  * Updated docs.
00024  *
00025  * Revision 1.78  2004/10/27 21:13:41  scowan
00026  * Moved internal closest point searching from conflate to its own method.
00027  *
00028  * Revision 1.77  2004/10/25 19:44:07  scowan
00029  * No real change, just some shortcuts added..
00030  *
00031  * Revision 1.76  2004/10/15 17:50:42  scowan
00032  * Added sections class and added and removed methos.
00033  *
00034  * Revision 1.75  2004/09/17 22:06:43  scowan
00035  * Fill in the spaces.
00036  *
00037  * Revision 1.74  2004/08/21 21:41:29  scowan
00038  *  Moved changes from 6.9 to here regarding conflate.
00039  *
00040  * Revision 1.73  2004/08/17 21:30:20  mju
00041  * Change combineresult enum names to be clearer and not specific to 'clipping'.
00042  *
00043  * Revision 1.72  2004/08/06 16:42:07  dwilliss
00044  * Added MoveVertex method
00045  *
00046  * Revision 1.71  2004/07/29 14:53:14  scowan
00047  * Added set precision method.
00048  *
00049  * Revision 1.70  2004/07/14 21:10:22  scowan
00050  * Removed methods that used legacy region code.
00051  *
00052  * Revision 1.69  2004/06/23 22:56:23  scowan
00053  * Added methods to transform the polyline points via a coord op transformation.
00054  *
00055  * Revision 1.68  2004/05/21 16:32:37  scowan
00056  * Added method to apply a zscale to the z coordinates of the line.
00057  *
00058  * Revision 1.67  2004/03/03 15:30:00  scowan
00059  * Fixed annoying warning issue.,
00060  *
00061  * Revision 1.66  2004/03/02 22:50:15  scowan
00062  * Export strip class.
00063  *
00064  * Revision 1.65  2004/03/02 15:23:56  scowan
00065  * Add function to allow milist < polyline >.
00066  *
00067  * Revision 1.64  2004/03/02 15:11:57  scowan
00068  * Removed defines when done.
00069  * Export poly line list.
00070  * Make dump ints info inline again.
00071  *
00072  * Revision 1.63  2004/03/02 00:24:38  scowan
00073  * Export from geom the class.
00074  *
00075  * Revision 1.62  2004/02/11 16:07:26  scowan
00076  * Added inline bool methods.
00077  *
00078  * Revision 1.61  2004/02/10 23:13:28  scowan
00079  * Added virtual method.
00080  *
00081  * Revision 1.60  2003/12/17 22:12:19  scowan
00082  * Added method for is equivalent to.
00083  *
00084  * Revision 1.59  2003/11/28 15:58:08  scowan
00085  * Changed is eqiv to method.
00086  *
00087  * Revision 1.58  2003/11/25 00:30:14  scowan
00088  * Added is equivalent to methods.
00089  *
00090  * Revision 1.57  2003/11/06 18:24:51  scowan
00091  * Added parameter to remove duplicate method.
00092  *
00093  * Revision 1.56  2003/10/16 20:16:30  scowan
00094  * Passed mi string instead of file pointer for log in validate.
00095  *
00096  * Revision 1.55  2003/09/25 21:29:07  dwilliss
00097  * Don't capitalize enum any more. Genitor needed it, doxygen doesn't like it.
00098  *
00099  * Revision 1.54  2003/09/15 13:49:56  fileserver!dwilliss
00100  * Doxygen
00101  *
00102  * Revision 1.53  2003/09/09 17:56:29  scowan
00103  * Added another convert to long method.
00104  *
00105  * Revision 1.52  2003/09/04 22:02:36  scowan
00106  * More class friends.
00107  *
00108  * Revision 1.51  2003/09/04 17:09:40  scowan
00109  * Added detach buffer method.
00110  *
00111  * Revision 1.50  2003/08/11 20:34:10  scowan
00112  * Added compute longest segment method and added length optimization.
00113  *
00114  * Revision 1.49  2003/07/22 22:15:37  scowan
00115  * Reset add join end method.
00116  *
00117  * Revision 1.48  2003/07/22 00:00:27  scowan
00118  * Added two more compute offset methods.
00119  *
00120  * Revision 1.47  2003/06/04 22:03:05  scowan
00121  * Added method to determine if extents are available and get them if they are.
00122  *
00123  * Revision 1.46  2003/04/29 17:26:17  scowan
00124  * Added typedef for poly line list.
00125  *
00126  * Revision 1.45  2003/01/09 19:21:04  scowan
00127  * Added new ctor.
00128  *
00129  * Revision 1.44  2002/12/18 23:17:36  scowan
00130  * Added trianglulate.
00131  *
00132  * Revision 1.43  2002/11/21 18:57:16  dwilliss
00133  * Added IsRectangle() method
00134  *
00135  * Revision 1.42  2002/11/14 16:48:34  scowan
00136  * Change parameter type.
00137  *
00138  * Revision 1.41  2002/11/12 20:18:14  dwilliss
00139  * Ok, so I don't have the points as a SIMPLE_ARRAY.
00140  * Implemented constructor/Assign that take array of LPOINT2D and NumPoints so
00141  *   we don't have to make a temporary copy.
00142  *
00143  * Revision 1.40  2002/11/12 20:09:34  dwilliss
00144  * Added constructor and Assign method taking SIMPLE_ARRAY<LPOINT2D>
00145  *
00146  * Revision 1.39  2002/10/18 13:52:14  scowan
00147  * Changed combine parameters.
00148  *
00149  * Revision 1.38  2002/10/14 16:24:38  scowan
00150  * Added equal method and operator overloads.
00151  *
00152  * Revision 1.37  2002/10/09 22:26:23  scowan
00153  * Added combination methods.
00154  *
00155  * Revision 1.36  2002/10/07 17:39:41  scowan
00156  * More comments.
00157  *
00158  * Revision 1.35  2002/10/04 21:14:36  scowan
00159  * Added orientation optimization.
00160  * Renamed swap to reverse.
00161  *
00162  * Revision 1.34  2002/09/20 19:38:10  scowan
00163  * Added check for strip optimization.
00164  *
00165  * Revision 1.33  2002/09/19 14:44:06  scowan
00166  * Removed use of vector include file.
00167  *
00168  * Revision 1.32  2002/09/18 19:22:55  scowan
00169  * Added 3d trans methods.
00170  *
00171  * Revision 1.31  2002/09/18 16:55:21  scowan
00172  * Added more comments.
00173  *
00174  * Revision 1.30  2002/09/16 15:12:08  scowan
00175  * Added methods for optimization, ref counting and Z coordinate settings.
00176  *
00177  * Revision 1.29  2002/07/11 15:50:04  scowan
00178  * nothing rteally.
00179  *
00180  * Revision 1.28  2002/07/05 19:41:01  scowan
00181  * Added method for 3d rect assignment.
00182  *
00183  * Revision 1.27  2002/06/20 15:51:57  scowan
00184  * Split up intersection clean.
00185  *
00186  * Revision 1.26  2002/06/03 23:58:26  scowan
00187  * nc
00188  *
00189  * Revision 1.25  2002/06/03 23:57:38  scowan
00190  * Added clip to arbitrary region.
00191  *
00192  * Revision 1.24  2002/05/10 19:33:48  scowan
00193  * Added another long to round.
00194  *
00195  * Revision 1.23  2002/04/23 16:27:37  scowan
00196  * Return value change and docs for clip.
00197  *
00198  * Revision 1.22  2002/04/23 15:59:55  scowan
00199  * Added more comments.
00200  *
00201  * Revision 1.21  2002/04/17 21:28:11  scowan
00202  * Added clip methods and classes.
00203  *
00204  * Revision 1.20  2002/03/14 18:21:57  scowan
00205  * Moved mid point comp inside.
00206  *
00207  * Revision 1.19  2002/02/28 18:58:52  scowan
00208  * Updated docs.
00209  *
00210  * Revision 1.18  2002/02/28 18:56:06  scowan
00211  * Updated documentation.
00212  *
00213  * Revision 1.17  2001/12/28 16:25:09  scowan
00214  * Added get test point method.
00215  *
00216  * Revision 1.16  2001/12/26 20:48:22  scowan
00217  * Added method and more const.
00218  *
00219  * Revision 1.15  2001/11/07 21:43:33  scowan
00220  * Added conflate method.
00221  *
00222  * Revision 1.14  2001/10/24 21:00:01  scowan
00223  * Nothing.
00224  *
00225  * Revision 1.13  2001/10/23 15:20:00  scowan
00226  * New extract method.
00227  *
00228  * Revision 1.12  2001/09/07 22:02:07  scowan
00229  * Added parameter.
00230  *
00231  * Revision 1.11  2001/05/24 17:00:22  scowan
00232  * Added many more methods, including intersect, thin, and spline.
00233  * Uses new MIDOUBLEARRAY for base operations.
00234  *
00235  * Revision 1.10  2001/02/13 23:31:52  scowan
00236  * Added methods to find point given distance and extract a sub-line given distance.
00237  *
00238  * Revision 1.9  2001/01/26 17:32:40  scowan
00239  * Fixed line closure ambiguity.
00240  *
00241  * Revision 1.8  2001/01/22 17:09:20  mju
00242  * Add GetVertices().
00243  *
00244  * Revision 1.7  2001/01/17 15:49:36  mju
00245  * Change default ctor to put ReservePoints at end.
00246  *
00247  * Revision 1.6  2001/01/17 15:19:38  mju
00248  * Add FindClosestSegment().
00249  *
00250  * Revision 1.5  2001/01/17 14:45:26  mju
00251  * Add FindClosestVertex which returns index.
00252  *
00253  * Revision 1.4  2001/01/12 22:56:42  scowan
00254  * Chagned compression method names.
00255  *
00256  * Revision 1.3  2001/01/11 16:42:27  scowan
00257  * Added compression methods.
00258  *
00259  * Revision 1.2  2001/01/05 20:58:02  scowan
00260  * Major changes suggested by Mike.
00261  *
00262  * Revision 1.1  2001/01/04 22:54:20  scowan
00263  * Initial revision
00264  *
00265  * \endif
00266 **/
00267 
00268 #ifndef INC_MI32_POLYLINE_H
00269 #define INC_MI32_POLYLINE_H
00270 
00271 #ifndef  INC_MI32_STDDEFNS_H
00272    #include <mi32/stddefns.h>
00273 #endif
00274 
00275 #ifndef  INC_MI32_DOUBLEAR_H
00276    #include <mi32/doublear.h>
00277 #endif
00278 
00279 #ifndef  INC_MI32_SIMPLEAR_H
00280    #include <mi32/simplear.h>
00281 #endif
00282 
00283 #ifndef  INC_MI32_POINT_H
00284    #include <mi32/point.h>
00285 #endif
00286 
00287 #ifndef  INC_MI32_RANGE_H
00288    #include <mi32/range.h>
00289 #endif
00290 
00291 #ifndef  INC_MI32_RECT_H
00292    #include <mi32/rect.h>
00293 #endif
00294 
00295 #ifndef  INC_MI32_MILIST_H
00296    #include <mi32/milist.h>
00297 #endif
00298 
00299 #ifdef GEOMDLL
00300    #define GEOMLIBEXPORT MI_DLLEXPORT
00301    #define GEOMLIBCLASSEXPORT MI_DLLCLASSEXPORT
00302 #else
00303    #define GEOMLIBEXPORT MI_DLLIMPORT
00304    #define GEOMLIBCLASSEXPORT MI_DLLCLASSIMPORT
00305 #endif
00306 
00307 struct DTRIANGLE2D {
00308    DPOINT2D p1;
00309    DPOINT2D p2;
00310    DPOINT2D p3;
00311    };
00312 
00313 #ifndef GENERATING_DOXYGEN_OUTPUT
00314 //! Forward declarations
00315 class BITSET_UNOWNED;
00316 class TRANS2D_AFFINE;
00317 class TRANS2D_MAPGEN;
00318 class TRANS3D;
00319 namespace SPATREF { class COORDOP; }
00320 #endif //!< GENERATING_DOXYGEN_OUTPUT
00321 
00322 enum CLIPMODE {
00323   CLIPMODE_Inside =  0,    //!< Clip to inside of region
00324   CLIPMODE_Outside = 1    //!< Clip to outside of region
00325   };
00326 
00327 enum TESTCRITERIA {
00328   TESTCRITERIA_FullOutside = 0,  //!< Test if fully outside region
00329   TESTCRITERIA_PartOutside = 1,  //!< Test if any part is outside region
00330   TESTCRITERIA_FullInside = 2,   //!< Test if fully inside region
00331   TESTCRITERIA_PartInside = 3    //!< Test if any part is inside region
00332   };
00333 
00334 
00335 //--------------------------------------------------------------------------------------------------------------------
00336 //! The POLYLINE class encapsulates a 2D or 3D polyline.  Its primary use is for manipulation of
00337 //! coordinates whether in 2D or 3D.  It does not maintain polygon topology (i.e. crossing segments are not
00338 //! resolved).  The base storage method is a MIDOUBLEARRAY, by which alignment is maintained.
00339 //!
00340 //! A POLYLINE instance can have associated with it certain optimization setups to improve some of the methods
00341 //! response times.  They are currently "Extents", "Section", and "Strip" optimizations.  The methods that can
00342 //! make use of these optimizations will state that in the documentation for that method.
00343 //--------------------------------------------------------------------------------------------------------------------
00344 
00345 class GEOMLIBCLASSEXPORT POLYLINE {
00346    public:
00347    
00348       enum COMPRESULT {
00349          COMPRESULT_Outside = 1,       //!< Both elements are outside of each other
00350          COMPRESULT_Inside,            //!< One element is completely inside the other
00351          COMPRESULT_Intersect,         //!< Both elements intersect
00352          COMPRESULT_Overlap            //!< One element overlaps the other
00353          };
00354 
00355       //! Values returned for Union(), Intersect(), Subtract() and ExclusiveUnion()
00356       enum COMBINERESULT {
00357          COMBINERESULT_Disjoint =      1, //!< Polygons are disjoint
00358          COMBINERESULT_OperInsideSrc = 2, //!< Operator polygon inside source polygon, may share border point(s)
00359          COMBINERESULT_SrcInsideOper = 3, //!< Source polygon inside operator polygon, may share border point(s)
00360          COMBINERESULT_Equal =         4, //!< Source polygon equals operator polygon
00361          COMBINERESULT_Intersect =     5, //!< Source and operator polygons intersect
00362          // Legacy names
00363          COMBINERESULT_ClipOutside =   COMBINERESULT_Disjoint,
00364          COMBINERESULT_ClipInside =    COMBINERESULT_OperInsideSrc,
00365          COMBINERESULT_SrcInside =     COMBINERESULT_SrcInsideOper
00366          };
00367 
00368       enum EXTRACT {
00369          EXTRACT_StartPoint = 1,
00370          EXTRACT_CenterPoint,
00371          EXTRACT_EndPoint
00372          };
00373          
00374       enum JOINTYPE {
00375          JOINTYPE_Miter = 0,
00376          JOINTYPE_Round,
00377          JOINTYPE_Bevel
00378          };
00379          
00380       enum SPLINEFLAGS {
00381          SPLINEFLAG_None =             0x0000,
00382          SPLINEFLAG_DontMoveEnds =     0x0001,
00383          SPLINEFLAG_UseMinDistance =   0x0002,
00384          SPLINEFLAG_TreatAsClosed =    0x0004
00385          };
00386          
00387       enum SPLINE {
00388          SPLINE_NoSpline = 0,
00389          SPLINE_Cubic,
00390          SPLINE_Quadratic,
00391          SPLINE_Bezier
00392          };
00393          
00394       enum THINMETHOD {
00395          THINMETHOD_MinRatio = 1,
00396          THINMETHOD_Minimum,
00397          THINMETHOD_Douglas
00398          };
00399 
00400       class ITERATOR;
00401 
00402       //! Constant iterator.
00403       class CONST_ITERATOR {
00404       public:
00405 
00406          CONST_ITERATOR (                 //! Default constructor
00407             ) :
00408             m_Index(0),
00409             m_PolyLine(0)
00410             {}
00411 
00412          CONST_ITERATOR (                 //! Internal constructor
00413             INT32 index,
00414             const POLYLINE*const PolyLine
00415             ) : 
00416             m_Index(index),
00417             m_PolyLine(PolyLine)
00418             {}
00419 
00420          CONST_ITERATOR (                 //! Copy constructor
00421             const CONST_ITERATOR& rhs
00422             ) : 
00423             m_Index(rhs.m_Index),
00424             m_PolyLine(rhs.m_PolyLine)
00425             {}
00426 
00427          CONST_ITERATOR (                 //! Copy constructor
00428             const ITERATOR& rhs
00429             ) : 
00430             m_Index(rhs.m_Index),
00431             m_PolyLine(rhs.m_PolyLine)
00432             {}
00433             
00434          CONST_ITERATOR& operator= (
00435             const CONST_ITERATOR& rhs
00436             ) {
00437             if (this != &rhs) {
00438                m_Index = rhs.m_Index;
00439                m_PolyLine = rhs.m_PolyLine;
00440                }
00441             return (*this);
00442             }
00443             
00444          const DPOINT2D& operator* (      //! Dereference operator, returns reference to templated item
00445             ) const {return (m_PolyLine->GetVertex(m_Index));}
00446 
00447          const DPOINT2D* operator-> (     //! Dereference operator, returns pointer to templated item
00448             ) const {return (&**this);}
00449 
00450          //! Pre-increment operator.
00451          CONST_ITERATOR& operator++ (
00452             ) {
00453             m_Index ++;
00454             return (*this);
00455             }
00456 
00457          //! Post-increment operator.
00458          CONST_ITERATOR operator++(int
00459             ) {
00460             CONST_ITERATOR temp = *this;
00461             ++*this;
00462             return (temp);
00463             }
00464 
00465          //! Pre-decrement operator.
00466          CONST_ITERATOR& operator-- (
00467             ) {
00468             m_Index --;
00469             return (*this);
00470             }
00471 
00472          //! Post-decrement operator.
00473          CONST_ITERATOR operator--(int
00474             ) {
00475             CONST_ITERATOR temp = *this;
00476             --*this;
00477             return (temp);
00478             }
00479 
00480          bool operator== (          //! Equality operator
00481             const CONST_ITERATOR& rhs
00482             ) const {return (m_Index == rhs.m_Index && m_PolyLine == rhs.m_PolyLine);}
00483 
00484          bool operator!= (          //! Inequality operator
00485             const CONST_ITERATOR& rhs
00486             ) const {return (!(*this == rhs));}
00487             
00488          INT32 GetIndex (
00489             ) const {return (m_Index);}
00490 
00491       protected:
00492          INT32 m_Index;
00493          const POLYLINE* m_PolyLine;
00494          };
00495 
00496       //! Non-const iterator.
00497       class ITERATOR {
00498       public:
00499 
00500          ITERATOR (                 //! Default constructor
00501             ) :
00502             m_Index(0),
00503             m_PolyLine(0)
00504             {}
00505 
00506          ITERATOR (                 //! Internal constructor
00507             INT32 index,
00508             POLYLINE* PolyLine
00509             ) : 
00510             m_Index(index),
00511             m_PolyLine(PolyLine)
00512             {}
00513 
00514          ITERATOR (                 //! Copy constructor
00515             const ITERATOR& rhs
00516             ) : 
00517             m_Index(rhs.m_Index),
00518             m_PolyLine(rhs.m_PolyLine)
00519             {}
00520 
00521          ITERATOR& operator= (
00522             const ITERATOR& rhs
00523             ) {
00524             if (this != &rhs) {
00525                m_Index = rhs.m_Index;
00526                m_PolyLine = rhs.m_PolyLine;
00527                }
00528             return (*this);
00529             }
00530             
00531          DPOINT2D& operator* (            //! Dereference operator, returns reference to templated item
00532             ) const {return (m_PolyLine->GetVertexRef(m_Index));}
00533 
00534          DPOINT2D* operator-> (        //! Dereference operator, returns pointer to templated item
00535             ) const {return (&**this);}
00536 
00537          //! Pre-increment operator.
00538          ITERATOR& operator++ (
00539             ) {
00540             m_Index ++;
00541             return (*this);
00542             }
00543 
00544          //! Post-increment operator.
00545          ITERATOR operator++(int
00546             ) {
00547             ITERATOR temp = *this;
00548             ++*this;
00549             return (temp);
00550             }
00551 
00552          //! Pre-decrement operator.
00553          ITERATOR& operator-- (
00554             ) {
00555             m_Index --;
00556             return (*this);
00557             }
00558 
00559          //! Post-increment operator.
00560          ITERATOR operator--(int
00561             ) {
00562             ITERATOR temp = *this;
00563             --*this;
00564             return (temp);
00565             }
00566 
00567          //! Equality operator
00568          bool operator== (
00569             const ITERATOR& rhs
00570             ) const {return (m_Index == rhs.m_Index && m_PolyLine == rhs.m_PolyLine);}
00571 
00572          //! Inequality operator
00573          bool operator!= (
00574             const ITERATOR& rhs
00575             ) const {return (!(*this == rhs));}
00576 
00577       protected:
00578          INT32 m_Index;
00579          POLYLINE *m_PolyLine;
00580          
00581          friend class CONST_ITERATOR;
00582          };
00583          
00584       class SECTION {
00585          public:
00586             SECTION (
00587                const DRECT2D& Extents,
00588                INT32 StartVertex,
00589                INT32 EndVertex
00590                ) : 
00591                m_Extents(Extents),
00592                m_VertexRange(StartVertex, EndVertex)
00593                {}
00594                
00595             ~SECTION (
00596                ) {}
00597                
00598             const DRECT2D& GetExtents (
00599                ) const { return (m_Extents); }
00600                
00601             const INT32_RANGE& GetVertexRange (
00602                ) const { return (m_VertexRange); }
00603                
00604          private:
00605             DRECT2D m_Extents;
00606             INT32_RANGE m_VertexRange;
00607             
00608             friend class POLYLINE;
00609          };
00610       typedef DOUBLE_ARRAY<SECTION> SECTIONARRAY;
00611 
00612       #ifndef GENERATING_DOXYGEN_OUTPUT
00613       class CLIP;
00614       class INTERSECTINFO;
00615       class SECTIONS;
00616       class SPLIT;
00617       class STRIPS;
00618       #endif //!< GENERATING_DOXYGEN_OUTPUT
00619       
00620       //! Default constructor
00621       POLYLINE (
00622          bool closed = false,                //!< Create and maintain a closed polyline
00623          DIMENSION dimension = DIMENSION_2D, //!< Create a 2D or 3D line
00624          double ZValue = 0.0,                //!< Initial Z value for POLYLINE if NumDim != 3
00625          UINT32 ReservePoints = 1            //!< Initial number of points to reserve in buffer
00626          );
00627 
00628       //! Constructor from DRECT2D, sets closed flag
00629       //! Sets "Extents" optimization
00630       explicit POLYLINE (
00631          const DRECT2D& rect,                //!< DRECT2D to create a line from
00632          double ZValue = 0.0                 //!< Initial Z value for POLYLINE if NumDim != 3
00633          );
00634          
00635       //! Constructor from DRECT3D, sets closed flag
00636       //! Sets "Extents" optimization
00637       explicit POLYLINE (
00638          const DRECT3D& rect                 //!< DRECT3D to create a line from
00639          );
00640          
00641       //! Constructor from legacy DPOLYGON
00642       explicit POLYLINE (
00643          const DPOLYGON& dpoly,              //!< Legacy DPOLYGON to create a line from
00644          bool closed = false,                //!< Create and maintain a closed polyline
00645          DIMENSION dimension = DIMENSION_2D, //!< Create a 2D or 3D line
00646          double ZValue = 0.0                 //!< Initial Z value for POLYLINE if NumDim != 3
00647          );
00648          
00649       //! Constructor from DPOINT2D array and number of points
00650       POLYLINE (
00651          const DPOINT2D* pts,
00652          INT32 NumPoints,
00653          bool closed = false,                //!< Create and maintain a closed polyline
00654          DIMENSION dimension = DIMENSION_2D, //!< Create a 2D or 3D line
00655          double ZValue = 0.0                 //!< Initial Z value for POLYLINE if NumDim != 3
00656          );
00657          
00658       //! Constructor from DOUBLE_ARRAY<double>
00659       //! This constructor transfers ownership from the DOUBLE_ARRAY<>
00660       explicit POLYLINE (
00661          DOUBLE_ARRAY<double>& rhs,
00662          bool closed = false,                //!< Create and maintain a closed polyline
00663          DIMENSION dimension = DIMENSION_2D, //!< Create a 2D or 3D line
00664          double ZValue = 0.0                 //!< Initial Z value for POLYLINE if NumDim != 3
00665          );
00666          
00667       //! Constructor from DOUBLE_ARRAY<DPOINT2D>
00668       explicit POLYLINE (
00669          const DOUBLE_ARRAY<DPOINT2D>& rhs,
00670          bool closed = false,                //!< Create and maintain a closed polyline
00671          double ZValue = 0.0                 //!< Initial Z value for POLYLINE if NumDim != 3
00672          );
00673          
00674       //! Constructor from DOUBLE_ARRAY<DPOINT2D>
00675       explicit POLYLINE (
00676          const SIMPLE_ARRAY<LPOINT2D>& rhs,
00677          bool closed = false,                //!< Create and maintain a closed polyline
00678          double ZValue = 0.0                 //!< Initial Z value for POLYLINE if NumDim != 3
00679          );
00680          
00681       //! Constructor from an array of LPOINT2D
00682       explicit POLYLINE (
00683          const LPOINT2D* points,
00684          INT32 NumPoints,
00685          bool closed = false,                //!< Create and maintain a closed polyline
00686          double ZValue = 0.0                 //!< Initial Z value for POLYLINE if NumDim != 3
00687          );
00688          
00689       //! Constructor from DOUBLE_ARRAY<DPOINT3D>
00690       explicit POLYLINE (
00691          const DOUBLE_ARRAY<DPOINT3D>& rhs,
00692          bool closed = false                 //!< Create and maintain a closed polyline
00693          );
00694          
00695       //! Copy constructor
00696       //! Will use any optimizations associated with "rhs"
00697       POLYLINE (
00698          const POLYLINE& rhs
00699          );
00700 
00701       //! Section copy constructor
00702       //! NO optimizations associated with "rhs" will be used
00703       POLYLINE (
00704          const POLYLINE& rhs,                //!< POLYLINE to copy from
00705          INT32 StartVertex,                  //!< Start vertex of 'rhs
00706          INT32 EndVertex                     //!< End vertex of 'rhs' (Inclusive)
00707          );
00708       
00709       //! Destructor    
00710       ~POLYLINE (
00711          );
00712 
00713       //! Assignment
00714       //! Will keep any optimizations associated with "rhs"
00715       //! If POLYLINE::Reserved() was called on 'this' to pre-allocate the point buffer, do not call this method,
00716       //! call POLYLINE::operator+=() or POLYLINE::Append().
00717       POLYLINE& operator= (
00718          const POLYLINE& rhs
00719          );
00720 
00721       //! Append 'rhs' to 'this'
00722       //! If both 'rhs' and 'this' have "Extents" optimization, this method update 'this' Extents optimization
00723       POLYLINE& operator+= (
00724          const POLYLINE& rhs
00725          );
00726 
00727       //! Add a vertex to the line
00728       ERRVALUE AddVertex (
00729          const DPOINT2D& point,              //!< Point to add
00730          INT32 index = -1                    //!< Default location is the end of the line
00731          );
00732 
00733       //! Add a vertex to the line
00734       ERRVALUE AddVertex (
00735          const DPOINT3D& point,              //!< Point to add
00736          INT32 index = -1                    //!< Default location is the end of the line
00737          );
00738          
00739       //! Append a POLYLINE to this one, by default removing duplicates and collinear points at the joined section
00740       //! This method will update the "Extents" optimization for 'this' if both 'this' and 'rhs' have that optimization
00741       ERRVALUE Append (
00742          const POLYLINE& rhs,
00743          bool RemovePoints = true
00744          );
00745          
00746       // Apply a z scale factor to each of the z coordinate values if 'this' has them, otherwise apply it to the z value stored
00747       void ApplyZScale (
00748          double zscale                       //!< Z Scale factor to apply to z coordinate (pt[i].z *= zscale)
00749          );
00750          
00751       //! Assign point values from legacy DPOLYGON structure
00752       ERRVALUE Assign (
00753          const DPOLYGON& dpoly,
00754          bool closed = false,                //!< Create and maintain a closed polyline
00755          DIMENSION dimension = DIMENSION_2D, //!< Create a 2D or 3D line
00756          double ZValue = 0.0                 //!< Initial Z value for POLYLINE if NumDim != 3
00757          );
00758 
00759       //! Assign point values from DPOINT2D array and number of points
00760       ERRVALUE Assign (
00761          const DPOINT2D* pts,
00762          INT32 NumPoints,
00763          bool closed = false,                //!< Create and maintain a closed polyline
00764          DIMENSION dimension = DIMENSION_2D, //!< Create a 2D or 3D line
00765          double ZValue = 0.0                 //!< Initial Z value for POLYLINE if NumDim != 3
00766          );
00767                
00768       //! Assign point values from SIMPLE_ARRAY<LPOINT2D> buffer
00769       ERRVALUE Assign (
00770          const SIMPLE_ARRAY<LPOINT2D>& rhs,
00771          bool closed = false,                //!< Create and maintain a closed polyline
00772          double ZValue = 0.0                 //!< Initial Z value for POLYLINE if NumDim != 3
00773          );
00774 
00775       //! Assign point values from SIMPLE_ARRAY<LPOINT2D> buffer
00776       ERRVALUE Assign (
00777          const LPOINT2D* rhs,
00778          int NumPoints,
00779          bool closed = false,                //!< Create and maintain a closed polyline
00780          double ZValue = 0.0                 //!< Initial Z value for POLYLINE if NumDim != 3
00781          );
00782                
00783       //! Assign point values from DOUBLE_ARRAY<DPOINT2D> buffer
00784       ERRVALUE Assign (
00785          const DOUBLE_ARRAY<DPOINT2D>& rhs,
00786          bool closed = false,                //!< Create and maintain a closed polyline
00787          double ZValue = 0.0                 //!< Initial Z value for POLYLINE if NumDim != 3
00788          );
00789                
00790       //! Assign point values from DOUBLE_ARRAY<DPOINT3D> buffer
00791       ERRVALUE Assign (
00792          const DOUBLE_ARRAY<DPOINT3D>& rhs,
00793          bool closed = false                 //!< Create and maintain a closed polyline
00794          );
00795          
00796       //! Assign point values from a DRECT2D
00797       ERRVALUE Assign (
00798          const DRECT2D& rect,                //!< DRECT2D to crete a line from
00799          double ZValue = 0.0                 //!< Initial Z value for POLYLINE
00800          );
00801          
00802       //! Assign point values from a DRECT3D
00803       ERRVALUE Assign (
00804          const DRECT3D& rect                 //!< DRECT2D to crete a line from
00805          );
00806          
00807       //! Attach a MIDOUBLEARRAY instance to 'this' by taking ownership of the MIDOUBLEARRAY buffer.  After this call, the 
00808       //! MIDOUBLEARRAY buffer is no longer valid
00809       void Attach (
00810          MIDOUBLEARRAY& rhs,
00811          INT32 NumPoints,
00812          bool closed = false,                //!< Create and maintain a closed polyline
00813          DIMENSION dimension = DIMENSION_2D, //!< Create a 2D or 3D line
00814          double ZValue = 0.0                 //!< Initial Z value for POLYLINE if NumDim != 3
00815          );
00816 
00817       //! Return a CONST_ITERATOR that refers to the beginning of the POLYLINE
00818       CONST_ITERATOR Begin (       
00819          ) const {return (CONST_ITERATOR(0, this));}
00820 
00821       //! Return an ITERATOR that refers to the beginning of the POLYLINE
00822       ITERATOR Begin (              
00823          ) {return (ITERATOR(0, this));}
00824 
00825       //! Clear POLYLINE of point data 
00826       void Clear (
00827          );
00828 
00829       //! Clear POLYLINE of all optimizations
00830       void ClearOptimizations (
00831          );
00832 
00833       //! Clear POLYLINE of point data 
00834       void ClearPoints (
00835          INT32 StartPosn = 0,
00836          INT32 EndPosn = INT32_MAX           //!< Inclusive
00837          );
00838          
00839       //! Clip a polyline to a rectangle, call the ClipTarget for each segment
00840       //! Uses the "Extent" optimization
00841       //! @return TRUE if part of the line is inside the clipping area, FALSE if not,  < 0 error
00842       int Clip (
00843          const DRECT2D& ClipRect,
00844          CLIP& ClipTarget,
00845          CLIPMODE ClipMode = CLIPMODE_Inside
00846          );
00847 
00848       //! Compare the two lines and return the result of the comparison.
00849       //! Uses "Extent" and "Section" optimizations
00850       //! @return COMPRESULT depending on the relationship of 'OtherLine' to 'this'
00851       COMPRESULT CompareLineToLine (
00852          const POLYLINE& OtherLine
00853          ) const;
00854 
00855       //! Compare the line against the polygon and return the result of the comparison.
00856       //! Uses "Extent", "Section" and "Strip" optimizations
00857       //! @return COMPRESULT depending on the relationship of 'Polygon' to 'this'
00858       COMPRESULT CompareLineToPolygon (
00859          const POLYLINE& Polygon
00860          ) const;
00861 
00862       //! Compare the line against the polygon and return the result of the comparison.
00863       //! Uses "Extent", "Section" and "Strip" optimizations
00864       //! @return COMPRESULT depending on the relationship of 'Polygon' to 'this'
00865       COMPRESULT CompareLineToPolygon (
00866          const DRECT2D& rect
00867          ) const;
00868 
00869       //! Compare the two polygons and return the result of the comparison.
00870       //! Uses "Extent", "Section" and "Strip" optimizations
00871       //! @return COMPRESULT depending on the relationship of 'OtherPoly' to 'this'
00872       COMPRESULT ComparePolygonToPolygon (
00873          const POLYLINE& OtherPoly
00874          ) const;
00875 
00876       //! Compute the angle for the line using the sum of all the angles in the line
00877       //! @return Angle summation of the angles between segments
00878       double ComputeAngle (
00879          ) const;
00880 
00881       //! Find area of polygon if the line is closed
00882       //! This method assumes that the polygon is topologically correct (i.e. it does not cross itself)
00883       //! @return: Area of the polygon if a polygon, Zero otherwize
00884       double ComputeArea (
00885          ) const {
00886          double area;
00887          ComputeStats(&area, 0);
00888          return (area);
00889          }
00890          
00891       //! Find centroid of polygon if the line is closed
00892       //! This method assumes that the polygon is topologically correct (i.e. it does not cross itself)
00893       void ComputeCentroid (
00894          DPOINT2D& cent
00895          ) const {ComputeStats(0, &cent);}
00896          
00897       //! Compute the shortest distance between the two lines.  If the lines cross, return zero.
00898       //! Uses "Section" optimization
00899       //! @return The shortest distance between the two lines
00900       double ComputeDistance (
00901          const POLYLINE& OtherLine,
00902          bool ExtentsOverlap = true       //!< Set to false if the extents of the two lines DO NOT overlap.  If set to 'false' this method does not need to check for segment intersections
00903          ) const;
00904 
00905       //! Determine a point on the line given a distance from the start or end of the line
00906       //! @return: True if point found on the line, false if not
00907       bool ComputeDistPointOnLine (
00908          double Distance,
00909          DPOINT3D& NewPoint,              //!< Computed point based on distance RETURNED
00910          bool DistanceFromStart = true
00911          ) const;
00912          
00913       //! Determine the extents of the line
00914       //! Uses and / or sets the "Extent" optimization
00915       void ComputeExtents (
00916          DRECT3D& rect
00917          ) const;
00918       
00919       //! Determine the extents of a sub-section of the line
00920       void ComputeExtents (
00921          DRECT3D& rect,
00922          INT32 StartVertex,
00923          INT32 EndVertex            //!< Inclusive
00924          ) const;
00925          
00926       //! Determine the extents of the line
00927       //! Uses and / or sets the "Extent" optimization
00928       void ComputeExtents (
00929          DRECT2D& rect
00930          ) const;
00931       
00932       //! Determine the extents of a sub-section of the line
00933       void ComputeExtents (
00934          DRECT2D& rect,
00935          INT32 StartVertex,
00936          INT32 EndVertex            //!< Inclusive
00937          ) const;
00938       
00939       //! Determine length of the line
00940       //! @return: Length of the line in line units
00941       double ComputeLength (
00942          ) const;
00943          
00944       //! Determine length of the line to the point specified
00945       //! @return: Length of the line in line units to the point specified
00946       double ComputeLength (
00947          const DPOINT3D& point            //!< Compute distance from start of line to point given
00948          ) const;
00949          
00950       //! Determine length of the longest segment of the line
00951       //! @return: Length of the longest segment of the line in line units
00952       double ComputeLongestSegmentLength (
00953          ) const;
00954 
00955       //! Determine maximum length between two vertices on the polygon
00956       //! Uses the "Section" and "Extent" optimizations
00957       //! @return Maximum dimension of the polygon       
00958       double ComputeMaxDimension (
00959          ) const;
00960          
00961       //! Determine line mid-point
00962       void ComputeMidPoint (
00963          DPOINT3D& MidPoint               //!< Computed mid-point RETURNED
00964          ) const;
00965 
00966       //! Compute an offset from the line using a distance and a join type.      
00967       //! Positive buffer distances will result in a buffer to the right of the line
00968       //! assuming Cartesian coordinates (+ right/up, - left/down)
00969       ERRVALUE ComputeOffset (
00970          double OffsetDistance,
00971          POLYLINE& OffsetLine,
00972          JOINTYPE JoinType = JOINTYPE_Miter
00973          ) const;
00974          
00975       //! Compute an offset from the line using a start distance, end distance and a join type.
00976       //! Positive buffer distances will result in a buffer to the right of the line
00977       //! assuming Cartesian coordinates (+ right/up, - left/down)
00978       ERRVALUE ComputeOffset (
00979          double StartOffsetDistance,
00980          double EndOffsetDistance,
00981          POLYLINE& OffsetLine,
00982          JOINTYPE JoinType = JOINTYPE_Miter
00983          ) const;
00984          
00985       //! Compute an offset from the line using a start distance, end distance and a join type.
00986       //! Positive buffer distances will result in a buffer to the right of the line
00987       //! assuming Cartesian coordinates (+ right/up, - left/down)
00988       ERRVALUE ComputeOffset (
00989          const SIMPLE_ARRAY<double>& OffsetDistance,        //!< One entry for each vertex in the line, sign of each distance needs to be the same
00990          POLYLINE& OffsetLine,
00991          JOINTYPE JoinType = JOINTYPE_Miter
00992          ) const;
00993          
00994       //! Find orientation of polygon if the line is closed
00995       //! This method assumes that the polygon is topologically correct (i.e. it does not cross itself)
00996       //! @return: Orientation of the polygon, ORIENTATION_Unknown otherwize
00997       ORIENTATION ComputeOrientation (
00998          ) const {return (ComputeStats(0, 0));}
00999          
01000       //! Determine a point on the line given a percentage from the start or end of the line
01001       void ComputePercentPointOnLine (
01002          double Percent,                  //!< Value between 0.0 and 1.0
01003          DPOINT3D& NewPoint,              //!< Computed point based on distance RETURNED
01004          bool DistanceFromStart = true
01005          ) const;
01006          
01007       //! Compute statistics for the polygon
01008       //! This method assumes that the polygon is topologically correct (i.e. it does not cross itself)
01009       //! @return: Orientation of the polygon, ORIENTATION_Unknown otherwize
01010       ORIENTATION ComputeStats (
01011          double *const area,                 //!< Area value RETURNED, NULL if not needed
01012          DPOINT2D *const centroid            //!< Centroid value RETURNED, NULL if not needed
01013          ) const;
01014          
01015       //! Conflate a set of POLYLINE's with the changed vertex priority assigned to the set.
01016       //! If there is a change to be made to get the lines to match along a set of segments, the 'LineList' will
01017       //! be picked to change its points before 'this' will.
01018       //! Uses the "Section" and "Extent" optimizations
01019       ERRVALUE Conflate (
01020          MILIST<POLYLINE>& LineList,
01021          double thresh,
01022          bool& LineChanged,
01023          BITSET_UNOWNED& LineListSet         //!< Matches the 'LineList' and tells which lines have been changed
01024          );
01025       
01026       //! Convert point coordinates using affine transformation      
01027       void ConvertForward (
01028          const TRANS2D_AFFINE& taf
01029          );
01030       
01031       //! Convert point coordinates using generic transformation     
01032       ERRVALUE ConvertForward (
01033          const TRANS2D_MAPGEN& tmg
01034          );
01035 
01036       //! Convert point coordinates using generic transformation with densification
01037       ERRVALUE ConvertForwardDense (
01038          const TRANS2D_MAPGEN& tmg
01039          );
01040 
01041       //! Convert point coordinates using 3D perspective transformation    
01042       void ConvertForward (
01043          const TRANS3D& t3d
01044          );
01045       
01046       //! Convert point coordinates using generic transformation     
01047       ERRVALUE ConvertForward (
01048          const SPATREF::COORDOP& Op
01049          );
01050 
01051       //! Convert point coordinates using generic transformation with densification
01052       ERRVALUE ConvertForwardDense (
01053          const SPATREF::COORDOP& Op,
01054          double tolerance
01055          );
01056 
01057       //! Convert point coordinates using affine transformation      
01058       void ConvertInverse (
01059          const TRANS2D_AFFINE& taf
01060          );
01061       
01062       //! Convert point coordinates using generic transformation     
01063       ERRVALUE ConvertInverse (
01064          const TRANS2D_MAPGEN& tmg
01065          );
01066 
01067       //! Convert point coordinates using generic transformation with densification
01068       ERRVALUE ConvertInverseDense (
01069          const TRANS2D_MAPGEN& tmg
01070          );
01071 
01072       //! Convert point coordinates using 3D perspective transformation    
01073       void ConvertInverse (
01074          const TRANS3D& t3d
01075          );
01076       
01077       //! Convert point coordinates using generic transformation     
01078       ERRVALUE ConvertReverse (
01079          const SPATREF::COORDOP& Op
01080          );
01081 
01082       //! Convert point coordinates using generic transformation with densification
01083       ERRVALUE ConvertReverseDense (
01084          const SPATREF::COORDOP& Op,
01085          double tolerance
01086          );
01087 
01088       //! Convert polygon from double's to INT32's (no rounding), removes duplicate points
01089       ERRVALUE ConvertToLong (
01090          SIMPLE_ARRAY<LPOINT2D>& LPointList
01091          ) const;
01092 
01093       //! Convert polygon from double's to INT32's (no rounding), removes duplicate points
01094       INT32 ConvertToLong (
01095          LPOINT2D* LPointList
01096          ) const;
01097 
01098       //! Convert polygon from double's to INT32's with rounding, removes duplicate points
01099       ERRVALUE ConvertToLongRound (
01100          SIMPLE_ARRAY<LPOINT2D>& LPointList
01101          ) const;
01102 
01103       //! Convert polygon from double's to INT32's with rounding, removes duplicate points
01104       //!
01105       //! @return Number of points converted into 'LPointList'
01106       INT32 ConvertToLongRound (
01107          LPOINT2D* LPointList
01108          ) const;
01109 
01110       //! Convert polygon from double's to INT32's with rounding, keep duplicate points
01111       ERRVALUE ConvertToLongRoundKeepDups (
01112          SIMPLE_ARRAY<LPOINT2D>& LPointList
01113          ) const;
01114 
01115       //! Delete a line vertex
01116       //! If the line is a closed polygon and removing a vertex causes less than 4 vertices
01117       //! to remain, the line is opened
01118       void DeleteVertex (                 //! Remove a vertex from the line
01119          int index                        //!< Index of vertex to remove
01120          );
01121          
01122       //! Detach the MIDOUBLEARRAY from 'this' to 'rhs'.  'this' does not have control of the buffer after this call
01123       void Detach (
01124          MIDOUBLEARRAY& rhs
01125          );
01126 
01127       //! Detach the MIDOUBLEARRAY from 'this' to 'rhs'.  'this' is not usable until Attach() is called, if you try, your process will die.
01128       void DetachBuffer (
01129          MIDOUBLEARRAY& rhs
01130          );
01131 
01132 
01133       //! Return an ITERATOR that refers to the end of the POLYLINE, not a valid point
01134       ITERATOR End (                
01135          ) {return (ITERATOR(m_NumPoints, this));}
01136 
01137       //! Return a CONST_ITERATOR that refers to the end of the POLYLINE, not a valid point
01138       CONST_ITERATOR End (          
01139          ) const {return (CONST_ITERATOR(m_NumPoints, this));}
01140 
01141       //! Exclusive Union (XOR) operator polygon with 'this'
01142       //! 'this' and 'PolyLineList' must be conflated using POLYLINE::Conflate()
01143       //! "PolyLineList" will contain ORIENTATION_Clockwise for shell polygons and ORIENTATION_CounterClockwise for islands
01144       ERRVALUE ExclusiveUnion (
01145          POLYLINE& OperPoly,
01146          MILIST<POLYLINE>& PolyLineList,        //!< Results of operation returned here
01147          COMBINERESULT& CombineResult
01148          );
01149          
01150       //! Extract a portion of the line into a new line based on a basepoint and distance from that basepoint
01151       void Extract (
01152          POLYLINE& NewLine,                  //!< Result of extraction
01153          const DPOINT3D& BasePoint,          //!< Point to extract from based on "ExtractPoint"
01154          double Distance,
01155          EXTRACT ExtractPoint,
01156          bool ExtrudePastEnds = false
01157          ) const;
01158          
01159       //! Extract a portion of the line into a new line based on two point on the line
01160       void Extract (
01161          POLYLINE& NewLine,                  //!< Result of extraction
01162          const DPOINT3D& StartPoint,         //!< Point to start extraction from
01163          const DPOINT3D& EndPoint            //!< Point to end extraction from
01164          ) const;
01165          
01166       //! Extract a portion of the line into a new line based on position and number of points
01167       void Extract (
01168          INT32 StartPosn,
01169          INT32 NumPoints,
01170          POLYLINE& ExtractLine
01171          ) const;
01172       
01173       //! Find closest point on the line (not necessarily at a vertex) to specified point.
01174       //! @return: Distance to closest point on the line, not necessarily a vertex point
01175       double FindClosestPoint (
01176          const DPOINT2D& point,              //!< Point to check
01177          DPOINT2D& retpt                     //!< Point on line found RETURNED
01178          ) const;
01179       
01180       //! Find closest point on the line (not necessarily at a vertex) to specified point.
01181       //! This method uses linear interpolation to determine the correct z value.
01182       //! @return: Distance to closest point on the line, not necessarily a vertex point
01183       double FindClosestPoint (
01184          const DPOINT3D& point,              //!< Point to check
01185          DPOINT3D& retpt                     //!< Point on line found RETURNED
01186          ) const;
01187 
01188       //! Find closest point on the line (not necessarily at a vertex) to specified point.
01189       //! This method uses linear interpolation to determine the correct z value.
01190       //! This method is faster than the above 'FindClosestPoint' methods because it will 
01191       //!   make less calls to DistPointLineSegD().
01192       //! @return: Distance to closest point on the line, may not be smaller than 'MaxmimumDistance'
01193       double FindClosestPoint (
01194          const DPOINT3D& point,              //!< Point to check
01195          double MaximumDistance,             //!< Maximum distance allowed between point on the line and 'point'
01196          DPOINT3D& retpt,                    //!< Point on line found RETURNED
01197          INT32& Vertex                       //!< Index of vertex BEFORE the location of the point RETURNED
01198          ) const;
01199 
01200       //! Find closest segment to specified point.
01201       //! @return Index of first vertex of segment, may be last polyline vertex if closed.
01202       int FindClosestSegment (
01203          const DPOINT2D& point,              //!< Point to check
01204          double *distance = 0                //!< Distance returned, 0 if don't need
01205          ) const;
01206          
01207       //! Find closest vertex to specified 2D point.
01208       //! @return: Distance to closest vertex on the line.
01209       double FindClosestVertex (
01210          const DPOINT2D& point,              //!< Point to check
01211          INT32& index                        //!< Index of closest vertex returned
01212          ) const;
01213       
01214       //! Find closest vertex to specified 2D point.
01215       //! @return: Index of closest vertex.
01216       int FindClosestVertex (
01217          const DPOINT2D& point,              //!< Point to check
01218          double *distance = 0                //!< Distance returned, 0 if don't need
01219          ) const;
01220       
01221       //! Find closest vertex to specified 3D point.
01222       //! This method uses linear interpolation to determine the Z value.
01223       //! @return: Distance to closest vertex on the line
01224       double FindClosestVertex (
01225          const DPOINT3D& point,              //!< Point to check
01226          INT32& index                        //!< Index of closest vertex returned
01227          ) const;
01228 
01229       //! Generate the "Extent" optimization.
01230       //! Used mostly for Compare...() methods and to setup the "Strip" optimization
01231       void GenerateExtentOptimization (
01232          DRECT2D& Extents
01233          ) const;
01234 
01235       //! Generate the "Extent" optimization.
01236       //! Used mostly for Compare...() methods and to setup the "Strip" optimization
01237       void GenerateExtentOptimization (
01238          ) const;
01239 
01240       //! Generate the "Section" optimization.
01241       //! Used for many methods.  A "Section" is defined as piece of the source line (defined by "NumVertices")
01242       //! and that sections extents.
01243       ERRVALUE GenerateSectionOptimization (
01244          SECTIONS*& Sections,                         //!< Section information RETURNED, you must free pointer
01245          INT32 NumVertices = 64
01246          ) const;
01247 
01248       //! Generate the "Section" optimization.
01249       //! Used for many methods.  A "Section" is defined as piece of the source line (defined by "NumVertices")
01250       //! and that sections extents.  
01251       void GenerateSectionOptimization (
01252          INT32 NumVertices = 64
01253          ) const;
01254 
01255       //! Generate the "Strip" optimization.
01256       //! Used for IsPointInside() method.  A "Strip" is defined as a list of segments that fall within a range of y values.
01257       ERRVALUE GenerateStripOptimization (
01258          STRIPS*& Strips,                             //!< Strip information RETURNED, you must free pointer
01259          INT32 NumDivs = 0
01260          ) const;
01261 
01262       //! Generate the "Strip" optimization.
01263       //! Used for IsPointInside() method.  A "Strip" is defined as a list of segments that fall within a range of y values.
01264       ERRVALUE GenerateStripOptimization (
01265          INT32 NumDivs = 0
01266          ) const;
01267 
01268       //! Get current line dimension
01269       DIMENSION GetDimension (
01270          ) const {return ((m_NumDim == 2) ? DIMENSION_2D : DIMENSION_3D);}
01271 
01272       //! Get the extents of the POLYLINE if it exists, this method will NOT compute the extents
01273       //! @return 'True' if the extent optimization is valid, 'false' if not
01274       bool GetExtentsOptimization (
01275          DRECT2D& Extents
01276          ) const;
01277 
01278       //! Get the number of points in the line
01279       //! @return: Number of points in the line
01280       INT32 GetNumPoints (
01281          ) const {return (m_NumPoints);}
01282 
01283       #ifndef GENERATING_DOXYGEN_OUTPUT
01284       double* GetPointer (
01285          int index = 0
01286          ) {return (m_Points + GetOffset(index));}
01287          
01288       const double* GetPointer (
01289          int index = 0
01290          ) const {return (m_Points + GetOffset(index));}
01291       #endif //!< GENERATING_DOXYGEN_OUTPUT
01292       
01293       //! Get Test Point
01294       //! Obtains valid test point for the line, either the middle vertex or. 
01295       //! if a two point line, the midpoint
01296       void GetTestPoint (
01297          DPOINT3D& pt
01298          ) const;
01299          
01300       //! Get 2D vertex.
01301       //! @return: Constant reference to a 2D point
01302       const DPOINT2D& GetVertex (
01303          INT32 index
01304          ) const { return (*reinterpret_cast<const DPOINT2D*>(GetPointer(index))); }
01305 
01306       //! Get a 3D point 
01307       void GetVertex3D (
01308          INT32 index,
01309          DPOINT3D& pt
01310          ) const {
01311          const double *p = GetPointer(index);
01312          pt.x = p[0];
01313          pt.y = p[1];
01314          pt.z = (m_NumDim == 2) ? m_ZValue : p[2];
01315          return;
01316          }
01317 
01318       //! Get 'Z' coordinate of a vertex
01319       //! @return: 'Z' coordinate
01320       double GetVertexZ (
01321          INT32 index
01322          ) const { 
01323          if (m_NumDim == 2) return (m_ZValue);
01324          const double *p = GetPointer(index);
01325          return (p[2]);
01326          }
01327 
01328       //! Get vertices into DOUBLE_ARRAY<DPOINT2D> array.
01329       ERRVALUE GetVertices (
01330          DOUBLE_ARRAY<DPOINT2D>& vertices       //!< Vertices returned
01331          ) const;
01332          
01333       //! Get vertices into DOUBLE_ARRAY<DPOINT3D> array.
01334       ERRVALUE GetVertices (
01335          DOUBLE_ARRAY<DPOINT3D>& vertices       //!< Vertices returned
01336          ) const;
01337          
01338       //! Get vertices into DPOLYGON
01339       ERRVALUE GetVertices (
01340          DPOLYGON& dpoly
01341          ) const;
01342          
01343       //! Get polyline Z value, only useful for 2D lines
01344       double GetZValue (
01345          ) const {return (m_ZValue);}
01346 
01347       //! Does 'this' have strip optimization
01348       bool HasSectionOptimization (
01349          ) const;
01350 
01351       //! Does 'this' have strip optimization
01352       bool HasStripOptimization (
01353          ) const;
01354 
01355       //! Intersect operator polygon with 'this'
01356       //! "PolyLineList" will contain ORIENTATION_Clockwise for shell polygons and ORIENTATION_CounterClockwise for islands
01357       //! 'this' and 'PolyLineList' must be conflated using POLYLINE::Conflate()
01358       //! @return '1' if "PolylineList" has one entry and is the same as 'this', 0 for all other cases, < 0 error
01359       int Intersect (
01360          POLYLINE& OperPoly,
01361          MILIST<POLYLINE>& PolyLineList,        //!< Results of operation returned here
01362          COMBINERESULT& CombineResult
01363          );
01364          
01365       //! Remove redundant and overlapping intersection entries from INTERSECTINFO.    
01366       void IntersectClean (
01367          INTERSECTINFO& IntsInfo
01368          ) const;
01369          
01370       //! Search for intersections against itself.  Intersection information is stored in the INTERSECTINFO
01371       //! Uses the "Section" and "Extent" optimizations
01372       ERRVALUE IntersectSearch (
01373          INTERSECTINFO& IntsInfo,
01374          double threshold
01375          ) const;
01376          
01377       //! Search for intersections against another line.  Intersection information is stored in the INTERSECTINFO instance.  
01378       //! If information already exists in the INTERSECTINFO, any new intersection information will be appended.
01379       //! Uses the "Section" and "Extent" optimizations
01380       ERRVALUE IntersectSearch (
01381          INTERSECTINFO& IntsInfo,
01382          const POLYLINE& OtherLine,
01383          INTERSECTINFO* OtherIntsInfo,                //!< Optional, used if you want to keep intersection info about "OtherLine'
01384          double threshold
01385          ) const;
01386          
01387       //! Split the line according to the INTERSECTINFO information.
01388       ERRVALUE IntersectSplitLine (
01389          INTERSECTINFO& IntsInfo,
01390          SPLIT& SplitInfo,                            //!< Callback base class for line splitting
01391          double threshold,
01392          bool CallBadSegment = false                  //!< Set to true if an intersection causes invalid lines to be generated
01393          ) const;
01394          
01395       //! Check if the line is marked closed
01396       //! @return: True if the line is marked closed
01397       bool IsClosed (
01398          ) const {return (m_LineClosed);}
01399 
01400       //! Determine if the two lines are exactly equal 
01401       //! This method uses "Exact" point comparisons
01402       //! @return 'True' if they are, 'False' if not
01403       bool IsEqual (
01404          const POLYLINE& rhs
01405          ) const;
01406 
01407       //! Determine if the two lines are equivalent 
01408       //! This method uses "Fuzzy" point comparisons and the direction of the lines are not relevant
01409       //! @return 'True' if they are, 'False' if not
01410       bool IsEquivalentTo (
01411          const POLYLINE& rhs,
01412          double threshold = 0.0
01413          ) const;
01414 
01415       //! Check if the point is inside the polygon
01416       //! Uses the "Strip" optimization if exists
01417       //! @return: True if the point is in, False if not or the line is not closed
01418       bool IsPointInside (
01419          const DPOINT2D& pt                  //!< Point to check
01420          ) const;
01421 
01422       //! Returns true if the POLYLINE describes a simple, unrotated rectangle
01423       bool IsRectangle (
01424          ) const;
01425       
01426       //! Move a vertex by some dx,dy
01427       //! If FixedVertex1 and/or FixedVertex2 are specified, all points
01428       //! between the vertex being moved and the fixed verticies will also
01429       //! be moved by an ammount inversely proportional to their distance
01430       //! from the vertex being moved.
01431       //! If you specify two fixed verticies, one had better be less than
01432       //! index and one greater than index or you will get weird results.
01433       //! Also, specifying a FixedVertex which is just index +/- 1 is the
01434       //! same as not specifying it.
01435       void MoveVertex (
01436          int index,              //!< Vertex to move
01437          const DPOINT2D& delta,  //!< Move distance
01438          int FixedVertex1 = -1,  //!< Vertex to keep in place
01439          int FixedVertex2 = -1   //!< Vertex to keep in place
01440          );
01441 
01442       //! Remove duplicate and colinear points along the line
01443       void RemoveDuplicates (
01444          double thresh = 0.0,                //!< Threshold value to test for same point or colinear point
01445          bool KeepEndPoints = false
01446          );
01447 
01448       //! Reserve space for given number of points    
01449       //! The POLYLINE::operator=() will not use the reserved buffer, 
01450       //! call POLYLINE::Clear() then POLYLINE::operator+=() or POLYLINE::Append() to use the reserved buffer.
01451       ERRVALUE Reserve (
01452          INT32 NumPoints
01453          );
01454          
01455       //! Reverse the vertices of the line
01456       //! This method will retain the "Extents" and "Orientation" optimizations
01457       void Reverse (
01458          );
01459 
01460       //! Close or open the line
01461       //! Will add closure point if set to 'true'
01462       void SetClosed (
01463          bool closed
01464          );
01465          
01466       //! Set line dimension from 2D->3D or 3D->2D          
01467       ERRVALUE SetDimension (
01468          DIMENSION dimension
01469          );
01470          
01471       //! Set polygon orientation
01472       //! Uses the "Orientation" optimization
01473       void SetOrientation (
01474          ORIENTATION Orientation
01475          );
01476 
01477       //! Set the precision of the coordinates in the POLYLINE
01478       //! 'Precision' is the number of decimal places to keep, '0' for precision of whole numbers, < '0' for the left of the decimal point,
01479       //! > '0' for right of the decimal point
01480       void SetPrecision (
01481          int Precision
01482          );
01483          
01484       //! Setup the "Extent" optimization.
01485       //! Used mostly for Compare...() methods and to setup the "Strip" optimization
01486       void SetupExtentOptimization (
01487          const DRECT2D& Extents
01488          ) const;
01489 
01490