summaryrefslogblamecommitdiffstats
path: root/friendfinder/util/projection.c
blob: d61a1685f0865838cd9f1d4b05cc259f3248f5e9 (plain) (tree)































































































                                                                    
#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;
}