diff -rupN location_current/contrib/location_views/location_views.module location_new/contrib/location_views/location_views.module
--- location_current/contrib/location_views/location_views.module	2008-11-25 11:57:03.000000000 +1100
+++ contrib/location_views/location_views.module	2008-11-25 12:59:11.000000000 +1100
@@ -104,6 +104,7 @@ function location_views_tables() {
       'province'    => array('name' => t('Province')),
       'country'     => array('name' => t('Country')),
       'postal_code' => array('name' => t('Postal Code')),
+      'lid'         => array('name' => t('Location: Location ID')),
     ),
     'filters' => array(
       'name' => array(
diff -rupN location_current/location.module location_new/location.module
--- location_current/location.module	2008-11-25 11:57:00.000000000 +1100
+++ location.module	2008-11-25 11:57:46.000000000 +1100
@@ -175,6 +175,223 @@ function location_map_link_options_form(
  * Process a location element.
  */
 function _location_expand_location($element) {
+
+  if (arg(0) == 'node' && is_numeric(arg(1))) {
+    $node = node_load(arg(1));
+    $nodetype = $node->type;
+  }
+  else if (arg(0) == 'node' && arg(1) == 'add') {
+    $nodetype = arg(2);
+  }
+  $singlemap = variable_get('location_single_map_' . $nodetype, 0);
+
+  if ($singlemap) {
+    $new_element = _location_single_map($element);
+  }
+  else {
+    $new_element = _location_multi_map($element);
+  }
+
+  return $new_element;
+}
+
+/**
+ * Process a single map location element. (multiple locations on single map)
+ */
+function _location_single_map($element) {
+  $url = request_uri();
+  if (arg(0) == 'node' && is_numeric(arg(1))) {
+    $node = node_load(arg(1));
+    $nodetype = $node->type;
+  }
+  else if (arg(0) == 'node' && arg(1) == 'add') {
+    $nodetype = arg(2);
+  }
+
+  $maxnum = variable_get('location_maxnum_'. $nodetype, 1);
+  $defaultnum = variable_get('location_defaultnum_'. $nodetype, 1);
+  $numloc = isset($element['#default_value']) ? count($element['#default_value']) : 0;
+
+  $location_form_count = min($numloc + $defaultnum, $maxnum);
+
+  drupal_add_css(drupal_get_path('module', 'location') .'/location.css');
+  $value = is_array($element['#value']) ? $element['#value'] : array();
+  $element['#tree'] = TRUE;
+
+  if (!isset($element['#title'])) {
+    $element['#title'] = t('Location');
+  }
+  if (empty($element['#location_settings'])) {
+    $element['#location_settings'] = array();
+  }
+  if (!isset($element['#default_value']) || $element['#default_value'] == 0) {
+    $element['#default_value'] = array();
+  }
+
+  // Merge defaults in.
+  $dummy = array();
+  $element['#location_settings'] = array_merge(location_invoke_locationapi($dummy, 'collection default'), $element['#location_settings']);
+  $element['#default_value'] = array_merge(location_invoke_locationapi($dummy, 'default values'), $element['#default_value']);
+  $dv =& $element['#default_value'];
+
+
+  // @@@ Split into submit and view permissions?
+  if (user_access('submit latitude/longitude')) {
+
+    $mapid = gmap_get_auto_mapid();
+    $map = gmap_parse_macro(variable_get('location_locpick_macro', '[gmap]'));
+    $map['id'] = $mapid;
+    $map['points'] = array();
+    $map['pointsOverlays'] = array();
+    $map['lines'] = array();
+
+    $map['behavior']['locpick'] = TRUE;
+    $map['behavior']['collapsehack'] = TRUE;
+    // Use previous coordinates to center the map.
+    if (location_has_coordinates($dv, FALSE)) {
+      $map['latitude'] = (float)$dv['latitude'];
+      $map['longitude'] = (float)$dv['longitude'];
+
+      $map['markers'][] = array(
+        'latitude' => $dv['latitude'],
+        'longitude' => $dv['longitude'],
+        'markername' => 'small gray', // @@@ Settable?
+        'offset' => 0,
+        'opts' => array(
+          'clickable' => FALSE,
+        ),
+      );
+    }
+
+    // Keep track of the LID.
+    // @@@ For some reason, hidden seems to work best.
+    for ($i = 0; $i < $location_form_count; $i++) {
+      $def = location_invoke_locationapi($dummy, 'default values');
+      $dv[$i] = $dv[$i] ? array_merge($def, $dv[$i]) : $def;
+
+      // Keep track of the LID.
+      // @@@ For some reason, hidden seems to work best.
+      $element[$i]['lid'] = array(
+        '#type' => 'hidden',
+        '#value' => isset($dv[$i]['lid']) ? $dv[$i]['lid'] : FALSE,
+      );
+
+      $location_settings = $element['#location_settings'];
+
+      $fields = location_field_names(TRUE);
+      foreach ($fields as $field => $title) {
+        if (!isset($element[$i][$field])) {
+          // @@@ Permission check hook?
+          if ($location_settings[$field] != 0) {
+            $element[$i][$field] = location_invoke_locationapi($dv[$i][$field], 'field_expand', $field, $location_settings[$field], $dv[$i]);
+          }
+
+          // Only include 'Street Additional' if 'Street' is 'allowed' or 'required'
+          if ($field == 'street' && $location_settings[$field]) {
+            $element[$i]['additional'] = location_invoke_locationapi($dv[$i]['additional'], 'field_expand', 'additional', 1, $dv[$i]);
+          }
+        }
+      }
+
+      $element[$i]['locpick'] = array();
+
+      if (location_has_coordinates($dv[$i], FALSE)) {
+        $element[$i]['locpick']['current'] = array(
+          '#type' => 'fieldset',
+          '#title' => t('Current coordinates'),
+        );
+        $element[$i]['locpick']['current']['current_latitude'] = array(
+          '#type' => 'item',
+          '#title' => t('Latitude'),
+          '#value' => $dv[$i]['latitude'],
+        );
+        $element[$i]['locpick']['current']['current_longitude'] = array(
+          '#type' => 'item',
+          '#title' => t('Longitude'),
+          '#value' => $dv[$i]['longitude'],
+        );
+        $source = t('Unknown');
+        switch($dv[$i]['source']) {
+          case LOCATION_LATLON_USER_SUBMITTED:
+            $source = t('User-submitted');
+            break;
+          case LOCATION_LATLON_GEOCODED_APPROX:
+            $source = t('Geocoded (Postal code level)');
+            break;
+          case LOCATION_LATLON_GEOCODED_EXACT:
+            $source = t('Geocoded (Exact)');
+        }
+        $element[$i]['locpick']['current']['current_source'] = array(
+          '#type' => 'item',
+          '#title' => t('Source'),
+          '#value' => $source,
+        );
+      }
+
+      $element[$i]['locpick']['user_latitude'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Latitude'),
+        '#default_value' => isset($element['#default_value'][$i]['locpick']['user_latitude']) ? $element['#default_value'][$i]['locpick']['user_latitude'] : '',
+        '#size' => 16,
+        '#attributes' => array('class' => 'container-inline'),
+        '#maxlength' => 20,
+      );
+      $element[$i]['locpick']['user_longitude'] = array(
+        '#type' => 'textfield',
+        '#title' => t('Longitude'),
+        '#default_value' => isset($element['#default_value'][$i]['locpick']['user_longitude']) ? $element['#default_value'][$i]['locpick']['user_longitude'] : '',
+        '#size' => 16,
+        '#maxlength' => 20,
+      );
+
+      $element[$i]['locpick']['instructions'] = array(
+        '#type' => 'markup',
+        '#weight' => 1,
+        '#prefix' => '<div class=\'description\'>',
+        '#value' => '<br /><br />' . t('If you wish to supply your own latitude and longitude, you may enter them above.  If you leave these fields blank, the system will attempt to determine a latitude and longitude for you from the entered address.  To have the system recalculate your location from the address, for example if you change the address, delete the values for these fields.'),
+        '#suffix' => '</div>',
+        );
+      if (function_exists('gmap_get_auto_mapid') && variable_get('location_usegmap', FALSE)) {
+        $element[$i]['locpick']['user_latitude']['#map'] = $mapid;
+        gmap_widget_setup($element[$i]['locpick']['user_latitude'], 'locpick_latitude');
+        $element[$i]['locpick']['user_longitude']['#map'] = $mapid;
+        gmap_widget_setup($element[$i]['locpick']['user_longitude'], 'locpick_longitude');
+      }
+
+      if (isset($dv[$i]['lid']) && $dv[$i]['lid'] !== FALSE) {
+        $element[$i]['delete_location'] = array(
+          '#type' => 'checkbox',
+          '#title' => t('Delete'),
+          '#default_value' => FALSE,
+          '#description' => t('Check this box to delete this location.'),
+        );
+      }
+    }
+
+    $element['map'] = array(
+      '#type' => 'gmap',
+      '#weight' => -10,
+      '#map' => $mapid,
+      '#settings' => $map,
+    );
+    $element['map_instructions'] = array(
+      '#type' => 'markup',
+      '#weight' => 2,
+      '#prefix' => '<div class=\'description\'>',
+      '#value' => t('You may set the location by clicking on the map, or dragging the location marker.  To clear the location and cause it to be recalculated, click on the marker.'),
+      '#suffix' => '</div>',
+    );
+  }
+
+  $element += _element_info('fieldset');
+
+  return $element;
+}
+
+/**
+ * Process a multi map location element. (one location per map)
+ */
+function _location_multi_map($element) {
   drupal_add_css(drupal_get_path('module', 'location') .'/location.css');
   $value = is_array($element['#value']) ? $element['#value'] : array();
   $element['#tree'] = TRUE;
@@ -702,6 +919,13 @@ function _location_node_type_form_alter(
     '#description'    => t('This setting only applies when you have enabled locations for this node type.  It determines how many blank location forms will show up on the original edit-screen for a node of this type.  It also only applies when you have enabled a maximum of 1 or more locations to be submitted for this node type.')
   );
 
+  $form['location']['multiple_locations']['location_single_map'] = array(
+    '#type'           => 'checkbox',
+    '#title'          => t('Single map'),
+    '#default_value'  => variable_get('location_single_map_' . $type, 0),
+    '#description'    => t('This setting controls whether you have one map on the screen or multiple.  If this option is checked, the multiple locations will display on one map, otherwise you will get a map for each location.')
+  );
+
   $form['location']['collection'] = array(
     '#type' => 'fieldset',
     '#title' => t('Collection settings'),
@@ -837,50 +1061,106 @@ function _location_node_form_alter($form
   $numloc = isset($node->locations) ? count($node->locations) : 0;
   $location_form_count = min($numloc + variable_get('location_defaultnum_'. $node->type, 1), variable_get('location_maxnum_'. $node->type, 1));
 
-  if ($location_form_count) {
+  $singlemap = variable_get('location_single_map_'. $node->type, 0);
 
-    $form['locations'] = array(
-      '#type' => 'fieldset',
-      '#title' => format_plural($location_form_count, 'Location', 'Locations'),
-      '#tree' => TRUE,
-      '#attributes' => array_merge((isset($form['locations']['#attributes']) && is_array($form['locations']['#attributes'])) ? $form['locations']['#attributes'] : array(), array('class' => 'locations')),
-      '#weight' => variable_get('location_weight_'. $form['type']['#value'], 9),
-      '#collapsible' => variable_get('location_collapsible_'. $form['type']['#value'], 0) == 0 ? FALSE : TRUE,
-      '#collapsed' => variable_get('location_collapsed_'. $form['type']['#value'], 0) == 0 ? FALSE : TRUE,
-    );
+  if ($singlemap) {
+    if ($location_form_count) {
+      $form['locations'] = array(
+        '#type' => 'maarkup',
+        '#title' => format_plural($location_form_count, 'Location', 'Locations'),
+        '#tree' => TRUE,
+        '#attributes' => array_merge((isset($form['locations']['#attributes']) && is_array($form['locations']['#attributes'])) ? $form['locations']['#attributes'] : array(), array('class' => 'locations')),
+        '#weight' => variable_get('location_weight_'. $form['type']['#value'], 9),
+        '#collapsible' => variable_get('location_collapsible_'. $form['type']['#value'], 0) == 0 ? FALSE : TRUE,
+        '#collapsed' => variable_get('location_collapsed_'. $form['type']['#value'], 0) == 0 ? FALSE : TRUE,
+      );
 
-    // If there is only one location, hide the outer fieldset.
-    if (variable_get('location_maxnum_'. $form['type']['#value'], 0) == 1) {
-      $form['locations']['#type'] = 'markup';
-    }
+      $settings = variable_get('location_fields_'. $node->type, array());
+
+      // This is a hack to stop fields other than locpicks displaying as other fields are not supported.
+      // This can be removed when other areas of the module are changed to support these single map elements.
+      foreach ($settings as $setting => &$value) {
+        if ($setting != 'country') {
+          $value = 0;
+        }
+      }
 
-    $settings = variable_get('location_fields_'. $node->type, array());
-    // Enforce required fields for the first location only.  The rest should be optional.
-    if ($location_form_count > 1) {
-      $settings_sans_reqs = array();
-      foreach ($settings as $field => $setting) {
-        // Allow Allow (Use), Force Default settings through.
-        // Block 2 (Required).
-        $settings_sans_reqs[$field] = $setting & 1;
+      // Enforce required fields for the first location only.  The rest should be optional.
+      if ($location_form_count > 1) {
+        $settings_sans_reqs = array();
+        foreach ($settings as $field => $setting) {
+          // Allow Allow (Use), Force Default settings through.
+          // Block 2 (Required).
+          $settings_sans_reqs[$field] = $setting & 1;
+        }
       }
-    }
 
-    for ($i = 0; $i < $location_form_count; $i++) {
-      $form['locations'][$i] = array(
+      $form['locations'] = array(
         '#type' => 'location_element',
-        '#title' => t('Location #%number', array('%number' => $i + 1)),
-        '#default_value' => isset($node->locations[$i]) ? $node->locations[$i] : NULL,
-        // Use relaxed settings for all locations past the first one.
-        '#location_settings' => ($i > 0) ? $settings_sans_reqs : $settings
+        '#title' => t('Locations'),
+        '#default_value' => isset($node->locations) ? $node->locations : NULL,
+        '#location_settings' => $settings,
+        '#attributes' => array_merge(is_array($form['locations']['#attributes']) ? $form['locations']['#attributes'] : array(), array('class' => 'locations')),
+        '#weight' => variable_get('location_weight_'. $form['type']['#value'], 9),
+        '#collapsible' => variable_get('location_collapsible_'. $form['type']['#value'], 0) == 0 ? FALSE : TRUE,
+        '#collapsed' => variable_get('location_collapsed_'. $form['type']['#value'], 0) == 0 ? FALSE : TRUE,
       );
+
+      if ($location_form_count == 1) {
+        $form['locations']['#title'] = t('Location');
+        // If the user had configured the form for a single location, inherit
+        // the collapsible / collapsed settings.
+        $form['locations']['#collapsible'] = $form['locations']['#collapsible'];
+        $form['locations']['#collapsed'] = $form['locations']['#collapsed'];
+      }
     }
+  }
+  else {
+    if ($location_form_count) {
+
+      $form['locations'] = array(
+        '#type' => 'fieldset',
+        '#title' => format_plural($location_form_count, 'Location', 'Locations'),
+        '#tree' => TRUE,
+        '#attributes' => array_merge((isset($form['locations']['#attributes']) && is_array($form['locations']['#attributes'])) ? $form['locations']['#attributes'] : array(), array('class' => 'locations')),
+        '#weight' => variable_get('location_weight_'. $form['type']['#value'], 9),
+        '#collapsible' => variable_get('location_collapsible_'. $form['type']['#value'], 0) == 0 ? FALSE : TRUE,
+        '#collapsed' => variable_get('location_collapsed_'. $form['type']['#value'], 0) == 0 ? FALSE : TRUE,
+      );
 
-    if ($location_form_count == 1) {
-      $form['locations'][0]['#title'] = t('Location');
-      // If the user had configured the form for a single location, inherit
-      // the collapsible / collapsed settings.
-      $form['locations'][0]['#collapsible'] = $form['locations']['#collapsible'];
-      $form['locations'][0]['#collapsed'] = $form['locations']['#collapsed'];
+      // If there is only one location, hide the outer fieldset.
+      if (variable_get('location_maxnum_'. $form['type']['#value'], 0) == 1) {
+        $form['locations']['#type'] = 'markup';
+      }
+
+      $settings = variable_get('location_fields_'. $node->type, array());
+      // Enforce required fields for the first location only.  The rest should be optional.
+      if ($location_form_count > 1) {
+        $settings_sans_reqs = array();
+        foreach ($settings as $field => $setting) {
+          // Allow Allow (Use), Force Default settings through.
+          // Block 2 (Required).
+          $settings_sans_reqs[$field] = $setting & 1;
+        }
+      }
+
+      for ($i = 0; $i < $location_form_count; $i++) {
+        $form['locations'][$i] = array(
+          '#type' => 'location_element',
+          '#title' => t('Location #%number', array('%number' => $i + 1)),
+          '#default_value' => isset($node->locations[$i]) ? $node->locations[$i] : NULL,
+          // Use relaxed settings for all locations past the first one.
+          '#location_settings' => ($i > 0) ? $settings_sans_reqs : $settings
+        );
+      }
+
+      if ($location_form_count == 1) {
+        $form['locations'][0]['#title'] = t('Location');
+        // If the user had configured the form for a single location, inherit
+        // the collapsible / collapsed settings.
+        $form['locations'][0]['#collapsible'] = $form['locations']['#collapsible'];
+        $form['locations'][0]['#collapsed'] = $form['locations']['#collapsed'];
+      }
     }
   }
 }
@@ -1087,7 +1367,7 @@ function location_nodeapi(&$node, $op, $
  * @return An array of loaded locations.
  */
 function location_load_locations($id, $key = 'vid') {
-  $result = db_query('SELECT lid FROM {location_instance} WHERE '. db_escape_table($key) .' = %d', $id);
+  $result = db_query('SELECT lid FROM {location_instance} WHERE '. db_escape_table($key) .' = %d ORDER BY lid', $id);
   $locations = array();
   while ($lid = db_fetch_object($result)) {
     $locations[] = location_load_location($lid->lid);
@@ -1420,6 +1700,11 @@ function location_save(&$location, $cow 
     $location['longitude'] = $location['locpick']['user_longitude'];
     $inhibit_geocode = TRUE;
   }
+  else {
+    $location['source'] = LOCATION_LATLON_UNDEFINED;
+    $location['latitude'] = 0;
+    $location['longitude'] = 0;
+  }
 
   // Pull in fields that hold data currently not editable directly by the user.
   $location = array_merge($oldloc, $location);
