Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e6db7eff8 |
3423
Cargo.lock
generated
Normal file
3423
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
11
Cargo.toml
Normal file
11
Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[package]
|
||||||
|
edition = "2024"
|
||||||
|
name = "web"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
fathom-function = { git = "ssh://git@github.com/fathom-io/pipeline-calculations.git", branch = "main" }
|
||||||
|
pipeline-application = { git = "ssh://git@github.com/fathom-io/pipeline-calculations.git", branch = "main" }
|
||||||
|
serde = { version = "1.0.219", features = ["derive"] }
|
||||||
|
tokio = { version = "1.43.0", features = ["macros", "rt-multi-thread"] }
|
||||||
|
uuid = { version = "1" }
|
||||||
78
README.md
78
README.md
@ -1,2 +1,78 @@
|
|||||||
# ba9b5754df8042e3b706f78c7cd2f563
|
# Pipeline route calculation
|
||||||
|
|
||||||
|
A function that exposes the pipeline route calculations.
|
||||||
|
|
||||||
|
The pipeline route can be defined by various means
|
||||||
|
- `kml` route file
|
||||||
|
- `kmz` route file
|
||||||
|
- `csv` of the x,y, and optionally z coordinates of the pipeline.
|
||||||
|
|
||||||
|
If the elevation is missing, we utilise one of the following services to obtain
|
||||||
|
the elevation of each waypoint on the pipeline.
|
||||||
|
|
||||||
|
- Google maps
|
||||||
|
- Map box
|
||||||
|
- Open elevation
|
||||||
|
|
||||||
|
This function implements the calculation of this following part of the BPML:
|
||||||
|
|
||||||
|
```mermaid
|
||||||
|
flowchart LR
|
||||||
|
Start((Start))
|
||||||
|
Start --> KML{User upload .kml or .csv?}
|
||||||
|
KML -->|.kml| V("Calculate pipeline measures (Vincenty's Method) - Calculation #2")
|
||||||
|
KML -->|.csv| POS{Is position in UTM or Lat/Lon?}
|
||||||
|
POS -->|UTM| PROJ(Poject to Lat/Lon - Calculation #3)
|
||||||
|
PROJ --> MEAS
|
||||||
|
POS -->|Lat/Lon| MEAS{Does the file contain the measure?}
|
||||||
|
MEAS -->|no| V
|
||||||
|
MEAS -->|yes| Done
|
||||||
|
V --> Done((Done))
|
||||||
|
```
|
||||||
|
|
||||||
|
## Input
|
||||||
|
|
||||||
|
### Arguments
|
||||||
|
|
||||||
|
- `org_id`: as string which should be a valid `uuid` for the organization
|
||||||
|
- `project_id`: the id of the data project where the pipeline data is found
|
||||||
|
- `elevation_provider`: a `string` value should be one of the following types
|
||||||
|
- `mapbox`
|
||||||
|
- `google_maps`
|
||||||
|
- `open_elevation`
|
||||||
|
- `pipeline_id`: an `array` of `strings` which should each be a valid uuid representing a pipeline.
|
||||||
|
- `route_file`: an `array` of `objects` containing the details of the uploaded file.
|
||||||
|
|
||||||
|
Note the pipeline_id array and route_file array should be the length such that
|
||||||
|
the first entry in each array corresponds to one another.
|
||||||
|
|
||||||
|
## Creating the function on the platform
|
||||||
|
|
||||||
|
To create this function on the platform using the `cli` set up the port forwarding as shown in README.
|
||||||
|
|
||||||
|
Then run the following command to create the function.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo run functions create \
|
||||||
|
-f functions/pipeline_route \
|
||||||
|
-d "Processes a pipeline route KML/KMZ/CSV file and creates the pipeline route sequence" \
|
||||||
|
-i org_id=string \
|
||||||
|
-i project_id=string \
|
||||||
|
-i elevation_provider=string \
|
||||||
|
-i pipeline_id=array \
|
||||||
|
-i route_file=array
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing the function locally
|
||||||
|
|
||||||
|
You can run and test the function locally by running
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo run
|
||||||
|
```
|
||||||
|
|
||||||
|
Then you can check it work with `curl` as follows
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl localhost:8080 -d $(jq '. | tojson' functions/pipeline_route/example_input.json)
|
||||||
|
```
|
||||||
|
|||||||
14
example_input.json
Normal file
14
example_input.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"elevation_provider": "open_elevation",
|
||||||
|
"org_id": "2cbfe270-d195-48ad-aed1-24145924635c",
|
||||||
|
"pipeline_id": [
|
||||||
|
"01966d47-1d4c-7751-a1f1-0617caa3a00d"
|
||||||
|
],
|
||||||
|
"project_id": "680b61b0aedd6f9e639d8699",
|
||||||
|
"route_file": [
|
||||||
|
{
|
||||||
|
"fileId": "a97c1871-b6b2-4ea0-8a04-43ae4c7d76e3",
|
||||||
|
"revisionId": "975b4034-aad1-4e12-b531-fb0cf0b6f255"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
92
src/main.rs
Normal file
92
src/main.rs
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
use fathom_function::tracing;
|
||||||
|
use pipeline_application::application::{
|
||||||
|
Application, ElevationProvider as ApplicationElevationProvider,
|
||||||
|
FileDetails as ApplicationFileDetails,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
#[fathom_function::function]
|
||||||
|
async fn pipeline_route(input: Input) -> Result<Output, String> {
|
||||||
|
let elevation_provider = input.elevation_provider;
|
||||||
|
let mut pipeline_ids = Vec::new();
|
||||||
|
let project_id = input.project_id.to_owned();
|
||||||
|
let org_id = input.org_id;
|
||||||
|
let mut app = Application::new_from_compile_env(org_id, &project_id).unwrap();
|
||||||
|
// TODO: We need a solution for getting API keys into functions
|
||||||
|
app.with_key()
|
||||||
|
.map_box("pk.eyJ1IjoiaG11YmFpcmVlayIsImEiOiJjam03ZXh1cXcxdXV2M3FtdWl4dGphNmxhIn0.1V1fEZMzOt0YumJtwU9AvA".to_owned())
|
||||||
|
.google_maps("AIzaSyB3qwZNz9MfreHYtfp93zzmnsCDFBU4cso".to_owned());
|
||||||
|
|
||||||
|
for (pipeline_id, file_details) in input.into_iter() {
|
||||||
|
pipeline_ids.push(pipeline_id);
|
||||||
|
|
||||||
|
app.process_pipeline_route_file(pipeline_id, file_details, elevation_provider)
|
||||||
|
.await
|
||||||
|
.map_err(|err| {
|
||||||
|
tracing::error!(%pipeline_id, ?err, "Error running pipeline route calculation");
|
||||||
|
format!("{err:?}")
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
Ok(Output {
|
||||||
|
pipeline_ids,
|
||||||
|
org_id,
|
||||||
|
project_id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize)]
|
||||||
|
struct Output {
|
||||||
|
org_id: Uuid,
|
||||||
|
project_id: String,
|
||||||
|
pipeline_ids: Vec<Uuid>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct Input {
|
||||||
|
org_id: Uuid,
|
||||||
|
project_id: String,
|
||||||
|
elevation_provider: ElevationProvider,
|
||||||
|
pipeline_id: Vec<Uuid>,
|
||||||
|
route_file: Vec<FileDetails>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Input {
|
||||||
|
fn into_iter(self) -> impl Iterator<Item = (Uuid, FileDetails)> {
|
||||||
|
self.pipeline_id.into_iter().zip(self.route_file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Deserialize)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub enum ElevationProvider {
|
||||||
|
OpenElevation,
|
||||||
|
Mapbox,
|
||||||
|
GoogleMaps,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ElevationProvider> for ApplicationElevationProvider {
|
||||||
|
fn from(value: ElevationProvider) -> Self {
|
||||||
|
match value {
|
||||||
|
ElevationProvider::OpenElevation => Self::OpenElevation,
|
||||||
|
ElevationProvider::Mapbox => Self::MapBox,
|
||||||
|
ElevationProvider::GoogleMaps => Self::GoogleMaps,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct FileDetails {
|
||||||
|
pub file_id: Uuid,
|
||||||
|
pub revision_id: Uuid,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<FileDetails> for ApplicationFileDetails {
|
||||||
|
fn from(value: FileDetails) -> Self {
|
||||||
|
Self {
|
||||||
|
id: value.file_id,
|
||||||
|
revision_id: value.revision_id,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user