diff --git a/okapi/services/caches/search/nearest.php b/okapi/services/caches/search/nearest.php index 64b5f4bf..d9dd3cd9 100644 --- a/okapi/services/caches/search/nearest.php +++ b/okapi/services/caches/search/nearest.php @@ -69,15 +69,32 @@ public static function call(OkapiRequest $request) { if (!preg_match("/^-?[0-9]+(\.?[0-9]*)$/", $tmp)) throw new InvalidParam('radius', "'$tmp' is not a valid float number."); - $radius = floatval($tmp); + $radius = floatval($tmp); # is given in kilometers if ($radius <= 0) throw new InvalidParam('radius', "Has to be a positive number."); - $radius *= 1000; # this one is given in kilemeters, converting to meters! + + # Apply a latitude-range prefilter if it looks promising. + # See https://github.com/opencaching/okapi/issues/363 for more info. + + $optimization_radius = 100; # in kilometers, optimized for Opencaching.de + $km2degrees_upper_estimate_factor = 0.01; + + if ($radius <= $optimization_radius) + { + $radius_degrees = $radius * $km2degrees_upper_estimate_factor; + $where_conds[] = " + latitude >= '".mysql_real_escape_string($center_lat - $radius_degrees)."' + and latitude <= '".mysql_real_escape_string($center_lat + $radius_degrees)."' + "; + } + + $radius *= 1000; # convert from kilometers to meters $where_conds[] = "$distance_formula <= '".mysql_real_escape_string($radius)."'"; } $search_params = $search_assistant->get_search_params(); $search_params['where_conds'] = array_merge($where_conds, $search_params['where_conds']); + $search_params['caches_indexhint'] = "use index (latitude)"; $search_params['order_by'][] = $distance_formula; # not replaced; added to the end! $search_assistant->set_search_params($search_params); diff --git a/okapi/services/caches/search/searching.inc.php b/okapi/services/caches/search/searching.inc.php index 4e5387d6..df9e8f44 100755 --- a/okapi/services/caches/search/searching.inc.php +++ b/okapi/services/caches/search/searching.inc.php @@ -692,6 +692,7 @@ public function prepare_common_search_params() 'offset' => (int)$offset, 'limit' => (int)$limit, 'order_by' => $order_clauses, + 'caches_indexhint' => '', 'extra_tables' => $extra_tables, 'extra_joins' => $extra_joins, ); @@ -717,7 +718,7 @@ public function prepare_common_search_params() public function get_common_search_result() { $tables = array_merge( - array('caches'), + array('caches '.$this->search_params['caches_indexhint']), $this->search_params['extra_tables'] ); $where_conds = array_merge(