# -*- coding: utf-8 -*-
from redis import StrictRedis
from .exc import InvalidPointError
default_config = {
'GEO_REDIS_HOST': 'localhost',
'GEO_REDIS_PORT': 6379,
'GEO_REDIS_PASSWORD': None,
'GEO_REDIS_DB': 0
}
[docs]class Point(object):
__metaclass__ = MetaPoint
def __init__(self, longitude, latitude, member):
self.longitude = longitude
self.latitude = latitude
self.member = member
@classmethod
[docs] def create(cls, longitude, latitude, member):
"""
Create a new Point instance
Args:
longitude(float): the point's longitude
latitude(float): the point's latitude
member(string): member
"""
cls.redis_store.geoadd(cls.__key__, longitude, latitude, member)
return cls(longitude, latitude, member)
[docs] def delete(self):
"""
Delete this point
"""
return self.__class__.redis_store.zrem(self.__key__, self.member)
[docs] def update(self, **kwargs):
"""
Update this point
Args:
longitude(float): the point's longitude
latitude(float): the point's latitude
member(string): member
"""
longitude = kwargs.get("longitude") or self.longitude
latitude = kwargs.get("latitude") or self.latitude
member = kwargs.get("member") or self.member
self.delete()
new_self = self.create(longitude, latitude, member)
self.longitude = new_self.longitude
self.latitude = new_self.latitude
self.member = new_self.member
@classmethod
[docs] def get_by_member(cls, member):
"""
Get a Point instance by its member
Args:
member(string): member
"""
longitude, latitude = cls.redis_store.geopos(cls.__key__, member)[0]
return cls(longitude, latitude, member)
@classmethod
[docs] def query_by_pos(cls, longitude, latitude, dist=100, unit='m'):
"""
Query points by position
Args:
longitude(float): the center's longitude
latitude(float): the center's latitude
dist(float): the radius of the circle
unit(string): m, km or other, the unit of the dist
"""
member_list = cls.redis_store.georadius(cls.__key__, longitude, latitude, dist, unit)
return [cls.get_by_member(member) for member in member_list]
@classmethod
[docs] def query_by_member(cls, member, dist=100, unit='m'):
"""
Query points by member
Args:
member(string): the point's member
dist(float): the radius of the circle
unit(string): m, km or other, the unit of the dist
"""
member_list = cls.redis_store.georadiusbymember(cls.__key__, member, dist, unit)
return [cls.get_by_member(_member) for _member in member_list]
@classmethod
[docs] def dist(cls, point1, point2):
"""
Calculate the distance between point1 and point2
Args:
point1(subclass of Point): a point.
point2(subclass of Point): another point.
"""
return cls.redis_store.geodist(cls.__key__, point1.member, point2.member)
[docs] def geo_hash(self):
"""
The hash of this point, can be view on http://geohash.org/<geohash-string>
"""
return self.__class__.redis_store.geohash(self.__key__, self.member)[0]
def __str__(self):
return '<%s __key__:%s longitude:%s latitude:%s member:%s>' % \
(self.__class__.__name__, self.__key__, self.longitude, self.latitude, self.member)
__repr__ = __str__