329 lines
8.8 KiB
PHP
329 lines
8.8 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
ini_set('display_errors', '1');
|
|
error_reporting(E_ALL);
|
|
date_default_timezone_set('UTC');
|
|
|
|
$config = require __DIR__ . '/../../config/database.php';
|
|
$csvFile = __DIR__ . '/deepsky.csv';
|
|
|
|
$dsn = sprintf(
|
|
'mysql:host=%s;dbname=%s;charset=%s',
|
|
$config['host'],
|
|
$config['dbname'],
|
|
$config['charset'] ?? 'utf8mb4'
|
|
);
|
|
|
|
$pdo = new PDO(
|
|
$dsn,
|
|
$config['user'],
|
|
$config['pass'],
|
|
[
|
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
|
]
|
|
);
|
|
|
|
function normalizeHeader(string $value): string
|
|
{
|
|
$value = trim($value);
|
|
$value = strtolower($value);
|
|
|
|
$map = [
|
|
' - ' => '_',
|
|
'-' => '_',
|
|
' ' => '_',
|
|
'(' => '',
|
|
')' => '',
|
|
'.' => '',
|
|
'/' => '_',
|
|
];
|
|
|
|
$value = strtr($value, $map);
|
|
$value = preg_replace('/[^a-z0-9_]+/', '', $value);
|
|
$value = preg_replace('/_+/', '_', $value);
|
|
|
|
return trim((string)$value, '_');
|
|
}
|
|
|
|
function nullIfEmpty(mixed $value): mixed
|
|
{
|
|
if ($value === null) {
|
|
return null;
|
|
}
|
|
|
|
if (is_string($value)) {
|
|
$value = trim($value);
|
|
return $value === '' ? null : $value;
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
function toNullableString(mixed $value): ?string
|
|
{
|
|
$value = nullIfEmpty($value);
|
|
return $value === null ? null : (string)$value;
|
|
}
|
|
|
|
function toNullableFloat(mixed $value): ?float
|
|
{
|
|
$value = nullIfEmpty($value);
|
|
if ($value === null) {
|
|
return null;
|
|
}
|
|
|
|
$value = str_replace(',', '.', (string)$value);
|
|
return is_numeric($value) ? (float)$value : null;
|
|
}
|
|
|
|
function hmsToDegrees(?string $ra): ?float
|
|
{
|
|
$ra = toNullableString($ra);
|
|
if ($ra === null) {
|
|
return null;
|
|
}
|
|
|
|
if (!preg_match('/^\s*(\d{1,2}):(\d{1,2}):(\d{1,2}(?:\.\d+)?)\s*$/', $ra, $m)) {
|
|
return null;
|
|
}
|
|
|
|
$hours = (float)$m[1];
|
|
$minutes = (float)$m[2];
|
|
$seconds = (float)$m[3];
|
|
|
|
$hoursDecimal = $hours + ($minutes / 60.0) + ($seconds / 3600.0);
|
|
return $hoursDecimal * 15.0;
|
|
}
|
|
|
|
function dmsToDegrees(?string $dec): ?float
|
|
{
|
|
$dec = toNullableString($dec);
|
|
if ($dec === null) {
|
|
return null;
|
|
}
|
|
|
|
if (!preg_match('/^\s*([+\-]?)(\d{1,2}):(\d{1,2}):(\d{1,2}(?:\.\d+)?)\s*$/', $dec, $m)) {
|
|
return null;
|
|
}
|
|
|
|
$sign = ($m[1] === '-') ? -1.0 : 1.0;
|
|
$degrees = (float)$m[2];
|
|
$minutes = (float)$m[3];
|
|
$seconds = (float)$m[4];
|
|
|
|
$value = $degrees + ($minutes / 60.0) + ($seconds / 3600.0);
|
|
return $sign * $value;
|
|
}
|
|
|
|
if (!is_file($csvFile)) {
|
|
exit("CSV-Datei nicht gefunden: {$csvFile}\n");
|
|
}
|
|
|
|
$handle = fopen($csvFile, 'r');
|
|
if ($handle === false) {
|
|
exit("CSV-Datei konnte nicht geöffnet werden: {$csvFile}\n");
|
|
}
|
|
|
|
$header = fgetcsv($handle, 0, ';', '"', '');
|
|
if ($header === false) {
|
|
fclose($handle);
|
|
exit("CSV-Datei ist leer oder ungültig.\n");
|
|
}
|
|
|
|
$header = array_map(
|
|
static fn($value) => normalizeHeader((string)$value),
|
|
$header
|
|
);
|
|
|
|
$sql = "
|
|
INSERT INTO `dso_objects` (
|
|
`catalog_group`,
|
|
`name`,
|
|
`messier`,
|
|
`ngc`,
|
|
`ic`,
|
|
`object_type_abrev`,
|
|
`object_type`,
|
|
`ra`,
|
|
`dec`,
|
|
`ra_deg`,
|
|
`dec_deg`,
|
|
`constellation`,
|
|
`major_axis`,
|
|
`minor_axis`,
|
|
`position_angle`,
|
|
`b_mag`,
|
|
`v_mag`,
|
|
`j_mag`,
|
|
`h_mag`,
|
|
`k_mag`,
|
|
`surface_brightness`,
|
|
`hubble_type`,
|
|
`cstar_u_mag`,
|
|
`cstar_b_mag`,
|
|
`cstar_v_mag`,
|
|
`cstar_names`,
|
|
`identifiers`,
|
|
`common_names`,
|
|
`ned_notes`,
|
|
`openngc_notes`,
|
|
`image`,
|
|
`created_at`,
|
|
`updated_at`
|
|
) VALUES (
|
|
:catalog_group,
|
|
:name,
|
|
:messier,
|
|
:ngc,
|
|
:ic,
|
|
:object_type_abrev,
|
|
:object_type,
|
|
:ra,
|
|
:dec,
|
|
:ra_deg,
|
|
:dec_deg,
|
|
:constellation,
|
|
:major_axis,
|
|
:minor_axis,
|
|
:position_angle,
|
|
:b_mag,
|
|
:v_mag,
|
|
:j_mag,
|
|
:h_mag,
|
|
:k_mag,
|
|
:surface_brightness,
|
|
:hubble_type,
|
|
:cstar_u_mag,
|
|
:cstar_b_mag,
|
|
:cstar_v_mag,
|
|
:cstar_names,
|
|
:identifiers,
|
|
:common_names,
|
|
:ned_notes,
|
|
:openngc_notes,
|
|
:image,
|
|
NOW(),
|
|
NOW()
|
|
)
|
|
ON DUPLICATE KEY UPDATE
|
|
`catalog_group` = VALUES(`catalog_group`),
|
|
`messier` = VALUES(`messier`),
|
|
`ngc` = VALUES(`ngc`),
|
|
`ic` = VALUES(`ic`),
|
|
`object_type_abrev` = VALUES(`object_type_abrev`),
|
|
`object_type` = VALUES(`object_type`),
|
|
`ra` = VALUES(`ra`),
|
|
`dec` = VALUES(`dec`),
|
|
`ra_deg` = VALUES(`ra_deg`),
|
|
`dec_deg` = VALUES(`dec_deg`),
|
|
`constellation` = VALUES(`constellation`),
|
|
`major_axis` = VALUES(`major_axis`),
|
|
`minor_axis` = VALUES(`minor_axis`),
|
|
`position_angle` = VALUES(`position_angle`),
|
|
`b_mag` = VALUES(`b_mag`),
|
|
`v_mag` = VALUES(`v_mag`),
|
|
`j_mag` = VALUES(`j_mag`),
|
|
`h_mag` = VALUES(`h_mag`),
|
|
`k_mag` = VALUES(`k_mag`),
|
|
`surface_brightness` = VALUES(`surface_brightness`),
|
|
`hubble_type` = VALUES(`hubble_type`),
|
|
`cstar_u_mag` = VALUES(`cstar_u_mag`),
|
|
`cstar_b_mag` = VALUES(`cstar_b_mag`),
|
|
`cstar_v_mag` = VALUES(`cstar_v_mag`),
|
|
`cstar_names` = VALUES(`cstar_names`),
|
|
`identifiers` = VALUES(`identifiers`),
|
|
`common_names` = VALUES(`common_names`),
|
|
`ned_notes` = VALUES(`ned_notes`),
|
|
`openngc_notes` = VALUES(`openngc_notes`),
|
|
`image` = VALUES(`image`),
|
|
`updated_at` = NOW()
|
|
";
|
|
|
|
$stmt = $pdo->prepare($sql);
|
|
|
|
$rowCount = 0;
|
|
$imported = 0;
|
|
$skipped = 0;
|
|
|
|
$pdo->beginTransaction();
|
|
|
|
try {
|
|
while (($row = fgetcsv($handle, 0, ';', '"', '')) !== false) {
|
|
$rowCount++;
|
|
|
|
if ($row === [null] || $row === false) {
|
|
continue;
|
|
}
|
|
|
|
if (count($row) !== count($header)) {
|
|
$skipped++;
|
|
continue;
|
|
}
|
|
|
|
$data = array_combine($header, $row);
|
|
if ($data === false) {
|
|
$skipped++;
|
|
continue;
|
|
}
|
|
|
|
$name = toNullableString($data['name'] ?? null);
|
|
if ($name === null) {
|
|
$skipped++;
|
|
continue;
|
|
}
|
|
|
|
$ra = toNullableString($data['ra'] ?? null);
|
|
$dec = toNullableString($data['dec'] ?? null);
|
|
|
|
$stmt->execute([
|
|
':catalog_group' => toNullableString($data['ic_ngc'] ?? null),
|
|
':name' => $name,
|
|
':messier' => toNullableString($data['messier'] ?? null),
|
|
':ngc' => toNullableString($data['ngc'] ?? null),
|
|
':ic' => toNullableString($data['ic'] ?? null),
|
|
':object_type_abrev' => toNullableString($data['object_type_abrev'] ?? null),
|
|
':object_type' => toNullableString($data['object_type'] ?? null),
|
|
':ra' => $ra,
|
|
':dec' => $dec,
|
|
':ra_deg' => hmsToDegrees($ra),
|
|
':dec_deg' => dmsToDegrees($dec),
|
|
':constellation' => toNullableString($data['constellation'] ?? null),
|
|
':major_axis' => toNullableFloat($data['major_axis'] ?? null),
|
|
':minor_axis' => toNullableFloat($data['minor_axis'] ?? null),
|
|
':position_angle' => toNullableFloat($data['position_angle'] ?? null),
|
|
':b_mag' => toNullableFloat($data['b_mag'] ?? null),
|
|
':v_mag' => toNullableFloat($data['v_mag'] ?? null),
|
|
':j_mag' => toNullableFloat($data['j_mag'] ?? null),
|
|
':h_mag' => toNullableFloat($data['h_mag'] ?? null),
|
|
':k_mag' => toNullableFloat($data['k_mag'] ?? null),
|
|
':surface_brightness' => toNullableFloat($data['surface_brigthness'] ?? null),
|
|
':hubble_type' => toNullableString($data['hubble_only_galaxies'] ?? null),
|
|
':cstar_u_mag' => toNullableFloat($data['cstar_u_mag_only_planetary_nebulae'] ?? null),
|
|
':cstar_b_mag' => toNullableFloat($data['cstar_b_mag_only_planetary_nebulae'] ?? null),
|
|
':cstar_v_mag' => toNullableFloat($data['cstar_v_mag_only_planetary_nebulae'] ?? null),
|
|
':cstar_names' => toNullableString($data['cstar_names_only_planetary_nebulae'] ?? null),
|
|
':identifiers' => toNullableString($data['identifiers'] ?? null),
|
|
':common_names' => toNullableString($data['common_names'] ?? null),
|
|
':ned_notes' => toNullableString($data['ned_notes'] ?? null),
|
|
':openngc_notes' => toNullableString($data['openngc_notes'] ?? null),
|
|
':image' => toNullableString($data['image'] ?? null),
|
|
]);
|
|
|
|
$imported++;
|
|
}
|
|
|
|
$pdo->commit();
|
|
} catch (Throwable $e) {
|
|
$pdo->rollBack();
|
|
fclose($handle);
|
|
exit("Fehler beim Import: " . $e->getMessage() . "\n");
|
|
}
|
|
|
|
fclose($handle);
|
|
|
|
echo "Deep-Sky-Import abgeschlossen\n";
|
|
echo "Verarbeitete Zeilen: {$rowCount}\n";
|
|
echo "Importiert/Aktualisiert: {$imported}\n";
|
|
echo "Übersprungen: {$skipped}\n"; |