Class: Tabula::SpatialIndex
- Inherits:
-
Object
- Object
- Tabula::SpatialIndex
- Defined in:
- lib/tabula/core/spatial_index.rb
Overview
Spatial index for efficient rectangle queries. Uses a simple grid-based approach for O(1) average lookup.
Instance Attribute Summary collapse
-
#rectangles ⇒ Object
readonly
Returns the value of attribute rectangles.
Instance Method Summary collapse
-
#add(rectangle) ⇒ Object
Add a rectangle to the index.
-
#add_all(rectangles) ⇒ Object
Add multiple rectangles.
-
#at_point(point) ⇒ Array<Rectangle>
Find all rectangles that contain the query point.
-
#bounds ⇒ Rectangle?
Compute bounding box of all indexed rectangles.
-
#clear ⇒ Object
Clear all indexed rectangles.
-
#contains(query) ⇒ Array<Rectangle>
Find all rectangles that are fully contained within the query rectangle.
- #empty? ⇒ Boolean
-
#initialize(cell_size: 50.0) ⇒ SpatialIndex
constructor
A new instance of SpatialIndex.
-
#intersects(query) ⇒ Array<Rectangle>
Find all rectangles that intersect with the query rectangle.
-
#nearby(query, distance) ⇒ Array<Rectangle>
Find rectangles within a given distance of the query rectangle.
-
#size ⇒ Object
Number of indexed rectangles.
Constructor Details
#initialize(cell_size: 50.0) ⇒ SpatialIndex
Returns a new instance of SpatialIndex.
10 11 12 13 14 |
# File 'lib/tabula/core/spatial_index.rb', line 10 def initialize(cell_size: 50.0) @cell_size = cell_size @grid = Hash.new { |h, k| h[k] = [] } @rectangles = [] end |
Instance Attribute Details
#rectangles ⇒ Object (readonly)
Returns the value of attribute rectangles.
7 8 9 |
# File 'lib/tabula/core/spatial_index.rb', line 7 def rectangles @rectangles end |
Instance Method Details
#add(rectangle) ⇒ Object
Add a rectangle to the index
18 19 20 21 22 23 24 |
# File 'lib/tabula/core/spatial_index.rb', line 18 def add(rectangle) @rectangles << rectangle cells_for(rectangle).each do |cell| @grid[cell] << rectangle end self end |
#add_all(rectangles) ⇒ Object
Add multiple rectangles
28 29 30 31 |
# File 'lib/tabula/core/spatial_index.rb', line 28 def add_all(rectangles) rectangles.each { |r| add(r) } self end |
#at_point(point) ⇒ Array<Rectangle>
Find all rectangles that contain the query point
52 53 54 55 |
# File 'lib/tabula/core/spatial_index.rb', line 52 def at_point(point) cell = cell_for_point(point) @grid[cell].select { |r| r.contains_point?(point) } end |
#bounds ⇒ Rectangle?
Compute bounding box of all indexed rectangles
73 74 75 |
# File 'lib/tabula/core/spatial_index.rb', line 73 def bounds Rectangle.bounding_box_of(@rectangles) end |
#clear ⇒ Object
Clear all indexed rectangles
87 88 89 90 91 |
# File 'lib/tabula/core/spatial_index.rb', line 87 def clear @grid.clear @rectangles.clear self end |
#contains(query) ⇒ Array<Rectangle>
Find all rectangles that are fully contained within the query rectangle
44 45 46 47 |
# File 'lib/tabula/core/spatial_index.rb', line 44 def contains(query) candidates = candidate_set(query) candidates.select { |r| query.contains?(r) } end |
#empty? ⇒ Boolean
82 83 84 |
# File 'lib/tabula/core/spatial_index.rb', line 82 def empty? @rectangles.empty? end |
#intersects(query) ⇒ Array<Rectangle>
Find all rectangles that intersect with the query rectangle
36 37 38 39 |
# File 'lib/tabula/core/spatial_index.rb', line 36 def intersects(query) candidates = candidate_set(query) candidates.select { |r| r.intersects?(query) } end |
#nearby(query, distance) ⇒ Array<Rectangle>
Find rectangles within a given distance of the query rectangle
61 62 63 64 65 66 67 68 69 |
# File 'lib/tabula/core/spatial_index.rb', line 61 def nearby(query, distance) = Rectangle.from_bounds( query.top - distance, query.left - distance, query.bottom + distance, query.right + distance ) intersects() end |
#size ⇒ Object
Number of indexed rectangles
78 79 80 |
# File 'lib/tabula/core/spatial_index.rb', line 78 def size @rectangles.size end |