use of uk.m0nom.adif3.contacts.Qso in project adif-processor by urbancamo.
the class ThymleafKmlContactInfoPanelTest method testThymeleafContactPanel.
@Test
public void testThymeleafContactPanel() throws IOException {
KmlContactInfoPanel infoPanel = new KmlContactInfoPanel();
TemplateEngine templateEngine = TemplateEngineConstructor.create();
TransformControl control = mock(TransformControl.class);
when(control.getTemplateEngine()).thenReturn(templateEngine);
Adif3Record rec = mock(Adif3Record.class);
Qso qso = mock(Qso.class);
CommsLinkResult clr = mock(CommsLinkResult.class);
LocalDate qsoDate = LocalDate.of(2021, 11, 10);
LocalTime qsoTime = LocalTime.of(21, 24);
when(qso.getRecord()).thenReturn(rec);
when(rec.getCall()).thenReturn("G8CPZ");
when(rec.getStationCallsign()).thenReturn("M0NOM");
when(rec.getQsoDate()).thenReturn(qsoDate);
when(rec.getTimeOn()).thenReturn(qsoTime);
when(rec.getBand()).thenReturn(Band.BAND_2m);
when(rec.getFreq()).thenReturn(145.450);
when(rec.getTxPwr()).thenReturn(50.0);
when(clr.getDistanceInKm()).thenReturn(20.5);
when(clr.getPropagation()).thenReturn(null);
when(rec.getFreqRx()).thenReturn(null);
String html = infoPanel.getPanelContentForCommsLink(qso, clr, TemplateEngineConstructor.create());
FileUtils.writeStringToFile(new File("target/contact.html"), html, StandardCharsets.UTF_8);
// System.out.println(html);
}
use of uk.m0nom.adif3.contacts.Qso in project adif-processor by urbancamo.
the class CommentParsingAdifRecordTransformer method transform.
@Override
public void transform(Qsos qsos, Adif3Record rec, int index) {
unmapped = new HashMap<>();
/* Add Adif3Record details to the Qsos meta structure */
Qso qso = new Qso(rec, index);
qsos.addQso(qso);
activityProcessor.processActivities(qso.getFrom(), rec);
setMyInfoFromQrz(qso);
QrzCallsign theirQrzData = setTheirInfoFromQrz(qso);
processSotaRef(qso);
processRailwaysOnTheAirCallsign(qso);
processSatelliteInfo(qso);
transformComment(qso, rec.getComment(), unmapped);
if (rec.getCoordinates() == null && rec.getGridsquare() == null) {
enricher.lookupLocationFromQrz(qso);
}
// IF qrz.com can't fill in the coordinates, and the gridsquare is set, fill in coordinates from that
if (hasValidGridsquareNoCoords(rec)) {
setCoordinatesFromGridsquare(qso);
}
// Last resort, attempt to find location from qrz.com address data via geolocation provider
if (hasNoValidGridsquareOrCoords(rec) && theirQrzData != null) {
setTheirLocationFromGeocodedAddress(qso, theirQrzData);
}
// Look to see if there is anything in the SIG/SIGINFO fields
if (StringUtils.isNotBlank(rec.getSig())) {
processSig(qso, unmapped);
}
if (control.isStripComment()) {
if (!unmapped.isEmpty()) {
addUnmappedToRecord(rec, unmapped);
} else {
// done a good job and slotted all the key/value pairs in the right place
rec.setComment("");
}
}
// Add the SOTA Microwave Award data to the end of the comment field
if (control.isSotaMicrowaveAwardComment()) {
SotaMicrowaveAward.addSotaMicrowaveAwardToComment(rec);
}
if (rec.getSatName() != null) {
results.getSatelliteActivity().recordSatelliteActivity(qso);
}
}
use of uk.m0nom.adif3.contacts.Qso in project adif-processor by urbancamo.
the class KmlWriter method write.
public void write(String pathname, String name, ActivityDatabases activities, Qsos qsos, TransformResults results) {
KmlLocalActivities kmlLocalActivities = new KmlLocalActivities();
KmlCommsUtils kmlCommsUtils = new KmlCommsUtils(control, activities);
KmlStationUtils kmlStationUtils = new KmlStationUtils(control);
KmlSatelliteTrack kmlSatelliteTrack = new KmlSatelliteTrack();
final Kml kml = new Kml();
Document doc = kml.createAndSetDocument().withName(name).withOpen(true);
// create a Folder
Folder contactsFolder = doc.createAndAddFolder();
contactsFolder.withName("Contacts").withOpen(true);
if (results.getSatelliteActivity().hasActivity()) {
results.getSatelliteActivity().spaceOutContactsInPasses();
}
Station myStation = null;
Iterator<Qso> qsoIterator = qsos.getQsos().iterator();
Folder folder = null;
while (qsoIterator.hasNext()) {
Qso qso = qsoIterator.next();
if (!qso.getFrom().equals(myStation)) {
folder = contactsFolder.createAndAddFolder().withName(qso.getFrom().getCallsign()).withOpen(true);
String error = kmlStationUtils.addMyStationToMap(doc, folder, qso);
if (error != null) {
results.setError(error);
}
if (qso.getFrom().hasActivity() && control.isKmlShowLocalActivationSites()) {
kmlLocalActivities.addLocalActivities(doc, folder, qso.getFrom(), control.getKmlLocalActivationSitesRadius(), activities);
}
myStation = qso.getFrom();
}
Folder contactFolder = folder.createAndAddFolder().withName(qso.getTo().getCallsign()).withOpen(false);
GlobalCoordinates coords = qso.getRecord().getCoordinates();
if (LatLongUtils.isCoordinateValid(coords)) {
String error = kmlStationUtils.createStationMarker(control, doc, contactFolder, qso);
if (error != null) {
results.setError(error);
}
if (qso.getTo().hasActivity() && control.isKmlShowLocalActivationSites()) {
Folder localActivityFolder = contactFolder.createAndAddFolder().withName("Local Activity").withOpen(false);
kmlLocalActivities.addLocalActivities(doc, localActivityFolder, qso.getTo(), control.getKmlLocalActivationSitesRadius(), activities);
}
error = kmlCommsUtils.createCommsLink(doc, contactFolder, qso, control, kmlStationUtils);
if (error != null) {
results.setError(error);
}
if (MaidenheadLocatorConversion.isADubiousGridSquare(qso.getRecord().getGridsquare())) {
results.addContactWithDubiousLocation(qso.getTo().getCallsign());
}
} else {
results.addContactWithoutLocation(qso.getTo().getCallsign());
logger.warning(String.format("Cannot determine communication link, no location data for: %s", qso.getTo().getCallsign()));
}
}
if (!results.hasErrors()) {
if (results.getSatelliteActivity().hasActivity()) {
GlobalCoordinates coords = qsos.getQsos().get(0).getRecord().getMyCoordinates();
GlobalCoords3D coordinatesWithSourceAccuracy = new GlobalCoords3D(coords, 0.0);
kmlSatelliteTrack.addSatelliteTracks(control, doc, results.getSatelliteActivity(), coordinatesWithSourceAccuracy);
}
try {
logger.info(String.format("Writing KML to: %s", pathname));
File file = new File(pathname);
kml.marshal(file);
String kmlContent = FileUtils.readFileToString(file, "UTF-8");
kmlContent = kmlContent.replaceAll("ns2:", "").replace("<kml xmlns:ns2=\"http://www.opengis.net/kml/2.2\" xmlns:ns3=\"http://www.w3.org/2005/Atom\" xmlns:ns4=\"urn:oasis:names:tc:ciq:xsdschema:xAL:2.0\" xmlns:ns5=\"http://www.google.com/kml/ext/2.2\">", "<kml>");
FileUtils.write(file, kmlContent, "UTF-8");
} catch (IOException e) {
results.setError(e.getMessage());
}
}
}
use of uk.m0nom.adif3.contacts.Qso in project adif-processor by urbancamo.
the class SatellitePass method createQsoCountPerTime.
/**
* For each time recorded for a contact determine the number of contacts that share that time
* @return map of contact times with number of QSOs
*/
private Map<LocalTime, Integer> createQsoCountPerTime() {
Map<LocalTime, Integer> qsoCountPerTime = new HashMap<>();
for (Qso qso : contacts) {
LocalTime time = qso.getRecord().getTimeOn();
Integer count = qsoCountPerTime.get(time);
if (count != null) {
count = count + 1;
} else {
count = 1;
}
qsoCountPerTime.put(time, count);
}
return qsoCountPerTime;
}
use of uk.m0nom.adif3.contacts.Qso in project adif-processor by urbancamo.
the class SatellitePass method spaceOutContacts.
/**
* For satellite QSOs often the recorded time is the same for multiple contacts.
* This isn't realistic and doesn't look good on the satellite path, so we artificially space out contacts
* (in both time and therefore along the satellite path) based on the order in which they are added to the pass,
* which will generally be the correct chronological order.
*/
public void spaceOutContacts() {
// Determine the number of contacts per time on the pass
Map<LocalTime, Integer> qsoCountPerTime = createQsoCountPerTime();
Iterator<Qso> qsoIterator = getContacts().iterator();
while (qsoIterator.hasNext()) {
Qso qso = qsoIterator.next();
LocalTime qsoTime = qso.getRecord().getTimeOn();
Integer numberOfQsosSharingTime = qsoCountPerTime.get(qsoTime);
// Only need to adjust times if there are more than one sharing a time
if (numberOfQsosSharingTime > 1) {
for (int i = 1; i < numberOfQsosSharingTime; i++) {
// No need to adjust the first one which will be on 0 seconds
qso = qsoIterator.next();
LocalTime adjustedTime = qsoTime.plusSeconds((long) 60 / numberOfQsosSharingTime * i);
qso.getRecord().setTimeOn(adjustedTime);
}
}
}
}
Aggregations