osgEarth 2.1.1

/home/cube/sources/osgearth/src/osgEarth/ECEF.cpp

Go to the documentation of this file.
00001 /* -*-c++-*- */
00002 /* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
00003  * Copyright 2008-2010 Pelican Mapping
00004  * http://osgearth.org
00005  *
00006  * osgEarth is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU Lesser General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses/>
00018  */
00019 
00020 #include <osgEarth/ECEF>
00021 
00022 using namespace osgEarth;
00023 
00024 #define LC "[ECEF] "
00025 
00026 // --------------------------------------------------------------------------
00027 
00028 
00029 osg::Matrixd
00030 ECEF::createInverseRefFrame( const osg::Vec3d& input )
00031 {
00032     // convert to geocentric first:
00033     double X = input.x(), Y = input.y(), Z = input.z();
00034 
00035     osg::Matrixd localToWorld;
00036     localToWorld.makeTranslate(X,Y,Z);
00037 
00038     // normalize X,Y,Z
00039     double inverse_length = 1.0/sqrt(X*X + Y*Y + Z*Z);
00040 
00041     X *= inverse_length;
00042     Y *= inverse_length;
00043     Z *= inverse_length;
00044 
00045     double length_XY = sqrt(X*X + Y*Y);
00046     double inverse_length_XY = 1.0/length_XY;
00047 
00048     // Vx = |(-Y,X,0)|
00049     localToWorld(0,0) = -Y*inverse_length_XY;
00050     localToWorld(0,1) = X*inverse_length_XY;
00051     localToWorld(0,2) = 0.0;
00052 
00053     // Vy = /(-Z*X/(sqrt(X*X+Y*Y), -Z*Y/(sqrt(X*X+Y*Y),sqrt(X*X+Y*Y))| 
00054     double Vy_x = -Z*X*inverse_length_XY;
00055     double Vy_y = -Z*Y*inverse_length_XY;
00056     double Vy_z = length_XY;
00057     inverse_length = 1.0/sqrt(Vy_x*Vy_x + Vy_y*Vy_y + Vy_z*Vy_z);            
00058     localToWorld(1,0) = Vy_x*inverse_length;
00059     localToWorld(1,1) = Vy_y*inverse_length;
00060     localToWorld(1,2) = Vy_z*inverse_length;
00061 
00062     // Vz = (X,Y,Z)
00063     localToWorld(2,0) = X;
00064     localToWorld(2,1) = Y;
00065     localToWorld(2,2) = Z;
00066 
00067     return localToWorld;
00068 }
00069 
00070 void
00071 ECEF::transformAndLocalize(const osg::Vec3d&       input,
00072                            osg::Vec3d&             output,
00073                            const SpatialReference* srs,
00074                            const osg::Matrixd&     world2local)
00075 {
00076     osg::Vec3d ecef;
00077     srs->transformToECEF( input, ecef );
00078     output = ecef * world2local;
00079 }
00080 
00081 
00082 void
00083 ECEF::transformAndLocalize(const std::vector<osg::Vec3d>& input,
00084                            osg::Vec3Array*                output,
00085                            const SpatialReference*        srs,
00086                            const osg::Matrixd&            world2local )
00087 {
00088     output->reserve( output->size() + input.size() );
00089     for( std::vector<osg::Vec3d>::const_iterator i = input.begin(); i != input.end(); ++i )
00090     {
00091         osg::Vec3d ecef;
00092         srs->transformToECEF( *i, ecef );
00093         output->push_back( ecef * world2local );
00094     }
00095 }
00096 
00097 void
00098 ECEF::transformAndGetRotationMatrix(const SpatialReference* srs,
00099                                     const osg::Vec3d&       input,
00100                                     osg::Vec3d&             out_point,
00101                                     osg::Matrixd&           out_rotation )
00102 {
00103     osg::Vec3d geod_point;
00104     if ( !srs->isGeographic() )
00105         srs->transform( input, srs->getGeographicSRS(), geod_point );
00106     else
00107         geod_point = input;
00108 
00109     const osg::EllipsoidModel* em = srs->getEllipsoid();
00110     
00111     em->convertLatLongHeightToXYZ(
00112         osg::DegreesToRadians( geod_point.y() ),
00113         osg::DegreesToRadians( geod_point.x() ),
00114         geod_point.z(),
00115         out_point.x(), out_point.y(), out_point.z() );
00116 
00117     em->computeCoordinateFrame(
00118         osg::DegreesToRadians( geod_point.y() ),
00119         osg::DegreesToRadians( geod_point.x() ),
00120         out_rotation );
00121 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines