class Geospatial::Map

Attributes

curve[R]
points[R]

Public Class Methods

for_earth(order = 20) click to toggle source
# File lib/geospatial/map.rb, line 60
def self.for_earth(order = 20)
        self.new(Hilbert::Curve.new(Dimensions.for_earth, order))
end
new(curve) click to toggle source
# File lib/geospatial/map.rb, line 64
def initialize(curve)
        @curve = curve
        @points = []
        @bounds = nil
end

Public Instance Methods

<<(object) click to toggle source
# File lib/geospatial/map.rb, line 105
def << object
        @points << point_for_coordinates(object.to_a, object)
        
        return self
end
bounds() click to toggle source
# 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
count() click to toggle source
# File lib/geospatial/map.rb, line 111
def count
        @points.count
end
filter_for(*regions, **options) click to toggle source
# 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) click to toggle source
# File lib/geospatial/map.rb, line 89
def hash_for_coordinates(coordinates)
        @curve.map(coordinates)
end
index() click to toggle source

serialize :point, Map.for_earth.index

# File lib/geospatial/map/index.rb, line 49
def index
        klass = Class.new(Index)
        
        klass.map = self
        
        return klass
end
order() click to toggle source
# File lib/geospatial/map.rb, line 72
def order
        @curve.order
end
point_for_coordinates(coordinates, object = nil) click to toggle source
# File lib/geospatial/map.rb, line 97
def point_for_coordinates(coordinates, object = nil)
        Point.new(self, coordinates, object)
end
point_for_hash(hash) click to toggle source
# File lib/geospatial/map.rb, line 93
def point_for_hash(hash)
        Point.new(self, @curve.unmap(hash))
end
point_for_object(object) click to toggle source
# File lib/geospatial/map.rb, line 101
def point_for_object(object)
        Point.new(self, object.to_a, object)
end
query(region, **options) click to toggle source
# File lib/geospatial/map.rb, line 119
def query(region, **options)
        filter = filter_for(region, **options)
        
        return filter.apply(@points).map(&:object)
end
sort!() click to toggle source
# File lib/geospatial/map.rb, line 115
def sort!
        @points.sort_by!(&:hash)
end
traverse(region, depth: 0) { |child, prefix, order| ... } click to toggle source
# 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