server: delint, rm dead code, optimize
This commit is contained in:
parent
3fb1083a7b
commit
2402721226
|
@ -1,16 +1,12 @@
|
|||
use std::collections::HashSet;
|
||||
use std::io::Cursor;
|
||||
use gotham::{
|
||||
helpers::http::response::create_response,
|
||||
hyper::{Body, Response},
|
||||
state::{FromState, State},
|
||||
};
|
||||
use geo::{Rect, LineString};
|
||||
use serde::Deserialize;
|
||||
use mime::{APPLICATION_JSON, IMAGE_PNG};
|
||||
use mime::APPLICATION_JSON;
|
||||
use http::StatusCode;
|
||||
use cairo::{ImageSurface, Context};
|
||||
use crate::{AppState, AreaExtractor, PointExtractor};
|
||||
use crate::{AppState, PointExtractor};
|
||||
|
||||
|
||||
pub fn get_details(state: State) -> (State, Response<Body>) {
|
||||
|
@ -38,123 +34,3 @@ pub fn get_details(state: State) -> (State, Response<Body>) {
|
|||
let res = create_response(&state, StatusCode::OK, APPLICATION_JSON, body);
|
||||
(state, res)
|
||||
}
|
||||
|
||||
pub fn get_heatmap(state: State) -> (State, Response<Body>) {
|
||||
let pe = AreaExtractor::borrow_from(&state);
|
||||
let app_state = AppState::borrow_from(&state);
|
||||
let result = app_state.with_db(|db| {
|
||||
db.query("SELECT path(coords), src, attrs FROM areas WHERE box(coords) ?# $1::box", &[
|
||||
&pe.to_rect()
|
||||
]).unwrap()
|
||||
});
|
||||
|
||||
const TILE_MAX: i32 = 256;
|
||||
let (w, h) = if pe.w() > pe.h() {
|
||||
(TILE_MAX, (TILE_MAX as f64 * pe.h() / pe.w()) as i32)
|
||||
} else {
|
||||
(((TILE_MAX as f64 * pe.w() / pe.h()) as i32), TILE_MAX)
|
||||
};
|
||||
println!("{}x{}", w, h);
|
||||
let s = ImageSurface::create(cairo::Format::ARgb32, w, h).unwrap();
|
||||
let ctx = Context::new(&s).unwrap();
|
||||
ctx.set_antialias(cairo::Antialias::Fast);
|
||||
|
||||
for row in result {
|
||||
// let src: String = row.get(1);
|
||||
let attrs: serde_json::Value = row.get(2);
|
||||
// println!("src: {:?} attrs: {:?}", src, attrs);
|
||||
|
||||
let coords: LineString<f64> = row.get(0);
|
||||
let points = coords.into_points();
|
||||
// println!("{} ps", points.len());
|
||||
ctx.move_to((points[0].x() - pe.x1) * (w as f64) / pe.w(), (pe.y2 - points[0].y()) * (h as f64) / pe.h());
|
||||
for point in &points[1..] {
|
||||
ctx.line_to((point.x() - pe.x1) * (w as f64) / pe.w(), (pe.y2 - point.y()) * (h as f64) / pe.h());
|
||||
}
|
||||
ctx.close_path();
|
||||
|
||||
let (r, g, b, a) = area_color(&attrs);
|
||||
ctx.set_source_rgba(r, g, b, a);
|
||||
ctx.fill().unwrap();
|
||||
}
|
||||
|
||||
let mut buffer = Cursor::new(vec![]);
|
||||
s.write_to_png(&mut buffer).unwrap();
|
||||
let res = create_response(&state, StatusCode::OK, IMAGE_PNG, buffer.into_inner());
|
||||
(state, res)
|
||||
}
|
||||
|
||||
// 0.0: green, 0.5: yellow, 1.0: red
|
||||
fn hue(mut x: f64) -> (f64, f64, f64) {
|
||||
x = x.max(0.).min(1.);
|
||||
|
||||
if x < 0.5 {
|
||||
(2.0 * x, 1.0, 0.0)
|
||||
} else {
|
||||
(1.0, 2.0 - 2.0 * x, 0.0)
|
||||
}
|
||||
}
|
||||
|
||||
fn area_color(attrs: &serde_json::Value) -> (f64, f64, f64, f64) {
|
||||
if let serde_json::Value::Object(attrs) = attrs {
|
||||
// bodenquali
|
||||
if let Some(serde_json::Value::Number(q)) = attrs.get("bodenqualitaet") {
|
||||
if let Some(q) = q.as_f64() {
|
||||
let (r, g, b) = hue(1.0 - q / 6.0);
|
||||
return (r, g, b, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(serde_json::Value::Number(q)) = attrs.get("wasserspeicher") {
|
||||
if let Some(mut q) = q.as_f64() {
|
||||
if q > 10. {
|
||||
q /= 10.;
|
||||
}
|
||||
let (r, g, b) = hue((5. - q) / 4.);
|
||||
return (r, g, b, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
// wasserhaushalt
|
||||
if let Some(serde_json::Value::String(typ)) = attrs.get("gebietstyp") {
|
||||
match typ.as_str() {
|
||||
"Gewässer" => return (0., 1., 0., 0.2),
|
||||
"versickerungsdominiert" => return (0., 1., 0., 0.1),
|
||||
"verdunstungs- und versickerungsbestimmt" => return (0.5, 1., 0., 0.05),
|
||||
"verdunstungsdominiert" => return (1.0, 1.0, 0., 0.1),
|
||||
"verdunstungs- und abflussbestimmt" => return (1.0, 0.5, 0., 0.05),
|
||||
"abflussdominiert" => return (1., 0., 0., 0.1),
|
||||
"ausgewogen" => return (0., 0., 0., 0.),
|
||||
_ => println!("typ: {}", typ),
|
||||
}
|
||||
}
|
||||
|
||||
// boden_fkt
|
||||
let mut x = 0.0;
|
||||
let mut a = 0.0;
|
||||
if let Some(serde_json::Value::Number(q)) = attrs.get("schutt") {
|
||||
if let Some(q) = q.as_f64() {
|
||||
if q > 1. {
|
||||
println!("schutt: {}", q);
|
||||
}
|
||||
x += q / 1.5;
|
||||
a += 0.1;
|
||||
}
|
||||
}
|
||||
if let Some(serde_json::Value::Number(q)) = attrs.get("versiegelung") {
|
||||
if let Some(q) = q.as_f64() {
|
||||
if q > 5. {
|
||||
println!("versiegelung: {}", q);
|
||||
}
|
||||
x += q / 5.0;
|
||||
a += 0.1;
|
||||
}
|
||||
}
|
||||
let (r, g, b) = hue(x);
|
||||
return (r, g, b, a);
|
||||
|
||||
}
|
||||
|
||||
println!("not painted: {:?}", attrs);
|
||||
(0., 0., 0., 0.)
|
||||
}
|
||||
|
|
|
@ -13,12 +13,6 @@ use gotham::{
|
|||
pipeline::single_middleware,
|
||||
router::builder::*,
|
||||
};
|
||||
use std::io::Cursor;
|
||||
use gotham::{
|
||||
helpers::http::response::create_response,
|
||||
hyper::{Body, Response},
|
||||
state::{FromState, State},
|
||||
};
|
||||
use geo::{Rect, Point};
|
||||
use serde::Deserialize;
|
||||
|
||||
|
@ -35,7 +29,6 @@ pub struct AppState {
|
|||
|
||||
impl AppState {
|
||||
pub fn with_db<F: Fn(&mut postgres::Client) -> R, R>(&self, f: F) -> R {
|
||||
use std::ops::Deref;
|
||||
let mut db_pool_index = self.db_pool_index.lock().unwrap();
|
||||
let mut db = self.db_pool[*db_pool_index].lock().unwrap();
|
||||
|
||||
|
@ -142,7 +135,7 @@ fn main() {
|
|||
))).collect();
|
||||
|
||||
let state = AppState {
|
||||
db_pool: db_pool,
|
||||
db_pool,
|
||||
db_pool_index: Arc::new(Mutex::new(0)),
|
||||
};
|
||||
let (chain, pipelines) = single_pipeline(
|
||||
|
@ -166,9 +159,6 @@ fn main() {
|
|||
route.get("/tree/:id")
|
||||
.with_path_extractor::<IdExtractor>()
|
||||
.to(trees::get_tree);
|
||||
// route.get("/tiles/:zoom/:x/:y/tile.png")
|
||||
// .with_path_extractor::<TileExtractor>()
|
||||
// .to(trees::get_tile);
|
||||
route.get("static/*").to_dir(
|
||||
FileOptions::new(&"static")
|
||||
.with_cache_control("no-cache")
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::io::Cursor;
|
||||
use std::rc::Rc;
|
||||
use gotham::{
|
||||
helpers::http::response::create_response,
|
||||
hyper::{Body, Response},
|
||||
state::{FromState, State},
|
||||
};
|
||||
use geo::{Point, Rect, LineString};
|
||||
use serde::Serialize;
|
||||
use mime::{APPLICATION_JSON, IMAGE_PNG};
|
||||
use geo::{Rect, LineString};
|
||||
use mime::IMAGE_PNG;
|
||||
use http::StatusCode;
|
||||
use chrono::{Local, NaiveDate};
|
||||
use cairo::{ImageSurface, Context};
|
||||
use crate::{tile_style, AppState, AreaExtractor, IdExtractor, TileExtractor};
|
||||
use crate::{tile_style, AppState, TileExtractor};
|
||||
|
||||
trait Grow {
|
||||
fn grow(&self, factor: f64) -> Self;
|
||||
|
@ -30,7 +29,7 @@ impl Grow for Rect<f64> {
|
|||
struct Shape {
|
||||
style: &'static tile_style::Style,
|
||||
path: LineString<f64>,
|
||||
exclude: Vec<LineString<f64>>,
|
||||
excludes: Rc<Vec<LineString<f64>>>,
|
||||
}
|
||||
|
||||
pub fn get_tile(state: State) -> (State, Response<Body>) {
|
||||
|
@ -81,7 +80,7 @@ pub fn get_tile(state: State) -> (State, Response<Body>) {
|
|||
tile_style::find(&zoom, &tags)
|
||||
.map(|style| {
|
||||
let path: LineString<f64> = row.get(0);
|
||||
let shape = Shape { style, path, exclude: vec![] };
|
||||
let shape = Shape { style, path, excludes: Rc::new(vec![]) };
|
||||
shapes.entry(style.z_index)
|
||||
.or_default()
|
||||
.push(shape);
|
||||
|
@ -109,7 +108,7 @@ pub fn get_tile(state: State) -> (State, Response<Body>) {
|
|||
(id, attrs, members)
|
||||
})
|
||||
});
|
||||
for (id, attrs, members) in result {
|
||||
for (_id, attrs, members) in result {
|
||||
let tags =
|
||||
if let serde_json::Value::Object(tags) = attrs {
|
||||
tags.into_iter()
|
||||
|
@ -132,11 +131,11 @@ pub fn get_tile(state: State) -> (State, Response<Body>) {
|
|||
None
|
||||
}
|
||||
}).cloned();
|
||||
let inners: Vec<_> = filter_members("inner").collect();
|
||||
let inners: Rc<Vec<_>> = Rc::new(filter_members("inner").collect());
|
||||
for path in filter_members("outer") {
|
||||
// TODO: expensive?
|
||||
let inners = inners.clone();
|
||||
let shape = Shape { style, path, exclude: inners };
|
||||
let shape = Shape { style, path, excludes: inners };
|
||||
shapes.entry(style.z_index)
|
||||
.or_default()
|
||||
.push(shape);
|
||||
|
@ -145,7 +144,7 @@ pub fn get_tile(state: State) -> (State, Response<Body>) {
|
|||
}
|
||||
|
||||
for shapes in shapes.values() {
|
||||
for Shape { style, path, exclude } in shapes {
|
||||
for Shape { style, path, excludes } in shapes {
|
||||
pctx.ctx.save().unwrap();
|
||||
|
||||
if path.is_closed() {
|
||||
|
@ -154,10 +153,10 @@ pub fn get_tile(state: State) -> (State, Response<Body>) {
|
|||
|
||||
pctx.create_path(path);
|
||||
pctx.ctx.close_path();
|
||||
if ! exclude.is_empty() {
|
||||
if ! excludes.is_empty() {
|
||||
pctx.ctx.clip_preserve();
|
||||
for path in exclude {
|
||||
pctx.create_path(path);
|
||||
for exclude in excludes.iter() {
|
||||
pctx.create_path(exclude);
|
||||
pctx.ctx.close_path();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue