PostGIS support for PostGraphile v5.
Automatically generates GraphQL types for PostGIS geometry and geography columns, including GeoJSON scalar types, dimension-aware interfaces, and subtype-specific fields (coordinates, points, rings, etc.).
npm install graphile-postgisimport { GraphilePostgisPreset } from 'graphile-postgis';
const preset = {
extends: [GraphilePostgisPreset]
};- GeoJSON scalar type for input/output
- GraphQL interfaces for geometry and geography base types
- Dimension-aware interfaces (XY, XYZ, XYM, XYZM)
- Concrete types for all geometry subtypes: Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection
- Subtype-specific fields (x/y/z for Points, points for LineStrings, exterior/interiors for Polygons, etc.)
- Geography-aware field naming (longitude/latitude/height instead of x/y/z)
- Cross-table spatial filters via
@spatialRelationsmart tags (see below) - Graceful degradation when PostGIS is not installed
PostgisSpatialRelationsPlugin lets you declare a cross-table or
self-relation whose join predicate is a PostGIS spatial function. The
plugin emits a first-class relation + filter field on the owning codec's
Filter type that compiles to an EXISTS (…) subquery using the
declared operator.
COMMENT ON COLUMN <owner_table>.<owner_col> IS
E'@spatialRelation <relation_name> <target_table>.<target_col> <operator> [<param_name>]';<relation_name>— user-chosen name for the generated field (e.g.county)<target_table>.<target_col>— target geometry/geography column; also accepts<schema>.<table>.<col><operator>— PG-nativest_*function name; resolved at schema build time againstpg_proc<param_name>— required only for parametric operators (currentlyst_dwithin)
| Operator | PostGIS function | Kind | Arity |
|---|---|---|---|
st_contains |
ST_Contains |
function | 2 |
st_within |
ST_Within |
function | 2 |
st_covers |
ST_Covers |
function | 2 |
st_coveredby |
ST_CoveredBy |
function | 2 |
st_intersects |
ST_Intersects |
function | 2 |
st_equals |
ST_Equals |
function | 2 |
st_bbox_intersects |
&& |
infix | 2 |
st_dwithin |
ST_DWithin |
function | 3 (parametric) |
2-arg operators use the familiar some / every / none shape:
telemedicineClinics(
filter: { county: { some: { name: { eq: "California County" } } } }
) { nodes { id name } }st_dwithin takes its distance at the relation level (it parametrises
the join, not the joined row):
telemedicineClinics(
filter: {
nearbyClinic: {
distance: 5000
some: { specialty: { eq: "pediatrics" } }
}
}
) { nodes { id name } }Distance units follow PostGIS semantics: meters for geography
columns, SRID coordinate units for geometry columns.
When <owner_table> equals <target_table>, the plugin emits an
automatic self-exclusion predicate so a row is never "related to
itself":
- Single-column PK:
other.id <> self.id - Composite PK:
(other.a, other.b) IS DISTINCT FROM (self.a, self.b)
Self-relations on tables without a primary key are rejected at schema build time.
At schema build time the plugin emits a non-fatal warning when the target geometry/geography column has no GIST index — spatial predicates are typically unusable without one.
MIT