server: delint, rm dead code, optimize

This commit is contained in:
Astro 2021-08-28 01:00:13 +02:00
parent 3fb1083a7b
commit 2402721226
3 changed files with 16 additions and 151 deletions

View File

@ -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.)
}

View File

@ -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")

View File

@ -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();
}
}