summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2009-05-27 13:45:54 +0000
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2009-05-27 13:45:54 +0000
commit1cf3ebc267ec6d5358990e79b3e38ffe8e2de729 (patch)
tree9697447235e4b6552da83f2163b6f0fc1c4e2350
parent6a69500ae9abb0bac14804d439f4d79a6cba8d48 (diff)
downloadnavit-1cf3ebc267ec6d5358990e79b3e38ffe8e2de729.tar.gz
Add:Core:Added support for utm projection
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@2291 ffa7fe5e-494d-0410-b361-a75ebd5db220
-rw-r--r--navit/attr_def.h1
-rw-r--r--navit/coord.c2
-rw-r--r--navit/navit.c2
-rw-r--r--navit/projection.c17
-rw-r--r--navit/projection.h7
-rw-r--r--navit/transform.c69
-rw-r--r--navit/transform.h1
7 files changed, 92 insertions, 7 deletions
diff --git a/navit/attr_def.h b/navit/attr_def.h
index 95952bf3e..e3375ef02 100644
--- a/navit/attr_def.h
+++ b/navit/attr_def.h
@@ -230,6 +230,7 @@ ATTR(fax)
ATTR(email)
ATTR(url)
ATTR(profilename)
+ATTR(projectionname)
ATTR2(0x0003ffff,type_string_end)
ATTR2(0x00040000,type_special_begin)
ATTR(order)
diff --git a/navit/coord.c b/navit/coord.c
index e63cd7b4e..a61eddeed 100644
--- a/navit/coord.c
+++ b/navit/coord.c
@@ -302,7 +302,7 @@ coord_print(enum projection pro, struct coord *c, FILE *out) {
y = c->y;
}
fprintf( out, "%s: %s0x%x %s0x%x\n",
- projection_to_name( pro ),
+ projection_to_name( pro , NULL),
sign_x, x,
sign_y, y );
return;
diff --git a/navit/navit.c b/navit/navit.c
index de90af040..f816438ff 100644
--- a/navit/navit.c
+++ b/navit/navit.c
@@ -800,7 +800,7 @@ new_file:
f=fopen(file, "a");
if (f) {
if (c) {
- prostr = projection_to_name(c->pro);
+ prostr = projection_to_name(c->pro,NULL);
fprintf(f,"%s%s%s0x%x %s0x%x type=%s label=\"%s\"\n",
prostr, *prostr ? ":" : "",
c->x >= 0 ? "":"-", c->x >= 0 ? c->x : -c->x,
diff --git a/navit/projection.c b/navit/projection.c
index eae465dd7..65db1944f 100644
--- a/navit/projection.c
+++ b/navit/projection.c
@@ -33,23 +33,36 @@ struct projection_name projection_names[]={
{projection_none, ""},
{projection_mg, "mg"},
{projection_garmin, "garmin"},
+ {projection_utm, "utm"},
+ {projection_gk, "gk"},
};
enum projection
-projection_from_name(const char *name)
+projection_from_name(const char *name, struct coord *offset)
{
int i;
+ int zone;
+ char ns;
+ dbg(0,"name=%s\n",name);
for (i=0 ; i < sizeof(projection_names)/sizeof(struct projection_name) ; i++) {
if (! strcmp(projection_names[i].name, name))
return projection_names[i].projection;
}
+ if (offset) {
+ dbg(0,"%s %d\n",name,sscanf(name,"utm%d%c",&zone,&ns));
+ if (sscanf(name,"utm%d%c",&zone,&ns) == 2 && zone > 0 && zone <= 60 && (ns == 'n' || ns == 's')) {
+ offset->x=zone*1000000;
+ offset->y=(ns == 's' ? -10000000:0);
+ return projection_utm;
+ }
+ }
return projection_none;
}
char *
-projection_to_name(enum projection proj)
+projection_to_name(enum projection proj, struct coord *offset)
{
int i;
diff --git a/navit/projection.h b/navit/projection.h
index 01317bc76..449c28fb0 100644
--- a/navit/projection.h
+++ b/navit/projection.h
@@ -21,15 +21,16 @@
#define NAVIT_PROJECTION_H
enum projection {
- projection_none, projection_mg, projection_garmin, projection_screen,
+ projection_none, projection_mg, projection_garmin, projection_screen, projection_utm, projection_gk
};
enum map_datum {
map_datum_none, map_datum_wgs84, map_datum_dhdn
};
-enum projection projection_from_name(const char *name);
-char * projection_to_name(enum projection proj);
+struct coord;
+enum projection projection_from_name(const char *name, struct coord *offset);
+char * projection_to_name(enum projection proj, struct coord *offset);
#endif
diff --git a/navit/transform.c b/navit/transform.c
index a2711f6bc..c336e01f2 100644
--- a/navit/transform.c
+++ b/navit/transform.c
@@ -228,6 +228,7 @@ static const navit_float geo2gar_units = 1/(360.0/(1<<24));
void
transform_to_geo(enum projection pro, struct coord *c, struct coord_geo *g)
{
+ int x,y,northern,zone;
switch (pro) {
case projection_mg:
g->lng=c->x/6371000.0/M_PI*180;
@@ -237,6 +238,17 @@ transform_to_geo(enum projection pro, struct coord *c, struct coord_geo *g)
g->lng=c->x*gar2geo_units;
g->lat=c->y*gar2geo_units;
break;
+ case projection_utm:
+ x=c->x;
+ y=c->y;
+ northern=y >= 0;
+ if (!northern) {
+ y+=10000000;
+ }
+ zone=(x/1000000);
+ x=x%1000000;
+ transform_utm_to_geo(x, y, zone, northern, g);
+ break;
default:
break;
}
@@ -298,6 +310,63 @@ transform_cart_to_geo(struct coord_geo_cart *cart, navit_float a, navit_float b,
void
+transform_utm_to_geo(const double UTMEasting, const double UTMNorthing, int ZoneNumber, int NorthernHemisphere, struct coord_geo *geo)
+{
+//converts UTM coords to lat/long. Equations from USGS Bulletin 1532
+//East Longitudes are positive, West longitudes are negative.
+//North latitudes are positive, South latitudes are negative
+//Lat and Long are in decimal degrees.
+ //Written by Chuck Gantz- chuck.gantz@globalstar.com
+
+ double Lat, Long;
+ double k0 = 0.99960000000000004;
+ double a = 6378137;
+ double eccSquared = 0.0066943799999999998;
+ double eccPrimeSquared;
+ double e1 = (1-sqrt(1-eccSquared))/(1+sqrt(1-eccSquared));
+ double N1, T1, C1, R1, D, M;
+ double LongOrigin;
+ double mu, phi1, phi1Rad;
+ double x, y;
+ double rad2deg = 180/M_PI;
+
+ x = UTMEasting - 500000.0; //remove 500,000 meter offset for longitude
+ y = UTMNorthing;
+
+ if (!NorthernHemisphere) {
+ y -= 10000000.0;//remove 10,000,000 meter offset used for southern hemisphere
+ }
+
+ LongOrigin = (ZoneNumber - 1)*6 - 180 + 3; //+3 puts origin in middle of zone
+
+ eccPrimeSquared = (eccSquared)/(1-eccSquared);
+
+ M = y / k0;
+ mu = M/(a*(1-eccSquared/4-3*eccSquared*eccSquared/64-5*eccSquared*eccSquared*eccSquared/256));
+ phi1Rad = mu + (3*e1/2-27*e1*e1*e1/32)*sin(2*mu)
+ + (21*e1*e1/16-55*e1*e1*e1*e1/32)*sin(4*mu)
+ +(151*e1*e1*e1/96)*sin(6*mu);
+ phi1 = phi1Rad*rad2deg;
+
+ N1 = a/sqrt(1-eccSquared*sin(phi1Rad)*sin(phi1Rad));
+ T1 = tan(phi1Rad)*tan(phi1Rad);
+ C1 = eccPrimeSquared*cos(phi1Rad)*cos(phi1Rad);
+ R1 = a*(1-eccSquared)/pow(1-eccSquared*sin(phi1Rad)*sin(phi1Rad), 1.5);
+ D = x/(N1*k0);
+
+ Lat = phi1Rad - (N1*tan(phi1Rad)/R1)*(D*D/2-(5+3*T1+10*C1-4*C1*C1-9*eccPrimeSquared)*D*D*D*D/24
+ +(61+90*T1+298*C1+45*T1*T1-252*eccPrimeSquared-3*C1*C1)*D*D*D*D*D*D/720);
+ Lat = Lat * rad2deg;
+
+ Long = (D-(1+2*T1+C1)*D*D*D/6+(5-2*C1+28*T1-3*C1*C1+8*eccPrimeSquared+24*T1*T1)
+ *D*D*D*D*D/120)/cos(phi1Rad);
+ Long = LongOrigin + Long * rad2deg;
+
+ geo->lat=Lat;
+ geo->lng=Long;
+}
+
+void
transform_datum(struct coord_geo *from, enum map_datum from_datum, struct coord_geo *to, enum map_datum to_datum)
{
}
diff --git a/navit/transform.h b/navit/transform.h
index d69842158..e1600b6af 100644
--- a/navit/transform.h
+++ b/navit/transform.h
@@ -47,6 +47,7 @@ void transform_from_geo(enum projection pro, struct coord_geo *g, struct coord *
void transform_from_to(struct coord *cfrom, enum projection from, struct coord *cto, enum projection to);
void transform_geo_to_cart(struct coord_geo *geo, navit_float a, navit_float b, struct coord_geo_cart *cart);
void transform_cart_to_geo(struct coord_geo_cart *cart, navit_float a, navit_float b, struct coord_geo *geo);
+void transform_utm_to_geo(const double UTMEasting, const double UTMNorthing, int ZoneNumber, int NorthernHemisphere, struct coord_geo *geo);
void transform_datum(struct coord_geo *from, enum map_datum from_datum, struct coord_geo *to, enum map_datum to_datum);
int transform(struct transformation *t, enum projection pro, struct coord *c, struct point *p, int count, int unique, int width, int *width_return);
void transform_reverse(struct transformation *t, struct point *p, struct coord *c);