HAYASHI Kentaro
null+****@clear*****
Tue Nov 6 17:02:14 JST 2012
HAYASHI Kentaro 2012-11-06 17:02:14 +0900 (Tue, 06 Nov 2012) New Revision: 94446e1550ce98c1c2f809767e3a27f4e755a566 https://github.com/groonga/groonga/commit/94446e1550ce98c1c2f809767e3a27f4e755a566 Log: Extract geo_distance rectangle calculation function by distance type Modified files: lib/geo.c Modified: lib/geo.c (+116 -101) =================================================================== --- lib/geo.c 2012-11-06 13:10:24 +0900 (ede1277) +++ lib/geo.c 2012-11-06 17:02:14 +0900 (c5104ae) @@ -1951,6 +1951,121 @@ geo_distance_rectangle_square_root(double start_longitude, double start_latitude return sqrt((x * x) + (y * y)); } +static inline double +geo_distance_rectangle_short_dist_type(quadrant_type quad_type, + double lng1, double lat1, + double lng2, double lat2) +{ + double distance; + double slope, intercept, longitude_delta, latitude_delta; + double east_distance, west_distance, intercept_edge; + double north_distance, south_distance, intermediate_distance; + double first_longitude, first_latitude, third_longitude, third_latitude; + + longitude_delta = lng2 - lng1; + latitude_delta = lat2 - lat1; + if (quad_type == QUADRANT_1ST_TO_4TH || + quad_type == QUADRANT_4TH_TO_1ST || + quad_type == QUADRANT_2ND_TO_3RD || + quad_type == QUADRANT_3RD_TO_2ND) { + if (longitude_delta > 0 || longitude_delta < 0) { + slope = latitude_delta / longitude_delta; + intercept = lat1 - slope * lng1; + intercept_edge = -intercept / slope; + north_distance = geo_distance_rectangle_square_root(lng1, + lat1, + intercept_edge, + 0); + south_distance = geo_distance_rectangle_square_root(intercept_edge, + 0, + lng2, + lat2); + } else { + north_distance = geo_distance_rectangle_square_root(lng1, + lat1, + lng2, + 0); + south_distance = geo_distance_rectangle_square_root(lng1, + 0, + lng2, + lat2); + } + distance = (north_distance + south_distance) * GRN_GEO_RADIUS; + } else if (quad_type == QUADRANT_1ST_TO_3RD || + quad_type == QUADRANT_3RD_TO_1ST || + quad_type == QUADRANT_2ND_TO_4TH || + quad_type == QUADRANT_4TH_TO_2ND) { + slope = latitude_delta / longitude_delta; + intercept = lat1 - slope * lng1; + intercept_edge = -intercept / slope; + if (lng1 > lng2) { + first_longitude = lng1; + first_latitude = lat1; + third_longitude = lng2; + third_latitude = lat2; + } else { + first_longitude = lng2; + first_latitude = lat2; + third_longitude = lng1; + third_latitude = lat1; + } + if (intercept_edge > 0) { + north_distance = geo_distance_rectangle_square_root(first_longitude, + first_latitude, + intercept_edge, + 0); + intermediate_distance = geo_distance_rectangle_square_root(intercept_edge, + 0, + 0, + intercept); + south_distance = geo_distance_rectangle_square_root(0, + intercept, + third_longitude, + third_latitude); + distance = (north_distance + intermediate_distance + + south_distance) * GRN_GEO_RADIUS; + } else if (intercept_edge < 0) { + north_distance = geo_distance_rectangle_square_root(first_longitude, + first_latitude, + 0, + intercept); + intermediate_distance = geo_distance_rectangle_square_root(0, + intercept, + intercept_edge, + 0); + south_distance = geo_distance_rectangle_square_root(intercept_edge, + 0, + third_longitude, + third_latitude); + distance = (north_distance + intermediate_distance + + south_distance) * GRN_GEO_RADIUS; + } else { + north_distance = geo_distance_rectangle_square_root(first_longitude, + first_latitude, + intercept_edge, + 0); + south_distance = geo_distance_rectangle_square_root(intercept_edge, + 0, + third_longitude, + third_latitude); + distance = (north_distance + south_distance) * GRN_GEO_RADIUS; + } + } else { + slope = latitude_delta / longitude_delta; + intercept = lat1 - slope * lng1; + east_distance = geo_distance_rectangle_square_root(lng1, + lat1, + 0, + intercept); + west_distance = geo_distance_rectangle_square_root(0, + intercept, + lng2, + lat2); + distance = (east_distance + west_distance) * GRN_GEO_RADIUS; + } + return distance; +} + double grn_geo_distance_rectangle_raw(grn_ctx *ctx, grn_geo_point *point1, grn_geo_point *point2) @@ -1980,107 +2095,7 @@ grn_geo_distance_rectangle_raw(grn_ctx *ctx, dist_type = geo_longitude_distance_type(point1->longitude, point2->longitude); if (dist_type == LONGITUDE_SHORT) { - longitude_delta = lng2 - lng1; - latitude_delta = lat2 - lat1; - if (quad_type == QUADRANT_1ST_TO_4TH || - quad_type == QUADRANT_4TH_TO_1ST || - quad_type == QUADRANT_2ND_TO_3RD || - quad_type == QUADRANT_3RD_TO_2ND) { - if (longitude_delta > 0 || longitude_delta < 0) { - slope = latitude_delta / longitude_delta; - intercept = lat1 - slope * lng1; - intercept_edge = -intercept / slope; - north_distance = geo_distance_rectangle_square_root(lng1, - lat1, - intercept_edge, - 0); - south_distance = geo_distance_rectangle_square_root(intercept_edge, - 0, - lng2, - lat2); - } else { - north_distance = geo_distance_rectangle_square_root(lng1, - lat1, - lng2, - 0); - south_distance = geo_distance_rectangle_square_root(lng1, - 0, - lng2, - lat2); - } - distance = (north_distance + south_distance) * GRN_GEO_RADIUS; - } else if (quad_type == QUADRANT_1ST_TO_3RD || - quad_type == QUADRANT_3RD_TO_1ST || - quad_type == QUADRANT_2ND_TO_4TH || - quad_type == QUADRANT_4TH_TO_2ND) { - slope = latitude_delta / longitude_delta; - intercept = lat1 - slope * lng1; - intercept_edge = -intercept / slope; - if (lng1 > lng2) { - first_longitude = lng1; - first_latitude = lat1; - third_longitude = lng2; - third_latitude = lat2; - } else { - first_longitude = lng2; - first_latitude = lat2; - third_longitude = lng1; - third_latitude = lat1; - } - if (intercept_edge > 0) { - north_distance = geo_distance_rectangle_square_root(first_longitude, - first_latitude, - intercept_edge, - 0); - intermediate_distance = geo_distance_rectangle_square_root(intercept_edge, - 0, - 0, - intercept); - south_distance = geo_distance_rectangle_square_root(0, - intercept, - third_longitude, - third_latitude); - distance = (north_distance + intermediate_distance + - south_distance) * GRN_GEO_RADIUS; - } else if (intercept_edge < 0) { - north_distance = geo_distance_rectangle_square_root(first_longitude, - first_latitude, - 0, - intercept); - intermediate_distance = geo_distance_rectangle_square_root(0, - intercept, - intercept_edge, - 0); - south_distance = geo_distance_rectangle_square_root(intercept_edge, - 0, - third_longitude, - third_latitude); - distance = (north_distance + intermediate_distance + - south_distance) * GRN_GEO_RADIUS; - } else { - north_distance = geo_distance_rectangle_square_root(first_longitude, - first_latitude, - intercept_edge, - 0); - south_distance = geo_distance_rectangle_square_root(intercept_edge, - 0, - third_longitude, - third_latitude); - distance = (north_distance + south_distance) * GRN_GEO_RADIUS; - } - } else { - slope = latitude_delta / longitude_delta; - intercept = lat1 - slope * lng1; - east_distance = geo_distance_rectangle_square_root(lng1, - lat1, - 0, - intercept); - west_distance = geo_distance_rectangle_square_root(0, - intercept, - lng2, - lat2); - distance = (east_distance + west_distance) * GRN_GEO_RADIUS; - } + distance = geo_distance_rectangle_short_dist_type(quad_type, lng1, lat1, lng2, lat2); } else { if (quad_type == QUADRANT_1ST_TO_2ND || quad_type == QUADRANT_4TH_TO_3RD) { -------------- next part -------------- HTML����������������������������... 다운로드