Пример #1
0
struct CTABLE *nad_init(projCtx ctx, char *name) 
{
    char 	fname[MAX_PATH_FILENAME+1];
    struct CTABLE *ct;
    PAFile      fid;

    ctx->last_errno = 0;

/* -------------------------------------------------------------------- */
/*      Open the file using the usual search rules.                     */
/* -------------------------------------------------------------------- */
    strcpy(fname, name);
    if (!(fid = pj_open_lib(ctx, fname, "rb"))) {
        return 0;
    }

    ct = nad_ctable_init( ctx, fid );
    if( ct != NULL )
    {
        if( !nad_ctable_load( ctx, ct, fid ) )
        {
            nad_free( ct );
            ct = NULL;
        }
    }

    pj_ctx_fclose(ctx, fid);
    return ct;
}
Пример #2
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;
}
Пример #3
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;
    }
}
Пример #4
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;
}
Пример #5
0
static CPLString GetProj4Filename(const char* pszFilename)
{
    CPLString osFilename;

    /* or fixed path: /name, ./name or ../name */
    if ( !CPLIsFilenameRelative(pszFilename) || *pszFilename == '.' )
    {
        return pszFilename;
    }

#if defined(PROJ_STATIC) && PROJ_VERSION >= 5
    PJ_GRID_INFO info = proj_grid_info(pszFilename);
    if( info.filename[0] )
    {
        osFilename = info.filename;
    }
#elif defined(PROJ_STATIC) && PJ_VERSION > 493
    osFilename.resize(2048);
    projCtx ctx = pj_ctx_alloc();
    if( pj_find_file(ctx, pszFilename, &osFilename[0], osFilename.size()) )
    {
        osFilename.resize( strlen(osFilename) );
    }
    else
    {
        osFilename.clear();
    }
    pj_ctx_free(ctx);
#else
    // Transpose some of the proj.4 pj_open_lib() logic...

    /* check if ~/name */
    char* pszSysname;
    if (*pszFilename == '~' &&
        (pszFilename[1] == '/' || pszFilename[1] == '\\') )
    {
        if ((pszSysname = getenv("HOME")) != nullptr)
        {
            osFilename = CPLFormFilename(pszSysname, pszFilename + 1, nullptr);
        }
        return osFilename;
    }

    /* or is environment PROJ_LIB defined */
    else if ((pszSysname = getenv("PROJ_LIB")) != nullptr)
    {
        osFilename = CPLFormFilename(pszSysname, pszFilename, nullptr);
        VSIStatBufL sStat;
        if( VSIStatL(osFilename, &sStat) == 0 )
            return osFilename;
        osFilename.clear();
    }


#if defined(PROJ_STATIC) && PJ_VERSION >= 490
    // Super messy. proj.4 up to 4.9.3 had no public API to return the full
    // path to a resource file, so we rely on the fact that it emits a log
    // message with it...
    // Basically this is needed in the case where the file is in the
    // resource installation directory of proj.4, which we have no way to
    // know otherwise.
    CPLString osMsg;
    projCtx ctx = pj_ctx_alloc();
    pj_ctx_set_app_data(ctx, &osMsg);
    pj_ctx_set_debug(ctx, PJ_LOG_DEBUG_MAJOR);
    pj_ctx_set_logger(ctx, my_proj4_logger);
    PAFile f = pj_open_lib(ctx, pszFilename, "rb");
    if( f )
    {
        pj_ctx_fclose(ctx, f);
        size_t nPos = osMsg.find("fopen(");
        if( nPos != std::string::npos )
        {
            osFilename = osMsg.substr(nPos + strlen("fopen("));
            nPos = osFilename.find(")");
            if( nPos != std::string::npos )
                osFilename = osFilename.substr(0, nPos);
        }
    }
    pj_ctx_free(ctx);
#endif
#endif
    return osFilename;
}