Visualizing ECI orbits in cesium

Hi all,
currently working a project where I would like to visualize the orbit of a satellite using the ECI frame. I’ve tried doing some research online saying I need to use CZML in order to this and make sure I set the reference frame to “INERTIAL” which I’ve done, but the resulting orbit is in the wrong place or shifted and I don’t understand what I’m missing. I’m also not super knowledgeable about how orbit in general and knowledge really only spans as far as there are several reference frames which satellites can be plotted on so forgive me if there is something missing that should be obvious to those who know a lot more about this. I’ve been using the satellite.js library to calculate the ECI positions, which has been pretty accurate for ECEF coordinates and can only assume that is the case for ECI. Is there something wrong with how I’m setting up my CZML file that would cause the polyline I’m rendering to not be accurate? Here is the code that I’ve been using to generate ECI coordinates and produce a czml file that should be rendered:


export function getPositionsECI(tleline1: string, tleline2: string) {
	const NUM_OF_POINTS = 180;
	const satrec = twoline2satrec(tleline1, tleline2);
	const period = 1 / (satrec.no / (2 * Math.PI));
	const intervalMinutes = period / NUM_OF_POINTS; // Get evenly distrbuted minutes for points
	const curr = new Date();
	const positions = [];

	for (let i = 0; i < NUM_OF_POINTS; i++) {
		// Increment date by intervalMinutes
		// * 60 * 1000 is to convert from minutes to milliseconds cause thats what constructor expects
		const date = new Date(curr.getTime() + i * intervalMinutes * 60 * 1000);
		const positionAndVelocity = propagate(satrec, date);

		if (positionAndVelocity?.position) {
			// positions are in kilometers and need to be converted to meters
			positions.push(positionAndVelocity.position.x * 1000);
			positions.push(positionAndVelocity.position.y * 1000);
			positions.push(positionAndVelocity.position.z * 1000);
		}
	}

	const dataHeader = {
		id: "document",
		version: "1.0",
	};

	const dataBody = {
		id: "satellite orbit",
		polyline: {
			positions: {
				referenceFrame: "INERTIAL",
				cartesian: positions,
			},
			material: {
				solidColor: {
					color: {
						rgba: [0, 255, 255, 255],
					},
				},
			},
			width: 2,
		},
	};

	const czmlECIOrbit = [dataHeader, dataBody];

	return czmlECIOrbit;
}

Hi @wsl2025 welcome to the community!

the resulting orbit is in the wrong place or shifted

Can you explain what you mean by this? A screenshot would help, or better yet, a Sandcastle example that demonstrates the problem.

Hi, so I could not manage to get satellite js to work in the cesium sandcastle environment. If you have some tips on how to accomplish that, I could make a sandcastle for you. To clarify further this is what I mean but the orbit is in the wrong place.


In the screenshot below. The red line represents the orbit of the satellite in ECEF reference frame. and the Cyan line is supposed to be the same satellites orbit in eci. As you can see satellite outlined by the green box is not contained at all on the ECI orbit. This is essentially what I am trying to accomplish. Any advice on this would be appreciated. Also if you have any further questions about the set up let me know.

Hi @wsl2025 I’m afraid this is getting a little beyond my limited knowledge of orbital dynamics.

Have you looked at satvis.space? It has an option to switch between fixed and inertial cameras. And according to the GitHub README, it is using both satellite.js and Cesium.