As seen onFavicon for

Making Ground Track Generator

I wrote a little program to make shapefiles (GIS map layers) of satellite ground tracks. Here's the story of its development, recounted from my comments on Twitter (the internet's water cooler).


  1. Here was my first mention of Ground Track Generator, posted at the end of the day I started working on it:
  2. After posting the "sneak peek" image, I followed up with brief explanation of the niche I envision for the program. You can easily visualize satellite orbits at a variety of sites (see Online Satellite Tracking at the CelesTrak satellite tracking software index), but I could not find any tools obviously capable of exporting satellite tracks to a format readily compatible with typical desktop GIS software. As a GIS user and a remote sensing buff, I thought it might be useful, for example, to be able to overlay satellite imagery with the actual path of the satellite that collected the imagery (more on that later).
  3. It did not take long to get to that first milestone, thanks to the libraries I was using to do the heavy lifting:
  4. Before long I discovered some challenges to the basic features I wanted to include, such as line output. Specifically, since longitude coordinates jump from -180˚ to 180˚ at the antimeridian, some programs render lines which cross the ±180th meridian from east to west as crossing the rest of globe from west to east instead (or vice versa). 
  5. The solution I implemented is not entirely satisfactory, since it treats the globe as a sphere instead of the WGS-72 ellipsoid used by the SGP4 model. Essentially, the program finds the intersection of the antimeridian with the great circle connecting each endpoint of the suspect line segment. The offending line segment is split into two parts at that point, circumventing any confusion about how to draw lines that cross the ±180th meridian.

    My first stab at a quick fix was even more naïve in that it treated the coordinates as Cartesian coordinates. This post highlighted the difference between the Cartesian "y = mx + b" split method (red segment) and the great circles split method (blue segment):
  6. For now I am content with the spherical approximation since the split feature is provided mainly as a cosmetic fix. Nevertheless, as I learn more about the math and perhaps figure out how to use the SGP4 model to solve for different unknowns, I expect I will eventually return to Do It Right…
  7. Disregarding some rough edges, the program was working more or less as I'd envisioned by the end of the first week of work. I started experimenting with some "real world" projected ground tracks:
  8. (The ISS and Automated Transfer Vehicle 3 have since docked successfully.)

    I spent the first few days of the second week setting up tests to compare Ground Track Generator's output with the SGP4 library's output and the reference cases published in appendices D and E of Revisiting Spacetrack Report #3 (RSR3), the source of the model used in the library. It is wonderful to have well-documented test cases, since the tests quickly revealed a bug in my code:
  9. The bug was manifesting as small inconsistencies in the interval between each step of the ground track. Instead of precise increments of 30 seconds, for example, the timestamps of consecutive points were very gradually drifting further apart. Although not at all apparent on the map, these errors resulted in many attribute discrepancies east of the decimal point which were picked up in comparison of the test output with the reference values. (BBEdit's Find Differences function is quite useful for reviewing these differences; I wrote a script to make it even easier in some cases.)

    Anyway, a funny thing happened on the way to a fix:
  10. Nothing reveals how little you know like having no idea what is going on in code you wrote, but every little victory over the forces of ignorance and entropy is cause for a small celebration. (But don't get cocky.)
  11. I was repeatedly adding and subtracting the same values to a floating-point variable. Mathematically, this doesn't seem like cause for alarm, but as a consequence of the way floating-point numbers are stored, this can result in the promotion of insignificant bits to significance and consequently the accumulation of error.
  12. I am sure other bugs remain in the code. Additionally, although my program's output now matches the SGP4 library's test output (as you would expect, since one is built on the other), the library's output does not match the reference output exactly. I believe the difference is within acceptable limits ("TLE data is [only] accurate to about a kilometer or so at epoch" anyway - RSR3), but it would still be nice to account for the difference.

    Anyway, here was another interesting experiment: