diff options
author | martin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2009-05-27 13:45:54 +0000 |
---|---|---|
committer | martin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2009-05-27 13:45:54 +0000 |
commit | 1cf3ebc267ec6d5358990e79b3e38ffe8e2de729 (patch) | |
tree | 9697447235e4b6552da83f2163b6f0fc1c4e2350 | |
parent | 6a69500ae9abb0bac14804d439f4d79a6cba8d48 (diff) | |
download | navit-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.h | 1 | ||||
-rw-r--r-- | navit/coord.c | 2 | ||||
-rw-r--r-- | navit/navit.c | 2 | ||||
-rw-r--r-- | navit/projection.c | 17 | ||||
-rw-r--r-- | navit/projection.h | 7 | ||||
-rw-r--r-- | navit/transform.c | 69 | ||||
-rw-r--r-- | navit/transform.h | 1 |
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); |