     [txmin, tymin] = @meters_to_tile(xmin, ymin, level)
     [txmax, tymax] = @meters_to_tile(xmax, ymax, level)
 
-
     # add tiles which border
     txmin -= tile_border
     tymin -= tile_border

  _index_data: () ->
    @_xy_index()

  get_extent: () ->
    return [@x_range.get('start'), @y_range.get('start'), @x_range.get('end'), @y_range.get('end')]

  _on_dblclick: (e) =>
    extent = @get_extent()
    [xmin, xmax, ymin, ymax] = extent
    zoom_level = @tile_provider.get_level_by_extent(extent, @map_frame.get('height'), @map_frame.get('width'))

    rect = @map_canvas.canvas.getBoundingClientRect()
    x = e.clientX + rect.left
    #TODO: y-dim is not perfect.  zooming doesn't seem completely correct
    y = e.clientY - rect.top - (@map_frame.get('top') - @map_frame.get('height'))
    y = @map_frame.get("height") - y

    x_meters = @x_mapper.map_from_target(e.clientX)
    y_meters = @y_mapper.map_from_target(e.clientY)

    x_offset = Math.abs((@x_range.get('end') - @x_range.get('start')) / 2)
    y_offset = Math.abs((@y_range.get('end') - @y_range.get('start')) / 2)

    updated_extent =  [x_meters - x_offset, y_meters - y_offset, x_meters + x_offset, y_meters + y_offset]

    if e.shiftKey
      zoom_level = zoom_level - 1
    else
      zoom_level = zoom_level + 1

    new_extent = @tile_provider.snap_to_zoom(updated_extent, @map_frame.get('height'), @map_frame.get('width'), zoom_level)
    @x_range.set('start', new_extent[0])
    @y_range.set('start', new_extent[1])
    @x_range.set('end', new_extent[2])
    @y_range.set('end', new_extent[3])

  _set_data: () ->
    @tile_provider = @_create_tile_provider(@mget('tile_provider'), @mget('url'), @mget('tile_size'))

  get_level_by_extent: (extent, height, width) ->
    x_rs = (extent[2] - extent[0]) / width
    y_rs = (extent[3] - extent[1]) / height
    resolution = Math.max(x_rs, y_rs)
    i = 0
    for r in @resolutions
      if resolution > r
        return 0 if i == 0
        return i - 1 if i > 0
      i += 1

  get_closest_level_by_extent:(extent, height, width) ->
    x_rs = (extent[2] - extent[0]) / width
    y_rs = (extent[3] - extent[1]) / height
    resolution = Math.max(x_rs, y_rs)

    closest = @resolutions.reduce (previous, current) ->
      return current if (Math.abs(current - resolution) < Math.abs(previous - resolution))
      return previous

    return @resolutions.indexOf(closest)

  snap_to_zoom: (extent, height, width, level) ->
    desired_res = @resolutions[level]
