mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-23 09:53:15 +00:00
Merge pull request #2597 from jygaulier/PHRAS-2009_Geo-operator_MASTER
PHRAS-2009_Geo-operator_MASTER
This commit is contained in:
@@ -27,11 +27,16 @@ class EqualExpression extends Node
|
||||
throw new QueryException(sprintf('Value "%s" for key "%s" is not valid.', $this->value, $this->key));
|
||||
}
|
||||
|
||||
$query = [
|
||||
'term' => [
|
||||
$this->key->getIndexField($context, true) => $this->value
|
||||
]
|
||||
];
|
||||
if(method_exists($this->key, "buildQuery")) {
|
||||
$query = $this->key->buildQuery($this->value, $context);
|
||||
}
|
||||
else {
|
||||
$query = [
|
||||
'term' => [
|
||||
$this->key->getIndexField($context, true) => $this->value
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
if ($this->key instanceof QueryPostProcessor) {
|
||||
return $this->key->postProcessQuery($query, $context);
|
||||
|
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace Alchemy\Phrasea\SearchEngine\Elastic\AST\KeyValue;
|
||||
|
||||
use Alchemy\Phrasea\SearchEngine\Elastic\Search\QueryContext;
|
||||
|
||||
class GeolocationKey implements Key
|
||||
{
|
||||
const TYPE_GEOLOCATION = 'geolocation';
|
||||
|
||||
private $type;
|
||||
private $key;
|
||||
private $matcher = '/^(-?\\d*(\\.\\d*)?)[\\s]+(-?\\d*(\\.\\d*)?)[\\s]+(\\d*(\\.\\d*)?)(\\D*)$/';
|
||||
private $units = [
|
||||
'mi', 'miles',
|
||||
'yd', 'yards',
|
||||
'ft', 'feet',
|
||||
'in', 'inch',
|
||||
'km', 'kilometers',
|
||||
'm', 'meters',
|
||||
'cm', 'centimeters',
|
||||
'mm', 'millimeters',
|
||||
'NM', 'nmi', 'nauticalmiles',
|
||||
];
|
||||
|
||||
public static function geolocation()
|
||||
{
|
||||
return new self(self::TYPE_GEOLOCATION, 'geolocation');
|
||||
}
|
||||
|
||||
public function buildQuery($value, QueryContext $context)
|
||||
{
|
||||
$matches = [];
|
||||
if(preg_match($this->matcher, trim($value), $matches) === 1) {
|
||||
$lat = $matches[1];
|
||||
$lon = $matches[3];
|
||||
$dst = $matches[5];
|
||||
$uni = trim($matches[7]);
|
||||
if(in_array($uni, $this->units)) {
|
||||
return [
|
||||
'geo_distance' => [
|
||||
'distance' => $dst . $uni,
|
||||
'location' => [
|
||||
'lat' => $lat,
|
||||
'lon' => $lon
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private function __construct($type, $key)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->key = $key;
|
||||
}
|
||||
|
||||
public function getIndexField(QueryContext $context, $raw = false)
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
public function isValueCompatible($value, QueryContext $context)
|
||||
{
|
||||
return preg_match($this->matcher, trim($value), $matches) === 1;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
}
|
@@ -28,6 +28,7 @@ class NodeTypes
|
||||
const FLAG = '#flag';
|
||||
const NATIVE_KEY = '#native_key';
|
||||
const TIMESTAMP_KEY = '#timestamp_key';
|
||||
const GEOLOCATION_KEY = '#geolocation_key';
|
||||
// Token types for leaf nodes
|
||||
const TOKEN_WORD = 'word';
|
||||
const TOKEN_QUOTED_STRING = 'quoted';
|
||||
|
@@ -108,6 +108,9 @@ class QueryVisitor implements Visit
|
||||
case NodeTypes::TIMESTAMP_KEY:
|
||||
return $this->visitTimestampKeyNode($element);
|
||||
|
||||
case NodeTypes::GEOLOCATION_KEY:
|
||||
return $this->visitGeolocationKeyNode($element);
|
||||
|
||||
case NodeTypes::METADATA_KEY:
|
||||
return new AST\KeyValue\MetadataKey($this->visitString($element));
|
||||
|
||||
@@ -337,6 +340,11 @@ class QueryVisitor implements Visit
|
||||
});
|
||||
}
|
||||
|
||||
private function visitGeolocationKeyNode(TreeNode $node)
|
||||
{
|
||||
return AST\KeyValue\GeolocationKey::geolocation();
|
||||
}
|
||||
|
||||
private function visitNativeKeyNode(TreeNode $node)
|
||||
{
|
||||
$this->assertChildrenCount($node, 1);
|
||||
|
Reference in New Issue
Block a user