App Engine Python SDK version 1.9.9
[gae.git] / python / google / appengine / api / search / geo_util.py
blob739ba20f9fd2ee9f11fe6e17bc93be15d49b3813
1 #!/usr/bin/env python
3 # Copyright 2007 Google Inc.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 """Utilities to support geo fields on the Python dev server."""
19 import math
22 class LatLng(object):
23 """A class representing a Latitude/Longitude pair."""
25 _EARTH_RADIUS_METERS = 6371010
27 def __init__(self, latitude, longitude):
28 """Initializer.
30 Args:
31 latitude: The latitude in degrees.
32 longitude: The longitude in degrees.
34 Raises:
35 TypeError: If a non-numeric latitude or longitude is passed.
36 """
37 self._lat = latitude
38 self._lng = longitude
40 @property
41 def latitude(self):
42 """Returns the latitude in degrees."""
43 return self._lat
45 @property
46 def longitude(self):
47 """Returns the longitude in degrees."""
48 return self._lng
50 def __sub__(self, other):
51 """Subtraction.
53 Args:
54 other: the LatLng which this LatLng is subtracted by.
56 Returns:
57 the great circle distance between two LatLng objects as computed
58 by the Haversine formula.
59 """
61 assert isinstance(other, LatLng)
63 lat_rad = math.radians(self._lat)
64 lng_rad = math.radians(self._lng)
65 other_lat_rad = math.radians(other.latitude)
66 other_lng_rad = math.radians(other.longitude)
68 dlat = lat_rad - other_lat_rad
69 dlng = lng_rad - other_lng_rad
70 a1 = math.sin(dlat / 2)**2
71 a2 = math.cos(lat_rad) * math.cos(other_lat_rad) * math.sin(dlng / 2)**2
72 return 2 * self._EARTH_RADIUS_METERS * math.asin(math.sqrt(a1 + a2))