How to Convert ECI Coordinates to Geodetic Using satellite.js
The satellite.js library converts Earth-Centered Inertial (ECI) vectors to geodetic latitude, longitude, and altitude using the eciToGeodetic function combined with gstime for Greenwich Mean Sidereal Time calculations, as implemented in the God's Eye View repository.
The God's Eye View project leverages satellite.js to transform raw orbital propagation data into user-friendly geodetic coordinates suitable for 3D globe rendering. Converting ECI coordinates to geodetic using satellite.js requires calculating the correct sidereal time offset before applying the core coordinate transformation. This workflow enables accurate real-time satellite tracking and orbit visualization on web-based mapping platforms.
Understanding the ECI to Geodetic Conversion Workflow
The conversion follows the standard SGP4 orbital mechanics pipeline. The process involves four distinct steps that transform raw ECI vectors into decimal degrees and meters for geographic display.
Import Required Helpers from satellite.js
The implementation in src/data/satellites.js [line 2] imports four critical functions from the library:
eciToGeodetic– Performs the core coordinate transformation from ECI to geodeticgstime– Calculates Greenwich Mean Sidereal Time for rotational alignmentdegreesLong– Converts longitude from radians to decimal degreesdegreesLat– Converts latitude from radians to decimal degrees
Calculate Greenwich Mean Sidereal Time (GMST)
Before converting coordinates, obtain the GMST for your target epoch. The gstime(date) function accepts a JavaScript Date object and returns the Greenwich Mean Sidereal Time in radians [satellites.js line 483]. This value accounts for Earth's rotation relative to the fixed stars, which is essential for aligning the inertial reference frame with Earth's surface at a specific moment.
Execute the Coordinate Transformation
Pass the ECI position vector (typically containing x, y, z values in meters) and the GMST value to eciToGeodetic. As implemented in src/data/satellites.js [line 527], this function returns an object with three properties:
longitude– Angular position east-west in radianslatitude– Angular position north-south in radiansheight– Altitude above Earth's ellipsoid in kilometers
Normalize Units for Display
The raw output requires unit conversion for most geographic information systems. Multiply the height property by 1000 to convert kilometers to meters. Apply degreesLong and degreesLat to convert angular measurements from radians to decimal degrees for mapping APIs.
Implementation in the God's Eye View Codebase
The repository centralizes conversion logic in src/data/satellites.js, exposing it through two primary functions that handle different visualization requirements.
Real-Time Position Updates with propagatePosition
The propagatePosition function handles per-frame satellite tracking for live visualization. Located at lines 483-495 in src/data/satellites.js, this helper:
- Calls
propagateto generate ECI coordinates for the current timestamp - Invokes
gstimeto calculate the rotational offset for the epoch - Passes both values to
eciToGeodetic - Returns a plain JavaScript object with
longitude,latitude, andaltitude(in meters)
This ensures satellite point primitives update correctly in the CesiumJS visualization without exposing radian calculations to the rendering layer.
Orbit Path Generation with computeOrbitPath
For rendering complete orbital rings, the computeOrbitPath function (lines 527-533) repeatedly propagates the satellite across a future time range. At each sample point, it converts ECI coordinates to geodetic using the same eciToGeodetic workflow before passing the results to Cesium.Cartesian3.fromDegrees. This generates the smooth path lines visible in the application's 3D view.
Complete Working Example
The following implementation demonstrates the conversion pipeline used throughout the God's Eye View project:
// Example: Convert an ECI vector to geodetic coordinates
import {
eciToGeodetic,
gstime,
degreesLong,
degreesLat,
} from 'satellite.js';
/**
* @param {Cesium.Cartesian3} eciPos – ECI position vector (in metres)
* @param {Date} epoch – The time at which the vector was calculated
* @returns {{ latitude: number, longitude: number, altitude: number }}
*/
function eciToGeodeticDegrees(eciPos, epoch) {
// 1️⃣ Compute Greenwich Mean Sidereal Time for the epoch
const gmst = gstime(epoch); // radians
// 2️⃣ Convert ECI → geodetic (radians + km)
const geo = eciToGeodetic(eciPos, gmst); // { latitude, longitude, height }
// 3️⃣ Turn radians → decimal degrees, km → metres
return {
latitude: degreesLat(geo.latitude), // degrees
longitude: degreesLong(geo.longitude), // degrees
altitude: geo.height * 1000, // metres
};
}
/* ------------------------------------------------------------------ */
// Using the helper inside the project's satellite propagation flow
import { propagate } from 'satellite.js';
import { twoline2satrec } from 'satellite.js';
import * as Cesium from 'cesium';
// Assume we already have a satrec object from a TLE
const satrec = twoline2satrec(tleLine1, tleLine2);
const now = new Date();
// Propagate the satellite to obtain an ECI position/velocity pair
const { position } = propagate(satrec, now);
// Convert the position to geodetic for UI display or further calculations
const geo = eciToGeodeticDegrees(position, now);
console.log(`Lat: ${geo.latitude.toFixed(4)}°, Lon: ${geo.longitude.toFixed(4)}°, Alt: ${geo.altitude.toFixed(0)} m`);
Summary
- The satellite.js library provides
eciToGeodeticto convert Earth-Centered Inertial coordinates to geodetic latitude, longitude, and altitude. - You must calculate Greenwich Mean Sidereal Time using
gstime()before performing the conversion to account for Earth's rotation relative to the stars. - The
eciToGeodeticfunction returns radians for angular measurements and kilometers for altitude, requiring conversion to degrees and meters for standard mapping applications. - The God's Eye View repository implements this workflow in
src/data/satellites.jswithin thepropagatePosition(lines 483-495) andcomputeOrbitPath(lines 527-533) functions. - Import
degreesLonganddegreesLatfrom satellite.js to handle radian-to-degree conversions without manual math.
Frequently Asked Questions
What is the difference between ECI and geodetic coordinates?
Earth-Centered Inertial (ECI) coordinates fix the origin at Earth's center of mass with axes that do not rotate with Earth, making them ideal for orbital mechanics and propagation calculations. Geodetic coordinates express position as latitude, longitude, and altitude relative to Earth's ellipsoid surface, which is necessary for mapping, ground-based tracking, and geographic information systems.
Why does satellite.js require GMST for the conversion?
The eciToGeodetic function requires Greenwich Mean Sidereal Time (GMST) because ECI reference frames remain fixed in space while geodetic coordinates rotate with Earth. The gstime() calculation determines how far Earth has rotated relative to the fixed stars at your specific epoch. This angular offset aligns the inertial vector with the correct longitude on Earth's rotating surface.
What units does eciToGeodetic return?
According to the satellite.js implementation used in src/data/satellites.js [line 527], the eciToGeodetic function returns an object where latitude and longitude are in radians and height (altitude) is in kilometers. You must multiply the height by 1000 to obtain meters and use degreesLat/degreesLong to convert angular measurements to decimal degrees for display purposes.
Can I use this conversion without CesiumJS?
Yes. While the God's Eye View project uses Cesium.Cartesian3 objects for ECI vectors, the satellite.js functions accept any object or array with x, y, and z numeric properties representing kilometers. The conversion logic works independently of any visualization library, allowing integration with Leaflet, Mapbox, or custom canvas renderers.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →