void pj_clear_initcache() { if( cache_alloc > 0 ) { int i; pj_acquire_lock(); for( i = 0; i < cache_count; i++ ) { paralist *n, *t = cache_paralist[i]; pj_dalloc( cache_key[i] ); /* free parameter list elements */ for (; t != NULL; t = n) { n = t->next; pj_dalloc(t); } } pj_dalloc( cache_key ); pj_dalloc( cache_paralist ); cache_count = 0; cache_alloc= 0; cache_key = NULL; cache_paralist = NULL; pj_release_lock(); } }
void /* free 2D array */ freev2(void **v, int nrows) { if (v) { for (v += nrows; nrows > 0; --nrows) pj_dalloc(*--v); pj_dalloc(v); } }
void nad_free(struct CTABLE *ct) { if (ct) { if( ct->cvs != NULL ) pj_dalloc(ct->cvs); pj_dalloc(ct); } }
int bchgen(projUV a, projUV b, int nu, int nv, projUV **f, projUV(*func)(projUV)) { int i, j, k; projUV arg, *t, bma, bpa, *c; double d, fac; bma.u = 0.5 * (b.u - a.u); bma.v = 0.5 * (b.v - a.v); bpa.u = 0.5 * (b.u + a.u); bpa.v = 0.5 * (b.v + a.v); for ( i = 0; i < nu; ++i) { arg.u = cos(PI * (i + 0.5) / nu) * bma.u + bpa.u; for ( j = 0; j < nv; ++j) { arg.v = cos(PI * (j + 0.5) / nv) * bma.v + bpa.v; f[i][j] = (*func)(arg); if ((f[i][j]).u == HUGE_VAL) return(1); } } if (!(c = (projUV *) vector1(nu, sizeof(projUV)))) return 1; fac = 2. / nu; for ( j = 0; j < nv ; ++j) { for ( i = 0; i < nu; ++i) { arg.u = arg.v = 0.; for (k = 0; k < nu; ++k) { d = cos(PI * i * (k + .5) / nu); arg.u += f[k][j].u * d; arg.v += f[k][j].v * d; } arg.u *= fac; arg.v *= fac; c[i] = arg; } for (i = 0; i < nu; ++i) f[i][j] = c[i]; } pj_dalloc(c); if (!(c = (projUV*) vector1(nv, sizeof(projUV)))) return 1; fac = 2. / nv; for ( i = 0; i < nu; ++i) { t = f[i]; for (j = 0; j < nv; ++j) { arg.u = arg.v = 0.; for (k = 0; k < nv; ++k) { d = cos(PI * j * (k + .5) / nv); arg.u += t[k].u * d; arg.v += t[k].v * d; } arg.u *= fac; arg.v *= fac; c[j] = arg; } f[i] = c; c = t; } pj_dalloc(c); return(0); }
int nad_ctable_load( 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; if( getenv("PROJ_DEBUG") != NULL ) { fprintf( stderr, "ctable loading failed on fread() - binary incompatible?\n" ); } pj_errno = -38; return 0; } return 1; }
static void /* convert columns to power series */ cols(projUV **c, projUV **d, int nu, int nv) { projUV *sv, **dd; int j, k; dd = (projUV **)vector2(nu, nv, sizeof(projUV)); sv = (projUV *)vector1(nv, sizeof(projUV)); bclear(d, nu, nv); bclear(dd, nu, nv); bmove(d[0], c[nu-1], nv); for (j = nu-2; j >= 1; --j) { for (k = nu-j; k >= 1; --k) { bmove(sv, d[k], nv); submop(d[k], 2., d[k-1], dd[k], nv); bmove(dd[k], sv, nv); } bmove(sv, d[0], nv); subop(d[0], c[j], dd[0], nv); bmove(dd[0], sv, nv); } for (j = nu-1; j >= 1; --j) subop(d[j], d[j-1], dd[j], nv); submop(d[0], .5, c[0], dd[0], nv); freev2((void **) dd, nu); pj_dalloc(sv); }
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; }
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 ); }
int pj_apply_gridshift( projCtx ctx, const char *nadgrids, int inverse, long point_count, int point_offset, double *x, double *y, double *z ) { PJ_GRIDINFO **gridlist; int grid_count; int ret; gridlist = pj_gridlist_from_nadgrids( ctx, nadgrids, &grid_count ); if( gridlist == NULL || grid_count == 0 ) return ctx->last_errno; ret = pj_apply_gridshift_3( ctx, gridlist, grid_count, inverse, point_count, point_offset, x, y, z ); /* ** Note this frees the array of grid list pointers, but not the grids ** which is as intended. The grids themselves live on. */ pj_dalloc( gridlist ); return ret; }
static void /* convert row to pover series */ rows(projUV *c, projUV *d, int n) { projUV sv, *dd; int j, k; dd = (projUV *)vector1(n-1, sizeof(projUV)); sv.u = sv.v = 0.; for (j = 0; j < n; ++j) d[j] = dd[j] = sv; d[0] = c[n-1]; for (j = n-2; j >= 1; --j) { for (k = n-j; k >= 1; --k) { sv = d[k]; d[k].u = 2. * d[k-1].u - dd[k].u; d[k].v = 2. * d[k-1].v - dd[k].v; dd[k] = sv; } sv = d[0]; d[0].u = -dd[0].u + c[j].u; d[0].v = -dd[0].v + c[j].v; dd[0] = sv; } for (j = n-1; j >= 1; --j) { d[j].u = d[j-1].u - dd[j].u; d[j].v = d[j-1].v - dd[j].v; } d[0].u = -dd[0].u + .5 * c[0].u; d[0].v = -dd[0].v + .5 * c[0].v; pj_dalloc(dd); }
static VALUE method_proj4_initialize_copy(VALUE self, VALUE orig) { RGeo_Proj4Data* self_data; projPJ pj; RGeo_Proj4Data* orig_data; char* str; // Clear out any existing value self_data = RGEO_PROJ4_DATA_PTR(self); pj = self_data->pj; if (pj) { pj_free(pj); self_data->pj = NULL; self_data->original_str = Qnil; } // Copy value from orig orig_data = RGEO_PROJ4_DATA_PTR(orig); if (!NIL_P(orig_data->original_str)) { self_data->pj = pj_init_plus(RSTRING_PTR(orig_data->original_str)); } else { str = pj_get_def(orig_data->pj, 0); self_data->pj = pj_init_plus(str); pj_dalloc(str); } self_data->original_str = orig_data->original_str; self_data->uses_radians = orig_data->uses_radians; return self; }
void geod_set(int argc, char **argv) { paralist *start = 0, *curr; double es; char *name; int i; /* put arguments into internal linked list */ if (argc <= 0) emess(1, "no arguments in initialization list"); start = curr = pj_mkparam(argv[0]); for (i = 1; i < argc; ++i) { curr->next = pj_mkparam(argv[i]); curr = curr->next; } /* set elliptical parameters */ if (pj_ell_set(pj_get_default_ctx(),start, &geod_a, &es)) emess(1,"ellipse setup failure"); /* set units */ if ((name = pj_param(NULL,start, "sunits").s) != NULL) { char *s; struct PJ_UNITS *unit_list = pj_get_units_ref(); for (i = 0; (s = unit_list[i].id) && strcmp(name, s) ; ++i) ; if (!s) emess(1,"%s unknown unit conversion id", name); fr_meter = 1. / (to_meter = atof(unit_list[i].to_meter)); } else to_meter = fr_meter = 1.; geod_f = es/(1 + sqrt(1 - es)); geod_ini(); /* check if line or arc mode */ if (pj_param(NULL,start, "tlat_1").i) { double del_S; #undef f phi1 = pj_param(NULL,start, "rlat_1").f; lam1 = pj_param(NULL,start, "rlon_1").f; if (pj_param(NULL,start, "tlat_2").i) { phi2 = pj_param(NULL,start, "rlat_2").f; lam2 = pj_param(NULL,start, "rlon_2").f; geod_inv(); geod_pre(); } else if ((geod_S = pj_param(NULL,start, "dS").f) != 0.) { al12 = pj_param(NULL,start, "rA").f; geod_pre(); geod_for(); } else emess(1,"incomplete geodesic/arc info"); if ((n_alpha = pj_param(NULL,start, "in_A").i) > 0) { if (!(del_alpha = pj_param(NULL,start, "rdel_A").f)) emess(1,"del azimuth == 0"); } else if ((del_S = fabs(pj_param(NULL,start, "ddel_S").f)) != 0.) { n_S = (int)(geod_S / del_S + .5); } else if ((n_S = pj_param(NULL,start, "in_S").i) <= 0) emess(1,"no interval divisor selected"); } /* free up linked list */ for ( ; start; start = curr) { curr = start->next; pj_dalloc(start); } }
PJ_INIT_INFO proj_init_info(const char *initname){ /****************************************************************************** Information about a named init file. Maximum length of initname is 64. Returns PJ_INIT_INFO struct. If the init file is not found all members of the return struct are set to the empty string. If the init file is found, but the metadata is missing, the value is set to "Unknown". ******************************************************************************/ int file_found; char param[80], key[74]; paralist *start, *next; PJ_INIT_INFO ininfo; PJ_CONTEXT *ctx = pj_get_default_ctx(); memset(&ininfo, 0, sizeof(PJ_INIT_INFO)); file_found = pj_find_file(ctx, initname, ininfo.filename, sizeof(ininfo.filename)); if (!file_found || strlen(initname) > 64) { return ininfo; } /* The initial memset (0) makes strncpy safe here */ strncpy (ininfo.name, initname, sizeof(ininfo.name) - 1); strcpy(ininfo.origin, "Unknown"); strcpy(ininfo.version, "Unknown"); strcpy(ininfo.lastupdate, "Unknown"); strncpy (key, initname, 64); /* make room for ":metadata\0" at the end */ key[64] = 0; strncat(key, ":metadata", 9); strcpy(param, "+init="); /* The +strlen(param) avoids a cppcheck false positive warning */ strncat(param + strlen(param), key, sizeof(param)-1-strlen(param)); start = pj_mkparam(param); pj_expand_init(ctx, start); if (pj_param(ctx, start, "tversion").i) strncpy(ininfo.version, pj_param(ctx, start, "sversion").s, sizeof(ininfo.version) - 1); if (pj_param(ctx, start, "torigin").i) strncpy(ininfo.origin, pj_param(ctx, start, "sorigin").s, sizeof(ininfo.origin) - 1); if (pj_param(ctx, start, "tlastupdate").i) strncpy(ininfo.lastupdate, pj_param(ctx, start, "slastupdate").s, sizeof(ininfo.lastupdate) - 1); for ( ; start; start = next) { next = start->next; pj_dalloc(start); } return ininfo; }
/** Returns the PROJ.4 initialization string suitable for use with pj_init_plus() that would produce this coordinate system, but with the definition expanded as much as possible (for instance +init= and +datum= definitions). @param options Unused at this point */ std::string get_def(int options=0) const { char *pj_def = 0; pj_def = pj_get_def(pj, options); std::string ret = std::string(pj_def); pj_dalloc(pj_def); return ret; }
void pj_free(PJ *P) { if (P) { paralist *t = P->params, *n; /* free parameter list elements */ for (t = P->params; t; t = n) { n = t->next; pj_dalloc(t); } /* free array of grid pointers if we have one */ if( P->gridlist != NULL ) pj_dalloc( P->gridlist ); /* free projection parameters */ P->pfree(P); } }
void pj_insert_initcache( const char *filekey, const paralist *list ) { pj_acquire_lock(); /* ** Grow list if required. */ if( cache_count == cache_alloc ) { char **cache_key_new; paralist **cache_paralist_new; cache_alloc = cache_alloc * 2 + 15; cache_key_new = (char **) pj_malloc(sizeof(char*) * cache_alloc); memcpy( cache_key, cache_key_new, sizeof(char*) * cache_count); pj_dalloc( cache_key ); cache_key = cache_key_new; cache_paralist_new = (paralist **) pj_malloc(sizeof(paralist*) * cache_alloc); memcpy( cache_paralist_new, cache_paralist, sizeof(paralist*) * cache_count ); pj_dalloc( cache_paralist ); cache_paralist = cache_paralist_new; } /* ** Duplicate the filekey and paralist, and insert in cache. */ cache_key[cache_count] = (char *) pj_malloc(strlen(filekey)+1); strcpy( cache_key[cache_count], filekey ); cache_paralist[cache_count] = pj_clone_paralist( list ); cache_count++; pj_release_lock(); }
Handle<Value> Projection::GetDefinition(Local<String> name, const AccessorInfo& info) { HandleScope scope; Projection *self = ObjectWrap::Unwrap<Projection>(info.Holder()); char *def; Handle<Value> def_obj; def = pj_get_def(self->pj, 0); def_obj = String::New(def); pj_dalloc(def); return scope.Close(def_obj); }
static VALUE method_proj4_canonical_str(VALUE self) { VALUE result = Qnil; projPJ pj = RGEO_PROJ4_DATA_PTR(self)->pj; if (pj) { char* str = pj_get_def(pj, 0); if (str) { result = rb_str_new2(str); pj_dalloc(str); } } return result; }
PJ * pj_init_plus( const char *definition ) { #define MAX_ARG 200 char *argv[MAX_ARG]; char *defn_copy; int argc = 0, i; PJ *result; /* make a copy that we can manipulate */ defn_copy = (char *) pj_malloc( strlen(definition)+1 ); strcpy( defn_copy, definition ); /* split into arguments based on '+' and trim white space */ for( i = 0; defn_copy[i] != '\0'; i++ ) { switch( defn_copy[i] ) { case '+': if( i == 0 || defn_copy[i-1] == '\0' ) { if( argc+1 == MAX_ARG ) { pj_errno = -44; return NULL; } argv[argc++] = defn_copy + i + 1; } break; case ' ': case '\t': case '\n': defn_copy[i] = '\0'; break; default: /* do nothing */; } } /* perform actual initialization */ result = pj_init( argc, argv ); pj_dalloc( defn_copy ); return result; }
static projectionObj* msGetProjectNormalized( const projectionObj* p ) { int i; char* pszNewProj4Def; projectionObj* pnew; pnew = (projectionObj*)msSmallMalloc(sizeof(projectionObj)); msInitProjection(pnew); msCopyProjection(pnew, (projectionObj*)p); if(p->proj == NULL ) return pnew; /* Normalize definition so that msProjectDiffers() works better */ pszNewProj4Def = pj_get_def( p->proj, 0 ); msFreeCharArray(pnew->args, pnew->numargs); pnew->args = msStringSplit(pszNewProj4Def,'+', &pnew->numargs); for(i = 0; i < pnew->numargs; i++) { /* Remove trailing space */ if( strlen(pnew->args[i]) > 0 && pnew->args[i][strlen(pnew->args[i])-1] == ' ' ) pnew->args[i][strlen(pnew->args[i])-1] = '\0'; /* Remove spurious no_defs or init= */ if( strcmp(pnew->args[i], "no_defs") == 0 || strncmp(pnew->args[i], "init=", 5) == 0 ) { if( i < pnew->numargs - 1 ) { msFree(pnew->args[i]); memmove(pnew->args + i, pnew->args + i + 1, sizeof(char*) * (pnew->numargs - 1 -i )); } pnew->numargs --; i --; continue; } } /* Sort the strings so they can be compared */ qsort(pnew->args, pnew->numargs, sizeof(char*), msProjectSortString); /*{ fprintf(stderr, "'%s' =\n", pszNewProj4Def); for(i = 0; i < p->numargs; i++) fprintf(stderr, "'%s' ", p->args[i]); fprintf(stderr, "\n"); }*/ pj_dalloc(pszNewProj4Def); return pnew; }
void pj_free(PJ *P) { if (P) { paralist *t = P->params, *n; /* free parameter list elements */ for (t = P->params; t; t = n) { n = t->next; pj_dalloc(t); } /* free projection parameters */ P->pfree(P); } }
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; } }
/*! * \brief * retrieves projection parameters * * JNI informations: * Class: org_proj4_Projections * Method: getProjInfo * Signature: (Ljava/lang/String;)Ljava/lang/String; * * * \param env - parameter used by jni (see JNI specification) * \param parent - parameter used by jni (see JNI specification) * \param projdefinition - definition of the projection */ JNIEXPORT jstring JNICALL Java_org_proj4_Projections_getProjInfo (JNIEnv * env, jobject parent, jstring projdefinition) { PJ *pj; char * pjdesc; char info[arraysize]; char * proj_def = (char *) (*env)->GetStringUTFChars (env, projdefinition, 0); if (!(pj = pj_init_plus(proj_def))) exit(1); // put together all the info of the projection and free the pointer to pjdesc pjdesc = pj_get_def(pj, 0); strcpy(info,pjdesc); pj_dalloc(pjdesc); return (*env)->NewStringUTF(env,info); }
char *pj_get_def( PJ *P, int options ) { paralist *t; int l; char *definition; size_t def_max = 10; (void) options; definition = (char *) pj_malloc(def_max); definition[0] = '\0'; for (t = P->params; t; t = t->next) { /* skip unused parameters ... mostly appended defaults and stuff */ if (!t->used) continue; /* grow the resulting string if needed */ l = strlen(t->param) + 1; if( strlen(definition) + l + 5 > def_max ) { char *def2; def_max = def_max * 2 + l + 5; def2 = (char *) pj_malloc(def_max); strcpy( def2, definition ); pj_dalloc( definition ); definition = def2; } /* append this parameter */ strcat( definition, " +" ); strcat( definition, t->param ); } return definition; }
void print_proj4(int dontprettify) { struct pj_info pjinfo; char *proj4, *proj4mod, *i; const char *unfact; if (check_xy(FALSE)) return; if (pj_get_kv(&pjinfo, projinfo, projunits) == -1) G_fatal_error(_("Unable to convert projection information to PROJ.4 format")); proj4 = pj_get_def(pjinfo.pj, 0); pj_free(pjinfo.pj); /* GRASS-style PROJ.4 strings don't include a unit factor as this is * handled separately in GRASS - must include it here though */ unfact = G_find_key_value("meters", projunits); if (unfact != NULL && (strcmp(pjinfo.proj, "ll") != 0)) G_asprintf(&proj4mod, "%s +to_meter=%s", proj4, unfact); else proj4mod = G_store(proj4); pj_dalloc(proj4); for (i = proj4mod; *i; i++) { /* Don't print the first space */ if (i == proj4mod && *i == ' ') continue; if (*i == ' ' && *(i+1) == '+' && !(dontprettify)) fputc('\n', stdout); else fputc(*i, stdout); } fputc('\n', stdout); G_free(proj4mod); return; }
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; }
PJ * pj_init(int argc, char **argv) { char *s, *name; paralist *start = NULL; PJ *(*proj)(PJ *); paralist *curr; int i; PJ *PIN = 0; const char *old_locale; errno = pj_errno = 0; start = NULL; old_locale = setlocale(LC_NUMERIC, NULL); setlocale(LC_NUMERIC,"C"); /* put arguments into internal linked list */ if (argc <= 0) { pj_errno = -1; goto bum_call; } for (i = 0; i < argc; ++i) if (i) curr = curr->next = pj_mkparam(argv[i]); else start = curr = pj_mkparam(argv[i]); if (pj_errno) goto bum_call; /* check if +init present */ if (pj_param(start, "tinit").i) { paralist *last = curr; if (!(curr = get_init(&start, curr, pj_param(start, "sinit").s))) goto bum_call; if (curr == last) { pj_errno = -2; goto bum_call; } } /* find projection selection */ if (!(name = pj_param(start, "sproj").s)) { pj_errno = -4; goto bum_call; } for (i = 0; (s = pj_list[i].id) && strcmp(name, s) ; ++i) ; if (!s) { pj_errno = -5; goto bum_call; } /* set defaults, unless inhibited */ if (!pj_param(start, "bno_defs").i) curr = get_defaults(&start, curr, name); proj = (PJ *(*)(PJ *)) pj_list[i].proj; /* allocate projection structure */ if (!(PIN = (*proj)(0))) goto bum_call; PIN->params = start; PIN->is_latlong = 0; PIN->is_geocent = 0; PIN->long_wrap_center = 0.0; /* set datum parameters */ if (pj_datum_set(start, PIN)) goto bum_call; /* set ellipsoid/sphere parameters */ if (pj_ell_set(start, &PIN->a, &PIN->es)) goto bum_call; PIN->a_orig = PIN->a; PIN->es_orig = PIN->es; PIN->e = sqrt(PIN->es); PIN->ra = 1. / PIN->a; PIN->one_es = 1. - PIN->es; if (PIN->one_es == 0.) { pj_errno = -6; goto bum_call; } PIN->rone_es = 1./PIN->one_es; /* Now that we have ellipse information check for WGS84 datum */ if( PIN->datum_type == PJD_3PARAM && PIN->datum_params[0] == 0.0 && PIN->datum_params[1] == 0.0 && PIN->datum_params[2] == 0.0 && PIN->a == 6378137.0 && ABS(PIN->es - 0.006694379990) < 0.000000000050 )/*WGS84/GRS80*/ { PIN->datum_type = PJD_WGS84; } /* set PIN->geoc coordinate system */ PIN->geoc = (PIN->es && pj_param(start, "bgeoc").i); /* over-ranging flag */ PIN->over = pj_param(start, "bover").i; /* longitude center for wrapping */ PIN->long_wrap_center = pj_param(start, "rlon_wrap").f; /* central meridian */ PIN->lam0=pj_param(start, "rlon_0").f; /* central latitude */ PIN->phi0 = pj_param(start, "rlat_0").f; /* false easting and northing */ PIN->x0 = pj_param(start, "dx_0").f; PIN->y0 = pj_param(start, "dy_0").f; /* general scaling factor */ if (pj_param(start, "tk_0").i) PIN->k0 = pj_param(start, "dk_0").f; else if (pj_param(start, "tk").i) PIN->k0 = pj_param(start, "dk").f; else PIN->k0 = 1.; if (PIN->k0 <= 0.) { pj_errno = -31; goto bum_call; } /* set units */ s = 0; if ((name = pj_param(start, "sunits").s)) { for (i = 0; (s = pj_units[i].id) && strcmp(name, s) ; ++i) ; if (!s) { pj_errno = -7; goto bum_call; } s = pj_units[i].to_meter; } if (s || (s = pj_param(start, "sto_meter").s)) { PIN->to_meter = strtod(s, &s); if (*s == '/') /* ratio number */ PIN->to_meter /= strtod(++s, 0); PIN->fr_meter = 1. / PIN->to_meter; } else PIN->to_meter = PIN->fr_meter = 1.; /* prime meridian */ s = 0; if ((name = pj_param(start, "spm").s)) { const char *value = NULL; char *next_str = NULL; for (i = 0; pj_prime_meridians[i].id != NULL; ++i ) { if( strcmp(name,pj_prime_meridians[i].id) == 0 ) { value = pj_prime_meridians[i].defn; break; } } if( value == NULL && (dmstor(name,&next_str) != 0.0 || *name == '0') && *next_str == '\0' ) value = name; if (!value) { pj_errno = -46; goto bum_call; } PIN->from_greenwich = dmstor(value,NULL); } else PIN->from_greenwich = 0.0; /* projection specific initialization */ if (!(PIN = (*proj)(PIN)) || errno || pj_errno) { bum_call: /* cleanup error return */ if (!pj_errno) pj_errno = errno; if (PIN) pj_free(PIN); else for ( ; start; start = curr) { curr = start->next; pj_dalloc(start); } PIN = 0; } setlocale(LC_NUMERIC,old_locale); return PIN; }
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; }
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; }
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; } }