Skip to content

Commit

Permalink
Define model for Transect and get_one/get_all funcs
Browse files Browse the repository at this point in the history
  • Loading branch information
evanjt committed Sep 18, 2024
1 parent ce7c33d commit fdaaf27
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 57 deletions.
53 changes: 8 additions & 45 deletions src/areas/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ use crate::sensors::db::Entity as SensorDB;
use crate::soil::profiles::db::Entity as SoilProfileDB;
use crate::transects::db::Entity as TransectDB;
use crate::transects::models::Transect;
use crate::transects::nodes::db::Entity as TransectNodeDB;
use crate::transects::nodes::models::TransectNode;
use chrono::NaiveDateTime;
use sea_orm::entity::prelude::*;
use sea_orm::ColumnTrait;
Expand Down Expand Up @@ -117,54 +115,20 @@ impl Area {
.unwrap();

// Query for transects with related transect nodes and their corresponding plots
let transects: Vec<(
crate::transects::db::Model,
Vec<crate::transects::nodes::db::Model>,
)> = TransectDB::find()
let transects: Vec<crate::transects::db::Model> = TransectDB::find()
.filter(crate::transects::db::Column::AreaId.eq(area.id))
.find_with_related(TransectNodeDB)
// .find_with_related(TransectNodeDB)
.all(&db)
.await
.unwrap();

let mut transects_with_nodes: Vec<Transect> = Vec::new();
for (transect, nodes) in transects {
let mut transect_nodes: Vec<TransectNode> = Vec::new();

for node in nodes {
let plot: PlotSimple = PlotDB::find()
.filter(crate::plots::db::Column::Id.eq(node.plot_id))
.column_as(Expr::cust("ST_X(plot.geom)"), "coord_x")
.column_as(Expr::cust("ST_Y(plot.geom)"), "coord_y")
.column_as(Expr::cust("ST_Z(plot.geom)"), "coord_z")
.column_as(
Expr::cust("ST_X(st_transform(plot.geom, 4326))"),
"longitude",
)
.column_as(
Expr::cust("ST_Y(st_transform(plot.geom, 4326))"),
"latitude",
)
.column_as(Expr::cust("st_srid(plot.geom)"), "coord_srid")
.into_model::<PlotSimple>()
.one(&db)
for transect in transects {
transects_with_nodes.push(
Transect::get_one(transect.id, &db)
.await
.unwrap()
.unwrap(); // Unwrapping safely assuming plot always exists

transect_nodes.push(TransectNode {
id: node.id,
name: None, // `name` doesn't exist in the `transectnode::Model`
order: node.order,
plot,
});
}

transects_with_nodes.push(Transect {
id: transect.id,
name: transect.name,
nodes: transect_nodes,
});
.expect("Transect not found"),
);
}

// Query for soil profiles with matching area_id
Expand Down Expand Up @@ -207,8 +171,7 @@ impl Area {
plots,
soil_profiles,
sensors,
// transects: transects_with_nodes, // Include transects with nodes
transects: vec![],
transects: transects_with_nodes, // Include transects with nodes
project,
geom,
}
Expand Down
2 changes: 1 addition & 1 deletion src/areas/services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub async fn get_convex_hull(db: &DatabaseConnection, area_id: Uuid) -> Option<V
DbBackend::Postgres,
raw_sql,
vec![
0.01.into(), // ST_Buffer value
10.into(), // ST_Buffer value
4326.into(), // ST_Transform value
2056.into(), // ST_Transform value for plot.geom
2056.into(), // ST_Transform value for soilprofile.geom
Expand Down
16 changes: 8 additions & 8 deletions src/plots/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ use uuid::Uuid;

#[derive(ToSchema, Serialize, FromQueryResult)]
pub struct PlotSimple {
id: Uuid,
name: String,
latitude: Option<f64>,
longitude: Option<f64>,
coord_srid: Option<i32>,
coord_x: Option<f64>,
coord_y: Option<f64>,
coord_z: Option<f64>,
pub id: Uuid,
pub name: String,
pub latitude: Option<f64>,
pub longitude: Option<f64>,
pub coord_srid: Option<i32>,
pub coord_x: Option<f64>,
pub coord_y: Option<f64>,
pub coord_z: Option<f64>,
}
#[derive(ToSchema, Serialize)]
pub struct Plot {
Expand Down
138 changes: 136 additions & 2 deletions src/transects/models.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
use crate::transects::nodes::models::TransectNode;
use crate::plots::db::Entity as PlotDB;
use crate::plots::models::PlotSimple;
use crate::transects::db::Entity as TransectDB;
use crate::transects::nodes::db::Entity as TransectNodeDB;
use crate::transects::nodes::models::TransectNodeAsPlotWithOrder;
use sea_orm::ColumnTrait;
use sea_orm::{DatabaseConnection, EntityTrait, QueryFilter, QuerySelect};
use sea_query::Expr;
use serde::Serialize;
use utoipa::ToSchema;
use uuid::Uuid;
Expand All @@ -7,5 +14,132 @@ use uuid::Uuid;
pub struct Transect {
pub id: Uuid,
pub name: Option<String>,
pub nodes: Vec<TransectNode>,
pub nodes: Vec<TransectNodeAsPlotWithOrder>,
}

impl Transect {
pub async fn get_all(db: &DatabaseConnection) -> Vec<Self> {
// Query for transects with related transect nodes and their corresponding plots
let transects: Vec<(
crate::transects::db::Model,
Vec<crate::transects::nodes::db::Model>,
)> = TransectDB::find()
.find_with_related(TransectNodeDB)
.all(db)
.await
.unwrap();

let mut transects_with_nodes: Vec<Transect> = Vec::new();
for (transect, nodes) in transects {
let mut transect_nodes: Vec<TransectNodeAsPlotWithOrder> = Vec::new();

for node in nodes {
// Fetch associated plot for the node
let plot: PlotSimple = PlotDB::find()
.filter(crate::plots::db::Column::Id.eq(node.plot_id))
.column_as(Expr::cust("ST_X(plot.geom)"), "coord_x")
.column_as(Expr::cust("ST_Y(plot.geom)"), "coord_y")
.column_as(Expr::cust("ST_Z(plot.geom)"), "coord_z")
.column_as(
Expr::cust("ST_X(st_transform(plot.geom, 4326))"),
"longitude",
)
.column_as(
Expr::cust("ST_Y(st_transform(plot.geom, 4326))"),
"latitude",
)
.column_as(Expr::cust("st_srid(plot.geom)"), "coord_srid")
.into_model::<PlotSimple>()
.one(db)
.await
.unwrap()
.unwrap(); // Assuming plot always exists

transect_nodes.push(TransectNodeAsPlotWithOrder {
id: plot.id,
order: node.order,
name: plot.name,
latitude: plot.latitude,
longitude: plot.longitude,
coord_srid: plot.coord_srid,
coord_x: plot.coord_x,
coord_y: plot.coord_y,
coord_z: plot.coord_z,
});
}

transects_with_nodes.push(Transect {
id: transect.id,
name: transect.name.clone(),
nodes: transect_nodes,
});
}

transects_with_nodes
}

pub async fn get_one(transect_id: Uuid, db: &DatabaseConnection) -> Option<Self> {
// Query for the single transect with the provided id and its related transect nodes
let transect_tuple: Option<(
crate::transects::db::Model,
Vec<crate::transects::nodes::db::Model>,
)> = TransectDB::find()
.filter(crate::transects::db::Column::Id.eq(transect_id))
.find_with_related(TransectNodeDB)
.all(db)
.await
.unwrap()
.into_iter()
.next(); // Retrieve the first result, if any

// If a transect is found, process it, otherwise return None
if let Some((transect, nodes)) = transect_tuple {
let mut transect_nodes: Vec<TransectNodeAsPlotWithOrder> = Vec::new();

// Iterate over nodes and fetch the associated plot for each node
for node in nodes {
let plot: PlotSimple = PlotDB::find()
.filter(crate::plots::db::Column::Id.eq(node.plot_id))
.column_as(Expr::cust("ST_X(plot.geom)"), "coord_x")
.column_as(Expr::cust("ST_Y(plot.geom)"), "coord_y")
.column_as(Expr::cust("ST_Z(plot.geom)"), "coord_z")
.column_as(
Expr::cust("ST_X(st_transform(plot.geom, 4326))"),
"longitude",
)
.column_as(
Expr::cust("ST_Y(st_transform(plot.geom, 4326))"),
"latitude",
)
.column_as(Expr::cust("st_srid(plot.geom)"), "coord_srid")
.into_model::<PlotSimple>()
.one(db)
.await
.unwrap()
.unwrap(); // Assuming plot always exists

transect_nodes.push(TransectNodeAsPlotWithOrder {
id: plot.id,
order: node.order,
name: plot.name,
latitude: plot.latitude,
longitude: plot.longitude,
coord_srid: plot.coord_srid,
coord_x: plot.coord_x,
coord_y: plot.coord_y,
coord_z: plot.coord_z,
});
}

// Return the constructed Transect
Some(Transect {
id: transect.id,
name: transect.name,
nodes: transect_nodes,
})
} else {
// Return None if no transect is found
None
}
}
}
16 changes: 15 additions & 1 deletion src/transects/nodes/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,21 @@ use uuid::Uuid;
#[derive(ToSchema, Serialize)]
pub struct TransectNode {
pub id: Uuid,
pub name: Option<String>,
pub order: i32,
pub plot: PlotSimple,
}

#[derive(ToSchema, Serialize)]
pub struct TransectNodeAsPlotWithOrder {
// A transect node is really a plot with an order value, this is similar to
// the PlotSimple struct but with an additional order field
pub id: Uuid,
pub name: String,
pub latitude: Option<f64>,
pub longitude: Option<f64>,
pub coord_srid: Option<i32>,
pub coord_x: Option<f64>,
pub coord_y: Option<f64>,
pub coord_z: Option<f64>,
pub order: i32,
}

0 comments on commit fdaaf27

Please sign in to comment.