diff -urN maemo-mapper-3.2/LICENSE-RDS-GPS maemo-mapper-3.2-RDS/LICENSE-RDS-GPS --- maemo-mapper-3.2/LICENSE-RDS-GPS 1970-01-01 01:00:00.000000000 +0100 +++ maemo-mapper-3.2-RDS/LICENSE-RDS-GPS 2011-08-06 10:32:43.000000000 +0200 @@ -0,0 +1,13 @@ +The RDS-GPS library contains a conversion algorithm between WGS84 +(a.k.a. GPS) and RDS (a.k.a. Amersfoort) coordinates. This algorithm +is a direct translation from javascript to C and C++ of the conversion +algorithm found in http://wnimg.nl/static/js/jgis.js. That algorithm +is published at the mentioned URL and does not carry a copyright +notice. + +The theory behind the algorithms may be found in the article +'Rijksdriehoeksstelsel.pdf' (author not mentioned) found at +http://www.johannespostgroep.nl/wp-content/uploads/2008/10/rijksdriehoeksstelsel.pdf. + +The algorithm in its original javascript formulation is also used in +the site http://waarneming.nl, web portal for nature observations. diff -urN maemo-mapper-3.2/src/data.c maemo-mapper-3.2-RDS/src/data.c --- maemo-mapper-3.2/src/data.c 2010-12-24 11:15:34.000000000 +0100 +++ maemo-mapper-3.2-RDS/src/data.c 2011-05-19 20:21:54.000000000 +0200 @@ -175,6 +175,14 @@ .long_field_2 = "", .field_2_in_use = FALSE, }, + [NL_RDS] = { + .name = "NL RDS (Amersfoort)", + .short_field_1 = "x", + .long_field_1 = "x-coordinaat", + .short_field_2 = "y", + .long_field_2 = "y-coordinaat", + .field_2_in_use = TRUE, + }, }; gchar *SPEED_LOCATION_ENUM_TEXT[SPEED_LOCATION_ENUM_COUNT]; diff -urN maemo-mapper-3.2/src/Makefile.am maemo-mapper-3.2-RDS/src/Makefile.am --- maemo-mapper-3.2/src/Makefile.am 2010-12-24 11:15:34.000000000 +0100 +++ maemo-mapper-3.2-RDS/src/Makefile.am 2011-08-07 12:33:26.000000000 +0200 @@ -79,7 +79,8 @@ tile.c \ util.c \ repository.c \ - tile_source.c + tile_source.c \ + RDS-GPS.c # bin_SCRIPTS = maemo-mapper.sh run: all diff -urN maemo-mapper-3.2/src/RDS-GPS.c maemo-mapper-3.2-RDS/src/RDS-GPS.c --- maemo-mapper-3.2/src/RDS-GPS.c 1970-01-01 01:00:00.000000000 +0100 +++ maemo-mapper-3.2-RDS/src/RDS-GPS.c 2011-05-20 14:24:02.000000000 +0200 @@ -0,0 +1,151 @@ +#include "RDS-GPS.h" + +RDSPoint *RDSPoint_new(gdouble x, gdouble y) +{ + RDSPoint *this = (RDSPoint *) g_malloc(sizeof(RDSPoint)); + this->x = x; + this->y = y; + return this; +} + +RDSPoint *RDSPoint_new_from_GPSPoint(GPSPoint *gpspoint) +{ + RDSPoint *this = (RDSPoint *) g_malloc(sizeof(RDSPoint)); + gdouble lat = GPSPoint_getLat(gpspoint); + gdouble lng = GPSPoint_getLng(gpspoint); + + // GPS to bessel + gdouble dlat = lat - 52.0; + gdouble dlng = lng - 5.0; + gdouble latcor = (-96.862 - dlat * 11.714 - dlng * .125) * 1e-5; + gdouble lngcor = (dlat * .329 - 37.902 - dlng * 14.667) * 1e-5; + gdouble latbes = lat - latcor; + gdouble lngbes = lng - lngcor; + + // deg to rad + gdouble phi = latbes / 180.0 * M_PI; + gdouble lambda = lngbes / 180.0 * M_PI; + + // bessel to RDS + gdouble qprime = log(tan(phi / 2.0 + (M_PI / 4))); + gdouble dq = RDS_e / 2.0 * log((RDS_e * sin(phi) + 1.0) / (1.0 - RDS_e * sin(phi))); + gdouble q = qprime - dq; + gdouble w = RDS_n * q + RDS_m; + gdouble b = atan(exp(w)) * 2.0 - (M_PI / 2); + gdouble dl = RDS_n * (lambda - RDS_lambda0); + // Computing 2nd power + gdouble d__1 = sin((b - RDS_b0) / 2.0); + // Computing 2nd power + gdouble d__2 = sin(dl / 2.0); + gdouble s2psihalf = d__1 * d__1 + d__2 * d__2 * cos(b) * cos(RDS_b0); + gdouble cpsihalf = sqrt(1.0 - s2psihalf); + gdouble spsihalf = sqrt(s2psihalf); + gdouble tpsihalf = spsihalf / cpsihalf; + gdouble spsi = spsihalf * 2.0 * cpsihalf; + gdouble cpsi = 1.0 - s2psihalf * 2.0; + gdouble sa = sin(dl) * cos(b) / spsi; + gdouble ca = (sin(b) - sin(RDS_b0) * cpsi) / (cos(RDS_b0) * spsi); + gdouble r = RDS_k * 2.0 * RDS_bigr * tpsihalf; + this->x = r * sa + RDS_x0; + this->y = r * ca + RDS_y0; + return this; +} + +gdouble RDSPoint_getX(RDSPoint *this) +{ + return this->x; +} + +gdouble RDSPoint_getY(RDSPoint *this) +{ + return this->y; +} + +// Validity: 13000 < x < 278000, 306000 < y < 620000 +gboolean RDSPoint_is_valid(RDSPoint *rdspoint) +{ + // gdouble x = RDSPoint_getX(rdspoint); + // gdouble y = RDSPoint_getY(rdspoint); + // return 10000 < x && x < 280000 && 304000 < y && y < 622000; + return TRUE; +} + +// Validity: 50.7566 < lat < 53.5462, 3.3517 < lng < 7.2079 +gboolean RDSPoint_is_valid_GPSPoint(GPSPoint *gpspoint) +{ + // gdouble lat = GPSPoint_getLat(gpspoint); + // gdouble lng = GPSPoint_getLng(gpspoint); + // return 50.7 < lat && lat < 53.6 && 3.3 < lng && lng < 7.25; + return TRUE; +} + +GPSPoint *GPSPoint_new(gdouble lat, gdouble lng) +{ + GPSPoint *this = (GPSPoint *) g_malloc(sizeof(GPSPoint)); + this->lat = lat; + this->lng = lng; + return this; +} + +GPSPoint *GPSPoint_new_from_RDSPoint(RDSPoint *rdspoint) +{ + GPSPoint *this = (GPSPoint *) g_malloc(sizeof(GPSPoint)); + gdouble x = RDSPoint_getX(rdspoint); + gdouble y = RDSPoint_getY(rdspoint); + + // RDS to bessel + gdouble d__1 = x - RDS_x0; + gdouble d__2 = y - RDS_y0; + gdouble r = sqrt(d__1 * d__1 + d__2 * d__2); + gdouble sa, ca; + if (r) { + sa = (x - RDS_x0) / r; + ca = (y - RDS_y0) / r; + } else { + sa = 0.0; + ca = 0.0; + } + gdouble psi = atan2(r, RDS_k * 2. * RDS_bigr) * 2.; + gdouble cpsi = cos(psi); + gdouble spsi = sin(psi); + gdouble sb = ca * cos(RDS_b0) * spsi + sin(RDS_b0) * cpsi; + gdouble cb = sqrt(1. - sb * sb); + gdouble b = acos(cb); + gdouble sdl = sa * spsi / cb; + gdouble dl = asin(sdl); + gdouble lambda = dl / RDS_n + RDS_lambda0; + gdouble w = log(tan(b / 2. + (M_PI / 4))); + gdouble q = (w - RDS_m) / RDS_n; + gdouble phiprime = atan(exp(q)) * 2. - (M_PI / 2); + gdouble phi; + for (gint i = 0; i < 4; ++i) { + gdouble dq = RDS_e / 2. * log((RDS_e * sin(phiprime) + 1.) / (1. - RDS_e * sin(phiprime))); + phi = atan(exp(q + dq)) * 2. - (M_PI/ 2); + phiprime = phi; + } + + // rad to deg + gdouble latbes = phi / M_PI * 180; + gdouble lngbes = lambda / M_PI * 180; + + // bessel to GPS + gdouble dlat = latbes - 52.0; + gdouble dlng = lngbes - 5.0; + gdouble latcor = (-96.862 - dlat * 11.714 - dlng * .125) * 1e-5; + gdouble lngcor = (dlat * .329 - 37.902 - dlng * 14.667) * 1e-5; + this->lat = latbes + latcor; + this->lng = lngbes + lngcor; + return this; +} + +gdouble GPSPoint_getLat(GPSPoint *this) +{ + return this->lat; +} + +gdouble GPSPoint_getLng(GPSPoint *this) +{ + return this->lng; +} + + diff -urN maemo-mapper-3.2/src/RDS-GPS.h maemo-mapper-3.2-RDS/src/RDS-GPS.h --- maemo-mapper-3.2/src/RDS-GPS.h 1970-01-01 01:00:00.000000000 +0100 +++ maemo-mapper-3.2-RDS/src/RDS-GPS.h 2011-05-20 09:20:13.000000000 +0200 @@ -0,0 +1,45 @@ +#ifndef RDS_GPS_H +#define RDS_GPS_H + +/* M_PI is not defined in C99 (-std=c99); + defining _GNU_SOURCE includes the definition again */ +#define _GNU_SOURCE +#include +#include + +static const gdouble RDS_x0 = 155000.0; +static const gdouble RDS_y0 = 463000.0; +static const gdouble RDS_k = .9999079; +static const gdouble RDS_bigr = 6382644.571; +static const gdouble RDS_m = .003773953832; +static const gdouble RDS_n = 1.00047585668; +static const gdouble RDS_lambda0 = M_PI * .029931327161111111; +static const gdouble RDS_phi0 = M_PI * .28975644753333335; +static const gdouble RDS_l0 = M_PI * .029931327161111111; +static const gdouble RDS_b0 = M_PI * .28956165138333334; +static const gdouble RDS_e = .08169683122; +static const gdouble RDS_a = 6377397.155; + +typedef struct RDSPoint +{ + gdouble x, y; +} RDSPoint; + +typedef struct GPSPoint +{ + gdouble lat, lng; +} GPSPoint; + +RDSPoint *RDSPoint_new(gdouble x, gdouble y); +RDSPoint *RDSPoint_new_from_GPSPoint(GPSPoint *gpspoint); +gdouble RDSPoint_getX(RDSPoint *this); +gdouble RDSPoint_getY(RDSPoint *this); +gboolean RDSPoint_is_valid(RDSPoint *rdspoint); +gboolean RDSPoint_is_valid_GPSPoint(GPSPoint *gpspoint); + +GPSPoint *GPSPoint_new(gdouble lat, gdouble lng); +GPSPoint *GPSPoint_new_from_RDSPoint(RDSPoint *rdspoint); +gdouble GPSPoint_getLat(GPSPoint *this); +gdouble GPSPoint_getLng(GPSPoint *this); + +#endif diff -urN maemo-mapper-3.2/src/types.h maemo-mapper-3.2-RDS/src/types.h --- maemo-mapper-3.2/src/types.h 2010-12-24 11:15:34.000000000 +0100 +++ maemo-mapper-3.2-RDS/src/types.h 2011-05-19 19:14:37.000000000 +0200 @@ -195,6 +195,7 @@ UK_NGR, // 8 char grid ref UK_NGR6,// 6 char grid ref IARU_LOC, + NL_RDS,// Netherlands RDS (aka Amersfoort) grid DEG_FORMAT_ENUM_COUNT } DegFormat; diff -urN maemo-mapper-3.2/src/util.c maemo-mapper-3.2-RDS/src/util.c --- maemo-mapper-3.2/src/util.c 2010-12-24 11:15:34.000000000 +0100 +++ maemo-mapper-3.2-RDS/src/util.c 2011-05-20 16:09:37.000000000 +0200 @@ -41,6 +41,7 @@ #include "types.h" #include "data.h" #include "defines.h" +#include "RDS-GPS.h" #include "util.h" @@ -72,6 +73,11 @@ switch(_degformat) { + // should not happen + case NL_RDS: + sprintf(scoor, "SNH-RDS"); + break; + case IARU_LOC: case UK_OSGB: case UK_NGR: @@ -476,6 +482,10 @@ valid = os_grid_check_lat_lon(lat, lon); if(fallback_deg_format != NULL) *fallback_deg_format = DDPDDDDD; break; + case NL_RDS: + valid = RDSPoint_is_valid_GPSPoint(GPSPoint_new(lat, lon)); + if(fallback_deg_format != NULL) *fallback_deg_format = DD_MM_SSPS; + break; default: valid = TRUE; break; @@ -709,6 +719,23 @@ return TRUE; } +// if x and y < 1000, assume the user used km; convert to m +gboolean convert_nl_rds_to_lat_lon(const gchar* txt_x, const gchar* txt_y, MapGeo* lat, MapGeo* lon) { + gdouble x = g_strtod(txt_x, NULL); + gdouble y = g_strtod(txt_y, NULL); + if (x < 1000 && y < 1000) { + x = x * 1000; + y = y * 1000; + } + RDSPoint* rdspoint = RDSPoint_new(x, y); + if (!RDSPoint_is_valid(rdspoint)) { + return FALSE; + } + GPSPoint* gpspoint = GPSPoint_new_from_RDSPoint(rdspoint); + *lat = (MapGeo) GPSPoint_getLat(gpspoint); + *lon = (MapGeo) GPSPoint_getLng(gpspoint); + return TRUE; +} // Attempt to convert any user entered grid reference to a double lat/lon // return TRUE on valid @@ -741,6 +768,13 @@ if(!valid || *lat < -90. || *lat > 90.) { valid = FALSE; } else if(*lon < -180. || *lon > 180.) { valid = FALSE; } } + else if(_degformat == NL_RDS) + { + valid = convert_nl_rds_to_lat_lon(txt_lat, txt_lon, lat, lon); + + if(!valid || *lat < -90. || *lat > 90.) { valid = FALSE; } + else if(*lon < -180. || *lon > 180.) { valid = FALSE; } + } // It must either be invalid, or a lat/lon format else { @@ -911,7 +945,21 @@ convert_lat_lon_to_iaru_loc(d_lat, d_lon, lat); break; - + + case NL_RDS: + { + GPSPoint* gpspoint = GPSPoint_new(d_lat, d_lon); + if (!RDSPoint_is_valid_GPSPoint(gpspoint)) { + sprintf(lat, "---"); + sprintf(lon, "---"); + } else { + RDSPoint* rdspoint = RDSPoint_new_from_GPSPoint(gpspoint); + sprintf(lat, "%'u", (uint) RDSPoint_getX(rdspoint)); + sprintf(lon, "%'u", (uint) RDSPoint_getY(rdspoint)); + } + } + break; + default: lat_format(d_lat, lat); lon_format(d_lon, lon);