     return @url.replace("{X}", x).replace('{Y}', y).replace("{Z}", z)
 
 class WMTSTileProvider extends MercatorTileProvider
-
-  get_tile_meter_bounds: (x, y, z) ->
-    [x, y, z] = @tms_to_wmts(x, y, z)
-    return super(x, y, z)
 
   get_image_url: (x, y, z) ->
     [x, y, z] = @tms_to_wmts(x, y, z)

    quadKey = @tile_xyz_to_quadkey(x, y, z)
    return @url.replace("{QUADKEY}", quadKey)


class TileLayerView extends Glyph.View

  _index_data: () ->
    @_xy_index()

  _set_data: () ->
    @need_load = (true for img in @url)
    @loaded = (false for img in @url)

    @_xy_index()

  _map_data: () ->
    @sw = @sdist(@renderer.xmapper, @x, @tile_size, 'edge', @mget('dilate'))
    @sh = @sdist(@renderer.ymapper, @y, @tile_size, 'edge', @mget('dilate'))

  _render: (ctx, indices, {url, image, need_load, sx, sy, sw, sh, angle}) ->
    for i in indices

      if isNaN(sx[i]+sy[i]+angle[i])
        continue

      if need_load[i]
        img = new Image()
        img.onload = do (img, i) =>
          return () =>
            @loaded[i] = true
            @renderer.request_render()

        img.src = url[i]
        need_load[i] = false
      else if @loaded[i]
        @_render_image(ctx, i, image[i], sx, sy, @tile_size, @tile_size, angle)

  _final_sx_sy: (anchor, sx, sy, sw, sh) ->
    switch anchor
      when "top_left"      then [sx       , sy       ]
      when "top_center"    then [sx - sw/2, sy       ]
      when "top_right"     then [sx - sw  , sy       ]
      when "right_center"  then [sx - sw  , sy - sh/2]
      when "bottom_right"  then [sx - sw  , sy - sh  ]
      when "bottom_center" then [sx - sw/2, sy - sh  ]
      when "bottom_left"   then [sx       , sy - sh  ]
      when "left_center"   then [sx       , sy - sh/2]
      when "center"        then [sx - sw/2, sy - sh/2]

  _render_image: (ctx, i, image, sx, sy, sw, sh, angle) ->

    anchor = @mget('anchor') or "top_left"
    [sx, sy] = @_final_sx_sy(anchor, sx[i], sy[i], 256, 256)

    ctx.save()

    ctx.globalAlpha = @mget("global_alpha")

    if angle[i]
      ctx.translate(sx, sy)
      ctx.rotate(angle[i])
      ctx.drawImage(image, 0, 0, 256, 256)
      ctx.rotate(-angle[i])
      ctx.translate(-sx, -sy)
    else
      ctx.drawImage(image, sx, sy, 256, 256)
    ctx.restore()

class TileLayer extends Glyph.Model
  default_view: TileLayerView
  type: 'TileLayer'
  tile_width: 256
  tile_height: 256
  visuals: []
  distances: ['w', 'h']
  angles: ['angle']
  fields: ['url:string']

  defaults: ->
    return _.extend {}, super(), {
      angle: 0
      global_alpha: 1.0
    }

  display_defaults: ->
    return _.extend {}, super(), {
    }

module.exports =

    return [minLon, minLat, maxLon, maxLat]

  get_tiles_by_extent: (extent, level) ->

    [xmin, ymin, xmax, ymax] = extent
    [txmin, tymin] = @meters_to_tile(xmin, ymin, level)
    [txmax, tymax] = @meters_to_tile(xmax, ymax, level)

    center_tile_x = (txmax - txmin) // 2
    center_tile_y = (tymax - tymin) // 2

    tiles = []
    for ty in [tymax..tymin] by -1
      for tx in [txmin..txmax] by 1
        tx = tx %% 2 ** level
        tiles.push([tx, ty, level, @get_tile_meter_bounds(tx, ty, level)])

    #TOOD: sort tiles by distance from center doesn't seem to be working
    tiles.sort (a, b) ->
      a_distance = Math.sqrt(Math.pow(center_tile_x - a[0], 2) + Math.pow(center_tile_y - a[1], 2))
      b_distance = Math.sqrt(Math.pow(center_tile_x - b[0], 2) + Math.pow(center_tile_y - b[1], 2))
      return a_distance - b_distance

    return tiles

