OpenXE/classes/Modules/HocrParser/Finder/RelativePositionFinderFacet.php
2021-05-21 08:49:41 +02:00

112 lines
3.1 KiB
PHP

<?php
namespace Xentral\Modules\HocrParser\Finder;
use Xentral\Modules\HocrParser\Data\BoundingBox;
use Xentral\Modules\HocrParser\Data\BoundingBoxCollection;
use Xentral\Modules\HocrParser\Exception\InvalidArgumentException;
class RelativePositionFinderFacet implements FinderFacetInterface
{
const DIRECTION_LEFT = 'left';
const DIRECTION_RIGHT = 'right';
const DIRECTION_ABOVE = 'above';
const DIRECTION_BELOW = 'below';
/** @var array $validDirections */
private static $validDirections = [
self::DIRECTION_ABOVE,
self::DIRECTION_RIGHT,
self::DIRECTION_BELOW,
self::DIRECTION_LEFT,
];
/** @var string $text */
private $text;
/** @var PatternMatcher $matcher */
private $matcher;
/** @var string $direction */
private $direction;
/**
* @param string $searchText
* @param string $direction
* @param string $pattern
*/
public function __construct($searchText, $direction, $pattern)
{
if (!in_array($direction, self::$validDirections, true)) {
throw new InvalidArgumentException(sprintf('Direction "%s" is not allowed.', $direction));
}
$this->matcher = new PatternMatcher($pattern);
$this->text = trim($searchText);
$this->direction = $direction;
}
/**
* @param string $text
*
* @return bool
*/
public function MatchPreCondition($text)
{
return $text === $this->text;
}
/**
* @param array|BoundingBox[] $candidates
* @param BoundingBoxCollection $boxes
*
* @return string|false
*/
public function Select(array $candidates, BoundingBoxCollection $boxes)
{
foreach ($candidates as $candidate) {
$coords = $candidate->GetCenterPoint();
/** @var BoundingBox $nearestBox */
$nearestBox = false;
switch ($this->direction) {
case self::DIRECTION_RIGHT:
$nearestBox = $boxes->GetNearestBoxRightFromPoint($coords['x'], $coords['y']);
break;
case self::DIRECTION_LEFT:
$nearestBox = $boxes->GetNearestBoxLeftFromPoint($coords['x'], $coords['y']);
break;
case self::DIRECTION_ABOVE:
$nearestBox = $boxes->GetNearestBoxAboveFromPoint($coords['x'], $coords['y']);
break;
case self::DIRECTION_BELOW:
$nearestBox = $boxes->GetNearestBoxBelowFromPoint($coords['x'], $coords['y']);
break;
}
if ($nearestBox === false) {
continue;
}
// Prüfen ob Wert einem bestimmten Muster folgt
$patternMatching = $this->IsPatternMatching($nearestBox->GetData('text'));
if ($patternMatching) {
return $nearestBox->GetData('text');
}
}
return false;
}
/**
* @param string $value
*
* @return bool
*/
private function IsPatternMatching($value)
{
return $this->matcher->Match($value);
}
}