// TransverseMercatorProjection.cpp: implementation of the TransverseMercatorProjection class. // // Developed by: Mike Childs // Started: 4/5/98 ////////////////////////////////////////////////////////////////////// #include "TransverseMercatorProjection.h" #include "DatumConvertor.h" #include // GCTPC includes #include "gctpc/gctpc.h" #include "gctpc/gctp.h" #include "gctpc/for_init.h" #include "gctpc/inv_init.h" #include "gctpc/proj.h" #include "gctpc/untfz.h" #ifndef NULL #define NULL 0 #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// TransverseMercatorProjection::TransverseMercatorProjection( double scaleFactor, double sMajor, double sMinor, double centMer, double originLat, double fe, double fn, DATUM d, UNIT u, DATUM geoDatum, UNIT geoUnit ) : MercatorProjection(sMajor,sMinor,centMer,originLat,fe,fn,d,u,geoDatum,geoUnit) { setCentralMeridianScaleFactor( scaleFactor ); } TransverseMercatorProjection::TransverseMercatorProjection( const TransverseMercatorProjection& p ) : MercatorProjection(p) { if ( this != &p ) { setCentralMeridianScaleFactor( p.getCentralMeridianScaleFactor() ); } } // Comparison functions bool TransverseMercatorProjection::operator==( const Projection& p ) const { const TransverseMercatorProjection* pRHS = dynamic_cast(&p); if ( NULL != pRHS ) { if ( getCentralMeridianScaleFactor() == pRHS->getCentralMeridianScaleFactor() ) { return MercatorProjection::operator==( p ); } } return false; } // toString override string TransverseMercatorProjection::toString() const { string str = "Transverse Mercator Projection\r\n"; str += Projection::toString(); str += "CENTRAL MERIDIAN: "; str += packedDMSToString( getCentralMeridian(), false ); str += "\r\nORIGIN LATITUDE: "; str += packedDMSToString( getOriginLatitude(), true ); char strFalseEasting[40]; sprintf( strFalseEasting, "\r\nFALSE EASTING: %g", getFalseEasting() ); str += strFalseEasting; char strFalseNorthing[40]; sprintf( strFalseNorthing, "\r\nFALSE NORTHING: %g", getFalseNorthing() ); str += strFalseNorthing; char strSemiMajorAxis[40]; sprintf( strSemiMajorAxis, "\r\nSEMI-MAJOR AXIS: %g", getSemiMajorAxis() ); str += strSemiMajorAxis; char strSemiMinorAxis[40]; sprintf( strSemiMinorAxis, "\r\nSEMI-MINOR AXIS: %g", getSemiMinorAxis() ); str += strSemiMinorAxis; char strScale[40]; sprintf( strScale, "\r\nCENT. MER. SCALE FACTOR: %g", getCentralMeridianScaleFactor() ); str += strScale; return str; } // Projection functions bool TransverseMercatorProjection::projectToGeo( double x, double y, double& latitude, double& longitude ) const { long iflg; // error flag // Initialize the inverse transformation InverseTransFunc inv_trans[MAXPROJ + 1]; inv_init( getProjectionSystem(), 0, const_cast(d_projParams), DatumConvertor::getDatumEllipsoid( getDatum() ), NULL, NULL, &iflg, inv_trans ); // Convert the x and y to meters double factor; untfz( getUnit(), METERS, &factor ); x *= factor; y *= factor; // do the inverse transformation tminv( x, y, &longitude, &latitude ); // Convert the input coordinates from radians to the correct units untfz( RADIANS, getGeoUnit(), &factor ); longitude *= factor; latitude *= factor; // Convert the datums return convertDatum( latitude, longitude, getDatum(), getGeoDatum() ); } bool TransverseMercatorProjection::projectFromGeo( double latitude, double longitude, double& x, double& y ) const { // Convert the datums if ( !convertDatum( latitude, longitude, getGeoDatum(), getDatum() ) ) { return false; } long iflg; // Initialize the UTM forward transformation ForwardTransFunc for_trans[MAXPROJ + 1]; for_init( getProjectionSystem(), 0, const_cast(d_projParams), DatumConvertor::getDatumEllipsoid( getDatum() ), NULL, NULL, &iflg, for_trans ); // Convert the input coordinates to radians double factor; untfz( getGeoUnit(), RADIANS, &factor ); longitude *= factor; latitude *= factor; // do the forward transformation tmfor( longitude, latitude, &x, &y ); // Convert the x and y from meters to the correct units untfz( METERS, getUnit(), &factor ); x *= factor; y *= factor; return true; } // Cloning Projection* TransverseMercatorProjection::clone() const { return ( new TransverseMercatorProjection( *this ) ); }