Initial xentral_oss_20.3.c9ffacf
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\HocrParser\Service;
|
||||
|
||||
use Xentral\Modules\HocrParser\Data\BoundingBoxCollection;
|
||||
use Xentral\Modules\HocrParser\Finder\BoundingBoxFinder;
|
||||
use Xentral\Modules\HocrParser\Finder\CurrencyCodeFinderFacet;
|
||||
use Xentral\Modules\HocrParser\Finder\PatternMatcher;
|
||||
use Xentral\Modules\HocrParser\Finder\RelativePositionFinderFacet;
|
||||
|
||||
class HocrDataExtractor
|
||||
{
|
||||
/** @var array|string[] $validCurrencies */
|
||||
private $validCurrencies;
|
||||
|
||||
/** @var HocrParser $parser */
|
||||
private $parser;
|
||||
|
||||
public function __construct(HocrParser $parser, array $validCurrencies)
|
||||
{
|
||||
$this->validCurrencies = $validCurrencies;
|
||||
$this->parser = $parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $document HOCR-Dokument
|
||||
* @param array $settings Einstellungen (pro Lieferant)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function extractLiabilityDataFromHocrDocument(string $document, array $settings): array
|
||||
{
|
||||
// Suchkriterien zusammenstellen
|
||||
$criteria = [];
|
||||
if(!empty($settings['invoice_number']['term']) && !empty($settings['invoice_number']['direction'])){
|
||||
$criteria['invoice_number'] =
|
||||
new RelativePositionFinderFacet(
|
||||
$settings['invoice_number']['term'],
|
||||
$settings['invoice_number']['direction'],
|
||||
PatternMatcher::PATTERN_DOCUMENT_NUMBER
|
||||
);
|
||||
}
|
||||
if(!empty($settings['invoice_date']['term']) && !empty($settings['invoice_date']['direction'])){
|
||||
$criteria['invoice_date'] =
|
||||
new RelativePositionFinderFacet(
|
||||
$settings['invoice_date']['term'],
|
||||
$settings['invoice_date']['direction'],
|
||||
PatternMatcher::PATTERN_DATE
|
||||
);
|
||||
}
|
||||
if(!empty($settings['total_gross']['term']) && !empty($settings['total_gross']['direction'])){
|
||||
$criteria['total_gross'] =
|
||||
new RelativePositionFinderFacet(
|
||||
$settings['total_gross']['term'],
|
||||
$settings['total_gross']['direction'],
|
||||
PatternMatcher::PATTERN_MONEY
|
||||
);
|
||||
}
|
||||
// Immer nach Währungen suchen
|
||||
$waehrungen = $this->validCurrencies;
|
||||
$criteria['currency'] = new CurrencyCodeFinderFacet($waehrungen);
|
||||
|
||||
// BoundingBoxes aus HOCR extrahieren + Suche anhand der Suchkriterien durchführen
|
||||
$boxes = new BoundingBoxCollection($this->parser->parse($document));
|
||||
$finder = new BoundingBoxFinder($boxes, $criteria);
|
||||
|
||||
return $finder->Find();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Xentral\Modules\HocrParser\Service;
|
||||
|
||||
use DOMDocument;
|
||||
use Xentral\Modules\HocrParser\Data\BoundingBox;
|
||||
|
||||
final class HocrParser
|
||||
{
|
||||
/**
|
||||
* @param string $content HOCR-Dokument
|
||||
*
|
||||
* @return array|BoundingBox[]
|
||||
*/
|
||||
public function parse(string $content): array
|
||||
{
|
||||
$boxes = [];
|
||||
|
||||
$dom = new DOMDocument;
|
||||
$dom->loadXML($content);
|
||||
$spans = $dom->getElementsByTagName('span');
|
||||
|
||||
/** @var DOMElement $span */
|
||||
foreach ($spans as $span) {
|
||||
if ($span->getAttribute('class') === 'ocrx_word') {
|
||||
$title = $span->getAttribute('title');
|
||||
$coords = $this->extractCoordinates($title);
|
||||
$text = trim($span->nodeValue);
|
||||
|
||||
// Boxen ohne Text auslassen; kann vorkommen bei Barcode-Fonts
|
||||
if (empty($text)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Boxen mit Text sammeln
|
||||
$boxes[] = new BoundingBox(
|
||||
$coords['tlx'], $coords['tly'], $coords['brx'], $coords['bry'], ['text' => $text]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $boxes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
*
|
||||
* @return array|bool
|
||||
*/
|
||||
private function extractCoordinates(string $text)
|
||||
{
|
||||
// bbox 599 2737 743 2758; x_wconf 96
|
||||
$parts = explode(' ', $text);
|
||||
if ($parts[0] === 'bbox') {
|
||||
return [
|
||||
'tlx' => (int)$parts[1], // Top left X-Coordinate
|
||||
'tly' => (int)$parts[2], // Top left Y
|
||||
'brx' => (int)$parts[3], // Bottom right X
|
||||
'bry' => (int)$parts[4], // Bottom right Y
|
||||
];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user