Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Read GeoTIFF files from remote urls via object_store #5

Merged
merged 12 commits into from
Mar 4, 2024
Merged
Prev Previous commit
Next Next commit
♻️ Use Url::from_file_path to add file:// to filepath
Use built-in function at https://docs.rs/url/2.5.0/url/struct.Url.html#method.from_file_path to add the file:// prefix instead of the DIY method at f9607f3. Hoping that this would handle Windows paths too. Also changed .expect to .map_err to raise PyValueError instead of panicking.
weiji14 committed Mar 3, 2024

Verified

This commit was signed with the committer’s verified signature.
weiji14 Wei Ji
commit 3c8a604e306dd103335e0b4e3263ad7ee6817a4d
23 changes: 11 additions & 12 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -17,10 +17,9 @@ use std::io::Cursor;
use ndarray::Dim;
use numpy::{PyArray, ToPyArray};
use object_store::{parse_url, ObjectStore};
use pyo3::exceptions::PyValueError;
use pyo3::prelude::{pyfunction, pymodule, PyModule, PyResult, Python};
use pyo3::wrap_pyfunction;
use tokio;
use url::ParseError;
use url::Url;

/// Read a GeoTIFF file from a path on disk into an ndarray
@@ -47,17 +46,15 @@ fn read_geotiff_py<'py>(
path: &str,
py: Python<'py>,
) -> PyResult<&'py PyArray<f32, Dim<[usize; 2]>>> {
// Parse URL, prepend file:// for local filepaths
let url = match Url::parse(path) {
Ok(url) => url,
Err(ParseError::RelativeUrlWithoutBase) => {
let new_path = "file://".to_owned() + path;
let url = Url::parse(new_path.as_str()).expect(&format!("Cannot parse path: {path}"));
url
// Parse URL into ObjectStore and path
let file_or_url = match Url::from_file_path(path) {
Ok(filepath) => filepath,
Err(_) => {
Url::parse(path).map_err(|_| PyValueError::new_err("Cannot parse path: {path}"))?
}
Err(e) => Err(format!("{}", e)).unwrap(),
};
let (store, location) = parse_url(&url).expect(&format!("Cannot parse url: {url}"));
let (store, location) = parse_url(&file_or_url)
.map_err(|_| PyValueError::new_err("Cannot parse url: {file_or_url}"))?;

// Initialize async runtime
let runtime = tokio::runtime::Builder::new_current_thread()
@@ -73,7 +70,9 @@ fn read_geotiff_py<'py>(
});

// Get image pixel data as an ndarray
let vec_data = io::geotiff::read_geotiff(stream).expect("Cannot read GeoTIFF");
let vec_data = io::geotiff::read_geotiff(stream)
.map_err(|_| PyValueError::new_err("Cannot read GeoTIFF"))?;

// Convert from ndarray (Rust) to numpy ndarray (Python)
Ok(vec_data.to_pyarray(py))
}