forked from leancloud/python-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgeo_point.py
More file actions
120 lines (94 loc) · 3.22 KB
/
Copy pathgeo_point.py
File metadata and controls
120 lines (94 loc) · 3.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# coding: utf-8
import math
__author__ = 'asaka <lan@leancloud.rocks>'
class GeoPoint(object):
def __init__(self, latitude=0, longitude=0):
"""
:param latitude: 纬度
:type latitude: int or float
:param longitude: 经度
:type longitude: int or float
:return: GeoPoint
"""
self._validate(latitude, longitude)
self._latitude = latitude
self._longitude = longitude
@classmethod
def _validate(cls, latitude, longitude):
if latitude < -90.0:
raise ValueError('GeoPoint latitude {0} < -90.0'.format(latitude))
if latitude > 90.0:
raise ValueError('GeoPoint latitude {0} > 90.0'.format(latitude))
if longitude < -180.0:
raise ValueError('GeoPoint longitude {0} < -180.0'.format(longitude))
if longitude > 180.0:
raise ValueError('GeoPoint longitude {0} > 180.0'.format(longitude))
@property
def latitude(self):
"""
当前对象的纬度
"""
return self._latitude
@latitude.setter
def latitude(self, latitude):
self._validate(latitude, self.longitude)
self._latitude = latitude
@property
def longitude(self):
"""
当前对象的经度
"""
return self._longitude
@longitude.setter
def longitude(self, longitude):
self._validate(self.latitude, longitude)
self._longitude = longitude
def dump(self):
self._validate(self.latitude, self.longitude)
return {
'__type': 'GeoPoint',
'latitude': self.latitude,
'longitude': self.longitude,
}
def radians_to(self, other):
"""
Returns the distance from this GeoPoint to another in radians.
:param other: point the other GeoPoint
:type other: GeoPoint
:rtype: float
"""
d2r = math.pi / 180.0
lat1rad = self.latitude * d2r
long1rad = self.longitude * d2r
lat2rad = other.latitude * d2r
long2rad = other.longitude * d2r
delta_lat = lat1rad - lat2rad
delta_long = long1rad - long2rad
sin_delta_lat_div2 = math.sin(delta_lat / 2.0)
sin_delta_long_div2 = math.sin(delta_long / 2.0)
a = ((sin_delta_lat_div2 * sin_delta_lat_div2) +
(math.cos(lat1rad) * math.cos(lat2rad) *
sin_delta_long_div2 * sin_delta_long_div2))
a = min(1.0, a)
return 2 * math.asin(math.sqrt(a))
def kilometers_to(self, other):
"""
Returns the distance from this GeoPoint to another in kilometers.
:param other: point the other GeoPoint
:type other: GeoPoint
:rtype: float
"""
return self.radians_to(other) * 6371.0
def miles_to(self, other):
"""
Returns the distance from this GeoPoint to another in miles.
:param other: point the other GeoPoint
:type other: GeoPoint
:rtype: float
"""
return self.radians_to(other) * 3958.8
def __eq__(self, other):
return \
isinstance(other, GeoPoint) and \
self.latitude == other.latitude and \
self.longitude == other.longitude