Class: RTree

Inherits:
Object
  • Object
show all
Defined in:
lib/nswtopo/geometry/r_tree.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(nodes, bounds, object = nil) ⇒ RTree

Returns a new instance of RTree.



4
5
6
# File 'lib/nswtopo/geometry/r_tree.rb', line 4

def initialize(nodes, bounds, object = nil)
  @nodes, @bounds, @object = nodes, bounds, object
end

Instance Attribute Details

#boundsObject (readonly)

Returns the value of attribute bounds.



8
9
10
# File 'lib/nswtopo/geometry/r_tree.rb', line 8

def bounds
  @bounds
end

Class Method Details

.load(objects, &bounds) ⇒ Object



18
19
20
# File 'lib/nswtopo/geometry/r_tree.rb', line 18

def self.load(objects, &bounds)
  load! objects.map(&bounds).zip(objects)
end

.load!(bounds_objects, range = 0...bounds_objects.length) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/nswtopo/geometry/r_tree.rb', line 22

def self.load!(bounds_objects, range = 0...bounds_objects.length)
  return RTree.new([], *bounds_objects[range.begin]) if range.one?
  bounds_objects.median_partition!(range) do |bounds, object|
    bounds[0].sum
  end.flat_map do |range|
    bounds_objects.median_partition!(range) do |bounds, object|
      bounds[1].sum
    end
  end.filter_map do |range|
    load!(bounds_objects, range) if range.any?
  end.then do |nodes|
    RTree.new nodes, nodes.map(&:bounds).transpose.map(&:flatten).map(&:minmax)
  end
end

Instance Method Details

#each {|@bounds, @object| ... } ⇒ Object

Yields:



48
49
50
51
52
53
# File 'lib/nswtopo/geometry/r_tree.rb', line 48

def each(&block)
  @nodes.each do |node|
    node.each(&block)
  end
  yield @bounds, @object if @object
end

#overlaps?(bounds, buffer) ⇒ Boolean

Returns:

  • (Boolean)


10
11
12
13
14
15
16
# File 'lib/nswtopo/geometry/r_tree.rb', line 10

def overlaps?(bounds, buffer)
  return false if @bounds.empty?
  return true unless bounds
  bounds.zip(@bounds).all? do |(min1, max1), (min2, max2)|
    max1 + buffer >= min2 && max2 + buffer >= min1
  end
end

#search(bounds, buffer = 0) ⇒ Object



37
38
39
40
41
42
43
44
45
46
# File 'lib/nswtopo/geometry/r_tree.rb', line 37

def search(bounds, buffer = 0)
  Enumerator.new do |yielder|
    if overlaps? bounds, buffer
      @nodes.each do |node|
        node.search(bounds, buffer).each(&yielder)
      end
      yielder << @object if @nodes.empty?
    end
  end
end