Initial xentral_oss_20.3.c9ffacf

This commit is contained in:
Alex
2021-05-21 08:49:41 +02:00
parent 5406e4a551
commit 34e5ac43d9
18884 changed files with 2109867 additions and 0 deletions
@@ -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;
}
}