from math import radians, sin, cos, asin, sqrt from sqlalchemy.types import TypeDecorator, String class Location(TypeDecorator): impl = String cache_ok = True def __init__(self, latitude=None, longitude=None): self.latitude = latitude self.longitude = longitude def process_bind_param(self, value, dialect): if value: return str(value) def process_result_value(self, value, dialect): if value: return Location(* map(float, value.split(","))) def load_dialect_impl(self, dialect): # Provide the implementation for the specified dialect return dialect.type_descriptor(String) def distance(self, other): R = 6371 d_lat = radians(self.latitude - other.latitude) d_lon = radians(self.longitude - other.longitude) a = sin(d_lat/2) * sin(d_lat/2) +\ sin(d_lon/2) * sin(d_lon/2) * cos(radians(self.latitude)) * cos(radians(other.latitude)) c = 2 * asin(sqrt(a)) d = R * c return d def get_cooldown(self, other): distance = self.distance(other) if distance <= 2: return 1 elif distance <= 5: return 2 elif distance <= 7: return 5 elif distance <= 10: return 7 elif distance <= 12: return 8 elif distance <= 18: return 10 elif distance <= 26: return 15 elif distance <= 42: return 19 elif distance <= 65: return 22 elif distance <= 81: return 25 elif distance <= 100: return 35 elif distance <= 220: return 40 elif distance <= 250: return 45 elif distance <= 350: return 51 elif distance <= 375: return 54 elif distance <= 460: return 62 elif distance <= 500: return 65 elif distance <= 565: return 69 elif distance <= 700: return 78 elif distance <= 800: return 84 elif distance <= 900: return 92 elif distance <= 1000: return 99 elif distance <= 1100: return 107 elif distance <= 1200: return 114 elif distance <= 1300: return 117 else: return 120 def __str__(self): return str(self.latitude) + "," + str(self.longitude) def __repr__(self): return str(self.latitude) + "," + str(self.longitude)