diff --git a/java/com.sap.sailing.declination.test/src/com/sap/sailing/declination/test/ColoradoTest.java b/java/com.sap.sailing.declination.test/src/com/sap/sailing/declination/test/ColoradoTest.java
index a0b6ea1ca73..8f6b3aca688 100755
--- a/java/com.sap.sailing.declination.test/src/com/sap/sailing/declination/test/ColoradoTest.java
+++ b/java/com.sap.sailing.declination.test/src/com/sap/sailing/declination/test/ColoradoTest.java
@@ -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);
+ }
}
diff --git a/java/com.sap.sailing.declination/src/com/sap/sailing/declination/impl/ColoradoImporter.java b/java/com.sap.sailing.declination/src/com/sap/sailing/declination/impl/ColoradoImporter.java
index ee0d7d8d033..8019535cc76 100755
--- a/java/com.sap.sailing.declination/src/com/sap/sailing/declination/impl/ColoradoImporter.java
+++ b/java/com.sap.sailing.declination/src/com/sap/sailing/declination/impl/ColoradoImporter.java
@@ -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());
+ }
}
diff --git a/java/com.sap.sailing.declination/src/com/sap/sailing/declination/impl/DeclinationImporter.java b/java/com.sap.sailing.declination/src/com/sap/sailing/declination/impl/DeclinationImporter.java
new file mode 100755
index 00000000000..bd0ffa14d9e
--- /dev/null
+++ b/java/com.sap.sailing.declination/src/com/sap/sailing/declination/impl/DeclinationImporter.java
@@ -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
+ * timeoutForOnlineFetchInMilliseconds, then the method will return whatever it found
+ * in the stored file, or null if no file exists for the year of timePoint.
+ *
+ * @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];
+ }
+}
diff --git a/java/com.sap.sailing.declination/src/com/sap/sailing/declination/impl/NOAAImporter.java b/java/com.sap.sailing.declination/src/com/sap/sailing/declination/impl/NOAAImporter.java
index 2e265682a56..3febf4decc3 100755
--- a/java/com.sap.sailing.declination/src/com/sap/sailing/declination/impl/NOAAImporter.java
+++ b/java/com.sap.sailing.declination/src/com/sap/sailing/declination/impl/NOAAImporter.java
@@ -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 = "
Declination = ([0-9]*)° ([0-9]*)' *([EW])"; private static final String REGEXP_ANNUAL_CHANGE = "changing by *([0-9]*)° *([0-9]*)' ([EW])/year *
"; @@ -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 - *timeoutForOnlineFetchInMilliseconds, then the method will return whatever it found
- * in the stored file, or null if no file exists for the year of timePoint.
- *
- * @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];
- }
-
}