<?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); } }