X-Git-Url: https://git.openstreetmap.org./rails.git/blobdiff_plain/33a65a90c9d0e2ab121e1da9c3efedaf9e6a9789..bda06347db52eb9dc64f2dbbe3c8c56a604b8798:/lib/quad_tile.rb?ds=inline diff --git a/lib/quad_tile.rb b/lib/quad_tile.rb index cb1b5a06e..931ec04a3 100644 --- a/lib/quad_tile.rb +++ b/lib/quad_tile.rb @@ -1,19 +1,19 @@ module QuadTile begin require "quad_tile/quad_tile_so" - rescue MissingSourceFile + rescue LoadError def self.tile_for_point(lat, lon) - x = ((lon + 180) * 65535 / 360).round - y = ((lat + 90) * 65535 / 180).round + x = ((lon.to_f + 180) * 65535 / 360).round + y = ((lat.to_f + 90) * 65535 / 180).round - return tile_for_xy(x, y) + tile_for_xy(x, y) end - def self.tiles_for_area(minlat, minlon, maxlat, maxlon) - minx = ((minlon + 180) * 65535 / 360).round - maxx = ((maxlon + 180) * 65535 / 360).round - miny = ((minlat + 90) * 65535 / 180).round - maxy = ((maxlat + 90) * 65535 / 180).round + def self.tiles_for_area(bbox) + minx = ((bbox.min_lon + 180) * 65535 / 360).round + maxx = ((bbox.max_lon + 180) * 65535 / 360).round + miny = ((bbox.min_lat + 90) * 65535 / 180).round + maxy = ((bbox.max_lat + 90) * 65535 / 180).round tiles = [] minx.upto(maxx) do |x| @@ -22,7 +22,7 @@ module QuadTile end end - return tiles + tiles end def self.tile_for_xy(x, y) @@ -30,51 +30,51 @@ module QuadTile 16.times do t = t << 1 - t = t | 1 unless (x & 0x8000).zero? + t |= 1 unless (x & 0x8000).zero? x <<= 1 t = t << 1 - t = t | 1 unless (y & 0x8000).zero? + t |= 1 unless (y & 0x8000).zero? y <<= 1 end - return t + t end - end - def self.sql_for_area(minlat, minlon, maxlat, maxlon) - sql = Array.new - single = Array.new + def self.iterate_tiles_for_area(bbox) + tiles = tiles_for_area(bbox) + first = last = nil - iterate_tiles_for_area(minlat, minlon, maxlat, maxlon) do |first,last| - if first == last - single.push(first) - else - sql.push("tile BETWEEN #{first} AND #{last}") - end - end + tiles.sort.each do |tile| + if last.nil? + first = last = tile + elsif tile == last + 1 + last = tile + else + yield first, last - sql.push("tile IN (#{single.join(',')})") if single.size > 0 + first = last = tile + end + end - return "( " + sql.join(" OR ") + " )" + yield first, last unless last.nil? + end end - def self.iterate_tiles_for_area(minlat, minlon, maxlat, maxlon) - tiles = tiles_for_area(minlat, minlon, maxlat, maxlon) - first = last = nil + def self.sql_for_area(bbox, prefix) + sql = [] + single = [] - tiles.sort.each do |tile| - if last.nil? - first = last = tile - elsif tile == last + 1 - last = tile + iterate_tiles_for_area(bbox) do |first, last| + if first == last + single.push(first) else - yield first, last - - first = last = tile + sql.push("#{prefix}tile BETWEEN #{first} AND #{last}") end end - yield first, last unless last.nil? + sql.push("#{prefix}tile IN (#{single.join(',')})") unless single.empty? + + "( " + sql.join(" OR ") + " )" end private_class_method :tile_for_xy, :iterate_tiles_for_area