summaryrefslogtreecommitdiffstats
path: root/librns510.c
diff options
context:
space:
mode:
Diffstat (limited to 'librns510.c')
-rw-r--r--librns510.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/librns510.c b/librns510.c
new file mode 100644
index 0000000..060c766
--- /dev/null
+++ b/librns510.c
@@ -0,0 +1,96 @@
+#include <stdint.h>
+#include <byteswap.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <inttypes.h>
+
+#define POI_CA 0x80000034 /*0 */
+#define POI_CB 0xF1C71CD4 /*160 */
+//
+#define ZERO (POI_CA)
+#define SCALE (((double) (POI_CB-POI_CA))/160.)
+
+static void
+fromz (int64_t a, double *lat, double *lon)
+{
+ uint64_t b, c;
+ uint32_t d, e, f;
+
+ memcpy (&b, &a, sizeof (a));
+ e = f = 0;
+
+ for (c = 1, d = 1; c; c <<= 1, d <<= 1)
+ {
+ if (b & c)
+ e |= d;
+ c <<= 1;
+ if (b & c)
+ f |= d;
+ }
+
+ *lon = e;
+ *lat = f;
+
+ *lon -= ZERO;
+ *lat -= ZERO;
+
+ *lon /= SCALE;
+ *lat /= SCALE;
+
+}
+
+static void
+toz (double lat, double lon, int64_t * a)
+{
+ uint64_t b, c;
+ uint32_t d, e, f;
+
+ lon *= SCALE;
+ lat *= SCALE;
+ lon += ZERO;
+ lat += ZERO;
+
+ e = (uint32_t) (lon + .5);
+ f = (uint32_t) (lat + .5);
+
+ //printf("%.1f %x\n",lat-ZERO, e,f);
+
+ b = 0;
+ for (c = 1, d = 1; c; c <<= 1, d <<= 1)
+ {
+ if (e & d)
+ b |= c;
+ c <<= 1;
+ if (f & d)
+ b |= c;
+ }
+
+
+ memcpy (a, &b, sizeof (*a));
+}
+
+void
+librns510_encode (const char *slat, const char *slon, char *out)
+{
+ double lat = atof (slat), lon = atof (slon);
+ int64_t z;
+
+ toz (lat, lon, &z);
+
+ sprintf (out, "%" PRId64, z);
+}
+
+void
+librns510_decode (const char *code, char *slat, char *slon)
+{
+ double lat, lon;
+ int64_t z = atoll (code);
+
+ fromz (z, &lat, &lon);
+
+ sprintf (slat, "%.10f", lat);
+ sprintf (slon, "%.10f", lon);
+
+}