summaryrefslogtreecommitdiffstats
path: root/friendfinder/util/projection.c
diff options
context:
space:
mode:
Diffstat (limited to 'friendfinder/util/projection.c')
-rw-r--r--friendfinder/util/projection.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/friendfinder/util/projection.c b/friendfinder/util/projection.c
new file mode 100644
index 0000000..d61a168
--- /dev/null
+++ b/friendfinder/util/projection.c
@@ -0,0 +1,96 @@
+#include <proj_api.h>
+#include "projection.h"
+
+struct projection
+{
+ int type;
+ projPJ pj;
+ int argc;
+ char *argv[];
+
+};
+
+static struct projection merc = {
+ PROJECTION_MERC,
+ NULL,
+ 6,
+ {
+ "proj=merc",
+ "datum=WGS84",
+ "k=1.0",
+ "units=m",
+ "over",
+ "no_defs"}
+};
+
+static struct projection utm = {
+ PROJECTION_UTM,
+ NULL,
+ 3,
+ {
+ "proj=utm",
+ "datum=WGS84",
+ "zone=32"
+ }
+};
+
+static struct projection *p;
+
+static inline int
+projection_init(int type)
+{
+ //XXX pj_free()
+ switch(type)
+ {
+ case PROJECTION_UTM:
+ p = &utm;
+ break;
+ case PROJECTION_MERC:
+ p = &merc;
+ break;
+ default:
+ p = NULL;
+ return -1;
+ }
+
+ if(p->pj != NULL)
+ return 0;
+
+ p->pj = pj_init(p->argc, p->argv);
+ if(p->pj == NULL)
+ {
+ p = NULL;
+ return -1;
+ }
+ return 0;
+}
+
+int
+project_latlon(double lat, double lon, int *e, int *n, int type)
+{
+ projUV point;
+ if(projection_init(type))
+ return -1;
+
+ point.u = lon * DEG_TO_RAD;
+ point.v = lat * DEG_TO_RAD;
+ point = pj_fwd(point, p->pj);
+ *e = point.u;
+ *n = point.v;
+ return 0;
+}
+
+int
+project_latlon_inv(int e, int n, double *lat, double *lon, int type)
+{
+ projUV point;
+ if(projection_init(type))
+ return -1;
+
+ point.u = e;
+ point.v = n;
+ point = pj_inv(point, p->pj);
+ *lon = point.u / DEG_TO_RAD;
+ *lat = point.v / DEG_TO_RAD;
+ return 0;
+}