OxiGDAL Shapefile Driver
A pure Rust implementation of ESRI Shapefile format support for the OxiGDAL ecosystem. Read and write complete Shapefiles (.shp, .dbf, .shx) with full geometry type support, attribute handling, and spatial indexing.
Features
- Pure Rust Implementation - Zero C/C++/Fortran dependencies; works everywhere Rust compiles
- Complete File Format Support - Reads and writes all three core files (.shp geometry, .dbf attributes, .shx spatial index)
- 14 Geometry Types - Point, PointZ, PointM, PolyLine, PolyLineZ, PolyLineM, Polygon, PolygonZ, PolygonM, MultiPoint, MultiPointZ, MultiPointM, MultiPatch, and Null types
- All DBF Field Types - Character, Number, Logical, Date, and Float fields with proper encoding
- Spatial Indexing - SHX file support for fast random access to records
- Round-Trip Compatibility - Read → modify → write workflow without data loss
- No Unsafe - Sound error handling with comprehensive
Result<T>types; nounwrap()orpanic!()in production code - Buffered I/O - Efficient streaming for large files
- OxiGDAL Integration - Native conversion to/from OxiGDAL vector types
- Feature Flags - Optional async, Arrow support, and no-std compatibility
Installation
Add to your Cargo.toml:
[]
= "0.1"
Optional Features
[]
= { = "0.1", = ["async", "arrow"] }
std(default) - Standard library supportasync- Tokio-based asynchronous I/Oarrow- Apache Arrow integration for columnar operations
Quick Start
Reading Shapefiles
use ShapefileReader;
Writing Shapefiles
use ;
use ShapeType;
use ShapefileSchemaBuilder;
use ;
use HashMap;
Usage Examples
Reading Individual Records
use ShapefileReader;
use Path;
Working with Different Geometry Types
use ShapeType;
// Check geometry type capabilities
let point_type = Point;
assert!;
assert!;
let point_z = PointZ;
assert!;
assert!;
let point_m = PointM;
assert!;
assert!;
// Polygon with Z coordinates
let polygon_z = PolygonZ;
assert!;
Building Complex Schemas
use ShapefileSchemaBuilder;
let schema = new
// Character fields (up to 254 characters)
.add_character_field?
.add_character_field?
// Numeric fields (precision.scale)
.add_numeric_field?
.add_numeric_field?
// Other field types
.add_logical_field?
.add_date_field?
.add_float_field?
.build;
Error Handling
use ;
// All errors use Result<T> pattern - no unwrap() calls
match read_safely
API Overview
Core Types
| Type | Description |
|---|---|
ShapefileReader |
High-level interface for reading complete Shapefiles |
ShapefileWriter |
High-level interface for writing Shapefiles |
ShapefileFeature |
Combines geometry and attributes from a Shapefile record |
ShapeType |
Enum of all 14 supported geometry types |
ShapefileError |
Comprehensive error type with contextual information |
Geometry Modules
| Module | Description |
|---|---|
shp |
Shapefile geometry format (.shp files) and Shape types |
dbf |
dBase attribute format (.dbf files), field types, and records |
shx |
Spatial index format (.shx files) for fast record access |
reader |
High-level reading interface combining all three files |
writer |
High-level writing interface with schema builder |
error |
Comprehensive error handling with Result type |
Key Traits
FieldType- Enumeration of DBF field typesFieldValue- Attribute values (String, Integer, Float, Date, Logical)Geometry- OxiGDAL integration for vector geometries
Supported Geometry Types
2D Geometries
- Point - Single coordinate point
- PolyLine - Connected line segments (LineString)
- Polygon - Closed rings with optional holes
- MultiPoint - Multiple disconnected points
3D Geometries (with Z)
- PointZ - Point with elevation/height
- PolyLineZ - LineString with Z coordinates
- PolygonZ - Polygon with Z coordinates
- MultiPointZ - MultiPoint with Z coordinates
Measured Geometries (with M)
- PointM - Point with measurement value
- PolyLineM - LineString with M values
- PolygonM - Polygon with M values
- MultiPointM - MultiPoint with M values
Other
- MultiPatch - 3D surface (limited support)
- Null - Empty geometry
Supported DBF Field Types
| Type | Description | Max Length |
|---|---|---|
| Character | Text strings | 254 bytes |
| Number | Fixed-point numbers with precision | 20 digits |
| Float | Double-precision floating point | 20 digits |
| Logical | Boolean (Y/N) | 1 byte |
| Date | Calendar dates (YYYYMMDD) | 8 bytes |
File Format Details
Shapefile (.shp)
Header (100 bytes):
[0-3] File Code (9994 - big endian)
[4-7] File Length in 16-bit words (big endian)
[8-11] Version (1000 - little endian)
[12-15] Shape Type (little endian)
[16-83] Bounding Box (4 doubles: Xmin, Ymin, Xmax, Ymax)
[84-99] Z/M ranges (if 3D)
Records (variable):
[0-3] Record Number (big endian)
[4-7] Content Length in 16-bit words (big endian)
[8+] Shape content (little endian)
dBase (.dbf)
Header (32 bytes):
[0] Version
[1-3] Last Update (YY, MM, DD)
[4-7] Record Count
[8-9] Header Size
[10-11] Record Size
[12-31] Reserved
Field Descriptors (32 bytes each):
[0-10] Field Name (null-padded)
[11] Field Type (C/N/F/L/D)
[12-15] Reserved
[16] Field Length
[17] Decimal Count
[18-31] Reserved
Record Data:
[0] Deletion Flag (0x20 = active, 0x2A = deleted)
[1+] Field data (fixed-length)
Terminator: 0x1A
Spatial Index (.shx)
Header (100 bytes): Same as .shp
Index Entries (8 bytes each):
[0-3] Record Offset in 16-bit words (big endian)
[4-7] Content Length in 16-bit words (big endian)
Performance Characteristics
Reading
- Header parsing: Negligible (O(1))
- Feature loading: O(n) where n = number of features
- Memory usage: One feature at a time with streaming API (future)
- Large files: Buffered I/O optimizes disk access
Writing
- Feature writing: O(n) with automatic bounding box calculation
- File generation: All three files (.shp, .dbf, .shx) written simultaneously
- Validation: Compile-time type safety + runtime error checking
Examples
See the examples directory for practical demonstrations:
create_test_shapefile_samples.rs- Create Shapefiles with various geometry typesverify_shapefile_samples.rs- Read and validate Shapefile integrity
Run examples with:
Integration with OxiGDAL
Convert to OxiGDAL types:
use ShapefileReader;
let reader = open?;
let shapefile_features = reader.read_features?;
// Convert to OxiGDAL Features
let oxigdal_features: = shapefile_features
.iter
.map
.collect;
Create from OxiGDAL types:
use ;
use Feature;
COOLJAPAN Policies
This library strictly adheres to COOLJAPAN ecosystem standards:
Pure Rust
- 100% pure Rust with zero C/C++/Fortran dependencies
- Works on any platform that Rust supports
- No platform-specific code or conditional compilation (except
stdfeature)
No unwrap() Policy
- All fallible operations return descriptive
Result<T, ShapefileError> - Comprehensive error types with contextual information
- Safe error handling throughout the entire codebase
Clean Architecture
- Single-responsibility modules (shp, dbf, shx, reader, writer)
- Clear public API with re-exports
- Extensive documentation with examples
- All files kept under 2000 lines using splitrs if needed
Testing
- Unit tests for all major functions
- Integration tests for round-trip operations
- Property-based tests for format validation
- Comprehensive error case coverage
Performance
- Zero-copy where possible
- Buffered I/O for large files
- Efficient spatial indexing
Limitations
- Point geometry conversion to OxiGDAL is fully supported
- PolyLine, Polygon, and MultiPoint parsing is implemented, conversion pending
- MultiPatch (3D surfaces) has limited support
- No support for memo fields (.dbt files)
- No support for extended .prj (projection) parsing beyond reading
- Single-threaded design (async feature for I/O only)
References
Testing
Run the full test suite:
Run with no default features:
Run specific examples:
Documentation
Full API documentation is available at docs.rs/oxigdal-shapefile.
Generate local documentation:
Contributing
Contributions are welcome! Please ensure:
- All tests pass:
cargo test --all-features - No clippy warnings:
cargo clippy --all-features - Code adheres to COOLJAPAN policies (no unwrap, pure Rust, etc.)
- Documentation is updated for public APIs
License
Licensed under the Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0).
Related Projects
Part of the OxiGDAL ecosystem:
- OxiGDAL Core - Pure Rust GDAL alternative
- OxiGDAL Drivers - Format drivers (GeoTIFF, NetCDF, HDF5, etc.)
- SciRS2 - Scientific computing ecosystem
- NumRS2 - Numerical computing (NumPy-like)
- OxiBLAS - Pure Rust BLAS operations
- Oxicode - Rust serialization (bincode replacement)
Part of the COOLJAPAN ecosystem - Pure Rust geospatial and scientific computing.