示例#1
0
文件: nad_init.c 项目: aleaf/swb
struct CTABLE *nad_ctable_init( projCtx ctx, FILE * fid )
{
    struct CTABLE *ct;
    int		id_end;

    /* read the table header */
    ct = (struct CTABLE *) pj_malloc(sizeof(struct CTABLE));
    if( ct == NULL 
        || fread( ct, sizeof(struct CTABLE), 1, fid ) != 1 )
    {
        pj_ctx_set_errno( ctx, -38 );
        return NULL;
    }

    /* do some minimal validation to ensure the structure isn't corrupt */
    if( ct->lim.lam < 1 || ct->lim.lam > 100000 
        || ct->lim.phi < 1 || ct->lim.phi > 100000 )
    {
        pj_ctx_set_errno( ctx, -38 );
        return NULL;
    }
    
    /* trim white space and newlines off id */
    for( id_end = strlen(ct->id)-1; id_end > 0; id_end-- )
    {
        if( ct->id[id_end] == '\n' || ct->id[id_end] == ' ' )
            ct->id[id_end] = '\0';
        else
            break;
    }

    ct->cvs = NULL;

    return ct;
}
示例#2
0
文件: nad_init.c 项目: aleaf/swb
int nad_ctable2_load( projCtx ctx, struct CTABLE *ct, FILE *fid )

{
    int  a_size;

    fseek( fid, 160, SEEK_SET );

    /* read all the actual shift values */
    a_size = ct->lim.lam * ct->lim.phi;
    ct->cvs = (FLP *) pj_malloc(sizeof(FLP) * a_size);
    if( ct->cvs == NULL 
        || fread(ct->cvs, sizeof(FLP), a_size, fid) != a_size )
    {
        pj_dalloc( ct->cvs );
        ct->cvs = NULL;

        if( getenv("PROJ_DEBUG") != NULL )
        {
            fprintf( stderr,
            "ctable2 loading failed on fread() - binary incompatible?\n" );
        }

        pj_ctx_set_errno( ctx, -38 );
        return 0;
    }

    if( !IS_LSB )
    {
        swap_words( ct->cvs, 4, a_size * 2 );
    }

    return 1;
} 
示例#3
0
文件: pj_fwd.c 项目: SvenGastauer/oce
	XY /* forward projection entry */
pj_fwd(LP lp, PJ *P) {
	XY xy;
	double t;

	/* check for forward and latitude or longitude overange */
	if ((t = fabs(lp.phi)-HALFPI) > EPS || fabs(lp.lam) > 10.) {
		xy.x = xy.y = HUGE_VAL;
		pj_ctx_set_errno( P->ctx, -14);
	} else { /* proceed with projection */
                P->ctx->last_errno = 0;
                pj_errno = 0;
                errno = 0;

		if (fabs(t) <= EPS)
			lp.phi = lp.phi < 0. ? -HALFPI : HALFPI;
		else if (P->geoc)
			lp.phi = atan(P->rone_es * tan(lp.phi));
		lp.lam -= P->lam0;	/* compute del lp.lam */
		if (!P->over)
			lp.lam = adjlon(lp.lam); /* adjust del longitude */
		xy = (*P->fwd)(lp, P); /* project */
		if ( P->ctx->last_errno )
			xy.x = xy.y = HUGE_VAL;
		/* adjust for major axis and easting/northings */
		else {
			xy.x = P->fr_meter * (P->a * xy.x + P->x0);
			xy.y = P->fr_meter * (P->a * xy.y + P->y0);
		}
	}
	return xy;
}
示例#4
0
static XY s_forward (LP lp, PJ *P) {           /* Spheroidal, forward */
    XY xy = {0.0,0.0};
    double b, cosphi;

    /*
     * Fail if our longitude is more than 90 degrees from the
     * central meridian since the results are essentially garbage.
     * Is error -20 really an appropriate return value?
     *
     *  http://trac.osgeo.org/proj/ticket/5
     */
    if( lp.lam < -HALFPI || lp.lam > HALFPI ) {
        xy.x = HUGE_VAL;
        xy.y = HUGE_VAL;
        pj_ctx_set_errno( P->ctx, -14 );
        return xy;
    }

    cosphi = cos(lp.phi);
    b = cosphi * sin (lp.lam);
    if (fabs (fabs (b) - 1.) <= EPS10)
        F_ERROR;

    xy.x = P->opaque->ml0 * log ((1. + b) / (1. - b));
    xy.y = cosphi * cos (lp.lam) / sqrt (1. - b * b);

    b = fabs ( xy.y );
    if (b >= 1.) {
        if ((b - 1.) > EPS10)
            F_ERROR
        else xy.y = 0.;
    } else
示例#5
0
double aacos(projCtx ctx, double v) {
	double av;

	if ((av = fabs(v)) >= 1.) {
		if (av > ONE_TOL)
			pj_ctx_set_errno(ctx, -19);
		return (v < 0. ? PI : 0.);
	}
	return acos(v);
}
示例#6
0
double aasin(projCtx ctx, double v) {
	double av;

	if ((av = fabs(v)) >= 1.) {
		if (av > ONE_TOL)
			pj_ctx_set_errno(ctx, -19);
		return (v < 0. ? -HALFPI : HALFPI);
	}
	return asin(v);
}
示例#7
0
static PJ_LP e_inverse (PJ_XY xy, PJ *P) {           /* Ellipsoidal/spheroidal, inverse */
    PJ_LP lp = {0.0,0.0};
    struct pj_opaque *Q = static_cast<struct pj_opaque*>(P->opaque);
    double yc, y2, y6;
    int i;

    /* Adjusting x and y for authalic radius */
    xy.x /= Q->rqda;
    xy.y /= Q->rqda;

    /* Make sure y is inside valid range */
    if (xy.y > MAX_Y)
        xy.y = MAX_Y;
    else if (xy.y < -MAX_Y)
        xy.y = -MAX_Y;

    yc = xy.y;

    /* Newton-Raphson */
    for (i = MAX_ITER; i ; --i) {
        double f, fder, tol;

        y2 = yc * yc;
        y6 = y2 * y2 * y2;

        f    = yc * (A1 + A2 * y2 + y6 * (A3 + A4 * y2)) - xy.y;
        fder = A1 + 3 * A2 * y2 + y6 * (7 * A3 + 9 * A4 * y2);

        tol  = f / fder;
        yc  -= tol;

        if (fabs(tol) < EPS)
            break;
    }

    if( i == 0 ) {
        pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT );
        return lp;
    }

    /* Longitude */
    y2 = yc * yc;
    y6 = y2 * y2 * y2;

    lp.lam = M * xy.x * (A1 + 3 * A2 * y2 + y6 * (7 * A3 + 9 * A4 * y2)) / cos(yc);

    /* Latitude (for spheroidal case, this is latitude */
    lp.phi = asin(sin(yc) / M);

    /* Ellipsoidal case, converting auth. latitude */
    if (P->es != 0.0)
       lp.phi = pj_authlat(lp.phi, Q->apa);

    return lp;
}
示例#8
0
static LP s_healpix_inverse(XY xy, PJ *P) { /* sphere */
    LP lp = {0.0,0.0};

    /* Check whether (x, y) lies in the HEALPix image */
    if (in_image(xy.x, xy.y, 0, 0, 0) == 0) {
        lp.lam = HUGE_VAL;
        lp.phi = HUGE_VAL;
        pj_ctx_set_errno(P->ctx, -15);
        return lp;
    }
    return healpix_sphere_inverse(xy);
}
示例#9
0
static LP e_healpix_inverse(XY xy, PJ *P) { /* ellipsoid */
    LP lp = {0.0,0.0};

    /* Check whether (x, y) lies in the HEALPix image. */
    if (in_image(xy.x, xy.y, 0, 0, 0) == 0) {
        lp.lam = HUGE_VAL;
        lp.phi = HUGE_VAL;
        pj_ctx_set_errno(P->ctx, -15);
        return lp;
    }
    lp = healpix_sphere_inverse(xy);
    lp.phi = auth_lat(P, lp.phi, 1);
    return lp;
}
示例#10
0
static LP s_rhealpix_inverse(XY xy, PJ *P) { /* sphere */
    struct pj_opaque *Q = P->opaque;
    LP lp = {0.0,0.0};

    /* Check whether (x, y) lies in the rHEALPix image. */
    if (in_image(xy.x, xy.y, 1, Q->north_square, Q->south_square) == 0) {
        lp.lam = HUGE_VAL;
        lp.phi = HUGE_VAL;
        pj_ctx_set_errno(P->ctx, -15);
        return lp;
    }
    xy = combine_caps(xy.x, xy.y, Q->north_square, Q->south_square, 1);
    return healpix_sphere_inverse(xy);
}
示例#11
0
文件: krovak.cpp 项目: OSGeo/proj.4
static PJ_LP krovak_e_inverse (PJ_XY xy, PJ *P) {                /* Ellipsoidal, inverse */
    struct pj_opaque *Q = static_cast<struct pj_opaque*>(P->opaque);
    PJ_LP lp = {0.0,0.0};

    double u, deltav, s, d, eps, rho, fi1, xy0;
    int i;

    xy0 = xy.x;
    xy.x = xy.y;
    xy.y = xy0;

    xy.x *= Q->czech;
    xy.y *= Q->czech;

    rho = sqrt(xy.x * xy.x + xy.y * xy.y);
    eps = atan2(xy.y, xy.x);

    d = eps / sin(S0);
    if( rho == 0.0 ) {
        s = M_PI_2;
    }
    else {
        s = 2. * (atan(  pow(Q->rho0 / rho, 1. / Q->n) * tan(S0 / 2. + M_PI_4)) - M_PI_4);
    }

    u = asin(cos(Q->ad) * sin(s) - sin(Q->ad) * cos(s) * cos(d));
    deltav = asin(cos(s) * sin(d) / cos(u));

    lp.lam = P->lam0 - deltav / Q->alpha;

    /* ITERATION FOR lp.phi */
    fi1 = u;

    for (i = MAX_ITER; i ; --i) {
        lp.phi = 2. * ( atan( pow( Q->k, -1. / Q->alpha)  *
                              pow( tan(u / 2. + M_PI_4) , 1. / Q->alpha)  *
                              pow( (1. + P->e * sin(fi1)) / (1. - P->e * sin(fi1)) , P->e / 2.)
                            )  - M_PI_4);

        if (fabs(fi1 - lp.phi) < EPS)
            break;
        fi1 = lp.phi;
    }
    if( i == 0 )
        pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT );

   lp.lam -= P->lam0;

   return lp;
}
示例#12
0
文件: robin.cpp 项目: QuLogic/proj.4
static PJ_LP s_inverse (PJ_XY xy, PJ *P) {           /* Spheroidal, inverse */
    PJ_LP lp = {0.0,0.0};
    long i;
    double t, t1;
    struct COEFS T;
    int iters;

    lp.lam = xy.x / FXC;
    lp.phi = fabs(xy.y / FYC);
    if (lp.phi >= 1.) { /* simple pathologic cases */
        if (lp.phi > ONEEPS) {
            proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION);
            return lp;
        }
        else {
            lp.phi = xy.y < 0. ? -M_HALFPI : M_HALFPI;
            lp.lam /= X[NODES].c0;
        }
    } else { /* general problem */
        /* in Y space, reduce to table interval */
        i = isnan(lp.phi) ? -1 : lround(floor(lp.phi * NODES));
        if( i < 0 || i >= NODES ) {
            proj_errno_set(P, PJD_ERR_TOLERANCE_CONDITION);
            return lp;
        }
        for (;;) {
            if (Y[i].c0 > lp.phi) --i;
            else if (Y[i+1].c0 <= lp.phi) ++i;
            else break;
        }
        T = Y[i];
        /* first guess, linear interp */
        t = 5. * (lp.phi - T.c0)/(Y[i+1].c0 - T.c0);
        /* make into root */
        T.c0 = (float)(T.c0 - lp.phi);
        for (iters = MAX_ITER; iters ; --iters) { /* Newton-Raphson */
            t -= t1 = V(T,t) / DV(T,t);
            if (fabs(t1) < EPS)
                break;
        }
        if( iters == 0 )
            pj_ctx_set_errno( P->ctx, PJD_ERR_NON_CONVERGENT );
        lp.phi = (5 * i + t) * DEG_TO_RAD;
        if (xy.y < 0.) lp.phi = -lp.phi;
        lp.lam /= V(X[i], t);
    }
    return lp;
}
示例#13
0
static paralist *
get_init(projCtx ctx, paralist **start, paralist *next, char *name) {
    char fname[MAX_PATH_FILENAME+ID_TAG_MAX+3], *opt;
    FILE *fid;
    paralist *init_items = NULL;
    const paralist *orig_next = next;

    (void)strncpy(fname, name, MAX_PATH_FILENAME + ID_TAG_MAX + 1);
	
    /* 
    ** Search for file/key pair in cache 
    */
	
    init_items = pj_search_initcache( name );
    if( init_items != NULL )
    {
        next->next = init_items;
        while( next->next != NULL )
            next = next->next;
        return next;
    }

    /*
    ** Otherwise we try to open the file and search for it.
    */
    if ((opt = strrchr(fname, ':')) != NULL)
        *opt++ = '\0';
    else { pj_ctx_set_errno(ctx,-3); return NULL; }

    if ( (fid = pj_open_lib(ctx,fname, "rt")) != NULL)
        next = get_opt(ctx, start, fid, opt, next);
    else
        return NULL;
    (void)fclose(fid);
    if (errno == 25)
        errno = 0; /* unknown problem with some sys errno<-25 */

    /* 
    ** If we seem to have gotten a result, insert it into the 
    ** init file cache.
    */
    if( next != NULL && next != orig_next )
        pj_insert_initcache( name, orig_next->next );

    return next;
}
示例#14
0
	double
pj_phi2(projCtx ctx, double ts, double e) {
	double eccnth, Phi, con, dphi;
	int i;

	eccnth = .5 * e;
	Phi = HALFPI - 2. * atan (ts);
	i = N_ITER;
	do {
		con = e * sin (Phi);
		dphi = HALFPI - 2. * atan (ts * pow((1. - con) /
		   (1. + con), eccnth)) - Phi;
		Phi += dphi;
	} while ( fabs(dphi) > TOL && --i);
	if (i <= 0)
		pj_ctx_set_errno( ctx, -18 );
	return Phi;
}
示例#15
0
double proj_inv_mdist(projCtx ctx, double dist, const void *b) {
	double s, t, phi, k;
	int i;

	k = 1. / (1. - B->es);
	i = MAX_ITER;
	phi = dist;
	while (i--) {
		s = sin(phi);
		t = 1. - B->es * s * s;
		phi -= t = (proj_mdist(phi, s, cos(phi), b) - dist) * (t * sqrt(t)) * k;
		if (fabs(t) < TOL) /* that is no change */
			return phi;
	}
	/* convergence failed */
	pj_ctx_set_errno(ctx, -17);
	return phi;
}
示例#16
0
static XY e_forward (LP lp, PJ *P) {          /* Ellipsoidal, forward */
    XY xy = {0.0, 0.0};
    struct pj_opaque *Q = P->opaque;
    double al, als, n, cosphi, sinphi, t;

    /*
     * Fail if our longitude is more than 90 degrees from the
     * central meridian since the results are essentially garbage.
     * Is error -20 really an appropriate return value?
     *
     *  http://trac.osgeo.org/proj/ticket/5
     */
    if( lp.lam < -HALFPI || lp.lam > HALFPI ) {
        xy.x = HUGE_VAL;
        xy.y = HUGE_VAL;
        pj_ctx_set_errno( P->ctx, -14 );
        return xy;
    }

    sinphi = sin (lp.phi);
    cosphi = cos (lp.phi);
    t = fabs (cosphi) > 1e-10 ? sinphi/cosphi : 0.;
    t *= t;
    al = cosphi * lp.lam;
    als = al * al;
    al /= sqrt (1. - P->es * sinphi * sinphi);
    n = Q->esp * cosphi * cosphi;
    xy.x = P->k0 * al * (FC1 +
        FC3 * als * (1. - t + n +
        FC5 * als * (5. + t * (t - 18.) + n * (14. - 58. * t)
        + FC7 * als * (61. + t * ( t * (179. - t) - 479. ) )
        )));
    xy.y = P->k0 * (pj_mlfn(lp.phi, sinphi, cosphi, Q->en) - Q->ml0 +
        sinphi * al * lp.lam * FC2 * ( 1. +
        FC4 * als * (5. - t + n * (9. + 4. * n) +
        FC6 * als * (61. + t * (t - 58.) + n * (270. - 330 * t)
        + FC8 * als * (1385. + t * ( t * (543. - t) - 3111.) )
        ))));
    return (xy);
}
示例#17
0
	LP /* inverse projection entry */
pj_inv(XY xy, PJ *P) {
	LP lp;

	/* can't do as much preliminary checking as with forward */
	if (xy.x == HUGE_VAL || xy.y == HUGE_VAL) {
		lp.lam = lp.phi = HUGE_VAL;
		pj_ctx_set_errno( P->ctx, -15);
                return lp;
	}

	errno = pj_errno = 0;
        P->ctx->last_errno = 0;

	xy.x = (xy.x * P->to_meter - P->x0) * P->ra; /* descale and de-offset */
	xy.y = (xy.y * P->to_meter - P->y0) * P->ra;

        //Check for NULL pointer
        if (P->inv != NULL)
        {
	    lp = (*P->inv)(xy, P); /* inverse project */
	    if (P->ctx->last_errno )
		lp.lam = lp.phi = HUGE_VAL;
	    else {
		lp.lam += P->lam0; /* reduce from del lp.lam */
		if (!P->over)
			lp.lam = adjlon(lp.lam); /* adjust longitude to CM */
		if (P->geoc && fabs(fabs(lp.phi)-HALFPI) > EPS)
			lp.phi = atan(P->one_es * tan(lp.phi));
	    }
        }
        else
        {
           lp.lam = lp.phi = HUGE_VAL;
        }
	return lp;
}
示例#18
0
int proj_errno_reset (const PJ *P) {
/******************************************************************************
    Clears errno in the context and thread local levels
    through the low level pj_ctx interface.

    Returns the previous value of the errno, for convenient reset/restore
    operations:

    int foo (PJ *P) {
        // errno may be set on entry, but we need to reset it to be able to
        // check for errors from "do_something_with_P(P)"
        int last_errno = proj_errno_reset (P);

        // local failure
        if (0==P)
            return proj_errno_set (P, 42);

        // call to function that may fail
        do_something_with_P (P);

        // failure in do_something_with_P? - keep latest error status
        if (proj_errno(P))
            return proj_errno (P);

        // success - restore previous error status, return 0
        return proj_errno_restore (P, last_errno);
    }
******************************************************************************/
    int last_errno;
    last_errno = proj_errno (P);

    pj_ctx_set_errno (pj_get_ctx ((PJ *) P), 0);
    errno = 0;
    pj_errno = 0;
    return last_errno;
}
示例#19
0
文件: nad_init.c 项目: aleaf/swb
int nad_ctable_load( projCtx ctx, struct CTABLE *ct, FILE *fid )

{
    int  a_size;

    fseek( fid, sizeof(struct CTABLE), SEEK_SET );

    /* read all the actual shift values */
    a_size = ct->lim.lam * ct->lim.phi;
    ct->cvs = (FLP *) pj_malloc(sizeof(FLP) * a_size);
    if( ct->cvs == NULL 
        || fread(ct->cvs, sizeof(FLP), a_size, fid) != a_size )
    {
        pj_dalloc( ct->cvs );
        ct->cvs = NULL;

        pj_log( ctx, PJ_LOG_ERROR, 
                "ctable loading failed on fread() - binary incompatible?\n" );
        pj_ctx_set_errno( ctx, -38 );
        return 0;
    }

    return 1;
} 
示例#20
0
static int pj_gridinfo_init_ntv1( projCtx ctx, PAFile fid, PJ_GRIDINFO *gi )

{
    unsigned char header[176];
    struct CTABLE *ct;
    LP		ur;

    assert( sizeof(int) == 4 );
    assert( sizeof(double) == 8 );
    if( sizeof(int) != 4 || sizeof(double) != 8 )
    {
        pj_log( ctx, PJ_LOG_ERROR,
                 "basic types of inappropraiate size in nad_load_ntv1()" );
        pj_ctx_set_errno( ctx, -38 );
        return 0;
    }

/* -------------------------------------------------------------------- */
/*      Read the header.                                                */
/* -------------------------------------------------------------------- */
    if( pj_ctx_fread( ctx, header, sizeof(header), 1, fid ) != 1 )
    {
        pj_ctx_set_errno( ctx, -38 );
        return 0;
    }

/* -------------------------------------------------------------------- */
/*      Regularize fields of interest.                                  */
/* -------------------------------------------------------------------- */
    if( IS_LSB )
    {
        swap_words( header+8, 4, 1 );
        swap_words( header+24, 8, 1 );
        swap_words( header+40, 8, 1 );
        swap_words( header+56, 8, 1 );
        swap_words( header+72, 8, 1 );
        swap_words( header+88, 8, 1 );
        swap_words( header+104, 8, 1 );
    }

    if( *((int *) (header+8)) != 12 )
    {
        pj_log( ctx, PJ_LOG_ERROR,
                "NTv1 grid shift file has wrong record count, corrupt?" );
        pj_ctx_set_errno( ctx, -38 );
        return 0;
    }

/* -------------------------------------------------------------------- */
/*      Fill in CTABLE structure.                                       */
/* -------------------------------------------------------------------- */
    ct = (struct CTABLE *) pj_malloc(sizeof(struct CTABLE));
    strcpy( ct->id, "NTv1 Grid Shift File" );

    ct->ll.lam = - *((double *) (header+72));
    ct->ll.phi = *((double *) (header+24));
    ur.lam = - *((double *) (header+56));
    ur.phi = *((double *) (header+40));
    ct->del.lam = *((double *) (header+104));
    ct->del.phi = *((double *) (header+88));
    ct->lim.lam = (int) (fabs(ur.lam-ct->ll.lam)/ct->del.lam + 0.5) + 1;
    ct->lim.phi = (int) (fabs(ur.phi-ct->ll.phi)/ct->del.phi + 0.5) + 1;

    pj_log( ctx, PJ_LOG_DEBUG_MINOR,
            "NTv1 %dx%d: LL=(%.9g,%.9g) UR=(%.9g,%.9g)",
            ct->lim.lam, ct->lim.phi,
            ct->ll.lam, ct->ll.phi, ur.lam, ur.phi );

    ct->ll.lam *= DEG_TO_RAD;
    ct->ll.phi *= DEG_TO_RAD;
    ct->del.lam *= DEG_TO_RAD;
    ct->del.phi *= DEG_TO_RAD;
    ct->cvs = NULL;

    gi->ct = ct;
    gi->grid_offset = pj_ctx_ftell( ctx, fid );
    gi->format = "ntv1";

    return 1;
}
示例#21
0
	double
dmstor_ctx(projCtx ctx, const char *is, char **rs) {
	int sign, n, nl;
	char *s, work[MAX_WORK];
        const char* p;
	double v, tv;

	if (rs)
		*rs = (char *)is;
	/* copy sting into work space */
	while (isspace(sign = *is)) ++is;
	n = MAX_WORK;
	s = work;
	p = (char *)is;
	while (isgraph(*p) && --n)
		*s++ = *p++;
	*s = '\0';
	/* it is possible that a really odd input (like lots of leading
		zeros) could be truncated in copying into work.  But ... */
	sign = *(s = work);
	if (sign == '+' || sign == '-') s++;
	else sign = '+';
	v = 0.;
	for (nl = 0 ; nl < 3 ; nl = n + 1 ) {
		if (!(isdigit(*s) || *s == '.')) break;
		if ((tv = proj_strtod(s, &s)) == HUGE_VAL)
			return tv;
		switch (*s) {
		case 'D': case 'd':
			n = 0; break;
		case '\'':
			n = 1; break;
		case '"':
			n = 2; break;
		case 'r': case 'R':
			if (nl) {
				pj_ctx_set_errno( ctx, PJD_ERR_WRONG_FORMAT_DMS_VALUE );
				return HUGE_VAL;
			}
			++s;
			v = tv;
			goto skip;
		default:
			v += tv * vm[nl];
		skip:	n = 4;
			continue;
		}
		if (n < nl) {
			pj_ctx_set_errno( ctx, PJD_ERR_WRONG_FORMAT_DMS_VALUE );
			return HUGE_VAL;
		}
		v += tv * vm[n];
		++s;
	}
		/* postfix sign */
	if (*s && (p = strchr(sym, *s))) {
		sign = (p - sym) >= 4 ? '-' : '+';
		++s;
	}
	if (sign == '-')
		v = -v;
	if (rs) /* return point of next char after valid string */
		*rs = (char *)is + (s - work);
	return v;
}
示例#22
0
PJ_GRIDINFO *pj_gridinfo_init( projCtx ctx, const char *gridname )

{
    char 	fname[MAX_PATH_FILENAME+1];
    PJ_GRIDINFO *gilist;
    PAFile 	fp;
    char	header[160];
    size_t      header_size = 0;

    errno = pj_errno = 0;
    ctx->last_errno = 0;

/* -------------------------------------------------------------------- */
/*      Initialize a GRIDINFO with stub info we would use if it         */
/*      cannot be loaded.                                               */
/* -------------------------------------------------------------------- */
    gilist = (PJ_GRIDINFO *) pj_calloc(1, sizeof(PJ_GRIDINFO));
    if (!gilist) {
        pj_ctx_set_errno(ctx, ENOMEM);
        return NULL;
    }

    gilist->gridname = pj_strdup( gridname );
    if (!gilist->gridname) {
        pj_dalloc(gilist);
        pj_ctx_set_errno(ctx, ENOMEM);
        return NULL;
    }
    gilist->filename = NULL;
    gilist->format = "missing";
    gilist->grid_offset = 0;
    gilist->ct = NULL;
    gilist->next = NULL;

/* -------------------------------------------------------------------- */
/*      Open the file using the usual search rules.                     */
/* -------------------------------------------------------------------- */
    strcpy(fname, gridname);
    if (!(fp = pj_open_lib(ctx, fname, "rb"))) {
        ctx->last_errno = 0; /* don't treat as a persistent error */
        return gilist;
    }

    gilist->filename = pj_strdup(fname);
    if (!gilist->filename) {
        pj_dalloc(gilist->gridname);
        pj_dalloc(gilist);
        pj_ctx_set_errno(ctx, ENOMEM);
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Load a header, to determine the file type.                      */
/* -------------------------------------------------------------------- */
    if( (header_size = pj_ctx_fread( ctx, header, 1,
                                     sizeof(header), fp ) ) != sizeof(header) )
    {
        /* some files may be smaller that sizeof(header), eg 160, so */
        ctx->last_errno = 0; /* don't treat as a persistent error */
        pj_log( ctx, PJ_LOG_DEBUG_MAJOR,
                "pj_gridinfo_init: short header read of %d bytes",
                (int)header_size );
    }

    pj_ctx_fseek( ctx, fp, SEEK_SET, 0 );

/* -------------------------------------------------------------------- */
/*      Determine file type.                                            */
/* -------------------------------------------------------------------- */
    if( header_size >= 144 + 16
        && strncmp(header + 0, "HEADER", 6) == 0
        && strncmp(header + 96, "W GRID", 6) == 0
        && strncmp(header + 144, "TO      NAD83   ", 16) == 0 )
    {
        pj_gridinfo_init_ntv1( ctx, fp, gilist );
    }

    else if( header_size >= 48 + 7
             && strncmp(header + 0, "NUM_OREC", 8) == 0
             && strncmp(header + 48, "GS_TYPE", 7) == 0 )
    {
        pj_gridinfo_init_ntv2( ctx, fp, gilist );
    }

    else if( strlen(gridname) > 4
             && (strcmp(gridname+strlen(gridname)-3,"gtx") == 0
                 || strcmp(gridname+strlen(gridname)-3,"GTX") == 0) )
    {
        pj_gridinfo_init_gtx( ctx, fp, gilist );
    }

    else if( header_size >= 9 && strncmp(header + 0,"CTABLE V2",9) == 0 )
    {
        struct CTABLE *ct = nad_ctable2_init( ctx, fp );

        gilist->format = "ctable2";
        gilist->ct = ct;

        if (ct == NULL)
        {
            pj_log( ctx, PJ_LOG_DEBUG_MAJOR,
                    "CTABLE V2 ct is NULL.");
        }
        else
        {
            pj_log( ctx, PJ_LOG_DEBUG_MAJOR,
                    "Ctable2 %s %dx%d: LL=(%.9g,%.9g) UR=(%.9g,%.9g)",
                    ct->id,
                    ct->lim.lam, ct->lim.phi,
                    ct->ll.lam * RAD_TO_DEG, ct->ll.phi * RAD_TO_DEG,
                    (ct->ll.lam + (ct->lim.lam-1)*ct->del.lam) * RAD_TO_DEG,
                    (ct->ll.phi + (ct->lim.phi-1)*ct->del.phi) * RAD_TO_DEG );
        }
    }

    else
    {
        struct CTABLE *ct = nad_ctable_init( ctx, fp );
        if (ct == NULL)
        {
            pj_log( ctx, PJ_LOG_DEBUG_MAJOR,
                    "CTABLE ct is NULL.");
        } else
        {
            gilist->format = "ctable";
            gilist->ct = ct;

            pj_log( ctx, PJ_LOG_DEBUG_MAJOR,
                    "Ctable %s %dx%d: LL=(%.9g,%.9g) UR=(%.9g,%.9g)",
                    ct->id,
                    ct->lim.lam, ct->lim.phi,
                    ct->ll.lam * RAD_TO_DEG, ct->ll.phi * RAD_TO_DEG,
                    (ct->ll.lam + (ct->lim.lam-1)*ct->del.lam) * RAD_TO_DEG,
                    (ct->ll.phi + (ct->lim.phi-1)*ct->del.phi) * RAD_TO_DEG );
        }
    }

    pj_ctx_fclose(ctx, fp);

    return gilist;
}
示例#23
0
static int pj_gridinfo_init_gtx( projCtx ctx, PAFile fid, PJ_GRIDINFO *gi )

{
    unsigned char header[40];
    struct CTABLE *ct;
    double      xorigin,yorigin,xstep,ystep;
    int         rows, columns;

    /* cppcheck-suppress sizeofCalculation */
    STATIC_ASSERT( sizeof(pj_int32) == 4 );
    /* cppcheck-suppress sizeofCalculation */
    STATIC_ASSERT( sizeof(double) == 8 );

/* -------------------------------------------------------------------- */
/*      Read the header.                                                */
/* -------------------------------------------------------------------- */
    if( pj_ctx_fread( ctx, header, sizeof(header), 1, fid ) != 1 )
    {
        pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
        return 0;
    }

/* -------------------------------------------------------------------- */
/*      Regularize fields of interest and extract.                      */
/* -------------------------------------------------------------------- */
    if( IS_LSB )
    {
        swap_words( header+0, 8, 4 );
        swap_words( header+32, 4, 2 );
    }

    memcpy( &yorigin, header+0, 8 );
    memcpy( &xorigin, header+8, 8 );
    memcpy( &ystep, header+16, 8 );
    memcpy( &xstep, header+24, 8 );

    memcpy( &rows, header+32, 4 );
    memcpy( &columns, header+36, 4 );

    if( xorigin < -360 || xorigin > 360
        || yorigin < -90 || yorigin > 90 )
    {
        pj_log( ctx, PJ_LOG_ERROR,
                "gtx file header has invalid extents, corrupt?");
        pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
        return 0;
    }

/* -------------------------------------------------------------------- */
/*      Fill in CTABLE structure.                                       */
/* -------------------------------------------------------------------- */
    ct = (struct CTABLE *) pj_malloc(sizeof(struct CTABLE));
    if (!ct) {
        pj_ctx_set_errno(ctx, ENOMEM);
        return 0;
    }
    strcpy( ct->id, "GTX Vertical Grid Shift File" );

    ct->ll.lam = xorigin;
    ct->ll.phi = yorigin;
    ct->del.lam = xstep;
    ct->del.phi = ystep;
    ct->lim.lam = columns;
    ct->lim.phi = rows;

    /* some GTX files come in 0-360 and we shift them back into the
       expected -180 to 180 range if possible.  This does not solve
       problems with grids spanning the dateline. */
    if( ct->ll.lam >= 180.0 )
        ct->ll.lam -= 360.0;

    if( ct->ll.lam >= 0.0 && ct->ll.lam + ct->del.lam * ct->lim.lam > 180.0 )
    {
        pj_log( ctx, PJ_LOG_DEBUG_MAJOR,
                "This GTX spans the dateline!  This will cause problems." );
    }

    pj_log( ctx, PJ_LOG_DEBUG_MINOR,
            "GTX %dx%d: LL=(%.9g,%.9g) UR=(%.9g,%.9g)",
            ct->lim.lam, ct->lim.phi,
            ct->ll.lam, ct->ll.phi,
            ct->ll.lam + (columns-1)*xstep, ct->ll.phi + (rows-1)*ystep);

    ct->ll.lam *= DEG_TO_RAD;
    ct->ll.phi *= DEG_TO_RAD;
    ct->del.lam *= DEG_TO_RAD;
    ct->del.phi *= DEG_TO_RAD;
    ct->cvs = NULL;

    gi->ct = ct;
    gi->grid_offset = 40;
    gi->format = "gtx";

    return 1;
}
示例#24
0
static int pj_gridinfo_init_ntv1( projCtx ctx, PAFile fid, PJ_GRIDINFO *gi )

{
    unsigned char header[176];
    struct CTABLE *ct;
    LP		ur;

    /* cppcheck-suppress sizeofCalculation */
    STATIC_ASSERT( sizeof(pj_int32) == 4 );
    /* cppcheck-suppress sizeofCalculation */
    STATIC_ASSERT( sizeof(double) == 8 );

/* -------------------------------------------------------------------- */
/*      Read the header.                                                */
/* -------------------------------------------------------------------- */
    if( pj_ctx_fread( ctx, header, sizeof(header), 1, fid ) != 1 )
    {
        pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
        return 0;
    }

/* -------------------------------------------------------------------- */
/*      Regularize fields of interest.                                  */
/* -------------------------------------------------------------------- */
    if( IS_LSB )
    {
        swap_words( header+8, 4, 1 );
        swap_words( header+24, 8, 1 );
        swap_words( header+40, 8, 1 );
        swap_words( header+56, 8, 1 );
        swap_words( header+72, 8, 1 );
        swap_words( header+88, 8, 1 );
        swap_words( header+104, 8, 1 );
    }

    if( *((int *) (header+8)) != 12 )
    {
        pj_log( ctx, PJ_LOG_ERROR,
                "NTv1 grid shift file has wrong record count, corrupt?" );
        pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
        return 0;
    }

/* -------------------------------------------------------------------- */
/*      Fill in CTABLE structure.                                       */
/* -------------------------------------------------------------------- */
    ct = (struct CTABLE *) pj_malloc(sizeof(struct CTABLE));
    if (!ct) {
        pj_ctx_set_errno(ctx, ENOMEM);
        return 0;
    }
    strcpy( ct->id, "NTv1 Grid Shift File" );

    ct->ll.lam = - to_double(header+72);
    ct->ll.phi = to_double(header+24);
    ur.lam = - to_double(header+56);
    ur.phi = to_double(header+40);
    ct->del.lam = to_double(header+104);
    ct->del.phi = to_double(header+88);
    ct->lim.lam = (pj_int32) (fabs(ur.lam-ct->ll.lam)/ct->del.lam + 0.5) + 1;
    ct->lim.phi = (pj_int32) (fabs(ur.phi-ct->ll.phi)/ct->del.phi + 0.5) + 1;

    pj_log( ctx, PJ_LOG_DEBUG_MINOR,
            "NTv1 %dx%d: LL=(%.9g,%.9g) UR=(%.9g,%.9g)",
            ct->lim.lam, ct->lim.phi,
            ct->ll.lam, ct->ll.phi, ur.lam, ur.phi );

    ct->ll.lam *= DEG_TO_RAD;
    ct->ll.phi *= DEG_TO_RAD;
    ct->del.lam *= DEG_TO_RAD;
    ct->del.phi *= DEG_TO_RAD;
    ct->cvs = NULL;

    gi->ct = ct;
    gi->grid_offset = pj_ctx_ftell( ctx, fid );
    gi->format = "ntv1";

    return 1;
}
示例#25
0
static int pj_gridinfo_init_ntv2( projCtx ctx, PAFile fid, PJ_GRIDINFO *gilist )
{
    unsigned char header[11*16];
    int num_subfiles, subfile;
    int must_swap;

    /* cppcheck-suppress sizeofCalculation */
    STATIC_ASSERT( sizeof(pj_int32) == 4 );
    /* cppcheck-suppress sizeofCalculation */
    STATIC_ASSERT( sizeof(double) == 8 );

/* -------------------------------------------------------------------- */
/*      Read the overview header.                                       */
/* -------------------------------------------------------------------- */
    if( pj_ctx_fread( ctx, header, sizeof(header), 1, fid ) != 1 )
    {
        pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
        return 0;
    }

    if( header[8] == 11 )
        must_swap = !IS_LSB;
    else
        must_swap = IS_LSB;

/* -------------------------------------------------------------------- */
/*      Byte swap interesting fields if needed.                         */
/* -------------------------------------------------------------------- */
    if( must_swap )
    {
        swap_words( header+8, 4, 1 );
        swap_words( header+8+16, 4, 1 );
        swap_words( header+8+32, 4, 1 );
        swap_words( header+8+7*16, 8, 1 );
        swap_words( header+8+8*16, 8, 1 );
        swap_words( header+8+9*16, 8, 1 );
        swap_words( header+8+10*16, 8, 1 );
    }

/* -------------------------------------------------------------------- */
/*      Get the subfile count out ... all we really use for now.        */
/* -------------------------------------------------------------------- */
    memcpy( &num_subfiles, header+8+32, 4 );

/* ==================================================================== */
/*      Step through the subfiles, creating a PJ_GRIDINFO for each.     */
/* ==================================================================== */
    for( subfile = 0; subfile < num_subfiles; subfile++ )
    {
        struct CTABLE *ct;
        LP ur;
        int gs_count;
        PJ_GRIDINFO *gi;

/* -------------------------------------------------------------------- */
/*      Read header.                                                    */
/* -------------------------------------------------------------------- */
        if( pj_ctx_fread( ctx, header, sizeof(header), 1, fid ) != 1 )
        {
            pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
            return 0;
        }

        if( strncmp((const char *) header,"SUB_NAME",8) != 0 )
        {
            pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
            return 0;
        }

/* -------------------------------------------------------------------- */
/*      Byte swap interesting fields if needed.                         */
/* -------------------------------------------------------------------- */
        if( must_swap )
        {
            swap_words( header+8+16*4, 8, 1 );
            swap_words( header+8+16*5, 8, 1 );
            swap_words( header+8+16*6, 8, 1 );
            swap_words( header+8+16*7, 8, 1 );
            swap_words( header+8+16*8, 8, 1 );
            swap_words( header+8+16*9, 8, 1 );
            swap_words( header+8+16*10, 4, 1 );
        }

/* -------------------------------------------------------------------- */
/*      Initialize a corresponding "ct" structure.                      */
/* -------------------------------------------------------------------- */
        ct = (struct CTABLE *) pj_malloc(sizeof(struct CTABLE));
        if (!ct) {
            pj_ctx_set_errno(ctx, ENOMEM);
            return 0;
        }
        strncpy( ct->id, (const char *) header + 8, 8 );
        ct->id[8] = '\0';

        ct->ll.lam = - to_double(header+7*16+8); /* W_LONG */
        ct->ll.phi = to_double(header+4*16+8);   /* S_LAT */

        ur.lam = - to_double(header+6*16+8);     /* E_LONG */
        ur.phi = to_double(header+5*16+8);       /* N_LAT */

        ct->del.lam = to_double(header+9*16+8);
        ct->del.phi = to_double(header+8*16+8);

        ct->lim.lam = (pj_int32) (fabs(ur.lam-ct->ll.lam)/ct->del.lam + 0.5) + 1;
        ct->lim.phi = (pj_int32) (fabs(ur.phi-ct->ll.phi)/ct->del.phi + 0.5) + 1;

        pj_log( ctx, PJ_LOG_DEBUG_MINOR,
                "NTv2 %s %dx%d: LL=(%.9g,%.9g) UR=(%.9g,%.9g)",
                ct->id,
                ct->lim.lam, ct->lim.phi,
                ct->ll.lam/3600.0, ct->ll.phi/3600.0,
                ur.lam/3600.0, ur.phi/3600.0 );

        ct->ll.lam *= DEG_TO_RAD/3600.0;
        ct->ll.phi *= DEG_TO_RAD/3600.0;
        ct->del.lam *= DEG_TO_RAD/3600.0;
        ct->del.phi *= DEG_TO_RAD/3600.0;

        memcpy( &gs_count, header + 8 + 16*10, 4 );
        if( gs_count != ct->lim.lam * ct->lim.phi )
        {
            pj_log( ctx, PJ_LOG_ERROR,
                    "GS_COUNT(%d) does not match expected cells (%dx%d=%d)",
                    gs_count, ct->lim.lam, ct->lim.phi,
                    ct->lim.lam * ct->lim.phi );
            pj_dalloc(ct);
            pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
            return 0;
        }

        ct->cvs = NULL;

/* -------------------------------------------------------------------- */
/*      Create a new gridinfo for this if we aren't processing the      */
/*      1st subfile, and initialize our grid info.                      */
/* -------------------------------------------------------------------- */
        if( subfile == 0 )
            gi = gilist;
        else
        {
            gi = (PJ_GRIDINFO *) pj_calloc(1, sizeof(PJ_GRIDINFO));
            if (!gi) {
                pj_dalloc(ct);
                pj_gridinfo_free(ctx, gilist);
                pj_ctx_set_errno(ctx, ENOMEM);
                return 0;
            }

            gi->gridname = pj_strdup( gilist->gridname );
            gi->filename = pj_strdup( gilist->filename );
            if (!gi->gridname || !gi->filename) {
                pj_gridinfo_free(ctx, gi);
                pj_dalloc(ct);
                pj_gridinfo_free(ctx, gilist);
                pj_ctx_set_errno(ctx, ENOMEM);
                return 0;
            }
            gi->next = NULL;
        }

        gi->must_swap = must_swap;
        gi->ct = ct;
        gi->format = "ntv2";
        gi->grid_offset = pj_ctx_ftell( ctx, fid );

/* -------------------------------------------------------------------- */
/*      Attach to the correct list or sublist.                          */
/* -------------------------------------------------------------------- */
        if( strncmp((const char *)header+24,"NONE",4) == 0 )
        {
            if( gi != gilist )
            {
                PJ_GRIDINFO *lnk;

                for( lnk = gilist; lnk->next != NULL; lnk = lnk->next ) {}
                lnk->next = gi;
            }
        }

        else
        {
            PJ_GRIDINFO *lnk;
            PJ_GRIDINFO *gp = gridinfo_parent(gilist,
                                                 (const char*)header+24,8);

            if( gp == NULL )
            {
                pj_log( ctx, PJ_LOG_ERROR,
                        "pj_gridinfo_init_ntv2(): "
                        "failed to find parent %8.8s for %s.",
                        (const char *) header+24, gi->ct->id );

                for( lnk = gilist; lnk->next != NULL; lnk = lnk->next ) {}
                lnk->next = gi;
            }
            else
            {
                if( gp->child == NULL )
                {
                    gp->child = gi;
                }
                else
                {
                    for( lnk = gp->child; lnk->next != NULL; lnk = lnk->next ) {}
                    lnk->next = gi;
                }
            }
        }

/* -------------------------------------------------------------------- */
/*      Seek past the data.                                             */
/* -------------------------------------------------------------------- */
        pj_ctx_fseek( ctx, fid, gs_count * 16, SEEK_CUR );
    }

    return 1;
}
示例#26
0
int pj_gridinfo_load( projCtx ctx, PJ_GRIDINFO *gi )

{
    struct CTABLE ct_tmp;

    if( gi == NULL || gi->ct == NULL )
        return 0;

    pj_acquire_lock();
    if( gi->ct->cvs != NULL )
    {
        pj_release_lock();
        return 1;
    }

    memcpy(&ct_tmp, gi->ct, sizeof(struct CTABLE));

/* -------------------------------------------------------------------- */
/*      Original platform specific CTable format.                       */
/* -------------------------------------------------------------------- */
    if( strcmp(gi->format,"ctable") == 0 )
    {
        PAFile fid;
        int result;

        fid = pj_open_lib( ctx, gi->filename, "rb" );

        if( fid == NULL )
        {
            pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
            pj_release_lock();
            return 0;
        }

        result = nad_ctable_load( ctx, &ct_tmp, fid );

        pj_ctx_fclose( ctx, fid );

        gi->ct->cvs = ct_tmp.cvs;
        pj_release_lock();

        return result;
    }

/* -------------------------------------------------------------------- */
/*      CTable2 format.                                                 */
/* -------------------------------------------------------------------- */
    else if( strcmp(gi->format,"ctable2") == 0 )
    {
        PAFile fid;
        int result;

        fid = pj_open_lib( ctx, gi->filename, "rb" );

        if( fid == NULL )
        {
            pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
            pj_release_lock();
            return 0;
        }

        result = nad_ctable2_load( ctx, &ct_tmp, fid );

        pj_ctx_fclose( ctx, fid );

        gi->ct->cvs = ct_tmp.cvs;

        pj_release_lock();
        return result;
    }

/* -------------------------------------------------------------------- */
/*      NTv1 format.                                                    */
/*      We process one line at a time.  Note that the array storage     */
/*      direction (e-w) is different in the NTv1 file and what          */
/*      the CTABLE is supposed to have.  The phi/lam are also           */
/*      reversed, and we have to be aware of byte swapping.             */
/* -------------------------------------------------------------------- */
    else if( strcmp(gi->format,"ntv1") == 0 )
    {
        double	*row_buf;
        int	row;
        PAFile fid;

        fid = pj_open_lib( ctx, gi->filename, "rb" );

        if( fid == NULL )
        {
            pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
            pj_release_lock();
            return 0;
        }

        pj_ctx_fseek( ctx, fid, gi->grid_offset, SEEK_SET );

        row_buf = (double *) pj_malloc(gi->ct->lim.lam * sizeof(double) * 2);
        ct_tmp.cvs = (FLP *) pj_malloc(gi->ct->lim.lam*gi->ct->lim.phi*sizeof(FLP));
        if( row_buf == NULL || ct_tmp.cvs == NULL )
        {
            pj_dalloc( row_buf );
            pj_dalloc( ct_tmp.cvs );
            pj_ctx_set_errno( ctx, ENOMEM );
            pj_release_lock();
            return 0;
        }

        for( row = 0; row < gi->ct->lim.phi; row++ )
        {
            int	    i;
            FLP     *cvs;
            double  *diff_seconds;

            if( pj_ctx_fread( ctx, row_buf,
                              sizeof(double), gi->ct->lim.lam * 2, fid )
                != (size_t)( 2 * gi->ct->lim.lam ) )
            {
                pj_dalloc( row_buf );
                pj_dalloc( ct_tmp.cvs );
                pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
                pj_release_lock();
                return 0;
            }

            if( IS_LSB )
                swap_words( (unsigned char *) row_buf, 8, gi->ct->lim.lam*2 );

            /* convert seconds to radians */
            diff_seconds = row_buf;

            for( i = 0; i < gi->ct->lim.lam; i++ )
            {
                cvs = ct_tmp.cvs + (row) * gi->ct->lim.lam
                    + (gi->ct->lim.lam - i - 1);

                cvs->phi = (float) (*(diff_seconds++) * ((M_PI/180.0) / 3600.0));
                cvs->lam = (float) (*(diff_seconds++) * ((M_PI/180.0) / 3600.0));
            }
        }

        pj_dalloc( row_buf );

        pj_ctx_fclose( ctx, fid );

        gi->ct->cvs = ct_tmp.cvs;
        pj_release_lock();

        return 1;
    }

/* -------------------------------------------------------------------- */
/*      NTv2 format.                                                    */
/*      We process one line at a time.  Note that the array storage     */
/*      direction (e-w) is different in the NTv2 file and what          */
/*      the CTABLE is supposed to have.  The phi/lam are also           */
/*      reversed, and we have to be aware of byte swapping.             */
/* -------------------------------------------------------------------- */
    else if( strcmp(gi->format,"ntv2") == 0 )
    {
        float	*row_buf;
        int	row;
        PAFile fid;

        pj_log( ctx, PJ_LOG_DEBUG_MINOR,
                "NTv2 - loading grid %s", gi->ct->id );

        fid = pj_open_lib( ctx, gi->filename, "rb" );

        if( fid == NULL )
        {
            pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
            pj_release_lock();
            return 0;
        }

        pj_ctx_fseek( ctx, fid, gi->grid_offset, SEEK_SET );

        row_buf = (float *) pj_malloc(gi->ct->lim.lam * sizeof(float) * 4);
        ct_tmp.cvs = (FLP *) pj_malloc(gi->ct->lim.lam*gi->ct->lim.phi*sizeof(FLP));
        if( row_buf == NULL || ct_tmp.cvs == NULL )
        {
            pj_dalloc( row_buf );
            pj_dalloc( ct_tmp.cvs );
            pj_ctx_set_errno( ctx, ENOMEM );
            pj_release_lock();
            return 0;
        }

        for( row = 0; row < gi->ct->lim.phi; row++ )
        {
            int	    i;
            FLP     *cvs;
            float   *diff_seconds;

            if( pj_ctx_fread( ctx, row_buf, sizeof(float),
                              gi->ct->lim.lam*4, fid )
                != (size_t)( 4 * gi->ct->lim.lam ) )
            {
                pj_dalloc( row_buf );
                pj_dalloc( ct_tmp.cvs );
                pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
                pj_release_lock();
                return 0;
            }

            if( gi->must_swap )
                swap_words( (unsigned char *) row_buf, 4,
                            gi->ct->lim.lam*4 );

            /* convert seconds to radians */
            diff_seconds = row_buf;

            for( i = 0; i < gi->ct->lim.lam; i++ )
            {
                cvs = ct_tmp.cvs + (row) * gi->ct->lim.lam
                    + (gi->ct->lim.lam - i - 1);

                cvs->phi = (float) (*(diff_seconds++) * ((M_PI/180.0) / 3600.0));
                cvs->lam = (float) (*(diff_seconds++) * ((M_PI/180.0) / 3600.0));
                diff_seconds += 2; /* skip accuracy values */
            }
        }

        pj_dalloc( row_buf );

        pj_ctx_fclose( ctx, fid );

        gi->ct->cvs = ct_tmp.cvs;

        pj_release_lock();
        return 1;
    }

/* -------------------------------------------------------------------- */
/*      GTX format.                                                     */
/* -------------------------------------------------------------------- */
    else if( strcmp(gi->format,"gtx") == 0 )
    {
        int   words = gi->ct->lim.lam * gi->ct->lim.phi;
        PAFile fid;

        fid = pj_open_lib( ctx, gi->filename, "rb" );

        if( fid == NULL )
        {
            pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
            pj_release_lock();
            return 0;
        }

        pj_ctx_fseek( ctx, fid, gi->grid_offset, SEEK_SET );

        ct_tmp.cvs = (FLP *) pj_malloc(words*sizeof(float));
        if( ct_tmp.cvs == NULL )
        {
            pj_ctx_set_errno( ctx, ENOMEM );
            pj_release_lock();
            return 0;
        }

        if( pj_ctx_fread( ctx, ct_tmp.cvs, sizeof(float), words, fid )
            != (size_t)words )
        {
            pj_dalloc( ct_tmp.cvs );
            pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID );
            pj_release_lock();
            return 0;
        }

        if( IS_LSB )
            swap_words( (unsigned char *) ct_tmp.cvs, 4, words );

        pj_ctx_fclose( ctx, fid );
        gi->ct->cvs = ct_tmp.cvs;
        pj_release_lock();
        return 1;
    }

    else
    {
        pj_release_lock();
        return 0;
    }
}
示例#27
0
int pj_datum_set(projCtx ctx, paralist *pl, PJ *projdef)

{
    const char *name, *towgs84, *nadgrids, *catalog;

    projdef->datum_type = PJD_UNKNOWN;

/* -------------------------------------------------------------------- */
/*      Is there a datum definition in the parameters list?  If so,     */
/*      add the defining values to the parameter list.  Note that       */
/*      this will append the ellipse definition as well as the          */
/*      towgs84= and related parameters.  It should also be pointed     */
/*      out that the addition is permanent rather than temporary        */
/*      like most other keyword expansion so that the ellipse           */
/*      definition will last into the pj_ell_set() function called      */
/*      after this one.                                                 */
/* -------------------------------------------------------------------- */
    if( (name = pj_param(ctx, pl,"sdatum").s) != NULL )
    {
        paralist *curr;
        const char *s;
        int i;

        /* find the end of the list, so we can add to it */
        for (curr = pl; curr && curr->next ; curr = curr->next) {}
        
        /* find the datum definition */
        for (i = 0; (s = pj_datums[i].id) && strcmp(name, s) ; ++i) {}

        if (!s) { pj_ctx_set_errno(ctx, -9); return 1; }

        if( pj_datums[i].ellipse_id && strlen(pj_datums[i].ellipse_id) > 0 )
        {
            char	entry[100];
            
            strcpy( entry, "ellps=" );
            strncat( entry, pj_datums[i].ellipse_id, 80 );
            curr = curr->next = pj_mkparam(entry);
        }
        
        if( pj_datums[i].defn && strlen(pj_datums[i].defn) > 0 )
            curr = curr->next = pj_mkparam(pj_datums[i].defn);
    }

/* -------------------------------------------------------------------- */
/*      Check for nadgrids parameter.                                   */
/* -------------------------------------------------------------------- */
    if( (nadgrids = pj_param(ctx, pl,"snadgrids").s) != NULL )
    {
        /* We don't actually save the value separately.  It will continue
           to exist int he param list for use in pj_apply_gridshift.c */

        projdef->datum_type = PJD_GRIDSHIFT;
    }

/* -------------------------------------------------------------------- */
/*      Check for grid catalog parameter, and optional date.            */
/* -------------------------------------------------------------------- */
    else if( (catalog = pj_param(ctx, pl,"scatalog").s) != NULL )
    {
        const char *date;

        projdef->datum_type = PJD_GRIDSHIFT;
        projdef->catalog_name = strdup(catalog);

        date = pj_param(ctx, pl, "sdate").s;
        if( date != NULL) 
            projdef->datum_date = pj_gc_parsedate( ctx, date);
    }

/* -------------------------------------------------------------------- */
/*      Check for towgs84 parameter.                                    */
/* -------------------------------------------------------------------- */
    else if( (towgs84 = pj_param(ctx, pl,"stowgs84").s) != NULL )
    {
        int    parm_count = 0;
        const char *s;

        memset( projdef->datum_params, 0, sizeof(double) * 7);

        /* parse out the parameters */
        s = towgs84;
        for( s = towgs84; *s != '\0' && parm_count < 7; ) 
        {
            projdef->datum_params[parm_count++] = atof(s);
            while( *s != '\0' && *s != ',' )
                s++;
            if( *s == ',' )
                s++;
        }

        if( projdef->datum_params[3] != 0.0 
            || projdef->datum_params[4] != 0.0 
            || projdef->datum_params[5] != 0.0 
            || projdef->datum_params[6] != 0.0 )
        {
            projdef->datum_type = PJD_7PARAM;

            /* transform from arc seconds to radians */
            projdef->datum_params[3] *= SEC_TO_RAD;
            projdef->datum_params[4] *= SEC_TO_RAD;
            projdef->datum_params[5] *= SEC_TO_RAD;
            /* transform from parts per million to scaling factor */
            projdef->datum_params[6] = 
                (projdef->datum_params[6]/1000000.0) + 1;
        }
        else 
            projdef->datum_type = PJD_3PARAM;

        /* Note that pj_init() will later switch datum_type to 
           PJD_WGS84 if shifts are all zero, and ellipsoid is WGS84 or GRS80 */
    }

    return 0;
}
示例#28
0
文件: nad_init.c 项目: aleaf/swb
struct CTABLE *nad_ctable2_init( projCtx ctx, FILE * fid )
{
    struct CTABLE *ct;
    int		id_end;
    char        header[160];

    if( fread( header, sizeof(header), 1, fid ) != 1 )
    {
        pj_ctx_set_errno( ctx, -38 );
        return NULL;
    }

    if( !IS_LSB )
    {
        swap_words( header +  96, 8, 4 );
        swap_words( header + 128, 4, 2 );
    }

    if( strncmp(header,"CTABLE V2",9) != 0 )
    {
        pj_log( ctx, PJ_LOG_ERROR, "ctable2 - wrong header!" );
        pj_ctx_set_errno( ctx, -38 );
        return NULL;
    }

    /* read the table header */
    ct = (struct CTABLE *) pj_malloc(sizeof(struct CTABLE));
    if( ct == NULL )
    {
        pj_ctx_set_errno( ctx, -38 );
        return NULL;
    }

    memcpy( ct->id,       header +  16, 80 );
    memcpy( &ct->ll.lam,  header +  96, 8 );
    memcpy( &ct->ll.phi,  header + 104, 8 );
    memcpy( &ct->del.lam, header + 112, 8 );
    memcpy( &ct->del.phi, header + 120, 8 );
    memcpy( &ct->lim.lam, header + 128, 4 );
    memcpy( &ct->lim.phi, header + 132, 4 );

    /* do some minimal validation to ensure the structure isn't corrupt */
    if( ct->lim.lam < 1 || ct->lim.lam > 100000 
        || ct->lim.phi < 1 || ct->lim.phi > 100000 )
    {
        pj_ctx_set_errno( ctx, -38 );
        return NULL;
    }
    
    /* trim white space and newlines off id */
    for( id_end = strlen(ct->id)-1; id_end > 0; id_end-- )
    {
        if( ct->id[id_end] == '\n' || ct->id[id_end] == ' ' )
            ct->id[id_end] = '\0';
        else
            break;
    }

    ct->cvs = NULL;

    return ct;
}
示例#29
0
PJ *pj_latlong_from_proj( PJ *pj_in )

{
    char	defn[512];
    int		got_datum = FALSE;

    pj_errno = 0;
    strcpy( defn, "+proj=latlong" );

    if( pj_param(pj_in->ctx, pj_in->params, "tdatum").i )
    {
        got_datum = TRUE;
        sprintf( defn+strlen(defn), " +datum=%s", 
                 pj_param(pj_in->ctx, pj_in->params,"sdatum").s );
    }
    else if( pj_param(pj_in->ctx, pj_in->params, "tellps").i )
    {
        sprintf( defn+strlen(defn), " +ellps=%s", 
                 pj_param(pj_in->ctx, pj_in->params,"sellps").s );
    }
    else if( pj_param(pj_in->ctx,pj_in->params, "ta").i )
    {
        sprintf( defn+strlen(defn), " +a=%s", 
                 pj_param(pj_in->ctx,pj_in->params,"sa").s );
            
        if( pj_param(pj_in->ctx,pj_in->params, "tb").i )
            sprintf( defn+strlen(defn), " +b=%s", 
                     pj_param(pj_in->ctx,pj_in->params,"sb").s );
        else if( pj_param(pj_in->ctx,pj_in->params, "tes").i )
            sprintf( defn+strlen(defn), " +es=%s", 
                     pj_param(pj_in->ctx,pj_in->params,"ses").s );
        else if( pj_param(pj_in->ctx,pj_in->params, "tf").i )
            sprintf( defn+strlen(defn), " +f=%s", 
                     pj_param(pj_in->ctx,pj_in->params,"sf").s );
        else
            sprintf( defn+strlen(defn), " +es=%.16g", 
                     pj_in->es );
    }
    else
    {
        pj_ctx_set_errno( pj_in->ctx, -13 );

        return NULL;
    }

    if( !got_datum )
    {
        if( pj_param(pj_in->ctx,pj_in->params, "ttowgs84").i )
            sprintf( defn+strlen(defn), " +towgs84=%s", 
                     pj_param(pj_in->ctx,pj_in->params,"stowgs84").s );

        if( pj_param(pj_in->ctx,pj_in->params, "tnadgrids").i )
            sprintf( defn+strlen(defn), " +nadgrids=%s", 
                     pj_param(pj_in->ctx,pj_in->params,"snadgrids").s );
    }

    /* copy over some other information related to ellipsoid */
    if( pj_param(pj_in->ctx,pj_in->params, "tR").i )
        sprintf( defn+strlen(defn), " +R=%s", 
                 pj_param(pj_in->ctx,pj_in->params,"sR").s );

    if( pj_param(pj_in->ctx,pj_in->params, "tR_A").i )
        sprintf( defn+strlen(defn), " +R_A" );

    if( pj_param(pj_in->ctx,pj_in->params, "tR_V").i )
        sprintf( defn+strlen(defn), " +R_V" );

    if( pj_param(pj_in->ctx,pj_in->params, "tR_a").i )
        sprintf( defn+strlen(defn), " +R_a" );

    if( pj_param(pj_in->ctx,pj_in->params, "tR_lat_a").i )
        sprintf( defn+strlen(defn), " +R_lat_a=%s", 
                 pj_param(pj_in->ctx,pj_in->params,"sR_lat_a").s );

    if( pj_param(pj_in->ctx,pj_in->params, "tR_lat_g").i )
        sprintf( defn+strlen(defn), " +R_lat_g=%s", 
                 pj_param(pj_in->ctx,pj_in->params,"sR_lat_g").s );

    /* copy over prime meridian */
    if( pj_param(pj_in->ctx,pj_in->params, "tpm").i )
        sprintf( defn+strlen(defn), " +pm=%s", 
                 pj_param(pj_in->ctx,pj_in->params,"spm").s );

    return pj_init_plus_ctx( pj_in->ctx, defn );
}
示例#30
0
int pj_gc_apply_gridshift( PJ *defn, int inverse, 
                           long point_count, int point_offset, 
                           double *x, double *y, double *z )

{
    int i;

    if( defn->catalog == NULL ) 
    {
        defn->catalog = pj_gc_findcatalog( defn->ctx, defn->catalog_name );
        if( defn->catalog == NULL )
            return defn->ctx->last_errno;
    }

    defn->ctx->last_errno = 0;

    for( i = 0; i < point_count; i++ )
    {
        long io = i * point_offset;
        LP   input, output_after, output_before;
        double mix_ratio;
        PJ_GRIDINFO *gi;

        input.phi = y[io];
        input.lam = x[io];

        /* make sure we have appropriate "after" shift file available */
        if( defn->last_after_grid == NULL
            || input.lam < defn->last_after_region.ll_long
            || input.lam > defn->last_after_region.ur_long
            || input.phi < defn->last_after_region.ll_lat
            || input.phi > defn->last_after_region.ll_lat ) {
            defn->last_after_grid = 
                pj_gc_findgrid( defn->ctx, defn->catalog, 
                                1, input, defn->datum_date, 
                                &(defn->last_after_region), 
                                &(defn->last_after_date));
        }
        gi = defn->last_after_grid;
        assert( gi->child == NULL );

        /* load the grid shift info if we don't have it. */
        if( gi->ct->cvs == NULL && !pj_gridinfo_load( defn->ctx, gi ) )
        {
            pj_ctx_set_errno( defn->ctx, -38 );
            return -38;
        }
            
        output_after = nad_cvt( input, inverse, gi->ct );
        if( output_after.lam == HUGE_VAL )
        {
            if( defn->ctx->debug_level >= PJ_LOG_DEBUG_MAJOR )
            {
                pj_log( defn->ctx, PJ_LOG_DEBUG_MAJOR,
                        "pj_apply_gridshift(): failed to find a grid shift table for\n"
                        "                      location (%.7fdW,%.7fdN)",
                        x[io] * RAD_TO_DEG, 
                        y[io] * RAD_TO_DEG );
            }
            continue;
        }

        if( defn->datum_date == 0.0 ) 
        {
            y[io] = output_after.phi;
            x[io] = output_after.lam;
            continue;
        }

        /* make sure we have appropriate "before" shift file available */
        if( defn->last_before_grid == NULL
            || input.lam < defn->last_before_region.ll_long
            || input.lam > defn->last_before_region.ur_long
            || input.phi < defn->last_before_region.ll_lat
            || input.phi > defn->last_before_region.ll_lat ) {
            defn->last_before_grid = 
                pj_gc_findgrid( defn->ctx, defn->catalog, 
                                0, input, defn->datum_date, 
                                &(defn->last_before_region), 
                                &(defn->last_before_date));
        }

        gi = defn->last_before_grid;
        assert( gi->child == NULL );

        /* load the grid shift info if we don't have it. */
        if( gi->ct->cvs == NULL && !pj_gridinfo_load( defn->ctx, gi ) )
        {
            pj_ctx_set_errno( defn->ctx, -38 );
            return -38;
        }
            
        output_before = nad_cvt( input, inverse, gi->ct );
        if( output_before.lam == HUGE_VAL )
        {
            if( defn->ctx->debug_level >= PJ_LOG_DEBUG_MAJOR )
            {
                pj_log( defn->ctx, PJ_LOG_DEBUG_MAJOR,
                        "pj_apply_gridshift(): failed to find a grid shift table for\n"
                        "                      location (%.7fdW,%.7fdN)",
                        x[io] * RAD_TO_DEG, 
                        y[io] * RAD_TO_DEG );
            }
            continue;
        }

        mix_ratio = (defn->datum_date - defn->last_before_date) 
            / (defn->last_after_date - defn->last_before_date);

        y[io] = mix_ratio * output_after.phi 
            + (1.0-mix_ratio) * output_before.phi;
        x[io] = mix_ratio * output_after.lam 
            + (1.0-mix_ratio) * output_before.lam;
    }

    return 0;
}