-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #20 from NoahSchiro/v0.3.0-dev
V0.3.0 dev
- Loading branch information
Showing
20 changed files
with
364 additions
and
464 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
use osmgraph::overpass_api::OverpassResponse; | ||
use osmgraph::api::OverpassResponse; | ||
|
||
fn main() { | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
//! This module gives us all of the tools needed for interacting with the Overpass / OSM API | ||
//! endpoint. This crate relies on [reqwest](https://docs.rs/reqwest/latest/reqwest/) to make this | ||
//! possible but conviently hides the details of making HTTP requests to the endpoint. | ||
//! | ||
//! The API module provides to primary tools for the developer: the | ||
//! [`crate::api::query_engine::QueryEngine`] and the | ||
//! [`crate::api::overpass_response::OverpassResponse`]. | ||
//! | ||
//! The query engine provides a simple interface for interacting with the API and the structure | ||
//! provides some reasonable defaults of requests we might be interested in when we are using OSM | ||
//! data for building graphs. Naturally, it's possible to modify these defaults to whatever your | ||
//! end application demands. | ||
//! | ||
//! The overpass response exists because [serde_json](https://docs.rs/serde_json/latest/serde_json/) | ||
//! can automatically parse json strings into structures, provided the structures have a shape that | ||
//! matches the json. The response type from Overpass is very regular, so we can leverage this to | ||
//! our advantage. If you are not using the Overpass API, you don't need this structure. | ||
pub mod query_engine; | ||
pub use query_engine::*; | ||
|
||
pub mod overpass_response; | ||
pub use overpass_response::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
use std::io::Error; | ||
|
||
use serde::{Serialize, Deserialize}; | ||
use serde_json::Value; | ||
|
||
use tokio::{ | ||
fs::File, | ||
io::{AsyncWriteExt, AsyncReadExt}, | ||
runtime::Runtime | ||
}; | ||
|
||
#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] | ||
#[serde(rename_all = "lowercase")] | ||
#[serde(tag = "type")] | ||
pub enum Element { | ||
Node { | ||
id: u64, | ||
lat: f64, | ||
lon: f64, | ||
}, | ||
Way { | ||
id: u64, | ||
nodes: Vec<u64>, | ||
tags: Option<Value>, | ||
} | ||
} | ||
|
||
/// `OverpassResponse` is the basic structure that we expect the OSM to respond with. | ||
/// Serde JSON helps us parse this string into the correct data structure. | ||
/// | ||
/// Example: | ||
/// ```rust | ||
/// use osmgraph::api::{QueryEngine, OverpassResponse}; | ||
/// | ||
/// let engine = QueryEngine::new(); | ||
/// | ||
/// //Make the request | ||
/// let response: String = engine.query_blocking(r#" | ||
/// [out:json]; | ||
/// area[name="Selinsgrove"]->.searchArea; | ||
/// ( | ||
/// way(area.searchArea); | ||
/// node(area.searchArea); | ||
/// ); | ||
/// out body; | ||
/// >; | ||
/// out skel qt; | ||
/// "#.to_string()).expect("Was not able to request OSM!"); | ||
/// | ||
/// let json: OverpassResponse = serde_json::from_str(&response) | ||
/// .expect("Was not able to parse json!"); | ||
/// ``` | ||
#[derive(Serialize, Deserialize, Clone, PartialEq, Debug, Default)] | ||
pub struct OverpassResponse { | ||
|
||
//Graph data | ||
elements: Vec<Element>, | ||
|
||
//Metadata | ||
generator: Value, | ||
osm3s: Value, | ||
version: Value | ||
} | ||
|
||
impl OverpassResponse { | ||
|
||
/// Return the `elements` field from the response. This field is the most important as it | ||
/// contains the actual graph information. | ||
pub fn elements(&self) -> &Vec<Element> { | ||
&self.elements | ||
} | ||
/// Return the `generator` field from the response. | ||
pub fn generator(&self) -> &Value { | ||
&self.generator | ||
} | ||
/// Return the `osm3s` field from the response. | ||
pub fn osm3s(&self) -> &Value { | ||
&self.osm3s | ||
} | ||
/// Return the `version` field from the response. | ||
pub fn version(&self) -> &Value { | ||
&self.version | ||
} | ||
|
||
/// Given a specified `filepath`, save the OverpassResponse to that location. | ||
pub async fn save(&self, filepath: &str) -> Result<(), Error> { | ||
|
||
let list_as_json = serde_json::to_string(self)?; | ||
let mut file = File::create(filepath).await?; | ||
|
||
file.write_all(list_as_json.as_bytes()).await?; | ||
file.flush().await?; | ||
|
||
Ok(()) | ||
} | ||
|
||
/// Behaves the same as [`OverpassResponse::save`], but will wait for the function to finish before continuing. | ||
pub fn save_blocking(&self, filepath: &str) -> Result<(), Error> { | ||
Runtime::new()? | ||
.block_on(self.save(filepath)) | ||
} | ||
|
||
/// Given a specified `filepath`, load the OverpassResponse from that location. The file is | ||
/// assumed to be a JSON and follow the structure of OverpassResponse. | ||
pub async fn load(filepath: &str) -> Result<Self, Error> { | ||
|
||
let mut file = File::open(filepath).await?; | ||
|
||
let mut contents = Vec::new(); | ||
|
||
// Read the file's contents into the buffer | ||
file.read_to_end(&mut contents).await?; | ||
|
||
let contents_as_string: String = String::from_utf8_lossy(&contents).to_string(); | ||
|
||
let json: OverpassResponse = serde_json::from_str(&contents_as_string)?; | ||
|
||
Ok(json) | ||
} | ||
|
||
/// Behaves the same as [`OverpassResponse::load`], but will wait for the function to finish before continuing. | ||
pub fn load_blocking(filepath: &str) -> Result<Self, Error> { | ||
Runtime::new()? | ||
.block_on(Self::load(filepath)) | ||
} | ||
} |
Oops, something went wrong.