mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-13 14:12:11 +00:00
introduced abstract DeclinationImporter class of which now NOAAImporter and ColoradoImporter are two different implementations
Change-Id: Icc993ccb6b7111a5e30046f09c595d5445ccbf7c
This commit is contained in:
1 parent
ddd42f6b5e
commit
3e7e96f4d0
4 files changed
+102
-48
No files matched your search
+19
@@ -3,6 +3,9 @@ package com.sap.sailing.declination.test;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
@@ -11,14 +14,30 @@ import org.xml.sax.SAXException;
|
||||
|
||||
import com.sap.sailing.declination.Declination;
|
||||
import com.sap.sailing.declination.impl.ColoradoImporter;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
public class ColoradoTest {
|
||||
@Test
|
||||
public void simpleDocumentParsingTest() throws SAXException, IOException, ParserConfigurationException {
|
||||
final Declination declination = new ColoradoImporter().getDeclinationFromXml(getClass().getResourceAsStream("/colorado.xml"));
|
||||
validateSomeDeclinationInJanuary2018(declination);
|
||||
}
|
||||
|
||||
private void validateSomeDeclinationInJanuary2018(final Declination declination) {
|
||||
assertEquals(10.0, declination.getPosition().getLatDeg(), 0.000001);
|
||||
assertEquals(20.0, declination.getPosition().getLngDeg(), 0.000001);
|
||||
assertEquals(1.89255, declination.getBearing().getDegrees(), 0.000001);
|
||||
assertEquals(0.10649, declination.getAnnualChange().getDegrees(), 0.000001);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleOnlineTest() throws IOException, ParseException {
|
||||
final GregorianCalendar cal = new GregorianCalendar(2018, 0, 23);
|
||||
cal.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
final Declination declination = new ColoradoImporter().getDeclination(new DegreePosition(10, 20),
|
||||
new MillisecondsTimePoint(cal.getTime()),
|
||||
/* timeoutForOnlineFetchInMilliseconds */ 5000);
|
||||
validateSomeDeclinationInJanuary2018(declination);
|
||||
}
|
||||
}
|
||||
+18
-1
@@ -2,6 +2,10 @@ package com.sap.sailing.declination.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.parsers.SAXParserFactory;
|
||||
@@ -11,8 +15,10 @@ import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
import com.sap.sailing.declination.Declination;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
|
||||
import com.sap.sailing.domain.common.impl.DegreePosition;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
|
||||
/**
|
||||
@@ -43,7 +49,9 @@ import com.sap.sse.common.impl.MillisecondsTimePoint;
|
||||
* @author Axel Uhl (D043530)
|
||||
*
|
||||
*/
|
||||
public class ColoradoImporter {
|
||||
public class ColoradoImporter extends DeclinationImporter {
|
||||
private static final String URL_PATTERN = "http://magcalc.geomag.info/?model=WMM2015&sourcePage=oldCalc&decimalLatitude=%f&decimalLongitude=%f&minYear=%d&minMonth=%d&minDay=%d";
|
||||
|
||||
private static class XmlElementHandler extends DefaultHandler {
|
||||
private double dateAsDecimalYear;
|
||||
private double latDeg;
|
||||
@@ -104,4 +112,13 @@ public class ColoradoImporter {
|
||||
SAXParserFactory.newInstance().newSAXParser().parse(is, handler);
|
||||
return handler.getDeclination();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Declination importRecord(Position position, TimePoint timePoint)
|
||||
throws IOException, ParserConfigurationException, SAXException {
|
||||
final Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
|
||||
cal.setTime(timePoint.asDate());
|
||||
final URL url = new URL(String.format(URL_PATTERN, position.getLatDeg(), position.getLngDeg(), cal.get(Calendar.YEAR), cal.get(Calendar.MONTH)+1, cal.get(Calendar.DAY_OF_MONTH)));
|
||||
return getDeclinationFromXml(url.openStream());
|
||||
}
|
||||
}
|
||||
Executable
+63
@@ -0,0 +1,63 @@
|
||||
package com.sap.sailing.declination.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import com.sap.sailing.declination.Declination;
|
||||
import com.sap.sailing.domain.common.Position;
|
||||
import com.sap.sse.common.TimePoint;
|
||||
|
||||
public abstract class DeclinationImporter {
|
||||
private static final Logger logger = Logger.getLogger(DeclinationImporter.class.getName());
|
||||
|
||||
public abstract Declination importRecord(Position position, TimePoint timePoint)
|
||||
throws IOException, ParserConfigurationException, SAXException;
|
||||
|
||||
/**
|
||||
* Tries two things in parallel: fetch a more or less precise response from the online service and load
|
||||
* the requested year's declination values from a stored resource to look up a value that comes close.
|
||||
* The online lookup will be given preference. However, should it take longer than
|
||||
* <code>timeoutForOnlineFetchInMilliseconds</code>, then the method will return whatever it found
|
||||
* in the stored file, or <code>null</code> if no file exists for the year of <code>timePoint</code>.
|
||||
*
|
||||
* @param timeoutForOnlineFetchInMilliseconds if 0, this means wait forever for the online result
|
||||
* @throws ParseException
|
||||
* @throws ClassNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
public Declination getDeclination(final Position position, final TimePoint timePoint,
|
||||
long timeoutForOnlineFetchInMilliseconds) throws IOException, ParseException {
|
||||
final Declination[] result = new Declination[1];
|
||||
Thread fetcher = new Thread("Declination fetcher for "+position+"@"+timePoint) {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Declination fetched = importRecord(position, timePoint);
|
||||
synchronized (result) {
|
||||
result[0] = fetched;
|
||||
result.notifyAll();
|
||||
}
|
||||
} catch (IOException | ParserConfigurationException | SAXException e) {
|
||||
logger.log(Level.FINE, "Exception while trying to load magnetic declination online", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
fetcher.start();
|
||||
synchronized (result) {
|
||||
if (result[0] == null) {
|
||||
try {
|
||||
result.wait(timeoutForOnlineFetchInMilliseconds);
|
||||
} catch (InterruptedException e) {
|
||||
// ignore; simply use value from file in this case
|
||||
}
|
||||
}
|
||||
}
|
||||
return result[0];
|
||||
}
|
||||
}
|
||||
+2
-47
@@ -4,12 +4,9 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.text.ParseException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
@@ -31,8 +28,7 @@ import com.sap.sse.common.TimePoint;
|
||||
* @author Axel Uhl (d043530)
|
||||
*
|
||||
*/
|
||||
public class NOAAImporter {
|
||||
private static final Logger logger = Logger.getLogger(NOAAImporter.class.getName());
|
||||
public class NOAAImporter extends DeclinationImporter {
|
||||
private static final String QUERY_URL = "https://www.ngdc.noaa.gov/geomag-web/calculators/calculateDeclination";
|
||||
private static final String REGEXP_DECLINATION = "<p class=\"indent\"><b>Declination</b> = ([0-9]*)° ([0-9]*)' *([EW])";
|
||||
private static final String REGEXP_ANNUAL_CHANGE = "changing by *([0-9]*)° *([0-9]*)' ([EW])/year *</p>";
|
||||
@@ -54,6 +50,7 @@ public class NOAAImporter {
|
||||
return annualChangePattern;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Declination importRecord(Position position, TimePoint timePoint) throws IOException, ParserConfigurationException, SAXException {
|
||||
Declination result = null;
|
||||
Date date = timePoint.asDate();
|
||||
@@ -80,46 +77,4 @@ public class NOAAImporter {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries two things in parallel: fetch a more or less precise response from the online service and load
|
||||
* the requested year's declination values from a stored resource to look up a value that comes close.
|
||||
* The online lookup will be given preference. However, should it take longer than
|
||||
* <code>timeoutForOnlineFetchInMilliseconds</code>, then the method will return whatever it found
|
||||
* in the stored file, or <code>null</code> if no file exists for the year of <code>timePoint</code>.
|
||||
*
|
||||
* @param timeoutForOnlineFetchInMilliseconds if 0, this means wait forever for the online result
|
||||
* @throws ParseException
|
||||
* @throws ClassNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
public Declination getDeclination(final Position position, final TimePoint timePoint,
|
||||
long timeoutForOnlineFetchInMilliseconds) throws IOException, ParseException {
|
||||
final Declination[] result = new Declination[1];
|
||||
Thread fetcher = new Thread("Declination fetcher for "+position+"@"+timePoint) {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Declination fetched = importRecord(position, timePoint);
|
||||
synchronized (result) {
|
||||
result[0] = fetched;
|
||||
result.notifyAll();
|
||||
}
|
||||
} catch (IOException | ParserConfigurationException | SAXException e) {
|
||||
logger.log(Level.FINE, "Exception while trying to load magnetic declination online", e);
|
||||
}
|
||||
}
|
||||
};
|
||||
fetcher.start();
|
||||
synchronized (result) {
|
||||
if (result[0] == null) {
|
||||
try {
|
||||
result.wait(timeoutForOnlineFetchInMilliseconds);
|
||||
} catch (InterruptedException e) {
|
||||
// ignore; simply use value from file in this case
|
||||
}
|
||||
}
|
||||
}
|
||||
return result[0];
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user