PJ_GRID_INFO proj_grid_info(const char *gridname) { /****************************************************************************** Information about a named datum grid. Returns PJ_GRID_INFO struct. ******************************************************************************/ PJ_GRID_INFO grinfo; /*PJ_CONTEXT *ctx = proj_context_create(); */ PJ_CONTEXT *ctx = pj_get_default_ctx(); PJ_GRIDINFO *gridinfo = pj_gridinfo_init(ctx, gridname); memset(&grinfo, 0, sizeof(PJ_GRID_INFO)); /* in case the grid wasn't found */ if (gridinfo->filename == NULL) { pj_gridinfo_free(ctx, gridinfo); strcpy(grinfo.format, "missing"); return grinfo; } /* The string copies below are automatically null-terminated due to */ /* the memset above, so strncpy is safe */ /* name of grid */ strncpy (grinfo.gridname, gridname, sizeof(grinfo.gridname) - 1); /* full path of grid */ pj_find_file(ctx, gridname, grinfo.filename, sizeof(grinfo.filename) - 1); /* grid format */ strncpy (grinfo.format, gridinfo->format, sizeof(grinfo.format) - 1); /* grid size */ grinfo.n_lon = gridinfo->ct->lim.lam; grinfo.n_lat = gridinfo->ct->lim.phi; /* cell size */ grinfo.cs_lon = gridinfo->ct->del.lam; grinfo.cs_lat = gridinfo->ct->del.phi; /* bounds of grid */ grinfo.lowerleft = gridinfo->ct->ll; grinfo.upperright.lam = grinfo.lowerleft.lam + grinfo.n_lon*grinfo.cs_lon; grinfo.upperright.phi = grinfo.lowerleft.phi + grinfo.n_lat*grinfo.cs_lat; pj_gridinfo_free(ctx, gridinfo); return grinfo; }
void pj_gridinfo_free( projCtx ctx, PJ_GRIDINFO *gi ) { if( gi == NULL ) return; if( gi->child != NULL ) { PJ_GRIDINFO *child, *next; for( child = gi->child; child != NULL; child=next) { next=child->next; pj_gridinfo_free( ctx, child ); } } if( gi->ct != NULL ) nad_free( gi->ct ); free( gi->gridname ); if( gi->filename != NULL ) free( gi->filename ); pj_dalloc( gi ); }
void pj_deallocate_grids() { while( grid_list != NULL ) { PJ_GRIDINFO *item = grid_list; grid_list = grid_list->next; item->next = NULL; pj_gridinfo_free( item ); } if( last_nadgrids != NULL ) { pj_dalloc( last_nadgrids ); last_nadgrids = NULL; pj_dalloc( last_nadgrids_list ); last_nadgrids_list = NULL; last_nadgrids_count = 0; last_nadgrids_max = 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; }