Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

a unit test

  • Loading branch information...
commit d68dee19c577e1e988965c1808c80f1ffacdf362 1 parent c25db23
@eklitzke authored
Showing with 54 additions and 30 deletions.
  1. +2 −0  .gitignore
  2. +30 −30 geoquad.c
  3. +22 −0 tests.py
View
2  .gitignore
@@ -0,0 +1,2 @@
+build/
+.*.swp
View
60 geoquad.c
@@ -28,29 +28,29 @@ struct quad_s
float sw;
};
-static inline uint32_t interleave32(uint16_t x, uint16_t y)
+/* A half interleave/ */
+static inline uint32_t interleave_half(uint16_t x)
{
- return (
- morton_forward[y >> 8] << 17 |
- morton_forward[x >> 8] << 16 |
- morton_forward[y & 0xFF] << 1 |
- morton_forward[x & 0xFF]);
+ return (morton_forward[x >> 8] << 16) | morton_forward[x & 0xFF];
}
-/* Deinterleave a 32 bit number into one of its 16 bit constituent parts. */
-#define DEINTERLEAVE_HALF(z) \
- ((uint16_t)\
- (morton_sparse[(z) & INTER16L] |\
- (morton_sparse[((z) >> 16) & INTER16L] << 8)))
+/* A full interleave */
+static inline uint32_t interleave_full(uint16_t x, uint16_t y)
+{
+ return interleave_half(x) | (interleave_half(y) << 1);
+}
-#define INTERLEAVE_HALF(x) \
- ((morton_forward[x >> 8] << 16) | (morton_forward[x & 0xFF]))
+/* A half deinterleave */
+static inline uint16_t deinterleave_half(uint32_t z)
+{
+ return morton_sparse[z & INTER16L] | (morton_sparse[(z >> 16) & INTER16L] << 8);
+}
/* Deinterleave z into x and y */
-static inline void deinterleave32(uint32_t z, uint16_t *x, uint16_t *y)
+static inline void deinterleave_full(uint32_t z, uint16_t *x, uint16_t *y)
{
- *x = DEINTERLEAVE_HALF(z);
- *y = DEINTERLEAVE_HALF(z>>1); /* GCC will do the Right Thing */
+ *x = deinterleave_half(z);
+ *y = deinterleave_half(z>>1);
}
static inline float half_to_lng(uint16_t lng16)
@@ -63,26 +63,26 @@ static inline float half_to_lat(uint16_t lat16)
return (((float) lat16) * GEOQUAD_STEP) + LATITUDE_MIN;
}
-static inline uint16_t lng_to_16(float lng)
+static inline uint16_t lng_to_half(float lng)
{
return (uint16_t) ((lng - LONGITUDE_MIN) / GEOQUAD_STEP);
}
-static inline uint16_t lat_to_16(float lat)
+static inline uint16_t lat_to_half(float lat)
{
return (uint16_t) ((lat - LATITUDE_MIN) / GEOQUAD_STEP);
}
static inline uint32_t quad_northof(uint32_t gq)
{
- float lat = half_to_lat(DEINTERLEAVE_HALF(gq)) + GEOQUAD_STEP;
- return (gq & INTER32M) | INTERLEAVE_HALF(lat_to_16(lat));
+ float lat = half_to_lat(deinterleave_half(gq)) + GEOQUAD_STEP;
+ return (gq & INTER32M) | interleave_half(lat_to_half(lat));
}
static inline uint32_t quad_southof(uint32_t gq)
{
- float lat = half_to_lat(DEINTERLEAVE_HALF(gq)) - GEOQUAD_STEP;
- return (gq & INTER32M) | INTERLEAVE_HALF(lat_to_16(lat));
+ float lat = half_to_lat(deinterleave_half(gq)) - GEOQUAD_STEP;
+ return (gq & INTER32M) | interleave_half(lat_to_half(lat));
}
static PyObject*
@@ -91,13 +91,13 @@ geoquad_create(PyObject *self, PyObject *args)
uint16_t i, j;
uint32_t result;
float lng, lat;
- if (!PyArg_ParseTuple(args, "ff", &lng, &lat))
+ if (!PyArg_ParseTuple(args, "ff", &lat, &lng))
return NULL;
- i = (uint16_t) ((lng - LONGITUDE_MIN) / GEOQUAD_STEP);
- j = (uint16_t) ((lat - LATITUDE_MIN) / GEOQUAD_STEP);
+ i = (uint16_t) ((lat - LONGITUDE_MIN) / GEOQUAD_STEP);
+ j = (uint16_t) ((lng - LATITUDE_MIN) / GEOQUAD_STEP);
/* yes this is backwards. don't ask */
- result = interleave32(j, i);
+ result = interleave_full(j, i);
return PyInt_FromLong((long) result);
}
@@ -115,7 +115,7 @@ geoquad_parse(PyObject *self, PyObject *args)
if ((ret = PyTuple_New(2)) == NULL)
return NULL;
- deinterleave32((uint32_t) geoquad, &i, &j);
+ deinterleave_full((uint32_t) geoquad, &i, &j);
lat = (float) ((i * GEOQUAD_STEP) + LATITUDE_MIN);
lng = (float) ((j * GEOQUAD_STEP) + LONGITUDE_MIN);
@@ -125,12 +125,12 @@ geoquad_parse(PyObject *self, PyObject *args)
}
static PyObject*
-geoquad_rightof(PyObject *self, PyObject *args)
+geoquad_northof(PyObject *self, PyObject *args)
{
long geoquad;
if (!PyArg_ParseTuple(args, "l", &geoquad))
return NULL;
- return PyInt_FromLong((long) quad_rightof((uint32_t) geoquad));
+ return PyInt_FromLong((long) quad_northof((uint32_t) geoquad));
}
#if 0
@@ -147,7 +147,7 @@ static PyMethodDef geoquad_methods[] = {
{ "create", (PyCFunction) geoquad_create, METH_VARARGS, "create a geoquad from a (lng, lat)" },
{ "parse", (PyCFunction) geoquad_parse, METH_VARARGS, "parse a geoquad, returns a (lng, lat)" },
{ "northof", (PyCFunction) geoquad_northof, METH_VARARGS, "north of a geoquad, returns a (lng, lat)" },
- { "southof", (PyCFunction) geoquad_southof, METH_VARARGS, "south of a geoquad, returns a (lng, lat)" },
+ //{ "southof", (PyCFunction) quad_southof, METH_VARARGS, "south of a geoquad, returns a (lng, lat)" },
{ NULL }
};
View
22 tests.py
@@ -0,0 +1,22 @@
+import unittest
+import geoquad
+
+class RatioTestCase(unittest.TestCase):
+ def assertAlmostEqual(self, a, b, precision=0.99):
+ assert abs(a - b) < min(a, b) * (1 - precision)
+ assertAlmostEquals = assertAlmostEqual
+
+class Geoquadtester(RatioTestCase):
+
+ def test_create_then_parse(self):
+ '''
+ Test interleave -> deinterleave.
+ '''
+ lat, lng = (10, 20)
+ g = geoquad.create(lat, lng)
+ lat_, lng_ = geoquad.parse(g)
+ self.assertAlmostEqual(lat, lat_)
+ self.assertAlmostEqual(lng, lng_)
+
+if __name__ == '__main__':
+ unittest.main()
Please sign in to comment.
Something went wrong with that request. Please try again.