跳转至
开发版采用单机部署,无需产品 License 文件。需要多机部署或大规模性能测试? 了解企业版

地理空间

地理空间类型是由经度和纬度坐标组成的复合数据类型,用于表示地理空间数据。GQL 支持三种地理空间类型:Point、LineString 和 Polygon。

为了便于阅读,我们使用 Well-Known Text (WKT) 字符串表示投射在球面上的地理空间值。

Point 类型

WKT 格式:POINT(longitude latitude)

Point 类型代表球面上的单个点,由经度和纬度定义。例如,POINT(37.7749 -12.4194),其中37.7749是经度,-12.4194是纬度。

注意,所有地理空间类型的经度取值在-180到180之间,纬度取值在-90到90之间。

LineString 类型

WKT 格式:LINESTRING(longitude1 latitude1, longitude2 latitude2, ...)

LineString 类型代表由多条直线连接的点在球面上构成的路径。

每组经度和纬度坐标表示路径中的一个点。例如,LINESTRING(1 2, 2 4, 4 8, 8 16)表示一条从点POINT(1 2)开始,经过POINT(2 4),然后到达POINT(4 8),最后到达POINT(8 16)的路径。

LineString 类型也可以在末尾重复第一个点来表示一条闭合路径。

Polygon 类型

WKT 格式:POLYGON((longitude1 latitude1, longitude2 latitude2, ...), ...)

Polygon 类型代表一个具有闭合外边界的形状,该形状内可以包含 0 个或多个孔。它由一系列构成外边界的点,以及构成这些孔的点共同定义。

例如,POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))定义了一个外边界从点POINT(0 0)开始,经过POINT(0 10),然后到达POINT(10 10),接着到达POINT(10 0),最后回到POINT(0 0)的 Polygon。它没有孔。

若要定义包含多个孔的 Polygon,可以参考以下示例:POLYGON((0 0, 0 10, 10 10, 10 0, 0 0), (2 2, 4 2, 4 4, 2 4, 2 2), (6 6, 8 6, 8 8, 6 8, 6 6))。在本例中,外边界由第一组点定义,后续的两组点定义了边界内的孔。

在定义 Polygon 时,请注意以下限制:

  • 每个 Polygon 必须有闭合的外边界。外边界必须包含至少 4 个点,并且第一和最后一个点必须相同以构成闭合。
  • 每个 Polygon 不能自交,即连接点的线段之间不能相互交叉。
  • 若 Polygon 包含孔:
    • 每个孔也必须由至少 4 个点构成闭合环,第一和最后一个点必须相同。
    • 孔之间以及孔与外边界之间不能相互交叉,除非在边界点处。
    • 孔必须完全位于外边界内,并且相互不能重叠。

使用示例

要使用地理空间类型存储地理空间数据,请参考以下步骤:

  1. 在图类型定义中声明地理空间类型。

    '''
    CREATE GRAPH TYPE IF NOT EXISTS location AS 
      { NODE Person 
          ( { 
              id INT64 PRIMARY KEY, 
              any_geo Geography(Any), 
              home_location Geography(Point), 
              commute_route Geography(LineString), 
              favorite_area Geography(Polygon) } ), 
      EDGE GEdge (Person)-[LABEL hire {company_location Geography(Point)}]->(Person) }
    '''
    

    声明地理空间类型的语法如下:

    • Geography(Any)或Geography指代通用的地理空间类型,可以是三种类型中的任何一种(Point、LineString 或 Polygon)。
    • Geography(Point)专指 Point 类型。
    • Geography(LineString)专指 LineString 类型。
    • Geography(Polygon)专指 Polygon 类型。
  2. 基于声明的图类型创建图。

    '''
    CREATE GRAPH IF NOT EXISTS my_graph TYPED location
    '''
    
  3. 往图中插入数据。注意,插入数据时必须使用地理空间函数生成地理空间类型的值。

    插入新的点:

    '''
    USE my_graph INSERT OR REPLACE 
    (@Person {id: 101, 
      any_geo: ST_GeogFromText('POINT(37.7749 -12.4194)'), 
      home_location: ST_GeogFromText('POINT(37.7749 -12.4194)'), 
      commute_route: ST_GeogFromText('LINESTRING(1 2, 2 4, 4 8, 8 16)'), 
      favorite_area: ST_GeogFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))') }), 
    (@Person {id: 102, 
      any_geo: ST_GeogFromText('POINT(34.0522 -18.2437)'), 
      home_location: ST_GeogFromText('POINT(34.0522 -18.2437)'), 
      commute_route: ST_GeogFromText('LINESTRING(3 4, 5 6, 7 8, 9 10)'), 
      favorite_area: ST_GeogFromText('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0), (2 2, 4 2, 4 4, 2 4, 2 2))') })
    '''
    

    基于上述点,插入新的边:

    '''
    USE my_graph Match (n@Person{id:101}), (m@Person{id:102}) 
    INSERT (n)-[@GEdge {company_location: ST_GeogFromText('POINT(37.7749 -12.4194)')}]->(m)
    '''
    
  4. 查询图以检索空间数据。必须使用函数ST_ASText()将地理空间值转换为 WKT 字符串以便于显示。

    '''
    USE my_graph MATCH (p {id:101}) RETURN p.id, ST_ASText(p.home_location) AS home_location, 
    ST_ASText(p.commute_route) AS commute_route, ST_ASText(p.favorite_area) AS favorite_area
    '''
    

    返回:

    +------+-------------------------+---------------------------------+----------------------------------------+
    | p.id | home_location           | commute_route                   | favorite_area                          |
    +------+-------------------------+---------------------------------+----------------------------------------+
    | 101  | POINT(37.7749 -12.4194) | LINESTRING(1 2, 2 4, 4 8, 8 16) | POLYGON((0 0, 0 10, 10 10, 10 0, 0 0)) |
    +------+-------------------------+---------------------------------+----------------------------------------+
    

更多信息

地理空间函数