# How to Convert ECI Coordinates to Geodetic Using satellite.js

> Learn to convert ECI coordinates to Geodetic using satellite.js. This guide explains the eciToGeodetic function and gstime for accurate calculations, as seen in the God's Eye View repo.

- Repository: [Bilawal Sidhu/gods-eye-view](https://github.com/bilawalsidhu/gods-eye-view)
- Tags: how-to-guide
- Published: 2026-08-30

---

**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`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/satellites.js) [line 2] imports four critical functions from the library:

- **`eciToGeodetic`** – Performs the core coordinate transformation from ECI to geodetic
- **`gstime`** – Calculates Greenwich Mean Sidereal Time for rotational alignment
- **`degreesLong`** – Converts longitude from radians to decimal degrees
- **`degreesLat`** – 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`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/satellites.js) [line 527], this function returns an object with three properties:

- **`longitude`** – Angular position east-west in **radians**
- **`latitude`** – Angular position north-south in **radians**
- **`height`** – 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`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/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`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/satellites.js), this helper:

1. Calls `propagate` to generate ECI coordinates for the current timestamp
2. Invokes `gstime` to calculate the rotational offset for the epoch
3. Passes both values to `eciToGeodetic`
4. Returns a plain JavaScript object with `longitude`, `latitude`, and `altitude` (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:

```javascript
// 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 `eciToGeodetic` to 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 `eciToGeodetic` function 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.js`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/src/data/satellites.js) within the `propagatePosition` (lines 483-495) and `computeOrbitPath` (lines 527-533) functions.
- Import `degreesLong` and `degreesLat` from 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`](https://github.com/bilawalsidhu/gods-eye-view/blob/main/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.