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