diff options
| author | Daniel Schadt <kingdread@gmx.de> | 2025-11-29 14:19:54 +0100 |
|---|---|---|
| committer | Daniel Schadt <kingdread@gmx.de> | 2025-11-29 14:19:54 +0100 |
| commit | d9ea39135564a86d26adeba097c2541a02140ade (patch) | |
| tree | 4a74810f8fadfb326c22f34fbd60cded33a90169 | |
| parent | 918d06a7ffa92dce6dbf3a921263e56df1218bf0 (diff) | |
| download | hittekaart-d9ea39135564a86d26adeba097c2541a02140ade.tar.gz hittekaart-d9ea39135564a86d26adeba097c2541a02140ade.tar.bz2 hittekaart-d9ea39135564a86d26adeba097c2541a02140ade.zip | |
add some more documentation
| -rw-r--r-- | hittekaart/src/error.rs | 22 | ||||
| -rw-r--r-- | hittekaart/src/gpx.rs | 10 | ||||
| -rw-r--r-- | hittekaart/src/layer.rs | 5 | ||||
| -rw-r--r-- | hittekaart/src/lib.rs | 51 |
4 files changed, 75 insertions, 13 deletions
diff --git a/hittekaart/src/error.rs b/hittekaart/src/error.rs index f5abd1b..16cd597 100644 --- a/hittekaart/src/error.rs +++ b/hittekaart/src/error.rs @@ -5,32 +5,52 @@ use thiserror::Error; use super::renderer::RenderedTile; +/// Main error type. All hittekaart errors are mapped to this enum. #[derive(Error, Debug)] pub enum Error { + /// Error for crossbeam operations. + /// + /// hittekaart uses multithreading internally to speed up tile generation. We use crossbeam to + /// pass messages between threads. #[error("crossbeam error")] - Crossbeam(#[from] crossbeam_channel::SendError::<RenderedTile>), + Crossbeam(#[from] crossbeam_channel::SendError<RenderedTile>), + /// Underlying image processing error. #[error("image processing error")] Image(#[from] image::ImageError), + /// The GPX file contains an invalid latitude value. #[error("the latitude is invalid")] InvalidLatitude(#[source] ParseFloatError), + /// The GPX file contains an invalid longitude value. #[error("the longitude is invalid")] InvalidLongitude(#[source] ParseFloatError), + /// The output directory is invalid. #[error("the output directory is invalid")] InvalidOutputDirectory, + /// Underlying I/O error. + /// + /// The first field contains a description of the action that was executed when the error + /// occurred. #[error("error when {0} because of an underlying I/O error")] Io(&'static str, #[source] std::io::Error), + /// The input point had no latitude value attached. #[error("input has no latitude value")] MissingLatitude, + /// The input point had no longitude value attached. #[error("input has no longitude value")] MissingLongitude, + /// The output folder already exists. #[error("output file {0} already exists")] OutputAlreadyExists(PathBuf), + /// Underlying SQLite error. #[error("SQLite error")] Sqlite(#[from] rusqlite::Error), + /// UTF-8 decoding error. #[error("invalid utf8 input data")] Utf8(#[from] FromUtf8Error), + /// XML parsing error. #[error("XML parse error")] Xml(#[from] roxmltree::Error), } +/// Type alias that defaults to [`enum@Error`] as error variant. pub type Result<T, E = Error> = std::result::Result<T, E>; diff --git a/hittekaart/src/gpx.rs b/hittekaart/src/gpx.rs index 8bd076d..b645c21 100644 --- a/hittekaart/src/gpx.rs +++ b/hittekaart/src/gpx.rs @@ -1,8 +1,10 @@ //! GPX data extraction functions. //! -//! We *could* use the [gpx](https://github.com/georust/gpx) crate, but we don't care about much -//! other than the coordinates of the tracks. By implementing the little functionality ourselves, -//! we can use a fast XML parser ([roxmltree](https://github.com/RazrFalcon/roxmltree)). +//! Like the rest of hittekaart, this module is specialized to our use case. That's why this module +//! internally uses [roxmltree](https://github.com/RazrFalcon/roxmltree) for fast XML parsing, +//! instead of the [gpx](https://github.com/georust/gpx) crate that has more features. +//! +//! This module supports reading files that are `gzip` or `brotli` compressed. //! //! Note that we throw away all information that we don't care about. Since we need only the //! coordinates of a track, we simply use a `Vec<Coordinates>` to represent a track. @@ -125,7 +127,7 @@ impl Compression { /// for files ending with `.gz` or `.gzip`, and [`Compression::None`] for files ending with /// `.gpx`. /// - /// If the file does not end with any of the aforementioned extensions, an error is returned + /// If the file does not end with any of the aforementioned extensions, `None` is returned /// instead. pub fn suggest_from_path<P: AsRef<Path>>(path: P) -> Option<Compression> { let Some(ext) = path.as_ref().extension() else { diff --git a/hittekaart/src/layer.rs b/hittekaart/src/layer.rs index 03a168b..e8fea25 100644 --- a/hittekaart/src/layer.rs +++ b/hittekaart/src/layer.rs @@ -1,8 +1,7 @@ //! Lazy tiled image. //! -//! This supports OSM-style "tiled" images, but not all of the tiles have to be present. If a tile -//! is not present, a default pixel is returned. The tile is allocated with the first call to a -//! mutating operation. +//! This represents an OSM tile layer with 256x256 map tiles, but "lazily" saved -- tiles are only +//! allocated on the first write access. use std::{ fs::File, io::{BufWriter, Write}, diff --git a/hittekaart/src/lib.rs b/hittekaart/src/lib.rs index 3a4c7a3..5d71d2c 100644 --- a/hittekaart/src/lib.rs +++ b/hittekaart/src/lib.rs @@ -1,10 +1,51 @@ -//! `hittekaart` is a program to generate heatmaps from GPX tracks. +//! `hittekaart` is a crate to generate heatmaps from GPS tracks. It reads GPX files and produces +//! OSM-compatible overlay tiles. //! -//! Note that this crate is not meant to be used as a library. Instead, use the command line -//! program that is included in this crate. +//! This crate is mainly written to power the CLI wrapper and the Python interface, and as such, is +//! opinionated (and leaky) at points. //! -//! This library therefore contains an API that is tailored to the use case of the `hittekaart` -//! binary. +//! # Example +//! +//! ``` +//! use hittekaart::{gpx, renderer::{self, heatmap}, storage::{self, Storage}}; +//! const ZOOM: u32 = 10; +//! let source = +//! r#"<?xml version="1.0" encoding="UTF-8" standalone="no"?> +//! <gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1"> +//! <trk> +//! <trkseg> +//! <trkpt lat="49.184246" lon="9.201409"></trkpt> +//! </trkseg> +//! </trk> +//! </gpx>"#; +//! let track = gpx::extract_from_str(source)?; +//! let tracks = &[track]; +//! // Generating a heat-map is a two-step process: First, we collect the "heat zones", then we +//! // render each zone to a PNG. +//! let heat = renderer::prepare( +//! &renderer::heatmap::Renderer, +//! ZOOM, +//! tracks, +//! // A callback you can use to show progress +//! || Ok(()), +//! )?; +//! // Before we run the second step, we set up the storage system. You can save the bytes in any +//! // way you want, but there are convenience functions in this crate: +//! let mut store = storage::Sqlite::connect(":memory:")?; +//! store.prepare()?; +//! store.prepare_zoom(ZOOM)?; +//! // Now we're ready to do the actual colorizing +//! renderer::colorize( +//! &renderer::heatmap::Renderer, +//! heat, +//! // The callback receives the rendered tile, with the PNG data ready to grab. +//! |tile| { +//! store.store(ZOOM, tile.x, tile.y, &tile.data) +//! }, +//! )?; +//! store.finish()?; +//! # Ok::<_, hittekaart::error::Error>(()) +//! ``` pub mod error; pub mod gpx; pub mod layer; |
