Geographic Coordinate System Converter

Geographic Coordinate System Converter

Convert Degrees, Minutes, Seconds to Decimal Degrees

Convert Decimal Degrees to Degrees, Minutes, Seconds

About Coordinate Systems

This tool converts geographic coordinates between two common formats:

  • Degrees, Minutes, Seconds (DMS): A traditional format where each degree is divided into 60 minutes, and each minute into 60 seconds. Hemispheres are indicated (N/S for Latitude, E/W for Longitude).
    Example: 34° 56' 12.5" N, 118° 15' 30.8" W
  • Decimal Degrees (DD): A more modern and computationally friendly format where Latitude and Longitude are expressed as decimal numbers. Positive values are North and East, negative values are South and West.
    Example: 34.936806, -118.260833

Understanding these conversions is crucial for various applications, including mapping, navigation, and data analysis in Geographic Information Systems (GIS).

**Disclaimer:** This tool is for educational and illustrative purposes only. While designed for accuracy, it relies on user input and simplified calculations. It should **NOT** be used for critical navigation, legal boundary definitions, or any application where precise, certified geographic coordinates are required. Always verify results with professional tools or certified data sources for critical uses.

Input (DMS):

Latitude: ${latDeg}° ${latMin}' ${latSec.toFixed(3)}" ${latHemisphere}

Longitude: ${lonDeg}° ${lonMin}' ${lonSec.toFixed(3)}" ${lonHemisphere}

Output (Decimal Degrees):

Latitude: ${decimalLat.toFixed(6)}

Longitude: ${decimalLon.toFixed(6)}

`; outputSectionEl.style.display = 'block'; // Store data for PDF outputData = { method: 'DMS to Decimal Degrees', inputs: { 'Latitude (DMS)': `${latDeg}° ${latMin}' ${latSec.toFixed(3)}"${latHemisphere}`, 'Longitude (DMS)': `${lonDeg}° ${lonMin}' ${lonSec.toFixed(3)}"${lonHemisphere}` }, results: { 'Latitude (Decimal)': decimalLat.toFixed(6), 'Longitude (Decimal)': decimalLon.toFixed(6) } }; console.log('[DEBUG] DMS to Decimal conversion successful.'); } } catch (e) { console.error('[ERROR] Error in convertDmsToDecimal:', e); displayError('An error occurred during conversion. Check console for details.'); } } function convertDecimalToDms() { console.log('[DEBUG] convertDecimalToDms called.'); try { hideError(); // Get Decimal inputs const latDecimal = parseFloat(document.getElementById('latDecimal').value); const lonDecimal = parseFloat(document.getElementById('lonDecimal').value); // Validate inputs if (isNaN(latDecimal) || isNaN(lonDecimal)) { displayError("Please enter valid numbers for both Latitude and Longitude Decimal Degrees."); return; } if (latDecimal < -90 || latDecimal > 90) { displayError("Latitude Decimal Degrees must be between -90 and 90."); return; } if (lonDecimal < -180 || lonDecimal > 180) { displayError("Longitude Decimal Degrees must be between -180 and 180."); return; } // Convert Latitude to DMS let absLat = Math.abs(latDecimal); const latDeg = Math.floor(absLat); let latRemMin = (absLat - latDeg) * 60; const latMin = Math.floor(latRemMin); const latSec = (latRemMin - latMin) * 60; const latHemisphere = latDecimal >= 0 ? 'N' : 'S'; // Convert Longitude to DMS let absLon = Math.abs(lonDecimal); const lonDeg = Math.floor(absLon); let lonRemMin = (absLon - lonDeg) * 60; const lonMin = Math.floor(lonRemMin); const lonSec = (lonRemMin - lonMin) * 60; const lonHemisphere = lonDecimal >= 0 ? 'E' : 'W'; const resultEl = document.getElementById('conversionResult'); const outputSectionEl = document.getElementById('outputSection'); if (resultEl && outputSectionEl) { resultEl.innerHTML = `

Input (Decimal Degrees):

Latitude: ${latDecimal.toFixed(6)}

Longitude: ${lonDecimal.toFixed(6)}

Output (DMS):

Latitude: ${latDeg}° ${latMin}' ${latSec.toFixed(3)}"${latHemisphere}

Longitude: ${lonDeg}° ${lonMin}' ${lonSec.toFixed(3)}"${lonHemisphere}

`; outputSectionEl.style.display = 'block'; // Store data for PDF outputData = { method: 'Decimal Degrees to DMS', inputs: { 'Latitude (Decimal)': latDecimal.toFixed(6), 'Longitude (Decimal)': lonDecimal.toFixed(6) }, results: { 'Latitude (DMS)': `${latDeg}° ${latMin}' ${latSec.toFixed(3)}"${latHemisphere}`, 'Longitude (DMS)': `${lonDeg}° ${lonMin}' ${lonSec.toFixed(3)}"${lonHemisphere}` } }; console.log('[DEBUG] Decimal to DMS conversion successful.'); } } catch (e) { console.error('[ERROR] Error in convertDecimalToDms:', e); displayError('An error occurred during conversion. Check console for details.'); } } // --- Reset Functions --- function resetDmsToDecimalForm() { console.log('[DEBUG] resetDmsToDecimalForm called.'); try { hideError(); hideOutput(); document.getElementById('latDegDMS').value = '34'; document.getElementById('latMinDMS').value = '56'; document.getElementById('latSecDMS').value = '12.5'; document.getElementById('latHemisphereDMS').value = 'N'; document.getElementById('lonDegDMS').value = '118'; document.getElementById('lonMinDMS').value = '15'; document.getElementById('lonSecDMS').value = '30.8'; document.getElementById('lonHemisphereDMS').value = 'W'; console.log('[DEBUG] DMS to Decimal form reset successful.'); } catch (e) { console.error('[ERROR] Error in resetDmsToDecimalForm:', e); displayError('An error occurred during form reset. Check console for details.'); } } function resetDecimalToDmsForm() { console.log('[DEBUG] resetDecimalToDmsForm called.'); try { hideError(); hideOutput(); document.getElementById('latDecimal').value = '34.936806'; document.getElementById('lonDecimal').value = '-118.260833'; console.log('[DEBUG] Decimal to DMS form reset successful.'); } catch (e) { console.error('[ERROR] Error in resetDecimalToDmsForm:', e); displayError('An error occurred during form reset. Check console for details.'); } } // Combined reset for "all" forms (called only if a global reset was needed, but typically forms are reset individually per tab) function resetForm() { // This function is less critical since tabs usually have their own resets. // It's here for consistency with previous tools but might not be directly linked to a button. // When a tab's reset is called, it should hide its own output and errors. resetDmsToDecimalForm(); resetDecimalToDmsForm(); hideOutput(); // Ensure output is hidden after any reset hideError(); } // Function to hide the output section function hideOutput() { console.log('[DEBUG] hideOutput called.'); const outputSection = document.getElementById('outputSection'); if (outputSection) { outputSection.style.display = 'none'; outputData = {}; // Clear output data when hidden } } // Function to generate and download PDF async function generatePdf() { console.log('[DEBUG] generatePdf called.'); try { if (Object.keys(outputData).length === 0) { displayError("No conversion results to download. Please perform a conversion first."); return; } hideError(); // Clear error after checking const { jsPDF } = window.jspdf; const doc = new jsPDF(); const title = "Geographic Coordinate Conversion Results"; const currentDateTime = new Date().toLocaleString(); doc.setFontSize(18); doc.text(title, 105, 20, { align: 'center' }); doc.setFontSize(10); doc.text(`Date: ${currentDateTime}`, 105, 28, { align: 'center' }); let yOffset = 40; doc.setFontSize(11); doc.text(`Conversion Method: ${outputData.method}`, 20, yOffset); yOffset += 10; doc.setFontSize(11); doc.text('Input Coordinates:', 20, yOffset); yOffset += 7; // Draw inputs table const inputRows = Object.entries(outputData.inputs).map(([label, value]) => [label, value]); doc.autoTable({ startY: yOffset, head: [['Parameter', 'Value']], body: inputRows, theme: 'striped', styles: { fontSize: 10, cellPadding: 2, fillColor: [233, 247, 239], textColor: [51, 51, 51] }, headStyles: { fillColor: [40, 167, 69], textColor: [255, 255, 255], fontStyle: 'bold' }, columnStyles: { 0: { cellWidth: 70 }, 1: { cellWidth: 'auto', overflow: 'linebreak' } } }); yOffset = doc.autoTable.previous.finalY + 10; doc.setFontSize(11); doc.text('Converted Coordinates:', 20, yOffset); yOffset += 7; // Draw results table const resultRows = Object.entries(outputData.results).map(([label, value]) => [label, value]); doc.autoTable({ startY: yOffset, head: [['Parameter', 'Value']], body: resultRows, theme: 'striped', styles: { fontSize: 10, cellPadding: 2, fillColor: [233, 247, 239], textColor: [51, 51, 51] }, headStyles: { fillColor: [40, 167, 69], textColor: [255, 255, 255], fontStyle: 'bold' }, columnStyles: { 0: { cellWidth: 70 }, 1: { cellWidth: 'auto', overflow: 'linebreak' } } }); yOffset = doc.autoTable.previous.finalY + 15; // Add Disclaimer const disclaimerText = "Disclaimer: This tool is for educational and illustrative purposes only. While designed for accuracy, it relies on user input and simplified calculations. It should NOT be used for critical navigation, legal boundary definitions, or any application where precise, certified geographic coordinates are required. Always verify results with professional tools or certified data sources for critical uses."; const splitDisclaimer = doc.splitTextToSize(disclaimerText, 170); // Max width for text doc.setFontSize(9); doc.setTextColor(108, 117, 125); // Grey color for disclaimer doc.text(splitDisclaimer, 20, yOffset); doc.save('Geographic_Coordinates_Conversion.pdf'); console.log('[DEBUG] PDF generated successfully.'); } catch (e) { console.error('[ERROR] Error in generatePdf:', e); displayError('An error occurred during PDF generation. Check console for details.'); } } // Ensure DOM is fully loaded before executing JavaScript that interacts with it document.addEventListener('DOMContentLoaded', function() { console.log('[DEBUG] DOMContentLoaded fired.'); try { // Initialize tab buttons array document.querySelectorAll('.tabs-container .tab-button').forEach(button => { tabButtons.push(button); }); console.log(`[DEBUG] tabButtons array populated with ${tabButtons.length} buttons.`); // Set the initial active tab const initialActiveButton = document.querySelector('.tab-button.active'); if (initialActiveButton) { switchTab('dmsToDecimalTab', initialActiveButton); } else { console.warn('[DEBUG] No initial active tab button found, falling back.'); switchTab('dmsToDecimalTab', null); // Fallback to ensure tab is activated } // Pre-fill default values for demonstration resetDmsToDecimalForm(); resetDecimalToDmsForm(); console.log('[DEBUG] Default values pre-filled.'); console.log('[DEBUG] DOMContentLoaded finished.'); } catch (e) { console.error('[ERROR] Error during DOMContentLoaded:', e); // This error might prevent the tool from working at all. // Display a prominent message if this fails. const appContainer = document.getElementById('toolApp'); if (appContainer) { appContainer.innerHTML = '
An critical error occurred during tool initialization. Please check your browser console for details.
'; } } });
Scroll to Top