1# encoding: utf-8 2 3from __future__ import absolute_import, division, print_function, unicode_literals 4 5from django.contrib.gis.geos import Point 6from django.contrib.gis.measure import D, Distance 7 8from haystack.constants import WGS_84_SRID 9from haystack.exceptions import SpatialError 10 11 12def ensure_geometry(geom): 13 """ 14 Makes sure the parameter passed in looks like a GEOS ``GEOSGeometry``. 15 """ 16 if not hasattr(geom, 'geom_type'): 17 raise SpatialError("Point '%s' doesn't appear to be a GEOS geometry." % geom) 18 19 return geom 20 21 22def ensure_point(geom): 23 """ 24 Makes sure the parameter passed in looks like a GEOS ``Point``. 25 """ 26 ensure_geometry(geom) 27 28 if geom.geom_type != 'Point': 29 raise SpatialError("Provided geometry '%s' is not a 'Point'." % geom) 30 31 return geom 32 33 34def ensure_wgs84(point): 35 """ 36 Ensures the point passed in is a GEOS ``Point`` & returns that point's 37 data is in the WGS-84 spatial reference. 38 """ 39 ensure_point(point) 40 # Clone it so we don't alter the original, in case they're using it for 41 # something else. 42 new_point = point.clone() 43 44 if not new_point.srid: 45 # It has no spatial reference id. Assume WGS-84. 46 new_point.srid = WGS_84_SRID 47 elif new_point.srid != WGS_84_SRID: 48 # Transform it to get to the right system. 49 new_point.transform(WGS_84_SRID) 50 51 return new_point 52 53 54def ensure_distance(dist): 55 """ 56 Makes sure the parameter passed in is a 'Distance' object. 57 """ 58 try: 59 # Since we mostly only care about the ``.km`` attribute, make sure 60 # it's there. 61 km = dist.km 62 except AttributeError: 63 raise SpatialError("'%s' does not appear to be a 'Distance' object." % dist) 64 65 return dist 66 67 68def generate_bounding_box(bottom_left, top_right): 69 """ 70 Takes two opposite corners of a bounding box (order matters!) & generates 71 a two-tuple of the correct coordinates for the bounding box. 72 73 The two-tuple is in the form ``((min_lat, min_lng), (max_lat, max_lng))``. 74 """ 75 west, lat_1 = bottom_left.coords 76 east, lat_2 = top_right.coords 77 min_lat, max_lat = min(lat_1, lat_2), max(lat_1, lat_2) 78 return ((min_lat, west), (max_lat, east)) 79