AbstractGeoDistance.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. <?php
  2. namespace Elastica\Query;
  3. use Elastica\Exception\InvalidException;
  4. /**
  5. * Geo distance query.
  6. *
  7. * @author Nicolas Ruflin <spam@ruflin.com>
  8. *
  9. * @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-distance-query.html
  10. */
  11. abstract class AbstractGeoDistance extends AbstractQuery
  12. {
  13. const LOCATION_TYPE_GEOHASH = 'geohash';
  14. const LOCATION_TYPE_LATLON = 'latlon';
  15. /**
  16. * Location type.
  17. *
  18. * Decides if this query uses latitude/longitude or geohash for the location.
  19. * Values are "latlon" or "geohash".
  20. *
  21. * @var string
  22. */
  23. protected $_locationType;
  24. /**
  25. * Key.
  26. *
  27. * @var string
  28. */
  29. protected $_key;
  30. /**
  31. * Latitude.
  32. *
  33. * @var float
  34. */
  35. protected $_latitude;
  36. /**
  37. * Longitude.
  38. *
  39. * @var float
  40. */
  41. protected $_longitude;
  42. /**
  43. * Geohash.
  44. *
  45. * @var string
  46. */
  47. protected $_geohash;
  48. /**
  49. * Create GeoDistance object.
  50. *
  51. * @param string $key Key
  52. * @param array|string $location Location as array or geohash: array('lat' => 48.86, 'lon' => 2.35) OR 'drm3btev3e86'
  53. *
  54. * @internal param string $distance Distance
  55. */
  56. public function __construct($key, $location)
  57. {
  58. $this->setKey($key);
  59. $this->setLocation($location);
  60. }
  61. /**
  62. * @param string $key
  63. *
  64. * @return $this
  65. */
  66. public function setKey($key)
  67. {
  68. $this->_key = $key;
  69. return $this;
  70. }
  71. /**
  72. * @param array|string $location
  73. *
  74. * @throws \Elastica\Exception\InvalidException
  75. *
  76. * @return $this
  77. */
  78. public function setLocation($location)
  79. {
  80. // Location
  81. if (is_array($location)) { // Latitude/Longitude
  82. // Latitude
  83. if (isset($location['lat'])) {
  84. $this->setLatitude($location['lat']);
  85. } else {
  86. throw new InvalidException('$location[\'lat\'] has to be set');
  87. }
  88. // Longitude
  89. if (isset($location['lon'])) {
  90. $this->setLongitude($location['lon']);
  91. } else {
  92. throw new InvalidException('$location[\'lon\'] has to be set');
  93. }
  94. } elseif (is_string($location)) { // Geohash
  95. $this->setGeohash($location);
  96. } else { // Invalid location
  97. throw new InvalidException('$location has to be an array (latitude/longitude) or a string (geohash)');
  98. }
  99. return $this;
  100. }
  101. /**
  102. * @param float $latitude
  103. *
  104. * @return $this
  105. */
  106. public function setLatitude($latitude)
  107. {
  108. $this->_latitude = (float) $latitude;
  109. $this->_locationType = self::LOCATION_TYPE_LATLON;
  110. return $this;
  111. }
  112. /**
  113. * @param float $longitude
  114. *
  115. * @return $this
  116. */
  117. public function setLongitude($longitude)
  118. {
  119. $this->_longitude = (float) $longitude;
  120. $this->_locationType = self::LOCATION_TYPE_LATLON;
  121. return $this;
  122. }
  123. /**
  124. * @param string $geohash
  125. *
  126. * @return $this
  127. */
  128. public function setGeohash($geohash)
  129. {
  130. $this->_geohash = $geohash;
  131. $this->_locationType = self::LOCATION_TYPE_GEOHASH;
  132. return $this;
  133. }
  134. /**
  135. * @throws \Elastica\Exception\InvalidException
  136. *
  137. * @return array|string
  138. */
  139. protected function _getLocationData()
  140. {
  141. if (self::LOCATION_TYPE_LATLON === $this->_locationType) { // Latitude/longitude
  142. $location = [];
  143. if (isset($this->_latitude)) { // Latitude
  144. $location['lat'] = $this->_latitude;
  145. } else {
  146. throw new InvalidException('Latitude has to be set');
  147. }
  148. if (isset($this->_longitude)) { // Geohash
  149. $location['lon'] = $this->_longitude;
  150. } else {
  151. throw new InvalidException('Longitude has to be set');
  152. }
  153. } elseif (self::LOCATION_TYPE_GEOHASH === $this->_locationType) { // Geohash
  154. $location = $this->_geohash;
  155. } else { // Invalid location type
  156. throw new InvalidException('Invalid location type');
  157. }
  158. return $location;
  159. }
  160. /**
  161. * @see \Elastica\Param::toArray()
  162. *
  163. * @throws \Elastica\Exception\InvalidException
  164. *
  165. * @return array
  166. */
  167. public function toArray()
  168. {
  169. $this->setParam($this->_key, $this->_getLocationData());
  170. return parent::toArray();
  171. }
  172. }