File: reprojection.c

package info (click to toggle)
osm2pgsql 0.52.20080408-2
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 348 kB
  • ctags: 440
  • sloc: ansic: 3,963; sh: 469; cpp: 339; makefile: 125
file content (111 lines) | stat: -rw-r--r-- 2,533 bytes parent folder | download
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/* reprojection.c
 *
 * Convert OSM lattitude / longitude from degrees to mercator
 * so that Mapnik does not have to project the data again
 *
 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <proj_api.h>

#include "reprojection.h"

static projPJ pj_ll, pj_merc;
static int Proj;
const struct Projection_Info Projection_Info[] = {
  [PROJ_LATLONG] = { 
     descr: "Latlong", 
     proj4text: "(none)", 
     srs:4326, 
     option: "-l" },
  [PROJ_MERC]    = { 
     descr: "WGS84 Mercator", 
     proj4text: "+proj=merc +datum=WGS84  +k=1.0 +units=m +over +no_defs", 
     srs:3395, 
     option: "" },
  [PROJ_SPHERE_MERC] = { 
     descr: "Spherical Mercator",  
     proj4text: "+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +no_defs +over", 
     srs:900913, 
     option: "-m" }
};
static struct Projection_Info custom_projection;

// Positive numbers refer the to the table above, negative numbers are
// assumed to refer to EPSG codes and it uses the proj4 to find those.
void project_init(int proj)
{
	char buffer[16];
	Proj = proj;
	
	if( proj == PROJ_LATLONG )
		return;
		
	pj_ll   = pj_init_plus("+proj=latlong +ellps=GRS80 +no_defs");
	if( proj >= 0 && proj < PROJ_COUNT )
		pj_merc = pj_init_plus( Projection_Info[proj].proj4text );
	else if( proj < 0 )
	{
		sprintf( buffer, "+init=epsg:%d", -proj );
		pj_merc = pj_init_plus( buffer );
		if( !pj_merc )
		{
			fprintf( stderr, "Couldn't read EPSG definition (do you have /usr/share/proj/epsg?)\n" );
			exit(1);
		}
	}
			
	if (!pj_ll || !pj_merc) {
		fprintf(stderr, "Projection code failed to initialise\n");
		exit(1);
	}
	
	if( proj >= 0 )
		return;
	custom_projection.srs = -proj;
	custom_projection.proj4text = pj_get_def( pj_merc, 0 );
	sprintf( buffer, "EPSG:%d", -proj );
	custom_projection.descr = strdup(buffer);
	custom_projection.option = "-E";
	return;
}

void project_exit(void)
{
	if( Proj == PROJ_LATLONG )
		return;
		
	pj_free(pj_ll);
	pj_ll = NULL;
	pj_free(pj_merc);
	pj_merc = NULL;
}

struct Projection_Info const *project_getprojinfo(void)
{
  if( Proj >= 0 )
    return &Projection_Info[Proj];
  else
    return &custom_projection;
}

void reproject(double *lat, double *lon)
{
	double x[1], y[1], z[1];
	
	if( Proj == PROJ_LATLONG )
		return;

	x[0] = *lon * DEG_TO_RAD;
	y[0] = *lat * DEG_TO_RAD;
	z[0] = 0;
	
	pj_transform(pj_ll, pj_merc, 1, 1, x, y, z);
	
	//printf("%.4f\t%.4f -> %.4f\t%.4f\n", *lat, *lon, y[0], x[0]);	
	*lat = y[0];
	*lon = x[0];
}