GEOHASH_area* GEOHASH_decode(const char *hash) { const char *p; unsigned char c; char bits; GEOHASH_area *area; GEOHASH_range *range1, *range2, *range_tmp; area = (GEOHASH_area *)emalloc(sizeof(GEOHASH_area)); if (area == NULL) return NULL; area->latitude.max = 90; area->latitude.min = -90; area->longitude.max = 180; area->longitude.min = -180; range1 = &area->longitude; range2 = &area->latitude; p = hash; while (*p != '\0') { c = toupper(*p++); if (c < 0x30) { efree(area); return NULL; } c -= 0x30; if (c > 43) { efree(area); return NULL; } bits = BASE32_DECODE_TABLE[c]; if (bits == -1) { efree(area); return NULL; } REFINE_RANGE(range1, bits, 0x10); REFINE_RANGE(range2, bits, 0x08); REFINE_RANGE(range1, bits, 0x04); REFINE_RANGE(range2, bits, 0x02); REFINE_RANGE(range1, bits, 0x01); range_tmp = range1; range1 = range2; range2 = range_tmp; } return area; }
GhtErr ght_area_from_hash(const GhtHash *hash, GhtArea *area) { const char *p; unsigned char c; char bits; GhtRange *range1, *range2, *range_tmp; area->y.max = 90; /* latitude max */ area->y.min = -90; /* latitude min */ area->x.max = 180; /* longitude max */ area->x.min = -180; /* longitude min */ range1 = &(area->x); range2 = &(area->y); p = (const char*)hash; while (*p != '\0') { c = toupper(*p++); if (c < 0x30) { return GHT_ERROR; } c -= 0x30; if (c > 43) { return GHT_ERROR; } bits = BASE32_DECODE_TABLE[c]; if (bits == -1) { return GHT_ERROR; } REFINE_RANGE(range1, bits, 0x10); REFINE_RANGE(range2, bits, 0x08); REFINE_RANGE(range1, bits, 0x04); REFINE_RANGE(range2, bits, 0x02); REFINE_RANGE(range1, bits, 0x01); range_tmp = range1; range1 = range2; range2 = range_tmp; } return GHT_OK; }