"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/geohash_helper.c" between
redis-6.2-rc3.tar.gz and redis-6.2.0.tar.gz

About: redis is an advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets.

geohash_helper.c  (redis-6.2-rc3):geohash_helper.c  (redis-6.2.0)
skipping to change at line 88 skipping to change at line 88
/* Frame to valid range. */ /* Frame to valid range. */
if (step < 1) step = 1; if (step < 1) step = 1;
if (step > 26) step = 26; if (step > 26) step = 26;
return step; return step;
} }
/* Return the bounding box of the search area by shape (see geohash.h GeoShape) /* Return the bounding box of the search area by shape (see geohash.h GeoShape)
* bounds[0] - bounds[2] is the minimum and maximum longitude * bounds[0] - bounds[2] is the minimum and maximum longitude
* while bounds[1] - bounds[3] is the minimum and maximum latitude. * while bounds[1] - bounds[3] is the minimum and maximum latitude.
* since the higher the latitude, the shorter the arc length, the box shape is a
s follows
* (left and right edges are actually bent), as shown in the following diagram:
* *
* This function does not behave correctly with very large radius values, for * \-----------------/ -------- \-----------------/
* instance for the coordinates 81.634948934258375 30.561509253718668 and a * \ / / \ \ /
* radius of 7083 kilometers, it reports as bounding boxes: * \ (long,lat) / / (long,lat) \ \ (long,lat) /
* * \ / / \ / \
* min_lon 7.680495, min_lat -33.119473, max_lon 155.589402, max_lat 94.242491 * --------- /----------------\ /--------------\
* * Northern Hemisphere Southern Hemisphere Around the equator
* However, for instance, a min_lon of 7.680495 is not correct, because the */
* point -1.27579540014266968 61.33421815228281559 is at less than 7000
* kilometers away.
*
* Since this function is currently only used as an optimization, the
* optimization is not used for very big radiuses, however the function
* should be fixed. */
int geohashBoundingBox(GeoShape *shape, double *bounds) { int geohashBoundingBox(GeoShape *shape, double *bounds) {
if (!bounds) return 0; if (!bounds) return 0;
double longitude = shape->xy[0]; double longitude = shape->xy[0];
double latitude = shape->xy[1]; double latitude = shape->xy[1];
double height = shape->conversion * (shape->type == CIRCULAR_TYPE ? shape->t .radius : shape->t.r.height/2); double height = shape->conversion * (shape->type == CIRCULAR_TYPE ? shape->t .radius : shape->t.r.height/2);
double width = shape->conversion * (shape->type == CIRCULAR_TYPE ? shape->t. radius : shape->t.r.width/2); double width = shape->conversion * (shape->type == CIRCULAR_TYPE ? shape->t. radius : shape->t.r.width/2);
const double long_delta = rad_deg(width/EARTH_RADIUS_IN_METERS/cos(deg_rad(l atitude)));
const double lat_delta = rad_deg(height/EARTH_RADIUS_IN_METERS); const double lat_delta = rad_deg(height/EARTH_RADIUS_IN_METERS);
bounds[0] = longitude - long_delta; const double long_delta_top = rad_deg(width/EARTH_RADIUS_IN_METERS/cos(deg_r
bounds[2] = longitude + long_delta; ad(latitude+lat_delta)));
const double long_delta_bottom = rad_deg(width/EARTH_RADIUS_IN_METERS/cos(de
g_rad(latitude-lat_delta)));
/* The directions of the northern and southern hemispheres
* are opposite, so we choice different points as min/max long/lat */
int southern_hemisphere = latitude < 0 ? 1 : 0;
bounds[0] = southern_hemisphere ? longitude-long_delta_bottom : longitude-lo
ng_delta_top;
bounds[2] = southern_hemisphere ? longitude+long_delta_bottom : longitude+lo
ng_delta_top;
bounds[1] = latitude - lat_delta; bounds[1] = latitude - lat_delta;
bounds[3] = latitude + lat_delta; bounds[3] = latitude + lat_delta;
return 1; return 1;
} }
/* Calculate a set of areas (center + 8) that are able to cover a range query /* Calculate a set of areas (center + 8) that are able to cover a range query
* for the specified position and shape (see geohash.h GeoShape). * for the specified position and shape (see geohash.h GeoShape).
* the bounding box saved in shaple.bounds */ * the bounding box saved in shaple.bounds */
GeoHashRadius geohashCalculateAreasByShapeWGS84(GeoShape *shape) { GeoHashRadius geohashCalculateAreasByShapeWGS84(GeoShape *shape) {
GeoHashRange long_range, lat_range; GeoHashRange long_range, lat_range;
skipping to change at line 140 skipping to change at line 140
geohashBoundingBox(shape, shape->bounds); geohashBoundingBox(shape, shape->bounds);
min_lon = shape->bounds[0]; min_lon = shape->bounds[0];
min_lat = shape->bounds[1]; min_lat = shape->bounds[1];
max_lon = shape->bounds[2]; max_lon = shape->bounds[2];
max_lat = shape->bounds[3]; max_lat = shape->bounds[3];
double longitude = shape->xy[0]; double longitude = shape->xy[0];
double latitude = shape->xy[1]; double latitude = shape->xy[1];
/* radius_meters is calculated differently in different search types: /* radius_meters is calculated differently in different search types:
* 1) CIRCULAR_TYPE, just use radius. * 1) CIRCULAR_TYPE, just use radius.
* 2) RECTANGLE_TYPE, in order to calculate accurately, we should use * 2) RECTANGLE_TYPE, we use sqrt((width/2)^2 + (height/2)^2) to
* sqrt((width/2)^2 + (height/2)^2), so that the box is bound by a circle, * calculate the distance from the center point to the corner */
* But the current code a simpler approach resulting in a smaller circle,
* which is safe because we search the 8 nearby boxes anyway. */
double radius_meters = shape->type == CIRCULAR_TYPE ? shape->t.radius : double radius_meters = shape->type == CIRCULAR_TYPE ? shape->t.radius :
shape->t.r.width > shape->t.r.height ? shape->t.r.wi dth/2 : shape->t.r.height/2; sqrt((shape->t.r.width/2)*(shape->t.r.width/2) + (shape->t.r.height/ 2)*(shape->t.r.height/2));
radius_meters *= shape->conversion; radius_meters *= shape->conversion;
steps = geohashEstimateStepsByRadius(radius_meters,latitude); steps = geohashEstimateStepsByRadius(radius_meters,latitude);
geohashGetCoordRange(&long_range,&lat_range); geohashGetCoordRange(&long_range,&lat_range);
geohashEncode(&long_range,&lat_range,longitude,latitude,steps,&hash); geohashEncode(&long_range,&lat_range,longitude,latitude,steps,&hash);
geohashNeighbors(&hash,&neighbors); geohashNeighbors(&hash,&neighbors);
geohashDecode(long_range,lat_range,hash,&area); geohashDecode(long_range,lat_range,hash,&area);
/* Check if the step is enough at the limits of the covered area. /* Check if the step is enough at the limits of the covered area.
skipping to change at line 248 skipping to change at line 246
if (*distance > radius) return 0; if (*distance > radius) return 0;
return 1; return 1;
} }
int geohashGetDistanceIfInRadiusWGS84(double x1, double y1, double x2, int geohashGetDistanceIfInRadiusWGS84(double x1, double y1, double x2,
double y2, double radius, double y2, double radius,
double *distance) { double *distance) {
return geohashGetDistanceIfInRadius(x1, y1, x2, y2, radius, distance); return geohashGetDistanceIfInRadius(x1, y1, x2, y2, radius, distance);
} }
/* Judge whether a point is in the axis-aligned rectangle. /* Judge whether a point is in the axis-aligned rectangle, when the distance
* bounds : see geohash.h GeoShape::bounds * between a searched point and the center point is less than or equal to
* height/2 or width/2 in height and width, the point is in the rectangle.
*
* width_m, height_m: the rectangle
* x1, y1 : the center of the box * x1, y1 : the center of the box
* x2, y2 : the point to be searched * x2, y2 : the point to be searched
*/ */
int geohashGetDistanceIfInRectangle(double *bounds, double x1, double y1, int geohashGetDistanceIfInRectangle(double width_m, double height_m, double x1, double y1,
double x2, double y2, double *distance) { double x2, double y2, double *distance) {
if (x2 < bounds[0] || x2 > bounds[2] || y2 < bounds[1] || y2 > bounds[3]) re double lon_distance = geohashGetDistance(x2, y2, x1, y2);
turn 0; double lat_distance = geohashGetDistance(x2, y2, x2, y1);
if (lon_distance > width_m/2 || lat_distance > height_m/2) {
return 0;
}
*distance = geohashGetDistance(x1, y1, x2, y2); *distance = geohashGetDistance(x1, y1, x2, y2);
return 1; return 1;
} }
 End of changes. 9 change blocks. 
26 lines changed or deleted 35 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)