iOverlay
iOverlay is a high-performance polygon overlay engine for Rust. It solves robust boolean operations on complex polygons for GIS, CAD, and graphics workflows, built for developers who need reliable geometry at scale across integer and floating-point APIs.
iOverlay powers polygon boolean operations in geo.
Table of Contents
- Why iOverlay?
- Features
- Demo
- Performance
- Getting Started
- Boolean Operations
- Custom Point Type Support
- Slicing & Clipping
- Buffering
- FAQ
- Versioning Policy
- License
Why iOverlay?
- Built for robust polygon overlays where precision matters (GIS, CAD, graphics).
- High performance with predictable results across complex inputs.
- Supports both integer and floating-point APIs for flexible pipelines.
- OGC-valid output is available when strict topology is required.
- Core overlay engine used in geo.
Features
- Boolean Operations: union, intersection, difference, and exclusion.
- Polyline Operations: clip and slice.
- Polygons: with holes, self-intersections, and multiple contours.
- Simplification: removes degenerate vertices and merges collinear edges.
- Buffering: offsets paths and polygons.
- Fill Rules: even-odd, non-zero, positive and negative.
- Data Types: Supports i32, f32, and f64 APIs.
Demo
Performance
iOverlay is optimized for large and complex inputs while preserving robust geometry semantics. The benchmark report compares iOverlay to other polygon overlay engines with a focus on throughput and performance.
See the detailed report: Performance Comparison
Getting Started
Add the following to your Cargo.toml:
[dependencies]
i_overlay = "^4.0"
Read full documentation
Quick Start
use FillRule;
use OverlayRule;
use SingleFloatOverlay;
let subj = ;
let clip = ;
let result = subj.overlay;
println!;
Boolean Operations
Simple Example
use FillRule;
use OverlayRule;
use SingleFloatOverlay;
// Define the subject "O"
let subj = ;
// Define the clip "-"
let clip = ;
let result = subj.overlay;
println!;
The result is a vec of shapes:
The overlay function returns a Vec<Shapes>:
Vec<Shape>: A collection of shapes.Shape: Represents a shape made up of:Vec<Contour>: A list of contours.- The first contour is the outer boundary (counterclockwise), and subsequent contours represent holes (clockwise).
Contour: A sequence of points (Vec<P: FloatPointCompatible>) forming a closed contour.
Note: By default, outer boundaries are counterclockwise and holes are clockwise—unless main_direction is set. More information about contours.
Overlay Rules
| A,B | A ∪ B | A ∩ B | A - B | B - A | A ⊕ B |
|---|---|---|---|---|---|
Custom Point Type Support
iOverlay allows users to define custom point types, as long as they implement the FloatPointCompatible trait.
use FloatPointCompatible;
use FillRule;
use OverlayRule;
use SingleFloatOverlay;
let subj = ;
let clip = ;
let result = subj.overlay;
println!;
Slicing & Clipping
Slicing a Polygon with a Polyline
use FillRule;
use FloatSlice;
let polygon = ;
let slicing_line = ;
let result = polygon.slice_by;
println!;
Clipping a Polyline by a Polygon
use FillRule;
use FloatClip;
use ClipRule;
let polygon = ;
let string_line = ;
let clip_rule = ClipRule ;
let result = string_line.clip_by;
println!;
Buffering
Offsetting a Path
use StrokeOffset;
use ;
let path = ;
let style = new
.line_join
.start_cap
.end_cap;
let shapes = path.stroke;
println!;
Offsetting a Polygon
use OutlineOffset;
use ;
let shape = vec!;
let style = new.line_join;
let shapes = shape.outline;
println!;
Note:
-
Offsetting a polygon works reliably only with valid polygons. Ensure that:
- No self-intersections.
- Outer boundaries are counterclockwise, holes are clockwise—unless
main_directionis set.
If polygon validity cannot be guaranteed, it is recommended to apply the simplify_shape operation before offsetting.
More information on contour orientation. -
Using
LineJoin::Bevelwith a large offset may produce visual artifacts.
LineCap
| Butt | Square | Round | Custom |
|---|---|---|---|
LineJoin
| Bevel | Miter | Round |
|---|---|---|
FAQ
1. When should I use FloatOverlay, SingleFloatOverlay, or FloatOverlayGraph?
-
Use
FloatOverlaywhen you perform repeated overlay operations:let mut overlay = new; loop -
Use
SingleFloatOverlaytrait for one-shot operations. -
Use
FloatOverlayGraphif you need to extract multiple boolean results (e.g. union and intersection) from the same input geometry without recomputing.
2. I need to union many shapes at once. What's the most efficient way?
Use the simplify operation:
let result = shapes.simplify;
It internally merges shapes efficiently and is typically faster and more robust than chaining many overlay() calls manually.
3. How do I use a fixed grid size (fixed precision) for float overlays?
Use FixedScaleFloatOverlay or FloatOverlay::with_subj_and_clip_fixed_scale. The scale is
scale = 1.0 / grid_size.
use FillRule;
use OverlayRule;
use FixedScaleFloatOverlay;
let subj = vec!;
let clip = vec!;
let grid_size = 0.001;
let scale = 1.0 / grid_size;
let result = subj
.overlay_with_fixed_scale
.expect;
If you need more control, use FloatPointAdapter::with_scale and FloatOverlay::with_adapter.
4. How do I enable OGC-valid output?
Set the ocg flag in OverlayOptions.
use FillRule;
use OverlayRule;
use ;
// 0 1 2 3 4 5
// 5 ┌───────────────────┐
// │ │
// 4 │ ┌───────┐ │
// │ │ ░ ░ │ │ Two L-shaped holes share vertices at (2,2) and (3,3)
// 3 │ │ ┌───●───┐ │
// │ │ ░ │ │ ░ │ │ ░ = holes
// 2 │ └───●───┘ │ │
// │ │ ░ ░ │ │ The shared edge disconnects the interior
// 1 │ └───────┘ │
// │ │
// 0 └───────────────────┘
//
// OGC Simple Feature Specification (ISO 19125-1) states:
// "The interior of every Surface is a connected point set."
let subj = vec!;
let clip = vec!;
let options = ocg;
let mut overlay = with_subj_and_clip_custom;
let result = overlay.overlay;
assert_eq!;
Versioning Policy
This crate follows a pragmatic versioning approach:
PATCH updates (e.g., 1.8.1 → 1.8.2): Guaranteed to be backward-compatible, containing only bug fixes or small improvements.
MINOR updates (e.g., 1.8.0 → 1.9.0): Typically backward-compatible but may include changes to experimental or less commonly used APIs.
MAJOR updates (e.g., 1.x.x → 2.x.x): Reserved for significant breaking changes or major redesigns.
To minimize disruption, consider pinning dependencies when relying on specific versions.
License
Licensed under either of:
- MIT license (LICENSE-MIT)
- Apache License, Version 2.0 (LICENSE-APACHE)