2009-09-14 20:30:35 +00:00
|
|
|
/**********************************************************************
|
|
|
|
* $Id: lwgeodetic.c 4494 2009-09-14 10:54:33Z mcayland $
|
|
|
|
*
|
|
|
|
* PostGIS - Spatial Types for PostgreSQL
|
|
|
|
* Copyright 2009 Paul Ramsey <pramsey@cleverelephant.ca>
|
|
|
|
*
|
|
|
|
* This is free software; you can redistribute and/or modify it under
|
|
|
|
* the terms of the GNU General Public Licence. See the COPYING file.
|
|
|
|
*
|
|
|
|
**********************************************************************/
|
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
#include "libgeom.h"
|
|
|
|
|
2009-09-29 14:39:54 +00:00
|
|
|
extern int gbox_geocentric_slow;
|
|
|
|
|
2009-09-14 20:30:35 +00:00
|
|
|
/**
|
|
|
|
* Point in spherical coordinates on the world. Units of radians.
|
|
|
|
*/
|
2009-09-29 20:44:28 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
2009-09-14 20:30:35 +00:00
|
|
|
double lon;
|
2009-09-30 23:59:01 +00:00
|
|
|
double lat;
|
2009-09-14 20:30:35 +00:00
|
|
|
} GEOGRAPHIC_POINT;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Two-point great circle segment from a to b.
|
|
|
|
*/
|
2009-09-29 20:44:28 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
2009-09-15 19:50:24 +00:00
|
|
|
GEOGRAPHIC_POINT start;
|
|
|
|
GEOGRAPHIC_POINT end;
|
2009-09-14 20:30:35 +00:00
|
|
|
} GEOGRAPHIC_EDGE;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Conversion functions
|
|
|
|
*/
|
|
|
|
#define deg2rad(d) (PI * (d) / 180.0)
|
|
|
|
#define rad2deg(r) (180.0 * (r) / PI)
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Ape a java function
|
|
|
|
*/
|
|
|
|
#define signum(a) ((a) < 0 ? -1 : ((a) > 0 ? 1 : (a)))
|
|
|
|
|
2009-09-29 20:44:28 +00:00
|
|
|
/*
|
2009-09-14 20:30:35 +00:00
|
|
|
** Prototypes for internal functions.
|
|
|
|
*/
|
2009-09-29 18:48:47 +00:00
|
|
|
void geog2cart(GEOGRAPHIC_POINT g, POINT3D *p);
|
|
|
|
void cart2geog(POINT3D p, GEOGRAPHIC_POINT *g);
|
2009-09-15 19:50:24 +00:00
|
|
|
void robust_cross_product(GEOGRAPHIC_POINT p, GEOGRAPHIC_POINT q, POINT3D *a);
|
|
|
|
void x_to_z(POINT3D *p);
|
|
|
|
void y_to_z(POINT3D *p);
|
|
|
|
int edge_point_on_plane(GEOGRAPHIC_EDGE e, GEOGRAPHIC_POINT p);
|
2009-09-29 14:39:54 +00:00
|
|
|
int edge_point_in_cone(GEOGRAPHIC_EDGE e, GEOGRAPHIC_POINT p);
|
2009-10-05 05:05:50 +00:00
|
|
|
int edge_contains_coplanar_point(GEOGRAPHIC_EDGE e, GEOGRAPHIC_POINT p);
|
2009-09-16 22:43:20 +00:00
|
|
|
int edge_contains_point(GEOGRAPHIC_EDGE e, GEOGRAPHIC_POINT p);
|
2009-09-29 18:48:47 +00:00
|
|
|
double z_to_latitude(double z, int top);
|
2009-09-29 20:41:04 +00:00
|
|
|
int clairaut_cartesian(POINT3D start, POINT3D end, GEOGRAPHIC_POINT *g_top, GEOGRAPHIC_POINT *g_bottom);
|
|
|
|
int clairaut_geographic(GEOGRAPHIC_POINT start, GEOGRAPHIC_POINT end, GEOGRAPHIC_POINT *g_top, GEOGRAPHIC_POINT *g_bottom);
|
2009-09-16 18:50:54 +00:00
|
|
|
double sphere_distance(GEOGRAPHIC_POINT s, GEOGRAPHIC_POINT e);
|
2009-09-30 23:59:01 +00:00
|
|
|
double sphere_distance_cartesian(POINT3D s, POINT3D e);
|
2009-09-15 19:50:24 +00:00
|
|
|
int sphere_project(GEOGRAPHIC_POINT r, double distance, double azimuth, GEOGRAPHIC_POINT *n);
|
|
|
|
int edge_calculate_gbox(GEOGRAPHIC_EDGE e, GBOX *gbox);
|
2009-09-29 14:39:54 +00:00
|
|
|
int edge_calculate_gbox_slow(GEOGRAPHIC_EDGE e, GBOX *gbox);
|
2009-09-28 22:45:37 +00:00
|
|
|
int edge_intersection(GEOGRAPHIC_EDGE e1, GEOGRAPHIC_EDGE e2, GEOGRAPHIC_POINT *g);
|
2009-09-30 21:45:58 +00:00
|
|
|
double edge_distance_to_point(GEOGRAPHIC_EDGE e, GEOGRAPHIC_POINT gp, GEOGRAPHIC_POINT *closest);
|
2009-09-30 23:59:01 +00:00
|
|
|
double edge_distance_to_edge(GEOGRAPHIC_EDGE e1, GEOGRAPHIC_EDGE e2, GEOGRAPHIC_POINT *closest1, GEOGRAPHIC_POINT *closest2);
|
2009-09-28 22:45:37 +00:00
|
|
|
void edge_deg2rad(GEOGRAPHIC_EDGE *e);
|
|
|
|
void edge_rad2deg(GEOGRAPHIC_EDGE *e);
|
|
|
|
void point_deg2rad(GEOGRAPHIC_POINT *p);
|
|
|
|
void point_rad2deg(GEOGRAPHIC_POINT *p);
|
2009-09-30 23:59:01 +00:00
|
|
|
void geographic_point_init(double lon, double lat, GEOGRAPHIC_POINT *g);
|
2009-10-05 19:38:50 +00:00
|
|
|
int ptarray_point_in_ring_winding(POINTARRAY *pa, POINT2D pt_to_test);
|
2009-10-06 04:50:35 +00:00
|
|
|
int lwpoly_covers_point2d(const LWPOLY *poly, GBOX gbox, POINT2D pt_to_test);
|
2009-10-05 19:43:26 +00:00
|
|
|
int ptarray_point_in_ring(POINTARRAY *pa, POINT2D pt_outside, POINT2D pt_to_test);
|
2009-10-08 05:35:59 +00:00
|
|
|
double ptarray_area_sphere(POINTARRAY *pa, POINT2D pt_outside);
|
2009-10-07 03:38:41 +00:00
|
|
|
double latitude_degrees_normalize(double lat);
|
|
|
|
double longitude_degrees_normalize(double lon);
|
2009-10-31 00:01:45 +00:00
|
|
|
double ptarray_length_spheroid(POINTARRAY *pa, SPHEROID s);
|
2009-10-29 19:24:06 +00:00
|
|
|
int geographic_point_equals(GEOGRAPHIC_POINT g1, GEOGRAPHIC_POINT g2);
|
2009-11-03 00:36:02 +00:00
|
|
|
int crosses_dateline(GEOGRAPHIC_POINT s, GEOGRAPHIC_POINT e);
|
|
|
|
void point_shift(GEOGRAPHIC_POINT *p, double shift);
|
2009-10-31 00:01:45 +00:00
|
|
|
/*
|
|
|
|
** Prototypes for spheroid functions.
|
|
|
|
*/
|
|
|
|
double spheroid_distance(GEOGRAPHIC_POINT a, GEOGRAPHIC_POINT b, SPHEROID spheroid);
|
2009-11-03 00:36:02 +00:00
|
|
|
double spheroid_direction(GEOGRAPHIC_POINT r, GEOGRAPHIC_POINT s, SPHEROID spheroid);
|
|
|
|
int spheroid_project(GEOGRAPHIC_POINT r, SPHEROID spheroid, double distance, double azimuth, GEOGRAPHIC_POINT *g);
|