Ejemplo n.º 1
0
int proj_context_errno (PJ_CONTEXT *ctx) {
/******************************************************************************
    Read an error directly from a context, without going through a PJ
    belonging to that context.
******************************************************************************/
    if (0==ctx)
        ctx = pj_get_default_ctx();
    return pj_ctx_get_errno (ctx);
}
Ejemplo n.º 2
0
static paralist *append_defaults_to_paralist (PJ_CONTEXT *ctx, paralist *start, char *key) {
    paralist *defaults, *last = 0;
    char keystring[ID_TAG_MAX + 20];
    paralist *next, *proj;
    int err;

    if (0==start)
        return 0;

    if (strlen(key) > ID_TAG_MAX)
        return 0;

    /* Set defaults, unless inhibited (either explicitly through a "no_defs" token */
    /* or implicitly, because we are initializing a pipeline) */
    if (pj_param_exists (start, "no_defs"))
        return start;
    proj = pj_param_exists (start, "proj");
    if (0==proj)
        return start;
    if (strlen (proj->param) < 6)
        return start;
    if (0==strcmp ("pipeline", proj->param + 5))
        return start;

    err = pj_ctx_get_errno (ctx);
    pj_ctx_set_errno (ctx, 0);

    /* Locate end of start-list */
    for (last = start;  last->next;  last = last->next);

    strcpy (keystring, "proj_def.dat:");
    strcat (keystring, key);
    defaults = get_init (ctx, keystring);

    /* Defaults are optional - so we don't care if we cannot open the file */
    pj_ctx_set_errno (ctx, err);

    if (!defaults)
        return last;

    /* Loop over all default items */
    for (next = defaults;  next;  next = next->next) {

        /* Don't override existing parameter value of same name */
        if (pj_param_exists (start, next->param))
            continue;

        /* Don't default ellipse if datum, ellps or any ellipsoid information is set */
        if (0==strncmp(next->param,"ellps=", 6)) {
            if  (pj_param_exists (start, "datum"))  continue;
            if  (pj_param_exists (start, "ellps"))  continue;
            if  (pj_param_exists (start, "a"))      continue;
            if  (pj_param_exists (start, "b"))      continue;
            if  (pj_param_exists (start, "rf"))     continue;
            if  (pj_param_exists (start, "f"))      continue;
            if  (pj_param_exists (start, "e"))      continue;
            if  (pj_param_exists (start, "es"))     continue;
        }

        /* If we're here, it's OK to append the current default item */
        last = last->next = pj_mkparam(next->param);
    }
    last->next = 0;

    pj_dealloc_params (ctx, defaults, 0);
    return last;
}
Ejemplo n.º 3
0
int proj_errno (const PJ *P) {
/******************************************************************************
    Read an error level from the context of a PJ.
******************************************************************************/
    return pj_ctx_get_errno (pj_get_ctx ((PJ *) P));
}
Ejemplo n.º 4
0
int pj_transform( PJ *srcdefn, PJ *dstdefn, long point_count, int point_offset,
                  double *x, double *y, double *z )

{
    long      i;
    int       err;

    srcdefn->ctx->last_errno = 0;
    dstdefn->ctx->last_errno = 0;

    if( point_offset == 0 )
        point_offset = 1;

/* -------------------------------------------------------------------- */
/*      Transform unusual input coordinate axis orientation to          */
/*      standard form if needed.                                        */
/* -------------------------------------------------------------------- */
    if( strcmp(srcdefn->axis,"enu") != 0 )
    {
        int err;

        err = pj_adjust_axis( srcdefn->ctx, srcdefn->axis, 
                              0, point_count, point_offset, x, y, z );
        if( err != 0 )
            return err;
    }

/* -------------------------------------------------------------------- */
/*      Transform Z to meters if it isn't already.                      */
/* -------------------------------------------------------------------- */
    if( srcdefn->vto_meter != 1.0 && z != NULL )
    {
        for( i = 0; i < point_count; i++ )
            z[point_offset*i] *= srcdefn->vto_meter;
    }

/* -------------------------------------------------------------------- */
/*      Transform geocentric source coordinates to lat/long.            */
/* -------------------------------------------------------------------- */
    if( srcdefn->is_geocent )
    {
        if( z == NULL )
        {
            pj_ctx_set_errno( pj_get_ctx(srcdefn), PJD_ERR_GEOCENTRIC);
            return PJD_ERR_GEOCENTRIC;
        }

        if( srcdefn->to_meter != 1.0 )
        {
            for( i = 0; i < point_count; i++ )
            {
                if( x[point_offset*i] != HUGE_VAL )
                {
                    x[point_offset*i] *= srcdefn->to_meter;
                    y[point_offset*i] *= srcdefn->to_meter;
                }
            }
        }

        err = pj_geocentric_to_geodetic( srcdefn->a_orig, srcdefn->es_orig,
                                         point_count, point_offset, 
                                         x, y, z );
        if( err != 0 )
            return err;
    }

/* -------------------------------------------------------------------- */
/*      Transform source points to lat/long, if they aren't             */
/*      already.                                                        */
/* -------------------------------------------------------------------- */
    else if( !srcdefn->is_latlong )
    {
        if( srcdefn->inv == NULL )
        {
            pj_ctx_set_errno( pj_get_ctx(srcdefn), -17 );
            pj_log( pj_get_ctx(srcdefn), PJ_LOG_ERROR, 
                    "pj_transform(): source projection not invertable" );
            return -17;
        }

        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];

            if( projected_loc.u == HUGE_VAL )
                continue;

            geodetic_loc = pj_inv( projected_loc, srcdefn );
            if( srcdefn->ctx->last_errno != 0 )
            {
                if( (srcdefn->ctx->last_errno != 33 /*EDOM*/ 
                     && srcdefn->ctx->last_errno != 34 /*ERANGE*/ )
                    && (srcdefn->ctx->last_errno > 0 
                        || srcdefn->ctx->last_errno < -44 || point_count == 1
                        || transient_error[-srcdefn->ctx->last_errno] == 0 ) )
                    return srcdefn->ctx->last_errno;
                else
                {
                    geodetic_loc.u = HUGE_VAL;
                    geodetic_loc.v = HUGE_VAL;
                }
            }

            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.                             */
/* -------------------------------------------------------------------- */
    if( srcdefn->from_greenwich != 0.0 )
    {
        for( i = 0; i < point_count; i++ )
        {
            if( x[point_offset*i] != HUGE_VAL )
                x[point_offset*i] += srcdefn->from_greenwich;
        }
    }

/* -------------------------------------------------------------------- */
/*      Do we need to translate from geoid to ellipsoidal vertical      */
/*      datum?                                                          */
/* -------------------------------------------------------------------- */
    if( srcdefn->has_geoid_vgrids )
    {
        if( pj_apply_vgridshift( srcdefn, "sgeoidgrids", 
                                 &(srcdefn->vgridlist_geoid), 
                                 &(srcdefn->vgridlist_geoid_count),
                                 0, point_count, point_offset, x, y, z ) != 0 )
            return pj_ctx_get_errno(srcdefn->ctx);
    }
        
/* -------------------------------------------------------------------- */
/*      Convert datums if needed, and possible.                         */
/* -------------------------------------------------------------------- */
    if( pj_datum_transform( srcdefn, dstdefn, point_count, point_offset, 
                            x, y, z ) != 0 )
    {
        if( srcdefn->ctx->last_errno != 0 )
            return srcdefn->ctx->last_errno;
        else
            return dstdefn->ctx->last_errno;
    }

/* -------------------------------------------------------------------- */
/*      Do we need to translate from geoid to ellipsoidal vertical      */
/*      datum?                                                          */
/* -------------------------------------------------------------------- */
    if( dstdefn->has_geoid_vgrids )
    {
        if( pj_apply_vgridshift( dstdefn, "sgeoidgrids", 
                                 &(dstdefn->vgridlist_geoid), 
                                 &(dstdefn->vgridlist_geoid_count),
                                 1, point_count, point_offset, x, y, z ) != 0 )
            return dstdefn->ctx->last_errno;
    }
        
/* -------------------------------------------------------------------- */
/*      But if they are staying lat long, adjust for the prime          */
/*      meridian if there is one in effect.                             */
/* -------------------------------------------------------------------- */
    if( dstdefn->from_greenwich != 0.0 )
    {
        for( i = 0; i < point_count; i++ )
        {
            if( x[point_offset*i] != HUGE_VAL )
                x[point_offset*i] -= dstdefn->from_greenwich;
        }
    }


/* -------------------------------------------------------------------- */
/*      Transform destination latlong to geocentric if required.        */
/* -------------------------------------------------------------------- */
    if( dstdefn->is_geocent )
    {
        if( z == NULL )
        {
            pj_ctx_set_errno( dstdefn->ctx, PJD_ERR_GEOCENTRIC );
            return PJD_ERR_GEOCENTRIC;
        }

        pj_geodetic_to_geocentric( dstdefn->a_orig, dstdefn->es_orig,
                                   point_count, point_offset, x, y, z );

        if( dstdefn->fr_meter != 1.0 )
        {
            for( i = 0; i < point_count; i++ )
            {
                if( x[point_offset*i] != HUGE_VAL )
                {
                    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];

            if( geodetic_loc.u == HUGE_VAL )
                continue;

            projected_loc = pj_fwd( geodetic_loc, dstdefn );
            if( dstdefn->ctx->last_errno != 0 )
            {
                if( (dstdefn->ctx->last_errno != 33 /*EDOM*/ 
                     && dstdefn->ctx->last_errno != 34 /*ERANGE*/ )
                    && (dstdefn->ctx->last_errno > 0 
                        || dstdefn->ctx->last_errno < -44 || point_count == 1
                        || transient_error[-dstdefn->ctx->last_errno] == 0 ) )
                    return dstdefn->ctx->last_errno;
                else
                {
                    projected_loc.u = HUGE_VAL;
                    projected_loc.v = HUGE_VAL;
                }
            }

            x[point_offset*i] = projected_loc.u;
            y[point_offset*i] = projected_loc.v;
        }
    }

/* -------------------------------------------------------------------- */
/*      If a wrapping center other than 0 is provided, rewrap around    */
/*      the suggested center (for latlong coordinate systems only).     */
/* -------------------------------------------------------------------- */
    else if( dstdefn->is_latlong && dstdefn->is_long_wrap_set )
    {
        for( i = 0; i < point_count; i++ )
        {
            if( x[point_offset*i] == HUGE_VAL )
                continue;

            while( x[point_offset*i] < dstdefn->long_wrap_center - PI )
                x[point_offset*i] += TWOPI;
            while( x[point_offset*i] > dstdefn->long_wrap_center + PI )
                x[point_offset*i] -= TWOPI;
        }
    }

/* -------------------------------------------------------------------- */
/*      Transform Z from meters if needed.                              */
/* -------------------------------------------------------------------- */
    if( dstdefn->vto_meter != 1.0 && z != NULL )
    {
        for( i = 0; i < point_count; i++ )
            z[point_offset*i] *= dstdefn->vfr_meter;
    }

/* -------------------------------------------------------------------- */
/*      Transform normalized axes into unusual output coordinate axis   */
/*      orientation if needed.                                          */
/* -------------------------------------------------------------------- */
    if( strcmp(dstdefn->axis,"enu") != 0 )
    {
        int err;

        err = pj_adjust_axis( dstdefn->ctx, dstdefn->axis, 
                              1, point_count, point_offset, x, y, z );
        if( err != 0 )
            return err;
    }

    return 0;
}