Files
skyview.astronomiemuseum.de/scripts/import/import_openngc.php
T
2026-03-31 09:44:27 +02:00

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";