# Build geometry from coordinates

Model / geo

A variant of [Work with geography](https://meridian.online/operations/work-with-geography).

Make a point, line or polygon column from X and Y values or from text or binary geometry.

Page: <https://meridian.online/operations/work-with-geography/build-geometry-from-coordinates>

## Status

Runs as a SQL step.

arcform carries it as a `sql:` step today, with the `spatial` extension.

## The DuckDB step

make points, lines and polygons from coordinates, text and binary

```sql
INSTALL spatial; LOAD spatial; SET geometry_always_xy = true;

CREATE TEMP TABLE coords AS SELECT * FROM (VALUES (1, 1, 0.0, 0.0), (1, 2, 4.0, 0.0), (1, 3, 4.0, 3.0), (2, 1, 10.0, 10.0), (2, 2, 11.0, 12.0)) t(feature, seq, x, y);
-- a point for each coordinate pair
CREATE TEMP TABLE points AS SELECT feature, seq, ST_Point(x, y) AS geom FROM coords;
-- a line through each feature's points in order, and a polygon from the ring of feature 1 closed back to its first point
CREATE TEMP TABLE lines AS SELECT feature, ST_MakeLine(list(geom ORDER BY seq)) AS geom FROM points GROUP BY feature;
CREATE TEMP TABLE polygons AS SELECT ST_MakePolygon(ST_MakeLine(list(geom ORDER BY seq) || [first(geom ORDER BY seq)])) AS geom FROM points WHERE feature = 1;
-- from text, and from binary: well-known text, well-known binary as hex, and a round trip through binary
CREATE TEMP TABLE parsed AS SELECT ST_GeomFromText('POINT (1 2)') AS from_text, ST_GeomFromHEXWKB('0101000000000000000000F03F0000000000000040') AS from_hex, ST_GeomFromWKB(ST_AsWKB(ST_GeomFromText('LINESTRING (0 0, 1 1)'))) AS round_trip;
SELECT feature, ST_AsText(geom) AS line FROM lines ORDER BY feature;
SELECT ST_AsText(geom) AS polygon FROM polygons;
SELECT ST_AsText(from_text), ST_AsText(from_hex), ST_AsText(round_trip) FROM parsed;
SELECT CASE WHEN ((SELECT count(*) = 5 FROM points) AND (SELECT ST_AsText(geom) = 'POINT (4 3)' FROM points WHERE feature = 1 AND seq = 3)
  AND (SELECT list(ST_AsText(geom) ORDER BY feature) = ['LINESTRING (0 0, 4 0, 4 3)', 'LINESTRING (10 10, 11 12)'] FROM lines)
  AND (SELECT ST_AsText(geom) = 'POLYGON ((0 0, 4 0, 4 3, 0 0))' AND ST_Area(geom) = 6 FROM polygons)
  AND (SELECT ST_AsText(from_text) = 'POINT (1 2)' AND ST_Equals(from_text, from_hex) AND ST_GeometryType(round_trip) = 'LINESTRING' AND ST_AsText(round_trip) = 'LINESTRING (0 0, 1 1)' FROM parsed)) THEN 'as expected' ELSE error('the coordinates should become 5 points, the lines (0 0, 4 0, 4 3) and (10 10, 11 12), a triangle of area 6, and the same point from text and from hex binary') END AS verdict;
```

The statement builds its own data.

It needs the `spatial` extension.

## What other tools call it

Meridian's classification; an independent blind rating agreed on 95.7% of 324 rows (variant, version 3).

- Alteryx Designer: [`Create Points`](https://help.alteryx.com/current/en/designer/tools/spatial/create-points-tool.html) (read 2026-09-27)
- Alteryx Designer: [`Poly-Build`](https://help.alteryx.com/current/en/designer/tools/spatial/poly-build-tool.html) (read 2026-09-27)
- Duckle: [`Create Geometry`](https://github.com/slothflowlabs/duckle/blob/f85f8960edfb6efbf4cb89d58a7b32e16df0e867/frontend/src/workflow-ui/palette-data.ts) (read 2026-09-25)
- Ibis: [`GeoPoint`](https://github.com/ibis-project/ibis/blob/05d2b293344e86cb41c1a426071734f7e270335a/ibis/expr/operations/geospatial.py) (read 2026-09-27)
