summaryrefslogtreecommitdiffstats
path: root/friendfinder/util/projection.c
blob: d61a1685f0865838cd9f1d4b05cc259f3248f5e9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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;
}