Skip to content

Commit

Permalink
Add support for geography columns
Browse files Browse the repository at this point in the history
  • Loading branch information
rshk committed Dec 20, 2024
1 parent 321b7f0 commit 36dcbc2
Show file tree
Hide file tree
Showing 11 changed files with 164 additions and 8 deletions.
6 changes: 3 additions & 3 deletions martin/src/pg/query_tables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ SELECT
FROM (
SELECT
ST_AsMVTGeom(
ST_Transform(ST_CurveToLine({geometry_column}), 3857),
ST_Transform(ST_CurveToLine({geometry_column}::geometry), 3857),
ST_TileEnvelope($1::integer, $2::integer, $3::integer),
{extent}, {buffer}, {clip_geom}
) AS geom
Expand Down Expand Up @@ -223,11 +223,11 @@ async fn calc_bounds(
.await?
.query_one(&format!(
r#"
WITH real_bounds AS (SELECT ST_SetSRID(ST_Extent({geometry_column}), {srid}) AS rb FROM {schema}.{table})
WITH real_bounds AS (SELECT ST_SetSRID(ST_Extent({geometry_column}::geometry), {srid}) AS rb FROM {schema}.{table})
SELECT ST_Transform(
CASE
WHEN (SELECT ST_GeometryType(rb) FROM real_bounds LIMIT 1) = 'ST_Point'
THEN ST_SetSRID(ST_Extent(ST_Expand({geometry_column}, 1)), {srid})
THEN ST_SetSRID(ST_Extent(ST_Expand({geometry_column}::geometry, 1)), {srid})
ELSE (SELECT * FROM real_bounds)
END,
4326
Expand Down
43 changes: 38 additions & 5 deletions martin/src/pg/scripts/query_available_tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ WITH
JOIN pg_opclass op ON
op.oid = ix.indclass[0] AND
op.opcname IN ('gist_geometry_ops_2d', 'spgist_geometry_ops_2d',
'brin_geometry_inclusion_ops_2d')
'brin_geometry_inclusion_ops_2d',
'gist_geography_ops')
GROUP BY 1, 2, 3),
--
annotated_geometry_columns AS (
Expand All @@ -38,6 +39,7 @@ WITH
f_geometry_column AS geom,
srid,
type,
-- 'geometry' AS column_type
COALESCE(class.relkind = 'v', false) AS is_view,
bool_or(sic.column_name is not null) as geom_idx
FROM geometry_columns
Expand All @@ -50,6 +52,33 @@ WITH
geometry_columns.f_table_name = sic.table_name AND
geometry_columns.f_geometry_column = sic.column_name
GROUP BY 1, 2, 3, 4, 5, 6),
--
annotated_geography_columns AS (
-- list of geography columns with additional metadata
SELECT f_table_schema AS schema,
f_table_name AS name,
f_geography_column AS geom,
srid,
type,
-- 'geography' AS column_type
COALESCE(class.relkind = 'v', false) AS is_view,
bool_or(sic.column_name is not null) as geom_idx
FROM geography_columns
JOIN pg_catalog.pg_class AS class
ON class.relname = geography_columns.f_table_name
JOIN pg_catalog.pg_namespace AS ns
ON ns.nspname = geography_columns.f_table_schema
LEFT JOIN spatially_indexed_columns AS sic ON
geography_columns.f_table_schema = sic.table_schema AND
geography_columns.f_table_name = sic.table_name AND
geography_columns.f_geography_column = sic.column_name
GROUP BY 1, 2, 3, 4, 5, 6),
--
annotated_geo_columns AS (
SELECT * FROM annotated_geometry_columns
UNION SELECT * FROM annotated_geography_columns
),
--
descriptions AS (
-- comments on table/views
SELECT
Expand All @@ -69,12 +98,16 @@ SELECT schema,
is_view,
geom_idx,
COALESCE(
jsonb_object_agg(columns.column_name, columns.type_name)
FILTER (WHERE columns.column_name IS NOT NULL AND columns.type_name != 'geometry'),
'{}'::jsonb
jsonb_object_agg(columns.column_name, columns.type_name)
FILTER (
WHERE columns.column_name IS NOT NULL
AND columns.type_name != 'geometry'
AND columns.type_name != 'geography'
),
'{}'::jsonb
) as properties,
dc.description
FROM annotated_geometry_columns AS gc
FROM annotated_geo_columns AS gc
LEFT JOIN columns ON
gc.schema = columns.table_schema AND
gc.name = columns.table_name AND
Expand Down
2 changes: 2 additions & 0 deletions martin/tests/pg_server_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ postgres:
description: public.points3857.geom
table_source:
content_type: application/x-protobuf
table_source_geog:
content_type: application/x-protobuf
table_source_multiple_geom:
content_type: application/x-protobuf
description: public.table_source_multiple_geom.geom1
Expand Down
18 changes: 18 additions & 0 deletions martin/tests/pg_table_source_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ async fn table_source() {
description: public.points3857.geom
table_source:
content_type: application/x-protobuf
table_source_geog:
content_type: application/x-protobuf
table_source_multiple_geom:
content_type: application/x-protobuf
description: public.table_source_multiple_geom.geom1
Expand All @@ -106,6 +108,22 @@ async fn table_source() {
properties:
gid: int4
");

let source2 = table(&mock, "table_source_geog");
assert_yaml_snapshot!(source2, @r"
schema: public
table: table_source_geog
srid: 4326
geometry_column: geog
bounds:
- -2
- 0
- 142.84131509869133
- 45
geometry_type: Geometry
properties:
gid: int4
");
}

#[actix_rt::test]
Expand Down
3 changes: 3 additions & 0 deletions tests/expected/auto/catalog_auto.json
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@
"table_source": {
"content_type": "application/x-protobuf"
},
"table_source_geog": {
"content_type": "application/x-protobuf"
},
"table_source_multiple_geom": {
"content_type": "application/x-protobuf",
"description": "public.table_source_multiple_geom.geom1"
Expand Down
13 changes: 13 additions & 0 deletions tests/expected/auto/save_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,19 @@ postgres:
geometry_type: GEOMETRY
properties:
gid: int4
table_source_geog:
schema: public
table: table_source_geog
srid: 4326
geometry_column: geog
bounds:
- -2.0
- 0.0
- 142.84131509869133
- 45.0
geometry_type: Geometry
properties:
gid: int4
table_source_multiple_geom:
schema: public
table: table_source_multiple_geom
Expand Down
13 changes: 13 additions & 0 deletions tests/expected/martin-cp/flat-with-hash_save_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,19 @@ postgres:
geometry_type: GEOMETRY
properties:
gid: int4
table_source_geog:
schema: public
table: table_source_geog
srid: 4326
geometry_column: geog
bounds:
- -2.0
- 0.0
- 142.84131509869133
- 45.0
geometry_type: Geometry
properties:
gid: int4
table_source_multiple_geom:
schema: public
table: table_source_multiple_geom
Expand Down
13 changes: 13 additions & 0 deletions tests/expected/martin-cp/flat_save_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,19 @@ postgres:
geometry_type: GEOMETRY
properties:
gid: int4
table_source_geog:
schema: public
table: table_source_geog
srid: 4326
geometry_column: geog
bounds:
- -2.0
- 0.0
- 142.84131509869133
- 45.0
geometry_type: Geometry
properties:
gid: int4
table_source_multiple_geom:
schema: public
table: table_source_multiple_geom
Expand Down
13 changes: 13 additions & 0 deletions tests/expected/martin-cp/normalized_save_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,19 @@ postgres:
geometry_type: GEOMETRY
properties:
gid: int4
table_source_geog:
schema: public
table: table_source_geog
srid: 4326
geometry_column: geog
bounds:
- -2.0
- 0.0
- 142.84131509869133
- 45.0
geometry_type: Geometry
properties:
gid: int4
table_source_multiple_geom:
schema: public
table: table_source_multiple_geom
Expand Down
46 changes: 46 additions & 0 deletions tests/fixtures/tables/table_source_geog.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
DROP TABLE IF EXISTS table_source_geog;
CREATE TABLE table_source_geog(gid serial PRIMARY KEY, geog geography(GEOMETRY, 4326));

INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(0 0)'::geography);
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(-2 2)'::geography);
INSERT INTO table_source_geog(geog) values ('SRID=4326;LINESTRING(0 0, 1 1)'::geography);
INSERT INTO table_source_geog(geog) values ('SRID=4326;LINESTRING(2 2, 3 3)'::geography);

INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(30 10)'::geography);
INSERT INTO table_source_geog(geog) values ('SRID=4326;LINESTRING(30 10, 10 30, 40 40)'::geography);
INSERT INTO table_source_geog(geog) values ('SRID=4326;POLYGON((30 10, 40 40, 20 40, 10 20, 30 10))'::geography);
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);
INSERT INTO table_source_geog(geog) values ('SRID=4326;MULTIPOINT((10 40), (40 30), (20 20), (30 10))'::geography);
INSERT INTO table_source_geog(geog) values ('SRID=4326;MULTIPOINT(10 40, 40 30, 20 20, 30 10)'::geography);
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);
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);
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);
INSERT INTO table_source_geog(geog) values ('SRID=4326;GEOMETRYCOLLECTION(POINT(4 6),LINESTRING(4 6,7 10))'::geography);

-- Curves are not supported in geography columns
-- INSERT INTO table_source_geog(geog) values ('SRID=4326;CIRCULARSTRING(1 5, 6 2, 7 3)'::geography);
-- INSERT INTO table_source_geog(geog) values ('SRID=4326;COMPOUNDCURVE(CIRCULARSTRING(0 0,1 1,1 0),(1 0,0 1))'::geography);
-- 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);
-- 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);

INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(142.84124343269863 11.927545216212339)'::geography);
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(142.84022627741408 11.926919775099435)'::geography);
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(142.84116724279622 11.926986082398354)'::geography);
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(142.84129834730146 11.926483025982757)'::geography);
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(142.84086326293937 11.92741281580712)'::geography);
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(142.84083973422645 11.927188724740008)'::geography);
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(142.8407405154705 11.92659842381238)'::geography);
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(142.84029057105903 11.92711170365923)'::geography);
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(142.8403402985401 11.927568375227375)'::geography);
INSERT INTO table_source_geog(geog) values ('SRID=4326;POINT(142.84131509869133 11.92781306544329)'::geography);

-- DO NOT CREATE INDEX ON GEOGRAPHY COLUMN -- this table is used in a test case

DO $do$ BEGIN
EXECUTE 'COMMENT ON TABLE table_source_geog IS $tj$' || $$
{
"description": null,
"foo": {"bar": "foo"}
}
$$::json || '$tj$';
END $do$;
2 changes: 2 additions & 0 deletions tests/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ test_jsn fnc_comment function_Mixed_Name
kill_process "$MARTIN_PROC_ID" Martin

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

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

0 comments on commit 36dcbc2

Please sign in to comment.