diff --git a/README.txt b/README.txt
index 25fbf82..6700e84 100644
--- a/README.txt
+++ b/README.txt
@@ -48,6 +48,11 @@ Regarding third-party features, the following are supported:
 - search_api_spellcheck
   Introduced by module: search_api_spellcheck
   Gives the option to display automatic spellchecking for searches.
+- search_api_data_type_location
+  Introduced by module: search_api_location
+  Lets you index, filter and sort on location fields. Note, however, that only
+  single-valued fields are currently supported for Solr 3.x, and that the option
+  isn't supported at all in Solr 1.4.
 
 If you feel some service option is missing, or have other ideas for improving
 this implementation, please file a feature request in the project's issue queue,
diff --git a/service.inc b/service.inc
index 9047b08..3d3e59b 100644
--- a/service.inc
+++ b/service.inc
@@ -534,13 +534,13 @@ class SearchApiSolrService extends SearchApiAbstractService {
 
     // Extract sort
     $sort = array();
-    foreach ($query->getSort() as $f => $order) {
-      $f = $fields[$f];
+    foreach ($query->getSort() as $field => $order) {
+      $f = $fields[$field];
       if (substr($f, 0, 3) == 'ss_') {
         $f = 'sort_' . substr($f, 3);
       }
       $order = strtolower($order);
-      $sort[] = "$f $order";
+      $sort[$field] = "$f $order";
     }
 
     // Get facet fields
@@ -567,6 +567,63 @@ class SearchApiSolrService extends SearchApiAbstractService {
       $keys = 'id:' . SearchApiSolrConnection::phrase($this->createId($index->machine_name, $mlt['id']));
     }
 
+    // Handle spatial filters.
+    if ($spatials = $query->getOption('search_api_location')) {
+      foreach ($spatials as $spatial) {
+        if (empty($spatial['field']) || empty($spatial['lat']) || empty($spatial['lon'])) {
+          continue;
+        }
+
+        $field = $fields[$spatial['field']];
+        $escaped_field = SearchApiSolrConnection::escapeFieldName($field);
+        $point = ((float) $spatial['lat']) . ',' . ((float) $spatial['lon']);
+
+        // Prepare the filter settings.
+        if (isset($spatial['radius'])) {
+          $radius = (float) $spatial['radius'];
+          $spatial_method = 'geofilt';
+          if (isset($spatial['method']) && in_array($spatial['method'], array('geofilt', 'bbox'))) {
+            $spatial_method = $spatial['method'];
+          }
+          $fq[] = "{!$spatial_method pt=$point sfield=$field d=$radius}";
+        }
+
+        // Change sort on the field, if set.
+        if (isset($sort[$spatial['field']])) {
+          $sort[$spatial['field']] = str_replace($field, "geodist($field,$point)", $sort[$spatial['field']]);
+        }
+
+        // Change the fq facet ranges to the correct fq.
+        foreach ($fq as $key => $value) {
+          // If the fq contains only of this field, replace it with a range.
+          $preg_field = preg_quote($escaped_field, '/');
+          if (preg_match('/^(' . $preg_field . '):"(\*|\d+(\.\d+))--(\*|\d+(\.\d+))"$/', $value, $m)) {
+            $lower = $m[2] == '*' ? '' : " l={$m[2]}";
+            $upper = $m[4] == '*' ? '' : " u={$m[4]}";
+            if ("$lower$upper" != '**') {
+              $fq[$key] = "{!frange$lower$upper}geodist($field,$point)";
+            }
+          }
+        }
+
+        // Change the spatial field facet so it return distance facet ranges.
+        // @todo
+        /*if (!empty($facets)) {
+          foreach ($facet_params['facet.field'] as $i => $f) {
+            if ($f === $field) {
+              unset($facet_params['facet.field'][$i]);
+            }
+            if (!isset($range)) {
+              $range = $spatial['radius'] / 5;
+              for ($i = 1; $i <= 5; $i++) {
+                $facet_params['facet.query'][] = "{!frange l=0 u=" . $i * $range . "}geodist()";
+              }
+            }
+          }
+        }*/
+      }
+    }
+
     // Set defaults
     if (!$keys) {
       $keys = NULL;
@@ -595,6 +652,9 @@ class SearchApiSolrService extends SearchApiAbstractService {
     if (!empty($mlt_params['mlt.fl'])) {
       $params += $mlt_params;
     }
+    if (!empty($spatial_params)) {
+      $params += $spatial_params;
+    }
     if (!empty($this->options['retrieve_data'])) {
       $params['fl'] = '*,score';
     }
@@ -783,6 +843,7 @@ class SearchApiSolrService extends SearchApiAbstractService {
    * @return array
    *   An array describing facets that apply to the current results.
    */
+  // @todo Special treatment for spatial facets.
   protected function extractFacets(SearchApiQueryInterface $query, Apache_Solr_Response $response) {
     if (isset($response->facet_counts->facet_fields)) {
       $index = $query->getIndex();
