mirror of
https://github.com/OpenXE-org/OpenXE.git
synced 2024-12-27 23:20:28 +01:00
227 lines
5.6 KiB
PHP
227 lines
5.6 KiB
PHP
|
<?php
|
||
|
|
||
|
namespace Xentral\Modules\HocrParser\Data;
|
||
|
|
||
|
use Xentral\Components\ScanbotApi\Exception\RuntimeException;
|
||
|
|
||
|
class BoundingBoxCollection
|
||
|
{
|
||
|
/** @var array|BoundingBox[] $boxes */
|
||
|
private $boxes;
|
||
|
|
||
|
/**
|
||
|
* @param array|BoundingBox[] $boxes
|
||
|
*/
|
||
|
public function __construct(array $boxes = [])
|
||
|
{
|
||
|
$this->boxes = $boxes;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @return array|BoundingBox[]
|
||
|
*/
|
||
|
public function GetBoxes()
|
||
|
{
|
||
|
return $this->boxes;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Box mit der kürzesten Entfernung rechts vom übergebenen Punkt zurückgeben
|
||
|
*
|
||
|
* @param int $x
|
||
|
* @param int $y
|
||
|
*
|
||
|
* @return BoundingBox|false
|
||
|
*/
|
||
|
public function GetNearestBoxRightFromPoint($x, $y)
|
||
|
{
|
||
|
// Erstmal alle Elemente rechts vom Punkt finden; inkl. Entfernung zum Punkt
|
||
|
$candidates = $this->GetBoxesRightFromPoint($x, $y);
|
||
|
|
||
|
return $this->GetBoxWithLowestDistance($candidates);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Alle Boxen zurückgeben die sich rechts vom übergebenen Punkt befinden; inkl. Entfernung
|
||
|
*
|
||
|
* @param int $x
|
||
|
* @param int $y
|
||
|
*
|
||
|
* @return array|BoundingBox[]
|
||
|
*/
|
||
|
public function GetBoxesRightFromPoint($x, $y)
|
||
|
{
|
||
|
$result = [];
|
||
|
|
||
|
foreach ($this->boxes as $box) {
|
||
|
if ($box->IsRightFromPoint($x, $y)) {
|
||
|
$distance = $box->GetDistanceFromPoint($x, $y);
|
||
|
$box->SetData('distance', $distance);
|
||
|
$result[] = $box;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Box mit dem geringsten Abstand ermitteln
|
||
|
*
|
||
|
* Hinweis: Data-Eigenschaft "distance" muss dafür gesetzt sein.
|
||
|
*
|
||
|
* @param array|BoundingBox[] $boxes
|
||
|
*
|
||
|
* @return BoundingBox|false
|
||
|
*/
|
||
|
private function GetBoxWithLowestDistance(array $boxes)
|
||
|
{
|
||
|
// Index neu aufbauen
|
||
|
$boxes = array_values($boxes);
|
||
|
|
||
|
// Keine Box gefunden
|
||
|
if (count($boxes) === 0) {
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// Nur eine Box gefunden
|
||
|
if (count($boxes) === 1) {
|
||
|
return $boxes[0];
|
||
|
}
|
||
|
|
||
|
$shortestDistance = $boxes[0]->GetData('distance');
|
||
|
$shortestDistanceKey = 0;
|
||
|
|
||
|
// Prüfen ob Entfernung gesetzt sind
|
||
|
if ($shortestDistance === null) {
|
||
|
throw new RuntimeException('Distance not set.');
|
||
|
}
|
||
|
|
||
|
// Box mit der geringsten Entfernung suchen
|
||
|
/** @var BoundingBox $box */
|
||
|
foreach ($boxes as $key => $box) {
|
||
|
$boxDistance = $box->GetData('distance');
|
||
|
if ($boxDistance < $shortestDistance) {
|
||
|
$shortestDistance = $boxDistance;
|
||
|
$shortestDistanceKey = $key;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $boxes[$shortestDistanceKey];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Box mit der kürzesten Entfernung links vom übergebenen Punkt zurückgeben
|
||
|
*
|
||
|
* @param int $x
|
||
|
* @param int $y
|
||
|
*
|
||
|
* @return BoundingBox|false
|
||
|
*/
|
||
|
public function GetNearestBoxLeftFromPoint($x, $y)
|
||
|
{
|
||
|
// Erstmal alle Elemente rechts vom Punkt finden; inkl. Entfernung zum Punkt
|
||
|
$candidates = $this->GetBoxesLeftFromPoint($x, $y);
|
||
|
|
||
|
return $this->GetBoxWithLowestDistance($candidates);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Alle Boxen zurückgeben die sich links vom übergebenen Punkt befinden; inkl. Entfernung
|
||
|
*
|
||
|
* @param int $x
|
||
|
* @param int $y
|
||
|
*
|
||
|
* @return array|BoundingBox[]
|
||
|
*/
|
||
|
public function GetBoxesLeftFromPoint($x, $y)
|
||
|
{
|
||
|
$result = [];
|
||
|
|
||
|
foreach ($this->boxes as $box) {
|
||
|
if ($box->IsLeftFromPoint($x, $y)) {
|
||
|
$distance = $box->GetDistanceFromPoint($x, $y);
|
||
|
$box->SetData('distance', $distance);
|
||
|
$result[] = $box;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Box mit der kürzesten Entfernung oberhalb vom übergebenen Punkt zurückgeben
|
||
|
*
|
||
|
* @param int $x
|
||
|
* @param int $y
|
||
|
*
|
||
|
* @return BoundingBox|false
|
||
|
*/
|
||
|
public function GetNearestBoxAboveFromPoint($x, $y)
|
||
|
{
|
||
|
$candidates = $this->GetBoxesAboveFromPoint($x, $y);
|
||
|
|
||
|
return $this->GetBoxWithLowestDistance($candidates);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Alle Boxen zurückgeben die sich oberhalb vom übergebenen Punkt befinden; inkl. Entfernung
|
||
|
*
|
||
|
* @param int $x
|
||
|
* @param int $y
|
||
|
*
|
||
|
* @return array|BoundingBox[]
|
||
|
*/
|
||
|
public function GetBoxesAboveFromPoint($x, $y)
|
||
|
{
|
||
|
$result = [];
|
||
|
|
||
|
foreach ($this->boxes as $box) {
|
||
|
if ($box->IsAbovePoint($x, $y)) {
|
||
|
$distance = $box->GetDistanceFromPoint($x, $y);
|
||
|
$box->SetData('distance', $distance);
|
||
|
$result[] = $box;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $result;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Box mit der kürzesten Entfernung unterhalb vom übergebenen Punkt zurückgeben
|
||
|
*
|
||
|
* @param int $x
|
||
|
* @param int $y
|
||
|
*
|
||
|
* @return BoundingBox|false
|
||
|
*/
|
||
|
public function GetNearestBoxBelowFromPoint($x, $y)
|
||
|
{
|
||
|
$candidates = $this->GetBoxesBelowFromPoint($x, $y);
|
||
|
|
||
|
return $this->GetBoxWithLowestDistance($candidates);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Alle Boxen zurückgeben die sich unterhalb vom übergebenen Punkt befinden; inkl. Entfernung
|
||
|
*
|
||
|
* @param int $x
|
||
|
* @param int $y
|
||
|
*
|
||
|
* @return array|BoundingBox[]
|
||
|
*/
|
||
|
public function GetBoxesBelowFromPoint($x, $y)
|
||
|
{
|
||
|
$result = [];
|
||
|
|
||
|
foreach ($this->boxes as $box) {
|
||
|
if ($box->IsBelowPoint($x, $y)) {
|
||
|
$distance = $box->GetDistanceFromPoint($x, $y);
|
||
|
$box->SetData('distance', $distance);
|
||
|
$result[] = $box;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $result;
|
||
|
}
|
||
|
}
|