mmap-tile/src/service/mod.rs
Tsuki f0269a05fe
Some checks failed
Docker Build and Push / build (push) Has been cancelled
add new api: nearest
2025-08-07 22:57:51 +08:00

90 lines
2.4 KiB
Rust

use crate::model::responses::{NearestTileResponse, TileResponse};
use axum::Error;
use chrono::{DateTime, Utc};
use sqlx::PgPool;
#[derive(Clone)]
pub struct Service {
pub pool: PgPool,
}
impl Service {
pub fn new(pool: PgPool) -> Self {
Self { pool }
}
pub async fn get_tile_data(
&self,
datetime: DateTime<Utc>,
area: &str,
) -> Result<TileResponse, Error> {
let primitive_datetime = datetime.format("%Y%m%d%H%M%S").to_string();
let record = sqlx::query!(
r#"
SELECT
id,
ingestion_time,
data_time,
source,
storage_url
FROM data_ingestion
WHERE data_time = $1 AND source = $2
"#,
datetime.naive_utc(),
area
)
.fetch_optional(&self.pool)
.await
.map_err(|e| Error::new(format!("Database error: {}", e)))?;
match record {
Some(row) => Ok(TileResponse {
id: row.id,
ingestion_time: row.ingestion_time.and_utc(),
data_time: row.data_time.and_utc(),
source: row.source,
storage_url: row.storage_url,
}),
None => Err(Error::new(format!(
"No tile data found for datetime: {} and area: {}",
primitive_datetime, area
))),
}
}
pub async fn get_nearest_tile_data(
&self,
datetime: DateTime<Utc>,
area: &str,
) -> Result<NearestTileResponse, Error> {
let primitive_datetime = datetime.format("%Y%m%d%H%M%S").to_string();
// 查找距离指定 datetime 最近的数据
let record = sqlx::query!(
r#"
SELECT
id,
data_time
FROM data_ingestion
WHERE source = $1
ORDER BY ABS(EXTRACT(EPOCH FROM (data_time - $2)))
LIMIT 1
"#,
area,
datetime.naive_utc()
)
.fetch_optional(&self.pool)
.await
.map_err(|e| Error::new(format!("Database error: {}", e)))?;
match record {
Some(row) => Ok(NearestTileResponse {
id: row.id,
nearest_data_time: row.data_time.and_utc(),
}),
None => Err(Error::new(format!("No tile data found for area: {}", area))),
}
}
}