Q:

How do I properly redirect outbound links with special characters

The search form on my website has a couple radio inputs for the user to select which source (all but one are external to the website) the search query should use. 
I retrieve those inputs (search term and source as ) ; 
function search_redirect_form() {
  if (is_search() && ! empty( $_GET['simple'] ) ) {
        if (isset($_GET['simple']) && $_GET['simple'] == 'dogpile') {
            $query = $_GET["s"];
            wp_redirect(esc_url_raw('theurl1'. $query));
            exit();
        } 
        if (isset($_GET['simple']) && $_GET['simple'] == 'askjeeves') {
           $query =  sanitize_text_field($_GET["s"]);
            wp_redirect(esc_url('url3' . $query));
            exit();  
         } 
    else { 
        $query =  sanitize_text_field($_GET["s"]);
        wp_redirect(esc_url($home_url . "?s=" . $query));
        exit();  
    }   

When a user inputs a special character ((apostrophe, ampersand))
the remaining text of the query is often removed; For example: 
"earth wind & fire" just ends up as "earth wind"
From reading the codex, I thought esc_raw_url would be the most appropriate to use; but that still results in queries being butchered on the other search engines, namely with the ampersand (&) where the remaining part of the query is cut off. 
("Earth wind & fire" becomes "earth wind").
At this point, I'm sort of wondering because wp_redirect does additional escaping (via wp_sanitize_redirect), that this may be a bug; but I'm still rusty with php and not sure. This is also probably confounded that the other websites may escape/sanitize inputs slightly differently. 
Questions: 

Should I be escaping on the input itself instead of the 
URL?) (around the "s" variable in my example);

A:

Right after posting, I learned a couple things, most importantly, that url encoding is done differently for paths and queries and one of our search sources treats the search query as a path, so I had to use rawurlencode for the path; and urlencode for the others. This is why I was receiving inconsistent results from trying different search engines. 
There are a few sanitization functions within wp_redirect as well. 
function search_redirect_form() {
  if (is_search() && ! empty( $_GET['simple'] ) ) {
       if ( isset( $_GET['simple'] ) && $_GET['simple'] === 'dogpile') {
            $query = urlencode( $_GET["s"] )
            wp_redirect(esc_url('url1' . $query));
            exit(); 
        }
        if ( isset( $_GET['simple'] ) && $_GET['simple'] === 'altavista') {
            $query = rawurlencode( $_GET["s"] );
            wp_redirect(esc_url('url2'. $query .'/field/all/mode/all/conn/and/order/nosort'));
            exit(); 
        }
        if ( isset( $_GET['simple'] ) && $_GET['simple'] === 'askjeeves') {
            $query = urlencode( $_GET["s"] )
            wp_redirect(esc_url('url3' . $query));
            exit();  
        }
        else { 
            $query = urlencode( $_GET["s"] )
            wp_redirect(esc_url($home_url . "?s=" . $query));
            exit();  
        }   
  }
} add_action( 'pre_get_posts', 'search_redirect_form', 1 );

