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.



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

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

Instance Attribute Details

#pointsObject (readonly)

Returns the value of attribute points.



84
85
86
# File 'lib/geospatial/map.rb', line 84

def points
  @points
end

Class Method Details

.for_earth(order = 20) ⇒ Object



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

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

Instance Method Details

#<<(object) ⇒ Object



102
103
104
105
106
# File 'lib/geospatial/map.rb', line 102

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

#boundsObject



73
74
75
76
77
78
79
80
81
82
# File 'lib/geospatial/map.rb', line 73

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

#countObject



108
109
110
# File 'lib/geospatial/map.rb', line 108

def count
	@points.count
end

#filter_for(region, **options) ⇒ Object



145
146
147
148
149
150
151
152
153
154
# File 'lib/geospatial/map.rb', line 145

def filter_for(region, **options)
	filter = Filter.new
	
	# 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
	
	return filter
end

#hash_for_coordinates(coordinates) ⇒ Object



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

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



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

def order
	@curve.order
end

#point_for_coordinates(coordinates, object = nil) ⇒ Object



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

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

#point_for_hash(hash) ⇒ Object



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

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

#point_for_object(object) ⇒ Object



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

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

#query(region, **options) ⇒ Object



116
117
118
119
120
# File 'lib/geospatial/map.rb', line 116

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

#sort!Object



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

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

#traverse(region, depth: 0) ⇒ Object



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

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