Class: Geokdtree::Tree
- Inherits:
-
Object
- Object
- Geokdtree::Tree
- Defined in:
- lib/geokdtree/tree.rb
Class Method Summary collapse
-
.distance(pointa, pointb) ⇒ Float
compute the Euclidean distance between 2 points of n dimensions.
-
.geo_distance(pointa, pointb, units = :mi) ⇒ Float
compute the geo distance between 2 points of latitude, longitude.
Instance Method Summary collapse
-
#initialize(dimensions) ⇒ Tree
constructor
A new instance of Tree.
-
#insert(point, data = nil) ⇒ Tree
insert a point of n dimensions and arbritary associated object.
-
#nearest(point) ⇒ ResultPoint
find the given point nearest neighbor.
-
#nearest_geo_range(point, range, units = :mi) ⇒ Array<ResultPoint>
find all the given point neighbors within the given geo range.
-
#nearest_range(point, range) ⇒ Array<ResultPoint>
find all the given point neighbors within the given Euclidean range.
Constructor Details
#initialize(dimensions) ⇒ Tree
Returns a new instance of Tree.
22 23 24 25 26 27 |
# File 'lib/geokdtree/tree.rb', line 22 def initialize(dimensions) @dimensions = dimensions @tree = KdtreePointer.new(C::kd_create(dimensions)) @data_cache = {} @data_id = 0 end |
Class Method Details
.distance(pointa, pointb) ⇒ Float
compute the Euclidean distance between 2 points of n dimensions
87 88 89 90 91 92 |
# File 'lib/geokdtree/tree.rb', line 87 def self.distance(pointa, pointb) case k = pointa.size when 2 then C::euclidean_distance2(pointa[0].to_f, pointa[1].to_f, pointb[0].to_f, pointb[1].to_f) else C::euclidean_distance(allocate_doubles(pointa), allocate_doubles(pointb), k) end end |
.geo_distance(pointa, pointb, units = :mi) ⇒ Float
compute the geo distance between 2 points of latitude, longitude
99 100 101 |
# File 'lib/geokdtree/tree.rb', line 99 def self.geo_distance(pointa, pointb, units = :mi) C::slc_distance2(pointa[0].to_f, pointa[1].to_f, pointb[0].to_f, pointb[1].to_f, units == :mi ? RADIUS_MI : RADIUS_KM) end |
Instance Method Details
#insert(point, data = nil) ⇒ Tree
insert a point of n dimensions and arbritary associated object
33 34 35 36 37 38 39 40 41 42 |
# File 'lib/geokdtree/tree.rb', line 33 def insert(point, data = nil) # here we don't actually pass a pointer to our data but the object numeric key encoded into the pointer r = case point.size when 2 then C::kd_insert2(@tree, point[0].to_f, point[1].to_f, cache(data)) when 3 then C::kd_insert3(@tree, point[0].to_f, point[1].to_f, point[2].to_f, cache(data)) else C::kd_insert(@tree, Tree.allocate_doubles(point), cache(data)) end raise("error on Tree#insert, code=#{r}") unless r.zero? self end |
#nearest(point) ⇒ ResultPoint
find the given point nearest neighbor
47 48 49 50 51 52 53 54 55 |
# File 'lib/geokdtree/tree.rb', line 47 def nearest(point) set = case point.size when 2 then C::kd_nearest2(@tree, point[0].to_f, point[1].to_f) when 3 then C::kd_nearest3(@tree, point[0].to_f, point[1].to_f, point[2].to_f) else C::kd_nearest(@tree, Tree.allocate_doubles(point)) end return nil if set.null? retrieve_results(set).first end |
#nearest_geo_range(point, range, units = :mi) ⇒ Array<ResultPoint>
find all the given point neighbors within the given geo range
76 77 78 79 80 81 |
# File 'lib/geokdtree/tree.rb', line 76 def nearest_geo_range(point, range, units = :mi) raise("must have 2 dimensions for geo methods") unless @dimensions == 2 set = C::kd_nearest_geo_range(@tree, point[0].to_f, point[1].to_f, range.to_f, units == :mi ? GEO_UNITS_MI : GEO_UNITS_KM) return [] if set.null? retrieve_results(set) end |
#nearest_range(point, range) ⇒ Array<ResultPoint>
find all the given point neighbors within the given Euclidean range
61 62 63 64 65 66 67 68 69 |
# File 'lib/geokdtree/tree.rb', line 61 def nearest_range(point, range) set = case point.size when 2 then C::kd_nearest_range2(@tree, point[0].to_f, point[1].to_f, range.to_f) when 3 then C::kd_nearest_range3(@tree, point[0].to_f, point[1].to_f, point[2].to_f, range.to_f) else C::kd_nearest_range(@tree, Tree.allocate_doubles(point), range.to_f) end return [] if set.null? retrieve_results(set) end |