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

Increased documentation content of README and root rustdoc page. #296

Merged
merged 1 commit into from
Sep 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Initial update of README and rust doc root.
Clarification on C vs C++ documentation.

Update README.md

Update CHANGES.md
  • Loading branch information
metasim committed Sep 2, 2022
commit 7f382ea24b7efffab0f41c7a99612c227560d597
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/target
/.vscode
/gdal-sys/target
/.idea

# gtags
GPATH
Expand Down
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## Unreleased

- Added new content to README.md and root rust docs.

- <https://github.com/georust/gdal/pull/296>

## 0.13

- Add prebuild bindings for GDAL 3.5
Expand Down
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# GDAL

[![Documentation](https://docs.rs/gdal/badge.svg)](https://docs.rs/gdal)
![Build Status](https://github.com/georust/gdal/workflows/CI/badge.svg)

[GDAL](http://gdal.org/) is a translator and processing library for various raster and vector geospatial data formats.

This crate provides safe, idiomatic [Rust](http://www.rust-lang.org/) bindings for GDAL.

## Capabilities

GDAL is an incredibly powerful library. For a general understanding of its capabilities, a good place to get started is the [GDAL User-oriented documentation](https://gdal.org/user/index.html). These features include:

* Opening raster and vector file formats for reading/writing
* Translating between file formats
* Reading and writing metadata in raster and vector datasets
* Accessing raster bands and their metadata
* Reading and writing geospatial coordinate system and projection values
* Warping (resampling and re-projecting) between coordinate systems

## Documentation

This crate's [API documentation](https://docs.rs/crate/gdal) is hosted on [docs.rs](https://docs.rs).

The Rust documentation is currently a work in progress, and may not cover requisite details on parameter semantics, value interpretation, etc.
Therefore, the authoritative documentation is that of GDAL in the form of its [C](https://gdal.org/api/index.html#c-api) and [C++](https://gdal.org/api/index.html#id3) APIs.
The former is technically what this crate calls, but the latter is usually more clear and better documented.

## Usage

This crate provides high-level, idiomatic Rust bindings for GDAL.
To do that, it uses [`gdal-sys`](gdal-sys) internally, a low-level interface to the GDAL C library, which is generated using [`bindgen`](https://rust-lang.github.io/rust-bindgen/).
Using the `gdal-sys` crate directly is normally not needed, but it can be useful in order to call APIs that have not yet been exposed in `gdal`.

Building this crate assumes a compatible version of GDAL is installed with the corresponding header files and shared libraries.
This repository includes pre-generated bindings for GDAL 2.4 through 3.5 (see the`gdal-sys/prebuilt-bindings` directory).
If you're compiling against a later version of GDAL, you can enable the `bindgen` feature flag to have new bindings generated on the fly.

## Community

This crate is part of the expansive (and expanding!) [`georust`](https://georust.org/) organization. Come join our discussions on [Discord](https://discord.gg/Fp2aape)!

## Contributing

This crate continues to evolve, and PRs are welcome. Make sure you are comfortable with the [Code of Conduct](CODE_OF_CONDUCT.md) and [License](LICENSE.txt) before submitting a PR.

## License

This library is released under the [MIT license](http://opensource.org/licenses/MIT)
18 changes: 0 additions & 18 deletions Readme.md

This file was deleted.

5 changes: 5 additions & 0 deletions src/cpl.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
//! GDAL Common Portability Library Functions
//!
//! This module provides safe access to a subset of the [GDAL CPL functions](https://gdal.org/api/cpl.html).
//!

use std::ffi::CString;
use std::ptr;

Expand Down
2 changes: 2 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! GDAL Error Types

use libc::c_int;
use thiserror::Error;

Expand Down
180 changes: 165 additions & 15 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,175 @@
//! [GDAL](http://gdal.org/) bindings for Rust.
#![crate_name = "gdal"]
#![crate_type = "lib"]
#![doc = include_str!("../README.md")]

//! ## Examples
//!
//! A high-level API to access the GDAL library, for vector and raster data.
//! ### Raster
//!
//! ## Use
//! This example shows opening a raster [`Dataset`] and using a few of the data access methods.
//! The GDAL [Raster Data Model](https://gdal.org/user/raster_data_model.html) document provides
//! details on the various constructs involved, as this example only touches the surface.
//!
//! ```rust, no_run
//! // `Dataset` is required for opening files. `Metadata` is required to enable reading of some
//! // general information properties, such as `description`.
//! use gdal::{Dataset, Metadata};
//! # fn main() -> gdal::errors::Result<()> {
//! // The `Dataset::open` function is used to open all datasets, regardless of type.
//! // There's a `Dataset:open_ex` variant which provides some additional options.
//! let dataset = Dataset::open("fixtures/tinymarble.tif")?;
//! // The `description` property for a `Dataset` is often (but not necessarily) the file name
//! println!("Dataset description: {}", dataset.description()?);
//! let band_count = dataset.raster_count();
//! println!("Number of bands: {band_count}");
//! // Beware! In GDAL, band indexes are 1-based!
//! for i in 1..=band_count {
//! println!(" Band {i}");
//! let band = dataset.rasterband(i)?;
//! // Depending on the file, the description field may be the empty string :(
//! println!(" Description: '{}'", band.description()?);
//! // In GDAL, all no-data values are coerced to floating point types, regardless of the
//! // underlying pixel type.
//! println!(" No-data value: {:?}", band.no_data_value());
//! println!(" Pixel data type: {}", band.band_type());
//! // Scale and offset are often used with integral pixel types to convert between pixel value
//! // to some physical unit (e.g. watts per square meter per steradian)
//! println!(" Scale: {:?}", band.scale());
//! println!(" Offset: {:?}", band.offset());
//! // In GDAL you can read arbitrary regions of the raster, and have them up- or down-sampled
//! // when the output buffer size is different from the read size. The terminology GDAL
//! // uses takes getting used to. All parameters here are in pixel coordinates.
//! // Also note, tuples are in `(x, y)`/`(cols, rows)` order.
//! // `window` is the (x, y) coordinate of the upper left corner of the region to read.
//! let window = (20, 30);
//! // `window_size` is the amount to read `(cols, rows)`
//! let window_size = (2, 3);
//! // `size` is the output buffer size. If this is different from `window_size`, then
//! // the `resample_alg` parameter below becomes relevant.
//! let size = (2, 3);
//! // Options here include `NearestNeighbor` (default), `Bilinear`, `Cubic`, etc.
//! let resample_alg = None;
//! // Note the `u8` type parameter. GDAL will convert the native pixel type to whatever is
//! // specified here... which may or may not be right for your use case!
//! let rv = band.read_as::<u8>(window, window_size, size, resample_alg)?;
//! // `Rasterband::read_as` returns a `Buffer` struct, which contains the shape of the output
//! // `(cols, rows)` and a `Vec<_>` containing the pixel values.
//! println!(" Data size: {:?}", rv.size);
//! println!(" Data values: {:?}", rv.data);
//! }
//! # Ok(())
//! # }
//! ```
//! use std::path::Path;
//! use gdal::Dataset;
//! use gdal::vector::LayerAccess;
//!
//! let dataset = Dataset::open(Path::new("fixtures/roads.geojson")).unwrap();
//! let mut layer = dataset.layer(0).unwrap();
//! for feature in layer.features() {
//! let highway_field = feature.field("highway").unwrap().unwrap();
//! let geometry = feature.geometry();
//! println!("{} {}", highway_field.into_string().unwrap(), geometry.wkt().unwrap());
//! The resulting output is:
//!
//! ```text
//! Dataset description: fixtures/tinymarble.tif
//! Number of bands: 3
//! Band 1
//! Description: ''
//! No-data value: None
//! Pixel data type: 1
//! Scale: None
//! Offset: None
//! Data size: (2, 3)
//! Data values: [47, 74, 77, 118, 98, 122]
//! Band 2
//! Description: ''
//! No-data value: None
//! Pixel data type: 1
//! Scale: None
//! Offset: None
//! Data size: (2, 3)
//! Data values: [50, 79, 77, 118, 95, 119]
//! Band 3
//! Description: ''
//! No-data value: None
//! Pixel data type: 1
//! Scale: None
//! Offset: None
//! Data size: (2, 3)
//! Data values: [71, 94, 79, 115, 77, 98]
//! ```
//!
//!
//! ### Vector
//!
//! This example opens a vector [`Dataset`] and iterates over the various levels of structure within it.
//! The GDAL vector data model is quite sophisticated, so please refer to the GDAL
//! [Vector Data Model](https://gdal.org/user/vector_data_model.html) document for specifics.
//!
//! ```rust, no_run
//! use gdal::{Dataset, Metadata};
//! // The `LayerAccess` trait enables reading of vector specific fields from the `Dataset`.
//! use gdal::vector::LayerAccess;
//! # fn main() -> gdal::errors::Result<()> {
//! use gdal::errors::GdalError;
//! use gdal::vector::geometry_type_to_name;
//! let dataset = Dataset::open("fixtures/roads.geojson")?;
//! println!("Dataset description: {}", dataset.description()?);
//! let layer_count = dataset.layer_count();
//! println!("Number of layers: {layer_count}");
//! // Unlike raster bands, layers are zero-based
//! for l in 0..layer_count {
//! // We have to get a mutable borrow on the layer because the `Layer::features` iterator
//! // requires it.
//! let mut layer = dataset.layer(l)?;
//! let feature_count = layer.feature_count();
//! println!(" Layer {l}, name='{}', features={}", layer.name(), feature_count);
//! for feature in layer.features() {
//! // The fid is important in cases where the vector dataset is large can you
//! // need random access.
//! let fid = feature.fid().unwrap_or(0);
//! // Summarize the geometry
//! let geometry = feature.geometry();
//! let geom_type = geometry_type_to_name(geometry.geometry_type());
//! let geom_len = geometry.get_point_vec().len();
//! println!(" Feature fid={fid:?}, geometry_type='{geom_type}', geometry_len={geom_len}");
//! // Get all the available fields and print their values
//! for field in feature.fields() {
//! let name = field.0;
//! let value = field.1.and_then(|f| f.into_string()).unwrap_or("".into());
//! println!(" {name}={value}");
//! }
//! }
//! }
//! # Ok(())
//! # }
//! ```
//!
//! The resulting (truncated) output looks like this:
//!
//! ```text
//! Dataset description: fixtures/roads.geojson
//! Number of layers: 1
//! Layer 0, name='roads', features=21
//! Feature fid=236194095, geometry_type='Line String', geometry_len=3
//! kind=path
//! sort_key=
//! is_link=no
//! is_tunnel=no
//! is_bridge=no
//! railway=
//! highway=footway
//! Feature fid=236194098, geometry_type='Line String', geometry_len=3
//! kind=path
//! sort_key=
//! is_link=no
//! is_tunnel=no
//! is_bridge=no
//! railway=
//! highway=footway
//! Feature fid=236194101, geometry_type='Line String', geometry_len=4
//! kind=path
//! sort_key=
//! is_link=no
//! is_tunnel=no
//! is_bridge=no
//! railway=
//! highway=footway
//! ...
//! ```

#![crate_name = "gdal"]
#![crate_type = "lib"]

pub use version::version_info;

Expand Down
2 changes: 2 additions & 0 deletions src/programs/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
//! Rust implementations of [GDAL Programs](https://gdal.org/programs/index.html)

pub mod raster;
4 changes: 4 additions & 0 deletions src/spatial_ref/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
//! GDAL Spatial Reference System Functions
//!
//! https://gdal.org/api/ogr_srs_api.html

mod srs;

pub use gdal_sys::OGRAxisOrientation;
Expand Down
4 changes: 4 additions & 0 deletions src/version.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
//! GDAL Version Information Functions
//!
//! See [`GDALVersionInfo`](https://gdal.org/api/raster_c_api.html#_CPPv415GDALVersionInfoPKc) for details.

use crate::utils::_string;
use std::ffi::CString;

Expand Down
6 changes: 6 additions & 0 deletions src/vsi.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
//! GDAL Virtual File System Library Functions
//!
//! This module provides safe access to a subset of the [GDAL VSI Functions](https://gdal.org/doxygen/cpl__vsi_8h.html).
//! See [GDAL Virtual File Systems document](https://gdal.org/user/virtual_file_systems.html) for details.
//!

use std::marker::PhantomData;
use std::mem::ManuallyDrop;
use std::path::{Path, PathBuf};
Expand Down