A robust TypeScript library for converting between different geographic coordinate formats: Decimal Degrees (DD), Degrees-Minutes (DM), and Degrees-Minutes-Seconds (DMS). Features comprehensive parsing, validation, and formatting with support for hemisphere indicators.
You can see a demo on CodePen.
View it on GitHub.
- 🔄 Bidirectional Conversions: DD ↔ DM ↔ DMS
- 🌍 Smart Parsing: Handles various input formats with automatic hemisphere detection
- ✅ Robust Validation: Range checking and format validation
- 🎯 Type Safety: Full TypeScript support with comprehensive type definitions
- 📐 Precision Control: Configurable decimal precision for output formatting
- 🤝 Pair Functions: Work with latitude/longitude pairs together
- 🎨 Rich Formatting: Multiple formatting options for all coordinate types
- 🧪 Well Tested: Comprehensive test suite with round-trip validation
- 📦 Zero Dependencies: Lightweight with no external dependencies
- 🚀 Modern Build: ES modules and CommonJS support
npm install coordconversionFor quick browser usage without a build step, you can use CDN links:
Global Script (Easy):
<script src="https://unpkg.com/coordconversion@latest/dist/index.global.js"></script>
<script>
const { parseToDD, CoordinateType } = CoordConversion;
// Use the library functions directly
</script>ES Modules:
<script type="module">
import {
parseToDD,
CoordinateType,
} from "https://unpkg.com/coordconversion@latest/dist/index.js";
// Use the library functions
</script>Alternative CDNs:
- unpkg:
https://unpkg.com/coordconversion@latest/dist/ - jsDelivr:
https://cdn.jsdelivr.net/npm/coordconversion@latest/dist/
enum CoordinateType {
LAT = "lat", // Latitude
LON = "lon", // Longitude
}These are the available imports from the library.
import {
// For individual coordinates
parseToDD, // Parse values to Decimal Degrees (DD)
ddToDM, // Convert DD to Degrees-Minutes (DM)
ddToDMS, // Convert DD to Degrees-Minutes-Seconds (DMS)
dmToDD, // Convert DM to DD
dmsToDD, // Convert DMS to DD
formatDD, // Format DD for display
formatDM, // Format DM for display
formatDMS, // Format DMS for display
// For coordinate pairs
parsePairToDD, // Parse a pair of values to Decimal Degrees (DD)
ddPairToDM, // Convert a pair of DD values to Degrees-Minutes (DM)
ddPairToDMS, // Convert a pair of DD values to Degrees-Minutes-Seconds (DMS)
dmPairToDD, // Convert a pair of DM values to DD
dmsPairToDD, // Convert a pair of DMS values to DD
formatDDPair, // Format a pair of DD values for display
formatDMPair, // Format a pair of DM values for display
formatDMSPair, // Format a pair of DMS values for display
// Coordinate type for type safety
CoordinateType,
} from "coordconversion";Functions follow a parse -> convert -> format flow.
- Start by parsing a coordinate.
const dd = parseToDD("45° 7' 22.8\" N", CoordinateType.LAT);- Convert the result to another format.
- Format the restult into a readable string.
const formatted = formatDM(dm);
console.log(formatted); // e.g. "45° 7.38000' N"This can be accomplished in a single line.
const formatted = formatDM(
ddToDM(parseToDD("45° 7' 22.8\" N", CoordinateType.LAT))
);
console.log(formatted); // e.g. "45° 7.38000' N"- Parse a coordinate pair
const [lat, lon] = parsePairToDD("48.8544° N", "123.5005° W");- Convert the result to another format
const [latDM, lonDM] = ddPairToDM(lat, lon);- Format the result into a readable string
const [latStr, lonStr] = formatDMPair(latDM, lonDM);
console.log(latStr, lonStr); // e.g. "48° 51.26400' N", "123° 30.03000' W"This can also be accomplished in a single line
const [latStr, lonStr] = formatDMPair(
...ddPairToDM(...parsePairToDD("48.8544° N", "123.5005° W"))
);
console.log(latStr, lonStr); // e.g. "48° 51.26' N", "123° 30.03' W"Continue reading for detailed descriptions of functions including return data types/shapes and function options.
Takes any coordinate string or number and converts it to decimal degrees format. Automatically detects and handles different input formats including hemisphere indicators.
Supported formats:
- Decimal degrees, eg
"45.123" - Degrees-minutes, eg
"45° 7.38'"or"45 7.38 N" - Degrees-minutes-seconds, eg
"45° 7' 22.8\" N"or"45 7 22.8"
const dd = parseToDD("45° 7' 22.8\" N", CoordinateType.LAT);
// returns
// {
// kind: "lat",
// degrees: 45.123
// }What it does: Takes latitude and longitude inputs (strings or numbers) and converts both to decimal degrees format in one function call.
const [lat, lon] = parsePairToDD("48.8544° N", "123.5005° W");
// returns
// [
// {
// kind: "lat",
// degrees: 48.8544
// },
// {
// kind: "lon",
// degrees: -123.5005
// }
// ]- Converts decimal degrees to degrees and minutes format.
- Includes options for precision control and range clamping.
const dm = ddToDM({ kind: "lat", degrees: 45.123 });
// returns
// {
// kind: "lat",
// degrees: 45,
// minutes: 7.38,
// hemi: "N"
// }What it does: Converts decimal degrees to degrees, minutes, and seconds format. Provides the highest precision breakdown of coordinates.
const dms = ddToDMS({ kind: "lat", degrees: 45.123 });
// returns
// {
// kind: "lat",
// degrees: 45,
// minutes: 7,
// seconds: 22.80,
// hemi: "N"
// }What it does: Converts degrees-minutes format back to decimal degrees. Validates that minutes are within valid range (0-60).
const dd = dmToDD({ kind: "lat", degrees: 45, minutes: 7.38, hemi: "N" });
// returns
// {
// kind: "lat",
// degrees: 45.123
// }What it does: Converts degrees-minutes-seconds format back to decimal degrees. Validates that minutes and seconds are within valid ranges.
const dd = dmsToDD({
kind: "lat",
degrees: 45,
minutes: 7,
seconds: 22.8,
hemi: "N",
});
// returns
// {
// kind: "lat",
// degrees: 45.123
// }What it does: Converts both latitude and longitude from decimal degrees to degrees-minutes format in one function call.
const [latDM, lonDM] = ddPairToDM(latDD, lonDD);
// returns
// [
// {
// kind: "lat",
// degrees: 48,
// minutes: 51.26,
// hemi: "N"
// },
// {
// kind: "lon",
// degrees: 123,
// minutes: 30.03,
// hemi: "W"
// }
// ]What it does: Converts both latitude and longitude from decimal degrees to degrees-minutes-seconds format in one function call.
const [latDMS, lonDMS] = ddPairToDMS(latDD, lonDD);
// returns
// [
// {
// kind: "lat",
// degrees: 48,
// minutes: 51,
// seconds: 15.84,
// hemi: "N"
// },
// {
// kind: "lon",
// degrees: 123,
// minutes: 30,
// seconds: 1.8,
// hemi: "W"
// }
// ]What it does: Converts both latitude and longitude from degrees-minutes format back to decimal degrees in one function call.
const [latDD, lonDD] = dmPairToDD(latDM, lonDM);
// returns
// [
// {
// kind: "lat",
// degrees: 48.8544
// },
// {
// kind: "lon",
// degrees: -123.5005
// }
// ]What it does: Converts both latitude and longitude from degrees-minutes-seconds format back to decimal degrees in one function call.
const [latDD, lonDD] = dmsPairToDD(latDMS, lonDMS);
// returns
// [
// {
// kind: "lat",
// degrees: 48.8544
// },
// {
// kind: "lon",
// degrees: -123.5005
// }
// ]What it does: Takes a decimal degrees object and formats it as a human-readable string with hemisphere indicator. Default precision is 5 decimal places.
const formatted = formatDD({ kind: "lat", degrees: 45.123 });
// returns "45.12300° N"What it does: Takes a degrees-minutes object and formats it as a human-readable string with degree and minute symbols. Default precision is 2 decimal places for minutes.
const formatted = formatDM({
kind: "lat",
degrees: 45,
minutes: 7.38,
hemi: "N",
});
// returns "45° 7.38' N"What it does: Takes a degrees-minutes-seconds object and formats it as a human-readable string with all symbols. Default precision is 2 decimal places for seconds.
const formatted = formatDMS({
kind: "lat",
degrees: 45,
minutes: 7,
seconds: 22.8,
hemi: "N",
});
// returns "45° 7' 22.80\" N"What it does: Formats both latitude and longitude decimal degrees as human-readable strings in one function call.
const [latStr, lonStr] = formatDDPair(latDD, lonDD);
// returns
// [
// "48.85440° N",
// "123.50050° W"
// ]What it does: Formats both latitude and longitude degrees-minutes as human-readable strings in one function call.
const [latStr, lonStr] = formatDMPair(latDM, lonDM);
// returns
// [
// "48° 51.26' N",
// "123° 30.03' W"
// ]What it does: Formats both latitude and longitude degrees-minutes-seconds as human-readable strings in one function call.
const [latStr, lonStr] = formatDMSPair(latDMS, lonDMS);
// returns
// [
// "48° 51' 15.84\" N",
// "123° 30' 1.80\" W"
// ]Most conversion functions accept an optional opts parameter:
decimals: Number of decimal places for the output (varies by function)clamp: Whether to clamp degrees to valid ranges (default: false)
// Custom precision
const dm = ddToDM(dd, { decimals: 4 }); // 4 decimal places for minutes
const dms = ddToDMS(dd, { decimals: 3 }); // 3 decimal places for seconds
// Range clamping
const safeDM = ddToDM(dd, { clamp: true }); // Clamps to valid lat/lon rangesAll formatting functions accept an optional decimals parameter:
const formatted = formatDD(dd, 3); // 3 decimal places instead of default 5
const formatted2 = formatDM(dm, 4); // 4 decimal places for minutes instead of default 5The library includes comprehensive validation:
- Range Validation: Latitude (-90° to +90°), Longitude (-180° to +180°)
- Format Validation: Minutes (0-60), Seconds (0-60)
- Input Validation: Finite number checking, format recognition
- Error Messages: Descriptive error messages for debugging
Common Errors:
// Range errors
parseToDD("91", CoordinateType.LAT); // Error: LAT degrees out of range: 91
// Format errors
parseToDD("45° 65' N", CoordinateType.LAT); // Error: Minutes must be < 60
// Invalid input
parseToDD("invalid", CoordinateType.LAT); // Error: Unrecognized coordinate format// Parse and convert with custom precision
const dd = parseToDD("45.123456789", CoordinateType.LAT);
// High precision DM
const dm = ddToDM(dd, { decimals: 4 });
console.log(formatDM(dm)); // "45° 7.4074' N"
// High precision DMS
const dms = ddToDMS(dd, { decimals: 3 });
console.log(formatDMS(dms)); // "45° 7' 24.444\" N"// Parse invalid latitude (will throw error without clamp)
// const invalidLat = parseToDD("95", CoordinateType.LAT); // Error!
// Use clamp option to handle out-of-range values during conversion
const validDD = parseToDD("89.5", CoordinateType.LAT); // Valid input
const clampedDM = ddToDM(validDD, { clamp: true });
console.log(formatDM(clampedDM)); // "89° 30.00000' N"const coordinates = ["40.7128° N", "74.0060° W", "51.5074° N", "0.1278° W"];
const parsed = coordinates.map((coord, index) =>
parseToDD(coord, index % 2 === 0 ? CoordinateType.LAT : CoordinateType.LON)
);// Parse coordinate pairs from various formats
const [lat1, lon1] = parsePairToDD("48.8544° N", "123.5005° W");
const [lat2, lon2] = parsePairToDD(48.8544, -123.5005);
const [lat3, lon3] = parsePairToDD("48° 51.26' N", "123° 30.03' W");
// Convert pairs to all formats
const [latDM, lonDM] = ddPairToDM(lat1, lon1);
const [latDMS, lonDMS] = ddPairToDMS(lat1, lon1);
// Format pairs for display
const [latDDStr, lonDDStr] = formatDDPair(lat1, lon1);
const [latDMStr, lonDMStr] = formatDMPair(latDM, lonDM);
const [latDMSStr, lonDMSStr] = formatDMSPair(latDMS, lonDMS);
console.log("DD:", latDDStr, lonDDStr); // "48.85440° N" "123.50050° W"
console.log("DM:", latDMStr, lonDMStr); // "48° 51.26' N" "123° 30.03' W"
console.log("DMS:", latDMSStr, lonDMSStr); // "48° 51' 15.84\" N" "123° 30' 1.80\" W"// Complete workflow: Parse → Convert → Format
const [lat, lon] = parsePairToDD("48.8544° N", "123.5005° W");
// Convert to all formats
const [latDM, lonDM] = ddPairToDM(lat, lon);
const [latDMS, lonDMS] = ddPairToDMS(lat, lon);
// Format all formats
const [latDDStr, lonDDStr] = formatDDPair(lat, lon);
const [latDMStr, lonDMStr] = formatDMPair(latDM, lonDM);
const [latDMSStr, lonDMSStr] = formatDMSPair(latDMS, lonDMS);
// Round trip validation
const [latBack, lonBack] = dmPairToDD(latDM, lonDM);
const [latBack2, lonBack2] = dmsPairToDD(latDMS, lonDMS);
console.log("Original:", lat.degrees, lon.degrees);
console.log("From DM:", latBack.degrees, lonBack.degrees);
console.log("From DMS:", latBack2.degrees, lonBack2.degrees);import { parseToDD, ddToDM, formatDM, CoordinateType } from "coordconversion";
const dd = parseToDD("45° 7' 22.8\" N", CoordinateType.LAT);
const dm = ddToDM(dd);
console.log(formatDM(dm)); // "45° 7.38000' N"const {
parseToDD,
ddToDM,
formatDM,
CoordinateType,
} = require("coordconversion");
const dd = parseToDD("45° 7' 22.8\" N", CoordinateType.LAT);
const dm = ddToDM(dd);
console.log(formatDM(dm)); // "45° 7.38000' N"<script type="module">
import {
parseToDD,
ddToDM,
formatDM,
CoordinateType,
} from "https://unpkg.com/coordconversion@latest/dist/index.js";
const dd = parseToDD("45° 7' 22.8\" N", CoordinateType.LAT);
const dm = ddToDM(dd);
console.log(formatDM(dm)); // "45° 7.38000' N"
</script><script src="https://unpkg.com/coordconversion@latest/dist/index.global.js"></script>
<script>
const { parseToDD, ddToDM, formatDM, CoordinateType } = CoordConversion;
const dd = parseToDD("45° 7' 22.8\" N", CoordinateType.LAT);
const dm = ddToDM(dd);
console.log(formatDM(dm)); // "45° 7.38000' N"
</script><script>
(async () => {
const { parseToDD, ddToDM, formatDM, CoordinateType } = await import(
"https://unpkg.com/coordconversion@latest/dist/index.js"
);
const dd = parseToDD("45° 7' 22.8\" N", CoordinateType.LAT);
const dm = ddToDM(dd);
console.log(formatDM(dm)); // "45° 7.38000' N"
})();
</script><!DOCTYPE html>
<html>
<head>
<title>Coordinate Conversion Example</title>
</head>
<body>
<h1>Coordinate Conversion Demo</h1>
<div id="output"></div>
<script src="https://unpkg.com/coordconversion@latest/dist/index.global.js"></script>
<script>
const {
parseToDD,
ddToDM,
ddToDMS,
formatDD,
formatDM,
formatDMS,
CoordinateType,
} = CoordConversion;
// Parse a coordinate
const dd = parseToDD("48° 51' 15.84\" N", CoordinateType.LAT);
// Convert to different formats
const dm = ddToDM(dd);
const dms = ddToDMS(dd);
// Format for display
const ddStr = formatDD(dd);
const dmStr = formatDM(dm);
const dmsStr = formatDMS(dms);
// Display results
document.getElementById("output").innerHTML = `
<p><strong>Original:</strong> 48° 51' 15.84" N</p>
<p><strong>DD:</strong> ${ddStr}</p>
<p><strong>DM:</strong> ${dmStr}</p>
<p><strong>DMS:</strong> ${dmsStr}</p>
`;
</script>
</body>
</html>| Format | Description | Example |
|---|---|---|
| DD | Decimal Degrees | 45.123° N |
| DM | Degrees-Minutes | 45° 7.38' N |
| DMS | Degrees-Minutes-Seconds | 45° 7' 22.8" N |
- Latitude: -90° to +90° (N/S)
- Longitude: -180° to +180° (E/W)
- Minutes: 0 to 60 (exclusive)
- Seconds: 0 to 60 (exclusive)
MIT © Matthew Simpson, 2025