mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-23 18:03:17 +00:00
Merge pull request #2597 from jygaulier/PHRAS-2009_Geo-operator_MASTER
PHRAS-2009_Geo-operator_MASTER
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
%token database database
|
||||
%token collection collection
|
||||
%token sha256 sha256
|
||||
%token geolocation geolocation
|
||||
%token uuid uuid
|
||||
%token type type
|
||||
%token id id|recordid
|
||||
@@ -95,7 +96,8 @@ match_key:
|
||||
| <id>
|
||||
|
||||
key:
|
||||
timestamp_key()
|
||||
geolocation_key()
|
||||
| timestamp_key()
|
||||
| ::meta_prefix:: meta_key()
|
||||
| ::field_prefix:: field_key()
|
||||
| field_key()
|
||||
@@ -104,6 +106,9 @@ key:
|
||||
<created_on>
|
||||
| <updated_on>
|
||||
|
||||
#geolocation_key:
|
||||
<geolocation>
|
||||
|
||||
#meta_key:
|
||||
word_or_keyword()+
|
||||
|
||||
@@ -174,6 +179,7 @@ keyword:
|
||||
| <database>
|
||||
| <collection>
|
||||
| <sha256>
|
||||
| <geolocation>
|
||||
| <uuid>
|
||||
| <type>
|
||||
| <id>
|
||||
|
||||
@@ -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