diff --git a/deps/geohash-int/geohash.c b/deps/geohash-int/geohash.c index 66cff082..e797fbc8 100644 --- a/deps/geohash-int/geohash.c +++ b/deps/geohash-int/geohash.c @@ -43,17 +43,17 @@ * ----------------- */ -void geohashGetCoordRange(GeoHashRange *lat_range, GeoHashRange *long_range) { +void geohashGetCoordRange(GeoHashRange *long_range, GeoHashRange *lat_range) { /* These are constraints from EPSG:900913 / EPSG:3785 / OSGEO:41001 */ /* We can't geocode at the north/south pole. */ - lat_range->max = 85.05112878; - lat_range->min = -85.05112878; long_range->max = 180.0; long_range->min = -180.0; + lat_range->max = 85.05112878; + lat_range->min = -85.05112878; } -int geohashEncode(GeoHashRange *lat_range, GeoHashRange *long_range, - double latitude, double longitude, uint8_t step, +int geohashEncode(GeoHashRange *long_range, GeoHashRange *lat_range, + double longitude, double latitude, uint8_t step, GeoHashBits *hash) { uint8_t i; @@ -96,22 +96,22 @@ int geohashEncode(GeoHashRange *lat_range, GeoHashRange *long_range, return 1; } -int geohashEncodeType(double latitude, double longitude, uint8_t step, GeoHashBits *hash) { +int geohashEncodeType(double longitude, double latitude, uint8_t step, GeoHashBits *hash) { GeoHashRange r[2] = { { 0 } }; geohashGetCoordRange(&r[0], &r[1]); - return geohashEncode(&r[0], &r[1], latitude, longitude, step, hash); + return geohashEncode(&r[0], &r[1], longitude, latitude, step, hash); } -int geohashEncodeWGS84(double latitude, double longitude, uint8_t step, +int geohashEncodeWGS84(double longitude, double latitude, uint8_t step, GeoHashBits *hash) { - return geohashEncodeType(latitude, longitude, step, hash); + return geohashEncodeType(longitude, latitude, step, hash); } static inline uint8_t get_bit(uint64_t bits, uint8_t pos) { return (bits >> pos) & 0x01; } -int geohashDecode(const GeoHashRange lat_range, const GeoHashRange long_range, +int geohashDecode(const GeoHashRange long_range, const GeoHashRange lat_range, const GeoHashBits hash, GeoHashArea *area) { uint8_t i; @@ -121,10 +121,10 @@ int geohashDecode(const GeoHashRange lat_range, const GeoHashRange long_range, } area->hash = hash; - area->latitude.min = lat_range.min; - area->latitude.max = lat_range.max; area->longitude.min = long_range.min; area->longitude.max = long_range.max; + area->latitude.min = lat_range.min; + area->latitude.max = lat_range.max; for (i = 0; i < hash.step; i++) { uint8_t lat_bit, long_bit; @@ -159,28 +159,22 @@ int geohashDecodeWGS84(const GeoHashBits hash, GeoHashArea *area) { return geohashDecodeType(hash, area); } -int geohashDecodeAreaToLatLong(const GeoHashArea *area, double *latlong) { - double y, x; - - if (!latlong) return 0; - - y = (area->latitude.min + area->latitude.max) / 2; - x = (area->longitude.min + area->longitude.max) / 2; - - latlong[0] = y; - latlong[1] = x; +int geohashDecodeAreaToLongLat(const GeoHashArea *area, double *xy) { + if (!xy) return 0; + xy[0] = (area->longitude.min + area->longitude.max) / 2; + xy[1] = (area->latitude.min + area->latitude.max) / 2; return 1; } -int geohashDecodeToLatLongType(const GeoHashBits hash, double *latlong) { +int geohashDecodeToLongLatType(const GeoHashBits hash, double *xy) { GeoHashArea area = { { 0 } }; - if (!latlong || !geohashDecodeType(hash, &area)) + if (!xy || !geohashDecodeType(hash, &area)) return 0; - return geohashDecodeAreaToLatLong(&area, latlong); + return geohashDecodeAreaToLongLat(&area, xy); } -int geohashDecodeToLatLongWGS84(const GeoHashBits hash, double *latlong) { - return geohashDecodeToLatLongType(hash, latlong); +int geohashDecodeToLongLatWGS84(const GeoHashBits hash, double *xy) { + return geohashDecodeToLongLatType(hash, xy); } static void geohash_move_x(GeoHashBits *hash, int8_t d) { diff --git a/deps/geohash-int/geohash.h b/deps/geohash-int/geohash.h index 78310715..2bf1f5df 100644 --- a/deps/geohash-int/geohash.h +++ b/deps/geohash-int/geohash.h @@ -62,14 +62,14 @@ typedef struct { } GeoHashBits; typedef struct { - double max; double min; + double max; } GeoHashRange; typedef struct { GeoHashBits hash; - GeoHashRange latitude; GeoHashRange longitude; + GeoHashRange latitude; } GeoHashArea; typedef struct { @@ -87,22 +87,22 @@ typedef struct { * 0:success * -1:failed */ -void geohashGetCoordRange(GeoHashRange *lat_range, GeoHashRange *long_range); -int geohashEncode(GeoHashRange *lat_range, GeoHashRange *long_range, - double latitude, double longitude, uint8_t step, +void geohashGetCoordRange(GeoHashRange *long_range, GeoHashRange *lat_range); +int geohashEncode(GeoHashRange *long_range, GeoHashRange *lat_range, + double longitude, double latitude, uint8_t step, GeoHashBits *hash); -int geohashEncodeType(double latitude, double longitude, +int geohashEncodeType(double longitude, double latitude, uint8_t step, GeoHashBits *hash); -int geohashEncodeWGS84(double latitude, double longitude, uint8_t step, +int geohashEncodeWGS84(double longitude, double latitude, uint8_t step, GeoHashBits *hash); -int geohashDecode(const GeoHashRange lat_range, const GeoHashRange long_range, +int geohashDecode(const GeoHashRange long_range, const GeoHashRange lat_range, const GeoHashBits hash, GeoHashArea *area); int geohashDecodeType(const GeoHashBits hash, GeoHashArea *area); int geohashDecodeWGS84(const GeoHashBits hash, GeoHashArea *area); -int geohashDecodeAreaToLatLong(const GeoHashArea *area, double *latlong); -int geohashDecodeToLatLongType(const GeoHashBits hash, double *latlong); -int geohashDecodeToLatLongWGS84(const GeoHashBits hash, double *latlong); -int geohashDecodeToLatLongMercator(const GeoHashBits hash, double *latlong); +int geohashDecodeAreaToLongLat(const GeoHashArea *area, double *xy); +int geohashDecodeToLongLatType(const GeoHashBits hash, double *xy); +int geohashDecodeToLongLatWGS84(const GeoHashBits hash, double *xy); +int geohashDecodeToLongLatMercator(const GeoHashBits hash, double *xy); void geohashNeighbors(const GeoHashBits *hash, GeoHashNeighbors *neighbors); #if defined(__cplusplus) diff --git a/deps/geohash-int/geohash_helper.c b/deps/geohash-int/geohash_helper.c index b6a00b7b..729f010e 100644 --- a/deps/geohash-int/geohash_helper.c +++ b/deps/geohash-int/geohash_helper.c @@ -80,13 +80,13 @@ int geohashBitsComparator(const GeoHashBits *a, const GeoHashBits *b) { return a->step != b->step ? a->step - b->step : a->bits - b->bits; } -int geohashBoundingBox(double latitude, double longitude, double radius_meters, +int geohashBoundingBox(double longitude, double latitude, double radius_meters, double *bounds) { if (!bounds) return 0; - double latr, lonr; - latr = deg_rad(latitude); + double lonr, latr; lonr = deg_rad(longitude); + latr = deg_rad(latitude); double distance = radius_meters / EARTH_RADIUS_IN_METERS; double min_latitude = latr - distance; @@ -98,37 +98,36 @@ int geohashBoundingBox(double latitude, double longitude, double radius_meters, min_longitude = lonr - difference_longitude; max_longitude = lonr + difference_longitude; - bounds[0] = rad_deg(min_latitude); - bounds[1] = rad_deg(min_longitude); - bounds[2] = rad_deg(max_latitude); - bounds[3] = rad_deg(max_longitude); - + bounds[0] = rad_deg(min_longitude); + bounds[1] = rad_deg(min_latitude); + bounds[2] = rad_deg(max_longitude); + bounds[3] = rad_deg(max_latitude); return 1; } -GeoHashRadius geohashGetAreasByRadius(double latitude, double longitude, double radius_meters) { - GeoHashRange lat_range, long_range; +GeoHashRadius geohashGetAreasByRadius(double longitude, double latitude, double radius_meters) { + GeoHashRange long_range, lat_range; GeoHashRadius radius = { { 0 } }; GeoHashBits hash = { 0 }; GeoHashNeighbors neighbors = { { 0 } }; GeoHashArea area = { { 0 } }; - double min_lat, max_lat, min_lon, max_lon; + double min_lon, max_lon, min_lat, max_lat; double bounds[4]; int steps; - geohashBoundingBox(latitude, longitude, radius_meters, bounds); - min_lat = bounds[0]; - min_lon = bounds[1]; - max_lat = bounds[2]; - max_lon = bounds[3]; + geohashBoundingBox(longitude, latitude, radius_meters, bounds); + min_lon = bounds[0]; + min_lat = bounds[1]; + max_lon = bounds[2]; + max_lat = bounds[3]; steps = geohashEstimateStepsByRadius(radius_meters,latitude); - geohashGetCoordRange(&lat_range, &long_range); - geohashEncode(&lat_range, &long_range, latitude, longitude, steps, &hash); + geohashGetCoordRange(&long_range, &lat_range); + geohashEncode(&long_range, &lat_range, longitude, latitude, steps, &hash); geohashNeighbors(&hash, &neighbors); - geohashGetCoordRange(&lat_range, &long_range); - geohashDecode(lat_range, long_range, hash, &area); + geohashGetCoordRange(&long_range, &lat_range); + geohashDecode(long_range, lat_range, hash, &area); if (area.latitude.min < min_lat) { GZERO(neighbors.south); @@ -156,9 +155,9 @@ GeoHashRadius geohashGetAreasByRadius(double latitude, double longitude, double return radius; } -GeoHashRadius geohashGetAreasByRadiusWGS84(double latitude, double longitude, +GeoHashRadius geohashGetAreasByRadiusWGS84(double longitude, double latitude, double radius_meters) { - return geohashGetAreasByRadius(latitude, longitude, radius_meters); + return geohashGetAreasByRadius(longitude, latitude, radius_meters); } GeoHashFix52Bits geohashAlign52Bits(const GeoHashBits hash) { @@ -167,8 +166,8 @@ GeoHashFix52Bits geohashAlign52Bits(const GeoHashBits hash) { return bits; } -/* calculate distance using haversin great circle distance formula */ -double distanceEarth(double lat1d, double lon1d, double lat2d, double lon2d) { +/* Calculate distance using haversin great circle distance formula. */ +double distanceEarth(double lon1d, double lat1d, double lon2d, double lat2d) { double lat1r, lon1r, lat2r, lon2r, u, v; lat1r = deg_rad(lat1d); lon1r = deg_rad(lon1d); @@ -183,7 +182,7 @@ double distanceEarth(double lat1d, double lon1d, double lat2d, double lon2d) { int geohashGetDistanceIfInRadius(double x1, double y1, double x2, double y2, double radius, double *distance) { - *distance = distanceEarth(y1, x1, y2, x2); + *distance = distanceEarth(x1, y1, x2, y2); if (*distance > radius) return 0; return 1; } @@ -193,14 +192,3 @@ int geohashGetDistanceIfInRadiusWGS84(double x1, double y1, double x2, double *distance) { return geohashGetDistanceIfInRadius(x1, y1, x2, y2, radius, distance); } - -int geohashVerifyCoordinates(double x, double y) { - GeoHashRange lat_range, long_range; - geohashGetCoordRange(&lat_range, &long_range); - - if (x < long_range.min || x > long_range.max || y < lat_range.min || - y > lat_range.max) { - return 0; - } - return 1; -} diff --git a/deps/geohash-int/geohash_helper.h b/deps/geohash-int/geohash_helper.h index 9354a323..0e38740d 100644 --- a/deps/geohash-int/geohash_helper.h +++ b/deps/geohash-int/geohash_helper.h @@ -49,29 +49,20 @@ typedef struct { int GeoHashBitsComparator(const GeoHashBits *a, const GeoHashBits *b); uint8_t geohashEstimateStepsByRadius(double range_meters, double lat); -int geohashBoundingBox(double latitude, double longitude, double radius_meters, +int geohashBoundingBox(double longitude, double latitude, double radius_meters, double *bounds); -GeoHashRadius geohashGetAreasByRadius(double latitude, - double longitude, double radius_meters); -GeoHashRadius geohashGetAreasByRadiusWGS84(double latitude, double longitude, +GeoHashRadius geohashGetAreasByRadius(double longitude, + double latitude, double radius_meters); +GeoHashRadius geohashGetAreasByRadiusWGS84(double longitude, double latitude, double radius_meters); -GeoHashRadius geohashGetAreasByRadiusMercator(double latitude, double longitude, +GeoHashRadius geohashGetAreasByRadiusMercator(double longitude, double latitude, double radius_meters); GeoHashFix52Bits geohashAlign52Bits(const GeoHashBits hash); -double geohashGetXMercator(double longtitude); -double geohashGetYMercator(double latitude); -double geohashGetXWGS84(double x); -double geohashGetYWGS84(double y); -int geohashVerifyCoordinates(double x, double y); int geohashGetDistanceIfInRadius(double x1, double y1, double x2, double y2, double radius, double *distance); int geohashGetDistanceIfInRadiusWGS84(double x1, double y1, double x2, double y2, double radius, double *distance); -int geohashGetDistanceSquaredIfInRadiusMercator(double x1, double y1, - double x2, double y2, - double radius, - double *distance); #endif /* GEOHASH_HELPER_HPP_ */ diff --git a/src/geo.c b/src/geo.c index eb813473..40d962f3 100644 --- a/src/geo.c +++ b/src/geo.c @@ -82,18 +82,18 @@ void geoArrayFree(geoArray *ga) { /* ==================================================================== * Helpers * ==================================================================== */ -static inline int decodeGeohash(double bits, double *latlong) { +static inline int decodeGeohash(double bits, double *xy) { GeoHashBits hash = { .bits = (uint64_t)bits, .step = GEO_STEP_MAX }; - return geohashDecodeToLatLongWGS84(hash, latlong); + return geohashDecodeToLongLatWGS84(hash, xy); } /* Input Argument Helper */ /* Take a pointer to the latitude arg then use the next arg for longitude. * On parse error REDIS_ERR is returned, otherwise REDIS_OK. */ -static inline int extractLatLongOrReply(redisClient *c, robj **argv, - double *latlong) { +static inline int extractLongLatOrReply(redisClient *c, robj **argv, + double *xy) { for (int i = 0; i < 2; i++) { - if (getDoubleFromObjectOrReply(c, argv[i], latlong + i, NULL) != + if (getDoubleFromObjectOrReply(c, argv[i], xy + i, NULL) != REDIS_OK) { return REDIS_ERR; } @@ -104,11 +104,11 @@ static inline int extractLatLongOrReply(redisClient *c, robj **argv, /* Input Argument Helper */ /* Decode lat/long from a zset member's score. * Returns REDIS_OK on successful decoding, otherwise REDIS_ERR is returned. */ -static int latLongFromMember(robj *zobj, robj *member, double *latlong) { +static int longLatFromMember(robj *zobj, robj *member, double *xy) { double score = 0; if (zsetScore(zobj, member, &score) == REDIS_ERR) return REDIS_ERR; - if (!decodeGeohash(score, latlong)) return REDIS_ERR; + if (!decodeGeohash(score, xy)) return REDIS_ERR; return REDIS_OK; } @@ -166,13 +166,13 @@ static inline void addReplyDoubleDistance(redisClient *c, double d) { * only if the point is within the search area. * * returns REDIS_OK if the point is included, or REIDS_ERR if it is outside. */ -int geoAppendIfWithinRadius(geoArray *ga, double lat, double lon, double radius, double score, sds member) { - double distance, latlong[2]; +int geoAppendIfWithinRadius(geoArray *ga, double lon, double lat, double radius, double score, sds member) { + double distance, xy[2]; - if (!decodeGeohash(score,latlong)) return REDIS_ERR; /* Can't decode. */ + if (!decodeGeohash(score,xy)) return REDIS_ERR; /* Can't decode. */ /* Note that geohashGetDistanceIfInRadiusWGS84() takes arguments in * reverse order: longitude first, latitude later. */ - if (!geohashGetDistanceIfInRadiusWGS84(lon,lat,latlong[1], latlong[0], + if (!geohashGetDistanceIfInRadiusWGS84(lon,lat, xy[0], xy[1], radius, &distance)) { return REDIS_ERR; @@ -180,8 +180,8 @@ int geoAppendIfWithinRadius(geoArray *ga, double lat, double lon, double radius, /* Append the new element. */ geoPoint *gp = geoArrayAppend(ga); - gp->latitude = latlong[0]; - gp->longitude = latlong[1]; + gp->longitude = xy[0]; + gp->latitude = xy[1]; gp->dist = distance; gp->member = member; gp->score = score; @@ -200,7 +200,7 @@ int geoAppendIfWithinRadius(geoArray *ga, double lat, double lon, double radius, * using multiple queries to the sorted set, that we later need to sort * via qsort. Similarly we need to be able to reject points outside the search * radius area ASAP in order to allocate and process more points than needed. */ -int geoGetPointsInRange(robj *zobj, double min, double max, double lat, double lon, double radius, geoArray *ga) { +int geoGetPointsInRange(robj *zobj, double min, double max, double lon, double lat, double radius, geoArray *ga) { /* minex 0 = include min in range; maxex 1 = exclude max in range */ /* That's: min <= val < max */ zrangespec range = { .min = min, .max = max, .minex = 0, .maxex = 1 }; @@ -232,7 +232,7 @@ int geoGetPointsInRange(robj *zobj, double min, double max, double lat, double l ziplistGet(eptr, &vstr, &vlen, &vlong); member = (vstr == NULL) ? sdsfromlonglong(vlong) : sdsnewlen(vstr,vlen); - if (geoAppendIfWithinRadius(ga,lat,lon,radius,score,member) + if (geoAppendIfWithinRadius(ga,lon,lat,radius,score,member) == REDIS_ERR) sdsfree(member); zzlNext(zl, &eptr, &sptr); } @@ -255,7 +255,7 @@ int geoGetPointsInRange(robj *zobj, double min, double max, double lat, double l member = (o->encoding == REDIS_ENCODING_INT) ? sdsfromlonglong((long)o->ptr) : sdsdup(o->ptr); - if (geoAppendIfWithinRadius(ga,lat,lon,radius,ln->score,member) + if (geoAppendIfWithinRadius(ga,lon,lat,radius,ln->score,member) == REDIS_ERR) sdsfree(member); ln = ln->level[0].forward; } @@ -266,7 +266,7 @@ int geoGetPointsInRange(robj *zobj, double min, double max, double lat, double l /* Obtain all members between the min/max of this geohash bounding box. * Populate a geoArray of GeoPoints by calling geoGetPointsInRange(). * Return the number of points added to the array. */ -int membersOfGeoHashBox(robj *zobj, GeoHashBits hash, geoArray *ga, double lat, double lon, double radius) { +int membersOfGeoHashBox(robj *zobj, GeoHashBits hash, geoArray *ga, double lon, double lat, double radius) { GeoHashFix52Bits min, max; /* We want to compute the sorted set scores that will include all the @@ -293,11 +293,11 @@ int membersOfGeoHashBox(robj *zobj, GeoHashBits hash, geoArray *ga, double lat, hash.bits++; max = geohashAlign52Bits(hash); - return geoGetPointsInRange(zobj, min, max, lat, lon, radius, ga); + return geoGetPointsInRange(zobj, min, max, lon, lat, radius, ga); } /* Search all eight neighbors + self geohash box */ -int membersOfAllNeighbors(robj *zobj, GeoHashRadius n, double lat, double lon, double radius, geoArray *ga) { +int membersOfAllNeighbors(robj *zobj, GeoHashRadius n, double lon, double lat, double radius, geoArray *ga) { GeoHashBits neighbors[9]; unsigned int i, count = 0; @@ -316,7 +316,7 @@ int membersOfAllNeighbors(robj *zobj, GeoHashRadius n, double lat, double lon, d for (i = 0; i < sizeof(neighbors) / sizeof(*neighbors); i++) { if (HASHISZERO(neighbors[i])) continue; - count += membersOfGeoHashBox(zobj, neighbors[i], ga, lat, lon, radius); + count += membersOfGeoHashBox(zobj, neighbors[i], ga, lon, lat, radius); } return count; } @@ -342,9 +342,9 @@ static int sort_gp_desc(const void *a, const void *b) { * Commands * ==================================================================== */ void geoAddCommand(redisClient *c) { - /* args 0-4: [cmd, key, lat, lng, val]; optional 5-6: [radius, units] + /* args 0-4: [cmd, key, lng, lat, val]; optional 5-6: [radius, units] * - OR - - * args 0-N: [cmd, key, lat, lng, val, lat2, lng2, val2, ...] */ + * args 0-N: [cmd, key, lng, lat, val, lng2, lat2, val2, ...] */ /* Prepare for the three different forms of the add command. */ double radius_meters = 0; @@ -358,8 +358,8 @@ void geoAddCommand(redisClient *c) { return; } else if ((c->argc - 2) % 3 != 0) { /* Need an odd number of arguments if we got this far... */ - addReplyError(c, "format is: geoadd [key] [lat1] [long1] [member1] " - "[lat2] [long2] [member2] ... "); + addReplyError(c, "format is: geoadd [key] [x1] [y1] [member1] " + "[x2] [y2] [member2] ... "); return; } @@ -376,9 +376,9 @@ void geoAddCommand(redisClient *c) { uint8_t step = geohashEstimateStepsByRadius(radius_meters,0); int i; for (i = 0; i < elements; i++) { - double latlong[elements * 2]; + double xy[2]; - if (extractLatLongOrReply(c, (c->argv+2)+(i*3),latlong) == REDIS_ERR) { + if (extractLongLatOrReply(c, (c->argv+2)+(i*3),xy) == REDIS_ERR) { for (i = 0; i < argc; i++) if (argv[i]) decrRefCount(argv[i]); zfree(argv); @@ -391,10 +391,7 @@ void geoAddCommand(redisClient *c) { /* Turn the coordinates into the score of the element. */ GeoHashBits hash; - double latitude = latlong[0]; - double longitude = latlong[1]; - geohashEncodeWGS84(latitude, longitude, step, &hash); - + geohashEncodeWGS84(xy[0], xy[1], step, &hash); GeoHashFix52Bits bits = geohashAlign52Bits(hash); robj *score = createObject(REDIS_STRING, sdsfromlonglong(bits)); robj *val = c->argv[2 + i * 3 + 2]; @@ -416,7 +413,7 @@ void geoAddCommand(redisClient *c) { #define RADIUS_MEMBER 2 static void geoRadiusGeneric(redisClient *c, int type) { - /* type == cords: [cmd, key, lat, long, radius, units, [optionals]] + /* type == cords: [cmd, key, long, lat, radius, units, [optionals]] * type == member: [cmd, key, member, radius, units, [optionals]] */ robj *key = c->argv[1]; @@ -427,17 +424,17 @@ static void geoRadiusGeneric(redisClient *c, int type) { return; } - /* Find lat/long to use for radius search based on inquiry type */ + /* Find long/lat to use for radius search based on inquiry type */ int base_args; - double latlong[2] = { 0 }; + double xy[2] = { 0 }; if (type == RADIUS_COORDS) { base_args = 6; - if (extractLatLongOrReply(c, c->argv + 2, latlong) == REDIS_ERR) + if (extractLongLatOrReply(c, c->argv + 2, xy) == REDIS_ERR) return; } else if (type == RADIUS_MEMBER) { base_args = 5; robj *member = c->argv[2]; - if (latLongFromMember(zobj, member, latlong) == REDIS_ERR) { + if (longLatFromMember(zobj, member, xy) == REDIS_ERR) { addReplyError(c, "could not decode requested zset member"); return; } @@ -483,7 +480,7 @@ static void geoRadiusGeneric(redisClient *c, int type) { /* Get all neighbor geohash boxes for our radius search */ GeoHashRadius georadius = - geohashGetAreasByRadiusWGS84(latlong[0], latlong[1], radius_meters); + geohashGetAreasByRadiusWGS84(xy[0], xy[1], radius_meters); #ifdef DEBUG printf("Searching with step size: %d\n", georadius.hash.step); @@ -491,7 +488,7 @@ static void geoRadiusGeneric(redisClient *c, int type) { /* Search the zset for all matching points */ geoArray *ga = geoArrayCreate(); - membersOfAllNeighbors(zobj, georadius, latlong[0], latlong[1], radius_meters, ga); + membersOfAllNeighbors(zobj, georadius, xy[0], xy[1], radius_meters, ga); /* If no matching results, the user gets an empty reply. */ if (ga->used == 0) { @@ -549,15 +546,15 @@ static void geoRadiusGeneric(redisClient *c, int type) { if (withcoords) { addReplyMultiBulkLen(c, 2); - addReplyDouble(c, gp->latitude); addReplyDouble(c, gp->longitude); + addReplyDouble(c, gp->latitude); } } geoArrayFree(ga); } void geoRadiusCommand(redisClient *c) { - /* args 0-5: ["georadius", key, lat, long, radius, units]; + /* args 0-5: ["georadius", key, long, lat, radius, units]; * optionals: [withdist, withcoords, asc|desc] */ geoRadiusGeneric(c, RADIUS_COORDS); } @@ -578,30 +575,30 @@ void geoDecodeCommand(redisClient *c) { geohash.step = GEO_STEP_MAX; geohashDecodeWGS84(geohash, &area); - double lat = (area.latitude.min + area.latitude.max) / 2; double lon = (area.longitude.min + area.longitude.max) / 2; + double lat = (area.latitude.min + area.latitude.max) / 2; /* Returning three nested replies */ addReplyMultiBulkLen(c, 3); /* First, the minimum corner */ addReplyMultiBulkLen(c, 2); - addReplyDouble(c, area.latitude.min); addReplyDouble(c, area.longitude.min); + addReplyDouble(c, area.latitude.min); /* Next, the maximum corner */ addReplyMultiBulkLen(c, 2); - addReplyDouble(c, area.latitude.max); addReplyDouble(c, area.longitude.max); + addReplyDouble(c, area.latitude.max); /* Last, the averaged center of this bounding box */ addReplyMultiBulkLen(c, 2); - addReplyDouble(c, lat); addReplyDouble(c, lon); + addReplyDouble(c, lat); } void geoEncodeCommand(redisClient *c) { - /* args 0-2: ["geoencode", lat, long]; + /* args 0-2: ["geoencode", long, lat]; * optionals: [radius, units] */ double radius_meters = 0; @@ -613,13 +610,13 @@ void geoEncodeCommand(redisClient *c) { return; } - double latlong[2]; - if (extractLatLongOrReply(c, c->argv + 1, latlong) == REDIS_ERR) return; + double xy[2]; + if (extractLongLatOrReply(c, c->argv + 1, xy) == REDIS_ERR) return; /* Encode lat/long into our geohash */ GeoHashBits geohash; uint8_t step = geohashEstimateStepsByRadius(radius_meters,0); - geohashEncodeWGS84(latlong[0], latlong[1], step, &geohash); + geohashEncodeWGS84(xy[0], xy[1], step, &geohash); /* Align the hash to a valid 52-bit integer based on step size */ GeoHashFix52Bits bits = geohashAlign52Bits(geohash); @@ -631,8 +628,8 @@ void geoEncodeCommand(redisClient *c) { GeoHashArea area; geohashDecodeWGS84(geohash, &area); - double lat = (area.latitude.min + area.latitude.max) / 2; double lon = (area.longitude.min + area.longitude.max) / 2; + double lat = (area.latitude.min + area.latitude.max) / 2; /* Return four nested multibulk replies. */ addReplyMultiBulkLen(c, 4); @@ -642,18 +639,18 @@ void geoEncodeCommand(redisClient *c) { /* Return the minimum corner */ addReplyMultiBulkLen(c, 2); - addReplyDouble(c, area.latitude.min); addReplyDouble(c, area.longitude.min); + addReplyDouble(c, area.latitude.min); /* Return the maximum corner */ addReplyMultiBulkLen(c, 2); - addReplyDouble(c, area.latitude.max); addReplyDouble(c, area.longitude.max); + addReplyDouble(c, area.latitude.max); /* Return the averaged center */ addReplyMultiBulkLen(c, 2); - addReplyDouble(c, lat); addReplyDouble(c, lon); + addReplyDouble(c, lat); } /* GEOHASH key ele1 ele2 ... eleN @@ -684,8 +681,8 @@ void geoHashCommand(redisClient *c) { * standard ranges in order to output a valid geohash string. */ /* Decode... */ - double latlong[2]; - if (!decodeGeohash(score,latlong)) { + double xy[2]; + if (!decodeGeohash(score,xy)) { addReply(c,shared.nullbulk); continue; } @@ -693,11 +690,11 @@ void geoHashCommand(redisClient *c) { /* Re-encode */ GeoHashRange r[2]; GeoHashBits hash; - r[0].min = -90; - r[0].max = 90; - r[1].min = -180; - r[1].max = 180; - geohashEncode(&r[0],&r[1],latlong[0],latlong[1],26,&hash); + r[0].min = -180; + r[0].max = 180; + r[1].min = -90; + r[1].max = 90; + geohashEncode(&r[0],&r[1],xy[0],xy[1],26,&hash); char buf[12]; int i; diff --git a/src/geo.h b/src/geo.h index 9cd1f56b..4f5c5e6f 100644 --- a/src/geo.h +++ b/src/geo.h @@ -12,8 +12,8 @@ void geoAddCommand(redisClient *c); /* Structures used inside geo.c in order to represent points and array of * points on the earth. */ typedef struct geoPoint { - double latitude; double longitude; + double latitude; double dist; double score; char *member; diff --git a/tests/unit/geo.tcl b/tests/unit/geo.tcl index eedc40c9..a049804a 100644 --- a/tests/unit/geo.tcl +++ b/tests/unit/geo.tcl @@ -2,46 +2,46 @@ # verify the Redis implementation with a fuzzy test. proc geo_degrad deg {expr {$deg*atan(1)*8/360}} -proc geo_distance {lat1d lon1d lat2d lon2d} { - set lat1r [geo_degrad $lat1d] +proc geo_distance {lon1d lat1d lon2d lat2d} { set lon1r [geo_degrad $lon1d] - set lat2r [geo_degrad $lat2d] + set lat1r [geo_degrad $lat1d] set lon2r [geo_degrad $lon2d] - set u [expr {sin(($lat2r - $lat1r) / 2)}] + set lat2r [geo_degrad $lat2d] set v [expr {sin(($lon2r - $lon1r) / 2)}] + set u [expr {sin(($lat2r - $lat1r) / 2)}] expr {2.0 * 6372797.560856 * \ asin(sqrt($u * $u + cos($lat1r) * cos($lat2r) * $v * $v))} } -proc geo_random_point {latvar lonvar} { - upvar 1 $latvar lat +proc geo_random_point {lonvar latvar} { upvar 1 $lonvar lon + upvar 1 $latvar lat # Note that the actual latitude limit should be -85 to +85, we restrict # the test to -70 to +70 since in this range the algorithm is more precise # while outside this range occasionally some element may be missing. - set lat [expr {-70 + rand()*140}] set lon [expr {-180 + rand()*360}] + set lat [expr {-70 + rand()*140}] } start_server {tags {"geo"}} { test {GEOADD create} { - r geoadd nyc 40.747533 -73.9454966 "lic market" + r geoadd nyc -73.9454966 40.747533 "lic market" } {1} test {GEOADD update} { - r geoadd nyc 40.747533 -73.9454966 "lic market" + r geoadd nyc -73.9454966 40.747533 "lic market" } {0} test {GEOADD invalid coordinates} { catch { - r geoadd nyc 40.747533 -73.9454966 "lic market" \ + r geoadd nyc -73.9454966 40.747533 "lic market" \ foo bar "luck market" } err set err } {*valid*} test {GEOADD multi add} { - r geoadd nyc 40.7648057 -73.9733487 "central park n/q/r" 40.7362513 -73.9903085 "union square" 40.7126674 -74.0131604 "wtc one" 40.6428986 -73.7858139 "jfk" 40.7498929 -73.9375699 "q4" 40.7480973 -73.9564142 4545 + r geoadd nyc -73.9733487 40.7648057 "central park n/q/r" -73.9903085 40.7362513 "union square" -74.0131604 40.7126674 "wtc one" -73.7858139 40.6428986 "jfk" -73.9375699 40.7498929 "q4" -73.9564142 40.7480973 4545 } {6} test {Check geoset values} { @@ -49,11 +49,11 @@ start_server {tags {"geo"}} { } {{wtc one} 1791873972053020 {union square} 1791875485187452 {central park n/q/r} 1791875761332224 4545 1791875796750882 {lic market} 1791875804419201 q4 1791875830079666 jfk 1791895905559723} test {GEORADIUS simple (sorted)} { - r georadius nyc 40.7598464 -73.9798091 3 km ascending + r georadius nyc -73.9798091 40.7598464 3 km ascending } {{central park n/q/r} 4545 {union square}} test {GEORADIUS withdistance (sorted)} { - r georadius nyc 40.7598464 -73.9798091 3 km withdistance ascending + r georadius nyc -73.9798091 40.7598464 3 km withdistance ascending } {{{central park n/q/r} 0.7750} {4545 2.3651} {{union square} 2.7697}} test {GEORADIUSBYMEMBER simple (sorted)} { @@ -65,21 +65,21 @@ start_server {tags {"geo"}} { } {{{wtc one} 0.0000} {{union square} 3.2544} {{central park n/q/r} 6.7000} {4545 6.1975} {{lic market} 6.8969}} test {GEOENCODE simple} { - r geoencode 41.2358883 1.8063239 - } {3471579339700058 {41.235888125243704 1.8063229322433472}\ - {41.235890659964866 1.806328296661377}\ - {41.235889392604285 1.8063256144523621}} + r geoencode 1.8063239 41.2358883 + } {3471579339700058 {1.8063229322433472 41.235888125243704}\ + {1.806328296661377 41.235890659964866}\ + {1.8063256144523621 41.235889392604285}} test {GEODECODE simple} { r geodecode 3471579339700058 - } {{41.235888125243704 1.8063229322433472}\ - {41.235890659964866 1.806328296661377}\ - {41.235889392604285 1.8063256144523621}} + } {{1.8063229322433472 41.235888125243704}\ + {1.806328296661377 41.235890659964866}\ + {1.8063256144523621 41.235889392604285}} test {GEOHASH is able to return geohash strings} { # Example from Wikipedia. r del points - r geoadd points 42.6 -5.6 test + r geoadd points -5.6 42.6 test lindex [r geohash points test] 0 } {ezs42e44yx0} @@ -93,20 +93,20 @@ start_server {tags {"geo"}} { r del mypoints set radius_km [expr {[randomInt 200]+10}] set radius_m [expr {$radius_km*1000}] - geo_random_point search_lat search_lon - lappend debuginfo "Search area: $search_lat,$search_lon $radius_km km" + geo_random_point search_lon search_lat + lappend debuginfo "Search area: $search_lon,$search_lat $radius_km km" set tcl_result {} set argv {} for {set j 0} {$j < 20000} {incr j} { - geo_random_point lat lon - lappend argv $lat $lon "place:$j" - if {[geo_distance $lat $lon $search_lat $search_lon] < $radius_m} { + geo_random_point lon lat + lappend argv $lon $lat "place:$j" + if {[geo_distance $lon $lat $search_lon $search_lat] < $radius_m} { lappend tcl_result "place:$j" - lappend debuginfo "place:$j $lat $lon [expr {[geo_distance $lat $lon $search_lat $search_lon]/1000}] km" + lappend debuginfo "place:$j $lon $lat [expr {[geo_distance $lon $lat $search_lon $search_lat]/1000}] km" } } r geoadd mypoints {*}$argv - set res [lsort [r georadius mypoints $search_lat $search_lon $radius_km km]] + set res [lsort [r georadius mypoints $search_lon $search_lat $radius_km km]] set res2 [lsort $tcl_result] set test_result OK if {$res != $res2} {