Spatial functions

Spatial functions are used to specify 2D or 3D POINT values in a Coordinate Reference System (CRS) and to calculate the geodesic distance between two POINT values.

Example graph

The following graph is used for some of the examples below.

graph spatial functions

To recreate the graph, run the following query against an empty Neo4j database:

CREATE
  (copenhagen:TrainStation {latitude: 55.672874, longitude: 12.564590, city: 'Copenhagen'}),
  (malmo:Office {latitude: 55.611784, longitude: 12.994341, city: 'Malmö'}),
  (copenhagen)-[:TRAVEL_ROUTE]->(malmo)

point()

Details

Syntax

point(input)

Description

Returns a 2D or 3D point object, given two or respectively three coordinate values in the Cartesian coordinate system or WGS 84 geographic coordinate system.

Arguments

Name

Type

Description

input

MAP

Cartesian 2D: {
x :: FLOAT,
y :: FLOAT,
crs = "cartesian" :: STRING,
srid = 7203 :: INTEGER
}

Cartesian 3D: {
x :: FLOAT,
y :: FLOAT,
z :: FLOAT,
crs = "cartesian-3D" :: STRING,
srid = 9157 :: INTEGER
}

WGS 84 2D: {
longitude | x :: FLOAT
latitude | y :: FLOAT
crs = "WGS-84-2D" :: STRING
srid = 4326 :: INTEGER
}

WGS 84 3D: {
longitude | x :: FLOAT,
latitude | y :: FLOAT,
height | z :: FLOAT,
crs = "WGS-84-3D" :: STRING,
srid = 4979 :: INTEGER
}

Returns

POINT

Considerations

If any argument provided to point() is null, null will be returned.

If the coordinates are specified using latitude and longitude, the crs or srid fields are optional and inferred to be 'WGS-84' (srid:4326) for 2D points or 'WGS-84-3D' (srid:4979) for 3D points.

If the coordinates are specified using x and y, then either the crs or srid field is required if a geographic CRS is desired.

If the height/z key and value is not provided, a 2D POINT will be returned in either the WGS 84 or Cartesian CRS, depending on the coordinate system used.

The crs or srid fields are optional and default to the Cartesian CRS (which means srid:7203) for 2D points or the 3D Cartesian CRS (which means srid:9157) for 3D points.

Example 1. point() - WGS 84 2D
Query
RETURN point({longitude: 56.7, latitude: 12.78}) AS point

A 2D POINT with a longitude of 56.7 and a latitude of 12.78 in the WGS 84 CRS is returned.

Result
point

point({srid:4326, x:56.7, y:12.78})

Rows: 1

Example 2. point() - WGS 84 2D
Query
RETURN point({x: 2.3, y: 4.5, crs: 'WGS-84'}) AS point

x and y coordinates may be used in the WGS 84 CRS instead of longitude and latitude, respectively, providing crs is set to 'WGS-84', or srid is set to 4326.

Result
point

point({srid:4326, x:2.3, y:4.5})

Rows: 1

Example 3. point() - WGS 84 2D
Query
MATCH (p:Office)
RETURN point({longitude: p.longitude, latitude: p.latitude}) AS officePoint

A 2D POINT representing the coordinates of the city of Malmo in the WGS 84 CRS is returned.

Result
officePoint

point({srid:4326, x:12.994341, y:55.611784})

Rows: 1

Example 4. point() - WGS 84 3D
Query
RETURN point({longitude: 56.7, latitude: 12.78, height: 8}) AS point

A 3D POINT with a longitude of 56.7, a latitude of 12.78 and a height of 8 meters in the WGS 84 CRS is returned.

Result
point

point({srid:4979, x:56.7, y:12.78, z:8.0})

Rows: 1

Example 5. point() - Cartesian 2D
Query
RETURN point({x: 2.3, y: 4.5}) AS point

A 2D POINT with an x coordinate of 2.3 and a y coordinate of 4.5 in the Cartesian CRS is returned.

Result
point

point({srid:7203, x:2.3, y:4.5})

Rows: 1

Example 6. point() - Cartesian 3D
Query
RETURN point({x: 2.3, y: 4.5, z: 2}) AS point

A 3D POINT with an x coordinate of 2.3, a y coordinate of 4.5 and a z coordinate of 2 in the Cartesian CRS is returned.

Result
point

point({srid:9157, x:2.3, y:4.5, z:2.0})

Rows: 1

Example 7. point() - null
Query
RETURN point(null) AS p

If null is provided as the argument, null is returned.

Result
p

<null>

Rows: 1

point.distance()

Details

Syntax

point.distance(from, to)

Description

Returns a FLOAT representing the geodesic distance between any two points in the same CRS.

Arguments

Name

Type

Description

from

POINT

A start point.

to

POINT

An end point in the same CRS as the start point.

Returns

FLOAT

  • If the POINT values are in the Cartesian CRS (2D or 3D), then the units of the returned distance will be the same as the units of the points, calculated using Pythagoras' theorem.

  • If the POINT values are in the WGS-84 CRS (2D), then the units of the returned distance will be meters, based on the haversine formula over a spherical Earth approximation.

  • If the POINT values are in the WGS-84 CRS (3D), then the units of the returned distance will be meters.

    • The distance is calculated in two steps.

      • First, a haversine formula over a spherical Earth is used, at the average height of the two points.

      • To account for the difference in height, Pythagoras' theorem is used, combining the previously calculated spherical distance with the height difference.

    • This formula works well for points close to the earth’s surface; for instance, it is well-suited for calculating the distance of an airplane flight. It is less suitable for greater heights, however, such as when calculating the distance between two satellites.

Considerations

point.distance(null, null) return null.

point.distance(null, to) return null.

point.distance(from, null) return null.

Attempting to use points with different Coordinate Reference Systems (such as WGS 84 2D and WGS 84 3D) will return null.

Example 8. point.distance()
Query
WITH
  point({x: 2.3, y: 4.5, crs: 'cartesian'}) AS p1,
  point({x: 1.1, y: 5.4, crs: 'cartesian'}) AS p2
RETURN point.distance(p1,p2) AS dist

The distance between two 2D points in the Cartesian CRS is returned.

Result
dist

1.5

Rows: 1

Example 9. point.distance()
Query
WITH
  point({longitude: 12.78, latitude: 56.7, height: 100}) AS p1,
  point({latitude: 56.71, longitude: 12.79, height: 100}) AS p2
RETURN point.distance(p1, p2) AS dist

The distance between two 3D points in the WGS 84 CRS is returned.

Result
dist

1269.9148706779097

Rows: 1

Example 10. point.distance()
Query
MATCH (t:TrainStation)-[:TRAVEL_ROUTE]->(o:Office)
WITH
  point({longitude: t.longitude, latitude: t.latitude}) AS trainPoint,
  point({longitude: o.longitude, latitude: o.latitude}) AS officePoint
RETURN round(point.distance(trainPoint, officePoint)) AS travelDistance

The distance between the train station in Copenhagen and the Neo4j office in Malmo is returned.

Result
travelDistance

27842.0

Rows: 1

Example 11. point.distance()
Query
RETURN point.distance(null, point({longitude: 56.7, latitude: 12.78})) AS d

If null is provided as one or both of the arguments, null is returned.

Result
d

null

Rows: 1

point.withinBBox()

Details

Syntax

point.withinBBox(point, lowerLeft, upperRight)

Description

Returns true if the provided point is within the bounding box defined by the two provided points.

Arguments

Name

Type

Description

point

POINT

A point to be confirmed in the bounding box.

lowerLeft

POINT

The lower left side point of the bounding box.

upperRight

POINT

The upper right side point of the bounding box.

Returns

BOOLEAN

Considerations

point.withinBBox(point, lowerLeft, upperRight) will return null if any of the arguments evaluate to null.

Attempting to use POINT values with different Coordinate Reference Systems (such as WGS 84 2D and WGS 84 3D) will return null.

point.withinBBox will handle crossing the 180th meridian in geographic coordinates.

Switching the longitude of the lowerLeft and upperRight in geographic coordinates will switch the direction of the resulting bounding box.

Switching the latitude of the lowerLeft and upperRight in geographic coordinates so that the former is north of the latter will result in an empty range.

Example 12. point.withinBBox()
Query
WITH
  point({x: 0, y: 0, crs: 'cartesian'}) AS lowerLeft,
  point({x: 10, y: 10, crs: 'cartesian'}) AS upperRight
RETURN point.withinBBox(point({x: 5, y: 5, crs: 'cartesian'}), lowerLeft, upperRight) AS result

Checking if a point in Cartesian CRS is contained in the bounding box.

Result
result

true

Rows: 1

Example 13. point.withinBBox()
Query
WITH
  point({longitude: 12.53, latitude: 55.66}) AS lowerLeft,
  point({longitude: 12.614, latitude: 55.70}) AS upperRight
MATCH (t:TrainStation)
WHERE point.withinBBox(point({longitude: t.longitude, latitude: t.latitude}), lowerLeft, upperRight)
RETURN count(t)

Finds all train stations contained in a bounding box around Copenhagen.

Result
count(t)

1

Rows: 1

Example 14. point.withinBBox()
Query
WITH
  point({longitude: 179, latitude: 55.66}) AS lowerLeft,
  point({longitude: -179, latitude: 55.70}) AS upperRight
RETURN point.withinBBox(point({longitude: 180, latitude: 55.66}), lowerLeft, upperRight) AS result

A bounding box that crosses the 180th meridian.

Result
result

true

Rows: 1

Example 15. point.withinBBox()
Query
RETURN
  point.withinBBox(
    null,
    point({longitude: 56.7, latitude: 12.78}),
    point({longitude: 57.0, latitude: 13.0})
  ) AS in

If null is provided as any of the arguments, null is returned.

Result
in

null

Rows: 1