Class: Geospatial::Map

Inherits:
Object
  • Object
show all
Defined in:
lib/geospatial/map.rb,
lib/geospatial/map/index.rb

Defined Under Namespace

Classes: Index

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(curve) ⇒ Map

Returns a new instance of Map.


64
65
66
67
68
# File 'lib/geospatial/map.rb', line 64

def initialize(curve)
	@curve = curve
	@points = []
	@bounds = nil
end

Instance Attribute Details

#curveObject (readonly)

Returns the value of attribute curve


70
71
72
# File 'lib/geospatial/map.rb', line 70

def curve
  @curve
end

#pointsObject (readonly)

Returns the value of attribute points


87
88
89
# File 'lib/geospatial/map.rb', line 87

def points
  @points
end

Class Method Details

.for_earth(order = 20) ⇒ Object


60
61
62
# File 'lib/geospatial/map.rb', line 60

def self.for_earth(order = 20)
	self.new(Hilbert::Curve.new(Dimensions.for_earth, order))
end

Instance Method Details

#<<(object) ⇒ Object


105
106
107
108
109
# File 'lib/geospatial/map.rb', line 105

def << object
	@points << point_for_coordinates(object.to_a, object)
	
	return self
end

#boundsObject


76
77
78
79
80
81
82
83
84
85
# File 'lib/geospatial/map.rb', line 76

def bounds
	unless @bounds
		origin = @curve.origin
		size = @curve.size
		
		@bounds = Box.new(origin, size)
	end
	
	return @bounds
end

#countObject


111
112
113
# File 'lib/geospatial/map.rb', line 111

def count
	@points.count
end

#filter_for(*regions, **options) ⇒ Object


148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/geospatial/map.rb', line 148

def filter_for(*regions, **options)
	filter = Filter.new(@curve)
	
	regions.each do |region|
		# The filter will coalesce sequential segments of the curve into a single range.
		traverse(region, **options) do |child, prefix, order|
			filter.add(prefix, order)
		end
	end
	
	return filter
end

#hash_for_coordinates(coordinates) ⇒ Object


89
90
91
# File 'lib/geospatial/map.rb', line 89

def hash_for_coordinates(coordinates)
	@curve.map(coordinates)
end

#indexObject

serialize :point, Map.for_earth.index


49
50
51
52
53
54
55
# File 'lib/geospatial/map/index.rb', line 49

def index
	klass = Class.new(Index)
	
	klass.map = self
	
	return klass
end

#orderObject


72
73
74
# File 'lib/geospatial/map.rb', line 72

def order
	@curve.order
end

#point_for_coordinates(coordinates, object = nil) ⇒ Object


97
98
99
# File 'lib/geospatial/map.rb', line 97

def point_for_coordinates(coordinates, object = nil)
	Point.new(self, coordinates, object)
end

#point_for_hash(hash) ⇒ Object


93
94
95
# File 'lib/geospatial/map.rb', line 93

def point_for_hash(hash)
	Point.new(self, @curve.unmap(hash))
end

#point_for_object(object) ⇒ Object


101
102
103
# File 'lib/geospatial/map.rb', line 101

def point_for_object(object)
	Point.new(self, object.to_a, object)
end

#query(region, **options) ⇒ Object


119
120
121
122
123
# File 'lib/geospatial/map.rb', line 119

def query(region, **options)
	filter = filter_for(region, **options)
	
	return filter.apply(@points).map(&:object)
end

#sort!Object


115
116
117
# File 'lib/geospatial/map.rb', line 115

def sort!
	@points.sort_by!(&:hash)
end

#traverse(region, depth: 0) ⇒ Object


125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/geospatial/map.rb', line 125

def traverse(region, depth: 0)
	@curve.traverse do |child_origin, child_size, prefix, order|
		child = Box.new(Vector.elements(child_origin), Vector.elements(child_size))
		
		# puts "Considering (order=#{order}) #{child.inspect}..."
		
		if region.intersect?(child)
			if order == depth # at bottom
				# puts "at bottom -> found prefix #{prefix.to_s(2)} (#{child.inspect})"
				yield(child, prefix, order); :skip
			elsif region.include?(child)
				# puts "include child -> found prefix #{prefix.to_s(2)} (#{child.inspect})"
				yield(child, prefix, order); :skip
			else
				# puts "going deeper..."
			end
		else
			# puts "out of bounds."
			:skip
		end
	end
end