// StatePlaneProjection.cpp: implementation of the StatePlaneProjection class // // Developed by: Mike Childs // Started: 3/18/98 ////////////////////////////////////////////////////////////////////// #include "StatePlaneProjection.h" #include "DatumConvertor.h" #include // GCTPC includes #include "gctpc/gctp.h" #include "gctpc/gctpc.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 // Static member initialization string StatePlaneProjection::d_strNAD27ParamFilename; string StatePlaneProjection::d_strNAD83ParamFilename; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// StatePlaneProjection::StatePlaneProjection( long zone, DATUM d, UNIT u, DATUM geoDatum, UNIT geoUnit ) : Projection(d,u,geoDatum,geoUnit), ZonedProjection(zone) { } StatePlaneProjection::StatePlaneProjection( const StatePlaneProjection& p ) : Projection(p), ZonedProjection(p) { } StatePlaneProjection::~StatePlaneProjection() { } // Operator overloads bool StatePlaneProjection::operator==( const Projection& p ) const { // Check to see if the projection passed in is UTM if ( SPCS == p.getProjectionSystem() ) { const StatePlaneProjection* pRHS = dynamic_cast(&p); if ( NULL != pRHS ) { if ( getZone() == pRHS->getZone() ) { return Projection::operator==(p); } } } return false; } // Modifiers void StatePlaneProjection::setZone( long zone ) { // Make sure the zone number is valid before setting it if ( ( zone < 101 || zone > 5400 ) ) { // Invalid zone number, use zero instead zone = 0; } ZonedProjection::setZone( zone ); } // Projection functions bool StatePlaneProjection::projectToGeo( double x, double y, double& latitude, double& longitude ) const { double inparm[15]; // input parameter array long iflg; // error flag // Initialize the projection parameter arrays to all zeroes for ( int i = 0; i < 15; i++ ) { inparm[i] = 0.0; } // Initialize the state plane inverse transformation InverseTransFunc inv_trans[MAXPROJ + 1]; inv_init( getProjectionSystem(), getZone(), inparm, DatumConvertor::getDatumEllipsoid( getDatum() ), (char*)d_strNAD27ParamFilename.c_str(), (char*)d_strNAD83ParamFilename.c_str(), &iflg, inv_trans ); // Convert the x and y to meters double factor; untfz( getUnit(), METERS, &factor ); x *= factor; y *= factor; // do the inverse transformation stplninv( 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 StatePlaneProjection::projectFromGeo( double latitude, double longitude, double& x, double& y ) const { // Convert the datums if ( !convertDatum( latitude, longitude, getGeoDatum(), getDatum() ) ) { return false; } double outparm[15]; // output parameter array long iflg; // error flag // Initialize the projection parameter arrays to all zeroes for ( int i = 0; i < 15; i++ ) { outparm[i] = 0.0; } // Initialize the state plane forward transformation ForwardTransFunc for_trans[MAXPROJ + 1]; for_init( getProjectionSystem(), getZone(), outparm, DatumConvertor::getDatumEllipsoid( getDatum() ), (char*)d_strNAD27ParamFilename.c_str(), (char*)d_strNAD83ParamFilename.c_str(), &iflg, for_trans ); // Convert the input coordinates to radians double factor; untfz( getGeoUnit(), RADIANS, &factor ); longitude *= factor; latitude *= factor; // do the forward transformation stplnfor( 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* StatePlaneProjection::clone() const { return ( new StatePlaneProjection( *this ) ); } string StatePlaneProjection::toString() const { string str = "State Plane Projection\r\n"; str += Projection::toString(); str += "STATE PLANE ZONE: "; char strZone[10]; sprintf( strZone, "%d", getZone() ); str += strZone; return str; } bool StatePlaneProjection::checkCoordinateRange( double latitude, double longitude ) const { if ( !Projection::checkCoordinateRange( latitude, longitude ) ) { return false; } return ( latitude <= 89.0 && latitude >= -89.0 ); }