1 /****************************************************************************** 2 * $Id: projects.h 2121 2011-11-22 22:51:47Z warmerdam $ 3 * 4 * Project: PROJ.4 5 * Purpose: Primary (private) include file for PROJ.4 library. 6 * Author: Gerald Evenden 7 * 8 ****************************************************************************** 9 * Copyright (c) 2000, Frank Warmerdam 10 * 11 * Permission is hereby granted, free of charge, to any person obtaining a 12 * copy of this software and associated documentation files (the "Software"), 13 * to deal in the Software without restriction, including without limitation 14 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 15 * and/or sell copies of the Software, and to permit persons to whom the 16 * Software is furnished to do so, subject to the following conditions: 17 * 18 * The above copyright notice and this permission notice shall be included 19 * in all copies or substantial portions of the Software. 20 * 21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 24 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 27 * DEALINGS IN THE SOFTWARE. 28 *****************************************************************************/ 29 30 /* General projections header file */ 31 #ifndef PROJECTS_H 32 #define PROJECTS_H 33 34 #ifdef _MSC_VER 35 # ifndef _CRT_SECURE_NO_DEPRECATE 36 # define _CRT_SECURE_NO_DEPRECATE 37 # endif 38 # ifndef _CRT_NONSTDC_NO_DEPRECATE 39 # define _CRT_NONSTDC_NO_DEPRECATE 40 # endif 41 #endif 42 43 /* standard inclusions */ 44 #include <math.h> 45 #include <stdio.h> 46 #include <stdlib.h> 47 #include <string.h> 48 49 #ifdef __cplusplus 50 #define C_NAMESPACE extern "C" 51 #define C_NAMESPACE_VAR extern "C" 52 extern "C" { 53 #else 54 #define C_NAMESPACE extern 55 #define C_NAMESPACE_VAR 56 #endif 57 58 #ifndef NULL 59 # define NULL 0 60 #endif 61 62 #ifndef FALSE 63 # define FALSE 0 64 #endif 65 66 #ifndef TRUE 67 # define TRUE 1 68 #endif 69 70 #ifndef MAX 71 # define MIN(a,b) ((a<b) ? a : b) 72 # define MAX(a,b) ((a>b) ? a : b) 73 #endif 74 75 #ifndef ABS 76 # define ABS(x) ((x<0) ? (-1*(x)) : x) 77 #endif 78 79 /* maximum path/filename */ 80 #ifndef MAX_PATH_FILENAME 81 #define MAX_PATH_FILENAME 1024 82 #endif 83 /* prototype hypot for systems where absent */ 84 #ifndef _WIN32 85 extern double hypot(double, double); 86 #endif 87 88 #ifdef _WIN32_WCE 89 # include <wce_stdlib.h> 90 # include <wce_stdio.h> 91 # define rewind wceex_rewind 92 # define getenv wceex_getenv 93 # define strdup _strdup 94 # define hypot _hypot 95 #endif 96 97 /* some useful constants */ 98 #define HALFPI 1.5707963267948966 99 #define FORTPI 0.78539816339744833 100 #define PI 3.14159265358979323846 101 #define TWOPI 6.2831853071795864769 102 103 /* environment parameter name */ 104 #ifndef PROJ_LIB 105 #define PROJ_LIB "PROJ_LIB" 106 #endif 107 /* maximum tag id length for +init and default files */ 108 #ifndef ID_TAG_MAX 109 #define ID_TAG_MAX 50 110 #endif 111 112 /* Use WIN32 as a standard windows 32 bit declaration */ 113 #if defined(_WIN32) && !defined(WIN32) && !defined(_WIN32_WCE) 114 # define WIN32 115 #endif 116 117 #if defined(_WINDOWS) && !defined(WIN32) && !defined(_WIN32_WCE) 118 # define WIN32 119 #endif 120 121 /* directory delimiter for DOS support */ 122 #ifdef WIN32 123 #define DIR_CHAR '\\' 124 #else 125 #define DIR_CHAR '/' 126 #endif 127 128 /* proj thread context */ 129 typedef struct { 130 int last_errno; 131 int debug_level; 132 void (*logger)(void *, int, const char *); 133 void *app_data; 134 } projCtx_t; 135 136 /* datum_type values */ 137 #define PJD_UNKNOWN 0 138 #define PJD_3PARAM 1 139 #define PJD_7PARAM 2 140 #define PJD_GRIDSHIFT 3 141 #define PJD_WGS84 4 /* WGS84 (or anything considered equivelent) */ 142 143 /* library errors */ 144 #define PJD_ERR_GEOCENTRIC -45 145 #define PJD_ERR_AXIS -47 146 #define PJD_ERR_GRID_AREA -48 147 148 #define USE_PROJUV 149 150 typedef struct { double u, v; } projUV; 151 typedef struct { double r, i; } COMPLEX; 152 153 #ifndef PJ_LIB__ 154 #define XY projUV 155 #define LP projUV 156 #else 157 typedef struct { double x, y; } XY; 158 typedef struct { double lam, phi; } LP; 159 #endif 160 161 typedef union { double f; int i; char *s; } PVALUE; 162 struct PJconsts; 163 164 struct PJ_LIST { 165 char *id; /* projection keyword */ 166 struct PJconsts *(*proj)(struct PJconsts*);/* projection entry point */ 167 char * const *descr; /* description text */ 168 }; 169 struct PJ_ELLPS { 170 char *id; /* ellipse keyword name */ 171 char *major; /* a= value */ 172 char *ell; /* elliptical parameter */ 173 char *name; /* comments */ 174 }; 175 struct PJ_UNITS { 176 char *id; /* units keyword */ 177 char *to_meter; /* multiply by value to get meters */ 178 char *name; /* comments */ 179 }; 180 181 struct PJ_DATUMS { 182 char *id; /* datum keyword */ 183 char *defn; /* ie. "to_wgs84=..." */ 184 char *ellipse_id; /* ie from ellipse table */ 185 char *comments; /* EPSG code, etc */ 186 }; 187 188 struct PJ_PRIME_MERIDIANS { 189 char *id; /* prime meridian keyword */ 190 char *defn; /* offset from greenwich in DMS format. */ 191 }; 192 193 struct DERIVS { 194 double x_l, x_p; /* derivatives of x for lambda-phi */ 195 double y_l, y_p; /* derivatives of y for lambda-phi */ 196 }; 197 198 struct FACTORS { 199 struct DERIVS der; 200 double h, k; /* meridinal, parallel scales */ 201 double omega, thetap; /* angular distortion, theta prime */ 202 double conv; /* convergence */ 203 double s; /* areal scale factor */ 204 double a, b; /* max-min scale error */ 205 int code; /* info as to analytics, see following */ 206 }; 207 #define IS_ANAL_XL_YL 01 /* derivatives of lon analytic */ 208 #define IS_ANAL_XP_YP 02 /* derivatives of lat analytic */ 209 #define IS_ANAL_HK 04 /* h and k analytic */ 210 #define IS_ANAL_CONV 010 /* convergence analytic */ 211 /* parameter list struct */ 212 typedef struct ARG_list { 213 struct ARG_list *next; 214 char used; 215 char param[1]; } paralist; 216 /* base projection data structure */ 217 218 219 typedef struct PJconsts { 220 projCtx_t *ctx; 221 XY (*fwd)(LP, struct PJconsts *); 222 LP (*inv)(XY, struct PJconsts *); 223 void (*spc)(LP, struct PJconsts *, struct FACTORS *); 224 void (*pfree)(struct PJconsts *); 225 const char *descr; 226 paralist *params; /* parameter list */ 227 int over; /* over-range flag */ 228 int geoc; /* geocentric latitude flag */ 229 int is_latlong; /* proj=latlong ... not really a projection at all */ 230 int is_geocent; /* proj=geocent ... not really a projection at all */ 231 double 232 a, /* major axis or radius if es==0 */ 233 a_orig, /* major axis before any +proj related adjustment */ 234 es, /* e ^ 2 */ 235 es_orig, /* es before any +proj related adjustment */ 236 e, /* eccentricity */ 237 ra, /* 1/A */ 238 one_es, /* 1 - e^2 */ 239 rone_es, /* 1/one_es */ 240 lam0, phi0, /* central longitude, latitude */ 241 x0, y0, /* easting and northing */ 242 k0, /* general scaling factor */ 243 to_meter, fr_meter; /* cartesian scaling */ 244 245 int datum_type; /* PJD_UNKNOWN/3PARAM/7PARAM/GRIDSHIFT/WGS84 */ 246 double datum_params[7]; 247 struct _pj_gi **gridlist; 248 int gridlist_count; 249 250 int has_geoid_vgrids; 251 struct _pj_gi **vgridlist_geoid; 252 int vgridlist_geoid_count; 253 double vto_meter, vfr_meter; 254 255 double from_greenwich; /* prime meridian offset (in radians) */ 256 double long_wrap_center; /* 0.0 for -180 to 180, actually in radians*/ 257 int is_long_wrap_set; 258 char axis[4]; 259 260 #ifdef PROJ_PARMS__ 261 PROJ_PARMS__ 262 #endif /* end of optional extensions */ 263 } PJ; 264 265 /* public API */ 266 #include "proj_api.h" 267 268 /* Generate pj_list external or make list from include file */ 269 #ifndef PJ_LIST_H 270 extern struct PJ_LIST pj_list[]; 271 #else 272 #define PROJ_HEAD(id, name) \ 273 struct PJconsts *pj_##id(struct PJconsts*); extern char * const pj_s_##id; 274 275 #ifndef lint 276 #define DO_PJ_LIST_ID 277 #endif 278 #include PJ_LIST_H 279 #ifndef lint 280 #undef DO_PJ_LIST_ID 281 #endif 282 #undef PROJ_HEAD 283 #define PROJ_HEAD(id, name) {#id, pj_##id, &pj_s_##id}, 284 struct PJ_LIST 285 pj_list[] = { 286 #include PJ_LIST_H 287 {0, 0, 0}, 288 }; 289 #undef PROJ_HEAD 290 #endif 291 292 #ifndef PJ_ELLPS__ 293 extern struct PJ_ELLPS pj_ellps[]; 294 #endif 295 296 #ifndef PJ_UNITS__ 297 extern struct PJ_UNITS pj_units[]; 298 #endif 299 300 #ifndef PJ_DATUMS__ 301 extern struct PJ_DATUMS pj_datums[]; 302 extern struct PJ_PRIME_MERIDIANS pj_prime_meridians[]; 303 #endif 304 305 #ifdef PJ_LIB__ 306 /* repeatative projection code */ 307 #define PROJ_HEAD(id, name) static const char des_##id [] = name 308 #define ENTRYA(name) \ 309 C_NAMESPACE_VAR const char * const pj_s_##name = des_##name; \ 310 C_NAMESPACE PJ *pj_##name(PJ *P) { if (!P) { \ 311 if( (P = (PJ*) pj_malloc(sizeof(PJ))) != NULL) { \ 312 memset( P, 0, sizeof(PJ) ); \ 313 P->pfree = freeup; P->fwd = 0; P->inv = 0; \ 314 P->spc = 0; P->descr = des_##name; 315 #define ENTRYX } return P; } else { 316 #define ENTRY0(name) ENTRYA(name) ENTRYX 317 #define ENTRY1(name, a) ENTRYA(name) P->a = 0; ENTRYX 318 #define ENTRY2(name, a, b) ENTRYA(name) P->a = 0; P->b = 0; ENTRYX 319 #define ENDENTRY(p) } return (p); } 320 #define E_ERROR(err) { pj_ctx_set_errno( P->ctx, err); freeup(P); return(0); } 321 #define E_ERROR_0 { freeup(P); return(0); } 322 #define F_ERROR { pj_ctx_set_errno( P->ctx, -20); return(xy); } 323 #define I_ERROR { pj_ctx_set_errno( P->ctx, -20); return(lp); } 324 #define FORWARD(name) static XY name(LP lp, PJ *P) { XY xy = {0.0,0.0} 325 #define INVERSE(name) static LP name(XY xy, PJ *P) { LP lp = {0.0,0.0} 326 #define FREEUP static void freeup(PJ *P) { 327 #define SPECIAL(name) static void name(LP lp, PJ *P, struct FACTORS *fac) 328 #endif 329 #define MAX_TAB_ID 80 330 typedef struct { float lam, phi; } FLP; 331 typedef struct { int lam, phi; } ILP; 332 333 struct CTABLE { 334 char id[MAX_TAB_ID]; /* ascii info */ 335 LP ll; /* lower left corner coordinates */ 336 LP del; /* size of cells */ 337 ILP lim; /* limits of conversion matrix */ 338 FLP *cvs; /* conversion matrix */ 339 }; 340 341 typedef struct _pj_gi { 342 char *gridname; /* identifying name of grid, eg "conus" or ntv2_0.gsb */ 343 char *filename; /* full path to filename */ 344 345 const char *format; /* format of this grid, ie "ctable", "ntv1", 346 "ntv2" or "missing". */ 347 348 int grid_offset; /* offset in file, for delayed loading */ 349 350 struct CTABLE *ct; 351 352 struct _pj_gi *next; 353 struct _pj_gi *child; 354 } PJ_GRIDINFO; 355 356 /* procedure prototypes */ 357 double dmstor(const char *, char **); 358 double dmstor_ctx(projCtx ctx, const char *, char **); 359 void set_rtodms(int, int); 360 char *rtodms(char *, double, int, int); 361 double adjlon(double); 362 double aacos(projCtx,double), aasin(projCtx,double), asqrt(double), aatan2(double, double); 363 PVALUE pj_param(projCtx ctx, paralist *, const char *); 364 paralist *pj_mkparam(char *); 365 int pj_ell_set(projCtx ctx, paralist *, double *, double *); 366 int pj_datum_set(projCtx,paralist *, PJ *); 367 int pj_prime_meridian_set(paralist *, PJ *); 368 int pj_angular_units_set(paralist *, PJ *); 369 370 paralist *pj_clone_paralist( const paralist* ); 371 paralist*pj_search_initcache( const char *filekey ); 372 void pj_insert_initcache( const char *filekey, const paralist *list); 373 374 double *pj_enfn(double); 375 double pj_mlfn(double, double, double, double *); 376 double pj_inv_mlfn(projCtx, double, double, double *); 377 double pj_qsfn(double, double, double); 378 double pj_tsfn(double, double, double); 379 double pj_msfn(double, double, double); 380 double pj_phi2(projCtx, double, double); 381 double pj_qsfn_(double, PJ *); 382 double *pj_authset(double); 383 double pj_authlat(double, double *); 384 COMPLEX pj_zpoly1(COMPLEX, COMPLEX *, int); 385 COMPLEX pj_zpolyd1(COMPLEX, COMPLEX *, int, COMPLEX *); 386 FILE *pj_open_lib(projCtx, char *, char *); 387 388 int pj_deriv(LP, double, PJ *, struct DERIVS *); 389 int pj_factors(LP, PJ *, double, struct FACTORS *); 390 391 struct PW_COEF {/* row coefficient structure */ 392 int m; /* number of c coefficients (=0 for none) */ 393 double *c; /* power coefficients */ 394 }; 395 396 /* Approximation structures and procedures */ 397 typedef struct { /* Chebyshev or Power series structure */ 398 projUV a, b; /* power series range for evaluation */ 399 /* or Chebyshev argument shift/scaling */ 400 struct PW_COEF *cu, *cv; 401 int mu, mv; /* maximum cu and cv index (+1 for count) */ 402 int power; /* != 0 if power series, else Chebyshev */ 403 } Tseries; 404 Tseries *mk_cheby(projUV, projUV, double, projUV *, projUV (*)(projUV), int, int, int); 405 projUV bpseval(projUV, Tseries *); 406 projUV bcheval(projUV, Tseries *); 407 projUV biveval(projUV, Tseries *); 408 void *vector1(int, int); 409 void **vector2(int, int, int); 410 void freev2(void **v, int nrows); 411 int bchgen(projUV, projUV, int, int, projUV **, projUV(*)(projUV)); 412 int bch2bps(projUV, projUV, projUV **, int, int); 413 /* nadcon related protos */ 414 LP nad_intr(LP, struct CTABLE *); 415 LP nad_cvt(LP, int, struct CTABLE *); 416 struct CTABLE *nad_init(projCtx ctx, char *); 417 struct CTABLE *nad_ctable_init( projCtx ctx, FILE * fid ); 418 int nad_ctable_load( projCtx ctx, struct CTABLE *, FILE * fid ); 419 struct CTABLE *nad_ctable2_init( projCtx ctx, FILE * fid ); 420 int nad_ctable2_load( projCtx ctx, struct CTABLE *, FILE * fid ); 421 void nad_free(struct CTABLE *); 422 423 /* higher level handling of datum grid shift files */ 424 425 int pj_apply_vgridshift( PJ *defn, const char *listname, 426 PJ_GRIDINFO ***gridlist_p, 427 int *gridlist_count_p, 428 int inverse, 429 long point_count, int point_offset, 430 double *x, double *y, double *z ); 431 int pj_apply_gridshift_2( PJ *defn, int inverse, 432 long point_count, int point_offset, 433 double *x, double *y, double *z ); 434 int pj_apply_gridshift_3( projCtx ctx, 435 PJ_GRIDINFO **gridlist, int gridlist_count, 436 int inverse, long point_count, int point_offset, 437 double *x, double *y, double *z ); 438 439 PJ_GRIDINFO **pj_gridlist_from_nadgrids( projCtx, const char *, int * ); 440 void pj_deallocate_grids(); 441 442 PJ_GRIDINFO *pj_gridinfo_init( projCtx, const char * ); 443 int pj_gridinfo_load( projCtx, PJ_GRIDINFO * ); 444 void pj_gridinfo_free( projCtx, PJ_GRIDINFO * ); 445 446 void *proj_mdist_ini(double); 447 double proj_mdist(double, double, double, const void *); 448 double proj_inv_mdist(projCtx ctx, double, const void *); 449 void *pj_gauss_ini(double, double, double *,double *); 450 LP pj_gauss(projCtx, LP, const void *); 451 LP pj_inv_gauss(projCtx, LP, const void *); 452 453 extern char const pj_release[]; 454 455 struct PJ_ELLPS *pj_get_ellps_ref( void ); 456 struct PJ_DATUMS *pj_get_datums_ref( void ); 457 struct PJ_UNITS *pj_get_units_ref( void ); 458 struct PJ_LIST *pj_get_list_ref( void ); 459 struct PJ_PRIME_MERIDIANS *pj_get_prime_meridians_ref( void ); 460 461 #ifndef DISABLE_CVSID 462 # if defined(__GNUC__) && __GNUC__ >= 4 463 # define PJ_CVSID(string) static char pj_cvsid[] __attribute__((used)) = string; 464 # else 465 # define PJ_CVSID(string) static char pj_cvsid[] = string; \ 466 static char *cvsid_aw() { return( cvsid_aw() ? ((char *) NULL) : pj_cvsid ); } 467 # endif 468 #else 469 # define PJ_CVSID(string) 470 #endif 471 472 #ifdef __cplusplus 473 } 474 #endif 475 476 #endif /* end of basic projections header */ 477