docs: def tile_metadata(tile, product, geometry_check=None):
      """ Generate metadata for a given tile
  
      - geometry_check is a function the determines whether to calculate the geometry by downloading
      B01 and override provided geometry in tilejson. The meta object is passed to this function.
      The function return a True or False response.
      """
  
      grid = 'T{0}{1}{2}'.format(pad(tile['utmZone'], 2), tile['latitudeBand'], tile['gridSquare'])
  
      meta = OrderedDict({
          'tile_name': product['tiles'][grid]
      })
  
      logger.info('%s Processing tile %s' % (threading.current_thread().name, tile['path']))
  
      meta['date'] = tile['timestamp'].split('T')[0]
  
      meta['thumbnail'] = '{1}/{0}/preview.jp2'.format(tile['path'], s3_url)
  
      # remove unnecessary keys
      product.pop('tiles')
      tile.pop('datastrip')
      bands = product.pop('band_list')
  
      for k, v in iteritems(tile):
          meta[camelcase_underscore(k)] = v
  
      meta.update(product)
  
      # construct download links
      links = ['{2}/{0}/{1}.jp2'.format(meta['path'], b, s3_url) for b in bands]
  
      meta['download_links'] = {
          'aws_s3': links
      }
  
      meta['original_tile_meta'] = '{0}/{1}/tileInfo.json'.format(s3_url, meta['path'])
  
      def internal_latlon(meta):
          keys = ['tile_origin', 'tile_geometry', 'tile_data_geometry']
          for key in keys:
              if key in meta:
                  meta[key] = to_latlon(meta[key])
          return meta
  
      # change coordinates to wsg4 degrees
      if geometry_check:
          if geometry_check(meta):
              meta = get_tile_geometry_from_s3(meta)
          else:
              meta = internal_latlon(meta)
      else:
          meta = internal_latlon(meta)
  
      # rename path key to aws_path
      meta['aws_path'] = meta.pop('path')
  
      return meta