/*
 * geography.h --
 *
 *	This header file declares general structures, constants, and functions
 *	for basic geographic calculations.  See the Geography(3) man page
 *	for more information.
 * 
 * Copyright (c) 2004 Gordon D. Carrie.  All rights reserved.
 * 
 * Licensed under the Open Software License version 2.1
 * 
 * Please address questions and feedback to user0@tkgeomap.org
 *
 * @(#) $Id: geography.h,v 1.12 2007/06/26 21:49:30 tkgeomap Exp $
 *
 ********************************************
 *
 */


/*
 * Note:
 * Default distance units (unless otherwise noted):
 *   great circle degrees on sphere
 *   meters on Earth's surface
 *   meters on plane
 */

#ifndef _GEOGRAPHY_H_
#define _GEOGRAPHY_H_

#include <float.h>
#include <math.h>
#include <tcl.h>

/*
 * For C++ compilers, use extern "C"
 */

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Macro for prototypes, from tcl.h
 */

#undef _ANSI_ARGS_
#if ((defined(__STDC__) || defined(SABER)) && !defined(NO_PROTOTYPE)) || defined(__cplusplus) || defined(USE_PROTOTYPE)
#   define _USING_PROTOTYPES_ 1
#   define _ANSI_ARGS_(x)	x
#   define CONST const
#else
#   define _ANSI_ARGS_(x)	()
#   define CONST
#endif

/*
 * EXTERN macro for C++, from tcl.h
 */

#ifdef EXTERN
#undef EXTERN
#endif

#ifdef __cplusplus
#   define EXTERN extern "C"
#else
#   define EXTERN extern
#endif

/*
 * Constants for Windows
 */

#if defined(__WIN32__)
#ifndef M_PI
#define M_PI     3.1415926535897932384626433832795
#endif
#ifndef M_PI_2
#define M_PI_2   1.5707963267948966192313216916398
#endif
#ifndef M_PI_4
#define M_PI_4   0.78539816339744830961566084581988
#endif
#endif

/* 
 * Distance units
 */

#define NMI 1852.0
#define SMI 1609.344

/*
 * Angle conversion factors
 */

#define MPERDEG (REarth() * M_PI / 180.0)
#define DEGPERM (180.0 / (REarth() * M_PI))
#define NMIPERDEG (MPERDEG / NMI)
#define SMIPERDEG (MPERDEG / SMI)
#define KMPERDEG (MPERDEG / 1000.0)
#define RADPERDEG 0.017453292519943294892
#define DEGPERRAD 57.29577951308232088
#define DEG_INV 0.002777777777777778

/*
 * The following data type stores angle measurements.
 */

typedef int Angle;

/*
 * This structure stores a geopoint - point on the Earth's surface.
 */

typedef struct
{
  Angle			lat;		/* Latitude */
  Angle			lon;		/* Longitude */
} GeoPt;

/*
 * This structure stores a map-point - a point on a 2D map.
 */

typedef struct
{
  float			abs;		/* Abscissa */
  float			ord;		/* Ordinate */
} MapPt;

/*
 * A point in a 3D Cartesian coordinate system with origin at the Earth's,
 * center, in which Earth has a radius of 1.0.
 */

typedef struct
{
  double		x;
  double		y;
  double		z;
} CartPt;

/*
 * Global functions
 */

#define CKALLOC ckalloc
#define CKFREE ckfree
#define CKREALLOC ckrealloc

EXTERN double	REarth _ANSI_ARGS_((void));
EXTERN void	SetREarth _ANSI_ARGS_((double r));
EXTERN Angle	AngleFmDeg _ANSI_ARGS_((double deg));
EXTERN double	AngleToDeg _ANSI_ARGS_((Angle a));
EXTERN Angle	AngleFmRad _ANSI_ARGS_((double rad));
EXTERN double	AngleToRad _ANSI_ARGS_((Angle a));
EXTERN Angle	BadAngle _ANSI_ARGS_((void));
EXTERN int	AngleIsOK _ANSI_ARGS_((Angle a));
EXTERN int	AngleIsBad _ANSI_ARGS_((Angle a));
EXTERN double	ISin _ANSI_ARGS_((Angle a));
EXTERN double	ICos _ANSI_ARGS_((Angle a));
EXTERN GeoPt	GeoPtFmDeg _ANSI_ARGS_((double dLat, double dLon));
EXTERN GeoPt	GeoPtFmRad _ANSI_ARGS_((double dLat, double dLon));
EXTERN void	GeoPtGetDeg _ANSI_ARGS_((GeoPt geoPt, double *dLatPtr,
			double *dLonPtr));
EXTERN void	GeoPtGetRad _ANSI_ARGS_((GeoPt geoPt, double *dLatPtr,
			double *dLonPtr));
EXTERN CartPt	LatLonToCart _ANSI_ARGS_((GeoPt geoPt));
EXTERN int	GeoPtIsSomewhere _ANSI_ARGS_((GeoPt geoPt));
EXTERN int	GeoPtIsNowhere _ANSI_ARGS_((GeoPt geoPt));
EXTERN GeoPt	GeoPtNowhere _ANSI_ARGS_((void));
EXTERN int	MapPtIsSomewhere _ANSI_ARGS_((MapPt mapPt));
EXTERN int	MapPtIsNowhere _ANSI_ARGS_((MapPt mapPt));
EXTERN MapPt	MapPtNowhere _ANSI_ARGS_((void));
EXTERN MapPt	ScaleMapPt _ANSI_ARGS_((MapPt mapPt, double scale));
EXTERN GeoPt	GeoStep _ANSI_ARGS_((GeoPt geoPt, Angle dir, Angle dist));
EXTERN Angle	GeoDistance _ANSI_ARGS_((GeoPt p1, GeoPt p2));
EXTERN double	GeoQuickDistance _ANSI_ARGS_((GeoPt p1, GeoPt p2));
EXTERN Angle	Azimuth _ANSI_ARGS_((GeoPt p1, GeoPt p2));
EXTERN GeoPt	GCircleX _ANSI_ARGS_((GeoPt ln1pt1, GeoPt ln1pt2, GeoPt ln2pt1,
	    		GeoPt ln2pt2));

/*
 * These constants specify relative Cardinal directions.
 */

enum LatSgn {North, Eq, South};
enum LonSgn {West, PrMd, East};

/*
 * Global functions for comparing angles and putting them into domains.
 */

EXTERN Angle	DomainLat _ANSI_ARGS_((Angle lat));
EXTERN Angle	DomainLon _ANSI_ARGS_((Angle lon, Angle refLon));
EXTERN Angle	GwchLon _ANSI_ARGS_((Angle lon));
EXTERN GeoPt	DomainLonPt _ANSI_ARGS_((GeoPt geoPt, Angle refLon));
EXTERN GeoPt	GwchLonPt _ANSI_ARGS_((GeoPt geoPt));
EXTERN enum	LonSgn LonCmp _ANSI_ARGS_((Angle lon0, Angle lon1));
EXTERN enum	LatSgn LatCmp _ANSI_ARGS_((Angle lat0, Angle lat1));
EXTERN int	AngleCmp _ANSI_ARGS_((Angle d0, Angle d1));
EXTERN int	LonBtwn _ANSI_ARGS_((Angle lon, Angle lon0, Angle lon1));
EXTERN int	LonBtwn1 _ANSI_ARGS_((Angle lon, Angle lon0, Angle lon1));

/*
 * This structure stores a time instant as a Julian day and seconds
 * since midnight.
 */

struct GeoTime_Jul {
    int   day;		/* Julian day */
    double second;	/* Seconds since midnight */
};

/*
 * This structure stores a time instant as a calendar date and clock time.
 */

struct GeoTime_Cal {
    int year;
    int month;
    int day;
    int hour;
    int minute;
    double second;
};

/*
 * The following functions convert between time representations.
 */

struct GeoTime_Cal GeoTime_CalSet(int year, int month, int day, int hour,
	int minute, double second);
struct GeoTime_Jul GeoTime_JulSet(int day, double second);
struct GeoTime_Jul GeoTime_CalToJul(struct GeoTime_Cal cal);
struct GeoTime_Cal GeoTime_JulToCal(struct GeoTime_Jul jul);
void GeoTime_Incr(struct GeoTime_Jul *jul, double ds);
int GeoTime_Cmp(struct GeoTime_Jul jul1, struct GeoTime_Jul jul2);
double GeoTime_Diff(struct GeoTime_Jul jul1, struct GeoTime_Jul jul2);

/*
 * end block for C++
 */
    
#ifdef __cplusplus
}
#endif

#endif


syntax highlighted by Code2HTML, v. 0.9.1