Skip to content

Commit 36dcbc2

Browse files
committed
Add support for geography columns
1 parent 321b7f0 commit 36dcbc2

11 files changed

+164
-8
lines changed

martin/src/pg/query_tables.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ SELECT
192192
FROM (
193193
SELECT
194194
ST_AsMVTGeom(
195-
ST_Transform(ST_CurveToLine({geometry_column}), 3857),
195+
ST_Transform(ST_CurveToLine({geometry_column}::geometry), 3857),
196196
ST_TileEnvelope($1::integer, $2::integer, $3::integer),
197197
{extent}, {buffer}, {clip_geom}
198198
) AS geom
@@ -223,11 +223,11 @@ async fn calc_bounds(
223223
.await?
224224
.query_one(&format!(
225225
r#"
226-
WITH real_bounds AS (SELECT ST_SetSRID(ST_Extent({geometry_column}), {srid}) AS rb FROM {schema}.{table})
226+
WITH real_bounds AS (SELECT ST_SetSRID(ST_Extent({geometry_column}::geometry), {srid}) AS rb FROM {schema}.{table})
227227
SELECT ST_Transform(
228228
CASE
229229
WHEN (SELECT ST_GeometryType(rb) FROM real_bounds LIMIT 1) = 'ST_Point'
230-
THEN ST_SetSRID(ST_Extent(ST_Expand({geometry_column}, 1)), {srid})
230+
THEN ST_SetSRID(ST_Extent(ST_Expand({geometry_column}::geometry, 1)), {srid})
231231
ELSE (SELECT * FROM real_bounds)
232232
END,
233233
4326

martin/src/pg/scripts/query_available_tables.sql

+38-5
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ WITH
2828
JOIN pg_opclass op ON
2929
op.oid = ix.indclass[0] AND
3030
op.opcname IN ('gist_geometry_ops_2d', 'spgist_geometry_ops_2d',
31-
'brin_geometry_inclusion_ops_2d')
31+
'brin_geometry_inclusion_ops_2d',
32+
'gist_geography_ops')
3233
GROUP BY 1, 2, 3),
3334
--
3435
annotated_geometry_columns AS (
@@ -38,6 +39,7 @@ WITH
3839
f_geometry_column AS geom,
3940
srid,
4041
type,
42+
-- 'geometry' AS column_type
4143
COALESCE(class.relkind = 'v', false) AS is_view,
4244
bool_or(sic.column_name is not null) as geom_idx
4345
FROM geometry_columns
@@ -50,6 +52,33 @@ WITH
5052
geometry_columns.f_table_name = sic.table_name AND
5153
geometry_columns.f_geometry_column = sic.column_name
5254
GROUP BY 1, 2, 3, 4, 5, 6),
55+
--
56+
annotated_geography_columns AS (
57+
-- list of geography columns with additional metadata
58+
SELECT f_table_schema AS schema,
59+
f_table_name AS name,
60+
f_geography_column AS geom,
61+
srid,
62+
type,
63+
-- 'geography' AS column_type
64+
COALESCE(class.relkind = 'v', false) AS is_view,
65+
bool_or(sic.column_name is not null) as geom_idx
66+
FROM geography_columns
67+
JOIN pg_catalog.pg_class AS class
68+
ON class.relname = geography_columns.f_table_name
69+
JOIN pg_catalog.pg_namespace AS ns
70+
ON ns.nspname = geography_columns.f_table_schema
71+
LEFT JOIN spatially_indexed_columns AS sic ON
72+
geography_columns.f_table_schema = sic.table_schema AND
73+
geography_columns.f_table_name = sic.table_name AND
74+
geography_columns.f_geography_column = sic.column_name
75+
GROUP BY 1, 2, 3, 4, 5, 6),
76+
--
77+
annotated_geo_columns AS (
78+
SELECT * FROM annotated_geometry_columns
79+
UNION SELECT * FROM annotated_geography_columns
80+
),
81+
--
5382
descriptions AS (
5483
-- comments on table/views
5584
SELECT
@@ -69,12 +98,16 @@ SELECT schema,
6998
is_view,
7099
geom_idx,
71100
COALESCE(
72-
jsonb_object_agg(columns.column_name, columns.type_name)
73-
FILTER (WHERE columns.column_name IS NOT NULL AND columns.type_name != 'geometry'),
74-
'{}'::jsonb
101+
jsonb_object_agg(columns.column_name, columns.type_name)
102+
FILTER (
103+
WHERE columns.column_name IS NOT NULL
104+
AND columns.type_name != 'geometry'
105+
AND columns.type_name != 'geography'
106+
),
107+
'{}'::jsonb
75108
) as properties,
76109
dc.description
77-
FROM annotated_geometry_columns AS gc
110+
FROM annotated_geo_columns AS gc
78111
LEFT JOIN columns ON
79112
gc.schema = columns.table_schema AND
80113
gc.name = columns.table_name AND

martin/tests/pg_server_test.rs

+2
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@ postgres:
121121
description: public.points3857.geom
122122
table_source:
123123
content_type: application/x-protobuf
124+
table_source_geog:
125+
content_type: application/x-protobuf
124126
table_source_multiple_geom:
125127
content_type: application/x-protobuf
126128
description: public.table_source_multiple_geom.geom1

martin/tests/pg_table_source_test.rs

+18
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ async fn table_source() {
8282
description: public.points3857.geom
8383
table_source:
8484
content_type: application/x-protobuf
85+
table_source_geog:
86+
content_type: application/x-protobuf
8587
table_source_multiple_geom:
8688
content_type: application/x-protobuf
8789
description: public.table_source_multiple_geom.geom1
@@ -106,6 +108,22 @@ async fn table_source() {
106108
properties:
107109
gid: int4
108110
");
111+
112+
let source2 = table(&mock, "table_source_geog");
113+
assert_yaml_snapshot!(source2, @r"
114+
schema: public
115+
table: table_source_geog
116+
srid: 4326
117+
geometry_column: geog
118+
bounds:
119+
- -2
120+
- 0
121+
- 142.84131509869133
122+
- 45
123+
geometry_type: Geometry
124+
properties:
125+
gid: int4
126+
");
109127
}
110128

111129
#[actix_rt::test]

tests/expected/auto/catalog_auto.json

+3
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,9 @@
156156
"table_source": {
157157
"content_type": "application/x-protobuf"
158158
},
159+
"table_source_geog": {
160+
"content_type": "application/x-protobuf"
161+
},
159162
"table_source_multiple_geom": {
160163
"content_type": "application/x-protobuf",
161164
"description": "public.table_source_multiple_geom.geom1"

tests/expected/auto/save_config.yaml

+13
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,19 @@ postgres:
146146
geometry_type: GEOMETRY
147147
properties:
148148
gid: int4
149+
table_source_geog:
150+
schema: public
151+
table: table_source_geog
152+
srid: 4326
153+
geometry_column: geog
154+
bounds:
155+
- -2.0
156+
- 0.0
157+
- 142.84131509869133
158+
- 45.0
159+
geometry_type: Geometry
160+
properties:
161+
gid: int4
149162
table_source_multiple_geom:
150163
schema: public
151164
table: table_source_multiple_geom

tests/expected/martin-cp/flat-with-hash_save_config.yaml

+13
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,19 @@ postgres:
145145
geometry_type: GEOMETRY
146146
properties:
147147
gid: int4
148+
table_source_geog:
149+
schema: public
150+
table: table_source_geog
151+
srid: 4326
152+
geometry_column: geog
153+
bounds:
154+
- -2.0
155+
- 0.0
156+
- 142.84131509869133
157+
- 45.0
158+
geometry_type: Geometry
159+
properties:
160+
gid: int4
148161
table_source_multiple_geom:
149162
schema: public
150163
table: table_source_multiple_geom

tests/expected/martin-cp/flat_save_config.yaml

+13
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,19 @@ postgres:
145145
geometry_type: GEOMETRY
146146
properties:
147147
gid: int4
148+
table_source_geog:
149+
schema: public
150+
table: table_source_geog
151+
srid: 4326
152+
geometry_column: geog
153+
bounds:
154+
- -2.0
155+
- 0.0
156+
- 142.84131509869133
157+
- 45.0
158+
geometry_type: Geometry
159+
properties:
160+
gid: int4
148161
table_source_multiple_geom:
149162
schema: public
150163
table: table_source_multiple_geom

tests/expected/martin-cp/normalized_save_config.yaml

+13
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,19 @@ postgres:
145145
geometry_type: GEOMETRY
146146
properties:
147147
gid: int4
148+
table_source_geog:
149+
schema: public
150+
table: table_source_geog
151+
srid: 4326
152+
geometry_column: geog
153+
bounds:
154+
- -2.0
155+
- 0.0
156+
- 142.84131509869133
157+
- 45.0
158+
geometry_type: Geometry
159+
properties:
160+
gid: int4
148161
table_source_multiple_geom:
149162
schema: public
150163
table: table_source_multiple_geom
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
DROP TABLE IF EXISTS table_source_geog;
2+
CREATE TABLE table_source_geog(gid serial PRIMARY KEY, geog geography(GEOMETRY, 4326));
3+
4+
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(0 0)'::geography);
5+
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(-2 2)'::geography);
6+
INSERT INTO table_source_geog(geog) values ('SRID=4326;LINESTRING(0 0, 1 1)'::geography);
7+
INSERT INTO table_source_geog(geog) values ('SRID=4326;LINESTRING(2 2, 3 3)'::geography);
8+
9+
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(30 10)'::geography);
10+
INSERT INTO table_source_geog(geog) values ('SRID=4326;LINESTRING(30 10, 10 30, 40 40)'::geography);
11+
INSERT INTO table_source_geog(geog) values ('SRID=4326;POLYGON((30 10, 40 40, 20 40, 10 20, 30 10))'::geography);
12+
INSERT INTO table_source_geog(geog) values ('SRID=4326;POLYGON((35 10, 45 45, 15 40, 10 20, 35 10),(20 30, 35 35, 30 20, 20 30))'::geography);
13+
INSERT INTO table_source_geog(geog) values ('SRID=4326;MULTIPOINT((10 40), (40 30), (20 20), (30 10))'::geography);
14+
INSERT INTO table_source_geog(geog) values ('SRID=4326;MULTIPOINT(10 40, 40 30, 20 20, 30 10)'::geography);
15+
INSERT INTO table_source_geog(geog) values ('SRID=4326;MULTILINESTRING((10 10, 20 20, 10 40),(40 40, 30 30, 40 20, 30 10))'::geography);
16+
INSERT INTO table_source_geog(geog) values ('SRID=4326;MULTIPOLYGON(((30 20, 45 40, 10 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))'::geography);
17+
INSERT INTO table_source_geog(geog) values ('SRID=4326;MULTIPOLYGON(((40 40, 20 45, 45 30, 40 40)),((20 35, 10 30, 10 10, 30 5, 45 20, 20 35),(30 20, 20 15, 20 25, 30 20)))'::geography);
18+
INSERT INTO table_source_geog(geog) values ('SRID=4326;GEOMETRYCOLLECTION(POINT(4 6),LINESTRING(4 6,7 10))'::geography);
19+
20+
-- Curves are not supported in geography columns
21+
-- INSERT INTO table_source_geog(geog) values ('SRID=4326;CIRCULARSTRING(1 5, 6 2, 7 3)'::geography);
22+
-- INSERT INTO table_source_geog(geog) values ('SRID=4326;COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,1 0),(1 0,0 1))'::geography);
23+
-- INSERT INTO table_source_geog(geog) values ('SRID=4326;CURVEPOLYGON(CIRCULARSTRING(-2 0,-1 -1,0 0,1 -1,2 0,0 2,-2 0),(-1 0,0 0.5,1 0,0 1,-1 0))'::geography);
24+
-- INSERT INTO table_source_geog(geog) values ('SRID=4326;MULTICURVE((5 5,3 5,3 3,0 3),CIRCULARSTRING(0 0,2 1,2 2))'::geography);
25+
26+
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(142.84124343269863 11.927545216212339)'::geography);
27+
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(142.84022627741408 11.926919775099435)'::geography);
28+
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(142.84116724279622 11.926986082398354)'::geography);
29+
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(142.84129834730146 11.926483025982757)'::geography);
30+
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(142.84086326293937 11.92741281580712)'::geography);
31+
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(142.84083973422645 11.927188724740008)'::geography);
32+
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(142.8407405154705 11.92659842381238)'::geography);
33+
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(142.84029057105903 11.92711170365923)'::geography);
34+
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(142.8403402985401 11.927568375227375)'::geography);
35+
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(142.84131509869133 11.92781306544329)'::geography);
36+
37+
-- DO NOT CREATE INDEX ON GEOGRAPHY COLUMN -- this table is used in a test case
38+
39+
DO $do$ BEGIN
40+
EXECUTE 'COMMENT ON TABLE table_source_geog IS $tj$' || $$
41+
{
42+
"description": null,
43+
"foo": {"bar": "foo"}
44+
}
45+
$$::json || '$tj$';
46+
END $do$;

tests/test.sh

+2
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ test_jsn fnc_comment function_Mixed_Name
291291
kill_process "$MARTIN_PROC_ID" Martin
292292

293293
test_log_has_str "$LOG_FILE" 'WARN martin::pg::query_tables] Table public.table_source has no spatial index on column geom'
294+
test_log_has_str "$LOG_FILE" 'WARN martin::pg::query_tables] Table public.table_source_geog has no spatial index on column geog'
294295
test_log_has_str "$LOG_FILE" 'WARN martin::fonts] Ignoring duplicate font Overpass Mono Regular from tests'
295296
validate_log "$LOG_FILE"
296297
remove_line "${TEST_OUT_DIR}/save_config.yaml" " connection_string: "
@@ -387,6 +388,7 @@ test_jsn fnc_comment_cfg fnc_Mixed_Name
387388

388389
kill_process "$MARTIN_PROC_ID" Martin
389390
test_log_has_str "$LOG_FILE" 'WARN martin::pg::query_tables] Table public.table_source has no spatial index on column geom'
391+
test_log_has_str "$LOG_FILE" 'WARN martin::pg::query_tables] Table public.table_source_geog has no spatial index on column geog'
390392
test_log_has_str "$LOG_FILE" 'WARN martin::fonts] Ignoring duplicate font Overpass Mono Regular from tests'
391393
validate_log "$LOG_FILE"
392394
remove_line "${TEST_OUT_DIR}/save_config.yaml" " connection_string: "

0 commit comments

Comments
 (0)