cad area
This commit is contained in:
@@ -46,6 +46,7 @@ public/userarea/last_url.txt
|
|||||||
public/userarea/class/curl_auth_debug.log
|
public/userarea/class/curl_auth_debug.log
|
||||||
public/userarea/class/curl_request_debug.log
|
public/userarea/class/curl_request_debug.log
|
||||||
|
|
||||||
|
public/userarea/uploads/cad_area/originals/*
|
||||||
# Ignora tutti i log
|
# Ignora tutti i log
|
||||||
*.log
|
*.log
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Phinx\Migration\AbstractMigration;
|
||||||
|
|
||||||
|
final class AddRoiFieldsToCadAreaJobsTable extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function change(): void
|
||||||
|
{
|
||||||
|
$table = $this->table('cad_area_jobs');
|
||||||
|
|
||||||
|
if (!$table->hasColumn('roi_x')) {
|
||||||
|
$table->addColumn('roi_x', 'decimal', [
|
||||||
|
'precision' => 12,
|
||||||
|
'scale' => 6,
|
||||||
|
'null' => true,
|
||||||
|
'after' => 'file_size',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('roi_y')) {
|
||||||
|
$table->addColumn('roi_y', 'decimal', [
|
||||||
|
'precision' => 12,
|
||||||
|
'scale' => 6,
|
||||||
|
'null' => true,
|
||||||
|
'after' => 'roi_x',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('roi_width')) {
|
||||||
|
$table->addColumn('roi_width', 'decimal', [
|
||||||
|
'precision' => 12,
|
||||||
|
'scale' => 6,
|
||||||
|
'null' => true,
|
||||||
|
'after' => 'roi_y',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('roi_height')) {
|
||||||
|
$table->addColumn('roi_height', 'decimal', [
|
||||||
|
'precision' => 12,
|
||||||
|
'scale' => 6,
|
||||||
|
'null' => true,
|
||||||
|
'after' => 'roi_width',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('roi_page')) {
|
||||||
|
$table->addColumn('roi_page', 'integer', [
|
||||||
|
'null' => true,
|
||||||
|
'default' => 1,
|
||||||
|
'after' => 'roi_height',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('calculation_mode')) {
|
||||||
|
$table->addColumn('calculation_mode', 'string', [
|
||||||
|
'limit' => 50,
|
||||||
|
'null' => true,
|
||||||
|
'default' => 'auto_roi',
|
||||||
|
'after' => 'roi_page',
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$table->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Phinx\Migration\AbstractMigration;
|
||||||
|
|
||||||
|
final class AddResultDetailFieldsToCadAreaJobsTable extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function change(): void
|
||||||
|
{
|
||||||
|
$table = $this->table('cad_area_jobs');
|
||||||
|
|
||||||
|
if (!$table->hasColumn('width_mm')) {
|
||||||
|
$table->addColumn('width_mm', 'decimal', [
|
||||||
|
'precision' => 18,
|
||||||
|
'scale' => 6,
|
||||||
|
'null' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('height_mm')) {
|
||||||
|
$table->addColumn('height_mm', 'decimal', [
|
||||||
|
'precision' => 18,
|
||||||
|
'scale' => 6,
|
||||||
|
'null' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('scale_used')) {
|
||||||
|
$table->addColumn('scale_used', 'decimal', [
|
||||||
|
'precision' => 12,
|
||||||
|
'scale' => 6,
|
||||||
|
'null' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('strategy_used')) {
|
||||||
|
$table->addColumn('strategy_used', 'string', [
|
||||||
|
'limit' => 100,
|
||||||
|
'null' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$table->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Phinx\Migration\AbstractMigration;
|
||||||
|
|
||||||
|
final class AddManualTracingFieldsToCadAreaJobsTable extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function change(): void
|
||||||
|
{
|
||||||
|
$table = $this->table('cad_area_jobs');
|
||||||
|
|
||||||
|
if (!$table->hasColumn('width_mm')) {
|
||||||
|
$table->addColumn('width_mm', 'decimal', [
|
||||||
|
'precision' => 18,
|
||||||
|
'scale' => 6,
|
||||||
|
'null' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('height_mm')) {
|
||||||
|
$table->addColumn('height_mm', 'decimal', [
|
||||||
|
'precision' => 18,
|
||||||
|
'scale' => 6,
|
||||||
|
'null' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('scale_used')) {
|
||||||
|
$table->addColumn('scale_used', 'decimal', [
|
||||||
|
'precision' => 12,
|
||||||
|
'scale' => 6,
|
||||||
|
'null' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('strategy_used')) {
|
||||||
|
$table->addColumn('strategy_used', 'string', [
|
||||||
|
'limit' => 100,
|
||||||
|
'null' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('manual_calibration_px')) {
|
||||||
|
$table->addColumn('manual_calibration_px', 'decimal', [
|
||||||
|
'precision' => 18,
|
||||||
|
'scale' => 6,
|
||||||
|
'null' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('manual_calibration_mm')) {
|
||||||
|
$table->addColumn('manual_calibration_mm', 'decimal', [
|
||||||
|
'precision' => 18,
|
||||||
|
'scale' => 6,
|
||||||
|
'null' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('manual_mm_per_px')) {
|
||||||
|
$table->addColumn('manual_mm_per_px', 'decimal', [
|
||||||
|
'precision' => 18,
|
||||||
|
'scale' => 10,
|
||||||
|
'null' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('manual_polygon_json')) {
|
||||||
|
$table->addColumn('manual_polygon_json', 'text', [
|
||||||
|
'null' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('manual_area_mm2')) {
|
||||||
|
$table->addColumn('manual_area_mm2', 'decimal', [
|
||||||
|
'precision' => 18,
|
||||||
|
'scale' => 6,
|
||||||
|
'null' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('manual_area_cm2')) {
|
||||||
|
$table->addColumn('manual_area_cm2', 'decimal', [
|
||||||
|
'precision' => 18,
|
||||||
|
'scale' => 6,
|
||||||
|
'null' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('manual_width_mm')) {
|
||||||
|
$table->addColumn('manual_width_mm', 'decimal', [
|
||||||
|
'precision' => 18,
|
||||||
|
'scale' => 6,
|
||||||
|
'null' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('manual_height_mm')) {
|
||||||
|
$table->addColumn('manual_height_mm', 'decimal', [
|
||||||
|
'precision' => 18,
|
||||||
|
'scale' => 6,
|
||||||
|
'null' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('manual_status')) {
|
||||||
|
$table->addColumn('manual_status', 'string', [
|
||||||
|
'limit' => 50,
|
||||||
|
'null' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$table->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Phinx\Migration\AbstractMigration;
|
||||||
|
|
||||||
|
final class AddManualHoleFieldsToCadAreaJobsTable extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function change(): void
|
||||||
|
{
|
||||||
|
$table = $this->table('cad_area_jobs');
|
||||||
|
|
||||||
|
if (!$table->hasColumn('manual_outer_area_mm2')) {
|
||||||
|
$table->addColumn('manual_outer_area_mm2', 'decimal', [
|
||||||
|
'precision' => 18,
|
||||||
|
'scale' => 6,
|
||||||
|
'null' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('manual_holes_area_mm2')) {
|
||||||
|
$table->addColumn('manual_holes_area_mm2', 'decimal', [
|
||||||
|
'precision' => 18,
|
||||||
|
'scale' => 6,
|
||||||
|
'null' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$table->hasColumn('manual_holes_json')) {
|
||||||
|
$table->addColumn('manual_holes_json', 'text', [
|
||||||
|
'null' => true,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$table->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
+1278
-99
File diff suppressed because it is too large
Load Diff
@@ -1,213 +1,149 @@
|
|||||||
<?php
|
<?php
|
||||||
header('Content-Type: application/json');
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
|
||||||
require_once(__DIR__ . '/include/headscript.php');
|
require_once(__DIR__ . '/include/headscript.php');
|
||||||
|
|
||||||
try {
|
function jsonResponse(array $data): void
|
||||||
$db = DBHandlerSelect::getInstance();
|
{
|
||||||
$pdo = $db->getConnection();
|
echo json_encode($data);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
$iduser = $iduserlogin ?? null;
|
function updateJobProcessing(PDO $pdo, int $id): void
|
||||||
|
{
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
UPDATE cad_area_jobs
|
||||||
|
SET
|
||||||
|
status = 'processing',
|
||||||
|
message = 'Elaborazione in corso...',
|
||||||
|
updated_at = NOW()
|
||||||
|
WHERE id = ?
|
||||||
|
");
|
||||||
|
|
||||||
$input = json_decode(file_get_contents('php://input'), true);
|
$stmt->execute([$id]);
|
||||||
|
}
|
||||||
|
|
||||||
if (empty($input['ids']) || !is_array($input['ids'])) {
|
function updateJobError(PDO $pdo, int $id, string $message, ?array $pythonResponse = null): void
|
||||||
throw new Exception('Nessun file selezionato.');
|
{
|
||||||
}
|
$stmt = $pdo->prepare("
|
||||||
|
UPDATE cad_area_jobs
|
||||||
|
SET
|
||||||
|
status = 'error',
|
||||||
|
message = ?,
|
||||||
|
python_response = ?,
|
||||||
|
updated_at = NOW()
|
||||||
|
WHERE id = ?
|
||||||
|
");
|
||||||
|
|
||||||
$ids = array_values(array_filter(array_map('intval', $input['ids'])));
|
$stmt->execute([
|
||||||
|
$message,
|
||||||
if (empty($ids)) {
|
$pythonResponse ? json_encode($pythonResponse) : null,
|
||||||
throw new Exception('ID non validi.');
|
$id
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Local Python service URL.
|
|
||||||
* In produzione su cPanel/Keliweb lo sostituiremo con l'URL reale del servizio Python.
|
|
||||||
*/
|
|
||||||
$pythonServiceUrl = 'http://127.0.0.1:5055/calculate';
|
|
||||||
|
|
||||||
$results = [];
|
|
||||||
|
|
||||||
foreach ($ids as $id) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Recupero job.
|
|
||||||
* Uso placeholder ? per evitare errori PDO HY093.
|
|
||||||
*/
|
|
||||||
if ($iduser === null || $iduser === '') {
|
|
||||||
$stmt = $pdo->prepare("
|
|
||||||
SELECT *
|
|
||||||
FROM cad_area_jobs
|
|
||||||
WHERE id = ?
|
|
||||||
LIMIT 1
|
|
||||||
");
|
|
||||||
|
|
||||||
$stmt->execute([
|
|
||||||
$id
|
|
||||||
]);
|
|
||||||
} else {
|
|
||||||
$stmt = $pdo->prepare("
|
|
||||||
SELECT *
|
|
||||||
FROM cad_area_jobs
|
|
||||||
WHERE id = ?
|
|
||||||
AND iduser = ?
|
|
||||||
LIMIT 1
|
|
||||||
");
|
|
||||||
|
|
||||||
$stmt->execute([
|
|
||||||
$id,
|
|
||||||
$iduser
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
$job = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
||||||
|
|
||||||
if (!$job) {
|
|
||||||
$results[] = [
|
|
||||||
'id' => $id,
|
|
||||||
'success' => false,
|
|
||||||
'message' => 'Record non trovato.'
|
|
||||||
];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (empty($job['file_path']) || !file_exists($job['file_path'])) {
|
|
||||||
updateJobError($pdo, $id, 'File PDF non trovato sul server.');
|
|
||||||
|
|
||||||
$results[] = [
|
|
||||||
'id' => $id,
|
|
||||||
'success' => false,
|
|
||||||
'message' => 'File PDF non trovato sul server.'
|
|
||||||
];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$stmtProcessing = $pdo->prepare("
|
|
||||||
UPDATE cad_area_jobs
|
|
||||||
SET
|
|
||||||
status = ?,
|
|
||||||
message = ?
|
|
||||||
WHERE id = ?
|
|
||||||
");
|
|
||||||
|
|
||||||
$stmtProcessing->execute([
|
|
||||||
'processing',
|
|
||||||
null,
|
|
||||||
$id
|
|
||||||
]);
|
|
||||||
|
|
||||||
$pythonResponse = callPythonAreaService(
|
|
||||||
$pythonServiceUrl,
|
|
||||||
$job['file_path'],
|
|
||||||
$job['original_filename']
|
|
||||||
);
|
|
||||||
|
|
||||||
if (empty($pythonResponse['success'])) {
|
|
||||||
updateJobError(
|
|
||||||
$pdo,
|
|
||||||
$id,
|
|
||||||
$pythonResponse['message'] ?? 'Errore servizio Python.',
|
|
||||||
$pythonResponse
|
|
||||||
);
|
|
||||||
|
|
||||||
$results[] = [
|
|
||||||
'id' => $id,
|
|
||||||
'success' => false,
|
|
||||||
'message' => $pythonResponse['message'] ?? 'Errore servizio Python.',
|
|
||||||
'python_response' => $pythonResponse
|
|
||||||
];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$areaMm2 = isset($pythonResponse['area_mm2']) && $pythonResponse['area_mm2'] !== null
|
|
||||||
? (float)$pythonResponse['area_mm2']
|
|
||||||
: null;
|
|
||||||
|
|
||||||
$areaCm2 = isset($pythonResponse['area_cm2']) && $pythonResponse['area_cm2'] !== null
|
|
||||||
? (float)$pythonResponse['area_cm2']
|
|
||||||
: ($areaMm2 !== null ? $areaMm2 / 100 : null);
|
|
||||||
|
|
||||||
$areaM2 = isset($pythonResponse['area_m2']) && $pythonResponse['area_m2'] !== null
|
|
||||||
? (float)$pythonResponse['area_m2']
|
|
||||||
: ($areaMm2 !== null ? $areaMm2 / 1000000 : null);
|
|
||||||
|
|
||||||
$stmtUpdate = $pdo->prepare("
|
|
||||||
UPDATE cad_area_jobs
|
|
||||||
SET
|
|
||||||
status = ?,
|
|
||||||
area_mm2 = ?,
|
|
||||||
area_cm2 = ?,
|
|
||||||
area_m2 = ?,
|
|
||||||
scale_detected = ?,
|
|
||||||
confidence = ?,
|
|
||||||
message = ?,
|
|
||||||
python_response = ?
|
|
||||||
WHERE id = ?
|
|
||||||
");
|
|
||||||
|
|
||||||
$stmtUpdate->execute([
|
|
||||||
'completed',
|
|
||||||
$areaMm2,
|
|
||||||
$areaCm2,
|
|
||||||
$areaM2,
|
|
||||||
$pythonResponse['scale_detected'] ?? null,
|
|
||||||
$pythonResponse['confidence'] ?? null,
|
|
||||||
$pythonResponse['message'] ?? null,
|
|
||||||
json_encode($pythonResponse, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE),
|
|
||||||
$id
|
|
||||||
]);
|
|
||||||
|
|
||||||
$results[] = [
|
|
||||||
'id' => $id,
|
|
||||||
'success' => true,
|
|
||||||
'area_mm2' => $areaMm2,
|
|
||||||
'area_cm2' => $areaCm2,
|
|
||||||
'area_m2' => $areaM2,
|
|
||||||
'message' => $pythonResponse['message'] ?? null
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
echo json_encode([
|
|
||||||
'success' => true,
|
|
||||||
'results' => $results
|
|
||||||
]);
|
|
||||||
} catch (Throwable $e) {
|
|
||||||
error_log('CAD area process error: ' . $e->getMessage());
|
|
||||||
error_log('File: ' . $e->getFile());
|
|
||||||
error_log('Line: ' . $e->getLine());
|
|
||||||
|
|
||||||
echo json_encode([
|
|
||||||
'success' => false,
|
|
||||||
'message' => $e->getMessage(),
|
|
||||||
'file' => $e->getFile(),
|
|
||||||
'line' => $e->getLine()
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateJobCompleted(PDO $pdo, int $id, array $response): void
|
||||||
function callPythonAreaService(string $url, string $filePath, string $originalFilename): array
|
|
||||||
{
|
{
|
||||||
if (!class_exists('CURLFile')) {
|
$stmt = $pdo->prepare("
|
||||||
|
UPDATE cad_area_jobs
|
||||||
|
SET
|
||||||
|
status = 'completed',
|
||||||
|
message = ?,
|
||||||
|
area_mm2 = ?,
|
||||||
|
area_cm2 = ?,
|
||||||
|
area_m2 = ?,
|
||||||
|
width_mm = ?,
|
||||||
|
height_mm = ?,
|
||||||
|
scale_detected = ?,
|
||||||
|
scale_used = ?,
|
||||||
|
confidence = ?,
|
||||||
|
python_response = ?,
|
||||||
|
updated_at = NOW()
|
||||||
|
WHERE id = ?
|
||||||
|
");
|
||||||
|
|
||||||
|
$stmt->execute([
|
||||||
|
$response['message'] ?? 'Area calcolata correttamente.',
|
||||||
|
$response['area_mm2'] ?? null,
|
||||||
|
$response['area_cm2'] ?? null,
|
||||||
|
$response['area_m2'] ?? null,
|
||||||
|
$response['width_mm'] ?? null,
|
||||||
|
$response['height_mm'] ?? null,
|
||||||
|
$response['scale_detected'] ?? null,
|
||||||
|
$response['scale_used'] ?? null,
|
||||||
|
$response['confidence'] ?? null,
|
||||||
|
json_encode($response),
|
||||||
|
$id
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeCalculationMode(?string $mode): string
|
||||||
|
{
|
||||||
|
$allowed = [
|
||||||
|
'auto_roi',
|
||||||
|
'stitch_contour',
|
||||||
|
'filled_union',
|
||||||
|
'closed_path'
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!$mode || !in_array($mode, $allowed, true)) {
|
||||||
|
return 'auto_roi';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasValidRoi(array $job): bool
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
array_key_exists('roi_x', $job) &&
|
||||||
|
array_key_exists('roi_y', $job) &&
|
||||||
|
array_key_exists('roi_width', $job) &&
|
||||||
|
array_key_exists('roi_height', $job) &&
|
||||||
|
$job['roi_x'] !== null &&
|
||||||
|
$job['roi_y'] !== null &&
|
||||||
|
$job['roi_width'] !== null &&
|
||||||
|
$job['roi_height'] !== null &&
|
||||||
|
(float)$job['roi_width'] > 0 &&
|
||||||
|
(float)$job['roi_height'] > 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function callPythonAreaService(string $url, array $job): array
|
||||||
|
{
|
||||||
|
$filePath = $job['file_path'] ?? '';
|
||||||
|
$originalFilename = $job['original_filename'] ?? basename($filePath);
|
||||||
|
|
||||||
|
if (!$filePath || !file_exists($filePath)) {
|
||||||
return [
|
return [
|
||||||
'success' => false,
|
'success' => false,
|
||||||
'message' => 'CURLFile non disponibile sul server PHP.'
|
'message' => 'File PDF non trovato sul server: ' . $filePath
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!function_exists('curl_init')) {
|
$mode = normalizeCalculationMode($job['calculation_mode'] ?? 'auto_roi');
|
||||||
return [
|
|
||||||
'success' => false,
|
$scaleRatio = $job['scale_used'] ?? null;
|
||||||
'message' => 'Estensione PHP cURL non disponibile.'
|
|
||||||
];
|
if ($scaleRatio === null || $scaleRatio === '' || (float)$scaleRatio <= 0) {
|
||||||
|
$scaleRatio = '1';
|
||||||
}
|
}
|
||||||
|
|
||||||
$curlFile = new CURLFile($filePath, 'application/pdf', $originalFilename);
|
$curlFile = new CURLFile(
|
||||||
|
$filePath,
|
||||||
|
'application/pdf',
|
||||||
|
$originalFilename
|
||||||
|
);
|
||||||
|
|
||||||
$postFields = [
|
$postFields = [
|
||||||
'file' => $curlFile,
|
'file' => $curlFile,
|
||||||
'mode' => 'pdf_vector',
|
'mode' => $mode,
|
||||||
'scale_ratio' => '1'
|
'scale_ratio' => (string)$scaleRatio,
|
||||||
|
'roi_x' => (string)$job['roi_x'],
|
||||||
|
'roi_y' => (string)$job['roi_y'],
|
||||||
|
'roi_width' => (string)$job['roi_width'],
|
||||||
|
'roi_height' => (string)$job['roi_height'],
|
||||||
|
'roi_page' => (string)($job['roi_page'] ?? 1)
|
||||||
];
|
];
|
||||||
|
|
||||||
$ch = curl_init();
|
$ch = curl_init();
|
||||||
@@ -218,65 +154,185 @@ function callPythonAreaService(string $url, string $filePath, string $originalFi
|
|||||||
CURLOPT_POSTFIELDS => $postFields,
|
CURLOPT_POSTFIELDS => $postFields,
|
||||||
CURLOPT_RETURNTRANSFER => true,
|
CURLOPT_RETURNTRANSFER => true,
|
||||||
CURLOPT_TIMEOUT => 180,
|
CURLOPT_TIMEOUT => 180,
|
||||||
CURLOPT_CONNECTTIMEOUT => 20,
|
CURLOPT_CONNECTTIMEOUT => 10,
|
||||||
CURLOPT_SSL_VERIFYPEER => false,
|
CURLOPT_HTTPHEADER => [
|
||||||
CURLOPT_SSL_VERIFYHOST => false
|
'Accept: application/json'
|
||||||
|
]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$response = curl_exec($ch);
|
$rawResponse = curl_exec($ch);
|
||||||
|
$curlError = curl_error($ch);
|
||||||
|
$httpCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
|
||||||
if ($response === false) {
|
|
||||||
$error = curl_error($ch);
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
return [
|
|
||||||
'success' => false,
|
|
||||||
'message' => 'Errore cURL verso Python: ' . $error
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
||||||
curl_close($ch);
|
curl_close($ch);
|
||||||
|
|
||||||
$decoded = json_decode($response, true);
|
if ($rawResponse === false) {
|
||||||
|
|
||||||
if ($httpCode < 200 || $httpCode >= 300) {
|
|
||||||
return [
|
return [
|
||||||
'success' => false,
|
'success' => false,
|
||||||
'message' => 'Servizio Python HTTP ' . $httpCode,
|
'message' => 'Errore cURL verso Python: ' . $curlError
|
||||||
'raw_response' => $response
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$decoded = json_decode($rawResponse, true);
|
||||||
|
|
||||||
if (!is_array($decoded)) {
|
if (!is_array($decoded)) {
|
||||||
return [
|
return [
|
||||||
'success' => false,
|
'success' => false,
|
||||||
'message' => 'Risposta Python non valida.',
|
'message' => 'Risposta Python non JSON valida.',
|
||||||
'raw_response' => $response
|
'http_code' => $httpCode,
|
||||||
|
'raw_response' => $rawResponse
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($httpCode < 200 || $httpCode >= 300) {
|
||||||
|
return [
|
||||||
|
'success' => false,
|
||||||
|
'message' => $decoded['message'] ?? ('Servizio Python HTTP ' . $httpCode),
|
||||||
|
'http_code' => $httpCode,
|
||||||
|
'python_response' => $decoded,
|
||||||
|
'raw_response' => $rawResponse
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $decoded;
|
return $decoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
function updateJobError(PDO $pdo, int $id, string $message, ?array $pythonResponse = null): void
|
$iduser = $iduserlogin ?? null;
|
||||||
{
|
|
||||||
$stmt = $pdo->prepare("
|
|
||||||
UPDATE cad_area_jobs
|
|
||||||
SET
|
|
||||||
status = ?,
|
|
||||||
message = ?,
|
|
||||||
python_response = ?
|
|
||||||
WHERE id = ?
|
|
||||||
");
|
|
||||||
|
|
||||||
$stmt->execute([
|
$input = json_decode(file_get_contents('php://input'), true);
|
||||||
'error',
|
|
||||||
$message,
|
if (!is_array($input)) {
|
||||||
$pythonResponse
|
jsonResponse([
|
||||||
? json_encode($pythonResponse, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
|
'success' => false,
|
||||||
: null,
|
'message' => 'Payload JSON non valido.'
|
||||||
$id
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$ids = $input['ids'] ?? [];
|
||||||
|
|
||||||
|
if (!is_array($ids) || count($ids) === 0) {
|
||||||
|
jsonResponse([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Nessun ID ricevuto.'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$ids = array_values(array_unique(array_map('intval', $ids)));
|
||||||
|
$ids = array_filter($ids, fn($id) => $id > 0);
|
||||||
|
|
||||||
|
if (count($ids) === 0) {
|
||||||
|
jsonResponse([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Nessun ID valido ricevuto.'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$pythonServiceUrl = 'http://127.0.0.1:5055/calculate';
|
||||||
|
|
||||||
|
$results = [];
|
||||||
|
|
||||||
|
foreach ($ids as $id) {
|
||||||
|
if ($iduser === null || $iduser === '') {
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
SELECT *
|
||||||
|
FROM cad_area_jobs
|
||||||
|
WHERE id = ?
|
||||||
|
LIMIT 1
|
||||||
|
");
|
||||||
|
|
||||||
|
$stmt->execute([$id]);
|
||||||
|
} else {
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
SELECT *
|
||||||
|
FROM cad_area_jobs
|
||||||
|
WHERE id = ?
|
||||||
|
AND iduser = ?
|
||||||
|
LIMIT 1
|
||||||
|
");
|
||||||
|
|
||||||
|
$stmt->execute([$id, $iduser]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$job = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if (!$job) {
|
||||||
|
$results[] = [
|
||||||
|
'id' => $id,
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Record non trovato.'
|
||||||
|
];
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasValidRoi($job)) {
|
||||||
|
$message = 'Prima devi definire la sezione da misurare tramite il pulsante Sezione.';
|
||||||
|
|
||||||
|
updateJobError($pdo, $id, $message, [
|
||||||
|
'success' => false,
|
||||||
|
'message' => $message,
|
||||||
|
'job_roi_debug' => [
|
||||||
|
'roi_x' => $job['roi_x'] ?? null,
|
||||||
|
'roi_y' => $job['roi_y'] ?? null,
|
||||||
|
'roi_width' => $job['roi_width'] ?? null,
|
||||||
|
'roi_height' => $job['roi_height'] ?? null,
|
||||||
|
'roi_page' => $job['roi_page'] ?? null,
|
||||||
|
'calculation_mode' => $job['calculation_mode'] ?? null
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$results[] = [
|
||||||
|
'id' => $id,
|
||||||
|
'success' => false,
|
||||||
|
'message' => $message
|
||||||
|
];
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateJobProcessing($pdo, $id);
|
||||||
|
|
||||||
|
$pythonResponse = callPythonAreaService($pythonServiceUrl, $job);
|
||||||
|
|
||||||
|
if (!($pythonResponse['success'] ?? false)) {
|
||||||
|
$message = $pythonResponse['message'] ?? 'Errore durante il calcolo Python.';
|
||||||
|
|
||||||
|
updateJobError($pdo, $id, $message, $pythonResponse);
|
||||||
|
|
||||||
|
$results[] = [
|
||||||
|
'id' => $id,
|
||||||
|
'success' => false,
|
||||||
|
'message' => $message,
|
||||||
|
'python_response' => $pythonResponse
|
||||||
|
];
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateJobCompleted($pdo, $id, $pythonResponse);
|
||||||
|
|
||||||
|
$results[] = [
|
||||||
|
'id' => $id,
|
||||||
|
'success' => true,
|
||||||
|
'message' => $pythonResponse['message'] ?? 'Area calcolata.',
|
||||||
|
'area_mm2' => $pythonResponse['area_mm2'] ?? null,
|
||||||
|
'area_cm2' => $pythonResponse['area_cm2'] ?? null
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonResponse([
|
||||||
|
'success' => true,
|
||||||
|
'results' => $results
|
||||||
|
]);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
error_log('CAD area process error: ' . $e->getMessage());
|
||||||
|
|
||||||
|
jsonResponse([
|
||||||
|
'success' => false,
|
||||||
|
'message' => $e->getMessage()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,297 @@
|
|||||||
|
<?php
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
|
||||||
|
require_once(__DIR__ . '/include/headscript.php');
|
||||||
|
|
||||||
|
function jsonResponse(array $data): void
|
||||||
|
{
|
||||||
|
echo json_encode($data);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$iduser = $iduserlogin ?? null;
|
||||||
|
|
||||||
|
$rawInput = file_get_contents('php://input');
|
||||||
|
$input = json_decode($rawInput, true);
|
||||||
|
|
||||||
|
if (!is_array($input)) {
|
||||||
|
jsonResponse([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Payload JSON non valido.'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = (int)($input['id'] ?? 0);
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
jsonResponse([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'ID non valido.'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$areaMm2 = isset($input['area_mm2']) ? (float)$input['area_mm2'] : 0;
|
||||||
|
$areaCm2 = isset($input['area_cm2']) ? (float)$input['area_cm2'] : 0;
|
||||||
|
|
||||||
|
$outerAreaMm2 = isset($input['manual_outer_area_mm2']) ? (float)$input['manual_outer_area_mm2'] : $areaMm2;
|
||||||
|
$holesAreaMm2 = isset($input['manual_holes_area_mm2']) ? (float)$input['manual_holes_area_mm2'] : 0;
|
||||||
|
|
||||||
|
$widthMm = isset($input['width_mm']) ? (float)$input['width_mm'] : null;
|
||||||
|
$heightMm = isset($input['height_mm']) ? (float)$input['height_mm'] : null;
|
||||||
|
|
||||||
|
$calibrationPx = isset($input['manual_calibration_px']) ? (float)$input['manual_calibration_px'] : 0;
|
||||||
|
$calibrationMm = isset($input['manual_calibration_mm']) ? (float)$input['manual_calibration_mm'] : 0;
|
||||||
|
$mmPerPx = isset($input['manual_mm_per_px']) ? (float)$input['manual_mm_per_px'] : 0;
|
||||||
|
|
||||||
|
$outerPolygon = $input['manual_polygon'] ?? null;
|
||||||
|
$holes = $input['manual_holes'] ?? [];
|
||||||
|
$roi = $input['roi'] ?? null;
|
||||||
|
|
||||||
|
if ($areaMm2 <= 0) {
|
||||||
|
jsonResponse([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Area finale non valida.'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($outerAreaMm2 <= 0) {
|
||||||
|
jsonResponse([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Area esterna non valida.'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($holesAreaMm2 < 0) {
|
||||||
|
jsonResponse([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Area fori non valida.'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($calibrationPx <= 0 || $calibrationMm <= 0 || $mmPerPx <= 0) {
|
||||||
|
jsonResponse([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Calibrazione non valida.'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($outerPolygon) || count($outerPolygon) < 3) {
|
||||||
|
jsonResponse([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Poligono esterno non valido. Servono almeno 3 punti.'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_array($holes)) {
|
||||||
|
$holes = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$manualPolygonJson = json_encode([
|
||||||
|
'outer_polygon' => $outerPolygon,
|
||||||
|
'holes' => $holes,
|
||||||
|
'roi' => $roi,
|
||||||
|
'calibration' => $input['calibration'] ?? null,
|
||||||
|
'canvas' => $input['canvas'] ?? null,
|
||||||
|
'areas' => [
|
||||||
|
'outer_area_mm2' => $outerAreaMm2,
|
||||||
|
'holes_area_mm2' => $holesAreaMm2,
|
||||||
|
'final_area_mm2' => $areaMm2,
|
||||||
|
'final_area_cm2' => $areaCm2
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
$manualHolesJson = json_encode($holes);
|
||||||
|
|
||||||
|
$roiX = null;
|
||||||
|
$roiY = null;
|
||||||
|
$roiW = null;
|
||||||
|
$roiH = null;
|
||||||
|
|
||||||
|
if (is_array($roi)) {
|
||||||
|
$roiX = isset($roi['x']) ? (float)$roi['x'] : null;
|
||||||
|
$roiY = isset($roi['y']) ? (float)$roi['y'] : null;
|
||||||
|
$roiW = isset($roi['width']) ? (float)$roi['width'] : null;
|
||||||
|
$roiH = isset($roi['height']) ? (float)$roi['height'] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($iduser === null || $iduser === '') {
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
UPDATE cad_area_jobs
|
||||||
|
SET
|
||||||
|
roi_x = COALESCE(?, roi_x),
|
||||||
|
roi_y = COALESCE(?, roi_y),
|
||||||
|
roi_width = COALESCE(?, roi_width),
|
||||||
|
roi_height = COALESCE(?, roi_height),
|
||||||
|
roi_page = 1,
|
||||||
|
|
||||||
|
status = 'completed',
|
||||||
|
message = 'Area calcolata tramite tracciamento manuale calibrato.',
|
||||||
|
|
||||||
|
area_mm2 = ?,
|
||||||
|
area_cm2 = ?,
|
||||||
|
area_m2 = ?,
|
||||||
|
|
||||||
|
manual_area_mm2 = ?,
|
||||||
|
manual_area_cm2 = ?,
|
||||||
|
manual_outer_area_mm2 = ?,
|
||||||
|
manual_holes_area_mm2 = ?,
|
||||||
|
manual_width_mm = ?,
|
||||||
|
manual_height_mm = ?,
|
||||||
|
|
||||||
|
width_mm = ?,
|
||||||
|
height_mm = ?,
|
||||||
|
|
||||||
|
manual_calibration_px = ?,
|
||||||
|
manual_calibration_mm = ?,
|
||||||
|
manual_mm_per_px = ?,
|
||||||
|
manual_polygon_json = ?,
|
||||||
|
manual_holes_json = ?,
|
||||||
|
manual_status = 'completed',
|
||||||
|
|
||||||
|
scale_used = ?,
|
||||||
|
scale_detected = ?,
|
||||||
|
confidence = 'manual_validated',
|
||||||
|
strategy_used = 'manual_tracing_with_exclusions',
|
||||||
|
|
||||||
|
python_response = NULL,
|
||||||
|
updated_at = NOW()
|
||||||
|
WHERE id = ?
|
||||||
|
");
|
||||||
|
|
||||||
|
$stmt->execute([
|
||||||
|
$roiX,
|
||||||
|
$roiY,
|
||||||
|
$roiW,
|
||||||
|
$roiH,
|
||||||
|
|
||||||
|
$areaMm2,
|
||||||
|
$areaCm2,
|
||||||
|
$areaMm2 / 1000000,
|
||||||
|
|
||||||
|
$areaMm2,
|
||||||
|
$areaCm2,
|
||||||
|
$outerAreaMm2,
|
||||||
|
$holesAreaMm2,
|
||||||
|
$widthMm,
|
||||||
|
$heightMm,
|
||||||
|
|
||||||
|
$widthMm,
|
||||||
|
$heightMm,
|
||||||
|
|
||||||
|
$calibrationPx,
|
||||||
|
$calibrationMm,
|
||||||
|
$mmPerPx,
|
||||||
|
$manualPolygonJson,
|
||||||
|
$manualHolesJson,
|
||||||
|
|
||||||
|
$mmPerPx,
|
||||||
|
'manual',
|
||||||
|
|
||||||
|
$id
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
UPDATE cad_area_jobs
|
||||||
|
SET
|
||||||
|
roi_x = COALESCE(?, roi_x),
|
||||||
|
roi_y = COALESCE(?, roi_y),
|
||||||
|
roi_width = COALESCE(?, roi_width),
|
||||||
|
roi_height = COALESCE(?, roi_height),
|
||||||
|
roi_page = 1,
|
||||||
|
|
||||||
|
status = 'completed',
|
||||||
|
message = 'Area calcolata tramite tracciamento manuale calibrato.',
|
||||||
|
|
||||||
|
area_mm2 = ?,
|
||||||
|
area_cm2 = ?,
|
||||||
|
area_m2 = ?,
|
||||||
|
|
||||||
|
manual_area_mm2 = ?,
|
||||||
|
manual_area_cm2 = ?,
|
||||||
|
manual_outer_area_mm2 = ?,
|
||||||
|
manual_holes_area_mm2 = ?,
|
||||||
|
manual_width_mm = ?,
|
||||||
|
manual_height_mm = ?,
|
||||||
|
|
||||||
|
width_mm = ?,
|
||||||
|
height_mm = ?,
|
||||||
|
|
||||||
|
manual_calibration_px = ?,
|
||||||
|
manual_calibration_mm = ?,
|
||||||
|
manual_mm_per_px = ?,
|
||||||
|
manual_polygon_json = ?,
|
||||||
|
manual_holes_json = ?,
|
||||||
|
manual_status = 'completed',
|
||||||
|
|
||||||
|
scale_used = ?,
|
||||||
|
scale_detected = ?,
|
||||||
|
confidence = 'manual_validated',
|
||||||
|
strategy_used = 'manual_tracing_with_exclusions',
|
||||||
|
|
||||||
|
python_response = NULL,
|
||||||
|
updated_at = NOW()
|
||||||
|
WHERE id = ?
|
||||||
|
AND iduser = ?
|
||||||
|
");
|
||||||
|
|
||||||
|
$stmt->execute([
|
||||||
|
$roiX,
|
||||||
|
$roiY,
|
||||||
|
$roiW,
|
||||||
|
$roiH,
|
||||||
|
|
||||||
|
$areaMm2,
|
||||||
|
$areaCm2,
|
||||||
|
$areaMm2 / 1000000,
|
||||||
|
|
||||||
|
$areaMm2,
|
||||||
|
$areaCm2,
|
||||||
|
$outerAreaMm2,
|
||||||
|
$holesAreaMm2,
|
||||||
|
$widthMm,
|
||||||
|
$heightMm,
|
||||||
|
|
||||||
|
$widthMm,
|
||||||
|
$heightMm,
|
||||||
|
|
||||||
|
$calibrationPx,
|
||||||
|
$calibrationMm,
|
||||||
|
$mmPerPx,
|
||||||
|
$manualPolygonJson,
|
||||||
|
$manualHolesJson,
|
||||||
|
|
||||||
|
$mmPerPx,
|
||||||
|
'manual',
|
||||||
|
|
||||||
|
$id,
|
||||||
|
$iduser
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($stmt->rowCount() === 0) {
|
||||||
|
jsonResponse([
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'Nessun record aggiornato. Controlla ID o utente.'
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonResponse([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'Area manuale salvata correttamente.',
|
||||||
|
'area_mm2' => $areaMm2,
|
||||||
|
'area_cm2' => $areaCm2,
|
||||||
|
'outer_area_mm2' => $outerAreaMm2,
|
||||||
|
'holes_area_mm2' => $holesAreaMm2
|
||||||
|
]);
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
error_log('CAD manual area save error: ' . $e->getMessage());
|
||||||
|
|
||||||
|
jsonResponse([
|
||||||
|
'success' => false,
|
||||||
|
'message' => $e->getMessage()
|
||||||
|
]);
|
||||||
|
}
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
<?php
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
|
||||||
|
require_once(__DIR__ . '/include/headscript.php');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$iduser = $iduserlogin ?? null;
|
||||||
|
|
||||||
|
$rawInput = file_get_contents('php://input');
|
||||||
|
$input = json_decode($rawInput, true);
|
||||||
|
|
||||||
|
if (!is_array($input)) {
|
||||||
|
throw new Exception('Payload JSON non valido.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = (int)($input['id'] ?? 0);
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
throw new Exception('ID non valido.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$roiX = isset($input['roi_x']) ? (float)$input['roi_x'] : null;
|
||||||
|
$roiY = isset($input['roi_y']) ? (float)$input['roi_y'] : null;
|
||||||
|
$roiW = isset($input['roi_width']) ? (float)$input['roi_width'] : null;
|
||||||
|
$roiH = isset($input['roi_height']) ? (float)$input['roi_height'] : null;
|
||||||
|
$roiPage = isset($input['roi_page']) ? (int)$input['roi_page'] : 1;
|
||||||
|
$mode = $input['calculation_mode'] ?? 'auto_roi';
|
||||||
|
|
||||||
|
if ($roiX === null || $roiY === null || $roiW === null || $roiH === null) {
|
||||||
|
throw new Exception('ROI non valida.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($roiW <= 0 || $roiH <= 0) {
|
||||||
|
throw new Exception('Dimensioni ROI non valide.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($roiX < 0 || $roiY < 0 || $roiX > 1 || $roiY > 1 || $roiW > 1 || $roiH > 1) {
|
||||||
|
throw new Exception('Coordinate ROI fuori scala.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$allowedModes = [
|
||||||
|
'auto_roi',
|
||||||
|
'stitch_contour',
|
||||||
|
'filled_union',
|
||||||
|
'closed_path'
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!in_array($mode, $allowedModes, true)) {
|
||||||
|
$mode = 'auto_roi';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($iduser === null || $iduser === '') {
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
UPDATE cad_area_jobs
|
||||||
|
SET
|
||||||
|
roi_x = ?,
|
||||||
|
roi_y = ?,
|
||||||
|
roi_width = ?,
|
||||||
|
roi_height = ?,
|
||||||
|
roi_page = ?,
|
||||||
|
calculation_mode = ?,
|
||||||
|
status = 'uploaded',
|
||||||
|
message = NULL
|
||||||
|
WHERE id = ?
|
||||||
|
");
|
||||||
|
|
||||||
|
$stmt->execute([
|
||||||
|
$roiX,
|
||||||
|
$roiY,
|
||||||
|
$roiW,
|
||||||
|
$roiH,
|
||||||
|
$roiPage,
|
||||||
|
$mode,
|
||||||
|
$id
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
UPDATE cad_area_jobs
|
||||||
|
SET
|
||||||
|
roi_x = ?,
|
||||||
|
roi_y = ?,
|
||||||
|
roi_width = ?,
|
||||||
|
roi_height = ?,
|
||||||
|
roi_page = ?,
|
||||||
|
calculation_mode = ?,
|
||||||
|
status = 'uploaded',
|
||||||
|
message = NULL
|
||||||
|
WHERE id = ?
|
||||||
|
AND iduser = ?
|
||||||
|
");
|
||||||
|
|
||||||
|
$stmt->execute([
|
||||||
|
$roiX,
|
||||||
|
$roiY,
|
||||||
|
$roiW,
|
||||||
|
$roiH,
|
||||||
|
$roiPage,
|
||||||
|
$mode,
|
||||||
|
$id,
|
||||||
|
$iduser
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($stmt->rowCount() === 0) {
|
||||||
|
throw new Exception('Nessun record aggiornato. Controlla ID o utente.');
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'ROI salvata correttamente.'
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
error_log('CAD area save ROI error: ' . $e->getMessage());
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => $e->getMessage()
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+50
-8
@@ -16,6 +16,30 @@ def health():
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
def get_float_or_none(name):
|
||||||
|
value = request.form.get(name, "").strip()
|
||||||
|
|
||||||
|
if value == "":
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
return float(value)
|
||||||
|
except ValueError:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_int_or_default(name, default=1):
|
||||||
|
value = request.form.get(name, "").strip()
|
||||||
|
|
||||||
|
if value == "":
|
||||||
|
return default
|
||||||
|
|
||||||
|
try:
|
||||||
|
return int(value)
|
||||||
|
except ValueError:
|
||||||
|
return default
|
||||||
|
|
||||||
|
|
||||||
@app.route("/calculate", methods=["POST"])
|
@app.route("/calculate", methods=["POST"])
|
||||||
def calculate():
|
def calculate():
|
||||||
try:
|
try:
|
||||||
@@ -41,19 +65,37 @@ def calculate():
|
|||||||
|
|
||||||
pdf_bytes = uploaded_file.read()
|
pdf_bytes = uploaded_file.read()
|
||||||
|
|
||||||
scale_ratio = request.form.get("scale_ratio", "1")
|
scale_ratio = get_float_or_none("scale_ratio")
|
||||||
|
|
||||||
try:
|
if scale_ratio is not None and scale_ratio <= 0:
|
||||||
scale_ratio = float(scale_ratio)
|
scale_ratio = None
|
||||||
if scale_ratio <= 0:
|
|
||||||
scale_ratio = 1.0
|
roi = {
|
||||||
except ValueError:
|
"x": get_float_or_none("roi_x"),
|
||||||
scale_ratio = 1.0
|
"y": get_float_or_none("roi_y"),
|
||||||
|
"width": get_float_or_none("roi_width"),
|
||||||
|
"height": get_float_or_none("roi_height"),
|
||||||
|
"page": get_int_or_default("roi_page", 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
has_roi = (
|
||||||
|
roi["x"] is not None and
|
||||||
|
roi["y"] is not None and
|
||||||
|
roi["width"] is not None and
|
||||||
|
roi["height"] is not None and
|
||||||
|
roi["width"] > 0 and
|
||||||
|
roi["height"] > 0
|
||||||
|
)
|
||||||
|
|
||||||
|
mode = request.form.get("mode", "auto_roi")
|
||||||
|
|
||||||
result = calculate_pdf_vector_area(
|
result = calculate_pdf_vector_area(
|
||||||
pdf_bytes=pdf_bytes,
|
pdf_bytes=pdf_bytes,
|
||||||
filename=uploaded_file.filename,
|
filename=uploaded_file.filename,
|
||||||
scale_ratio=scale_ratio
|
scale_ratio=scale_ratio,
|
||||||
|
profile_color=None,
|
||||||
|
roi=roi if has_roi else None,
|
||||||
|
mode=mode
|
||||||
)
|
)
|
||||||
|
|
||||||
status_code = 200 if result.get("success") else 422
|
status_code = 200 if result.get("success") else 422
|
||||||
|
|||||||
@@ -0,0 +1,124 @@
|
|||||||
|
<?php
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
|
||||||
|
require_once(__DIR__ . '/include/headscript.php');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$db = DBHandlerSelect::getInstance();
|
||||||
|
$pdo = $db->getConnection();
|
||||||
|
|
||||||
|
$iduser = $iduserlogin ?? null;
|
||||||
|
|
||||||
|
$rawInput = file_get_contents('php://input');
|
||||||
|
$input = json_decode($rawInput, true);
|
||||||
|
|
||||||
|
if (!is_array($input)) {
|
||||||
|
throw new Exception('Payload JSON non valido.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = (int)($input['id'] ?? 0);
|
||||||
|
|
||||||
|
if ($id <= 0) {
|
||||||
|
throw new Exception('ID non valido.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$roiX = isset($input['roi_x']) ? (float)$input['roi_x'] : null;
|
||||||
|
$roiY = isset($input['roi_y']) ? (float)$input['roi_y'] : null;
|
||||||
|
$roiW = isset($input['roi_width']) ? (float)$input['roi_width'] : null;
|
||||||
|
$roiH = isset($input['roi_height']) ? (float)$input['roi_height'] : null;
|
||||||
|
$roiPage = isset($input['roi_page']) ? (int)$input['roi_page'] : 1;
|
||||||
|
$mode = $input['calculation_mode'] ?? 'auto_roi';
|
||||||
|
|
||||||
|
if ($roiX === null || $roiY === null || $roiW === null || $roiH === null) {
|
||||||
|
throw new Exception('ROI non valida.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($roiW <= 0 || $roiH <= 0) {
|
||||||
|
throw new Exception('Dimensioni ROI non valide.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($roiX < 0 || $roiY < 0 || $roiX > 1 || $roiY > 1 || $roiW > 1 || $roiH > 1) {
|
||||||
|
throw new Exception('Coordinate ROI fuori scala.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$allowedModes = [
|
||||||
|
'auto_roi',
|
||||||
|
'stitch_contour',
|
||||||
|
'filled_union',
|
||||||
|
'closed_path'
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!in_array($mode, $allowedModes, true)) {
|
||||||
|
$mode = 'auto_roi';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($iduser === null || $iduser === '') {
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
UPDATE cad_area_jobs
|
||||||
|
SET
|
||||||
|
roi_x = ?,
|
||||||
|
roi_y = ?,
|
||||||
|
roi_width = ?,
|
||||||
|
roi_height = ?,
|
||||||
|
roi_page = ?,
|
||||||
|
calculation_mode = ?,
|
||||||
|
status = 'uploaded',
|
||||||
|
message = NULL
|
||||||
|
WHERE id = ?
|
||||||
|
");
|
||||||
|
|
||||||
|
$stmt->execute([
|
||||||
|
$roiX,
|
||||||
|
$roiY,
|
||||||
|
$roiW,
|
||||||
|
$roiH,
|
||||||
|
$roiPage,
|
||||||
|
$mode,
|
||||||
|
$id
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
$stmt = $pdo->prepare("
|
||||||
|
UPDATE cad_area_jobs
|
||||||
|
SET
|
||||||
|
roi_x = ?,
|
||||||
|
roi_y = ?,
|
||||||
|
roi_width = ?,
|
||||||
|
roi_height = ?,
|
||||||
|
roi_page = ?,
|
||||||
|
calculation_mode = ?,
|
||||||
|
status = 'uploaded',
|
||||||
|
message = NULL
|
||||||
|
WHERE id = ?
|
||||||
|
AND iduser = ?
|
||||||
|
");
|
||||||
|
|
||||||
|
$stmt->execute([
|
||||||
|
$roiX,
|
||||||
|
$roiY,
|
||||||
|
$roiW,
|
||||||
|
$roiH,
|
||||||
|
$roiPage,
|
||||||
|
$mode,
|
||||||
|
$id,
|
||||||
|
$iduser
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($stmt->rowCount() === 0) {
|
||||||
|
throw new Exception('Nessun record aggiornato. Controlla ID o utente.');
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'message' => 'ROI salvata correttamente.'
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
} catch (Throwable $e) {
|
||||||
|
error_log('CAD area save ROI error: ' . $e->getMessage());
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'success' => false,
|
||||||
|
'message' => $e->getMessage()
|
||||||
|
]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
+678
-277
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user