⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pj_transform.c

📁 开源投影系统 Cartographic Projections library originally written by Gerald Evenden then of the USGS. The
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** * $Id: pj_transform.c,v 1.9 2003/03/26 16:52:30 warmerda Exp $ * * Project:  PROJ.4 * Purpose:  Perform overall coordinate system to coordinate system  *           transformations (pj_transform() function) including reprojection *           and datum shifting. * Author:   Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 2000, Frank Warmerdam * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. ****************************************************************************** * * $Log: pj_transform.c,v $ * Revision 1.9  2003/03/26 16:52:30  warmerda * added check that an inverse transformation func exists * * Revision 1.8  2002/12/14 20:35:43  warmerda * implement units support for geocentric coordinates * * Revision 1.7  2002/12/14 20:14:35  warmerda * added geocentric support * * Revision 1.6  2002/12/09 16:01:02  warmerda * added prime meridian support * * Revision 1.5  2002/12/01 19:25:26  warmerda * applied fix for 7 param shift in pj_geocentric_from_wgs84, see bug 194 * * Revision 1.4  2002/02/15 14:30:36  warmerda * provide default Z array if none passed in in pj_datum_transform() * * Revision 1.3  2001/04/04 21:13:21  warmerda * do arcsecond/radian and ppm datum parm transformation in pj_set_datum() * * Revision 1.2  2001/04/04 16:08:08  warmerda * rewrote 7 param datum shift to match EPSG:9606, now works with example * * Revision 1.1  2000/07/06 23:32:27  warmerda * New * */#include <projects.h>#include <string.h>#include <math.h>#include "geocent.h"PJ_CVSID("$Id: pj_transform.c,v 1.9 2003/03/26 16:52:30 warmerda Exp $");#ifndef SRS_WGS84_SEMIMAJOR#define SRS_WGS84_SEMIMAJOR 6378137.0#endif#ifndef SRS_WGS84_ESQUARED#define SRS_WGS84_ESQUARED 0.006694379990#endif#define Dx_BF (defn->datum_params[0])#define Dy_BF (defn->datum_params[1])#define Dz_BF (defn->datum_params[2])#define Rx_BF (defn->datum_params[3])#define Ry_BF (defn->datum_params[4])#define Rz_BF (defn->datum_params[5])#define M_BF  (defn->datum_params[6])/************************************************************************//*                            pj_transform()                            *//*                                                                      *//*      Currently this function doesn't recognise if two projections    *//*      are identical (to short circuit reprojection) because it is     *//*      difficult to compare PJ structures (since there are some        *//*      projection specific components).                                *//************************************************************************/int pj_transform( PJ *srcdefn, PJ *dstdefn, long point_count, int point_offset,                  double *x, double *y, double *z ){    long      i;    int       need_datum_shift;    pj_errno = 0;    if( point_offset == 0 )        point_offset = 1;/* -------------------------------------------------------------------- *//*      Transform geocentric source coordinates to lat/long.            *//* -------------------------------------------------------------------- */    if( srcdefn->is_geocent )    {        if( z == NULL )        {            pj_errno = PJD_ERR_GEOCENTRIC;            return PJD_ERR_GEOCENTRIC;        }        if( srcdefn->to_meter != 1.0 )        {            for( i = 0; i < point_count; i++ )            {                x[point_offset*i] *= srcdefn->to_meter;                y[point_offset*i] *= srcdefn->to_meter;            }        }        pj_geocentric_to_geodetic( srcdefn->a, srcdefn->es,                                   point_count, point_offset, x, y, z );    }/* -------------------------------------------------------------------- *//*      Transform source points to lat/long, if they aren't             *//*      already.                                                        *//* -------------------------------------------------------------------- */    else if( !srcdefn->is_latlong )    {        if( srcdefn->inv == NULL )        {            pj_errno = -17; /* this isn't correct, we need a no inverse err */            if( getenv( "PROJ_DEBUG" ) != NULL )            {                fprintf( stderr,                        "pj_transform(): source projection not invertable\n" );            }            return pj_errno;        }        for( i = 0; i < point_count; i++ )        {            XY         projected_loc;            LP	       geodetic_loc;            projected_loc.u = x[point_offset*i];            projected_loc.v = y[point_offset*i];            geodetic_loc = pj_inv( projected_loc, srcdefn );            if( pj_errno != 0 )                return pj_errno;            x[point_offset*i] = geodetic_loc.u;            y[point_offset*i] = geodetic_loc.v;        }    }/* -------------------------------------------------------------------- *//*      But if they are already lat long, adjust for the prime          *//*      meridian if there is one in effect.                             *//* -------------------------------------------------------------------- */    else if( srcdefn->from_greenwich != 0.0 )    {        for( i = 0; i < point_count; i++ )            x[point_offset*i] += srcdefn->from_greenwich;    }/* -------------------------------------------------------------------- *//*      Convert datums if needed, and possible.                         *//* -------------------------------------------------------------------- */    if( pj_datum_transform( srcdefn, dstdefn, point_count, point_offset,                             x, y, z ) != 0 )        return pj_errno;/* -------------------------------------------------------------------- *//*      Transform destination latlong to geocentric if required.        *//* -------------------------------------------------------------------- */    if( dstdefn->is_geocent )    {        if( z == NULL )        {            pj_errno = PJD_ERR_GEOCENTRIC;            return PJD_ERR_GEOCENTRIC;        }        pj_geodetic_to_geocentric( dstdefn->a, dstdefn->es,                                   point_count, point_offset, x, y, z );        if( dstdefn->fr_meter != 1.0 )        {            for( i = 0; i < point_count; i++ )            {                x[point_offset*i] *= dstdefn->fr_meter;                y[point_offset*i] *= dstdefn->fr_meter;            }        }    }/* -------------------------------------------------------------------- *//*      Transform destination points to projection coordinates, if      *//*      desired.                                                        *//* -------------------------------------------------------------------- */    else if( !dstdefn->is_latlong )    {        for( i = 0; i < point_count; i++ )        {            XY         projected_loc;            LP	       geodetic_loc;            geodetic_loc.u = x[point_offset*i];            geodetic_loc.v = y[point_offset*i];            projected_loc = pj_fwd( geodetic_loc, dstdefn );            if( pj_errno != 0 )                return pj_errno;            x[point_offset*i] = projected_loc.u;            y[point_offset*i] = projected_loc.v;        }    }/* -------------------------------------------------------------------- *//*      But if they are staying lat long, adjust for the prime          *//*      meridian if there is one in effect.                             *//* -------------------------------------------------------------------- */    else if( dstdefn->from_greenwich != 0.0 )    {        for( i = 0; i < point_count; i++ )            x[point_offset*i] -= dstdefn->from_greenwich;    }    return 0;}/************************************************************************//*                     pj_geodetic_to_geocentric()                      *//************************************************************************/int pj_geodetic_to_geocentric( double a, double es,                                long point_count, int point_offset,                               double *x, double *y, double *z ){    double b;    int    i;    if( es == 0.0 )        b = a;    else        b = a * sqrt(1-es);    if( Set_Geocentric_Parameters( a, b ) != 0 )    {        pj_errno = PJD_ERR_GEOCENTRIC;        return pj_errno;    }    for( i = 0; i < point_count; i++ )    {        long io = i * point_offset;        if( Convert_Geodetic_To_Geocentric( y[io], x[io], z[io],                                             x+io, y+io, z+io ) != 0 )        {            pj_errno = PJD_ERR_GEOCENTRIC;            return PJD_ERR_GEOCENTRIC;        }    }    return 0;}/************************************************************************//*                     pj_geodetic_to_geocentric()                      */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -