Example #1
0
static void *freeup_new (PJ *P) {                       /* Destructor */
    if (0==P)
        return 0;
    if (0==P->opaque)
        return pj_dealloc (P);
    pj_dealloc (P->opaque);
    return pj_dealloc(P);
}
Example #2
0
PJ *proj_create_argv (PJ_CONTEXT *ctx, int argc, char **argv) {
/**************************************************************************************
Create a new PJ object in the context ctx, using the given definition argument
array argv. If ctx==0, the default context is used, if definition==0, or invalid,
a null-pointer is returned. The definition arguments may use '+' as argument start
indicator, as in {"+proj=utm", "+zone=32"}, or leave it out, as in {"proj=utm",
"zone=32"}.
**************************************************************************************/
    PJ *P;
    const char *c;

    if (0==argv)
        return 0;
    if (0==ctx)
        ctx = pj_get_default_ctx ();

    /* We assume that free format is used, and build a full proj_create compatible string */
    c = pj_make_args (argc, argv);
    if (0==c)
        return 0;

    P = proj_create (ctx, c);

    pj_dealloc ((char *) c);
    return P;
}
Example #3
0
static char *path_append (char *buf, const char *app, size_t *buf_size) {
/******************************************************************************
    Helper for proj_info() below. Append app to buf, separated by a
    semicolon. Also handle allocation of longer buffer if needed.

    Returns buffer and adjusts *buf_size through provided pointer arg.
******************************************************************************/
    char *p;
    size_t len, applen = 0, buflen = 0;
#ifdef _WIN32
    char *delim = ";";
#else
    char *delim = ":";
#endif

    /* Nothing to do? */
    if (0 == app)
        return buf;
    applen = strlen (app);
    if (0 == applen)
        return buf;

    /* Start checking whether buf is long enough */
    if (0 != buf)
        buflen = strlen (buf);
    len = buflen+applen+strlen (delim) + 1;

    /* "pj_realloc", so to speak */
    if (*buf_size < len) {
        p = pj_calloc (2 * len, sizeof (char));
        if (0==p) {
            pj_dealloc (buf);
            return 0;
        }
        *buf_size = 2 * len;
        if (buf != 0)
            strcpy (p, buf);
        pj_dealloc (buf);
        buf = p;
    }

    /* Only append a semicolon if something's already there */
    if (0 != buflen)
        strcat (buf, ";");
    strcat (buf, app);
    return buf;
}
Example #4
0
PJ *proj_create (PJ_CONTEXT *ctx, const char *definition) {
/**************************************************************************************
    Create a new PJ object in the context ctx, using the given definition. If ctx==0,
    the default context is used, if definition==0, or invalid, a null-pointer is
    returned. The definition may use '+' as argument start indicator, as in
    "+proj=utm +zone=32", or leave it out, as in "proj=utm zone=32".

    It may even use free formatting "proj  =  utm;  zone  =32  ellps= GRS80".
    Note that the semicolon separator is allowed, but not required.
**************************************************************************************/
    PJ    *P;
    char  *args, **argv;
    size_t argc, n;
    int    ret;

    if (0==ctx)
        ctx = pj_get_default_ctx ();

    /* Make a copy that we can manipulate */
    n = strlen (definition);
    args = (char *) malloc (n + 1);
    if (0==args)
        return 0;
    strcpy (args, definition);

    argc = pj_trim_argc (args);
    if (argc==0) {
        pj_dealloc (args);
        return 0;
    }

    argv = pj_trim_argv (argc, args);

    /* ...and let pj_init_ctx do the hard work */
    P = pj_init_ctx (ctx, (int) argc, argv);

    pj_dealloc (argv);
    pj_dealloc (args);

    /* Support cs2cs-style modifiers */
    ret = cs2cs_emulation_setup  (P);
    if (0==ret)
        return proj_destroy (P);

    return P;
}
Example #5
0
static PJ *destructor (PJ *P, int errlev) {
    if (nullptr==P)
        return nullptr;

    if (nullptr==P->opaque)
        return pj_default_destructor (P, errlev);

    pj_dealloc (static_cast<struct pj_opaque*>(P->opaque)->en);
    return pj_default_destructor (P, errlev);
}
Example #6
0
static void *destructor (PJ *P, int errlev) {
    if (0==P)
        return 0;

    if (0==P->opaque)
        return pj_default_destructor (P, errlev);

    pj_dealloc (P->opaque->en);
    return pj_default_destructor (P, errlev);
}
Example #7
0
static PJ *destructor (PJ *P, int errlev) {
    int i;
    if (nullptr==P)
        return nullptr;

    if (nullptr==P->opaque)
        return pj_default_destructor (P, errlev);

    /* Deallocate each pipeline step, then pipeline array */
    if (nullptr!=static_cast<struct pj_opaque*>(P->opaque)->pipeline)
        for (i = 0;  i < static_cast<struct pj_opaque*>(P->opaque)->steps; i++)
            proj_destroy (static_cast<struct pj_opaque*>(P->opaque)->pipeline[i+1]);
    pj_dealloc (static_cast<struct pj_opaque*>(P->opaque)->pipeline);

    pj_dealloc (static_cast<struct pj_opaque*>(P->opaque)->argv);
    pj_dealloc (static_cast<struct pj_opaque*>(P->opaque)->current_argv);

    for (i=0; i<4; i++)
        delete static_cast<struct pj_opaque*>(P->opaque)->stack[i];

    return pj_default_destructor(P, errlev);
}
Example #8
0
int proj_vgrid_init(PJ* P, const char *grids) {
/**********************************************

  Initizalize and populate gridlist.

    Takes a PJ-object and the plus-parameter
    name that is used in the proj-string to
    specify the grids to load, e.g. "+grids".
    The + should be left out here.

    Returns the number of loaded grids.

***********************************************/

    /* prepend "s" to the "grids" string to allow usage with pj_param */
    char *sgrids = (char *) pj_malloc( (strlen(grids)+1+1) *sizeof(char) );
    sprintf(sgrids, "%s%s", "s", grids);

    if (P->vgridlist_geoid == NULL) {
        P->vgridlist_geoid = pj_gridlist_from_nadgrids(
            P->ctx,
            pj_param(P->ctx, P->params, sgrids).s,
            &(P->vgridlist_geoid_count)
        );

        if( P->vgridlist_geoid == NULL || P->vgridlist_geoid_count == 0 ) {
            pj_dealloc(sgrids);
            return 0;
        }
    }

    if (P->vgridlist_geoid_count == 0) {
        proj_errno_set(P, PJD_ERR_FAILED_TO_LOAD_GRID);
    }

    pj_dealloc(sgrids);
    return P->vgridlist_geoid_count;
}
Example #9
0
static paralist *get_init(PJ_CONTEXT *ctx, char *key) {
/*************************************************************************
Expand key from buffer or (if not in buffer) from init file
*************************************************************************/
    char *xkey, *definition;
    paralist *init_items = 0;

    /* support "init=file:section", "+init=file:section", and "file:section" format */
    xkey = strstr (key, "init=");
    if (0==xkey)
        xkey = key;
    else
        xkey += 5;
    pj_log (ctx, PJ_LOG_TRACE, "get_init: searching cache for key: [%s]", xkey);

    /* Is file/key pair already in cache? */
    init_items = pj_search_initcache (xkey);
    if (init_items)
        return init_items;

    /* If not, we must read it from file */
    pj_log (ctx, PJ_LOG_TRACE,
            "get_init: searching on in init files for [%s]", xkey);
    definition = get_init_string (ctx, xkey);
    if (0==definition)
        return 0;
    init_items = string_to_paralist (ctx, definition);
    if (init_items)
        pj_log (ctx, PJ_LOG_TRACE, "get_init: got [%s], paralist[0,1]: [%s,%s]",
                definition,
                init_items->param,
                init_items->next ? init_items->next->param : "(empty)");
    pj_dealloc (definition);
    if (0==init_items)
        return 0;

    /* We found it in file - now insert into the cache, before returning */
    pj_insert_initcache (xkey, init_items);
    return init_items;
}
Example #10
0
static void *freeup_new (PJ *P) {                       /* Destructor */
    return pj_dealloc(P);
}
Example #11
0
static void freeup(PJ *P) {                             /* Destructor */
    pj_dealloc(P);
}
Example #12
0
static char *get_init_string (PJ_CONTEXT *ctx, char *name) {
/***************************************************************************************
    Read a section of an init file. Return its contents as a plain character string.
    It is the duty of the caller to free the memory allocated for the string.
***************************************************************************************/
#define MAX_LINE_LENGTH 1000
    size_t current_buffer_size = 5 * (MAX_LINE_LENGTH + 1);
    char *fname, *section, *key;
    char *buffer = 0;
    char *line = 0;
    PAFile fid;
    size_t n;


    line = pj_malloc (MAX_LINE_LENGTH + 1);
    if (0==line)
        return 0;

    fname = pj_malloc (MAX_PATH_FILENAME+ID_TAG_MAX+3);
    if (0==fname) {
        pj_dealloc (line);
        return 0;
    }

    /* Support "init=file:section", "+init=file:section", and "file:section" format */
    key = strstr (name, "init=");
    if (0==key)
        key = name;
    else
        key += 5;
    if (MAX_PATH_FILENAME + ID_TAG_MAX + 2 < strlen (key)) {
        pj_dealloc (fname);
        pj_dealloc (line);
        return 0;
    }
    memmove (fname, key, strlen (key) + 1);

    /* Locate the name of the section we search for */
    section = strrchr(fname, ':');
    if (0==section) {
        proj_context_errno_set (ctx, PJD_ERR_NO_COLON_IN_INIT_STRING);
        pj_dealloc (fname);
        pj_dealloc (line);
        return 0;
    }
    *section = 0;
    section++;
    n = strlen (section);
    pj_log (ctx, PJ_LOG_TRACE,
            "get_init_string: searching for section [%s] in init file [%s]",
            section, fname);

    fid = pj_open_lib (ctx, fname, "rt");
    if (0==fid) {
        pj_dealloc (fname);
        pj_dealloc (line);
        proj_context_errno_set (ctx, PJD_ERR_NO_OPTION_IN_INIT_FILE);
        return 0;
    }

    /* Search for section in init file */
    for (;;) {

        /* End of file? */
        if (0==pj_ctx_fgets (ctx, line, MAX_LINE_LENGTH, fid)) {
            pj_dealloc (buffer);
            pj_dealloc (fname);
            pj_dealloc (line);
            pj_ctx_fclose (ctx, fid);
            proj_context_errno_set (ctx, PJD_ERR_NO_OPTION_IN_INIT_FILE);
            return 0;
        }

        /* At start of right section? */
        pj_chomp (line);
        if ('<'!=line[0])
            continue;
        if (strlen (line) < n + 2)
            continue;
        if (line[n + 1] != '>')
            continue;
        if (0==strncmp (line + 1, section, n))
            break;
    }

    /* We're at the first line of the right section - copy line to buffer */
    buffer = pj_malloc (current_buffer_size);
    if (0==buffer) {
        pj_dealloc (fname);
        pj_dealloc (line);
        pj_ctx_fclose (ctx, fid);
        return 0;
    }

    /* Skip the "<section>" indicator, and copy the rest of the line over */
    strcpy (buffer, line + strlen (section) + 2);

    /* Copy the remaining lines of the section to buffer */
    for (;;) {
        char *end_i_cator;
        size_t next_length, buffer_length;

        /* Did the section end somewhere in the most recently read line? */
        end_i_cator = strchr (buffer, '<');
        if (end_i_cator) {
            *end_i_cator = 0;
            break;
        }

        /* End of file? - done! */
        if (0==pj_ctx_fgets (ctx, line, MAX_LINE_LENGTH, fid))
            break;

        /* Otherwise, handle the line. It MAY be the start of the next section, */
        /* but that will be handled at the start of next trip through the loop  */
        buffer_length = strlen (buffer);
        pj_chomp (line);   /* Remove '#' style comments */
        next_length = strlen (line) + buffer_length + 2;
        if (next_length > current_buffer_size) {
            char *b = pj_malloc (2 * current_buffer_size);
            if (0==b) {
                pj_dealloc (buffer);
                buffer = 0;
                break;
            }
            strcpy (b, buffer);
            current_buffer_size *= 2;
            pj_dealloc (buffer);
            buffer = b;
        }
        buffer[buffer_length] = ' ';
        strcpy (buffer + buffer_length + 1, line);
    }

    pj_ctx_fclose (ctx, fid);
    pj_dealloc (fname);
    pj_dealloc (line);
    if (0==buffer)
        return 0;
    pj_shrink (buffer);
    pj_log (ctx, PJ_LOG_TRACE, "key=%s, value: [%s]", key, buffer);
    return buffer;
}
Example #13
0
PJ *PROJECTION(ob_tran) {
    double phip;
    char *name;
    ARGS args;
    PJ *R; /* projection to rotate */

    struct pj_opaque *Q = static_cast<struct pj_opaque*>(pj_calloc (1, sizeof (struct pj_opaque)));
    if (nullptr==Q)
        return destructor(P, ENOMEM);

    P->opaque = Q;
    P->destructor = destructor;

    /* get name of projection to be translated */
    if (!(name = pj_param(P->ctx, P->params, "so_proj").s))
        return destructor(P, PJD_ERR_NO_ROTATION_PROJ);

    /* avoid endless recursion */
    if( strcmp(name, "ob_tran") == 0 )
        return destructor(P, PJD_ERR_FAILED_TO_FIND_PROJ);

    /* Create the target projection object to rotate */
    args = ob_tran_target_params (P->params);
    R = pj_init_ctx (pj_get_ctx(P), args.argc, args.argv);
    pj_dealloc (args.argv);

    if (nullptr==R)
        return destructor (P, PJD_ERR_UNKNOWN_PROJECTION_ID);
    Q->link = R;

    if (pj_param(P->ctx, P->params, "to_alpha").i) {
        double lamc, phic, alpha;

        lamc    = pj_param(P->ctx, P->params, "ro_lon_c").f;
        phic    = pj_param(P->ctx, P->params, "ro_lat_c").f;
        alpha   = pj_param(P->ctx, P->params, "ro_alpha").f;

        if (fabs(fabs(phic) - M_HALFPI) <= TOL)
            return destructor(P, PJD_ERR_LAT_0_OR_ALPHA_EQ_90);

        Q->lamp = lamc + aatan2(-cos(alpha), -sin(alpha) * sin(phic));
        phip = aasin(P->ctx,cos(phic) * sin(alpha));
    } else if (pj_param(P->ctx, P->params, "to_lat_p").i) { /* specified new pole */
        Q->lamp = pj_param(P->ctx, P->params, "ro_lon_p").f;
        phip = pj_param(P->ctx, P->params, "ro_lat_p").f;
    } else { /* specified new "equator" points */
        double lam1, lam2, phi1, phi2, con;

        lam1 = pj_param(P->ctx, P->params, "ro_lon_1").f;
        phi1 = pj_param(P->ctx, P->params, "ro_lat_1").f;
        lam2 = pj_param(P->ctx, P->params, "ro_lon_2").f;
        phi2 = pj_param(P->ctx, P->params, "ro_lat_2").f;
        if (fabs(phi1 - phi2) <= TOL || (con = fabs(phi1)) <= TOL ||
            fabs(con - M_HALFPI) <= TOL || fabs(fabs(phi2) - M_HALFPI) <= TOL)
                return destructor(P, PJD_ERR_LAT_1_OR_2_ZERO_OR_90);

        Q->lamp = atan2(cos(phi1) * sin(phi2) * cos(lam1) -
            sin(phi1) * cos(phi2) * cos(lam2),
            sin(phi1) * cos(phi2) * sin(lam2) -
            cos(phi1) * sin(phi2) * sin(lam1));
        phip = atan(-cos(Q->lamp - lam1) / tan(phi1));
    }

    if (fabs(phip) > TOL) { /* oblique */
        Q->cphip = cos(phip);
        Q->sphip = sin(phip);
        P->fwd = Q->link->fwd ? o_forward : nullptr;
        P->inv = Q->link->inv ? o_inverse : nullptr;
    } else { /* transverse */
        P->fwd = Q->link->fwd ? t_forward : nullptr;
        P->inv = Q->link->inv ? t_inverse : nullptr;
    }

    /* Support some rather speculative test cases, where the rotated projection */
    /* is actually latlong. We do not want scaling in that case... */
    if (Q->link->right==PJ_IO_UNITS_RADIANS)
        P->right = PJ_IO_UNITS_PROJECTED;


    return P;
}