TairGis是一种使用R-Tree做索引,支持地理信息系统GIS(Geographic Information System)相关接口的数据结构。Redis的原生GEO命令是使用GeoHash和Redis Sorted Set结构完成的,主要用于点的查询,TairGIS在此基础上还支持线、面的查询,功能更加强大。

前提条件

主要特性

  • 使用R-Tree作为索引存储。
  • 支持点、线、面的相关查询(含相交查询)。
  • 兼容Redis的原生GEO命令。

命令列表

表 1. TairGIS命令
命令 语法 说明
GIS.ADD GIS.ADD <area> <polygonName> <polygonWkt> [<polygonName> <polygonWkt> ...] 在area中添加指定名称的多边形(可添加多个),多边形使用WKT(Well-known text)格式描述。
说明 WKT是一种文本标记语言,用于描述矢量几何对象、空间参照系统及空间参照系统之间的转换。
GIS.GET GIS.GET <area> <polygonName> 在area中查找指定名称的多边形的WKT信息。
GIS.GETALL GIS.GETALL <area> [WITHOUTWKT] 返回一个area中所有多边形的名称和WKT信息。
GIS.DEL GIS.DEL <area> <polygonName> 删除area中指定名称的多边形。
DEL DEL <key> [key ...] 原生Redis命令,可以删除一条或多条TairGIS数据。
GIS.CONTAINS GIS.CONTAINS <area> <polygonWkt> [WITHOUTWKT] 判断指定的点、线或面是否包含在area中的某个多边形内。
GIS.INTERSECTS GIS.INTERSECTS <area> <polygonWkt> 判断给定点、线或面,和area中包含的多边形的相交情况。
GIS.SEARCH GIS.SEARCH [RADIUS longitude latitude distance m|km|ft|mi] [MEMBER field distance m|km|ft|mi] [GEOM geom] [COUNT count] [ASC|DESC] [WITHDIST] [WITHOUTWKT] 查找给定经纬度及距离为半径范围内的点。
GIS.WITHIN GIS.WITHIN <area> <polygonWkt> [WITHOUTWKT] 在area中搜索指定多边形内部的点、线或面。

通用参数说明

参数 说明
area 一个几何区域。
PolygonName 一个多边形的名称。
polygonWkt 一个多边形的描述信息,使用WKT(Well-known text)描述,支持如下类型:
  • POINT:描述一个点的WKT信息,例如'POINT (30 11)'
  • LINESTRING:描述一条线的WKT信息,例如'LINESTRING (30 10, 40 40)'
  • POLYGON:描述一个多边形的WKT信息,例如'POLYGON ((31 20, 29 20, 29 21, 31 31))'
说明 不支持MULTIPOINT、MULTILINESTRING、MULTIPOLYGON、GEOMETRY和COLLECTION。
WITHOUTWKT 用于控制是否返回多边形的WKT信息。在使用GIS.GETALLGIS.CONTAINSGIS.SEARCHGIS.WITHIN命令时,如果加上该参数,则不返回多边形的WKT信息。

GIS.ADD

  • 语法

    GIS.ADD <area> <polygonName> <polygonWkt> [<polygonName> <polygonWkt>...]

  • 时间复杂度(用于表示命令执行时间随数据规模增长的变化趋势)

    O(log n)

  • 命令描述

    在area中添加指定名称的多边形(可添加多个),使用WKT(Well-known text)描述。

  • 返回值
    • 成功:返回插入和更新成功的个数。
    • 其它情况:返回相应的异常信息。
  • 使用示例
    127.0.0.1:6379> GIS.ADD hangzhou campus 'POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))'
    (integer) 1

GIS.GET

  • 语法
    GIS.GET <area> <polygonName>
  • 时间复杂度

    O(1)

  • 命令描述

    在area中查找指定名称的多边形的WKT信息。

  • 返回值
    • 成功:返回查询到的WKT。
    • area或polygonName不存在:返回nil。
    • 其它情况:返回相应的异常信息。
  • 使用示例
    127.0.0.1:6379> GIS.ADD hangzhou campus 'POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))'
    (integer) 1
    127.0.0.1:6379> GIS.GET hangzhou campus
    "POLYGON((30 10,40 40,20 40,10 20,30 10))"
    127.0.0.1:6379> GIS.GET hangzhou not-exists
    (nil)
    127.0.0.1:6379> GIS.GET not-exists campus
    (nil)

GIS.GETALL

  • 语法
    GIS.GETALL <area> [WITHOUTWKT]
  • 时间复杂度

    O(n)

  • 命令描述

    返回一个area中所有多边形的名称和WKT信息。如果设置了WITHOUTWKT选项,仅返回多边形的名称。

  • 返回值
    • 成功:返回多边形的名称和WKT信息。如果设置了WITHOUTWKT选项,仅返回多边形的名称。
    • 未查询到:返回nil。
    • 其它情况:返回相应的异常信息。
  • 使用示例
    127.0.0.1:6379> GIS.ADD hangzhou campus 'POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))'
    (integer) 1
    127.0.0.1:6379> GIS.GETALL hangzhou
    1) "campus"
    2) "POLYGON((30 10,40 40,20 40,10 20,30 10))"
    127.0.0.1:6379> GIS.GETALL hangzhou WITHOUTWKT
    1) "campus"

GIS.DEL

  • 语法

    GIS.DEL <area> <polygonName>

  • 时间复杂度

    O(log n)

  • 命令描述

    删除area中指定名称的多边形。

  • 返回值
    • 成功:OK。
    • area或polygonName不存在:返回nil。
    • 其它情况:返回相应的异常信息。
  • 使用示例
    127.0.0.1:6379> GIS.ADD hangzhou campus 'POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))'
    (integer) 1
    127.0.0.1:6379> GIS.GET hangzhou campus
    "POLYGON((30 10,40 40,20 40,10 20,30 10))"
    127.0.0.1:6379> GIS.DEL hangzhou not-exists
    (nil)
    127.0.0.1:6379> GIS.DEL not-exists campus
    (nil)
    127.0.0.1:6379> GIS.DEL hangzhou campus
    OK
    127.0.0.1:6379> GIS.GET hangzhou campus
    (nil)

GIS.CONTAINS

  • 语法

    GIS.CONTAINS <area> <polygonWkt>

  • 时间复杂度
    • 最理想情况:log公式
    • 最差情况:log(n)
  • 命令描述

    判断指定的点、线或面是否包含在area中的某个多边形内。

  • 返回值
    • 成功:返回包含指定点、线或面的多边形的名称和WKT信息。如果设置了WITHOUTWKT选项,仅返回多边形的名称。
    • 未查询到:返回nil。
    • 其它情况:返回相应的异常信息。
  • 使用示例
    127.0.0.1:6379> GIS.ADD hangzhou campus 'POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))'
    (integer) 1
    127.0.0.1:6379> GIS.CONTAINS hangzhou 'POINT (30 11)'
    1) "0"
    2) 1) "campus"
       2) "POLYGON((30 10,40 40,20 40,10 20,30 10))"
    127.0.0.1:6379> GIS.CONTAINS hangzhou 'LINESTRING (30 10, 40 40)'
    1) "0"
    2) 1) "campus"
       2) "POLYGON((30 10,40 40,20 40,10 20,30 10))"
    127.0.0.1:6379> GIS.CONTAINS hangzhou 'POLYGON ((31 20, 29 20, 29 21, 31 31))'
    1) "0"
    2) 1) "campus"
       2) "POLYGON((30 10,40 40,20 40,10 20,30 10))"

GIS.INTERSECTS

  • 语法

    GIS.INTERSECTS <area> <polygonWkt>

  • 时间复杂度
    • 最理想情况:log公式
    • 最差情况:log(n)
  • 命令描述

    判断指定的点、线或面,与area中的某个多边形的相交情况。

  • 返回值
    • 成功:返回与指定点、线或面相交的多边形的名称和WKT信息。
    • 未查询到:返回nil。
    • 其它情况:返回相应的异常信息。
  • 使用示例
    127.0.0.1:6379> GIS.ADD hangzhou campus 'POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))'
    (integer) 1
    127.0.0.1:6379> GIS.INTERSECTS hangzhou 'POINT (30 11)'
    1) "0"
    2) 1) "campus"
       2) "POLYGON((30 10,40 40,20 40,10 20,30 10))"
    127.0.0.1:6379> GIS.INTERSECTS hangzhou 'LINESTRING (30 10, 40 40)'
    1) "0"
    2) 1) "campus"
       2) "POLYGON((30 10,40 40,20 40,10 20,30 10))"
    127.0.0.1:6379> GIS.INTERSECTS hangzhou 'POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))'
    1) "0"
    2) 1) "campus"
       2) "POLYGON((30 10,40 40,20 40,10 20,30 10))"
    127.0.0.1:6379>

GIS.SEARCH

  • 语法
    GIS.SEARCH [RADIUS longitude latitude distance m|km|ft|mi]
    [MEMBER field distance m|km|ft|mi]
    [GEOM geom]
    [COUNT count]
    [ASC|DESC]
    [WITHDIST]
    [WITHOUTWKT]
  • 时间复杂度
    • 最理想情况:log公式
    • 最差情况:log(n)
  • 命令描述

    查找给定经纬度及距离为半径范围内的点,支持下述可选参数:

    • RADIUS:按照参数传递的经度、纬度和半径搜索,取值顺序为经度、纬度、半径、半径单位,例如RADIUS 15 37 200 km
    • MEMBER:从已经存在的多边形中获取经纬度并根据半径搜索,取值顺序为多边形名称、半径、半径单位,例如MEMBER Agrigento 100 km
    • GEOM:按照WKT的格式设置搜索范围,可以是任意多边形,例如GIS.SEARCH Sicily "POINT (13.361389 38.115556)"
    • COUNT:用于限定返回的个数,例如COUNT 3
    • ASC|DESC:用于控制返回信息按照距离排序,例如ASC表示根据中心位置,由近到远排序。
    • WITHDIST:用于控制是否返回距离。
    • WITHOUTWKT:用于控制是否返回多边形的WKT信息。
  • 返回值
    • 成功:返回查询到的多边形名称和WKT信息。
    • 未查询到:返回nil。
    • 其它情况:返回相应的异常信息。
  • 使用示例
    127.0.0.1:6379> GIS.ADD Sicily "Palermo" "POINT (13.361389 38.115556)" "Catania" "POINT(15.087269 37.502669)"
    (integer) 2
    127.0.0.1:6379> GIS.SEARCH Sicily RADIUS 15 37 200 km WITHDIST
    1) "2"
    2) 1) "Palermo"
       2) "POINT(13.361389 38.115556)"
       3) "190.4424"
       4) "Catania"
       5) "POINT(15.087269 37.502669)"
       6) "56.4413"
    127.0.0.1:6379> GIS.SEARCH Sicily RADIUS 15 37 200 km WITHDIST WITHOUTWKT
    1) "2"
    2) 1) "Palermo"
       2) "190.4424"
       3) "Catania"
       4) "56.4413"
    127.0.0.1:6379> GIS.SEARCH Sicily RADIUS 15 37 200 km WITHDIST WITHOUTWKT ASC
    1) "2"
    2) 1) "Catania"
       2) "56.4413"
       3) "Palermo"
       4) "190.4424"
    127.0.0.1:6379> GIS.SEARCH Sicily RADIUS 15 37 200 km WITHDIST WITHOUTWKT ASC COUNT 1
    1) "2"
    2) 1) "Catania"
       2) "56.4413"
    127.0.0.1:6379> GIS.ADD Sicily "Agrigento" "POINT (13.583333 37.316667)"
    (integer) 1
    127.0.0.1:6379> GIS.SEARCH Sicily MEMBER Agrigento 100 km
    1) "2"
    2) 1) "Palermo"
       2) "POINT(13.361389 38.115556)"
       3) "Agrigento"
       4) "POINT(13.583333 37.316667)"

GIS.WITHIN

  • 语法
    GIS.WITHIN <area> <polygonWkt> [WITHOUTWKT]
  • 时间复杂度
    • 最理想情况:log公式
    • 最差情况:log(n)
  • 命令描述

    在area中搜索指定的多边形内部的点、线或面。如果设置了WITHOUTWKT选项,仅返回多边形的名称。

  • 返回值
    • 成功:成功则返回对应多边形的名称和WKT信息。
    • 未查找到:返回null。
    • 其它情况:返回相应的异常信息。
  • 使用示例
    127.0.0.1:6379> GIS.ADD hangzhou campus 'POINT (30 10)'
    (integer) 1
    127.0.0.1:6379> GIS.ADD hangzhou campus1 'LINESTRING (30 10, 40 40)'
    (integer) 1
    127.0.0.1:6379> GIS.WITHIN hangzhou 'POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))'
    1) "2"
    2) 1) "campus"
       2) "POINT(30 10)"
       3) "campus1"
       4) "LINESTRING(30 10,40 40)"