coordop.h

Go to the documentation of this file.
00001 /**
00002  * \file coordop.h <mi32/coordop.h>
00003  * \brief Coordinate Operation (COORDOP) class definitions
00004  *
00005  * \if NODOC
00006  * $Id: coordop.h_v 1.9 2006/02/20 21:15:26 mju Exp $
00007  *
00008  * $Log: coordop.h_v $
00009  * Revision 1.9  2006/02/20 21:15:26  mju
00010  * Make impl_list friend of impl.
00011  *
00012  * Revision 1.8  2006/02/17 18:42:38  mju
00013  * Add parm to disable range checking.
00014  *
00015  * Revision 1.7  2005/04/12 17:35:32  mju
00016  * Add op_single.ReleaseAttached.
00017  *
00018  * Revision 1.6  2004/08/09 17:16:23  mju
00019  * Fix unix warning.
00020  *
00021  * Revision 1.5  2004/07/12 16:58:03  mju
00022  * Forgot to export coordop_zoned from dll.
00023  *
00024  * Revision 1.4  2004/07/12 15:59:14  mju
00025  * Add zoned conversion from string.
00026  *
00027  * Revision 1.3  2004/07/12 15:18:48  mju
00028  * Change op_str to op_zoned.
00029  *
00030  * Revision 1.1  2004/06/17 17:42:38  mju
00031  * Initial revision
00032  *
00033  * \endif
00034 **/
00035 
00036 #ifndef  INC_MI32_COORDOP_H
00037 #define  INC_MI32_COORDOP_H
00038 
00039 #ifndef  INC_MI32_MILIST_H
00040 #include <mi32/milist.h>
00041 #endif
00042 
00043 #ifndef  INC_MI32_POINT_H
00044 #include <mi32/point.h>
00045 #endif
00046 
00047 #ifndef  INC_MI32_SPATREF_H
00048 #include <mi32/spatref.h>
00049 #endif
00050 
00051 #ifdef GEOMDLL
00052    #define CLASSLIBEXPORT MI_DLLCLASSEXPORT
00053 #else
00054    #define CLASSLIBEXPORT MI_DLLCLASSIMPORT
00055 #endif
00056 
00057 // Forward declarations.
00058 #ifndef GENERATING_DOXYGEN_OUTPUT
00059 class REGION2D;
00060 struct CTRLPOINT;
00061 struct CTRLPOINT3;
00062 namespace SPATREF {
00063    class COORDOP;
00064    class COORDOP_SINGLE;
00065    class COORDOP_LIST;
00066    class COORDOP_IMPL_LINEAR;
00067    class COORDOP_IMPL_LIST;
00068    }
00069 #endif
00070 
00071 
00072 namespace SPATREF {
00073 
00074 enum COORDOP_DIRECTION {
00075    COORDOP_DIRECTION_Reverse = -1,
00076    COORDOP_DIRECTION_Forward = 1
00077    };
00078 
00079 //=====================================================================================================================
00080 //! Target for densification operations.
00081 
00082 class CLASSLIBEXPORT COORDOP_TARGET {
00083    public:
00084 
00085       //! Called before first input vertex processed.
00086       ERRVALUE OnBegin (
00087          ) { return (v_OnBegin()); }
00088 
00089       //! Called after last input vertex processed.
00090       ERRVALUE OnEnd (
00091          ) { return (v_OnEnd()); }
00092 
00093       //! Called for each dense point generated.
00094       ERRVALUE OnPoint (
00095          const double* pPoint,      //!< Pointer to point of output dimension
00096          INT32 InVertexNum,         //!< Vertex number in input array associated with point
00097          INT32 SubVertexNum         //!< Sub-vertex number, 0 if at input vertex
00098          ) { return (v_OnPoint(pPoint,InVertexNum,SubVertexNum)); }
00099 
00100    private:
00101       // Overridables.
00102 
00103       //! Called before first input vertex processed.
00104       virtual ERRVALUE v_OnBegin (
00105          );
00106 
00107       //! Called after last input vertex processed.
00108       virtual ERRVALUE v_OnEnd (
00109          );
00110 
00111       //! Called for each dense point generated.
00112       virtual ERRVALUE v_OnPoint (
00113          const double* pPoint,      //!< Pointer to point of output dimension
00114          INT32 InVertexNum,         //!< Vertex number in input array associated with point
00115          INT32 SubVertexNum         //!< Sub-vertex number within densified 'segment', 0 if at input vertex
00116          ) = 0;
00117    };
00118 
00119 //=====================================================================================================================
00120 
00121 //! Base for coordinate operation implementation.
00122 class CLASSLIBEXPORT COORDOP_IMPL {
00123    public:
00124 
00125       class CLASSLIBEXPORT LINEAR {
00126          public:
00127 
00128             //! Default constructor.
00129             LINEAR () { SetIdentity(); }
00130 
00131             //! Copy constructor.
00132             LINEAR (const LINEAR&);
00133 
00134             //! Combination constructor.
00135             LINEAR (const LINEAR& lhs, const LINEAR& rhs);
00136 
00137             //! Destructor.
00138             ~LINEAR () { }
00139 
00140             //! Assignment.
00141             LINEAR& operator= (const LINEAR&);
00142 
00143             //! Apply scale to axes.
00144             void ApplyScale (
00145                double scaleX,
00146                double scaleY,
00147                double scaleZ = 1,
00148                bool reverse = false             //!< Specified values apply to reverse direction
00149                );
00150 
00151             //! Apply scale to X/Y axes using DPOINT2D.
00152             void ApplyScale (
00153                const DPOINT2D& scale,
00154                bool reverse = false             //!< Specified values apply to reverse direction
00155                ) { ApplyScale(scale.x,scale.y,1.0,reverse); }
00156 
00157             //! Apply scale to axes using DPOINT3D.
00158             void ApplyScale (
00159                const DPOINT3D& scale,
00160                bool reverse = false             //!< Specified values apply to reverse direction
00161                ) { ApplyScale(scale.x,scale.y,scale.z,reverse); }
00162 
00163             //! Apply translation to origin.
00164             void ApplyTranslation (
00165                double transX,
00166                double transY,
00167                double transZ = 0,
00168                bool reverse = false             //!< Specified values apply to reverse direction
00169                );
00170 
00171             //! Apply translation to origin X/Y using DPOINT2D.
00172             void ApplyTranslation (
00173                const DPOINT2D& trans,
00174                bool reverse = false             //!< Specified values apply to reverse direction
00175                ) { ApplyTranslation(trans.x,trans.y,0,reverse); }
00176 
00177             //! Apply translation to origin using DPOINT3D..
00178             void ApplyTranslation (
00179                const DPOINT3D& trans,
00180                bool reverse = false             //!< Specified values apply to reverse direction
00181                ) { ApplyTranslation(trans.x,trans.y,trans.z,reverse); }
00182 
00183             //! Compute (2D) linear transformation using CTRLPOINT array.
00184             ERRVALUE Compute (
00185                const CTRLPOINT *CtrlPoints,
00186                int NumPoints
00187                );
00188 
00189             //! Compute linear transformation using CTRLPOINT3 array.
00190             ERRVALUE Compute (
00191                const CTRLPOINT3 *CtrlPoints,
00192                int NumPoints
00193                );
00194 
00195             //! Perform forward operation on DPOINT2D.
00196             //! Note, the output point must not be the same as the input point.
00197             void ConvertForward (
00198                const DPOINT2D& ipoint,          //!< Input point
00199                DPOINT2D& opoint                 //!< Output point
00200                ) const {
00201                opoint.x = m_Fwd[0][0] * ipoint.x + m_Fwd[0][1] * ipoint.y + m_Fwd[0][3];
00202                opoint.y = m_Fwd[1][0] * ipoint.x + m_Fwd[1][1] * ipoint.y + m_Fwd[1][3];
00203                }
00204 
00205             //! Perform forward operation on DPOINT2D.
00206             //! @return Converted point.
00207             DPOINT2D ConvertForward (
00208                const DPOINT2D& ipoint           //!< Input point
00209                ) const {
00210                return (DPOINT2D(
00211                   (m_Fwd[0][0] * ipoint.x + m_Fwd[0][1] * ipoint.y + m_Fwd[0][3]),
00212                   (m_Fwd[1][0] * ipoint.x + m_Fwd[1][1] * ipoint.y + m_Fwd[1][3])
00213                   ));
00214                }
00215 
00216             //! Perform forward operation on DPOINT3D.
00217             //! Note, the output point must not be the same as the input point.
00218             void ConvertForward (
00219                const DPOINT3D& ipoint,          //!< Input point
00220                DPOINT3D& opoint                 //!< Output point
00221                ) const {
00222                opoint.x = m_Fwd[0][0] * ipoint.x + m_Fwd[0][1] * ipoint.y + m_Fwd[0][2] * ipoint.z + m_Fwd[0][3];
00223                opoint.y = m_Fwd[1][0] * ipoint.x + m_Fwd[1][1] * ipoint.y + m_Fwd[1][2] * ipoint.z + m_Fwd[1][3];
00224                opoint.z = m_Fwd[2][0] * ipoint.x + m_Fwd[2][1] * ipoint.y + m_Fwd[2][2] * ipoint.z + m_Fwd[2][3];
00225                }
00226 
00227             //! Perform forward operation on DPOINT3D.
00228             //! @return Converted point.
00229             DPOINT3D ConvertForward (
00230                const DPOINT3D& ipoint           //!< Input point
00231                ) const {
00232                return (DPOINT3D(
00233                   (m_Fwd[0][0] * ipoint.x + m_Fwd[0][1] * ipoint.y + m_Fwd[0][2] * ipoint.z + m_Fwd[0][3]),
00234                   (m_Fwd[1][0] * ipoint.x + m_Fwd[1][1] * ipoint.y + m_Fwd[1][2] * ipoint.z + m_Fwd[1][3]),
00235                   (m_Fwd[2][0] * ipoint.x + m_Fwd[2][1] * ipoint.y + m_Fwd[2][2] * ipoint.z + m_Fwd[2][3])
00236                   ));
00237                }
00238 
00239             //! Perform forward operation on DPOINT3DH.
00240             //! Note, the output point must not be the same as the input point.
00241             void ConvertForward (
00242                const DPOINT3DH& ipoint,            //!< Input point
00243                DPOINT3DH& opoint                //!< Output point
00244                ) const {
00245                opoint.x = m_Fwd[0][0] * ipoint.x + m_Fwd[0][1] * ipoint.y + m_Fwd[0][2] * ipoint.z + m_Fwd[0][3] * ipoint.w;
00246                opoint.y = m_Fwd[1][0] * ipoint.x + m_Fwd[1][1] * ipoint.y + m_Fwd[1][2] * ipoint.z + m_Fwd[1][3] * ipoint.w;
00247                opoint.z = m_Fwd[2][0] * ipoint.x + m_Fwd[2][1] * ipoint.y + m_Fwd[2][2] * ipoint.z + m_Fwd[2][3] * ipoint.w;
00248                opoint.w = m_Fwd[3][0] * ipoint.x + m_Fwd[3][1] * ipoint.y + m_Fwd[3][2] * ipoint.z + m_Fwd[3][3] * ipoint.w;
00249                }
00250 
00251             //! Perform forward operation on DPOINT3DH.
00252             //! @return Converted point.
00253             DPOINT3DH ConvertForward (
00254                const DPOINT3DH& ipoint          //!< Input point
00255                ) const {
00256                return (DPOINT3DH(
00257                   (m_Fwd[0][0] * ipoint.x + m_Fwd[0][1] * ipoint.y + m_Fwd[0][2] * ipoint.z + m_Fwd[0][3] * ipoint.w),
00258                   (m_Fwd[1][0] * ipoint.x + m_Fwd[1][1] * ipoint.y + m_Fwd[1][2] * ipoint.z + m_Fwd[1][3] * ipoint.w),
00259                   (m_Fwd[2][0] * ipoint.x + m_Fwd[2][1] * ipoint.y + m_Fwd[2][2] * ipoint.z + m_Fwd[2][3] * ipoint.w),
00260                   (m_Fwd[3][0] * ipoint.x + m_Fwd[3][1] * ipoint.y + m_Fwd[3][2] * ipoint.z + m_Fwd[3][3] * ipoint.w)
00261                   ));
00262                }
00263 
00264             //! Perform reverse operation on DPOINT2D.
00265             //! Note, the output point must not be the same as the input point.
00266             void ConvertReverse (
00267                const DPOINT2D& ipoint,          //!< Input point
00268                DPOINT2D& opoint                 //!< Output point
00269                ) const {
00270                opoint.x = m_Rev[0][0] * ipoint.x + m_Rev[0][1] * ipoint.y + m_Rev[0][3];
00271                opoint.y = m_Rev[1][0] * ipoint.x + m_Rev[1][1] * ipoint.y + m_Rev[1][3];
00272                }
00273 
00274             //! Perform reverse operation on DPOINT2D.
00275             //! @return Converted point.
00276             DPOINT2D ConvertReverse (
00277                const DPOINT2D& ipoint           //!< Input point
00278                ) const {
00279                return (DPOINT2D(
00280                   (m_Rev[0][0] * ipoint.x + m_Rev[0][1] * ipoint.y + m_Rev[0][3]),
00281                   (m_Rev[1][0] * ipoint.x + m_Rev[1][1] * ipoint.y + m_Rev[1][3])
00282                   ));
00283                }
00284 
00285             //! Perform reverse operation on DPOINT3D.
00286             //! Note, the output point must not be the same as the input point.
00287             void ConvertReverse (
00288                const DPOINT3D& ipoint,          //!< Input point
00289                DPOINT3D& opoint                 //!< Output point
00290                ) const {
00291                opoint.x = m_Rev[0][0] * ipoint.x + m_Rev[0][1] * ipoint.y + m_Rev[0][2] * ipoint.z + m_Rev[0][3];
00292                opoint.y = m_Rev[1][0] * ipoint.x + m_Rev[1][1] * ipoint.y + m_Rev[1][2] * ipoint.z + m_Rev[1][3];
00293                opoint.z = m_Rev[2][0] * ipoint.x + m_Rev[2][1] * ipoint.y + m_Rev[2][2] * ipoint.z + m_Rev[2][3];
00294                }
00295 
00296             //! Perform reverse operation on DPOINT3D.
00297             //! @return Converted point.
00298             DPOINT3D ConvertReverse (
00299                const DPOINT3D& ipoint           //!< Input point
00300                ) const {
00301                return (DPOINT3D(
00302                   (m_Rev[0][0] * ipoint.x + m_Rev[0][1] * ipoint.y + m_Rev[0][2] * ipoint.z + m_Rev[0][3]),
00303                   (m_Rev[1][0] * ipoint.x + m_Rev[1][1] * ipoint.y + m_Rev[1][2] * ipoint.z + m_Rev[1][3]),
00304                   (m_Rev[2][0] * ipoint.x + m_Rev[2][1] * ipoint.y + m_Rev[2][2] * ipoint.z + m_Rev[2][3])
00305                   ));
00306                }
00307 
00308             //! Perform reverse operation on DPOINT3DH.
00309             //! Note, the output point must not be the same as the input point.
00310             void ConvertReverse (
00311                const DPOINT3DH& ipoint,            //!< Input point
00312                DPOINT3DH& opoint                //!< Output point
00313                ) const {
00314                opoint.x = m_Rev[0][0] * ipoint.x + m_Rev[0][1] * ipoint.y + m_Rev[0][2] * ipoint.z + m_Rev[0][3] * ipoint.w;
00315                opoint.y = m_Rev[1][0] * ipoint.x + m_Rev[1][1] * ipoint.y + m_Rev[1][2] * ipoint.z + m_Rev[1][3] * ipoint.w;
00316                opoint.z = m_Rev[2][0] * ipoint.x + m_Rev[2][1] * ipoint.y + m_Rev[2][2] * ipoint.z + m_Rev[2][3] * ipoint.w;
00317                opoint.w = m_Rev[3][0] * ipoint.x + m_Rev[3][1] * ipoint.y + m_Rev[3][2] * ipoint.z + m_Rev[3][3] * ipoint.w;
00318                }
00319 
00320             //! Perform reverse operation on DPOINT3DH.
00321             //! @return Converted point.
00322             DPOINT3DH ConvertReverse (
00323                const DPOINT3DH& ipoint          //!< Input point
00324                ) const {
00325                return (DPOINT3DH(
00326                   (m_Rev[0][0] * ipoint.x + m_Rev[0][1] * ipoint.y + m_Rev[0][2] * ipoint.z + m_Rev[0][3] * ipoint.w),
00327                   (m_Rev[1][0] * ipoint.x + m_Rev[1][1] * ipoint.y + m_Rev[1][2] * ipoint.z + m_Rev[1][3] * ipoint.w),
00328                   (m_Rev[2][0] * ipoint.x + m_Rev[2][1] * ipoint.y + m_Rev[2][2] * ipoint.z + m_Rev[2][3] * ipoint.w),
00329                   (m_Rev[3][0] * ipoint.x + m_Rev[3][1] * ipoint.y + m_Rev[3][2] * ipoint.z + m_Rev[3][3] * ipoint.w)
00330                   ));
00331                }
00332 
00333             //! Reverse direction of operation.
00334             void Reverse (
00335                );
00336 
00337             //! Set to identity operation.
00338             void SetIdentity (
00339                );
00340 
00341          private:
00342             #ifndef GENERATING_DOXYGEN_OUTPUT
00343             void ApplyMatrix(const MAT4X4 mat, bool reverse);
00344             MAT4X4 m_Fwd;
00345             MAT4X4 m_Rev;
00346             #endif
00347          };
00348 
00349       //! Destructor.
00350       virtual ~COORDOP_IMPL (
00351          );
00352 
00353       // Increment reference count.
00354       void AddRef (
00355          ) { ++m_RefCount; }
00356 
00357       //! Compute approximated linear transformation if within specified tolerance.
00358       //! Regardless of direction specified, any returned LINEAR operation will have the same direction
00359       //! as the operation instance itself.
00360       //! @return TRUE if approximation valid, FALSE if not, < 0 if error
00361       int ComputeLinearApproximation (
00362          COORDOP_DIRECTION direction,        //!< Direction in which to perform approximation
00363          const REGION2D& region,             //!< Region in 'input' CRS based on specified direction
00364          double tolerance,                   //!< Tolerance in 'output' CRS based on specified direction
00365          LINEAR& Linear                      //!< Linear approximation returned if available
00366          ) const;
00367 
00368       //! Perform forward operation on DPOINT2D array.
00369       ERRVALUE ConvertForward (
00370          const DPOINT2D* ipoints,            //!< Input point array
00371          DPOINT2D* opoints,                  //!< Output point array
00372          INT32 NumPoints                     //!< Number of points to convert
00373          ) const {
00374             if (IsLinear()) {
00375                for (INT32 p = 0; (p < NumPoints); ++p)
00376                   *opoints++ = m_Linear.ConvertForward(*ipoints++);
00377                return (0);
00378                }
00379             else return (v_ConvertForward(ipoints,opoints,NumPoints));
00380             }
00381 
00382       //! Perform forward operation on DPOINT3D array.
00383       ERRVALUE ConvertForward (
00384          const DPOINT3D* ipoints,         //!< Input point array
00385          DPOINT3D* opoints,               //!< Output point array
00386          INT32 NumPoints                  //!< Number of points to convert
00387          ) const {
00388             if (IsLinear()) {
00389                for (INT32 p = 0; (p < NumPoints); ++p)
00390                   *opoints++ = m_Linear.ConvertForward(*ipoints++);
00391                return (0);
00392                }
00393             else return (v_ConvertForward(ipoints,opoints,NumPoints));
00394             }
00395 
00396       //! Perform forward operation on DPOINT3DH array.
00397       ERRVALUE ConvertForward (
00398          const DPOINT3DH* ipoints,        //!< Input point array
00399          DPOINT3DH* opoints,              //!< Output point array
00400          INT32 NumPoints                  //!< Number of points to convert
00401          ) const {
00402             if (IsLinear()) {
00403                for (INT32 p = 0; (p < NumPoints); ++p)
00404                   *opoints++ = m_Linear.ConvertForward(*ipoints++);
00405                return (0);
00406                }
00407             else return (v_ConvertForward(ipoints,opoints,NumPoints));
00408             }
00409 
00410       //! Perform forward operation with possible densification.
00411       ERRVALUE ConvertForwardDense (
00412          INT32 NumPoints,                 //!< Number of points
00413          int NumDim,                      //!< Number of dimensions (usually 2, 3 or 4 (indicates homogeneous))
00414          const double *ipoint,            //!< Input point array of specified dimension
00415          double tolerance,                //!< Densification tolerance in target coordinates
00416          COORDOP_TARGET& target           //!< Target for converted points
00417          ) const;
00418 
00419       //! Perform reverse operation on DPOINT2D array.
00420       ERRVALUE ConvertReverse (
00421          const DPOINT2D* ipoints,         //!< Input point array
00422          DPOINT2D* opoints,               //!< Output point array
00423          INT32 NumPoints                  //!< Number of points to convert
00424          ) const {
00425             if (IsLinear()) {
00426                for (INT32 p = 0; (p < NumPoints); ++p)
00427                   *opoints++ = m_Linear.ConvertReverse(*ipoints++);
00428                return (0);
00429                }
00430             else return (v_ConvertReverse(ipoints,opoints,NumPoints));
00431             }
00432 
00433       //! Perform reverse operation on DPOINT3D array.
00434       ERRVALUE ConvertReverse (
00435          const DPOINT3D* ipoints,         //!< Input point array
00436          DPOINT3D* opoints,               //!< Output point array
00437          INT32 NumPoints                  //!< Number of points to convert
00438          ) const {
00439             if (IsLinear()) {
00440                for (INT32 p = 0; (p < NumPoints); ++p)
00441                   *opoints++ = m_Linear.ConvertReverse(*ipoints++);
00442                return (0);
00443                }
00444             else return (v_ConvertReverse(ipoints,opoints,NumPoints));
00445             }
00446 
00447       //! Perform reverse operation on DPOINT3DH array.
00448       ERRVALUE ConvertReverse (
00449          const DPOINT3DH* ipoints,        //!< Input point array
00450          DPOINT3DH* opoints,              //!< Output point array
00451          INT32 NumPoints                  //!< Number of points to convert
00452          ) const {
00453             if (IsLinear()) {
00454                for (INT32 p = 0; (p < NumPoints); ++p)
00455                   *opoints++ = m_Linear.ConvertReverse(*ipoints++);
00456                return (0);
00457                }
00458             else return (v_ConvertReverse(ipoints,opoints,NumPoints));
00459             }
00460 
00461       //! Perform reverse operation with possible densification.
00462       ERRVALUE ConvertReverseDense (
00463          INT32 NumPoints,                 //!< Number of points
00464          int NumDim,                      //!< Number of dimensions (usually 2, 3 or 4 (indicates homogeneous))
00465          const double *ipoint,            //!< Input point array of specified dimension
00466          double tolerance,                //!< Densification tolerance in target coordinates
00467          COORDOP_TARGET& target           //!< Target for converted points
00468          ) const;
00469 
00470       //! Get linear implementation if operation is linear.
00471       const LINEAR& GetLinear (
00472          ) const { return (m_Linear); }
00473 
00474       //! Get source coordinate reference system description.
00475       const COORDREFSYS& GetSourceCRS (
00476          ) const { return (m_SourceCRS); }
00477 
00478       //! Get target coordinate reference system description.
00479       const COORDREFSYS& GetTargetCRS (
00480          ) const { return (m_TargetCRS); }
00481 
00482       //! Determine if forward operation is supported.
00483       bool HasForward (
00484          ) const { return (m_HasForward); }
00485 
00486       //! Determine if reverse operation is supported.
00487       bool HasReverse (
00488          ) const { return (m_HasReverse); }
00489 
00490       //! Determine if both forward and reverse operations are supported.
00491       bool IsBidirectional (
00492          ) const { return (m_HasForward && m_HasReverse); }
00493 
00494       //! Determine if operation is linear.
00495       bool IsLinear (
00496          ) const { return (m_IsLinear); }
00497 
00498       // Release reference, destroying if last one.
00499       void Release ();
00500 
00501       //! Set source region over which operation is valid.
00502       ERRVALUE SetSourceRegion (
00503          const REGION2D& region              //!< Region in source coordinate reference system
00504          );
00505 
00506       //! Set target region over which operation is valid.
00507       ERRVALUE SetTargetRegion (
00508          const REGION2D& region              //!< Region in target coordinate reference system
00509          );
00510 
00511    protected:
00512 
00513       enum TYPE {
00514          TYPE_Identity,
00515          TYPE_Single,
00516          TYPE_List
00517          };
00518 
00519       //! Default constructor.
00520       explicit COORDOP_IMPL (
00521          TYPE type,
00522          bool IsLinear = false
00523          );
00524 
00525       //! Copy constructor.
00526       COORDOP_IMPL (
00527          const COORDOP_IMPL& rhs
00528          );
00529 
00530       bool GetDisableRangeCheck (
00531          ) const { return (m_DisableRangeCheck); }
00532 
00533       //! Get operation type.
00534       TYPE GetType (
00535          ) const { return (m_Type); }
00536 
00537       void SetDisableRangeCheck (
00538          bool DisableRangeCheck
00539          ) { m_DisableRangeCheck = DisableRangeCheck; }
00540 
00541       //! Set to use specified linear implementation.
00542       void SetLinear (
00543          const LINEAR& Linear
00544          ) { m_IsLinear = true; m_Linear = Linear; }
00545 
00546       //! Set operation to be nonlinear.
00547       void SetNonLinear (
00548          ) { m_IsLinear = false; }
00549 
00550       //! Set source coordinate reference system.
00551       void SetSourceCRS (
00552          const COORDREFSYS& SourceCRS
00553          ) { m_SourceCRS = SourceCRS; }
00554 
00555       //! Set target coordinate reference system.
00556       void SetTargetCRS (
00557          const COORDREFSYS& TargetCRS
00558          ) { m_TargetCRS = TargetCRS; }
00559 
00560       //! Set valid directions.
00561       void SetValidDirections (
00562          bool hasForward,
00563          bool hasReverse
00564          ) { m_HasForward = hasForward; m_HasReverse = hasReverse; }
00565 
00566    private:
00567       #ifndef GENERATING_DOXYGEN_OUTPUT
00568 
00569       // Explicitly initialized.
00570       int m_RefCount;
00571       TYPE m_Type;
00572       bool m_IsLinear;
00573       bool m_HasForward;
00574       bool m_HasReverse;
00575       bool m_DisableRangeCheck;
00576       // Self initializing.
00577       COORDREFSYS m_SourceCRS;
00578       COORDREFSYS m_TargetCRS;
00579       LINEAR m_Linear;                       // Linear implementation
00580 
00581       // Conversion with densification.
00582       ERRVALUE ConvertDense (
00583          INT32 NumPoints,                 // Number of points
00584          int NumDim,                      // Number of dimensions (usually 2, 3 or 4 (indicates homogeneous))
00585          const double *ipoint,            // Input point array of specified dimension
00586          COORDOP_DIRECTION direction,     // Operation direction
00587          double tolerance,                // Densification tolerance in target coordinates
00588          COORDOP_TARGET& target           // Target for converted points
00589          ) const;
00590 
00591       // Copy implementation instance.
00592       COORDOP_IMPL* Copy (
00593          ) const { return (v_Copy()); }
00594 
00595       // Get reference count.
00596       int GetRefCount () const { return (m_RefCount); }
00597 
00598       // Reverse direction of operation.
00599       void Reverse ();
00600 
00601       // Assignment unimplemented.
00602       COORDOP_IMPL& operator= (const COORDOP_IMPL&);
00603 
00604       friend class SPATREF::COORDOP;
00605       friend class SPATREF::COORDOP_SINGLE;
00606       friend class SPATREF::COORDOP_LIST;
00607       friend class SPATREF::COORDOP_IMPL_LINEAR;
00608       friend class SPATREF::COORDOP_IMPL_LIST;
00609 
00610       #endif // GENERATING_DOXYGEN_OUTPUT
00611 
00612       // Overridables
00613 
00614       //! Perform forward operation on DPOINT2D array.
00615       virtual ERRVALUE v_ConvertForward (const DPOINT2D* ipoints, DPOINT2D* opoints, INT32 NumPoints) const = 0;
00616 
00617       //! Perform forward operation on DPOINT3D array.
00618       virtual ERRVALUE v_ConvertForward (const DPOINT3D* ipoints, DPOINT3D* opoints, INT32 NumPoints) const = 0;
00619 
00620       //! Perform forward operation on DPOINT3DH array.
00621       virtual ERRVALUE v_ConvertForward (const DPOINT3DH* ipoints, DPOINT3DH* opoints, INT32 NumPoints) const = 0;
00622 
00623       //! Perform reverse operation on DPOINT2D array.
00624       virtual ERRVALUE v_ConvertReverse (const DPOINT2D* ipoints, DPOINT2D* opoints, INT32 NumPoints) const = 0;
00625 
00626       //! Perform reverse operation on DPOINT3D array.
00627       virtual ERRVALUE v_ConvertReverse (const DPOINT3D* ipoints, DPOINT3D* opoints, INT32 NumPoints) const = 0;
00628 
00629       //! Perform reverse operation on DPOINT3DH array.
00630       virtual ERRVALUE v_ConvertReverse (const DPOINT3DH* ipoints, DPOINT3DH* opoints, INT32 NumPoints) const = 0;
00631 
00632       //! Construct copy of instance.
00633       virtual COORDOP_IMPL* v_Copy () const = 0;
00634 
00635       //! Reverse operation direction.
00636       virtual void v_Reverse () = 0;
00637 
00638    };
00639 
00640 
00641 //=====================================================================================================================
00642 //! Coordinate Operation (conversion/transformation) service.
00643 //! Coordinate operatiosn instances are reference-counted so that assignment and
00644 //! list manipulation is efficient and requires no additional memory allocation.
00645 class CLASSLIBEXPORT COORDOP {
00646    public:
00647 
00648       //! Copy constructor.
00649       COORDOP (
00650          const COORDOP& rhs
00651          );
00652 
00653       //! Destructor.
00654       ~COORDOP (
00655          );
00656 
00657       //! Assignment.
00658       COORDOP& operator= (
00659          const COORDOP& rhs
00660          );
00661 
00662       //! Perform forward operation on DPOINT2D
00663       ERRVALUE ConvertForward (
00664          const DPOINT2D& ipoint,          //!< Input point
00665          DPOINT2D& opoint                 //!< Output point
00666          ) const { return (m_pImpl->ConvertForward(&ipoint,&opoint,1)); }
00667 
00668       //! Perform forward operation on DPOINT3D.
00669       ERRVALUE ConvertForward (
00670          const DPOINT3D& ipoint,          //!< Input point
00671          DPOINT3D& opoint                 //!< Output point
00672          ) const { return (m_pImpl->ConvertForward(&ipoint,&opoint,1)); }
00673 
00674       //! Perform forward operation on DPOINT3DH.
00675       ERRVALUE ConvertForward (
00676          const DPOINT3DH& ipoint,         //!< Input point
00677          DPOINT3DH& opoint                //!< Output point
00678          ) const { return (m_pImpl->ConvertForward(&ipoint,&opoint,1)); }
00679 
00680       //! Perform forward operation on DPOINT2D array.
00681       ERRVALUE ConvertForward (
00682          const DPOINT2D* ipoints,         //!< Input point array
00683          DPOINT2D* opoints,               //!< Output point array
00684          INT32 NumPoints                  //!< Number of points to convert
00685          ) const { return (m_pImpl->ConvertForward(ipoints,opoints,NumPoints)); }
00686 
00687       //! Perform forward operation on DPOINT3D array.
00688       ERRVALUE ConvertForward (
00689          const DPOINT3D* ipoints,         //!< Input point array
00690          DPOINT3D* opoints,               //!< Output point array
00691          INT32 NumPoints                  //!< Number of points to convert
00692          ) const { return (m_pImpl->ConvertForward(ipoints,opoints,NumPoints)); }
00693 
00694       //! Perform forward operation on DPOINT3DH array.
00695       ERRVALUE ConvertForward (
00696          const DPOINT3DH* ipoints,        //!< Input point array
00697          DPOINT3DH* opoints,              //!< Output point array
00698          INT32 NumPoints                  //!< Number of points to convert
00699          ) const { return (m_pImpl->ConvertForward(ipoints,opoints,NumPoints)); }
00700 
00701       //! Perform forward operation with possible densification.
00702       ERRVALUE ConvertForwardDense (
00703          INT32 NumPoints,                 //!< Number of points
00704          int NumDim,                      //!< Number of dimensions (usually 2, 3 or 4 (indicates homogeneous))
00705          const double *ipoint,            //!< Input point array of specified dimension
00706          double tolerance,                //!< Densification tolerance in target coordinates
00707          COORDOP_TARGET& target              //!< Target for converted points
00708          ) const { return (m_pImpl->ConvertForwardDense(NumPoints,NumDim,ipoint,tolerance,target)); }
00709 
00710       //! Perform reverse operation on DPOINT2D
00711       ERRVALUE ConvertReverse (
00712          const DPOINT2D& ipoint,          //!< Input point
00713          DPOINT2D& opoint                 //!< Output point
00714          ) const { return (m_pImpl->ConvertReverse(&ipoint,&opoint,1)); }
00715 
00716       //! Perform reverse operation on DPOINT3D.
00717       ERRVALUE ConvertReverse (
00718          const DPOINT3D& ipoint,          //!< Input point
00719          DPOINT3D& opoint                 //!< Output point
00720          ) const { return (m_pImpl->ConvertReverse(&ipoint,&opoint,1)); }
00721 
00722       //! Perform reverse operation on DPOINT3DH.
00723       ERRVALUE ConvertReverse (
00724          const DPOINT3DH& ipoint,            //!< Input point
00725          DPOINT3DH& opoint                //!< Output point
00726          ) const { return (m_pImpl->ConvertReverse(&ipoint,&opoint,1)); }
00727 
00728       //! Perform reverse operation on DPOINT2D array.
00729       ERRVALUE ConvertReverse (
00730          const DPOINT2D* ipoints,         //!< Input point array
00731          DPOINT2D* opoints,               //!< Output point array
00732          INT32 NumPoints                  //!< Number of points to convert
00733          ) const { return (m_pImpl->ConvertReverse(ipoints,opoints,NumPoints)); }
00734 
00735       //! Perform reverse operation on DPOINT3D array.
00736       ERRVALUE ConvertReverse (
00737          const DPOINT3D* ipoints,         //!< Input point array
00738          DPOINT3D* opoints,               //!< Output point array
00739          INT32 NumPoints                  //!< Number of points to convert
00740          ) const { return (m_pImpl->ConvertReverse(ipoints,opoints,NumPoints)); }
00741 
00742       //! Perform reverse operation on DPOINT3DH array.
00743       ERRVALUE ConvertReverse (
00744          const DPOINT3DH* ipoints,           //!< Input point array
00745          DPOINT3DH* opoints,                 //!< Output point array
00746          INT32 NumPoints                     //!< Number of points to convert
00747          ) const { return (m_pImpl->ConvertReverse(ipoints,opoints,NumPoints)); }
00748 
00749       //! Perform reverse operation with possible densification.
00750       ERRVALUE ConvertReverseDense (
00751          INT32 NumPoints,                    //!< Number of points
00752          int NumDim,                         //!< Number of dimensions (usually 2, 3 or 4 (indicates homogeneous))
00753          const double *ipoint,               //!< Input point array of specified dimension
00754          double tolerance,                   //!< Densification tolerance in target coordinates
00755          COORDOP_TARGET& target              //!< Target for converted points
00756          ) const { return (m_pImpl->ConvertReverseDense(NumPoints,NumDim,ipoint,tolerance,target)); }
00757 
00758       //! Get linear implementation instance for subsequent fast inline conversion.
00759       //! Note: If IsLinear() returns false then the returned LINEAR operation will not be valid.
00760       const COORDOP_IMPL::LINEAR& GetLinear (
00761          ) const { return (m_pImpl->GetLinear()); }
00762 
00763       //! Attempt to get linear approximation to operation within specified tolerance.
00764       //! Regardless of direction specified, any returned LINEAR operation will have the same direction
00765       //! as the operation instance itself.
00766       //! @return TRUE if returned operation is linear, FALSE if not, < 0 if error.
00767       int GetLinearApproximation (
00768          COORDOP& CoordOp,                   //!< Coordinate operation returned
00769          COORDOP_DIRECTION direction,        //!< Direction in which to perform approximation
00770          const REGION2D& region,             //!< Region in 'input' CRS based on specified direction
00771          double tolerance                    //!< Tolerance in 'output' CRS based on specified direction
00772          ) const;
00773 
00774       //! Get source coordinate reference system description.
00775       const COORDREFSYS& GetSourceCRS (
00776          ) const { return (m_pImpl->GetSourceCRS()); }
00777 
00778       //! Get target coordinate reference system description.
00779       const COORDREFSYS& GetTargetCRS (
00780          ) const { return (m_pImpl->GetTargetCRS()); }
00781 
00782       //! Determine if forward operation is supported.
00783       bool HasForward (
00784          ) const { return (m_pImpl->HasForward()); }
00785 
00786       //! Determine if reverse operation is supported.
00787       bool HasReverse (
00788          ) const { return (m_pImpl->HasReverse()); }
00789 
00790       //! Determine if both forward and reverse operations are supported.
00791       bool IsBidirectional (
00792          ) const { return (m_pImpl->IsBidirectional()); }
00793 
00794       bool IsIdentity (
00795          ) const { return (m_pImpl->m_Type == COORDOP_IMPL::TYPE_Identity); }
00796 
00797       //! Determine if linear transformation available.
00798       bool IsLinear (
00799          ) const { return (m_pImpl->IsLinear()); }
00800 
00801       //! Determine if operation uses a list.
00802       bool IsList (
00803          ) const { return (m_pImpl->m_Type == COORDOP_IMPL::TYPE_List); }
00804 
00805       //! Reverse direction of operation.
00806       void ReverseDirection (
00807          );
00808 
00809    protected:
00810       #ifndef GENERATING_DOXYGEN_OUTPUT
00811       COORDOP_IMPL *m_pImpl;
00812       COORDOP ();
00813       void GetExclusive ();
00814       #endif // GENERATING_DOXYGEN_OUTPUT
00815    };
00816 
00817 
00818 //=====================================================================================================================
00819 //! Coordinate Operation service with attach/detach interface for use with
00820 //! operation implementations not created automatically by spatial reference system.
00821 class CLASSLIBEXPORT COORDOP_SINGLE : public COORDOP {
00822    public:
00823 
00824       //! Default constructor.
00825       //! Operation will reference 'null' implementation until Attach() or Create().
00826       COORDOP_SINGLE (
00827          );
00828 
00829       //! Construct and attach implementation instance.
00830       //! After attachment, COORDOP instance is responsible for deletion and the
00831       //! passed-in pointer will be set to NULL.
00832       //! Used when implementation instance is manually created.
00833       COORDOP_SINGLE (
00834          COORDOP_IMPL *& pImpl            //!< Operation implementation to attach
00835          );
00836 
00837       //! Attach implemention to operation container.
00838       //! After attachment, COORDOP instance is responsible for deletion and the
00839       //! passed-in pointer will be set to NULL.
00840       //! Used when implementation instance is manually created.
00841       void Attach (
00842          COORDOP_IMPL *& pImpl            //!< Operation implementation to attach
00843          );
00844 
00845       //! Create operation using operation definition.
00846       //! Not for use with concatenated coordinate operation.
00847       ERRVALUE Create (
00848          const COORDOPDEF& CoordOpDef,    //!< Coordinate operation definition
00849          const COORDREFSYS& SourceCRS,
00850          const COORDREFSYS& TargetCRS,
00851          bool DisableRangeCheck = false   //!< Disable range check where supported
00852          );
00853 
00854       //! Detach implementation from operation container.
00855       //! @return Pointer to implementation instance, caller responsible for deletion.
00856       //! Operation will reference 'null' implementation after detachment.
00857       COORDOP_IMPL* Detach (
00858          );
00859 
00860       //! Release attached implementation if any.
00861       void ReleaseAttached (
00862          );
00863 
00864    };
00865 
00866 
00867 //=====================================================================================================================
00868 //! Coordinate Operation service with list management interface.
00869 class CLASSLIBEXPORT COORDOP_LIST : public COORDOP {
00870    public:
00871 
00872       //! Default constructor.
00873       COORDOP_LIST (
00874          );
00875 
00876       //! Copy constructor.
00877       COORDOP_LIST (
00878          const COORDOP_LIST& rhs
00879          );
00880 
00881       //! Construct from COORDOP.
00882       COORDOP_LIST (
00883          const COORDOP& rhs
00884          );
00885 
00886       //! Assignment.
00887       COORDOP_LIST& operator= (
00888          const COORDOP_LIST& rhs
00889          );
00890 
00891       //! Assignment from COORDOP.
00892       COORDOP_LIST& operator= (
00893          const COORDOP& rhs
00894          );
00895 
00896       //! Add operation to end.
00897       //! Any linear approximation and target region settings will be lost.
00898       ERRVALUE AddEnd (
00899          const COORDOP& operation         //!< Operation to add
00900          );
00901 
00902       //! Add operation list to end.
00903       //! Any linear approximation and target region settings will be lost.
00904       ERRVALUE AddEnd (
00905          const COORDOP_LIST& oplist       //!< Operation list to add
00906          );
00907 
00908       //! Attempt to add operations to end of list to achieve specified target CRS.
00909       //! If specified CRS matches current target then no operations will be added and 0 will be returned.
00910       //! Any linear approximation and target region settings will be lost.
00911       //! @return Number of operations actually added or error < 0
00912       int AddEnd (
00913          const COORDREFSYS& TargetCRS     //! Desired target coordinate reference system
00914          );
00915 
00916       //! Add operation to start of operation list.
00917       //! Any linear approximation and source region settings will be lost.
00918       ERRVALUE AddStart (
00919          const COORDOP& operation         //!< Operation to add
00920          );
00921 
00922       //! Add operation list to start.
00923       //! Any linear approximation and source region settings will be lost.
00924       ERRVALUE AddStart (
00925          const COORDOP_LIST& oplist       //!< Operation list to add
00926          );
00927 
00928       //! Attempt to add operations to start of list to achieve specified source CRS.
00929       //! If specified CRS matches current source then no operations will be added and 0 will be returned.
00930       //! Any linear approximation and source region settings will be lost.
00931       //! @return Number of operations actually added or error < 0
00932       int AddStart (
00933          const COORDREFSYS& SourceCRS     //!< Desired source coordinate reference system
00934          );
00935 
00936       //! Clear operation list, reverting to empty/undefined.
00937       void Clear (
00938          );
00939 
00940       //! Create operation using operation definition.
00941       //! Source and target CRS are determined from operation definition, may not be used
00942       //! with projection definition obtained from a projected CRS.
00943       ERRVALUE Create (
00944          const COORDOPDEF& CoordOpDef,    //!< Coordinate operation definition
00945          bool DisableRangeCheck = false   //!< Disable range check where supported
00946          );
00947 
00948       //! Create operation list for conversion between specified coordinate reference systems.
00949       ERRVALUE Create (
00950          const COORDREFSYS& SourceCRS,    //!< Source coordinate reference system
00951          const COORDREFSYS& TargetCRS,    //!< Target coordinate reference system
00952          bool DisableRangeCheck = false   //!< Disable range check where supported
00953          );
00954 
00955       //! Remove operation at end of operation list.
00956       //! Any linear approximation and target region settings will be lost.
00957       void RemoveEnd (
00958          );
00959 
00960       //! Remove operation at start of operation list.
00961       //! Any linear approximation and source region settings will be lost.
00962       void RemoveStart (
00963          );
00964 
00965    private:
00966       #ifndef GENERATING_DOXYGEN_OUTPUT
00967       ERRVALUE Create (const COORDREFSYS& CoordRefSys, bool DisableRangeCheck);
00968       const MILIST<COORDOP>& GetOpListMin () const;
00969 
00970       friend class COORDOP_IMPL_LIST;
00971       #endif // GENERATING_DOXYGEN_OUTPUT
00972    };
00973 
00974 //=====================================================================================================================
00975 
00976 class COORDOPZONED_IMPL;
00977 
00978 //! Service for converting between 'zoned' and non-zoned reference systems.
00979 class CLASSLIBEXPORT COORDOP_ZONED {
00980    public:
00981 
00982       //! Constructor.
00983       COORDOP_ZONED (
00984          );
00985 
00986       //! Copy constructor.
00987       COORDOP_ZONED (
00988          const COORDOP_ZONED& rhs
00989          );
00990 
00991       //! Destructor.
00992       ~COORDOP_ZONED (
00993          );
00994 
00995       //! Assignment.
00996       COORDOP_ZONED& operator= (
00997          const COORDOP_ZONED& rhs
00998          );
00999 
01000       //! Convert zone and DPOINT2D to non-zoned CRS
01001       ERRVALUE ConvertFromZoned (
01002          const MISTRING& zonestr,               //!< Zone string for point
01003          const DPOINT2D& ipoint,                //!< Point to convert
01004          const COORDREFSYS& PointCoordRefSys,   //!< Non-zoned coordinate reference system to convert to
01005          DPOINT2D& opoint                       //!< Point returned
01006          ) const;
01007 
01008       //! Convert zone and DPOINT3D to non-zoned CRS
01009       ERRVALUE ConvertFromZoned (
01010          const MISTRING& zonestr,               //!< Zone string for point
01011          const DPOINT3D& ipoint,                //!< Point to convert
01012          const COORDREFSYS& PointCoordRefSys,   //!< Non-zoned coordinate reference system to convert to
01013          DPOINT3D& opoint                       //!< Point returned
01014          ) const;
01015 
01016       //! Parse and convert string to non-zoned CRS
01017       ERRVALUE ConvertFromZoned (
01018          const MISTRING& string,                //!< String to parse
01019          const COORDREFSYS& PointCoordRefSys,   //!< Non-zoned coordinate reference system to convert to
01020          DPOINT2D& opoint                       //!< Point returned
01021          ) const;
01022 
01023       //! Convert DPOINT2D to zoned CRS.
01024       ERRVALUE ConvertToZoned (
01025          const COORDREFSYS& PointCoordRefSys,   //!< Coordinate reference system to convert from
01026          const DPOINT2D& ipoint,                //!< Point to convert
01027          MISTRING& zonestr,                     //!< Zone string returned
01028          DPOINT2D& opoint                       //!< Point returned
01029          ) const;
01030 
01031       //! Convert DPOINT3D to zoned CRS.
01032       ERRVALUE ConvertToZoned (
01033          const COORDREFSYS& PointCoordRefSys,   //!< Coordinate reference system to convert from
01034          const DPOINT3D& ipoint,                //!< Point to convert
01035          MISTRING& zonestr,                     //!< Zone string returned
01036          DPOINT3D& opoint                       //!< Point returned
01037          ) const;
01038 
01039       //! Set zoned coordinate reference system.
01040       ERRVALUE SetCoordRefSys (
01041          const COORDREFSYS& ZonedCRS            //!< Zoned coordinate reference system
01042          );
01043 
01044    private:
01045       #ifndef GENERATING_DOXYGEN_OUTPUT
01046       COORDOPZONED_IMPL *m_pImpl;
01047       #endif // GENERATING_DOXYGEN_OUTPUT
01048    };
01049 
01050 //=====================================================================================================================
01051 
01052 }  // End namespace SPATREF
01053 
01054 #undef   CLASSLIBEXPORT
01055 
01056 #endif   // INC_MI32_COORDOP_H

Generated on Wed May 31 15:26:49 2006 for TNTsdk by  doxygen 1.3.8-20040913