mirror of
https://github.com/maplibre/martin.git
synced 2024-12-24 07:22:52 +03:00
Require PostGIS 3 and use ST_TileEnvelope (#497)
* All tests and internal code now uses ST_TileEnvelope function * Remove `tile_bbox` * Rename test function sources for clarity - this will be needed in a subsequent PR to add other function tests
This commit is contained in:
parent
a009383039
commit
c1b65796f6
24
README.md
24
README.md
@ -42,7 +42,7 @@ Martin is a [PostGIS](https://github.com/postgis/postgis) [vector tiles](https:/
|
||||
|
||||
## Requirements
|
||||
|
||||
Martin requires PostGIS >= 2.4.0.
|
||||
Martin requires PostGIS >= 3.0.0
|
||||
|
||||
## Installation
|
||||
|
||||
@ -119,13 +119,13 @@ map.addLayer({
|
||||
```js
|
||||
map.addSource('rpc', {
|
||||
type: 'vector',
|
||||
url: `http://localhost:3000/function_source`
|
||||
url: `http://localhost:3000/function_zxy_query`
|
||||
});
|
||||
map.addLayer({
|
||||
id: 'points',
|
||||
type: 'circle',
|
||||
source: 'rpc',
|
||||
'source-layer': 'function_source',
|
||||
'source-layer': 'function_zxy_query',
|
||||
paint: {
|
||||
'circle-color': 'blue'
|
||||
},
|
||||
@ -242,8 +242,8 @@ curl localhost:3000/catalog | jq
|
||||
```yaml
|
||||
[
|
||||
{
|
||||
"id": "function_source",
|
||||
"name": "public.function_source"
|
||||
"id": "function_zxy_query",
|
||||
"name": "public.function_zxy_query"
|
||||
},
|
||||
{
|
||||
"id": "points1",
|
||||
@ -320,20 +320,18 @@ Function Source is a database function which can be used to query [vector tiles]
|
||||
| y | integer | Tile y parameter |
|
||||
| query_params | json | Query string parameters |
|
||||
|
||||
**Hint**: You may want to use [TileBBox](https://github.com/mapbox/postgis-vt-util#tilebbox) function to generate bounding-box geometry of the area covered by a tile.
|
||||
|
||||
For example, if you have a table `table_source` in WGS84 (`4326` SRID), then you can use this function as a Function Source:
|
||||
|
||||
```sql, ignore
|
||||
CREATE OR REPLACE FUNCTION function_source(z integer, x integer, y integer, query_params json) RETURNS bytea AS $$
|
||||
CREATE OR REPLACE FUNCTION function_zxy_query(z integer, x integer, y integer, query_params json) RETURNS bytea AS $$
|
||||
DECLARE
|
||||
mvt bytea;
|
||||
BEGIN
|
||||
SELECT INTO mvt ST_AsMVT(tile, 'function_source', 4096, 'geom') FROM (
|
||||
SELECT INTO mvt ST_AsMVT(tile, 'function_zxy_query', 4096, 'geom') FROM (
|
||||
SELECT
|
||||
ST_AsMVTGeom(ST_Transform(ST_CurveToLine(geom), 3857), TileBBox(z, x, y, 3857), 4096, 64, true) AS geom
|
||||
ST_AsMVTGeom(ST_Transform(ST_CurveToLine(geom), 3857), ST_TileEnvelope(z, x, y), 4096, 64, true) AS geom
|
||||
FROM table_source
|
||||
WHERE geom && TileBBox(z, x, y, 4326)
|
||||
WHERE geom && ST_Transform(ST_TileEnvelope(z, x, y), 4326)
|
||||
) as tile WHERE geom IS NOT NULL;
|
||||
|
||||
RETURN mvt;
|
||||
@ -350,7 +348,7 @@ curl \
|
||||
--data-urlencode 'stringParam=value' \
|
||||
--data-urlencode 'booleanParam=true' \
|
||||
--data-urlencode 'objectParam={"answer" : 42}' \
|
||||
--get localhost:3000/function_source/0/0/0
|
||||
--get localhost:3000/function_zxy_query/0/0/0
|
||||
```
|
||||
|
||||
then `query_params` will be parsed as:
|
||||
@ -520,7 +518,7 @@ function_sources:
|
||||
schema: public
|
||||
|
||||
# Function name (required)
|
||||
function: function_source
|
||||
function: function_zxy_query
|
||||
|
||||
# An integer specifying the minimum zoom level
|
||||
minzoom: 0
|
||||
|
@ -82,12 +82,12 @@ fn main() {}
|
||||
// }
|
||||
//
|
||||
// async fn get_function_source() {
|
||||
// let source = mock_function_source("public", "function_source");
|
||||
// let source = mock_function_source("public", "function_zxy_query");
|
||||
// let _tilejson = source.get_tilejson();
|
||||
// }
|
||||
//
|
||||
// async fn get_function_source_tile() {
|
||||
// let source = mock_function_source("public", "function_source");
|
||||
// let source = mock_function_source("public", "function_zxy_query");
|
||||
// let xyz = Xyz { z: 0, x: 0, y: 0 };
|
||||
//
|
||||
// let _tile = source.get_tile(&xyz, &None).await.unwrap();
|
||||
|
9
justfile
9
justfile
@ -12,8 +12,12 @@ export CARGO_TERM_COLOR := "always"
|
||||
run *ARGS: start-db
|
||||
cargo run -- {{ARGS}}
|
||||
|
||||
# Run PSQL utility against the test database
|
||||
psql *ARGS: start-db
|
||||
psql {{ARGS}} {{DATABASE_URL}}
|
||||
|
||||
# Perform cargo clean to delete all build files
|
||||
clean: clean-test
|
||||
clean: clean-test stop
|
||||
cargo clean
|
||||
|
||||
# Delete test output files
|
||||
@ -48,7 +52,7 @@ test-unit: start-db
|
||||
test-int: start-db clean-test
|
||||
#!/usr/bin/env sh
|
||||
tests/test.sh
|
||||
echo "** Skipping comparison with the expected values - not yet stable"
|
||||
# echo "** Skipping comparison with the expected values - not yet stable"
|
||||
# if ( ! diff --brief --recursive --new-file tests/output tests/expected ); then
|
||||
# echo "** Expected output does not match actual output"
|
||||
# echo "** If this is expected, run 'just bless' to update expected output"
|
||||
@ -70,5 +74,6 @@ docker-run *ARGS:
|
||||
docker run -it --rm --net host -e DATABASE_URL -v $PWD/tests:/tests martin {{ARGS}}
|
||||
|
||||
# Do any git command, ensuring that the testing environment is set up. Accepts the same arguments as git.
|
||||
[no-exit-message]
|
||||
git *ARGS: start-db
|
||||
git {{ARGS}}
|
||||
|
@ -75,6 +75,7 @@ mod tests {
|
||||
use crate::pg::config::{FunctionInfo, TableInfo};
|
||||
use indoc::indoc;
|
||||
use std::collections::HashMap;
|
||||
use tilejson::Bounds;
|
||||
|
||||
#[test]
|
||||
fn parse_config() {
|
||||
@ -106,9 +107,9 @@ mod tests {
|
||||
gid: int4
|
||||
|
||||
function_sources:
|
||||
function_source:
|
||||
function_zxy_query:
|
||||
schema: public
|
||||
function: function_source
|
||||
function: function_zxy_query
|
||||
minzoom: 0
|
||||
maxzoom: 30
|
||||
bounds: [-180.0, -90.0, 180.0, 90.0]
|
||||
@ -152,13 +153,13 @@ mod tests {
|
||||
},
|
||||
)]),
|
||||
function_sources: HashMap::from([(
|
||||
"function_source".to_string(),
|
||||
"function_zxy_query".to_string(),
|
||||
FunctionInfo {
|
||||
schema: "public".to_string(),
|
||||
function: "function_source".to_string(),
|
||||
function: "function_zxy_query".to_string(),
|
||||
minzoom: Some(0),
|
||||
maxzoom: Some(30),
|
||||
bounds: Some([-180, -90, 180, 90].into()),
|
||||
bounds: Some(Bounds::MAX),
|
||||
unrecognized: HashMap::new(),
|
||||
},
|
||||
)]),
|
||||
|
19
src/pg/db.rs
19
src/pg/db.rs
@ -27,7 +27,8 @@ pub type ConnectionManager = PostgresConnectionManager<postgres::NoTls>;
|
||||
pub type Pool = bb8::Pool<ConnectionManager>;
|
||||
pub type Connection<'a> = PooledConnection<'a, ConnectionManager>;
|
||||
|
||||
const REQUIRED_POSTGIS_VERSION: &str = ">= 2.4.0";
|
||||
// We require ST_TileEnvelope that was added in PostGIS 3.0.0
|
||||
const REQUIRED_POSTGIS_VERSION: &str = ">= 3.0.0";
|
||||
|
||||
pub struct PgConfigurator {
|
||||
pool: Pool,
|
||||
@ -121,9 +122,8 @@ impl PgConfigurator {
|
||||
let mut tables = TableInfoSources::new();
|
||||
if self.discover_tables {
|
||||
info!("Automatically detecting table sources");
|
||||
for info in
|
||||
get_table_sources(&self.pool, &self.table_sources, self.default_srid).await?
|
||||
{
|
||||
let srcs = get_table_sources(&self.pool, &self.table_sources, self.default_srid).await;
|
||||
for info in srcs? {
|
||||
self.add_table_src(&mut sources, Some(&mut tables), info.table.clone(), info);
|
||||
}
|
||||
}
|
||||
@ -153,10 +153,8 @@ impl PgConfigurator {
|
||||
info.geometry_type.as_deref().unwrap_or("null"),
|
||||
info.srid
|
||||
);
|
||||
sources.insert(
|
||||
id.clone(),
|
||||
Box::new(TableSource::new(id, info, self.pool.clone())),
|
||||
);
|
||||
let source = TableSource::new(id.clone(), info, self.pool.clone());
|
||||
sources.insert(id, Box::new(source));
|
||||
}
|
||||
|
||||
pub async fn instantiate_functions(&self) -> Result<(Sources, FunctionInfoSources), io::Error> {
|
||||
@ -235,9 +233,8 @@ pub async fn get_connection(pool: &Pool) -> io::Result<Connection<'_>> {
|
||||
}
|
||||
|
||||
async fn select_postgis_version(pool: &Pool) -> io::Result<String> {
|
||||
let connection = get_connection(pool).await?;
|
||||
|
||||
connection
|
||||
get_connection(pool)
|
||||
.await?
|
||||
.query_one(include_str!("scripts/get_postgis_version.sql"), &[])
|
||||
.await
|
||||
.map(|row| row.get::<_, String>("postgis_version"))
|
||||
|
@ -1,4 +1,4 @@
|
||||
SELECT
|
||||
ST_AsMVTGeom (ST_Transform (ST_CurveToLine("{geometry_column}"), 3857), {mercator_bounds}, {extent}, {buffer}, {clip_geom}) AS geom {properties} FROM {schema}."{table}", bounds
|
||||
ST_AsMVTGeom (ST_Transform (ST_CurveToLine("{geometry_column}"), 3857), ST_TileEnvelope({z}, {x}, {y}), {extent}, {buffer}, {clip_geom}) AS geom {properties} FROM {schema}."{table}", bounds
|
||||
WHERE
|
||||
"{geometry_column}" && bounds.srid_{srid}
|
||||
|
@ -1 +1 @@
|
||||
ST_Transform({mercator_bounds}, {srid}) AS srid_{srid}
|
||||
ST_Transform(ST_TileEnvelope({z}, {x}, {y}), {srid}) AS srid_{srid}
|
||||
|
@ -3,7 +3,7 @@ use crate::pg::db::get_connection;
|
||||
use crate::pg::db::Pool;
|
||||
use crate::pg::utils::{
|
||||
creat_tilejson, get_bounds_cte, get_source_bounds, get_srid_bounds, io_error, is_valid_zoom,
|
||||
json_to_hashmap, polygon_to_bbox, tile_bbox,
|
||||
json_to_hashmap, polygon_to_bbox,
|
||||
};
|
||||
use crate::source::{Source, Tile, UrlQuery, Xyz};
|
||||
use async_trait::async_trait;
|
||||
@ -43,8 +43,6 @@ impl TableSource {
|
||||
}
|
||||
|
||||
pub fn get_geom_query(&self, xyz: &Xyz) -> String {
|
||||
let mercator_bounds = tile_bbox(xyz);
|
||||
|
||||
let info = &self.info;
|
||||
let properties = if info.properties.is_empty() {
|
||||
String::new()
|
||||
@ -65,7 +63,9 @@ impl TableSource {
|
||||
table = info.table,
|
||||
srid = info.srid,
|
||||
geometry_column = info.geometry_column,
|
||||
mercator_bounds = mercator_bounds,
|
||||
z = xyz.z,
|
||||
x = xyz.x,
|
||||
y = xyz.y,
|
||||
extent = info.extent.unwrap_or(DEFAULT_EXTENT),
|
||||
buffer = info.buffer.unwrap_or(DEFAULT_BUFFER),
|
||||
clip_geom = info.clip_geom.unwrap_or(DEFAULT_CLIP_GEOM),
|
||||
|
@ -18,23 +18,6 @@ macro_rules! io_error {
|
||||
|
||||
pub(crate) use io_error;
|
||||
|
||||
// https://github.com/mapbox/postgis-vt-util/blob/master/src/TileBBox.sql
|
||||
pub fn tile_bbox(xyz: &Xyz) -> String {
|
||||
let x = xyz.x;
|
||||
let y = xyz.y;
|
||||
let z = xyz.z;
|
||||
|
||||
let max = 20_037_508.34;
|
||||
let res = (max * 2.0) / f64::from(2_i32.pow(z as u32));
|
||||
|
||||
let x_min = -max + (f64::from(x) * res);
|
||||
let y_min = max - (f64::from(y) * res);
|
||||
let x_max = -max + (f64::from(x) * res) + res;
|
||||
let y_max = max - (f64::from(y) * res) - res;
|
||||
|
||||
format!("ST_MakeEnvelope({x_min}, {y_min}, {x_max}, {y_max}, 3857)")
|
||||
}
|
||||
|
||||
pub fn json_to_hashmap(value: &serde_json::Value) -> HashMap<String, String> {
|
||||
let mut hashmap = HashMap::new();
|
||||
|
||||
@ -69,8 +52,10 @@ pub fn get_bounds_cte(srid_bounds: &str) -> String {
|
||||
pub fn get_srid_bounds(srid: u32, xyz: &Xyz) -> String {
|
||||
format!(
|
||||
include_str!("scripts/get_srid_bounds.sql"),
|
||||
z = xyz.z,
|
||||
x = xyz.x,
|
||||
y = xyz.y,
|
||||
srid = srid,
|
||||
mercator_bounds = tile_bbox(xyz),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -116,12 +116,12 @@ table_sources:
|
||||
|
||||
# Associative arrays of function sources
|
||||
function_sources:
|
||||
function_source:
|
||||
function_zxy_query:
|
||||
# Schema name (required)
|
||||
schema: public
|
||||
|
||||
# Function name (required)
|
||||
function: function_source
|
||||
function: function_zxy_query
|
||||
|
||||
# An integer specifying the minimum zoom level
|
||||
minzoom: 0
|
||||
@ -135,9 +135,9 @@ function_sources:
|
||||
# Values may be integers or floating point numbers.
|
||||
bounds: [-180.0, -90.0, 180.0, 90.0]
|
||||
|
||||
function_source_query_params:
|
||||
function_zxy_query_test:
|
||||
schema: public
|
||||
function: function_source_query_params
|
||||
function: function_zxy_query_test
|
||||
minzoom: 0
|
||||
maxzoom: 30
|
||||
bounds: [-180.0, -90.0, 180.0, 90.0]
|
||||
|
@ -37,14 +37,14 @@
|
||||
map.on('load', function () {
|
||||
map.addSource('rpc', {
|
||||
type: 'vector',
|
||||
url: `http://localhost:3000/function_source`
|
||||
url: `http://localhost:3000/function_zxy_query`
|
||||
});
|
||||
|
||||
map.addLayer({
|
||||
id: 'points',
|
||||
type: 'circle',
|
||||
source: 'rpc',
|
||||
'source-layer': 'function_source',
|
||||
'source-layer': 'function_zxy_query',
|
||||
paint: {
|
||||
'circle-color': 'blue'
|
||||
}
|
||||
|
39
tests/fixtures/TileBBox.sql
vendored
39
tests/fixtures/TileBBox.sql
vendored
@ -1,39 +0,0 @@
|
||||
/******************************************************************************
|
||||
### TileBBox ###
|
||||
|
||||
Given a Web Mercator tile ID as (z, x, y), returns a bounding-box
|
||||
geometry of the area covered by that tile.
|
||||
|
||||
__Parameters:__
|
||||
|
||||
- `integer` z - A tile zoom level.
|
||||
- `integer` x - A tile x-position.
|
||||
- `integer` y - A tile y-position.
|
||||
- `integer` srid - SRID of the desired target projection of the bounding
|
||||
box. Defaults to 3857 (Web Mercator).
|
||||
|
||||
__Returns:__ `geometry(polygon)`
|
||||
******************************************************************************/
|
||||
create or replace function TileBBox(z int, x int, y int, srid int = 3857)
|
||||
returns geometry
|
||||
language plpgsql immutable as
|
||||
$func$
|
||||
declare
|
||||
max numeric := 20037508.34;
|
||||
res numeric := (max*2)/(2^z);
|
||||
bbox geometry;
|
||||
begin
|
||||
bbox := ST_MakeEnvelope(
|
||||
-max + (x * res),
|
||||
max - (y * res),
|
||||
-max + (x * res) + res,
|
||||
max - (y * res) - res,
|
||||
3857
|
||||
);
|
||||
if srid = 3857 then
|
||||
return bbox;
|
||||
else
|
||||
return ST_Transform(bbox, srid);
|
||||
end if;
|
||||
end;
|
||||
$func$;
|
17
tests/fixtures/function_source.sql
vendored
17
tests/fixtures/function_source.sql
vendored
@ -1,17 +0,0 @@
|
||||
DROP FUNCTION IF EXISTS public.function_source;
|
||||
CREATE OR REPLACE FUNCTION public.function_source(z integer, x integer, y integer, query_params json) RETURNS bytea AS $$
|
||||
DECLARE
|
||||
mvt bytea;
|
||||
BEGIN
|
||||
RAISE NOTICE 'query_params: %', query_params;
|
||||
|
||||
SELECT INTO mvt ST_AsMVT(tile, 'public.function_source', 4096, 'geom') FROM (
|
||||
SELECT
|
||||
ST_AsMVTGeom(ST_Transform(ST_CurveToLine(geom), 3857), TileBBox(z, x, y, 3857), 4096, 64, true) AS geom
|
||||
FROM public.table_source
|
||||
WHERE geom && TileBBox(z, x, y, 4326)
|
||||
) as tile WHERE geom IS NOT NULL;
|
||||
|
||||
RETURN mvt;
|
||||
END
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;
|
21
tests/fixtures/function_source_query_params.sql
vendored
21
tests/fixtures/function_source_query_params.sql
vendored
@ -1,21 +0,0 @@
|
||||
DROP FUNCTION IF EXISTS public.function_source_query_params;
|
||||
CREATE OR REPLACE FUNCTION public.function_source_query_params(z integer, x integer, y integer, query_params json) RETURNS bytea AS $$
|
||||
DECLARE
|
||||
mvt bytea;
|
||||
BEGIN
|
||||
RAISE DEBUG 'query_params: %', query_params;
|
||||
|
||||
IF (query_params->>'token')::varchar IS NULL THEN
|
||||
RAISE EXCEPTION 'the `token` json parameter does not exist in `query_params`';
|
||||
END IF;
|
||||
|
||||
SELECT INTO mvt ST_AsMVT(tile, 'public.function_source_query_params', 4096, 'geom') FROM (
|
||||
SELECT
|
||||
ST_AsMVTGeom(ST_Transform(ST_CurveToLine(geom), 3857), TileBBox(z, x, y, 3857), 4096, 64, true) AS geom
|
||||
FROM public.table_source
|
||||
WHERE geom && TileBBox(z, x, y, 4326)
|
||||
) as tile WHERE geom IS NOT NULL;
|
||||
|
||||
RETURN mvt;
|
||||
END
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;
|
17
tests/fixtures/functions/function_zxy_query.sql
vendored
Normal file
17
tests/fixtures/functions/function_zxy_query.sql
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
DROP FUNCTION IF EXISTS public.function_zxy_query;
|
||||
CREATE OR REPLACE FUNCTION public.function_zxy_query(z integer, x integer, y integer, query_params json) RETURNS bytea AS $$
|
||||
DECLARE
|
||||
mvt bytea;
|
||||
BEGIN
|
||||
RAISE NOTICE 'query_params: %', query_params;
|
||||
|
||||
SELECT INTO mvt ST_AsMVT(tile, 'public.function_zxy_query', 4096, 'geom') FROM (
|
||||
SELECT
|
||||
ST_AsMVTGeom(ST_Transform(ST_CurveToLine(geom), 3857), ST_TileEnvelope(z, x, y), 4096, 64, true) AS geom
|
||||
FROM public.table_source
|
||||
WHERE geom && ST_Transform(ST_TileEnvelope(z, x, y), 4326)
|
||||
) as tile WHERE geom IS NOT NULL;
|
||||
|
||||
RETURN mvt;
|
||||
END
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;
|
21
tests/fixtures/functions/function_zxy_query_test.sql
vendored
Normal file
21
tests/fixtures/functions/function_zxy_query_test.sql
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
DROP FUNCTION IF EXISTS public.function_zxy_query_test;
|
||||
CREATE OR REPLACE FUNCTION public.function_zxy_query_test(z integer, x integer, y integer, query_params json) RETURNS bytea AS $$
|
||||
DECLARE
|
||||
mvt bytea;
|
||||
BEGIN
|
||||
RAISE DEBUG 'query_params: %', query_params;
|
||||
|
||||
IF (query_params->>'token')::varchar IS NULL THEN
|
||||
RAISE EXCEPTION 'the `token` json parameter does not exist in `query_params`';
|
||||
END IF;
|
||||
|
||||
SELECT INTO mvt ST_AsMVT(tile, 'public.function_zxy_query_test', 4096, 'geom') FROM (
|
||||
SELECT
|
||||
ST_AsMVTGeom(ST_Transform(ST_CurveToLine(geom), 3857), ST_TileEnvelope(z, x, y), 4096, 64, true) AS geom
|
||||
FROM public.table_source
|
||||
WHERE geom && ST_Transform(ST_TileEnvelope(z, x, y), 4326)
|
||||
) as tile WHERE geom IS NOT NULL;
|
||||
|
||||
RETURN mvt;
|
||||
END
|
||||
$$ LANGUAGE plpgsql IMMUTABLE STRICT PARALLEL SAFE;
|
21
tests/fixtures/initdb.sh
vendored
21
tests/fixtures/initdb.sh
vendored
@ -2,7 +2,7 @@
|
||||
set -euo pipefail
|
||||
|
||||
FIXTURES_DIR="$(dirname "$0")"
|
||||
echo "Loading Martin test fixtures into '$PGDATABASE' as user '$PGUSER' from '$FIXTURES_DIR'"
|
||||
echo "Loading Martin test fixtures into '$PGDATABASE' as user '$PGUSER'"
|
||||
|
||||
|
||||
psql -P pager=off -v ON_ERROR_STOP=1 -c "CREATE EXTENSION IF NOT EXISTS postgis;"
|
||||
@ -11,12 +11,13 @@ psql -P pager=off -v ON_ERROR_STOP=1 -c "DROP SCHEMA IF EXISTS tiger CASCADE;"
|
||||
psql -P pager=off -v ON_ERROR_STOP=1 -t -c "select version();"
|
||||
psql -P pager=off -v ON_ERROR_STOP=1 -t -c "select PostGIS_Full_Version();"
|
||||
|
||||
psql -e -P pager=off -v ON_ERROR_STOP=1 -f $FIXTURES_DIR/TileBBox.sql
|
||||
psql -e -P pager=off -v ON_ERROR_STOP=1 -f $FIXTURES_DIR/table_source.sql
|
||||
psql -e -P pager=off -v ON_ERROR_STOP=1 -f $FIXTURES_DIR/table_source_multiple_geom.sql
|
||||
psql -e -P pager=off -v ON_ERROR_STOP=1 -f $FIXTURES_DIR/function_source.sql
|
||||
psql -e -P pager=off -v ON_ERROR_STOP=1 -f $FIXTURES_DIR/function_source_query_params.sql
|
||||
psql -e -P pager=off -v ON_ERROR_STOP=1 -f $FIXTURES_DIR/points1_source.sql
|
||||
psql -e -P pager=off -v ON_ERROR_STOP=1 -f $FIXTURES_DIR/points2_source.sql
|
||||
psql -e -P pager=off -v ON_ERROR_STOP=1 -f $FIXTURES_DIR/points3857_source.sql
|
||||
psql -e -P pager=off -v ON_ERROR_STOP=1 -f $FIXTURES_DIR/points_empty_srid_source.sql
|
||||
|
||||
echo "Importing tables from $FIXTURES_DIR/tables"
|
||||
for sql_file in "$FIXTURES_DIR"/tables/*.sql; do
|
||||
psql -e -P pager=off -v ON_ERROR_STOP=1 -f "$sql_file"
|
||||
done
|
||||
|
||||
echo "Importing functions from $FIXTURES_DIR/functions"
|
||||
for sql_file in "$FIXTURES_DIR"/functions/*.sql; do
|
||||
psql -e -P pager=off -v ON_ERROR_STOP=1 -f "$sql_file"
|
||||
done
|
||||
|
@ -16,33 +16,33 @@ fn init() {
|
||||
#[actix_rt::test]
|
||||
async fn get_function_sources() {
|
||||
let pool = mock_pool().await;
|
||||
let function_sources = get_sources(&pool, &FunctionInfoSources::default())
|
||||
let sources = get_sources(&pool, &FunctionInfoSources::default())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
info!("function_sources = {function_sources:#?}");
|
||||
info!("sources = {sources:#?}");
|
||||
|
||||
assert!(!function_sources.is_empty());
|
||||
let function_source = single(&function_sources, |v| v.function == "function_source")
|
||||
.expect("function_source not found");
|
||||
assert_eq!(function_source.schema, "public");
|
||||
assert_eq!(function_source.function, "function_source");
|
||||
assert_eq!(function_source.minzoom, None);
|
||||
assert_eq!(function_source.maxzoom, None);
|
||||
assert_eq!(function_source.bounds, None);
|
||||
assert!(!sources.is_empty());
|
||||
let source = single(&sources, |v| v.function == "function_zxy_query")
|
||||
.expect("function_zxy_query not found");
|
||||
assert_eq!(source.schema, "public");
|
||||
assert_eq!(source.function, "function_zxy_query");
|
||||
assert_eq!(source.minzoom, None);
|
||||
assert_eq!(source.maxzoom, None);
|
||||
assert_eq!(source.bounds, None);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn function_source_tilejson() {
|
||||
let sources = mock_sources(None, None).await;
|
||||
let source = sources.get("function_source").unwrap();
|
||||
let source = sources.get("function_zxy_query").unwrap();
|
||||
let tilejson = source.get_tilejson();
|
||||
|
||||
info!("tilejson = {tilejson:#?}");
|
||||
|
||||
assert_eq!(tilejson.tilejson, "2.2.0");
|
||||
assert_eq!(tilejson.version, Some("1.0.0".to_owned()));
|
||||
assert_eq!(tilejson.name, Some("public.function_source".to_owned()));
|
||||
assert_eq!(tilejson.name, Some("public.function_zxy_query".to_owned()));
|
||||
assert_eq!(tilejson.scheme, Some("xyz".to_owned()));
|
||||
assert_eq!(tilejson.minzoom, Some(0));
|
||||
assert_eq!(tilejson.maxzoom, Some(30));
|
||||
@ -53,7 +53,7 @@ async fn function_source_tilejson() {
|
||||
#[actix_rt::test]
|
||||
async fn function_source_tile() {
|
||||
let sources = mock_sources(None, None).await;
|
||||
let source = sources.get("function_source").unwrap();
|
||||
let source = sources.get("function_zxy_query").unwrap();
|
||||
let tile = source
|
||||
.get_tile(&Xyz { x: 0, y: 0, z: 0 }, &None)
|
||||
.await
|
||||
|
@ -56,7 +56,7 @@ async fn get_function_catalog_ok() {
|
||||
|
||||
let body = read_body(response).await;
|
||||
let sources: Vec<IndexEntry> = serde_json::from_slice(&body).unwrap();
|
||||
let expected = "function_source";
|
||||
let expected = "function_zxy_query";
|
||||
assert_eq!(sources.into_iter().filter(|v| v.id == expected).count(), 1);
|
||||
}
|
||||
|
||||
@ -362,18 +362,18 @@ async fn get_function_source_ok() {
|
||||
let response = call_service(&app, req).await;
|
||||
assert_eq!(response.status(), StatusCode::NOT_FOUND);
|
||||
|
||||
let req = test_get("/function_source");
|
||||
let req = test_get("/function_zxy_query");
|
||||
let response = call_service(&app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
|
||||
let req = TestRequest::get()
|
||||
.uri("/function_source?token=martin")
|
||||
.insert_header(("x-rewrite-url", "/tiles/function_source?token=martin"))
|
||||
.uri("/function_zxy_query?token=martin")
|
||||
.insert_header(("x-rewrite-url", "/tiles/function_zxy_query?token=martin"))
|
||||
.to_request();
|
||||
let result: TileJSON = call_and_read_body_json(&app, req).await;
|
||||
assert_eq!(
|
||||
result.tiles,
|
||||
&["http://localhost:8080/tiles/function_source/{z}/{x}/{y}?token=martin"]
|
||||
&["http://localhost:8080/tiles/function_zxy_query/{z}/{x}/{y}?token=martin"]
|
||||
);
|
||||
}
|
||||
|
||||
@ -381,7 +381,7 @@ async fn get_function_source_ok() {
|
||||
async fn get_function_source_tile_ok() {
|
||||
let app = create_app!(mock_default_function_sources());
|
||||
|
||||
let req = test_get("/function_source/0/0/0");
|
||||
let req = test_get("/function_zxy_query/0/0/0");
|
||||
let response = call_service(&app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
}
|
||||
@ -390,7 +390,7 @@ async fn get_function_source_tile_ok() {
|
||||
async fn get_function_source_tile_minmax_zoom_ok() {
|
||||
let function_source1 = FunctionInfo {
|
||||
schema: "public".to_owned(),
|
||||
function: "function_source".to_owned(),
|
||||
function: "function_zxy_query".to_owned(),
|
||||
minzoom: None,
|
||||
maxzoom: None,
|
||||
bounds: Some(Bounds::MAX),
|
||||
@ -399,7 +399,7 @@ async fn get_function_source_tile_minmax_zoom_ok() {
|
||||
|
||||
let function_source2 = FunctionInfo {
|
||||
schema: "public".to_owned(),
|
||||
function: "function_source".to_owned(),
|
||||
function: "function_zxy_query".to_owned(),
|
||||
minzoom: Some(6),
|
||||
maxzoom: Some(12),
|
||||
bounds: Some(Bounds::MAX),
|
||||
@ -457,12 +457,12 @@ async fn get_function_source_tile_minmax_zoom_ok() {
|
||||
async fn get_function_source_query_params_ok() {
|
||||
let app = create_app!(mock_default_function_sources());
|
||||
|
||||
let req = test_get("/function_source_query_params/0/0/0");
|
||||
let req = test_get("/function_zxy_query_test/0/0/0");
|
||||
let response = call_service(&app, req).await;
|
||||
println!("response.status = {:?}", response.status());
|
||||
assert!(response.status().is_server_error());
|
||||
|
||||
let req = test_get("/function_source_query_params/0/0/0?token=martin");
|
||||
let req = test_get("/function_zxy_query_test/0/0/0?token=martin");
|
||||
let response = call_service(&app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
}
|
||||
|
@ -109,14 +109,14 @@ test_pbf cmp_20_633856_327787 http://localhost:3000/table_source,points1,point
|
||||
test_pbf cmp_21_1267712_655574 http://localhost:3000/table_source,points1,points2/21/1267712/655574
|
||||
|
||||
>&2 echo "Test server response for function source"
|
||||
test_pbf fnc_0_0_0 http://localhost:3000/function_source/0/0/0
|
||||
test_pbf fnc_6_38_20 http://localhost:3000/function_source/6/38/20
|
||||
test_pbf fnc_12_2476_1280 http://localhost:3000/function_source/12/2476/1280
|
||||
test_pbf fnc_13_4952_2560 http://localhost:3000/function_source/13/4952/2560
|
||||
test_pbf fnc_14_9904_5121 http://localhost:3000/function_source/14/9904/5121
|
||||
test_pbf fnc_20_633856_327787 http://localhost:3000/function_source/20/633856/327787
|
||||
test_pbf fnc_21_1267712_655574 http://localhost:3000/function_source/21/1267712/655574
|
||||
test_pbf fnc_0_0_0_token http://localhost:3000/function_source_query_params/0/0/0?token=martin
|
||||
test_pbf fnc_0_0_0 http://localhost:3000/function_zxy_query/0/0/0
|
||||
test_pbf fnc_6_38_20 http://localhost:3000/function_zxy_query/6/38/20
|
||||
test_pbf fnc_12_2476_1280 http://localhost:3000/function_zxy_query/12/2476/1280
|
||||
test_pbf fnc_13_4952_2560 http://localhost:3000/function_zxy_query/13/4952/2560
|
||||
test_pbf fnc_14_9904_5121 http://localhost:3000/function_zxy_query/14/9904/5121
|
||||
test_pbf fnc_20_633856_327787 http://localhost:3000/function_zxy_query/20/633856/327787
|
||||
test_pbf fnc_21_1267712_655574 http://localhost:3000/function_zxy_query/21/1267712/655574
|
||||
test_pbf fnc_0_0_0_token http://localhost:3000/function_zxy_query_test/0/0/0?token=martin
|
||||
|
||||
>&2 echo "Test server response for table source with different SRID"
|
||||
test_pbf points3857_srid_0_0_0 http://localhost:3000/points3857/0/0/0
|
||||
@ -145,7 +145,9 @@ $CURL http://localhost:3000/catalog | jq --sort-keys -e | tee "$TEST_OUT_DIR/cat
|
||||
|
||||
test_pbf tbl_0_0_0 http://localhost:3000/table_source/0/0/0
|
||||
test_pbf cmp_0_0_0 http://localhost:3000/points1,points2/0/0/0
|
||||
test_pbf fnc_0_0_0 http://localhost:3000/function_source/0/0/0
|
||||
test_pbf fnc2_0_0_0 http://localhost:3000/function_source_query_params/0/0/0?token=martin
|
||||
test_pbf fnc_0_0_0 http://localhost:3000/function_zxy_query/0/0/0
|
||||
test_pbf fnc2_0_0_0 http://localhost:3000/function_zxy_query_test/0/0/0?token=martin
|
||||
|
||||
kill_process $PROCESS_ID
|
||||
|
||||
>&2 echo "All integration tests have passed"
|
||||
|
@ -173,26 +173,26 @@ pub async fn mock_default_table_sources() -> Sources {
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub async fn mock_default_function_sources() -> Sources {
|
||||
let function_source = FunctionInfo {
|
||||
let function_zxy_query = FunctionInfo {
|
||||
schema: "public".to_owned(),
|
||||
function: "function_source".to_owned(),
|
||||
function: "function_zxy_query".to_owned(),
|
||||
minzoom: Some(0),
|
||||
maxzoom: Some(30),
|
||||
bounds: Some(Bounds::MAX),
|
||||
unrecognized: HashMap::new(),
|
||||
};
|
||||
|
||||
let function_source_query_params = FunctionInfo {
|
||||
let function_zxy_query_test = FunctionInfo {
|
||||
schema: "public".to_owned(),
|
||||
function: "function_source_query_params".to_owned(),
|
||||
function: "function_zxy_query_test".to_owned(),
|
||||
unrecognized: HashMap::new(),
|
||||
..function_source
|
||||
..function_zxy_query
|
||||
};
|
||||
|
||||
mock_sources(
|
||||
Some(&[
|
||||
("function_source", function_source),
|
||||
("function_source_query_params", function_source_query_params),
|
||||
("function_zxy_query", function_zxy_query),
|
||||
("function_zxy_query_test", function_zxy_query_test),
|
||||
]),
|
||||
None,
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user