这里主要是计算区域,覆盖范围查询。
- /* 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).
-  * the bounding box saved in shaple.bounds */
- GeoHashRadius geohashCalculateAreasByShapeWGS84(GeoShape *shape) {
-     GeoHashRange long_range, lat_range;
-     GeoHashRadius radius;
-     GeoHashBits hash;
-     GeoHashNeighbors neighbors;
-     GeoHashArea area;
-     double min_lon, max_lon, min_lat, max_lat;
-     int steps;
-  
-     geohashBoundingBox(shape, shape->bounds);
-     min_lon = shape->bounds[0];
-     min_lat = shape->bounds[1];
-     max_lon = shape->bounds[2];
-     max_lat = shape->bounds[3];
-  
-     double longitude = shape->xy[0];
-     double latitude = shape->xy[1];
-     /* radius_meters is calculated differently in different search types:
-      * 1) CIRCULAR_TYPE, just use radius.
-      * 2) RECTANGLE_TYPE, we use sqrt((widthhttps://cdn.jxasp.com:9143/image/2)^2 + (heighthttps://cdn.jxasp.com:9143/image/2)^2) to
-      * calculate the distance from the center point to the corner */
-     double radius_meters = shape->type == CIRCULAR_TYPE ? shape->t.radius :
-             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;
-  
-     steps = geohashEstimateStepsByRadius(radius_meters,latitude);
-  
-     geohashGetCoordRange(&long_range,&lat_range);
-     geohashEncode(&long_range,&lat_range,longitude,latitude,steps,&hash);
-     geohashNeighbors(&hash,&neighbors);
-     geohashDecode(long_range,lat_range,hash,&area);
-  
-     /* Check if the step is enough at the limits of the covered area.
-      * Sometimes when the search area is near an edge of the
-      * area, the estimated step is not small enough, since one of the
-      * north / south / west / east square is too near to the search area
-      * to cover everything. */
-     int decrease_step = 0;
-     {
-         GeoHashArea north, south, east, west;
-  
-         geohashDecode(long_range, lat_range, neighbors.north, &north);
-         geohashDecode(long_range, lat_range, neighbors.south, &south);
-         geohashDecode(long_range, lat_range, neighbors.east, &east);
-         geohashDecode(long_range, lat_range, neighbors.west, &west);
-  
-         if (geohashGetDistance(longitude,latitude,longitude,north.latitude.max)
-             < radius_meters) decrease_step = 1;
-         if (geohashGetDistance(longitude,latitude,longitude,south.latitude.min)
-             < radius_meters) decrease_step = 1;
-         if (geohashGetDistance(longitude,latitude,east.longitude.max,latitude)
-             < radius_meters) decrease_step = 1;
-         if (geohashGetDistance(longitude,latitude,west.longitude.min,latitude)
-             < radius_meters) decrease_step = 1;
-     }
-  
-     if (steps > 1 && decrease_step) {
-         steps--;
-         geohashEncode(&long_range,&lat_range,longitude,latitude,steps,&hash);
-         geohashNeighbors(&hash,&neighbors);
-         geohashDecode(long_range,lat_range,hash,&area);
-     }
-  
-     /* Exclude the search areas that are useless. */
-     if (steps >= 2) {
-         if (area.latitude.min < min_lat) {
-             GZERO(neighbors.south);
-             GZERO(neighbors.south_west);
-             GZERO(neighbors.south_east);
-         }
-         if (area.latitude.max > max_lat) {
-             GZERO(neighbors.north);
-             GZERO(neighbors.north_east);
-             GZERO(neighbors.north_west);
-         }
-         if (area.longitude.min < min_lon) {
-             GZERO(neighbors.west);
-             GZERO(neighbors.south_west);
-             GZERO(neighbors.north_west);
-         }
-         if (area.longitude.max > max_lon) {
-             GZERO(neighbors.east);
-             GZERO(neighbors.south_east);
-             GZERO(neighbors.north_east);
-         }
-     }
-     radius.hash = hash;
-     radius.neighbors = neighbors;
-     radius.area = area;
-     return radius;
- }
-  
- GeoHashFix52Bits geohashAlign52Bits(const GeoHashBits hash) {
-     uint64_t bits = hash.bits;
-     bits <<= (52 - hash.step * 2);
-     return bits;
- }
-  
- /* Calculate distance using haversin great circle distance formula. */
- double geohashGetDistance(double lon1d, double lat1d, double lon2d, double lat2d) {
-     double lat1r, lon1r, lat2r, lon2r, u, v;
-     lat1r = deg_rad(lat1d);
-     lon1r = deg_rad(lon1d);
-     lat2r = deg_rad(lat2d);
-     lon2r = deg_rad(lon2d);
-     u = sin((lat2r - lat1r) / 2);
-     v = sin((lon2r - lon1r) / 2);
-     return 2.0 * EARTH_RADIUS_IN_METERS *
-            asin(sqrt(u * u + cos(lat1r) * cos(lat2r) * v * v));
- }
-  
- int geohashGetDistanceIfInRadius(double x1, double y1,
-                                  double x2, double y2, double radius,
-                                  double *distance) {
-     *distance = geohashGetDistance(x1, y1, x2, y2);
-     if (*distance > radius) return 0;
-     return 1;
- }
-  
- int geohashGetDistanceIfInRadiusWGS84(double x1, double y1, double x2,
-                                       double y2, double radius,
-                                       double *distance) {
-     return geohashGetDistanceIfInRadius(x1, y1, x2, y2, radius, distance);
- }
-  
- /* Judge whether a point is in the axis-aligned rectangle, when the distance
-  * between a searched point and the center point is less than or equal to
-  * heighthttps://cdn.jxasp.com:9143/image/2 or widthhttps://cdn.jxasp.com:9143/image/2 in height and width, the point is in the rectangle.
-  *
-  * width_m, height_m: the rectangle
-  * x1, y1 : the center of the box
-  * x2, y2 : the point to be searched
-  */
- int geohashGetDistanceIfInRectangle(double width_m, double height_m, double x1, double y1,
-                                     double x2, double y2, double *distance) {
-     double lon_distance = geohashGetDistance(x2, y2, x1, y2);
-     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);
-     return 1;
- }

 
                

















