mirror of
https://github.com/maplibre/martin.git
synced 2024-12-24 07:22:52 +03:00
feat: add minzoom and maxzoom support (#265)
This commit is contained in:
parent
a9cf508c33
commit
194a83e63f
71
README.md
71
README.md
@ -390,8 +390,11 @@ martin --config config.yaml
|
||||
You can find an example of a configuration file [here](https://github.com/urbica/martin/blob/master/tests/config.yaml).
|
||||
|
||||
```yaml
|
||||
# The socket address to bind [default: 0.0.0.0:3000]
|
||||
listen_addresses: '0.0.0.0:3000'
|
||||
|
||||
# Database connection string
|
||||
connection_string: 'postgres://postgres@localhost/db'
|
||||
connection_string: 'postgres://postgres@localhost:5432/db'
|
||||
|
||||
# Maximum connections pool size [default: 20]
|
||||
pool_size: 20
|
||||
@ -402,60 +405,84 @@ keep_alive: 75
|
||||
# Number of web server workers
|
||||
worker_processes: 8
|
||||
|
||||
# The socket address to bind [default: 0.0.0.0:3000]
|
||||
listen_addresses: '0.0.0.0:3000'
|
||||
|
||||
# Enable watch mode
|
||||
watch: true
|
||||
watch: false
|
||||
|
||||
# Trust invalid certificates. This introduces significant vulnerabilities, and should only be used as a last resort.
|
||||
danger_accept_invalid_certs: false
|
||||
|
||||
# associative arrays of table sources
|
||||
# Associative arrays of table sources
|
||||
table_sources:
|
||||
public.table_source:
|
||||
# table source id
|
||||
# Table source id (required)
|
||||
id: public.table_source
|
||||
|
||||
# table schema
|
||||
# Table schema (required)
|
||||
schema: public
|
||||
|
||||
# table name
|
||||
# Table name (required)
|
||||
table: table_source
|
||||
|
||||
# geometry column name
|
||||
geometry_column: geom
|
||||
|
||||
# geometry srid
|
||||
# Geometry SRID (required)
|
||||
srid: 4326
|
||||
|
||||
# tile extent in tile coordinate space
|
||||
# Geometry column name (required)
|
||||
geometry_column: geom
|
||||
|
||||
# Feature id column name
|
||||
id_column: ~
|
||||
|
||||
# An integer specifying the minimum zoom level
|
||||
minzoom: 0
|
||||
|
||||
# An integer specifying the maximum zoom level. MUST be >= minzoom
|
||||
maxzoom: 30
|
||||
|
||||
# The maximum extent of available map tiles. Bounds MUST define an area
|
||||
# covered by all zoom levels. The bounds are represented in WGS:84
|
||||
# latitude and longitude values, in the order left, bottom, right, top.
|
||||
# Values may be integers or floating point numbers.
|
||||
bounds: [-180.0, -90.0, 180.0, 90.0]
|
||||
|
||||
# Tile extent in tile coordinate space
|
||||
extent: 4096
|
||||
|
||||
# buffer distance in tile coordinate space to optionally clip geometries
|
||||
# Buffer distance in tile coordinate space to optionally clip geometries
|
||||
buffer: 64
|
||||
|
||||
# boolean to control if geometries should be clipped or encoded as is
|
||||
# Boolean to control if geometries should be clipped or encoded as is
|
||||
clip_geom: true
|
||||
|
||||
# geometry type
|
||||
# Geometry type
|
||||
geometry_type: GEOMETRY
|
||||
|
||||
# list of columns, that should be encoded as a tile properties
|
||||
# List of columns, that should be encoded as tile properties (required)
|
||||
properties:
|
||||
gid: int4
|
||||
|
||||
# associative arrays of function sources
|
||||
# Associative arrays of function sources
|
||||
function_sources:
|
||||
public.function_source:
|
||||
# function source id
|
||||
# Function source id (required)
|
||||
id: public.function_source
|
||||
|
||||
# schema name
|
||||
# Schema name (required)
|
||||
schema: public
|
||||
|
||||
# function name
|
||||
# Function name (required)
|
||||
function: function_source
|
||||
|
||||
# An integer specifying the minimum zoom level
|
||||
minzoom: 0
|
||||
|
||||
# An integer specifying the maximum zoom level. MUST be >= minzoom
|
||||
maxzoom: 30
|
||||
|
||||
# The maximum extent of available map tiles. Bounds MUST define an area
|
||||
# covered by all zoom levels. The bounds are represented in WGS:84
|
||||
# latitude and longitude values, in the order left, bottom, right, top.
|
||||
# Values may be integers or floating point numbers.
|
||||
bounds: [-180.0, -90.0, 180.0, 90.0]
|
||||
```
|
||||
|
||||
## Using with Docker
|
||||
|
@ -16,6 +16,8 @@ fn mock_table_source(schema: &str, table: &str) -> TableSource {
|
||||
table: table.to_owned(),
|
||||
id_column: None,
|
||||
geometry_column: "geom".to_owned(),
|
||||
minzoom: None,
|
||||
maxzoom: None,
|
||||
bounds: None,
|
||||
srid: 3857,
|
||||
extent: Some(4096),
|
||||
@ -31,6 +33,9 @@ fn mock_function_source(schema: &str, function: &str) -> FunctionSource {
|
||||
id: format!("{}.{}", schema, function),
|
||||
schema: schema.to_owned(),
|
||||
function: function.to_owned(),
|
||||
minzoom: None,
|
||||
maxzoom: None,
|
||||
bounds: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,20 @@ impl CompositeSource {
|
||||
format!("{} {}", bounds_cte, tile_query)
|
||||
}
|
||||
|
||||
pub fn get_minzoom(&self) -> Option<u8> {
|
||||
self.table_sources
|
||||
.iter()
|
||||
.filter_map(|table_source| table_source.minzoom)
|
||||
.min()
|
||||
}
|
||||
|
||||
pub fn get_maxzoom(&self) -> Option<u8> {
|
||||
self.table_sources
|
||||
.iter()
|
||||
.filter_map(|table_source| table_source.maxzoom)
|
||||
.max()
|
||||
}
|
||||
|
||||
pub fn get_bounds(&self) -> Option<Vec<f32>> {
|
||||
self.table_sources
|
||||
.iter()
|
||||
@ -75,6 +89,14 @@ impl Source for CompositeSource {
|
||||
tilejson_builder.scheme("xyz");
|
||||
tilejson_builder.name(&self.id);
|
||||
|
||||
if let Some(minzoom) = self.get_minzoom() {
|
||||
tilejson_builder.minzoom(minzoom);
|
||||
};
|
||||
|
||||
if let Some(maxzoom) = self.get_maxzoom() {
|
||||
tilejson_builder.maxzoom(maxzoom);
|
||||
};
|
||||
|
||||
if let Some(bounds) = self.get_bounds() {
|
||||
tilejson_builder.bounds(bounds);
|
||||
};
|
||||
|
57
src/dev.rs
57
src/dev.rs
@ -12,13 +12,24 @@ use crate::function_source::{FunctionSource, FunctionSources};
|
||||
use crate::server::AppState;
|
||||
use crate::table_source::{TableSource, TableSources};
|
||||
|
||||
pub fn mock_table_sources() -> Option<TableSources> {
|
||||
pub fn mock_table_sources(sources: Vec<TableSource>) -> TableSources {
|
||||
let mut table_sources: TableSources = HashMap::new();
|
||||
for source in sources {
|
||||
table_sources.insert(source.id.to_owned(), Box::new(source));
|
||||
}
|
||||
|
||||
table_sources
|
||||
}
|
||||
|
||||
pub fn mock_default_table_sources() -> TableSources {
|
||||
let source = TableSource {
|
||||
id: "public.table_source".to_owned(),
|
||||
schema: "public".to_owned(),
|
||||
table: "table_source".to_owned(),
|
||||
id_column: None,
|
||||
geometry_column: "geom".to_owned(),
|
||||
minzoom: Some(0),
|
||||
maxzoom: Some(30),
|
||||
bounds: Some(vec![-180.0, -90.0, 180.0, 90.0]),
|
||||
srid: 4326,
|
||||
extent: Some(4096),
|
||||
@ -34,6 +45,8 @@ pub fn mock_table_sources() -> Option<TableSources> {
|
||||
table: "points1".to_owned(),
|
||||
id_column: None,
|
||||
geometry_column: "geom".to_owned(),
|
||||
minzoom: Some(0),
|
||||
maxzoom: Some(30),
|
||||
bounds: Some(vec![-180.0, -90.0, 180.0, 90.0]),
|
||||
srid: 4326,
|
||||
extent: Some(4096),
|
||||
@ -49,6 +62,8 @@ pub fn mock_table_sources() -> Option<TableSources> {
|
||||
table: "points2".to_owned(),
|
||||
id_column: None,
|
||||
geometry_column: "geom".to_owned(),
|
||||
minzoom: Some(0),
|
||||
maxzoom: Some(30),
|
||||
bounds: Some(vec![-180.0, -90.0, 180.0, 90.0]),
|
||||
srid: 4326,
|
||||
extent: Some(4096),
|
||||
@ -64,6 +79,8 @@ pub fn mock_table_sources() -> Option<TableSources> {
|
||||
table: "points3857".to_owned(),
|
||||
id_column: None,
|
||||
geometry_column: "geom".to_owned(),
|
||||
minzoom: Some(0),
|
||||
maxzoom: Some(30),
|
||||
bounds: Some(vec![-180.0, -90.0, 180.0, 90.0]),
|
||||
srid: 3857,
|
||||
extent: Some(4096),
|
||||
@ -73,36 +90,38 @@ pub fn mock_table_sources() -> Option<TableSources> {
|
||||
properties: HashMap::new(),
|
||||
};
|
||||
|
||||
let mut table_sources: TableSources = HashMap::new();
|
||||
table_sources.insert("public.table_source".to_owned(), Box::new(source));
|
||||
table_sources.insert("public.points1".to_owned(), Box::new(table_source1));
|
||||
table_sources.insert("public.points2".to_owned(), Box::new(table_source2));
|
||||
table_sources.insert("public.points3857".to_owned(), Box::new(table_source3857));
|
||||
Some(table_sources)
|
||||
mock_table_sources(vec![source, table_source1, table_source2, table_source3857])
|
||||
}
|
||||
|
||||
pub fn mock_function_sources() -> Option<FunctionSources> {
|
||||
pub fn mock_function_sources(sources: Vec<FunctionSource>) -> FunctionSources {
|
||||
let mut function_sources: FunctionSources = HashMap::new();
|
||||
for source in sources {
|
||||
function_sources.insert(source.id.to_owned(), Box::new(source));
|
||||
}
|
||||
|
||||
function_sources.insert(
|
||||
"public.function_source".to_owned(),
|
||||
Box::new(FunctionSource {
|
||||
function_sources
|
||||
}
|
||||
|
||||
pub fn mock_default_function_sources() -> FunctionSources {
|
||||
let function_source = FunctionSource {
|
||||
id: "public.function_source".to_owned(),
|
||||
schema: "public".to_owned(),
|
||||
function: "function_source".to_owned(),
|
||||
}),
|
||||
);
|
||||
minzoom: Some(0),
|
||||
maxzoom: Some(30),
|
||||
bounds: Some(vec![-180.0, -90.0, 180.0, 90.0]),
|
||||
};
|
||||
|
||||
function_sources.insert(
|
||||
"public.function_source_query_params".to_owned(),
|
||||
Box::new(FunctionSource {
|
||||
let function_source_query_params = FunctionSource {
|
||||
id: "public.function_source_query_params".to_owned(),
|
||||
schema: "public".to_owned(),
|
||||
function: "function_source_query_params".to_owned(),
|
||||
}),
|
||||
);
|
||||
minzoom: Some(0),
|
||||
maxzoom: Some(30),
|
||||
bounds: Some(vec![-180.0, -90.0, 180.0, 90.0]),
|
||||
};
|
||||
|
||||
Some(function_sources)
|
||||
mock_function_sources(vec![function_source, function_source_query_params])
|
||||
}
|
||||
|
||||
pub fn make_pool() -> Pool {
|
||||
|
@ -11,9 +11,28 @@ use crate::utils::{prettify_error, query_to_json};
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct FunctionSource {
|
||||
// Function source id
|
||||
pub id: String,
|
||||
// Schema name
|
||||
pub schema: String,
|
||||
|
||||
// Function name
|
||||
pub function: String,
|
||||
|
||||
// An integer specifying the minimum zoom level
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub minzoom: Option<u8>,
|
||||
|
||||
// An integer specifying the maximum zoom level. MUST be >= minzoom
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub maxzoom: Option<u8>,
|
||||
|
||||
// The maximum extent of available map tiles. Bounds MUST define an area
|
||||
// covered by all zoom levels. The bounds are represented in WGS:84
|
||||
// latitude and longitude values, in the order left, bottom, right, top.
|
||||
// Values may be integers or floating point numbers.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub bounds: Option<Vec<f32>>,
|
||||
}
|
||||
|
||||
pub type FunctionSources = HashMap<String, Box<FunctionSource>>;
|
||||
@ -30,6 +49,18 @@ impl Source for FunctionSource {
|
||||
tilejson_builder.name(&self.id);
|
||||
tilejson_builder.tiles(vec![]);
|
||||
|
||||
if let Some(minzoom) = &self.minzoom {
|
||||
tilejson_builder.minzoom(*minzoom);
|
||||
};
|
||||
|
||||
if let Some(maxzoom) = &self.maxzoom {
|
||||
tilejson_builder.maxzoom(*maxzoom);
|
||||
};
|
||||
|
||||
if let Some(bounds) = &self.bounds {
|
||||
tilejson_builder.bounds(bounds.to_vec());
|
||||
};
|
||||
|
||||
Ok(tilejson_builder.finalize())
|
||||
}
|
||||
|
||||
@ -100,6 +131,9 @@ pub fn get_function_sources(conn: &mut Connection) -> Result<FunctionSources, io
|
||||
id: id.clone(),
|
||||
schema,
|
||||
function,
|
||||
minzoom: None,
|
||||
maxzoom: None,
|
||||
bounds: None,
|
||||
};
|
||||
|
||||
sources.insert(id, Box::new(source));
|
||||
|
@ -170,6 +170,17 @@ async fn get_composite_source_tile(
|
||||
.split(',')
|
||||
.filter_map(|source_id| table_sources.get(source_id))
|
||||
.map(|source| source.deref().clone())
|
||||
.filter(|source| {
|
||||
let gte_minzoom = source
|
||||
.minzoom
|
||||
.map_or(true, |minzoom| path.z >= minzoom.into());
|
||||
|
||||
let lte_maxzoom = source
|
||||
.maxzoom
|
||||
.map_or(true, |maxzoom| path.z <= maxzoom.into());
|
||||
|
||||
gte_minzoom && lte_maxzoom
|
||||
})
|
||||
.collect();
|
||||
|
||||
if sources.is_empty() {
|
||||
@ -295,7 +306,20 @@ async fn get_function_source_tile(
|
||||
.clone()
|
||||
.ok_or_else(|| error::ErrorNotFound("There is no function sources"))?;
|
||||
|
||||
let source = function_sources.get(&path.source_id).ok_or_else(|| {
|
||||
let source = function_sources
|
||||
.get(&path.source_id)
|
||||
.filter(|source| {
|
||||
let gte_minzoom = source
|
||||
.minzoom
|
||||
.map_or(true, |minzoom| path.z >= minzoom.into());
|
||||
|
||||
let lte_maxzoom = source
|
||||
.maxzoom
|
||||
.map_or(true, |maxzoom| path.z <= maxzoom.into());
|
||||
|
||||
gte_minzoom && lte_maxzoom
|
||||
})
|
||||
.ok_or_else(|| {
|
||||
error::ErrorNotFound(format!("Function source '{}' not found", path.source_id))
|
||||
})?;
|
||||
|
||||
|
@ -10,17 +10,57 @@ use crate::utils;
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct TableSource {
|
||||
// Table source id
|
||||
pub id: String,
|
||||
|
||||
// Table schema
|
||||
pub schema: String,
|
||||
|
||||
// Table name
|
||||
pub table: String,
|
||||
pub id_column: Option<String>,
|
||||
pub geometry_column: String,
|
||||
|
||||
// Geometry SRID
|
||||
pub srid: u32,
|
||||
|
||||
// Geometry column name
|
||||
pub geometry_column: String,
|
||||
|
||||
// Feature id column name
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub id_column: Option<String>,
|
||||
|
||||
// An integer specifying the minimum zoom level
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub minzoom: Option<u8>,
|
||||
|
||||
// An integer specifying the maximum zoom level. MUST be >= minzoom
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub maxzoom: Option<u8>,
|
||||
|
||||
// The maximum extent of available map tiles. Bounds MUST define an area
|
||||
// covered by all zoom levels. The bounds are represented in WGS:84
|
||||
// latitude and longitude values, in the order left, bottom, right, top.
|
||||
// Values may be integers or floating point numbers.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub bounds: Option<Vec<f32>>,
|
||||
|
||||
// Tile extent in tile coordinate space
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub extent: Option<u32>,
|
||||
|
||||
// Buffer distance in tile coordinate space to optionally clip geometries
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub buffer: Option<u32>,
|
||||
|
||||
// Boolean to control if geometries should be clipped or encoded as is
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub clip_geom: Option<bool>,
|
||||
|
||||
// Geometry type
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub geometry_type: Option<String>,
|
||||
|
||||
// List of columns, that should be encoded as tile properties
|
||||
pub properties: HashMap<String, String>,
|
||||
}
|
||||
|
||||
@ -93,6 +133,14 @@ impl Source for TableSource {
|
||||
tilejson_builder.scheme("xyz");
|
||||
tilejson_builder.name(&self.id);
|
||||
|
||||
if let Some(minzoom) = &self.minzoom {
|
||||
tilejson_builder.minzoom(*minzoom);
|
||||
};
|
||||
|
||||
if let Some(maxzoom) = &self.maxzoom {
|
||||
tilejson_builder.maxzoom(*maxzoom);
|
||||
};
|
||||
|
||||
if let Some(bounds) = &self.bounds {
|
||||
tilejson_builder.bounds(bounds.to_vec());
|
||||
};
|
||||
@ -168,6 +216,8 @@ pub fn get_table_sources(conn: &mut Connection) -> Result<TableSources, io::Erro
|
||||
id_column: None,
|
||||
geometry_column,
|
||||
bounds,
|
||||
minzoom: None,
|
||||
maxzoom: None,
|
||||
srid: srid as u32,
|
||||
extent: Some(DEFAULT_EXTENT),
|
||||
buffer: Some(DEFAULT_BUFFER),
|
||||
|
@ -20,28 +20,52 @@ watch: false
|
||||
# Trust invalid certificates. This introduces significant vulnerabilities, and should only be used as a last resort.
|
||||
danger_accept_invalid_certs: false
|
||||
|
||||
# associative arrays of table sources
|
||||
# Associative arrays of table sources
|
||||
table_sources:
|
||||
public.table_source:
|
||||
# table source id
|
||||
# Table source id (required)
|
||||
id: public.table_source
|
||||
# table schema
|
||||
|
||||
# Table schema (required)
|
||||
schema: public
|
||||
# table name
|
||||
|
||||
# Table name (required)
|
||||
table: table_source
|
||||
# geometry column name
|
||||
geometry_column: geom
|
||||
# geometry srid
|
||||
|
||||
# Geometry SRID (required)
|
||||
srid: 4326
|
||||
# tile extent in tile coordinate space
|
||||
|
||||
# Geometry column name (required)
|
||||
geometry_column: geom
|
||||
|
||||
# Feature id column name
|
||||
id_column: ~
|
||||
|
||||
# An integer specifying the minimum zoom level
|
||||
minzoom: 0
|
||||
|
||||
# An integer specifying the maximum zoom level. MUST be >= minzoom
|
||||
maxzoom: 30
|
||||
|
||||
# The maximum extent of available map tiles. Bounds MUST define an area
|
||||
# covered by all zoom levels. The bounds are represented in WGS:84
|
||||
# latitude and longitude values, in the order left, bottom, right, top.
|
||||
# Values may be integers or floating point numbers.
|
||||
bounds: [-180.0, -90.0, 180.0, 90.0]
|
||||
|
||||
# Tile extent in tile coordinate space
|
||||
extent: 4096
|
||||
# buffer distance in tile coordinate space to optionally clip geometries
|
||||
|
||||
# Buffer distance in tile coordinate space to optionally clip geometries
|
||||
buffer: 64
|
||||
# boolean to control if geometries should be clipped or encoded as is
|
||||
|
||||
# Boolean to control if geometries should be clipped or encoded as is
|
||||
clip_geom: true
|
||||
# geometry type
|
||||
|
||||
# Geometry type
|
||||
geometry_type: GEOMETRY
|
||||
# list of columns, that should be encoded as tile properties
|
||||
|
||||
# List of columns, that should be encoded as tile properties (required)
|
||||
properties:
|
||||
gid: int4
|
||||
|
||||
@ -49,6 +73,9 @@ table_sources:
|
||||
id: public.points1
|
||||
schema: public
|
||||
table: points1
|
||||
minzoom: 0
|
||||
maxzoom: 30
|
||||
bounds: [-180.0, -90.0, 180.0, 90.0]
|
||||
id_column: ~
|
||||
geometry_column: geom
|
||||
srid: 4326
|
||||
@ -63,6 +90,9 @@ table_sources:
|
||||
id: public.points2
|
||||
schema: public
|
||||
table: points2
|
||||
minzoom: 0
|
||||
maxzoom: 30
|
||||
bounds: [-180.0, -90.0, 180.0, 90.0]
|
||||
id_column: ~
|
||||
geometry_column: geom
|
||||
srid: 4326
|
||||
@ -77,6 +107,9 @@ table_sources:
|
||||
id: public.points3857
|
||||
schema: public
|
||||
table: points3857
|
||||
minzoom: 0
|
||||
maxzoom: 30
|
||||
bounds: [-180.0, -90.0, 180.0, 90.0]
|
||||
id_column: ~
|
||||
geometry_column: geom
|
||||
srid: 3857
|
||||
@ -87,17 +120,34 @@ table_sources:
|
||||
properties:
|
||||
gid: int4
|
||||
|
||||
# associative arrays of function sources
|
||||
# Associative arrays of function sources
|
||||
function_sources:
|
||||
public.function_source:
|
||||
# function source id
|
||||
# Function source id (required)
|
||||
id: public.function_source
|
||||
# schema name
|
||||
|
||||
# Schema name (required)
|
||||
schema: public
|
||||
# function name
|
||||
|
||||
# Function name (required)
|
||||
function: function_source
|
||||
|
||||
# An integer specifying the minimum zoom level
|
||||
minzoom: 0
|
||||
|
||||
# An integer specifying the maximum zoom level. MUST be >= minzoom
|
||||
maxzoom: 30
|
||||
|
||||
# The maximum extent of available map tiles. Bounds MUST define an area
|
||||
# covered by all zoom levels. The bounds are represented in WGS:84
|
||||
# latitude and longitude values, in the order left, bottom, right, top.
|
||||
# Values may be integers or floating point numbers.
|
||||
bounds: [-180.0, -90.0, 180.0, 90.0]
|
||||
|
||||
public.function_source_query_params:
|
||||
id: public.function_source_query_params
|
||||
schema: public
|
||||
function: function_source_query_params
|
||||
minzoom: 0
|
||||
maxzoom: 30
|
||||
bounds: [-180.0, -90.0, 180.0, 90.0]
|
||||
|
@ -31,8 +31,8 @@
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
border-radius: 3px;
|
||||
width: 120px;
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
@ -112,32 +112,42 @@
|
||||
case 'MULTISURFACE':
|
||||
return 'fill';
|
||||
default:
|
||||
throw new Error(`Unknown geometry_type ${source.geometry_type}`);
|
||||
return 'circle';
|
||||
}
|
||||
}
|
||||
|
||||
map.on('load', function () {
|
||||
fetch('http://0.0.0.0:3000/index.json')
|
||||
.then((r) => r.json())
|
||||
.then((sources) => {
|
||||
map.on('load', async function () {
|
||||
const table_sources = await fetch(
|
||||
'http://0.0.0.0:3000/index.json'
|
||||
).then((r) => r.json());
|
||||
|
||||
const function_sources = await fetch(
|
||||
'http://0.0.0.0:3000/rpc/index.json'
|
||||
).then((r) => r.json());
|
||||
|
||||
const sources = Object.values(table_sources).concat(
|
||||
Object.values(function_sources)
|
||||
);
|
||||
|
||||
// Set up the corresponding toggle button for each layer.
|
||||
for (const sourceId of Object.keys(sources).sort()) {
|
||||
for (const source of sources) {
|
||||
// Skip layers that already have a button set up.
|
||||
if (document.getElementById(sourceId)) {
|
||||
if (document.getElementById(source.id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const source = sources[sourceId];
|
||||
const layerType = geometryTypeToLayerType(source.geometry_type);
|
||||
|
||||
map.addLayer({
|
||||
id: sourceId,
|
||||
id: source.id,
|
||||
type: layerType,
|
||||
source: {
|
||||
type: 'vector',
|
||||
url: `http://0.0.0.0:3000/${sourceId}.json`
|
||||
url: source.hasOwnProperty('table')
|
||||
? `http://0.0.0.0:3000/${source.id}.json`
|
||||
: `http://0.0.0.0:3000/rpc/${source.id}.json`
|
||||
},
|
||||
'source-layer': sourceId,
|
||||
'source-layer': source.id,
|
||||
layout: {
|
||||
visibility: 'none'
|
||||
},
|
||||
@ -148,10 +158,10 @@
|
||||
|
||||
// Create a link.
|
||||
const link = document.createElement('a');
|
||||
link.id = sourceId;
|
||||
link.id = source.id;
|
||||
link.href = '#';
|
||||
link.textContent = sourceId;
|
||||
link.title = sourceId;
|
||||
link.textContent = source.id;
|
||||
link.title = source.id;
|
||||
|
||||
// Show or hide layer when the toggle is clicked.
|
||||
link.onclick = function (e) {
|
||||
@ -178,7 +188,6 @@
|
||||
layers.appendChild(link);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,11 +1,14 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
extern crate log;
|
||||
|
||||
use actix_web::{http, test, App};
|
||||
use tilejson::TileJSON;
|
||||
|
||||
use martin::dev::{mock_function_sources, mock_state, mock_table_sources};
|
||||
use martin::function_source::FunctionSources;
|
||||
use martin::dev;
|
||||
use martin::function_source::{FunctionSource, FunctionSources};
|
||||
use martin::server::router;
|
||||
use martin::table_source::TableSources;
|
||||
use martin::table_source::{TableSource, TableSources};
|
||||
|
||||
fn init() {
|
||||
let _ = env_logger::builder().is_test(true).try_init();
|
||||
@ -15,7 +18,7 @@ fn init() {
|
||||
async fn test_get_table_sources_ok() {
|
||||
init();
|
||||
|
||||
let state = mock_state(mock_table_sources(), None, false);
|
||||
let state = dev::mock_state(Some(dev::mock_default_table_sources()), None, false);
|
||||
let mut app = test::init_service(App::new().data(state).configure(router)).await;
|
||||
|
||||
let req = test::TestRequest::get().uri("/index.json").to_request();
|
||||
@ -31,7 +34,7 @@ async fn test_get_table_sources_ok() {
|
||||
async fn test_get_table_sources_watch_mode_ok() {
|
||||
init();
|
||||
|
||||
let state = mock_state(mock_table_sources(), None, true);
|
||||
let state = dev::mock_state(Some(dev::mock_default_table_sources()), None, true);
|
||||
let mut app = test::init_service(App::new().data(state).configure(router)).await;
|
||||
|
||||
let req = test::TestRequest::get().uri("/index.json").to_request();
|
||||
@ -47,7 +50,28 @@ async fn test_get_table_sources_watch_mode_ok() {
|
||||
async fn test_get_table_source_ok() {
|
||||
init();
|
||||
|
||||
let state = mock_state(mock_table_sources(), None, false);
|
||||
let table_source = TableSource {
|
||||
id: "public.table_source".to_owned(),
|
||||
schema: "public".to_owned(),
|
||||
table: "table_source".to_owned(),
|
||||
id_column: None,
|
||||
geometry_column: "geom".to_owned(),
|
||||
bounds: Some(vec![-180.0, -90.0, 180.0, 90.0]),
|
||||
minzoom: Some(0),
|
||||
maxzoom: Some(30),
|
||||
srid: 4326,
|
||||
extent: Some(4096),
|
||||
buffer: Some(64),
|
||||
clip_geom: Some(true),
|
||||
geometry_type: None,
|
||||
properties: HashMap::new(),
|
||||
};
|
||||
|
||||
let state = dev::mock_state(
|
||||
Some(dev::mock_table_sources(vec![table_source])),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
let mut app = test::init_service(App::new().data(state).configure(router)).await;
|
||||
|
||||
let req = test::TestRequest::get()
|
||||
@ -61,15 +85,25 @@ async fn test_get_table_source_ok() {
|
||||
.uri("/public.table_source.json")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
let result: TileJSON = test::read_response_json(&mut app, req).await;
|
||||
|
||||
println!("{:?}", result);
|
||||
|
||||
assert_eq!(result.name, Some(String::from("public.table_source")));
|
||||
assert_eq!(
|
||||
result.tiles,
|
||||
vec!["http://localhost:8080/public.table_source/{z}/{x}/{y}.pbf"]
|
||||
);
|
||||
assert_eq!(result.minzoom, Some(0));
|
||||
assert_eq!(result.maxzoom, Some(30));
|
||||
assert_eq!(result.bounds, Some(vec![-180.0, -90.0, 180.0, 90.0]));
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_get_table_source_tile_ok() {
|
||||
init();
|
||||
|
||||
let state = mock_state(mock_table_sources(), None, false);
|
||||
let state = dev::mock_state(Some(dev::mock_default_table_sources()), None, false);
|
||||
let mut app = test::init_service(App::new().data(state).configure(router)).await;
|
||||
|
||||
let req = test::TestRequest::get()
|
||||
@ -87,11 +121,193 @@ async fn test_get_table_source_tile_ok() {
|
||||
assert!(response.status().is_success());
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_get_table_source_tile_minmax_zoom_ok() {
|
||||
init();
|
||||
|
||||
let points1 = TableSource {
|
||||
id: "public.points1".to_owned(),
|
||||
schema: "public".to_owned(),
|
||||
table: "points1".to_owned(),
|
||||
id_column: None,
|
||||
geometry_column: "geom".to_owned(),
|
||||
bounds: Some(vec![-180.0, -90.0, 180.0, 90.0]),
|
||||
minzoom: Some(6),
|
||||
maxzoom: Some(12),
|
||||
srid: 4326,
|
||||
extent: Some(4096),
|
||||
buffer: Some(64),
|
||||
clip_geom: Some(true),
|
||||
geometry_type: None,
|
||||
properties: HashMap::new(),
|
||||
};
|
||||
|
||||
let points2 = TableSource {
|
||||
id: "public.points2".to_owned(),
|
||||
schema: "public".to_owned(),
|
||||
table: "points2".to_owned(),
|
||||
id_column: None,
|
||||
geometry_column: "geom".to_owned(),
|
||||
bounds: Some(vec![-180.0, -90.0, 180.0, 90.0]),
|
||||
minzoom: None,
|
||||
maxzoom: None,
|
||||
srid: 4326,
|
||||
extent: Some(4096),
|
||||
buffer: Some(64),
|
||||
clip_geom: Some(true),
|
||||
geometry_type: None,
|
||||
properties: HashMap::new(),
|
||||
};
|
||||
|
||||
let points3857 = TableSource {
|
||||
id: "public.points3857".to_owned(),
|
||||
schema: "public".to_owned(),
|
||||
table: "points3857".to_owned(),
|
||||
id_column: None,
|
||||
geometry_column: "geom".to_owned(),
|
||||
bounds: Some(vec![-180.0, -90.0, 180.0, 90.0]),
|
||||
minzoom: Some(6),
|
||||
maxzoom: None,
|
||||
srid: 4326,
|
||||
extent: Some(4096),
|
||||
buffer: Some(64),
|
||||
clip_geom: Some(true),
|
||||
geometry_type: None,
|
||||
properties: HashMap::new(),
|
||||
};
|
||||
|
||||
let table_source = TableSource {
|
||||
id: "public.table_source".to_owned(),
|
||||
schema: "public".to_owned(),
|
||||
table: "table_source".to_owned(),
|
||||
id_column: None,
|
||||
geometry_column: "geom".to_owned(),
|
||||
bounds: Some(vec![-180.0, -90.0, 180.0, 90.0]),
|
||||
minzoom: None,
|
||||
maxzoom: Some(6),
|
||||
srid: 4326,
|
||||
extent: Some(4096),
|
||||
buffer: Some(64),
|
||||
clip_geom: Some(true),
|
||||
geometry_type: None,
|
||||
properties: HashMap::new(),
|
||||
};
|
||||
|
||||
let state = dev::mock_state(
|
||||
Some(dev::mock_table_sources(vec![
|
||||
points1,
|
||||
points2,
|
||||
points3857,
|
||||
table_source,
|
||||
])),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
|
||||
let mut app = test::init_service(App::new().data(state).configure(router)).await;
|
||||
|
||||
// zoom = 0 (nothing)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/public.points1/0/0/0.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert_eq!(response.status(), http::StatusCode::NOT_FOUND);
|
||||
|
||||
// zoom = 6 (public.points1)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/public.points1/6/38/20.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
|
||||
// zoom = 12 (public.points1)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/public.points1/12/2476/1280.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
|
||||
// zoom = 13 (nothing)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/public.points1/13/4952/2560.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert_eq!(response.status(), http::StatusCode::NOT_FOUND);
|
||||
|
||||
// zoom = 0 (public.points2)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/public.points2/0/0/0.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
|
||||
// zoom = 6 (public.points2)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/public.points2/6/38/20.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
|
||||
// zoom = 12 (public.points2)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/public.points2/12/2476/1280.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
|
||||
// zoom = 13 (public.points2)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/public.points2/13/4952/2560.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
|
||||
// zoom = 0 (nothing)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/public.points3857/0/0/0.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert_eq!(response.status(), http::StatusCode::NOT_FOUND);
|
||||
|
||||
// zoom = 12 (public.points3857)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/public.points3857/12/2476/1280.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
|
||||
// zoom = 0 (public.table_source)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/public.table_source/0/0/0.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
|
||||
// zoom = 12 (nothing)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/public.table_source/12/2476/1280.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert_eq!(response.status(), http::StatusCode::NOT_FOUND);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_get_composite_source_ok() {
|
||||
init();
|
||||
|
||||
let state = mock_state(mock_table_sources(), None, false);
|
||||
let state = dev::mock_state(Some(dev::mock_default_table_sources()), None, false);
|
||||
let mut app = test::init_service(App::new().data(state).configure(router)).await;
|
||||
|
||||
let req = test::TestRequest::get()
|
||||
@ -113,7 +329,7 @@ async fn test_get_composite_source_ok() {
|
||||
async fn test_get_composite_source_tile_ok() {
|
||||
init();
|
||||
|
||||
let state = mock_state(mock_table_sources(), None, false);
|
||||
let state = dev::mock_state(Some(dev::mock_default_table_sources()), None, false);
|
||||
let mut app = test::init_service(App::new().data(state).configure(router)).await;
|
||||
|
||||
let req = test::TestRequest::get()
|
||||
@ -131,11 +347,116 @@ async fn test_get_composite_source_tile_ok() {
|
||||
assert!(response.status().is_success());
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_get_composite_source_tile_minmax_zoom_ok() {
|
||||
init();
|
||||
|
||||
let public_points1 = TableSource {
|
||||
id: "public.points1".to_owned(),
|
||||
schema: "public".to_owned(),
|
||||
table: "points1".to_owned(),
|
||||
id_column: None,
|
||||
geometry_column: "geom".to_owned(),
|
||||
bounds: Some(vec![-180.0, -90.0, 180.0, 90.0]),
|
||||
minzoom: Some(6),
|
||||
maxzoom: Some(13),
|
||||
srid: 4326,
|
||||
extent: Some(4096),
|
||||
buffer: Some(64),
|
||||
clip_geom: Some(true),
|
||||
geometry_type: None,
|
||||
properties: HashMap::new(),
|
||||
};
|
||||
|
||||
let public_points2 = TableSource {
|
||||
id: "public.points2".to_owned(),
|
||||
schema: "public".to_owned(),
|
||||
table: "points2".to_owned(),
|
||||
id_column: None,
|
||||
geometry_column: "geom".to_owned(),
|
||||
bounds: Some(vec![-180.0, -90.0, 180.0, 90.0]),
|
||||
minzoom: Some(13),
|
||||
maxzoom: Some(20),
|
||||
srid: 4326,
|
||||
extent: Some(4096),
|
||||
buffer: Some(64),
|
||||
clip_geom: Some(true),
|
||||
geometry_type: None,
|
||||
properties: HashMap::new(),
|
||||
};
|
||||
|
||||
let state = dev::mock_state(
|
||||
Some(dev::mock_table_sources(vec![
|
||||
public_points1,
|
||||
public_points2,
|
||||
])),
|
||||
None,
|
||||
false,
|
||||
);
|
||||
let mut app = test::init_service(App::new().data(state).configure(router)).await;
|
||||
|
||||
// zoom = 0 (nothing)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/public.points1,public.points2/0/0/0.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert_eq!(response.status(), http::StatusCode::NOT_FOUND);
|
||||
|
||||
// zoom = 6 (public.points1)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/public.points1,public.points2/6/38/20.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
|
||||
// zoom = 12 (public.points1)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/public.points1,public.points2/12/2476/1280.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
|
||||
// zoom = 13 (public.points1, public.points2)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/public.points1,public.points2/13/4952/2560.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
|
||||
// zoom = 14 (public.points2)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/public.points1,public.points2/14/9904/5121.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
|
||||
// zoom = 20 (public.points2)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/public.points1,public.points2/20/633856/327787.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
|
||||
// zoom = 21 (nothing)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/public.points1,public.points2/21/1267712/655574.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert_eq!(response.status(), http::StatusCode::NOT_FOUND);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_get_function_sources_ok() {
|
||||
init();
|
||||
|
||||
let state = mock_state(None, mock_function_sources(), false);
|
||||
let state = dev::mock_state(None, Some(dev::mock_default_function_sources()), false);
|
||||
let mut app = test::init_service(App::new().data(state).configure(router)).await;
|
||||
|
||||
let req = test::TestRequest::get().uri("/rpc/index.json").to_request();
|
||||
@ -151,7 +472,7 @@ async fn test_get_function_sources_ok() {
|
||||
async fn test_get_function_sources_watch_mode_ok() {
|
||||
init();
|
||||
|
||||
let state = mock_state(None, mock_function_sources(), true);
|
||||
let state = dev::mock_state(None, Some(dev::mock_default_function_sources()), true);
|
||||
let mut app = test::init_service(App::new().data(state).configure(router)).await;
|
||||
|
||||
let req = test::TestRequest::get().uri("/rpc/index.json").to_request();
|
||||
@ -167,7 +488,7 @@ async fn test_get_function_sources_watch_mode_ok() {
|
||||
async fn test_get_function_source_ok() {
|
||||
init();
|
||||
|
||||
let state = mock_state(None, mock_function_sources(), false);
|
||||
let state = dev::mock_state(None, Some(dev::mock_default_function_sources()), false);
|
||||
let mut app = test::init_service(App::new().data(state).configure(router)).await;
|
||||
|
||||
let req = test::TestRequest::get()
|
||||
@ -189,7 +510,7 @@ async fn test_get_function_source_ok() {
|
||||
async fn test_get_function_source_tile_ok() {
|
||||
init();
|
||||
|
||||
let state = mock_state(None, mock_function_sources(), false);
|
||||
let state = dev::mock_state(None, Some(dev::mock_default_function_sources()), false);
|
||||
let mut app = test::init_service(App::new().data(state).configure(router)).await;
|
||||
|
||||
let req = test::TestRequest::get()
|
||||
@ -200,11 +521,109 @@ async fn test_get_function_source_tile_ok() {
|
||||
assert!(response.status().is_success());
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_get_function_source_tile_minmax_zoom_ok() {
|
||||
init();
|
||||
|
||||
let function_source1 = FunctionSource {
|
||||
id: "public.function_source1".to_owned(),
|
||||
schema: "public".to_owned(),
|
||||
function: "function_source".to_owned(),
|
||||
minzoom: None,
|
||||
maxzoom: None,
|
||||
bounds: Some(vec![-180.0, -90.0, 180.0, 90.0]),
|
||||
};
|
||||
|
||||
let function_source2 = FunctionSource {
|
||||
id: "public.function_source2".to_owned(),
|
||||
schema: "public".to_owned(),
|
||||
function: "function_source".to_owned(),
|
||||
minzoom: Some(6),
|
||||
maxzoom: Some(12),
|
||||
bounds: Some(vec![-180.0, -90.0, 180.0, 90.0]),
|
||||
};
|
||||
|
||||
let state = dev::mock_state(
|
||||
None,
|
||||
Some(dev::mock_function_sources(vec![
|
||||
function_source1,
|
||||
function_source2,
|
||||
])),
|
||||
false,
|
||||
);
|
||||
|
||||
let mut app = test::init_service(App::new().data(state).configure(router)).await;
|
||||
|
||||
// zoom = 0 (public.function_source1)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/rpc/public.function_source1/0/0/0.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
|
||||
// zoom = 6 (public.function_source1)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/rpc/public.function_source1/6/38/20.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
|
||||
// zoom = 12 (public.function_source1)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/rpc/public.function_source1/12/2476/1280.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
|
||||
// zoom = 13 (public.function_source1)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/rpc/public.function_source1/13/4952/2560.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
|
||||
// zoom = 0 (nothing)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/rpc/public.function_source2/0/0/0.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert_eq!(response.status(), http::StatusCode::NOT_FOUND);
|
||||
|
||||
// zoom = 6 (public.function_source2)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/rpc/public.function_source2/6/38/20.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
|
||||
// zoom = 12 (public.function_source2)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/rpc/public.function_source2/12/2476/1280.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert!(response.status().is_success());
|
||||
|
||||
// zoom = 13 (nothing)
|
||||
let req = test::TestRequest::get()
|
||||
.uri("/rpc/public.function_source2/13/4952/2560.pbf")
|
||||
.to_request();
|
||||
|
||||
let response = test::call_service(&mut app, req).await;
|
||||
assert_eq!(response.status(), http::StatusCode::NOT_FOUND);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_get_function_source_query_params_ok() {
|
||||
init();
|
||||
|
||||
let state = mock_state(None, mock_function_sources(), false);
|
||||
let state = dev::mock_state(None, Some(dev::mock_default_function_sources()), false);
|
||||
let mut app = test::init_service(App::new().data(state).configure(router)).await;
|
||||
|
||||
let req = test::TestRequest::get()
|
||||
@ -227,7 +646,7 @@ async fn test_get_function_source_query_params_ok() {
|
||||
async fn test_get_health_returns_ok() {
|
||||
init();
|
||||
|
||||
let state = mock_state(None, mock_function_sources(), false);
|
||||
let state = dev::mock_state(None, Some(dev::mock_default_function_sources()), false);
|
||||
let mut app = test::init_service(App::new().data(state).configure(router)).await;
|
||||
|
||||
let req = test::TestRequest::get().uri("/healthz").to_request();
|
||||
|
Loading…
Reference in New Issue
Block a user