commit
fef23ba79d
@ -0,0 +1 @@
|
|||||||
|
/target
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "mbtiles_server"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
actix-cors = "0.7.0"
|
||||||
|
actix-web = "4.5.1"
|
||||||
|
dotenvy = "0.15.7"
|
||||||
|
env_logger = "0.11.3"
|
||||||
|
log = "0.4.21"
|
||||||
|
r2d2 = "0.8.10"
|
||||||
|
r2d2_sqlite = "0.24.0"
|
||||||
|
rusqlite = { version = "0.31.0", features = ["bundled"] }
|
@ -0,0 +1,105 @@
|
|||||||
|
type Pool = ::r2d2::Pool<::r2d2_sqlite::SqliteConnectionManager>;
|
||||||
|
pub type Connection = ::r2d2::PooledConnection<::r2d2_sqlite::SqliteConnectionManager>;
|
||||||
|
|
||||||
|
fn initialize_db_pool() -> Pool {
|
||||||
|
let conn_spec = std::env::var("DATABASE_URL").expect("DATABASE_URL should be set");
|
||||||
|
let manager = ::r2d2_sqlite::SqliteConnectionManager::file(conn_spec);
|
||||||
|
Pool::new(manager).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn execute(
|
||||||
|
pool: &Pool,
|
||||||
|
zoom_level: String,
|
||||||
|
tile_column: String,
|
||||||
|
tile_row: String,
|
||||||
|
) -> Result<Vec<u8>, actix_web::Error> {
|
||||||
|
let pool = pool.clone();
|
||||||
|
let conn = ::actix_web::web::block(move || pool.get())
|
||||||
|
.await?
|
||||||
|
.map_err(::actix_web::error::ErrorInternalServerError)?;
|
||||||
|
|
||||||
|
let data = ::actix_web::web::block(move || {
|
||||||
|
let mut stmt = conn.prepare("
|
||||||
|
SELECT tile_data FROM tiles WHERE zoom_level = :zoom_level AND tile_column = :tile_column AND tile_row = :tile_row
|
||||||
|
").unwrap();
|
||||||
|
|
||||||
|
let mut rows = stmt
|
||||||
|
.query(&[
|
||||||
|
(":zoom_level", zoom_level.as_str()),
|
||||||
|
(":tile_column", tile_column.as_str()),
|
||||||
|
(":tile_row", tile_row.as_str()),
|
||||||
|
])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut bytes = vec![];
|
||||||
|
|
||||||
|
while let Some(row) = rows.next().unwrap() {
|
||||||
|
bytes = row.get(0).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes
|
||||||
|
}).await.unwrap();
|
||||||
|
|
||||||
|
Ok(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[::actix_web::get("/{z}/{x}/{y}.png")]
|
||||||
|
async fn get_tile(
|
||||||
|
pool: ::actix_web::web::Data<Pool>,
|
||||||
|
info: ::actix_web::web::Path<(u32, i64, i64)>,
|
||||||
|
) -> impl ::actix_web::Responder {
|
||||||
|
let info = info.into_inner();
|
||||||
|
let zoom_level = info.0;
|
||||||
|
let tile_column = info.1;
|
||||||
|
let tile_row = info.2;
|
||||||
|
let tile_row = 2_i64.pow(zoom_level) - tile_row - 1;
|
||||||
|
|
||||||
|
let data = execute(
|
||||||
|
&pool,
|
||||||
|
zoom_level.to_string(),
|
||||||
|
tile_column.to_string(),
|
||||||
|
tile_row.to_string(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
::actix_web::HttpResponse::Ok()
|
||||||
|
.content_type(::actix_web::http::header::ContentType::png())
|
||||||
|
.body(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[::actix_web::main]
|
||||||
|
async fn main() -> std::io::Result<()> {
|
||||||
|
::dotenvy::dotenv().ok();
|
||||||
|
|
||||||
|
::env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
||||||
|
|
||||||
|
let pool = initialize_db_pool();
|
||||||
|
|
||||||
|
::log::info!("starting HTTP server at http://127.0.0.1:8080");
|
||||||
|
|
||||||
|
::actix_web::HttpServer::new(move || {
|
||||||
|
::actix_web::App::new()
|
||||||
|
.wrap(
|
||||||
|
::actix_cors::Cors::default()
|
||||||
|
.allowed_origin(
|
||||||
|
&std::env::var("ORIGIN_URL")
|
||||||
|
.unwrap_or(String::from("http://localhost:1420")),
|
||||||
|
)
|
||||||
|
.allowed_methods(vec!["GET"])
|
||||||
|
.allowed_headers(vec![
|
||||||
|
::actix_web::http::header::AUTHORIZATION,
|
||||||
|
::actix_web::http::header::ACCEPT,
|
||||||
|
])
|
||||||
|
.allowed_header(::actix_web::http::header::CONTENT_TYPE)
|
||||||
|
.supports_credentials()
|
||||||
|
.max_age(3600),
|
||||||
|
)
|
||||||
|
.app_data(::actix_web::web::Data::new(pool.clone()))
|
||||||
|
.service(get_tile)
|
||||||
|
})
|
||||||
|
.bind(("127.0.0.1", 8080))?
|
||||||
|
.workers(2)
|
||||||
|
.run()
|
||||||
|
.await
|
||||||
|
}
|
Loading…
Reference in new issue