空间值

Cypher® 内置支持处理空间值(POINT 值),这些值可以作为 Neo4j 数据库中节点和关系的属性存储。

本节首先解释 POINT 类型。然后继续讨论 Cypher 对坐标参考系统的支持,以及如何在 Cypher 中使用空间瞬时,包括空间点瞬时如何与 Cypher 索引一起使用。最后,它简要解释了关于空间瞬时的可比性和可排序性。

有关空间函数的更多信息,允许创建和操作空间值,请参阅有关 空间函数 的部分。

有关空间值的比较和排序的更多信息,请参阅有关 值的排序和比较 的部分。

POINT 类型

Neo4j 支持用于空间几何值 的 POINT 类型。

具有 POINT 类型的值具有以下特征

  • 每个点可以具有 2 或 3 个维度。这意味着它包含 2 或 3 个 64 位 FLOAT 值,这些值统称为坐标

  • 每个点还将与特定的 坐标参考系统 (CRS) 相关联,该系统确定坐标中值的含义。

  • POINTLIST<POINT> 的实例可以分配给节点和关系属性。

  • 具有 POINTLIST<POINT> 属性的节点和关系可以使用 点索引 进行索引。这适用于所有 CRS(以及 2D 和 3D)。

  • 距离函数 将对所有 CRS 中的点以及 2D 和 3D 中的点进行操作,但前提是这两个点具有相同的 CRS(因此也具有相同的维度)。

坐标参考系统

支持四种坐标参考系统 (CRS),每种都属于两种类型之一:地理坐标,对地球上的点进行建模,或笛卡尔坐标,对欧几里得空间中的点进行建模

不同坐标系中的数据完全不可比较,并且不能隐式地从一个转换为另一个。即使它们都是笛卡尔或都是地理的但具有不同的维度,也是如此。例如,如果您使用 2D 范围搜索 3D 点,则不会获得任何结果。但是,它们可以排序,如有关 值的排序和比较 的部分中更详细地讨论的那样。

地理坐标参考系统

支持两种地理坐标参考系统 (CRS),对地球上的点进行建模

  • WGS 84 2D

    • WGS 84 CRS 中的 2D 地理点可以通过两种方式之一指定

      • longitudelatitude(如果指定了这些,并且未指定 crs,则 crs 假定为 WGS-84)。

      • xy(在这种情况下,必须指定 crs,否则将假定为笛卡尔)。

    • 指定此 CRS 可以使用名称“wgs-84”或 SRID 4326 来完成,如 point() - WGS 84 2D 中所述。

  • WGS 84 3D

    • WGS 84 CRS 中的 3D 地理点可以通过两种方式之一指定

      • longitudelatitudeheightz(如果指定了这些,并且未指定 crs,则 crs 假定为 WGS-84-3D)。

      • xyz(在这种情况下,必须指定 crs,否则将假定为 Cartesian-3D)。

    • 指定此 CRS 可以使用名称“wgs-84-3d”或 SRID 4979 来完成,如 point() - WGS 84 3D 中所述。

转换坐标单位

latitudelongitude 字段的单位为十进制度,需要使用 Cypher 字面量指定为浮点数。无法使用任何其他格式,例如“度、分、秒”。height 字段的单位为米。当地理点传递到 距离函数 时,结果将始终以米为单位。如果坐标采用与支持的格式或单位不同的任何其他格式或单位,则需要显式转换它们。

例如,如果传入的 $height 是以千米为单位的 STRING 字段,则需要在查询中添加 height: toFloat($height) * 1000。同样,如果预期 distance 函数的结果以千米为单位返回,则需要进行显式转换。以下查询是此转换的一个示例

查询
WITH
  point({latitude: toFloat('13.43'), longitude: toFloat('56.21')}) AS p1,
  point({latitude: toFloat('13.10'), longitude: toFloat('56.41')}) AS p2
RETURN toInteger(point.distance(p1, p2)/1000) AS km
表 1. 结果
公里

42

行:1

笛卡尔坐标参考系统

支持两种笛卡尔坐标参考系统 (CRS),对欧几里得空间中的点进行建模

  • 笛卡尔 2D

    • 笛卡尔 CRS 中,二维点由包含xy坐标值的映射指定。

    • 可以使用名称“cartesian”或 SRID 7203 来指定此 CRS,如point() - 笛卡尔二维中所述。

  • 笛卡尔三维

    • 笛卡尔 CRS 中,三维点由包含xyz坐标值的映射指定。

    • 可以使用名称“cartesian-3d”或 SRID 9157 来指定此 CRS,如point() - 笛卡尔三维中所述。

xyz字段的单位未指定。这意味着当将两个笛卡尔点传递给distance函数时,结果值将与原始坐标具有相同的单位。这对于二维和三维点都适用,因为使用的毕达哥拉斯方程被推广到任意数量的维度。但是,就像您不能将地理点与笛卡尔点进行比较一样,您也不能计算二维点和三维点之间的距离。如果您需要这样做,请显式地将一种类型转换为另一种类型。例如

查询
WITH
  point({x: 3, y: 0}) AS p2d,
  point({x: 0, y: 4, z: 1}) AS p3d
RETURN
  point.distance(p2d, p3d) AS bad,
  point.distance(p2d, point({x: p3d.x, y: p3d.y})) AS good
表 2. 结果
错误 正确

<null>

5.0

行:1

空间瞬间

所有POINT类型都由两个组成部分创建

  • 包含 2 或 3 个FLOAT值(64 位)的坐标

  • 定义坐标中值的含义(以及可能的单位)的坐标参考系统(或 CRS)。

对于大多数用例,无需显式指定 CRS,因为它将从用于指定坐标的键中推断出来。应用两条规则从坐标中推断 CRS

  • 键的选择

    • 如果使用键latitudelongitude指定坐标,则假定 CRS 为地理,因此为WGS-84WGS-84-3D

    • 如果改为使用xy,则默认 CRS 将为CartesianCartesian-3D

  • 维数

    • 如果坐标中有 2 个维度,x & ylongitude & latitude,则 CRS 将为二维 CRS。

    • 如果坐标中有第三个维度,zheight,则 CRS 将为三维 CRS。

所有字段都以显式命名参数映射的形式提供给point函数。Neo4j 不支持坐标字段的有序列表,因为地理坐标和笛卡尔坐标之间的约定存在矛盾,其中地理坐标通常将y放在x之前(latitude放在longitude之前)。

以下查询返回在四个受支持的 CRS 中创建的点。请特别注意原始point函数中坐标的顺序和键,以及这些值在结果中如何显示

查询
RETURN
  point({x: 3, y: 0}) AS cartesian_2d,
  point({x: 0, y: 4, z: 1}) AS cartesian_3d,
  point({latitude: 12, longitude: 56}) AS geo_2d,
  point({latitude: 12, longitude: 56, height: 1000}) AS geo_3d
表 3. 结果
笛卡尔二维 笛卡尔三维 地理二维 地理三维

point({srid:7203, x: 3.0, y: 0.0})

point({srid:9157, x: 0.0, y: 4.0, z: 1.0})

point({srid:4326, x: 56.0, y: 12.0})

point({rid:4979, x: 56.0, y: 12.0, z: 1000.0})

行:1

对于地理坐标,请注意latitude值应始终位于区间[-90, 90]内。此范围之外的任何其他值都将引发异常。longitude值应始终位于区间[-180, 180]内。此范围之外的任何其他值都将被环绕以适合此范围。height值和任何笛卡尔坐标都没有明确限制。将接受有符号 64 位浮点数类型允许范围内的任何值。

点的组成部分

可以将POINT值的组成部分作为属性访问。

表 4. POINT实例的组成部分及其支持位置
组成部分 描述 类型 范围/格式 WGS-84 WGS-84-3D 笛卡尔 笛卡尔三维

instant.x

坐标的第一个元素

FLOAT

数字文字,范围取决于 CRS

instant.y

坐标的第二个元素

FLOAT

数字文字,范围取决于 CRS

instant.z

坐标的第三个元素

FLOAT

数字文字,范围取决于 CRS

instant.longitude

地理 CRS 的第一个坐标元素,本初子午线以东的度数

FLOAT

数字文字,-180.0180.0

instant.latitude

地理 CRS 的第二个坐标元素,赤道以北的度数

FLOAT

数字文字,-90.090.0

instant.height

地理 CRS 的第三个坐标元素,基准面(WGS-84)定义的椭球体上方的米数

FLOAT

数字文字,范围仅受底层 64 位浮点数类型限制

instant.crs

CRS 的名称

STRING

wgs-84wgs-84-3dcartesiancartesian-3d之一

instant.srid

CRS 的内部 Neo4j ID

INTEGER

4326497972039157之一

示例

以下查询显示如何提取笛卡尔二维POINT值的组成部分

查询
WITH point({x: 3, y: 4}) AS p
RETURN
  p.x AS x,
  p.y AS y,
  p.crs AS crs,
  p.srid AS srid
表 5. 结果
x y crs srid

3.0

4.0

"cartesian"

7203

行:1

以下查询显示如何提取WGS-84 三维POINT值的组成部分

查询
WITH point({latitude: 3, longitude: 4, height: 4321}) AS p
RETURN
  p.latitude AS latitude,
  p.longitude AS longitude,
  p.height AS height,
  p.x AS x,
  p.y AS y,
  p.z AS z,
  p.crs AS crs,
  p.srid AS srid
表 6. 结果
latitude longitude height x y z crs srid

3.0

4.0

4321.0

4.0

3.0

4321.0

"wgs-84-3d"

4979

行:1

空间值和索引

如果特定节点或关系属性上存在范围或点索引,并且将空间点分配给节点或关系上的该属性,则该节点或关系将被索引。

在点索引中,Neo4j 在底层广义 B+Tree 上使用二维或三维空间填充曲线。点索引针对距离和边界框查询进行了优化。有关更多信息,请参阅管理索引→点索引

在范围索引中,点将根据其每个坐标参考系统的词法顺序进行排序。对于点值,此索引支持相等性检查。有关更多信息,请参阅管理索引→范围索引

可比性和可排序性

Cypher 不支持使用不等式运算符<<=>>=比较空间值。尝试这样做将返回null

要比较特定范围内的空间点,请改用空间函数point.distancepoint.withinBBox