mirror of
https://github.com/maplibre/martin.git
synced 2024-12-24 07:22:52 +03:00
built-in tilebbox
This commit is contained in:
parent
6e68e9838c
commit
e41ca87439
@ -1,37 +0,0 @@
|
|||||||
/* https://github.com/mapbox/postgis-vt-util/blob/master/postgis-vt-util.sql */
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
### 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$;
|
|
@ -104,9 +104,9 @@ pub fn tile(req: &mut Request, caps: Captures) -> IronResult<Response> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let z: &i32 = &caps["z"].parse().unwrap();
|
let z: &u32 = &caps["z"].parse().unwrap();
|
||||||
let x: &i32 = &caps["x"].parse().unwrap();
|
let x: &u32 = &caps["x"].parse().unwrap();
|
||||||
let y: &i32 = &caps["y"].parse().unwrap();
|
let y: &u32 = &caps["y"].parse().unwrap();
|
||||||
|
|
||||||
let filter = get_filter(req).cloned();
|
let filter = get_filter(req).cloned();
|
||||||
let condition = match filter {
|
let condition = match filter {
|
||||||
|
@ -5,44 +5,61 @@ use std::error::Error;
|
|||||||
|
|
||||||
use super::db::PostgresConnection;
|
use super::db::PostgresConnection;
|
||||||
|
|
||||||
|
// https://github.com/mapbox/postgis-vt-util/blob/master/src/TileBBox.sql
|
||||||
|
fn tilebbox(z: u32, x: u32, y: u32) -> String {
|
||||||
|
let max = 20037508.34;
|
||||||
|
let res = (max * 2.0) / (2_i32.pow(z) as f64);
|
||||||
|
|
||||||
|
let xmin = -max + (x as f64 * res);
|
||||||
|
let ymin = max - (y as f64 * res);
|
||||||
|
let xmax = -max + (x as f64 * res) + res;
|
||||||
|
let ymax = max - (y as f64 * res) - res;
|
||||||
|
|
||||||
|
format!("ST_MakeEnvelope({0}, {1}, {2}, {3}, 3857)", xmin, ymin, xmax, ymax)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transform(geometry: String, srid: u32) -> String {
|
||||||
|
if srid == 3857 {
|
||||||
|
geometry
|
||||||
|
} else {
|
||||||
|
format!("ST_Transform({0}, 3857)", geometry)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Debug)]
|
#[derive(Serialize, Debug)]
|
||||||
pub struct Tileset {
|
pub struct Tileset {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
schema: String,
|
schema: String,
|
||||||
pub table: String,
|
pub table: String,
|
||||||
geometry_column: String,
|
geometry_column: String,
|
||||||
srid: i32,
|
srid: u32,
|
||||||
extent: i32,
|
extent: u32,
|
||||||
buffer: i32,
|
buffer: u32,
|
||||||
clip_geom: bool,
|
clip_geom: bool,
|
||||||
geometry_type: String,
|
geometry_type: String,
|
||||||
properties: HashMap<String, String>
|
properties: HashMap<String, String>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tileset {
|
impl Tileset {
|
||||||
pub fn get_query(&self, condition: Option<String>) -> String {
|
pub fn get_query(&self, z: u32, x: u32, y: u32, condition: Option<String>) -> String {
|
||||||
let keys: Vec<String> = self.properties.keys().map(|key| key.to_string()).collect();
|
let keys: Vec<String> = self.properties.keys().map(|key| key.to_string()).collect();
|
||||||
let columns = keys.join(",");
|
let columns = keys.join(",");
|
||||||
|
|
||||||
let transformed_geometry = if self.srid == 3857 {
|
|
||||||
self.geometry_column.clone()
|
|
||||||
} else {
|
|
||||||
format!("ST_Transform({0}, 3857)", self.geometry_column)
|
|
||||||
};
|
|
||||||
|
|
||||||
let query = format!(
|
let query = format!(
|
||||||
"SELECT ST_AsMVT(tile, '{0}.{1}', {4}, 'geom') FROM (\
|
"SELECT ST_AsMVT(tile, '{0}.{1}', {4}, 'geom') FROM (\
|
||||||
SELECT \
|
SELECT \
|
||||||
ST_AsMVTGeom({2}, TileBBox($1, $2, $3, 3857), {4}, {5}, {6}) AS geom, {3} \
|
ST_AsMVTGeom({2}, {3}, {4}, {5}, {6}) AS geom, \
|
||||||
FROM {0}.{1} {7}\
|
{7} \
|
||||||
|
FROM {0}.{1} {8}\
|
||||||
) AS tile;",
|
) AS tile;",
|
||||||
self.schema,
|
self.schema,
|
||||||
self.table,
|
self.table,
|
||||||
transformed_geometry,
|
transform(self.geometry_column.clone(), self.srid),
|
||||||
columns,
|
tilebbox(z, x, y),
|
||||||
self.extent,
|
self.extent,
|
||||||
self.buffer,
|
self.buffer,
|
||||||
self.clip_geom,
|
self.clip_geom,
|
||||||
|
columns,
|
||||||
condition.unwrap_or("".to_string())
|
condition.unwrap_or("".to_string())
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -97,7 +114,7 @@ pub fn get_tilesets(conn: PostgresConnection) -> Result<HashMap<String, Tileset>
|
|||||||
schema: schema,
|
schema: schema,
|
||||||
table: table,
|
table: table,
|
||||||
geometry_column: geometry_column,
|
geometry_column: geometry_column,
|
||||||
srid: srid,
|
srid: srid as u32,
|
||||||
extent: default_extent,
|
extent: default_extent,
|
||||||
buffer: default_buffer,
|
buffer: default_buffer,
|
||||||
clip_geom: default_clip_geom,
|
clip_geom: default_clip_geom,
|
||||||
@ -111,8 +128,10 @@ pub fn get_tilesets(conn: PostgresConnection) -> Result<HashMap<String, Tileset>
|
|||||||
Ok(tilesets)
|
Ok(tilesets)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_tile<'a>(conn: PostgresConnection, tileset: &Tileset, z: &i32, x: &i32, y: &i32, condition: Option<String>) -> Result<Vec<u8>, Box<Error>> {
|
pub fn get_tile<'a>(conn: PostgresConnection, tileset: &Tileset, z: &u32, x: &u32, y: &u32, condition: Option<String>) -> Result<Vec<u8>, Box<Error>> {
|
||||||
let rows = try!(conn.query(&tileset.get_query(condition), &[&z, &x, &y]));
|
let query = tileset.get_query(z.clone(), x.clone(), y.clone(), condition);
|
||||||
|
|
||||||
|
let rows = try!(conn.query(&query, &[]));
|
||||||
let tile = rows.get(0).get("st_asmvt");
|
let tile = rows.get(0).get("st_asmvt");
|
||||||
Ok(tile)
|
Ok(tile)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user