12

使用 Redis GEO 储存地理位置 — blog.huangz.me

 3 years ago
source link: https://blog.huangz.me/2019/redis-geo-location.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

使用 Redis GEO 储存地理位置

本文摘录自《Redis使用手册》, 详情请见: RedisGuide.com

../_images/redisguide.png

很多社交网站都提供了与地理位置相关的功能, 比如记录用户自己的位置、获取指定用户的位置, 又或者查找指定范围内的其他用户等等。

在学习了 GEOADDGEOPOSGEODIST 这三个命令之后, 我们同样可以构建出一个具有基本功能的用户地理位置程序, 该程序能够记录用户所在的位置、获取指定用户所在的位置以及计算两个用户之间的直线距离, 具体的实现如代码清单 9-1 所示。


代码清单 9-1 具有基本功能的用户地理位置程序:/geo/location.py

import random

USER_LOCATION_KEY = "user_locations"

class Location:

    def __init__(self, client):
        self.client = client
        self.key = USER_LOCATION_KEY

    def pin(self, user, longitude, latitude):
        """
        记录指定用户的坐标。
        """
        self.client.geoadd(self.key, longitude, latitude, user)

    def get(self, user):
        """
        获取指定用户的坐标。
        """
        position_list = self.client.geopos(self.key, user)
        # geopos() 允许用户输入多个位置,然后以列表形式返回各个位置的坐标。
        # 因为我们这里只传入了一个位置,所以只需要取出列表的第一个元素即可。
        if len(position_list) != 0:
            return position_list[0]

    def calculate_distance(self, user_a, user_b):
        """
        以公里为单位,计算两个用户之间的直线距离。
        """
        return self.client.geodist(self.key, user_a, user_b, unit="km")


这个程序所做的就是使用 GEOADD 命令把用户的 ID 以及用户所在的经纬度关联起来, 然后使用 GEOPOS 命令去获取用户所在的经纬度, 又或者使用 GEODIST 命令去计算两个用户之间的直线距离。

通过执行以下代码, 我们可以创建出相应的用户位置对象, 并使用它记录 peter 、jack 和 tom 这三个用户的地理位置:

>>> from redis import Redis
>>> from location import Location
>>> client = Redis(decode_responses=True)
>>> location = Location(client)
>>> location.pin("peter", 113.20996731519699, 23.593675019671288)
>>> location.pin("jack", 113.22784155607224, 23.125598202060807)
>>> location.pin("tom", 113.40603142976761, 22.511156445825442)

然后通过执行以下代码, 获取 peter 和 jack 的坐标:

>>> location.get("peter")
(113.20996731519699, 23.593675019671288)
>>> location.get("jack")
(113.22784155607224, 23.125598202060807)

最后通过执行以下代码, 计算 peter 和 jack 之间的直线距离, 以及 peter 和 tom 之间的直线距离:

>>> location.calculate_distance("peter", "jack")
52.0944
>>> location.calculate_distance("peter", "tom")
122.0651

Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK