Index: location_views.module
===================================================================
--- location_views.module	(revision 219)
+++ location_views.module	(working copy)
@@ -92,6 +92,26 @@
     )
   );
 
+  $tables['location']['filters']['proximitytotypedaddress'] = array(
+    'field' => 'proximitytotypedaddress',
+    'name' => t('Location: Within proximity of typed address'),
+    'operator' => array('within proximity'=>'Within proximity of'), // not really used but required
+    'value' => location_views_location_details_input_form(),
+    'handler' => 'location_views_filter_handler_typed_address',
+    'help' => t('Filter nodes by proximity to typed address, note you CANNOT as _yet_ store these details as preset informaton in your view due views not supporting keyed value entries when saving, however it does work fine if you expose this filter'), //todo
+    'cacheable' => 'no'
+  );
+
+
+  $tables['location']['filters']['proximitytouser'] = array(
+    'field' => 'proximitytouser',
+    'name' => t('Location: Within proximity of Current User'),
+    'operator' => location_views_proximity_measures(),
+    'handler' => 'location_views_filter_handler_proximity_to_user',
+    'help' => t('Filter to the distance to show from the users lat+long settings'),
+    'cacheable' => 'no',
+  );
+
   $tables['location']['filters']['province_select'] = array(
     'field' => 'province_select',
     'name' => t('Location: Province Selector'),
@@ -939,6 +959,14 @@
     );
 }
 
+function location_views_proximity_measures() {
+   
+  $options['miles'] = t('@miles', array('@miles' => 'miles'));
+  $options['kilometers'] = t('@kilometers', array('@kilometers' => 'kilometers'));
+  
+  return $options;
+
+}
 function location_views_proximity_operators() {
   $values = array(5 => 5, 10 => 10, 25 => 25, 50 => 50, 100 => 100, 250 => 250);
   foreach ($values as $val) {
@@ -985,6 +1013,74 @@
   $query->add_where("$table.latitude > %f AND $table.latitude < %f AND $table.longitude > %f AND $table.longitude < %f", $latrange[0], $latrange[1], $lonrange[0], $lonrange[1]);
 }
 
+function location_views_filter_handler_proximity_to_user($op, $filter, $filterinfo, &$query, $table = 'location') {
+  global $user;
+
+  $unit     = $filter['operator'];
+  $distance = $filter['value'];
+
+  $res=db_query("SELECT * FROM {location} WHERE eid=%d AND type='user'",$user->uid);
+  if ($gmap_user = db_fetch_array($res)) {
+    $lat  = $gmap_user['latitude'];
+    $lon = $gmap_user['longitude'];
+  }
+  
+  if( ! $lat || ! $lon ) {
+    drupal_set_message(t('Reminder: enter your location details in your user profile'));
+    reaturn;
+  }
+  
+  $divisor = $unit == 'kilometers' ? 1000 : 1609.347;
+  $latrange = earth_latitude_range($lon, $lat, ($distance * $divisor));
+  $lonrange = earth_longitude_range($lon, $lat, ($distance * $divisor));
+
+  $query->ensure_table($table);
+  $query->add_orderby(NULL, "((". earth_distance_sql($lon, $lat) .") / $divisor)", 'ASC', 'distance');
+  $query->add_where("$table.longitude IS NOT NULL");
+  $query->add_where("$table.latitude > %f AND $table.latitude < %f AND $table.longitude > %f AND $table.longitude < %f", $latrange[0], $latrange[1], $lonrange[0], $lonrange[1]);
+  
+}
+
+
+function location_views_filter_handler_typed_address($op, $filter, $filterinfo, &$query, $table = 'location') {
+
+
+  $unit     = $_GET['unit'];
+  $distance = $_GET['distance'];
+  
+  // try to get lat+long from google service
+  // we are not going to worry about using the structure in place to resolve to 
+  // different methods depending on the country as google maps is generally good enough
+  foreach($filterinfo['value'] as $key => $value) {
+    if(is_array($value)) {
+      if(strlen($value['#default_value'])) {
+        $location[$key] = $value['#default_value'];
+      }
+    }
+  }
+  
+  $latlong = google_geocode_location($location);
+  
+  if ( $latlong  == false ) {
+    drupal_set_message(t('Unable to find a location for those address details.'));
+    return;
+  }
+  
+  $lon = $latlong['lon'];
+  $lat = $latlong['lat'];
+  
+  $divisor = $unit == 'kilometers' ? 1000 : 1609.347;
+  $latrange = earth_latitude_range($lon, $lat, ($distance * $divisor));
+  $lonrange = earth_longitude_range($lon, $lat, ($distance * $divisor));
+
+  $query->ensure_table($table);
+  $query->add_orderby(NULL, "((". earth_distance_sql($lon, $lat) .") / $divisor)", 'ASC', 'distance');
+  $query->add_where("$table.longitude IS NOT NULL");
+  $query->add_where("$table.latitude > %f AND $table.latitude < %f AND $table.longitude > %f AND $table.longitude < %f", $latrange[0], $latrange[1], $lonrange[0], $lonrange[1]);
+  
+}
+
+
 /**
  *  Function to create a gmap map form
  */
@@ -1019,7 +1115,7 @@
   // get location_views_map_input_form() to regenerate itself by clearing the cache
   // and recalling the form
   foreach ($view->filter as $key => $filter) {
-    if ($filter['field'] == 'location.proximity_map' || $filter['field'] == 'user_location.proximity_map') {
+    if ($filter['field'] == 'location.proximity_map' || $filter['field'] == 'user_location.proximity_map' || $filter['field'] == 'location.proximitytotypedaddress') {
       // clear the cache so we can re-use our forms
       // this is a tradeoff because it drops the cache for every other views table just to perform this
       cache_clear_all('views_tables', 'cache_views', true);
@@ -1028,3 +1124,67 @@
   }
 
 }
+
+
+function location_views_location_details_input_form() {
+
+  $form = array();
+
+  $location_suppressed_values = variable_get('location_suppress_country', 0) ? array('country' => variable_get('location_default_country', 'us')) : array();
+
+  
+  foreach($_GET as $key => $value ) {
+    if(strlen($_GET[$key])) {
+      $location_params[$key]=check_plain($_GET[$key]);
+    }
+  }
+
+  $form = location_form(
+    array('street','additional','city','province','country'),
+    $location_params,
+    array(),
+    $location_suppressed_values,
+    ''
+    //'nearby_postalcodes_bylocation'
+  );
+  
+  $form['unit'] = array(
+    '#type' => 'select',
+    '#title' => t('Unit'),
+    '#options' => array('kilometers'=>'Kilometers', 'miles'=>'Miles'),
+    '#default_value' => $_GET['unit']
+  );
+
+  $form['distance'] = array(
+    '#type' => 'select',
+    '#title' => t('Distance'),
+    '#options' => drupal_map_assoc(array(10, 20, 30, 40, 50, 100, 150, 250, 300, 400, 500)),
+    '#default_value' => $_GET['distance']
+  );
+
+  /*
+  // because views saves the 'value' by imploding the results (no key relationship)
+  // we need to trust we can iterate, lets have a go!
+  // see views.module line 1063
+  
+  $res=db_query("SELECT * FROM {view_filter} WHERE field like '%%proximitytotypedaddress'");
+  $view_field = db_fetch_array($res);
+  $view_field['options']=explode(',',$view_field['value']);
+
+  // this wont work because the the views array of the values is a different order to the form value
+  $i=0;
+  foreach($form as $key => $value) {
+    if(is_array($value)) {
+      if(key_exists('#default_value',$value)) {
+        if(!$value['#default_value'] && $view_field['options'][$i] && $value['#type'] == 'textfield') {
+          $form[$key]['#default_value']=$view_field['options'][$i];
+        }
+      }
+      $i++;
+    }
+    
+  }
+  */
+  return $form;
+}
+
