geofield.apachesolr.inc 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <?php
  2. /**
  3. * Implements hook_apachesolr_field_mappings().
  4. */
  5. function geofield_apachesolr_field_mappings() {
  6. $mappings['geofield'] = array(
  7. 'indexing_callback' => 'geofield_apachesolr_indexing_callback',
  8. 'map callback' => 'geofield_apachesolr_map_callback',
  9. 'index_type' => 'geohash',
  10. 'facets' => TRUE,
  11. 'query types' => array('term','geo'),
  12. 'query type' => 'term',
  13. );
  14. return $mappings;
  15. }
  16. /**
  17. * Apachesolr indexing callback for geofield.
  18. *
  19. * It will index 2 fields on Solr:
  20. *
  21. * 1- Multi-valued field with all geometry(ies) points - as expected.
  22. * 2- The centroid of the geometry(ies), or the unique point.
  23. *
  24. * The single-value field is meant to be used for stats or as a performance
  25. * improvement in simple queries.
  26. *
  27. * The centroid can also be used in simple queries in favor of performance,
  28. * instead of using the full geometry when it is not necessary.
  29. *
  30. * @param object $entity
  31. * @param string $field_name
  32. * @param string $index_key
  33. * @param array $field_info
  34. * @return array $fields
  35. */
  36. function geofield_apachesolr_indexing_callback($entity, $field_name, $index_key, $field_info) {
  37. $fields = array();
  38. if (!empty($entity->{$field_name})) {
  39. $values = $entity->{$field_name}[LANGUAGE_NONE];
  40. // If there is no geometry, just return
  41. if (empty($values[0]['geom'])) {
  42. return $fields;
  43. }
  44. // Store multiple geometries in a multi-valued Solr field.
  45. foreach ($values as $delta => $item) {
  46. $fields[] = array(
  47. 'key' => $index_key,
  48. 'value' => $item['lat'] . ',' . $item['lon'],
  49. );
  50. }
  51. // Store the centroid of multiple geometries or the unique point in a
  52. // singular Solr field.
  53. if ($field_info['multiple'] && !empty($values[0])) {
  54. // If there are multiple values, then get the centroid.
  55. if (count($values) > 1) {
  56. // Combine the geometries.
  57. $geoms = array();
  58. foreach ($values as $delta => $item) {
  59. $geoms[] = geoPHP::load($item['geom']);
  60. }
  61. $combined_geom = geoPHP::geometryReduce($geoms);
  62. // Get the centroid.
  63. $centroid = $combined_geom->getCentroid();
  64. // Format the value to be indexed.
  65. $formated_value = $centroid->y() . ',' . $centroid->x();
  66. }
  67. // There is no need for additional computation of a single item.
  68. else {
  69. $item = reset($values);
  70. $formated_value = $item['lat'] . ',' . $item['lon'];
  71. }
  72. // Get the field info and make it singular.
  73. $singular_field_info = $field_info;
  74. $singular_field_info['multiple'] = FALSE;
  75. $single_key = apachesolr_index_key($singular_field_info);
  76. $fields[] = array(
  77. 'key' => $single_key,
  78. 'value' => $formated_value,
  79. );
  80. }
  81. }
  82. return $fields;
  83. }
  84. /**
  85. * Map of the facet labels.
  86. *
  87. * @param array $values
  88. * @param array $options
  89. * @return type
  90. */
  91. function geofield_apachesolr_map_callback(array $values, array $options) {
  92. $map = array();
  93. foreach ($values as $key) {
  94. $map[$key] = substr($key, 1) . 'km';
  95. }
  96. return $map;
  97. }