Class: GeoTreeModule::MultiTree

Inherits:
Object
  • Object
show all
Defined in:
lib/geotree/multitree.rb

Overview

See the README file for a description of this class.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, num_trees) ⇒ MultiTree

Construct MultiTree

Parameters:

  • path

    directory to store trees within

  • num_trees

    the number of trees to maintain (equivalently, the number of levels of detail to support)

Raises:

  • (ArgumentError)


17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/geotree/multitree.rb', line 17

def initialize(path,num_trees)
  @buffer = PtBuffer.new(self)
  @num_trees = num_trees
  raise ArgumentError if File.file?(path)

  @trees = []

  if !File.directory?(path)
    Dir::mkdir(path)
  end

  # Construct trees within this directory
  num_trees.times do |i|
    tp = File.join(path,"tree_#{i}.bin")
    t = GeoTree.open(tp)
    @trees << t
  end

  prepare_details
end

Instance Attribute Details

#num_treesObject (readonly)

Returns the value of attribute num_trees.



10
11
12
# File 'lib/geotree/multitree.rb', line 10

def num_trees
  @num_trees
end

Instance Method Details

#add(data_point) ⇒ Object

Add a datapoint to the trees. Does not ensure that a datapoint with this name already exists in the tree, even if it has the same location.



69
70
71
72
# File 'lib/geotree/multitree.rb', line 69

def add(data_point)
  raise IllegalStateException if !open?
  @buffer.add(data_point)
end

#add_buffered_point(data_point) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/geotree/multitree.rb', line 112

def add_buffered_point(data_point)
  
  # Determine which is the lowest detail level at which
  # this point is to be found

  stretch = 1.5
  contract = 0.5
  rf = rand() - contract

  wt = data_point.weight & (MAX_POINT_WEIGHT-1)

  randval = (wt + stretch*rf) / MAX_POINT_WEIGHT

  num_trees.times do |ti|
    di = num_trees - 1 - ti

    if ti > 0 && randval < @cutoffs[di]
      break
    end

    tree(di).add_buffered_point(data_point)
  end
end

#bufferingObject



38
39
40
# File 'lib/geotree/multitree.rb', line 38

def buffering
  @buffer.active
end

#buffering=(val) ⇒ Object



42
43
44
45
46
47
48
# File 'lib/geotree/multitree.rb', line 42

def buffering=(val)
  db = false

  raise IllegalStateException if !open?

  @buffer.active = val
end

#closeObject



54
55
56
57
58
59
60
61
62
63
# File 'lib/geotree/multitree.rb', line 54

def close
  raise IllegalStateException if !open?

  # Stop buffering, in case we were, to flush points to tree
  @buffer.active = false

  @trees.each{|t| t.close}
  @trees = nil

end

#find(rect, detail) ⇒ Object

Find all points intersecting a rectangle.

Parameters:

  • rect

    query rectangle

  • detail

    level of detail, 0…num_trees-1

Raises:



101
102
103
104
# File 'lib/geotree/multitree.rb', line 101

def find(rect, detail)
  raise IllegalStateException if (!open? || @buffer.active)
  tree(detail).find(rect)
end

#find_point(df, detail) ⇒ Object

Determine if a particular datapoint lies in the tree



107
108
109
110
# File 'lib/geotree/multitree.rb', line 107

def find_point(df, detail)
  raise IllegalStateException if (!open? || @buffer.active)
  tree(detail).find(rect)
end

#open?Boolean

Returns:

  • (Boolean)


50
51
52
# File 'lib/geotree/multitree.rb', line 50

def open?
  @trees != nil
end

#remove(data_point) ⇒ Object

Remove a datapoint. Returns the datapoint if it was found and removed, otherwise nil. A datapoint will be removed iff both its name and location match the sought point; the weight is ignored.



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/geotree/multitree.rb', line 78

def remove(data_point)

  raise IllegalStateException if  @buffer.active

  removed = nil

  # Start with highest-detail tree, and continue to remove the
  # same point until we reach a tree that doesn't contain it
  @trees.each do |t|
    rem = t.remove(data_point)
    if rem
      removed = true
    else
      break  # assume it's not in any lower detail tree
    end
  end
  removed
end