前言

  项目中有个经纬度的计算距离需求,想起redis中的GEO数据类型可以实现,记录下GEO的使用。

 

什么是GEO

  GEO是Redis的一种数据类型,在Redis3.2新增的功能,主要用于计算地理位置,并对存储的地理位置信息进行操作;

  GEO支持6个操作命令:

    1. geoadd
    2. geopos
    3. geodist
    4. georadius
    5. georadiusbymember
    6. geohash      

 

数据准备

Init
var redis = ConnectionMultiplexer.Connect("localhost");
var db = redis.GetDatabase(1);

#region init

List<Address> addressList = new List<Address>
{
    new Address("guangzhou","广州",113.27914,23.14987),
    new Address("changsha","长沙",112.95648,28.24896),
    new Address("nanchang","南昌", 115.87584,28.68836 ),
    new Address("hangzhou","杭州", 120.17621,30.30265 ),
    new Address("wuhan","武汉", 114.33453,30.61055 ),
    new Address("chongqing","重庆", 106.56042,29.56748 ),
    new Address("shanghai","上海", 121.48670 ,31.26156 ),
    new Address("chengdu","成都", 121.48670 ,31.26156 ),
    new Address("shijiezhichuang","世界之窗", 113.98041 ,22.54301 ),
    new Address("dongwuyuan","动物园", 113.97722 ,22.60152 ),
    new Address("huanlegu","欢乐谷", 113.98734, 22.54801 )
};

#endregion

foreach (var address in addressList)
{
    db.GeoAdd("address", new GeoEntry(address.Longitude,address.Latitude,address.Description));
}

public class Address
{
    public Address(string name, string description, double longitude, double latitude)
    {
        this.Name = name;
        this.Description = description;
        this.Longitude = longitude;
        this.Latitude = latitude;
    }
    public string Name { get; set; }
    public string Description { get; set; }
    public double Longitude { get; }
    public double Latitude { get; }
}

  

 

GEOADD

  geoadd用于添加经纬度信息,能将经纬度记录到redis geo集合中

  GEOADD key longitude latitude member [longitude latitude member ...]

    longitude:经度
    latitude:维度
    member:位置元素

  Redis示例

> geoadd address 116.40402 39.91500 北京
1

  C#示例

foreach (var address in addressList)
{
    //将准备好的数据写入Redis
    db.GeoAdd("address", new GeoEntry(address.Longitude,address.Latitude,address.Description));
}

   

 

GEOPOS

  geopos 获取地址的经纬度,通过位置元素查询地点的经纬度

  GEOPOS key member [member ...]

  

  Redis示例

> GEOPOS address 北京
116.40402227640151978
39.91500057149188763

  

  C#示例

db.GeoPosition("address", "北京");

 

 

GEODIST

  geodist用于计算两个坐标之间的距离,通过两个位置元素查询到经纬度计算两点之间的距离

  GEODIST key member1 member2 [unit]

    unit:距离单位,是一个可选项,默认以米未单位(m),其他可选项如下:
      ft:英尺
      mi:英里
      m:米
      km:千米

  Redis示例

> GEODIST address 北京 广州 km
1887.7529
> GEODIST address 北京 广州
1887752.8759

  

  C#示例

db.GeoDistance("address", "北京", "广州", GeoUnit.Kilometers);

 

 

GEORADIUS|GEORADIUSBYMEMBER

  georadius和georadiusbymember用于获取指定范围内的位置信息,以给定的经纬度为中心,返回半径内的位置信息

  georadius和georadiusbymember的不同之处在于georadius的中心位置为经纬度,而georadiusbymember的中心点为一个位置元素

  GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]

  GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key]

    radius:半径
    m|km|ft|mi:单位,默认m(m)
    WITHDIST:将位置元素和位置元素到中心的距离一起返回
    WITHCOORD:将位置元素的经纬度一起返回
    WITHHASH: 以 52 位有符号整数的形式, 返回位置元素经过原始 geohash 编码的有序集合分值。
    COUNT:限制记录数
    ASC|DESC:根据距离远近升序|降序排序

   Redis示例

查看代码
 GEORADIUS address 113.96834  22.56296 10 km
世界之窗
欢乐谷
动物园
> GEORADIUS address 113.96834  22.56296 10 km WITHDIST
世界之窗
2.5418
欢乐谷
2.5642
动物园
4.3847
> GEORADIUS address 113.96834  22.56296 10 km WITHDIST WITHCOORD
世界之窗
2.5418
113.98041039705276489
22.54301028663486051
欢乐谷
2.5642
113.98734122514724731
22.54800875676107097
动物园
4.3847
113.97721856832504272
22.60151925515588545
> GEORADIUS address 113.96834  22.56296 10 km WITHDIST WITHCOORD Count 2 desc
动物园
4.3847
113.97721856832504272
22.60151925515588545
欢乐谷
2.5642
113.98734122514724731
22.54800875676107097
> GEORADIUSBYMEMBER address 动物园 10 km
动物园
世界之窗
欢乐谷

 

  C#示例

db.GeoRadius("address", "动物园", 10, GeoUnit.Kilometers);

 

 

GEOHASH

  geohash用于获取位置的hash值
  GEOHASH key member [member ...]

  Redis示例

> geohash address 广州
ws0e9wr3g20

 

  C#示例

db.GeoHash("address", "广州");