SurrealDB stores geospatial data in the geometry type, which follows GeoJSON. The Python SDK has one class for each of the seven kinds of geometry, and each class maps to its SurrealDB kind in both directions. This page documents the constructors, which take their parts as separate arguments, and how geometry reads back.
from surrealdb import (
GeometryCollection,
GeometryLine,
GeometryMultiLine,
GeometryMultiPoint,
GeometryMultiPolygon,
GeometryPoint,
GeometryPolygon,
)Source: geometry.py
Classes
| Class | SurrealDB type | Constructor |
|---|---|---|
GeometryPoint | geometry<point> | GeometryPoint(longitude, latitude) |
GeometryLine | geometry<line> | GeometryLine(point1, point2, *more_points) |
GeometryPolygon | geometry<polygon> | GeometryPolygon(exterior_ring, *interior_rings) |
GeometryMultiPoint | geometry<multipoint> | GeometryMultiPoint(*points) |
GeometryMultiLine | geometry<multiline> | GeometryMultiLine(*lines) |
GeometryMultiPolygon | geometry<multipolygon> | GeometryMultiPolygon(*polygons) |
GeometryCollection | geometry<collection> | GeometryCollection(*geometries) |
Every constructor takes its parts as separate positional arguments. GeometryLine(start, end) is correct, and GeometryLine([start, end]) raises TypeError. To build a geometry from a list, unpack the list: GeometryLine(*points).
A point gives its longitude first and its latitude second, the same order as GeoJSON.
The Geometry base class is also exported. Use it in an isinstance() check for the first six classes. GeometryCollection is not a subclass of Geometry, and a Geometry itself cannot be sent.
GeometryPoint
A GeometryPoint is a single position.
GeometryPoint(longitude, latitude)Parameter | Type | Description |
|---|---|---|
longitude | float | The longitude, or the x coordinate. |
latitude | float | The latitude, or the y coordinate. |
The point keeps the two values as its longitude and latitude attributes.
london = GeometryPoint(-0.1278, 51.5074)
print(london.longitude, london.latitude)-0.1278 51.5074 GeometryLine
A GeometryLine is a line through two or more points, in order.
GeometryLine(point1, point2, *more_points)Parameter | Type | Description |
|---|---|---|
point1, point2 | GeometryPoint | The first two points of the line. |
*more_points | GeometryPoint | Further points, in order. |
The points are in the geometry_points attribute, a list[GeometryPoint].
route = GeometryLine(
GeometryPoint(-0.1278, 51.5074),
GeometryPoint(-1.8904, 52.4862),
GeometryPoint(-3.1883, 55.9533),
)
print(len(route.geometry_points))3 GeometryPolygon
A GeometryPolygon is a polygon made of one outer ring and any number of inner rings, which are holes. A ring is a GeometryLine that is closed: its first and last points are equal, and it has at least four points.
GeometryPolygon(exterior_ring, *interior_rings)Parameter | Type | Description |
|---|---|---|
exterior_ring | GeometryLine | The outer boundary. |
*interior_rings | GeometryLine | Holes inside the outer boundary. |
The rings are in the geometry_lines attribute, outer ring first. A ring that is not closed, or that has fewer than four points, raises InvalidGeometryError.
outer = GeometryLine(
GeometryPoint(0, 0),
GeometryPoint(4, 0),
GeometryPoint(4, 4),
GeometryPoint(0, 4),
GeometryPoint(0, 0),
)
hole = GeometryLine(
GeometryPoint(1, 1),
GeometryPoint(2, 1),
GeometryPoint(2, 2),
GeometryPoint(1, 2),
GeometryPoint(1, 1),
)
area = GeometryPolygon(outer, hole)
print(len(area.geometry_lines))2 GeometryMultiPoint
A GeometryMultiPoint is a group of points.
GeometryMultiPoint(*points)The points are in the geometry_points attribute.
stops = GeometryMultiPoint(
GeometryPoint(-0.1278, 51.5074),
GeometryPoint(-3.1883, 55.9533),
)
print(len(stops.geometry_points))2 GeometryMultiLine
A GeometryMultiLine is a group of lines.
GeometryMultiLine(*lines)The lines are in the geometry_lines attribute.
tracks = GeometryMultiLine(
GeometryLine(GeometryPoint(0, 0), GeometryPoint(1, 1)),
GeometryLine(GeometryPoint(2, 2), GeometryPoint(3, 3)),
)
print(len(tracks.geometry_lines))2 GeometryMultiPolygon
A GeometryMultiPolygon is a group of polygons.
GeometryMultiPolygon(*polygons)The polygons are in the geometry_polygons attribute.
square = GeometryLine(
GeometryPoint(0, 0),
GeometryPoint(1, 0),
GeometryPoint(1, 1),
GeometryPoint(0, 1),
GeometryPoint(0, 0),
)
farms = GeometryMultiPolygon(GeometryPolygon(square))
print(len(farms.geometry_polygons))1 GeometryCollection
A GeometryCollection is a group of geometries of any kind, mixed.
GeometryCollection(*geometries)The geometries are in the geometries attribute.
site = GeometryCollection(
GeometryPoint(-0.1278, 51.5074),
GeometryLine(GeometryPoint(0, 0), GeometryPoint(1, 1)),
)
print(len(site.geometries))2Common methods
str() renders a geometry as a SurrealQL literal, for logs and debugging. To use a geometry in a query, pass it as a variable instead.
print(GeometryPoint(-0.1278, 51.5074))
print(GeometryLine(GeometryPoint(0, 0), GeometryPoint(1, 1)))(-0.1278, 51.5074)
{ type: 'LineString', coordinates: [[0, 0], [1, 1]] }Every class except GeometryCollection also has these methods:
| Method | Returns | Description |
|---|---|---|
get_coordinates() | tuple or list | The GeoJSON coordinates, with each position as a (longitude, latitude) tuple. |
parse_coordinates(coordinates) | the same class | Static method. Builds a geometry from GeoJSON coordinates. |
Two geometries of the same class are equal when their coordinates are equal, and every geometry is hashable.
Usage
Store a geometry as a field value, and pass one as a query variable to use it with the geo functions.
from surrealdb import GeometryPoint, RecordID, Surreal
with Surreal("ws://localhost:8000") as db:
db.signin({"username": "root", "password": "secret"})
db.use("surrealdb", "docs")
db.create(RecordID("place", "london"), {
"location": GeometryPoint(-0.1278, 51.5074),
})
db.create(RecordID("place", "edinburgh"), {
"location": GeometryPoint(-3.1883, 55.9533),
})
sql = """
SELECT VALUE id FROM place
WHERE geo::distance(location, $here) < 50000
"""
here = GeometryPoint(-0.1180, 51.5099)
print(db.query(sql, {"here": here}).first())[RecordID(table_name=place, record_id='london')]A geometry reads back as the same class. The coordinates of a point read back as float values, so GeometryPoint(1, 2) reads back as GeometryPoint(longitude=1.0, latitude=2.0), which is still equal to the point that was sent.
See also
Python values for every value class
Geometries in SurrealQL
Geo functions for distance, area and other calculations