Geometry classes provide support for spatial and geographic data using GeoJSON-compatible structures. These types are essential for location-based applications and geospatial queries.
Import:
import { GeometryPoint, GeometryLine, GeometryPolygon, GeometryMultiPoint, GeometryMultiLine, GeometryMultiPolygon, GeometryCollection } from 'surrealdb';
Source: value/geometry.ts
GeometryPointA single point in 2D space (longitude, latitude).
new GeometryPoint([longitude, latitude]) new GeometryPoint(point) // Clone existing
// Create a point (San Francisco) const point = new GeometryPoint([-122.4194, 37.7749]); // Store location await db.create(new Table('locations')).content({ name: 'Office', position: point });
GeometryLineA line defined by two or more points.
new GeometryLine([point1, point2, ...points]) new GeometryLine(line) // Clone existing
// Create a line (path between two cities) const line = new GeometryLine([ new GeometryPoint([-122.4194, 37.7749]), // San Francisco new GeometryPoint([-118.2437, 34.0522]) // Los Angeles ]); // Multi-segment line const route = new GeometryLine([ new GeometryPoint([0, 0]), new GeometryPoint([1, 1]), new GeometryPoint([2, 1]), new GeometryPoint([3, 2]) ]);
GeometryPolygonA polygon defined by one or more lines (outer boundary and optional holes).
new GeometryPolygon([outerBoundary, ...holes]) new GeometryPolygon(polygon) // Clone existing
// Create a triangle const triangle = new GeometryPolygon([ new GeometryLine([ new GeometryPoint([0, 0]), new GeometryPoint([4, 0]), new GeometryPoint([2, 3]), new GeometryPoint([0, 0]) // Close the polygon ]) ]); // Polygon with hole (donut shape) const donut = new GeometryPolygon([ // Outer boundary new GeometryLine([ new GeometryPoint([0, 0]), new GeometryPoint([10, 0]), new GeometryPoint([10, 10]), new GeometryPoint([0, 10]), new GeometryPoint([0, 0]) ]), // Inner hole new GeometryLine([ new GeometryPoint([2, 2]), new GeometryPoint([8, 2]), new GeometryPoint([8, 8]), new GeometryPoint([2, 8]), new GeometryPoint([2, 2]) ]) ]);
GeometryMultiPointA collection of points.
new GeometryMultiPoint([point1, point2, ...points]) new GeometryMultiPoint(multiPoint) // Clone existing
// Multiple store locations const stores = new GeometryMultiPoint([ new GeometryPoint([-122.4194, 37.7749]), // SF new GeometryPoint([-118.2437, 34.0522]), // LA new GeometryPoint([-87.6298, 41.8781]) // Chicago ]);
GeometryMultiLineA collection of lines.
new GeometryMultiLine([line1, line2, ...lines]) new GeometryMultiLine(multiLine) // Clone existing
// Multiple delivery routes const routes = new GeometryMultiLine([ new GeometryLine([ new GeometryPoint([0, 0]), new GeometryPoint([1, 1]) ]), new GeometryLine([ new GeometryPoint([2, 2]), new GeometryPoint([3, 3]) ]) ]);
GeometryMultiPolygonA collection of polygons.
new GeometryMultiPolygon([polygon1, polygon2, ...polygons]) new GeometryMultiPolygon(multiPolygon) // Clone existing
// Multiple service areas const areas = new GeometryMultiPolygon([ new GeometryPolygon([/* first area */]), new GeometryPolygon([/* second area */]) ]);
GeometryCollectionA heterogeneous collection of geometry types.
new GeometryCollection([geometry1, geometry2, ...geometries]) new GeometryCollection(collection) // Clone existing
// Mixed geometry types const collection = new GeometryCollection([ new GeometryPoint([0, 0]), new GeometryLine([ new GeometryPoint([1, 1]), new GeometryPoint([2, 2]) ]), new GeometryPolygon([/* polygon data */]) ]);
All geometry types share these methods:
.toJSON()Convert to GeoJSON format.
const point = new GeometryPoint([-122.4194, 37.7749]); console.log(point.toJSON()); // { type: "Point", coordinates: [-122.4194, 37.7749] }
.toString()Convert to JSON string.
const point = new GeometryPoint([-122.4194, 37.7749]); console.log(point.toString()); // '{"type":"Point","coordinates":[-122.4194,37.7749]}'
.clone()Create a deep copy.
const original = new GeometryPoint([0, 0]); const copy = original.clone();
.equals(other)Check if two geometries are equal.
const a = new GeometryPoint([0, 0]); const b = new GeometryPoint([0, 0]); console.log(a.equals(b)); // true
import { Surreal, GeometryPoint, Table } from 'surrealdb'; const db = new Surreal(); await db.connect('ws://localhost:8000'); // Store locations with coordinates const locations = [ { name: 'Main Office', address: '123 Market St, San Francisco, CA', position: new GeometryPoint([-122.4194, 37.7749]) }, { name: 'LA Branch', address: '456 Sunset Blvd, Los Angeles, CA', position: new GeometryPoint([-118.2437, 34.0522]) } ]; for (const location of locations) { await db.create(new Table('locations')).content(location); }
// Define delivery route const route = new GeometryLine([ new GeometryPoint([-122.4194, 37.7749]), // Start: SF new GeometryPoint([-122.2711, 37.8044]), // Stop 1: Oakland new GeometryPoint([-122.0838, 37.3861]), // Stop 2: Mountain View new GeometryPoint([-121.8863, 37.3382]) // End: San Jose ]); await db.create(new Table('routes')).content({ driver: new RecordId('drivers', 'john'), route: route, estimated_time: Duration.parse('2h30m'), created_at: DateTime.now() });
// Define service coverage area (polygon) const serviceArea = new GeometryPolygon([ new GeometryLine([ new GeometryPoint([-122.5, 37.7]), new GeometryPoint([-122.3, 37.7]), new GeometryPoint([-122.3, 37.8]), new GeometryPoint([-122.5, 37.8]), new GeometryPoint([-122.5, 37.7]) // Close the polygon ]) ]); await db.create(new Table('service_areas')).content({ name: 'SF Downtown', area: serviceArea, active: true });
// Find locations near a point const centerPoint = new GeometryPoint([-122.4194, 37.7749]); const nearbyLocations = await db.query(` SELECT * FROM locations WHERE geo::distance(position, $center) < 5000 ORDER BY geo::distance(position, $center) `, { center: centerPoint }).collect(); console.log('Nearby locations:', nearbyLocations);
// Check if a point is within a polygon const region = new GeometryPolygon([ new GeometryLine([ new GeometryPoint([0, 0]), new GeometryPoint([10, 0]), new GeometryPoint([10, 10]), new GeometryPoint([0, 10]), new GeometryPoint([0, 0]) ]) ]); const testPoint = new GeometryPoint([5, 5]); const result = await db.query(` RETURN geo::area::contains($region, $point) `, { region, point: testPoint }).collect(); console.log('Point is inside:', result[0]);
// Store multiple branch locations const branches = new GeometryMultiPoint([ new GeometryPoint([-122.4194, 37.7749]), // SF new GeometryPoint([-118.2437, 34.0522]), // LA new GeometryPoint([-87.6298, 41.8781]), // Chicago new GeometryPoint([-74.0060, 40.7128]) // NYC ]); await db.create(new Table('companies')).content({ name: 'Tech Corp', headquarters: new GeometryPoint([-122.4194, 37.7749]), all_branches: branches, founded: DateTime.parse('2020-01-01') });
// Calculate distance between two points const pointA = new GeometryPoint([-122.4194, 37.7749]); // SF const pointB = new GeometryPoint([-118.2437, 34.0522]); // LA const distance = await db.query(` RETURN geo::distance($a, $b) `, { a: pointA, b: pointB }).collect(); console.log('Distance in meters:', distance[0]);
// Export as GeoJSON for mapping libraries const point = new GeometryPoint([-122.4194, 37.7749]); const geoJson = point.toJSON(); // Use with mapping libraries (Leaflet, Mapbox, etc.) /* { type: "Point", coordinates: [-122.4194, 37.7749] } */
// Define a park with a lake (hole) const park = new GeometryPolygon([ // Outer boundary (park border) new GeometryLine([ new GeometryPoint([0, 0]), new GeometryPoint([100, 0]), new GeometryPoint([100, 100]), new GeometryPoint([0, 100]), new GeometryPoint([0, 0]) ]), // Inner hole (lake) new GeometryLine([ new GeometryPoint([40, 40]), new GeometryPoint([60, 40]), new GeometryPoint([60, 60]), new GeometryPoint([40, 60]), new GeometryPoint([40, 40]) ]) ]); await db.create(new Table('parks')).content({ name: 'Central Park', boundary: park, has_lake: true });
All geometry types are compatible with GeoJSON format:
const point = new GeometryPoint([-122.4194, 37.7749]); const geoJson = point.toJSON(); // GeoJSON structure console.log(geoJson); /* { type: "Point", coordinates: [-122.4194, 37.7749] } */ // Use with any GeoJSON-compatible library
// Good: [longitude, latitude] (GeoJSON standard) const point = new GeometryPoint([-122.4194, 37.7749]); // Avoid: [latitude, longitude] (Google Maps format) const wrong = new GeometryPoint([37.7749, -122.4194]);
// Good: First and last points are the same const polygon = new GeometryPolygon([ new GeometryLine([ new GeometryPoint([0, 0]), new GeometryPoint([10, 0]), new GeometryPoint([10, 10]), new GeometryPoint([0, 10]), new GeometryPoint([0, 0]) // Closes the polygon ]) ]); // The library automatically closes polygons if needed
// Good: Single location const office = new GeometryPoint([-122.4194, 37.7749]); // Good: Multiple locations const branches = new GeometryMultiPoint([point1, point2, point3]); // Avoid: Using MultiPoint for single location const wrong = new GeometryMultiPoint([point1]);
// Good: Valid coordinates const valid = new GeometryPoint([-122.4194, 37.7749]); // Avoid: Invalid coordinates (out of range) // Longitude: -180 to 180, Latitude: -90 to 90 const invalid = new GeometryPoint([200, 100]); // Will create but may cause issues