Opened 11 years ago

Closed 11 years ago

#2250 closed enhancement (fixed)

ST_PointFromGeohash()

Reported by: darkblueb Owned by: pramsey
Priority: low Milestone: PostGIS 2.1.0
Component: postgis Version: master
Keywords: Cc:

Description

a round-trip for the geohash type would be useful.. this project is MIT license and has a simple function to do this..

https://github.com/lyokato/libgeohash

this code uses a struct that resembles a box, to return the result..

some adoption might be made for PostGIS LWGeom conventions..


excerpt from geohash.c The MIT License Copyright © 2011 lyo.kato@…

static const char BASE32_DECODE_TABLE[44] = {

/* 0 */ 0, /* 1 */ 1, /* 2 */ 2, /* 3 */ 3, /* 4 */ 4, /* 5 */ 5, /* 6 */ 6, /* 7 */ 7, /* 8 */ 8, /* 9 */ 9, /* : */ -1, /* ; */ -1, /* < */ -1, /* = */ -1, /* > */ -1, /* ? */ -1, /* @ */ -1, /* A */ -1, /* B */ 10, /* C */ 11, /* D */ 12, /* E */ 13, /* F */ 14, /* G */ 15, /* H */ 16, /* I */ -1, /* J */ 17, /* K */ 18, /* L */ -1, /* M */ 19, /* N */ 20, /* O */ -1, /* P */ 21, /* Q */ 22, /* R */ 23, /* S */ 24, /* T */ 25, /* U */ 26, /* V */ 27, /* W */ 28, /* X */ 29, /* Y */ 30, /* Z */ 31

};

#define MAX_HASH_LENGTH 22

#define REFINE_RANGE(range, bits, offset) \

if (((bits) & (offset)) == (offset)) \

(range)→min = ((range)→max + (range)→min) / 2.0; \

else \

(range)→max = ((range)→max + (range)→min) / 2.0;

#define SET_BIT(bits, mid, range, value, offset) \

mid = ((range)→max + (range)→min) / 2.0; \ if ((value) ≥ mid) { \

(range)→min = mid; \ (bits) |= (0x1 << (offset)); \

} else { \

(range)→max = mid; \ (bits) |= (0x0 << (offset)); \

}

typedef struct {

double max; double min;

} GEOHASH_range;

typedef struct {

GEOHASH_range latitude; GEOHASH_range longitude;

} GEOHASH_area;

bool GEOHASH_verify_hash(const char *hash) {

const char *p; unsigned char c; p = hash; while (*p != '\0') {

c = toupper(*p++); if (c < 0x30)

return false;

c -= 0x30; if (c > 43)

return false;

if (BASE32_DECODE_TABLE[c] == -1)

return false;

} return true;

}

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 *)malloc(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) {

free(area); return NULL;

} c -= 0x30; if (c > 43) {

free(area); return NULL;

} bits = BASE32_DECODE_TABLE[c]; if (bits == -1) {

free(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;

}

Change History (2)

comment:1 by darkpanda, 11 years ago

I actually wrote a patch for ST_GeomFromGeoHash and ST_PointFromGeoHash and the implementation is available in ticket #1818 - "C implementation for GeoHash input".

comment:2 by robe, 11 years ago

Milestone: PostGIS FuturePostGIS 2.1.0
Resolution: fixed
Status: newclosed

was committed in #1818 patch.

Note: See TracTickets for help on using tickets.