I have been given a list of 30 ground stations in the form of name/latitude/longitude. I want to know which LEO RSOs (~10k) pass over thier geographic zone, so I used a GeographicZoneDetector and created a 5 mile ‘zone’ around the lat/long position.
SpacePort POJO:
@Slf4j
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class SpacePort {
private String sp_no;
private String sp;
private double lat;
private double lon;
private SphericalPolygonsSet zone;
}
Zone creation:
try {
// Open the CSV file
BufferedReader br = new BufferedReader(new FileReader("src/main/resources/spaceports.csv"));
// Skip the header line
br.readLine();
// Read each line in the CSV file
while ((line = br.readLine()) != null) {
// Split the line by comma
String[] spacePortData = line.split(splitBy);
// Create a new SpacePort object and set its fields
SpacePort spacePort = new SpacePort();
spacePort.setSp_no(spacePortData[0]);
spacePort.setSp(spacePortData[1]);
spacePort.setLat(Double.parseDouble(spacePortData[2]));
spacePort.setLon(Double.parseDouble(spacePortData[3]));
double lat = Math.toRadians(spacePort.getLat());
double colatitude = Math.PI / 2 - lat;
double lon = Math.toRadians(spacePort.getLon());
double radiusMiles = 5.0; // THIS IS HOW BIG THE CIRCLE WILL BE
double radiusKm = radiusMiles * 1.60934;
double angularRadius = radiusKm / 6371.0;
GeodeticPoint center = new GeodeticPoint(lat, lon, 0.0);
int numPoints = 100;
S2Point[] boundary = new S2Point[numPoints];
for (int k = 0; k < numPoints; ++k) {
double theta = 2 * Math.PI * k / numPoints;
boundary[k] = new S2Point(
center.getLongitude() + angularRadius * Math.cos(theta),
colatitude + angularRadius * Math.sin(theta)
);
}
SphericalPolygonsSet zone = new SphericalPolygonsSet(1e-10, boundary);
spacePort.setZone(zone);
// Add the SpacePort object to the list
spacePorts.add(spacePort);
}
}
Main code loop:
I am trying to use Java Streams to take advantage of built in parallelism.
SpacePortReader spacePortReader = new SpacePortReader();
TLEReader tleReader = new TLEReader();
// The circle is defined in these spacePortAreas
List<SpacePort> spacePortAreas = spacePortReader.readSpacePorts();
Map<String, TLE> tles = tleReader.readTLEs();
spacePortAreas.stream().parallel().forEach(spacePort -> {
tles.entrySet().parallelStream().forEach(entry -> {
TLE tle = entry.getValue();
String rsoName = entry.getKey();
final Frame earthFrame = FramesFactory.getITRF(IERSConventions.IERS_2010, true);
final OneAxisEllipsoid earth = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
Constants.WGS84_EARTH_FLATTENING, earthFrame);
// Create a propagator for the TLE
Propagator propagator = TLEPropagator.selectExtrapolator(entry.getValue());
OneAxisEllipsoid earthShape = new OneAxisEllipsoid(Constants.WGS84_EARTH_EQUATORIAL_RADIUS,
Constants.WGS84_EARTH_FLATTENING, earthFrame);
GeographicZoneDetector zoneDetector = new GeographicZoneDetector(
60.0,
1e-3,
earthShape,
spacePort.getZone(),
Math.toRadians(0.1)
);
zoneDetector = zoneDetector.withHandler((state, detector, increasing) -> {
ZonedDateTime dataInEst = ZonedDateTime.ofInstant(state.getDate().toDate(TimeScalesFactory.getUTC()).toInstant(), ZoneId.of("America/New_York"));
if (increasing) {
System.out.println(rsoName + ": Entering geographic zone: " + spacePort.getSp() + " at: " + dataInEst);
} else {
System.out.println(rsoName + ": Exiting geographic zone: " + spacePort.getSp() + " at: " + dataInEst);
}
return Action.CONTINUE;
});
propagator.addEventDetector(zoneDetector);
propagator.propagate(propagator.getInitialState().getDate().shiftedBy(Constants.JULIAN_DAY));
});
});
}
My question is should this take 9 hours to run? I would love any insights into a better way to code this in order to speed it up. I am very new to satellite propagation and SGP4 so I don’t have anything to compare to.
Any insights are appreciated.
sg