This guide explains how to contribute to geodatafusion, a spatial extension for Apache DataFusion.
This is a Rust workspace with multiple crates:
rust/geodatafusion- Core library with spatial User-Defined Functions (UDFs)- Internally, each provider of functions is organized in submodules:
native/- Operations that are natively implemented, without the use of other dependencies likegeogeo/- Operations implemented using thegeocrategeohash/- GeoHash encoding/decoding, using thegeohashcrate
- Internally, each provider of functions is organized in submodules:
rust/geodatafusion-flatgeobuf- FlatGeobuf format supportrust/geodatafusion-geoparquet- GeoParquet format supportrust/geodatafusion-geojson- GeoJSON format supportpython/- Python bindings (separate workspace)
- Rust. The minimum supported Rust version (MSRV) is defined by
rust-versioninCargo.toml. You can update Rust using rustup:rustup update stable.
git clone https://github.com/datafusion-contrib/geodatafusion.git
cd geodatafusion# Build all Rust crates
cargo build
# Build with all features
cargo build --all-features# Run all Rust tests
cargo test --all-features
# Run tests for a specific crate
cargo test -p geodatafusionWe use rustfmt:
cargo +nightly-2025-05-14 fmt -- --unstable-features \
--config imports_granularity=Module,group_imports=StdExternalCrateWe use the nightly compiler for formatting because import ordering is an unstable feature.
Run clippy on all crates
cargo clippy --all-features --tests -- -D warningsBuild and view documentation
cargo doc --all-features --openWe follow the PostGIS API as closely as possible. When implementing a new function:
- Check the README - See if the function is listed in the function table
- Find similar implementations - Look at existing functions in the same category
- Implement the function - Follow existing patterns in
rust/geodatafusion/src/udf/ - Add tests - Include unit tests and integration tests
- Update documentation - Add doc comments and update the README checkboxes
Functions are organized by category in rust/geodatafusion/src/udf/:
native/constructors/- Geometry constructors (ST_MakePoint, etc.)native/accessors/- Geometry accessors (ST_X, ST_Y, etc.)native/io/- Input/output (WKT, WKB)native/bounding_box/- Bounding box functionsgeo/measurement/- Measurement functions (ST_Area, ST_Distance)geo/processing/- Processing functions (ST_Buffer, ST_Simplify)geo/relationships/- Spatial relationships (ST_Intersects, etc.)geo/validation/- Validation functions (ST_IsValid)geohash/- GeoHash functions
- Use meaningful variable and function names
- Add doc comments for public APIs
- Follow Rust naming conventions (snake_case for functions, PascalCase for types)
- Keep functions focused and single-purpose
- Prefer explicit error handling over panics
- Test both valid and invalid inputs
- Test edge cases (empty geometries, null values, etc.)
- Use descriptive test names
- Add SQL integration tests when appropriate
- Test against PostGIS behavior when possible
Example test structure:
#[test]
fn test_st_area_polygon() {
// Test case description
let input = /* ... */;
let expected = /* ... */;
let result = st_area(input);
assert_eq!(result, expected);
}Our CI pipeline runs on every pull request and includes:
- Formatting - Checks code formatting with
rustfmt - Linting - Runs
clippywith all features - Tests - Runs test suite with all features
- Documentation - Ensures docs build without warnings
- Python CI - Tests Python bindings
- Conventional Commits - Validates commit message format
Make sure all checks pass before requesting review.
We use Conventional Commits:
<type>(<scope>): <description>
[optional body]
[optional footer]
Types:
feat: New featurefix: Bug fixdocs: Documentation changestest: Adding or updating testsrefactor: Code refactoringchore: Maintenance tasksci: CI/CD changes
Examples:
feat(geodatafusion): Add ST_Buffer implementation
fix(geodatafusion-flatgeobuf): Handle multipoint parsing edge case
docs: Update README with ST_Area examples
- Issues: Open an issue on GitHub
- Discussions: Use GitHub Discussions for questions
- Documentation: Check the README and PostGIS docs
This project is dual-licensed under MIT OR Apache-2.0. By contributing, you agree to license your contributions under the same terms.