diff --git a/schema.xml b/schema.xml
index 0971ef6..a5bab7b 100644
--- a/schema.xml
+++ b/schema.xml
@@ -280,6 +280,20 @@
     <!-- A random sort type -->
     <fieldType name="rand" class="solr.RandomSortField" indexed="true" />
 
+
+    <!-- Begin added types to use features in Solr 3.3+ -->
+    <fieldType name="point" class="solr.PointType" dimension="2" subFieldType="tdouble"/>
+
+    <!-- A specialized field for geospatial search. If indexed, this fieldType must not be multivalued. -->
+    <fieldType name="location" class="solr.LatLonType" subFieldType="tdouble"/>
+
+   <!--
+    A Geohash is a compact representation of a latitude longitude pair in a single field.
+    See http://wiki.apache.org/solr/SpatialSearch
+   -->
+    <fieldtype name="geohash" class="solr.GeoHashField"/>
+
+
     <!-- since fields of this type are by default not stored or indexed, any data added to
          them will be ignored outright
      -->
@@ -370,6 +384,14 @@
    <copyField source="ss_*" dest="f_ss_*" />
    <copyField source="sm_*" dest="f_sm_*" />
 
+
+   <dynamicField name="points_*" type="point" indexed="true"  stored="true" multiValued="false"/>
+   <dynamicField name="pointm_*" type="point" indexed="true"  stored="true" multiValued="true"/>
+   <dynamicField name="locs_*" type="location" indexed="true"  stored="true" multiValued="false"/>
+   <dynamicField name="locm_*" type="location" indexed="true"  stored="true" multiValued="true"/>
+   <dynamicField name="geos_*" type="geohash" indexed="true"  stored="true" multiValued="false"/>
+   <dynamicField name="geom_*" type="geohash" indexed="true"  stored="true" multiValued="true"/>
+
    <!-- The following causes solr to ignore any fields that don't already match an existing
         field name or dynamic field, rather than reporting them as an error.
         Alternately, change the type="ignored" to some other type, e.g. "text", if you want
diff --git a/service.inc b/service.inc
index 62cbd8d..b247400 100644
--- a/service.inc
+++ b/service.inc
@@ -33,6 +33,8 @@ class SearchApiSolrService extends SearchApiAbstractService {
     'duration' => 'i',
     'boolean' => 'b',
     'uri' => 's',
+    'latlng' => 'loc',
+    'geohash' => 'geo',
   );
 
   /**
@@ -191,6 +193,7 @@ class SearchApiSolrService extends SearchApiAbstractService {
       'search_api_mlt',
       'search_api_multi',
       'search_api_spellcheck',
+      'search_api_data_type_latlng',
     ));
     return isset($supported[$feature]);
   }
@@ -349,6 +352,9 @@ class SearchApiSolrService extends SearchApiAbstractService {
         // Generate a field name; this corresponds with naming conventions in
         // our schema.xml
         $type = $field['type'];
+        if (isset($field['real_type'])) {
+          $type = $field['real_type'];
+        }
         $inner_type = search_api_extract_inner_type($type);
         $pref = isset(self::$type_prefixes[$inner_type]) ? self::$type_prefixes[$inner_type] : '';
         if ($pref != 't') {
@@ -528,6 +534,33 @@ class SearchApiSolrService extends SearchApiAbstractService {
       $keys = 'id:' . $index->machine_name . '-' . $mlt['id'];
     }
 
+
+    // Handle Spatial query
+    $spatial = $query->getOption('search_api_location');
+    if ($spatial) {
+      $spatial_params = array();
+      $spatial_params['sfield'] = $fields[$spatial['sfield']];
+      $spatial_params['pt'] = $spatial['pt'];
+
+      if (isset($spatial['d'])) {
+        $spatial_params['d'] = $spatial['d'];
+      }
+      if (isset($spatial['sort'])) {
+        $spatial_params['sort'][] = $spatial['sort'];
+      }
+      if (isset($spatial['query'])) {
+        if (!$keys) {
+          $keys = $spatial['query'];
+        }
+        else {
+          $keys = array($spatial['query'], $keys);
+        }
+      }
+      if (isset($spatial['fq'])) {
+        $fq[] = $spatial['fq'];
+      }
+    }
+
     // Set defaults
     if (!$keys) {
       $keys = NULL;
