class GlobalMapTiles::GlobalMercator

based on EPSG:900913 = EPSG:3785

Public Class Methods

new(tile_size = 256) click to toggle source
# File lib/global_map_tiles/global_mercator.rb, line 4
def initialize(tile_size = 256)
  @tile_size = tile_size
  @initial_resolution = 2 * Math::PI * 6378137 / @tile_size
  @origin_shift = 2 * Math::PI * 6378137 / 2.0
end

Public Instance Methods

google_tile(tx, ty, zoom) click to toggle source

Converts TMS tile coordinates to Google Tile coordinates

# File lib/global_map_tiles/global_mercator.rb, line 94
def google_tile(tx, ty, zoom)
  [tx, (2**zoom - 1) - ty]
end
lon_lat_to_meters(lon, lat) click to toggle source

Converts given lon/lat in WGS84 Datum to XY in Spherical Mercator EPSG:900913

# File lib/global_map_tiles/global_mercator.rb, line 11
def lon_lat_to_meters(lon, lat)
  mx = lon * @origin_shift / 180.0
  my = Math.log(Math.tan((90 + lat) * Math::PI / 360.0)) / (Math::PI / 180.0)

  my = my * @origin_shift / 180.0
  [mx, my]
end
meters_to_lon_lat(mx, my) click to toggle source

Converts XY point from Spherical Mercator EPSG:900913 to lon/lat in WGS84 Datum“

# File lib/global_map_tiles/global_mercator.rb, line 20
def meters_to_lon_lat(mx, my)
  lon = (mx / @origin_shift) * 180.0
  lat = (my / @origin_shift) * 180.0

  lat = 180 / Math::PI * (2 * Math.atan(Math.exp(lat * Math::PI / 180.0)) - Math::PI / 2.0)
  [lon, lat]
end
meters_to_pixels(mx, my, zoom) click to toggle source

Converts EPSG:900913 to pyramid pixel coordinates in given zoom level

# File lib/global_map_tiles/global_mercator.rb, line 37
def meters_to_pixels(mx, my, zoom)
  res = resolution(zoom)
  px = (mx + @origin_shift) / res
  py = (my + @origin_shift) / res
  [px, py]
end
meters_to_tile(mx, my, zoom) click to toggle source

returns tile for given mercator coordinates

# File lib/global_map_tiles/global_mercator.rb, line 58
def meters_to_tile(mx, my, zoom)
  px, py = meters_to_pixels(mx, my, zoom)
  pixels_to_tile(px, py)
end
pixels_to_meters(px, py, zoom) click to toggle source

Converts pixel coordinates in given zoom level of pyramid to EPSG:900913

# File lib/global_map_tiles/global_mercator.rb, line 29
def pixels_to_meters(px, py, zoom)
  res = resolution(zoom)
  mx = px * res - @origin_shift
  my = py * res - @origin_shift
  [mx, my]
end
pixels_to_raster(px, py, zoom) click to toggle source

Move the origin of pixel coordinates to top-left corner

# File lib/global_map_tiles/global_mercator.rb, line 52
def pixels_to_raster(px, py, zoom)
  map_size = @tile_size << zoom
  [px, map_size - py]
end
pixels_to_tile(px, py) click to toggle source

Returns a tile covering region in given pixel coordinates

# File lib/global_map_tiles/global_mercator.rb, line 45
def pixels_to_tile(px, py)
  tx = (px / @tile_size.to_f).ceil.to_i - 1
  ty = (py / @tile_size.to_f).ceil.to_i - 1
  [tx, ty]
end
quad_tree_key(tx, ty, zoom) click to toggle source

Converts TMS tile coordinates to Microsoft QuadTree

# File lib/global_map_tiles/global_mercator.rb, line 99
def quad_tree_key(tx, ty, zoom)
  quad_key = ""
  ty = (2**zoom - 1) - ty
  i = zoom
  while i > 0
    digit = 0
    mask = 1 << (i - 1)
    digit += 1 if (tx & mask) != 0
    digit += 2 if (ty & mask) != 0
    quad_key += digit.to_s
    i -= 1
  end
  quad_key
end
resolution(zoom) click to toggle source

Resolution (meters/pixel) for given zoom level (measured at Equator)

# File lib/global_map_tiles/global_mercator.rb, line 80
def resolution(zoom)
  @initial_resolution / (2**zoom)
end
tile_bounds(tx, ty, zoom) click to toggle source

Returns bounds of the given tile in EPSG:900913 coordinates

# File lib/global_map_tiles/global_mercator.rb, line 64
def tile_bounds(tx, ty, zoom)
  min_x, min_y = pixels_to_meters(tx * @tile_size, ty * @tile_size, zoom)
  max_x, max_y = pixels_to_meters((tx + 1) * @tile_size, (ty + 1) * @tile_size, zoom)
  [min_x, min_y, max_x, max_y]
end
tile_lon_lat_bounds(tx, ty, zoom) click to toggle source

Returns bounds of the given tile in longitude/latitude using WGS84 datum

# File lib/global_map_tiles/global_mercator.rb, line 71
def tile_lon_lat_bounds(tx, ty, zoom)
  bounds = tile_bounds(tx, ty, zoom)
  min_lon, min_lat = meters_to_lon_lat(bounds[0], bounds[1])
  max_lon, max_lat = meters_to_lon_lat(bounds[2], bounds[3])

  [min_lon, min_lat, max_lon, max_lat]
end
zoom_for_pixel_size(pixel_size) click to toggle source

“Maximal scaledown zoom of the pyramid closest to the pixelSize.

# File lib/global_map_tiles/global_mercator.rb, line 85
def zoom_for_pixel_size(pixel_size)
  (1..30).each do |i|
    if pixel_size > resolution(i)
      return i != 0 ? (i - 1) : 0
    end
  end
end