空间值
POINT 类型
Neo4j 支持用于空间几何值的 POINT 类型。
POINT 类型的值具有以下特征:
-
每个点可以具有 2 或 3 个维度。这意味着它包含 2 或 3 个 64 位
FLOAT值,它们共同被称为坐标 (Coordinate)。 -
每个点还将关联一个特定的坐标参考系统 (CRS),该系统决定了坐标中各数值的含义。
-
POINT和LIST<POINT>的实例可以分配给节点和关系属性。 -
具有
POINT或LIST<POINT>属性的节点和关系可以使用点索引进行索引。这适用于所有 CRS(2D 和 3D 均适用)。 -
距离函数 (distance function) 适用于所有 CRS 中的 2D 和 3D 点,但前提是两个点具有相同的 CRS(因此也具有相同的维度)。
坐标参考系统 (CRS)
支持四种坐标参考系统 (CRS),每种系统都属于以下两种类型之一:地理坐标 (geographic coordinates)(模拟地球上的点),或笛卡尔坐标 (Cartesian coordinates)(模拟欧几里得空间中的点)。
不同坐标系统中的数据完全不可比较,且无法从一种隐式转换为另一种。即使它们同为笛卡尔坐标或同为地理坐标但维度不同,也是如此。例如,如果您使用 2D 范围搜索 3D 点,将无法得到任何结果。不过,它们是可以排序的,详见空间和时间值的排序章节。
地理坐标参考系统
支持两种地理坐标参考系统 (CRS),用于模拟地球上的点。
-
-
WGS 84 CRS 中的 2D 地理点可通过以下两种方式之一指定:
-
longitude(经度)和latitude(纬度)(如果指定了这些参数,且未指定crs,则默认crs为WGS-84)。 -
x和y(在这种情况下,必须指定crs,否则将默认为笛卡尔坐标系)。
-
-
可以通过名称 'wgs-84' 或 SRID 4326 来指定此 CRS,详见 point() - WGS 84 2D。
-
-
-
WGS 84 CRS 中的 3D 地理点可通过以下两种方式之一指定:
-
longitude、latitude以及height或z(如果指定了这些参数,且未指定crs,则默认crs为WGS-84-3D)。 -
x、y和z(在这种情况下,必须指定crs,否则将默认为 Cartesian-3D)。
-
-
可以通过名称 'wgs-84-3d' 或 SRID 4979 来指定此 CRS,详见 point() - WGS 84 3D。
-
转换坐标单位
latitude 和 longitude 字段的单位为十进制度数,需要使用 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
| km |
|---|
|
行:1 |
笛卡尔坐标参考系统
支持两种笛卡尔坐标参考系统 (CRS),用于模拟欧几里得空间中的点。
-
笛卡尔 2D
-
笛卡尔 CRS 中的 2D 点由包含
x和y坐标值的映射 (map) 指定。 -
可以通过名称 'cartesian' 或 SRID 7203 来指定此 CRS,详见 point() - Cartesian 2D。
-
-
笛卡尔 3D
-
笛卡尔 CRS 中的 3D 点由包含
x、y和z坐标值的映射指定。 -
可以通过名称 'cartesian-3d' 或 SRID 9157 来指定此 CRS,详见 point() - Cartesian 3D。
-
x、y 和 z 字段的单位未指定。这意味着当将两个笛卡尔点传递给 distance 函数时,结果值的单位将与原始坐标相同。这对于 2D 和 3D 点都适用,因为所使用的毕达哥拉斯方程已推广到任意维度。但是,正如您不能比较地理点和笛卡尔点一样,您也无法计算 2D 点和 3D 点之间的距离。如果需要这样做,请显式将一种类型转换为另一种类型。例如:
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
| 错误 | 正确 |
|---|---|
|
|
行:1 |
|
空间实例
所有 POINT 类型均由两个部分创建:
-
包含 2 或 3 个
FLOAT值(64 位)的坐标。 -
定义坐标中数值含义(以及可能的单位)的坐标参考系统 (CRS)。
对于大多数用例,无需显式指定 CRS,因为它将从用于指定坐标的键中推导出来。推导 CRS 时遵循以下两条规则:
-
键的选择
-
如果坐标使用
latitude和longitude键指定,则 CRS 将假定为地理坐标,即WGS-84或WGS-84-3D。 -
如果使用
x和y,则默认 CRS 为Cartesian或Cartesian-3D。
-
-
维度数量
-
如果坐标中有 2 个维度(
x和y,或longitude和latitude),则 CRS 为 2D CRS。 -
如果坐标中有第三个维度(
z或height),则 CRS 为 3D CRS。
-
所有字段均以显式命名参数的映射形式提供给 point 函数。Neo4j 不支持坐标字段的有序列表,因为地理坐标和笛卡尔坐标之间存在冲突的约定(地理坐标通常先列出 y,即先 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
| cartesian_2d | cartesian_3d | geo_2d | geo_3d |
|---|---|---|---|
|
|
|
|
行:1 |
|||
对于地理坐标,请务必注意 latitude 值应始终位于区间 [-90, 90] 内。超出此范围的任何值都会抛出异常。longitude 值应始终位于区间 [-180, 180] 内。超出此范围的任何值都将进行循环处理以适应此范围。height 值和任何笛卡尔坐标没有明确限制。只要在带符号 64 位浮点类型允许的范围内,任何值都将被接受。
点的组成部分
POINT 值的组成部分可以作为属性进行访问。
| Component (组件) | 描述 | 类型 | 范围/格式 | WGS-84 | WGS-84-3D | Cartesian | Cartesian-3D |
|---|---|---|---|---|---|---|---|
|
坐标的第一个元素 |
|
数字字面量,范围取决于 CRS |
||||
|
坐标的第二个元素 |
|
数字字面量,范围取决于 CRS |
||||
|
坐标的第三个元素 |
|
数字字面量,范围取决于 CRS |
||||
|
地理 CRS 中坐标的第一个元素,本初子午线以东的度数 |
|
数字字面量, |
||||
|
地理 CRS 中坐标的第二个元素,赤道以北的度数 |
|
数字字面量, |
||||
|
地理 CRS 中坐标的第三个元素,基准面(WGS-84)定义的椭球体以上的高度(米) |
|
数字字面量,范围仅受底层 64 位浮点类型的限制 |
||||
|
CRS 的名称 |
|
|
||||
|
CRS 的内部 Neo4j ID |
|
|
示例
以下查询显示了如何提取 笛卡尔 2D 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
| x | y | crs | srid |
|---|---|---|---|
|
|
|
|
行:1 |
|||
以下查询显示了如何提取 WGS-84 3D 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
| latitude | longitude | height | x | y | z | crs | srid |
|---|---|---|---|---|---|---|---|
|
|
|
|
|
|
|
|
行:1 |
|||||||
空间值和索引
如果节点或关系属性上存在范围索引或点索引,并且空间点被分配给该属性,则该节点或关系将被索引。
在点索引中,Neo4j 使用基于广义 B+ 树的 2D 或 3D 空间填充曲线。点索引针对距离查询和边界框查询进行了优化。有关详细信息,请参阅 创建索引 → 点索引。
在范围索引中,点将根据每个坐标参考系统的字典顺序进行排序。对于点值,该索引支持相等性检查。有关详细信息,请参阅 创建索引 → 范围索引。
可比较性和可排序性
Cypher 不支持使用不等运算符 <、<=、> 和 >= 来比较空间值。尝试执行此操作将返回 null。
若要比较特定范围内的空间点,请改用空间函数 point.distance 或 point.withinBBox。