From 9f1d19d46565719a0a533884d14fb9972b528e5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Szymon=20Te=C5=BCewski?= Date: Thu, 17 Jan 2013 10:29:50 +0100 Subject: [PATCH] bounding box and within spatial search fixed --- docs/spatial.rst | 4 +--- haystack/backends/elasticsearch_backend.py | 10 +++++----- haystack/utils/geo.py | 11 +++++------ tests/spatial/tests.py | 9 +++++++++ tests/spatial_settings.py | 2 +- 5 files changed, 21 insertions(+), 15 deletions(-) diff --git a/docs/spatial.rst b/docs/spatial.rst index cd2c8c427..c862a34b9 100644 --- a/docs/spatial.rst +++ b/docs/spatial.rst @@ -218,9 +218,7 @@ finding results within an area. ``within`` is a bounding box comparison. A bounding box is a rectangular area within which to search. It's composed of a bottom-left point & a top-right -point, though provided you give two opposing corners in either order, Haystack -will determine the right coordinates. It is faster but slighty sloppier than -its counterpart. +point. It is faster but slighty sloppier than its counterpart. Examples:: diff --git a/haystack/backends/elasticsearch_backend.py b/haystack/backends/elasticsearch_backend.py index e6ba14b9a..9fa4f35c8 100644 --- a/haystack/backends/elasticsearch_backend.py +++ b/haystack/backends/elasticsearch_backend.py @@ -400,17 +400,17 @@ def build_search_kwargs(self, query_string, sort_by=None, start_offset=0, end_of if within is not None: from haystack.utils.geo import generate_bounding_box - ((min_lat, min_lng), (max_lat, max_lng)) = generate_bounding_box(within['point_1'], within['point_2']) + ((south, west), (north, east)) = generate_bounding_box(within['point_1'], within['point_2']) within_filter = { "geo_bounding_box": { within['field']: { "top_left": { - "lat": max_lat, - "lon": min_lng + "lat": north, + "lon": west }, "bottom_right": { - "lat": min_lat, - "lon": max_lng + "lat": south, + "lon": east } } }, diff --git a/haystack/utils/geo.py b/haystack/utils/geo.py index 8ecbbf1ca..072a0ce03 100644 --- a/haystack/utils/geo.py +++ b/haystack/utils/geo.py @@ -60,15 +60,14 @@ def ensure_distance(dist): return dist -def generate_bounding_box(point_1, point_2): +def generate_bounding_box(bottom_left, top_right): """ - Takes two opposite corners of a bounding box (in any order) & generates + Takes two opposite corners of a bounding box (order matters!) & generates a two-tuple of the correct coordinates for the bounding box. The two-tuple is in the form ``((min_lat, min_lng), (max_lat, max_lng))``. """ - lng_1, lat_1 = point_1.get_coords() - lng_2, lat_2 = point_2.get_coords() + west, lat_1 = bottom_left.get_coords() + east, lat_2 = top_right.get_coords() min_lat, max_lat = min(lat_1, lat_2), max(lat_1, lat_2) - min_lng, max_lng = min(lng_1, lng_2), max(lng_1, lng_2) - return ((min_lat, min_lng), (max_lat, max_lng)) + return ((min_lat, west), (max_lat, east)) diff --git a/tests/spatial/tests.py b/tests/spatial/tests.py index dc2d4838d..324f45095 100644 --- a/tests/spatial/tests.py +++ b/tests/spatial/tests.py @@ -54,6 +54,15 @@ def test_generate_bounding_box(self): self.assertEqual(max_lat, 38.973081081164715) self.assertEqual(max_lng, -95.23362278938293) + def test_generate_bounding_box_crossing_line_date(self): + downtown_bottom_left = Point(95.23947, 38.9637903) + downtown_top_right = Point(-95.23362278938293, 38.973081081164715) + ((south, west), (north, east)) = generate_bounding_box(downtown_bottom_left, downtown_top_right) + self.assertEqual(south, 38.9637903) + self.assertEqual(west, 95.23947) + self.assertEqual(north, 38.973081081164715) + self.assertEqual(east, -95.23362278938293) + class SpatialSolrNoDistanceTestCase(TestCase): fixtures = ['sample_spatial_data.json'] diff --git a/tests/spatial_settings.py b/tests/spatial_settings.py index a0878abe0..7056118ac 100644 --- a/tests/spatial_settings.py +++ b/tests/spatial_settings.py @@ -14,7 +14,7 @@ 'solr_native_distance': { # Solr 4.X+ 'ENGINE': 'haystack.backends.solr_backend.SolrEngine', - 'URL': 'http://localhost:9003/solr/', + 'URL': 'http://localhost:8983/solr/', # See ``haystack/backends/solr_backend.py`` for details on why not. # 'DISTANCE_AVAILABLE': True, },