Erweitere astronomische Umrechnungen um Koordinaten und Winkel
This commit is contained in:
@@ -40,6 +40,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && (string) ($_POST['ajax'] ?? '') ===
|
||||
trim((string) ($_POST['sourceValue'] ?? '')),
|
||||
trim((string) ($_POST['longitude'] ?? '')),
|
||||
]);
|
||||
} elseif ($kind === 'coordinates') {
|
||||
$pythonResult = runPythonApi('astronomical_conversions', [
|
||||
'coordinates',
|
||||
trim((string) ($_POST['sourceSystem'] ?? '')),
|
||||
trim((string) ($_POST['value1'] ?? '')),
|
||||
trim((string) ($_POST['value2'] ?? '')),
|
||||
]);
|
||||
} elseif ($kind === 'angle') {
|
||||
$pythonResult = runPythonApi('astronomical_conversions', [
|
||||
'angle',
|
||||
trim((string) ($_POST['sourceUnit'] ?? '')),
|
||||
trim((string) ($_POST['sourceValue'] ?? '')),
|
||||
]);
|
||||
} else {
|
||||
echo json_encode([
|
||||
'ok' => false,
|
||||
@@ -213,6 +226,8 @@ $timeLocationLongitude = isset($currentLocation['longitude']) && is_numeric($cur
|
||||
<button type="button" class="astro-conv-tab is-active" data-tab-target="distanceTab" role="tab" aria-selected="true">Entfernung</button>
|
||||
<button type="button" class="astro-conv-tab" data-tab-target="redshiftTab" role="tab" aria-selected="false">Rotverschiebung</button>
|
||||
<button type="button" class="astro-conv-tab" data-tab-target="timeTab" role="tab" aria-selected="false">Zeit</button>
|
||||
<button type="button" class="astro-conv-tab" data-tab-target="coordinatesTab" role="tab" aria-selected="false">Koordinaten</button>
|
||||
<button type="button" class="astro-conv-tab" data-tab-target="angleTab" role="tab" aria-selected="false">Winkel</button>
|
||||
</div>
|
||||
|
||||
<section class="card astro-conv-panel astro-conv-tab-panel is-active" id="distanceTab" role="tabpanel">
|
||||
@@ -416,6 +431,72 @@ $timeLocationLongitude = isset($currentLocation['longitude']) && is_numeric($cur
|
||||
<button type="button" class="btn btn-primary" id="timeJ2000">J2000</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card astro-conv-panel astro-conv-tab-panel" id="coordinatesTab" role="tabpanel">
|
||||
<h2>Koordinaten-Umrechner</h2>
|
||||
<p>Umrechnung zwischen äquatorialen und galaktischen Koordinaten auf Basis des J2000-Systems. Eingabe und Ausgabe erfolgen in Dezimalgrad.</p>
|
||||
|
||||
<div class="astro-conv-grid" id="coordinatesConverter">
|
||||
<div class="astro-conv-field">
|
||||
<label for="coordRa"><span class="astro-conv-label-help" title="Rektaszension α im äquatorialen System, in Dezimalgrad von 0° bis 360°.">Rektaszension α (°)</span></label>
|
||||
<input class="astro-conv-input" id="coordRa" type="text" inputmode="decimal" value="279,234735">
|
||||
</div>
|
||||
|
||||
<div class="astro-conv-field">
|
||||
<label for="coordDec"><span class="astro-conv-label-help" title="Deklination δ im äquatorialen System, in Dezimalgrad von -90° bis +90°.">Deklination δ (°)</span></label>
|
||||
<input class="astro-conv-input" id="coordDec" type="text" inputmode="decimal" value="38,783689">
|
||||
</div>
|
||||
|
||||
<div class="astro-conv-field">
|
||||
<label for="coordGalLon"><span class="astro-conv-label-help" title="Galaktische Länge l in Dezimalgrad von 0° bis 360°.">Galaktische Länge l (°)</span></label>
|
||||
<input class="astro-conv-input" id="coordGalLon" type="text" inputmode="decimal">
|
||||
</div>
|
||||
|
||||
<div class="astro-conv-field">
|
||||
<label for="coordGalLat"><span class="astro-conv-label-help" title="Galaktische Breite b in Dezimalgrad von -90° bis +90°.">Galaktische Breite b (°)</span></label>
|
||||
<input class="astro-conv-input" id="coordGalLat" type="text" inputmode="decimal">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="astro-conv-actions">
|
||||
<button type="button" class="btn btn-secondary" id="coordinatesClear">Leeren</button>
|
||||
<button type="button" class="btn btn-primary" id="coordinatesVega">Vega</button>
|
||||
<button type="button" class="btn btn-primary" id="coordinatesGalacticCenter">Galaktisches Zentrum</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="card astro-conv-panel astro-conv-tab-panel" id="angleTab" role="tabpanel">
|
||||
<h2>Winkel-Umrechner</h2>
|
||||
<p>Umrechnung zwischen Grad, Bogenminute, Bogensekunde und Radiant.</p>
|
||||
|
||||
<div class="astro-conv-grid" id="angleConverter">
|
||||
<div class="astro-conv-field">
|
||||
<label for="angleDeg">Grad (°)</label>
|
||||
<input class="astro-conv-input" id="angleDeg" type="text" inputmode="decimal" value="1">
|
||||
</div>
|
||||
|
||||
<div class="astro-conv-field">
|
||||
<label for="angleArcmin">Bogenminute (′)</label>
|
||||
<input class="astro-conv-input" id="angleArcmin" type="text" inputmode="decimal">
|
||||
</div>
|
||||
|
||||
<div class="astro-conv-field">
|
||||
<label for="angleArcsec">Bogensekunde (″)</label>
|
||||
<input class="astro-conv-input" id="angleArcsec" type="text" inputmode="decimal">
|
||||
</div>
|
||||
|
||||
<div class="astro-conv-field">
|
||||
<label for="angleRad">Radiant (rad)</label>
|
||||
<input class="astro-conv-input" id="angleRad" type="text" inputmode="decimal">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="astro-conv-actions">
|
||||
<button type="button" class="btn btn-secondary" id="angleClear">Leeren</button>
|
||||
<button type="button" class="btn btn-primary" id="angleDegree">1 Grad</button>
|
||||
<button type="button" class="btn btn-primary" id="angleArcsecond">1 Bogensekunde</button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<script src="js/number_to_german_words.js"></script>
|
||||
@@ -477,11 +558,25 @@ $timeLocationLongitude = isset($currentLocation['longitude']) && is_numeric($cur
|
||||
trueSolar: document.getElementById('timeTrueSolar'),
|
||||
sidereal: document.getElementById('timeSidereal')
|
||||
};
|
||||
const coordinateFields = {
|
||||
ra: document.getElementById('coordRa'),
|
||||
dec: document.getElementById('coordDec'),
|
||||
galLon: document.getElementById('coordGalLon'),
|
||||
galLat: document.getElementById('coordGalLat')
|
||||
};
|
||||
const angleFields = {
|
||||
deg: document.getElementById('angleDeg'),
|
||||
arcmin: document.getElementById('angleArcmin'),
|
||||
arcsec: document.getElementById('angleArcsec'),
|
||||
rad: document.getElementById('angleRad')
|
||||
};
|
||||
let isSyncingTimePicker = false;
|
||||
let timeUtcPicker = null;
|
||||
let distanceRequestId = 0;
|
||||
let redshiftRequestId = 0;
|
||||
let timeRequestId = 0;
|
||||
let coordinateRequestId = 0;
|
||||
let angleRequestId = 0;
|
||||
|
||||
const DECIMAL_DIVISION_PRECISION = 32;
|
||||
const pow10Cache = [1n];
|
||||
@@ -893,6 +988,18 @@ $timeLocationLongitude = isset($currentLocation['longitude']) && is_numeric($cur
|
||||
wireTooltipHover(field);
|
||||
});
|
||||
|
||||
const coordinateFieldEntries = Object.entries(coordinateFields);
|
||||
coordinateFieldEntries.forEach(function ([unit, field]) {
|
||||
attachTooltip(field, 'coordinates-' + unit);
|
||||
wireTooltipHover(field);
|
||||
});
|
||||
|
||||
const angleFieldEntries = Object.entries(angleFields);
|
||||
angleFieldEntries.forEach(function ([unit, field]) {
|
||||
attachTooltip(field, 'angle-' + unit);
|
||||
wireTooltipHover(field);
|
||||
});
|
||||
|
||||
const updateDistanceFrom = async function (sourceUnit) {
|
||||
const rawValue = distanceFields[sourceUnit].value.trim();
|
||||
if (rawValue === '') {
|
||||
@@ -1339,6 +1446,133 @@ $timeLocationLongitude = isset($currentLocation['longitude']) && is_numeric($cur
|
||||
updateTimeFrom('utc');
|
||||
});
|
||||
|
||||
const clearCoordinateGroup = function (keys) {
|
||||
keys.forEach(function (key) {
|
||||
if (coordinateFields[key]) {
|
||||
coordinateFields[key].value = '';
|
||||
updateTooltip(coordinateFields[key]);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const updateCoordinatesFrom = async function (sourceSystem) {
|
||||
const isEquatorial = sourceSystem === 'equatorial';
|
||||
const firstKey = isEquatorial ? 'ra' : 'galLon';
|
||||
const secondKey = isEquatorial ? 'dec' : 'galLat';
|
||||
const targetKeys = isEquatorial ? ['galLon', 'galLat'] : ['ra', 'dec'];
|
||||
const firstValue = coordinateFields[firstKey].value.trim();
|
||||
const secondValue = coordinateFields[secondKey].value.trim();
|
||||
|
||||
if (firstValue === '' || secondValue === '') {
|
||||
clearCoordinateGroup(targetKeys);
|
||||
return;
|
||||
}
|
||||
|
||||
const requestId = ++coordinateRequestId;
|
||||
try {
|
||||
const result = await requestConversion({
|
||||
kind: 'coordinates',
|
||||
sourceSystem,
|
||||
value1: firstValue,
|
||||
value2: secondValue
|
||||
});
|
||||
|
||||
if (requestId !== coordinateRequestId || !result.valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
setFieldValues(coordinateFields, result.fields || {});
|
||||
} catch (error) {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
['ra', 'dec'].forEach(function (key) {
|
||||
coordinateFields[key].addEventListener('input', function () {
|
||||
updateCoordinatesFrom('equatorial');
|
||||
});
|
||||
});
|
||||
|
||||
['galLon', 'galLat'].forEach(function (key) {
|
||||
coordinateFields[key].addEventListener('input', function () {
|
||||
updateCoordinatesFrom('galactic');
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById('coordinatesClear').addEventListener('click', function () {
|
||||
Object.values(coordinateFields).forEach(function (field) {
|
||||
field.value = '';
|
||||
updateTooltip(field);
|
||||
});
|
||||
coordinateFields.ra.focus();
|
||||
});
|
||||
|
||||
document.getElementById('coordinatesVega').addEventListener('click', function () {
|
||||
coordinateFields.ra.value = '279,234735';
|
||||
coordinateFields.dec.value = '38,783689';
|
||||
updateCoordinatesFrom('equatorial');
|
||||
});
|
||||
|
||||
document.getElementById('coordinatesGalacticCenter').addEventListener('click', function () {
|
||||
coordinateFields.galLon.value = '0';
|
||||
coordinateFields.galLat.value = '0';
|
||||
updateCoordinatesFrom('galactic');
|
||||
});
|
||||
|
||||
const updateAngleFrom = async function (sourceUnit) {
|
||||
const rawValue = angleFields[sourceUnit].value.trim();
|
||||
if (rawValue === '') {
|
||||
Object.entries(angleFields).forEach(function ([key, field]) {
|
||||
if (key !== sourceUnit) {
|
||||
field.value = '';
|
||||
updateTooltip(field);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const requestId = ++angleRequestId;
|
||||
try {
|
||||
const result = await requestConversion({
|
||||
kind: 'angle',
|
||||
sourceUnit,
|
||||
sourceValue: rawValue
|
||||
});
|
||||
|
||||
if (requestId !== angleRequestId || !result.valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
setFieldValues(angleFields, result.fields || {});
|
||||
} catch (error) {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
angleFieldEntries.forEach(function ([unit, field]) {
|
||||
field.addEventListener('input', function () {
|
||||
updateAngleFrom(unit);
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById('angleClear').addEventListener('click', function () {
|
||||
Object.values(angleFields).forEach(function (field) {
|
||||
field.value = '';
|
||||
updateTooltip(field);
|
||||
});
|
||||
angleFields.deg.focus();
|
||||
});
|
||||
|
||||
document.getElementById('angleDegree').addEventListener('click', function () {
|
||||
angleFields.deg.value = '1';
|
||||
updateAngleFrom('deg');
|
||||
});
|
||||
|
||||
document.getElementById('angleArcsecond').addEventListener('click', function () {
|
||||
angleFields.arcsec.value = '1';
|
||||
updateAngleFrom('arcsec');
|
||||
});
|
||||
|
||||
const tabs = Array.from(document.querySelectorAll('.astro-conv-tab'));
|
||||
const tabPanels = Array.from(document.querySelectorAll('.astro-conv-tab-panel'));
|
||||
|
||||
@@ -1363,6 +1597,8 @@ $timeLocationLongitude = isset($currentLocation['longitude']) && is_numeric($cur
|
||||
updateDistanceFrom('km');
|
||||
updateRedshift();
|
||||
updateTimeFrom('utc');
|
||||
updateCoordinatesFrom('equatorial');
|
||||
updateAngleFrom('deg');
|
||||
})();
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user