diff --git a/mock/src/test/resources/mockXML/boatXML/boatTest.xml b/mock/src/test/resources/mockXML/boatXML/boatTest.xml new file mode 100644 index 00000000..738502a5 --- /dev/null +++ b/mock/src/test/resources/mockXML/boatXML/boatTest.xml @@ -0,0 +1,251 @@ + + + + + 2012-05-17T07:49:40+0200 + + 12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/compiler.xml b/visualiser/.idea/compiler.xml new file mode 100644 index 00000000..4feb7dd4 --- /dev/null +++ b/visualiser/.idea/compiler.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/libraries/Maven__com_beust_jcommander_1_64.xml b/visualiser/.idea/libraries/Maven__com_beust_jcommander_1_64.xml new file mode 100644 index 00000000..e72647cc --- /dev/null +++ b/visualiser/.idea/libraries/Maven__com_beust_jcommander_1_64.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/libraries/Maven__com_github_bfsmith_geotimezone_1_0_3.xml b/visualiser/.idea/libraries/Maven__com_github_bfsmith_geotimezone_1_0_3.xml new file mode 100644 index 00000000..70fc370b --- /dev/null +++ b/visualiser/.idea/libraries/Maven__com_github_bfsmith_geotimezone_1_0_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/libraries/Maven__com_spatial4j_spatial4j_0_4_1.xml b/visualiser/.idea/libraries/Maven__com_spatial4j_spatial4j_0_4_1.xml new file mode 100644 index 00000000..e70d84d7 --- /dev/null +++ b/visualiser/.idea/libraries/Maven__com_spatial4j_spatial4j_0_4_1.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/libraries/Maven__commons_pool_commons_pool_1_5_4.xml b/visualiser/.idea/libraries/Maven__commons_pool_commons_pool_1_5_4.xml new file mode 100644 index 00000000..ab207212 --- /dev/null +++ b/visualiser/.idea/libraries/Maven__commons_pool_commons_pool_1_5_4.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/libraries/Maven__java3d_vecmath_1_3_2.xml b/visualiser/.idea/libraries/Maven__java3d_vecmath_1_3_2.xml new file mode 100644 index 00000000..1eebe0af --- /dev/null +++ b/visualiser/.idea/libraries/Maven__java3d_vecmath_1_3_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/libraries/Maven__javax_media_jai_core_1_1_3.xml b/visualiser/.idea/libraries/Maven__javax_media_jai_core_1_1_3.xml new file mode 100644 index 00000000..d8609e87 --- /dev/null +++ b/visualiser/.idea/libraries/Maven__javax_media_jai_core_1_1_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/libraries/Maven__jgridshift_jgridshift_1_0.xml b/visualiser/.idea/libraries/Maven__jgridshift_jgridshift_1_0.xml new file mode 100644 index 00000000..b7ad97c6 --- /dev/null +++ b/visualiser/.idea/libraries/Maven__jgridshift_jgridshift_1_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/libraries/Maven__joda_time_joda_time_2_7.xml b/visualiser/.idea/libraries/Maven__joda_time_joda_time_2_7.xml new file mode 100644 index 00000000..1259ecab --- /dev/null +++ b/visualiser/.idea/libraries/Maven__joda_time_joda_time_2_7.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/libraries/Maven__junit_junit_4_12.xml b/visualiser/.idea/libraries/Maven__junit_junit_4_12.xml new file mode 100644 index 00000000..d4110417 --- /dev/null +++ b/visualiser/.idea/libraries/Maven__junit_junit_4_12.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/libraries/Maven__net_java_dev_jsr_275_jsr_275_1_0_beta_2.xml b/visualiser/.idea/libraries/Maven__net_java_dev_jsr_275_jsr_275_1_0_beta_2.xml new file mode 100644 index 00000000..bf5f49be --- /dev/null +++ b/visualiser/.idea/libraries/Maven__net_java_dev_jsr_275_jsr_275_1_0_beta_2.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/libraries/Maven__org_geotools_gt_metadata_9_0.xml b/visualiser/.idea/libraries/Maven__org_geotools_gt_metadata_9_0.xml new file mode 100644 index 00000000..e872950f --- /dev/null +++ b/visualiser/.idea/libraries/Maven__org_geotools_gt_metadata_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/libraries/Maven__org_geotools_gt_opengis_9_0.xml b/visualiser/.idea/libraries/Maven__org_geotools_gt_opengis_9_0.xml new file mode 100644 index 00000000..01a5965e --- /dev/null +++ b/visualiser/.idea/libraries/Maven__org_geotools_gt_opengis_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/libraries/Maven__org_geotools_gt_referencing_9_0.xml b/visualiser/.idea/libraries/Maven__org_geotools_gt_referencing_9_0.xml new file mode 100644 index 00000000..36874c5c --- /dev/null +++ b/visualiser/.idea/libraries/Maven__org_geotools_gt_referencing_9_0.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml b/visualiser/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml new file mode 100644 index 00000000..f58bbc11 --- /dev/null +++ b/visualiser/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/libraries/Maven__org_mockito_mockito_all_1_9_5.xml b/visualiser/.idea/libraries/Maven__org_mockito_mockito_all_1_9_5.xml new file mode 100644 index 00000000..7797878d --- /dev/null +++ b/visualiser/.idea/libraries/Maven__org_mockito_mockito_all_1_9_5.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/libraries/Maven__org_testng_testng_6_11.xml b/visualiser/.idea/libraries/Maven__org_testng_testng_6_11.xml new file mode 100644 index 00000000..51052227 --- /dev/null +++ b/visualiser/.idea/libraries/Maven__org_testng_testng_6_11.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/libraries/Maven__org_yaml_snakeyaml_1_17.xml b/visualiser/.idea/libraries/Maven__org_yaml_snakeyaml_1_17.xml new file mode 100644 index 00000000..20e2920c --- /dev/null +++ b/visualiser/.idea/libraries/Maven__org_yaml_snakeyaml_1_17.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/misc.xml b/visualiser/.idea/misc.xml new file mode 100644 index 00000000..a46856d3 --- /dev/null +++ b/visualiser/.idea/misc.xml @@ -0,0 +1,43 @@ + + + + + + + + + + $USER_HOME$/.subversion + + + + + + 1.8 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/modules.xml b/visualiser/.idea/modules.xml new file mode 100644 index 00000000..e9597707 --- /dev/null +++ b/visualiser/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/uiDesigner.xml b/visualiser/.idea/uiDesigner.xml new file mode 100644 index 00000000..e96534fb --- /dev/null +++ b/visualiser/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/.idea/workspace.xml b/visualiser/.idea/workspace.xml new file mode 100644 index 00000000..58b5f16d --- /dev/null +++ b/visualiser/.idea/workspace.xml @@ -0,0 +1,1363 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + legs + + + + + + + + + + + + true + DEFINITION_ORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1492733921956 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/src/main/java/seng302/Controllers/RaceController.java b/visualiser/src/main/java/seng302/Controllers/RaceController.java index 6d4bdf8e..9c64bbfa 100644 --- a/visualiser/src/main/java/seng302/Controllers/RaceController.java +++ b/visualiser/src/main/java/seng302/Controllers/RaceController.java @@ -9,6 +9,7 @@ import javafx.fxml.FXML; import javafx.scene.control.*; import javafx.scene.layout.GridPane; import org.xml.sax.SAXException; +import seng302.Mock.StreamedRace; import seng302.Model.*; import seng302.RaceDataSource; import seng302.RaceXMLReader; @@ -116,14 +117,14 @@ public class RaceController extends Controller { * @param scaleFactor scale value of race */ public void startRace(int scaleFactor, RaceDataSource raceData) { - ConstantVelocityRace newRace = new ConstantVelocityRace(raceData, this, scaleFactor); - newRace.initialiseBoats(); + StreamedRace newRace = new StreamedRace(raceData, this, scaleFactor); + //newRace.initialiseBoats(); raceMap = new ResizableRaceCanvas(raceData); raceMap.setMouseTransparent(true); raceMap.widthProperty().bind(canvasBase.widthProperty()); raceMap.heightProperty().bind(canvasBase.heightProperty()); - raceMap.setBoats(newRace.getStartingBoats()); + //raceMap.setBoats(newRace.getStartingBoats()); raceMap.setRaceBoundaries(raceData.getBoundary()); raceMap.drawRaceMap(); raceMap.setVisible(true); @@ -133,7 +134,7 @@ public class RaceController extends Controller { //Initialize save annotation array, fps listener, and annotation listeners //timezone - RaceClock raceClock = new RaceClock(raceData.getMark()); + RaceClock raceClock = new RaceClock(raceData.getZonedDateTime()); timeZone.setText(raceClock.getTimeZone()); initializeFPS(); initializeAnnotations(); diff --git a/visualiser/src/main/java/seng302/Controllers/StartController.java b/visualiser/src/main/java/seng302/Controllers/StartController.java index f62fb6ea..4c70a1a2 100644 --- a/visualiser/src/main/java/seng302/Controllers/StartController.java +++ b/visualiser/src/main/java/seng302/Controllers/StartController.java @@ -13,6 +13,7 @@ import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.layout.AnchorPane; import javafx.scene.layout.GridPane; import org.xml.sax.SAXException; +import seng302.Mock.*; import seng302.Model.BoatInRace; import seng302.Model.RaceClock; import seng302.RaceDataSource; @@ -21,6 +22,7 @@ import seng302.RaceXMLReader; import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; import java.net.URL; +import java.text.ParseException; import java.util.List; import java.util.ResourceBundle; @@ -46,6 +48,7 @@ public class StartController extends Controller { private RaceClock raceClock; private RaceDataSource raceData; + private long timeLeft = 1; /** * Begins the race with a scale factor of 15 @@ -80,15 +83,23 @@ public class StartController extends Controller { public void initialize(URL location, ResourceBundle resources){ raceData = null; try { - raceData = new RaceXMLReader("raceXML/bermuda_AC35.xml"); + StreamedCourse streamedCourse = new StreamedCourse(new BoatXMLReader("mockXML/boatXML/boatTest.xml")); + streamedCourse.setStreamedCourseXMLReader(new StreamedCourseXMLReader("mockXML/raceXML/raceTest.xml")); + streamedCourse.setRegattaXMLReader(new RegattaXMLReader("mockXML/regattaXML/regattaTest.xml")); + raceData = streamedCourse; } catch (IOException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (ParserConfigurationException e) { e.printStackTrace(); + } catch (ParseException e) { + e.printStackTrace(); + } catch (StreamedCourseXMLException e) { + e.printStackTrace(); } initialiseTables(); + setRaceClock(); } public AnchorPane startWrapper(){ @@ -102,9 +113,6 @@ public class StartController extends Controller { boatNameTable.setItems(observableBoats); boatNameColumn.setCellValueFactory(cellData -> cellData.getValue().getName()); boatCodeColumn.setCellValueFactory(new PropertyValueFactory<>("abbrev")); - //timezone - raceClock = new RaceClock(raceData.getMark()); - timeZoneTime.textProperty().bind(raceClock.timeProperty()); } @@ -130,7 +138,6 @@ public class StartController extends Controller { long currentTimeInSeconds; long remainingSeconds; long hours; - long timeLeft; @Override public void handle(long arg0) { @@ -148,7 +155,6 @@ public class StartController extends Controller { hours = minutes / 60; minutes = minutes % 60; updateTime(String.format("Race Clock: -%02d:%02d:%02d", hours, minutes, remainingSeconds)); - raceClock.updateTime(); } currentTime = System.currentTimeMillis(); @@ -156,4 +162,20 @@ public class StartController extends Controller { }.start(); } + protected void setRaceClock() { + raceClock = new RaceClock(raceData.getZonedDateTime()); + timeZoneTime.textProperty().bind(raceClock.timeStringProperty()); + + new AnimationTimer() { + @Override + public void handle(long arg0) { + if (timeLeft > 0) { + raceClock.updateTime(); + } else { + stop(); + } + } + }.start(); + } + } diff --git a/visualiser/src/main/java/seng302/Mock/BoatXMLReader.java b/visualiser/src/main/java/seng302/Mock/BoatXMLReader.java new file mode 100644 index 00000000..a7d429dc --- /dev/null +++ b/visualiser/src/main/java/seng302/Mock/BoatXMLReader.java @@ -0,0 +1,156 @@ +package seng302.Mock; + +import javafx.scene.paint.Color; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; +import seng302.XMLReader; + +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.lang.annotation.ElementType; +import java.text.ParseException; +import java.util.*; + +/** + * Created by Joseph on 24/04/2017. + */ +public class BoatXMLReader extends XMLReader { + Map streamedBoatMap = new HashMap<>(); + Map participants = new HashMap<>(); + private List colours; + private static int currentColourIndex = 0; + + /** + * Constructor for Boat XML Reader + * @param filePath path of the file + * @throws IOException error + * @throws SAXException error + * @throws ParserConfigurationException error + */ + public BoatXMLReader(String filePath) throws IOException, SAXException, ParserConfigurationException, ParseException { + this(filePath, false); + makeColours(); + } + + /** + * Constructor for Boat XML Reader + * @param filePath file path to read + * @param read whether or not to read and store the files straight away. + * @throws IOException error + * @throws SAXException error + * @throws ParserConfigurationException error + */ + public BoatXMLReader(String filePath, boolean read) throws IOException, SAXException, ParserConfigurationException, ParseException { + super(filePath); + makeColours(); + if (read) { + read(); + } + } + + public void read() { + readSettings(); + readShapes(); + readBoats(); + } + + /** + * Reads boats settings. + * INFORMATION FROM HERE IS IGNORED FOR NOW + */ + private void readSettings() { + + } + + /** + * Reads different kinds of boat. + * INFORMATION FROM HERE IS IGNORED FOR NOW + */ + private void readShapes() { + + } + + /** + * Reads the boats in the race + */ + private void readBoats() { + Element nBoats = (Element) doc.getElementsByTagName("Boats").item(0); + for (int i = 0; i < nBoats.getChildNodes().getLength(); i++) { + Node boat = nBoats.getChildNodes().item(i); + if (boat.getNodeName().equals("Boat")) { + readSingleBoat(boat); + currentColourIndex = (currentColourIndex + 1) % colours.size(); + } + } + } + + /** + * Reads the information about one boat + * Ignored values: ShapeID, StoweName, HullNum, Skipper + */ + private void readSingleBoat(Node boat) { + StreamedBoat streamedBoat; + String type = "None"; + int sourceID = -1; + String boatName = null; + String shortName = null; + String country = null; + if (exists(boat, "Type")) type = boat.getAttributes().getNamedItem("Type").getTextContent(); + if (exists(boat, "SourceID")) sourceID = Integer.parseInt(boat.getAttributes().getNamedItem("SourceID").getTextContent()); + if (exists(boat, "BoatName")) boatName = boat.getAttributes().getNamedItem("BoatName").getTextContent(); + if (exists(boat, "ShortName")) shortName = boat.getAttributes().getNamedItem("ShortName").getTextContent(); + if (exists(boat, "Country")) country = boat.getAttributes().getNamedItem("Country").getTextContent(); + + // Ignore all non participating boats + if (participants.containsKey(sourceID)) { + + if (!streamedBoatMap.containsKey(sourceID)) { + if (country != null) { + streamedBoat = new StreamedBoat(sourceID, boatName, colours.get(currentColourIndex), country); + } else { + streamedBoat = new StreamedBoat(sourceID, boatName, colours.get(currentColourIndex), shortName); + } + streamedBoatMap.put(sourceID, streamedBoat); + // Override boat with new boat + participants.put(sourceID, streamedBoat); + } + + for (int i = 0; i < boat.getChildNodes().getLength(); i++) { + Node GPSPosition = boat.getChildNodes().item(i); + if (GPSPosition.getNodeName().equals("GPSposition")) readBoatPositionInformation(sourceID, GPSPosition); + } + } + } + + /** + * Reads the positional information about a boat + * Ignored values: FlagPosition, MastTop, Z value of GPSposition + */ + private void readBoatPositionInformation(int sourceID, Node GPSPosition) { + // TODO Get relative point before implementing. (GPSposition is based off a relative point). + } + + private void makeColours() { + colours = new ArrayList(Arrays.asList( + Color.BLUEVIOLET, + Color.BLACK, + Color.RED, + Color.ORANGE, + Color.DARKOLIVEGREEN, + Color.LIMEGREEN, + Color.PURPLE, + Color.DARKGRAY, + Color.YELLOW + )); + } + + public void setParticipants(Map participants) { + this.participants = participants; + } + + public Map getStreamedBoatMap() { + return streamedBoatMap; + } +} diff --git a/visualiser/src/main/java/seng302/Mock/Regatta.java b/visualiser/src/main/java/seng302/Mock/Regatta.java index 3b749256..a3785f68 100644 --- a/visualiser/src/main/java/seng302/Mock/Regatta.java +++ b/visualiser/src/main/java/seng302/Mock/Regatta.java @@ -1,5 +1,7 @@ package seng302.Mock; +import seng302.GPSCoordinate; + /** * Created by jjg64 on 19/04/17. */ @@ -96,4 +98,8 @@ public class Regatta { public void setMagneticVariation(float magneticVariation) { this.magneticVariation = magneticVariation; } + + public GPSCoordinate getGPSCoordinate() { + return new GPSCoordinate(centralLatitude, centralLongitude); + } } diff --git a/visualiser/src/main/java/seng302/Mock/RegattaXMLReader.java b/visualiser/src/main/java/seng302/Mock/RegattaXMLReader.java index 6291825f..6c9cc5f6 100644 --- a/visualiser/src/main/java/seng302/Mock/RegattaXMLReader.java +++ b/visualiser/src/main/java/seng302/Mock/RegattaXMLReader.java @@ -3,6 +3,7 @@ package seng302.Mock; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; +import seng302.RaceDataSource; import seng302.XMLReader; import javax.xml.parsers.ParserConfigurationException; diff --git a/visualiser/src/main/java/seng302/Mock/StreamedBoat.java b/visualiser/src/main/java/seng302/Mock/StreamedBoat.java new file mode 100644 index 00000000..0ff629a0 --- /dev/null +++ b/visualiser/src/main/java/seng302/Mock/StreamedBoat.java @@ -0,0 +1,44 @@ +package seng302.Mock; + +import javafx.scene.paint.Color; +import seng302.GPSCoordinate; +import seng302.Model.Boat; +import seng302.Model.BoatInRace; + +/** + * Created by Joseph on 24/04/2017. + */ +public class StreamedBoat extends BoatInRace { + private int sourceID; + private boolean complete; + + public StreamedBoat(int sourceID, String name, Color colour, String abbrev) { + super(name, colour, abbrev); + this.sourceID = sourceID; + this.complete = true; + } + + public StreamedBoat(int sourceID) { + super("None", Color.BLACK, "None"); + this.sourceID = sourceID; + this.complete = false; + } + + + /** + * Overridden to ignore this function + * @deprecated + * @return 0 + */ + public double getScaledVelocity() { + return 0; + } + + /** + * Overridden to ignore this function + * @deprecated + * @param velocity of boat + */ + public void setScaledVelocity(double velocity) { + } +} diff --git a/visualiser/src/main/java/seng302/Mock/StreamedCourse.java b/visualiser/src/main/java/seng302/Mock/StreamedCourse.java new file mode 100644 index 00000000..ebde5a4c --- /dev/null +++ b/visualiser/src/main/java/seng302/Mock/StreamedCourse.java @@ -0,0 +1,76 @@ +package seng302.Mock; + +import seng302.GPSCoordinate; +import seng302.Model.BoatInRace; +import seng302.Model.Leg; +import seng302.Model.RaceClock; +import seng302.RaceDataSource; + +import java.time.ZonedDateTime; +import java.util.*; + +/** + * Created by jjg64 on 21/04/17. + */ +public class StreamedCourse implements RaceDataSource { + StreamedCourseXMLReader streamedCourseXMLReader = null; + BoatXMLReader boatXMLReader = null; + RegattaXMLReader regattaXMLReader = null; + List boundary = new ArrayList<>(); + + public StreamedCourse(StreamedCourseXMLReader streamedCourseXMLReader) { + this.streamedCourseXMLReader = streamedCourseXMLReader; + } + + public StreamedCourse(BoatXMLReader boatXMLReader) { + this.boatXMLReader = boatXMLReader; + } + + public void setBoatXMLReader(BoatXMLReader boatXMLReader) { + this.boatXMLReader = boatXMLReader; + if (streamedCourseXMLReader != null) { + boatXMLReader.setParticipants(streamedCourseXMLReader.getParticipants()); + boatXMLReader.read(); + } + } + + public void setStreamedCourseXMLReader(StreamedCourseXMLReader streamedCourseXMLReader) { + this.streamedCourseXMLReader = streamedCourseXMLReader; + if (streamedCourseXMLReader != null) { + boatXMLReader.setParticipants(streamedCourseXMLReader.getParticipants()); + boatXMLReader.read(); + } + } + + public void setRegattaXMLReader(RegattaXMLReader regattaXMLReader) { + this.regattaXMLReader = regattaXMLReader; + } + + public RegattaXMLReader getRegattaXMLReader() { + return regattaXMLReader; + } + + public List getBoats() { + return new ArrayList<>(boatXMLReader.getStreamedBoatMap().values()); + } + + public List getLegs() { + return streamedCourseXMLReader.getLegs(); + } + + public List getBoundary() { + return streamedCourseXMLReader.getBoundary(); + } + + public ZonedDateTime getZonedDateTime() { + return RaceClock.getCurrentZonedDateTime(regattaXMLReader.getRegatta().getGPSCoordinate()); + } + + public GPSCoordinate getMapTopLeft() { + return streamedCourseXMLReader.getMapTopLeft(); + } + + public GPSCoordinate getMapBottomRight() { + return streamedCourseXMLReader.getMapBottomRight(); + } +} diff --git a/visualiser/src/main/java/seng302/Mock/StreamedCourseXMLException.java b/visualiser/src/main/java/seng302/Mock/StreamedCourseXMLException.java new file mode 100644 index 00000000..5bebaa09 --- /dev/null +++ b/visualiser/src/main/java/seng302/Mock/StreamedCourseXMLException.java @@ -0,0 +1,7 @@ +package seng302.Mock; + +/** + * Created by cbt24 on 25/04/17. + */ +public class StreamedCourseXMLException extends Throwable { +} diff --git a/visualiser/src/main/java/seng302/Mock/StreamedCourseXMLReader.java b/visualiser/src/main/java/seng302/Mock/StreamedCourseXMLReader.java new file mode 100644 index 00000000..8fe86835 --- /dev/null +++ b/visualiser/src/main/java/seng302/Mock/StreamedCourseXMLReader.java @@ -0,0 +1,239 @@ +package seng302.Mock; + +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; +import seng302.GPSCoordinate; +import seng302.Model.Leg; +import seng302.Model.Marker; +import seng302.XMLReader; + +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * Created by jjg64 on 21/04/17. + */ +public class StreamedCourseXMLReader extends XMLReader { + private static double COORDINATEPADDING = 0.0005; + private GPSCoordinate mapTopLeft, mapBottomRight; + private List boundary = new ArrayList<>(); + private Map marks = new HashMap<>(); + private Map participants = new HashMap<>(); + private List legs = new ArrayList<>(); + Date creationTimeDate; + Date raceStartTime; + int raceID; + String raceType; + boolean postpone; + + /** + * Constructor for Streamed Race XML + * @param filePath path of the file + * @throws IOException error + * @throws SAXException error + * @throws ParserConfigurationException error + */ + public StreamedCourseXMLReader(String filePath) throws IOException, SAXException, ParserConfigurationException, ParseException, StreamedCourseXMLException { + this(filePath, true); + } + + /** + * Constructor for Streamed Race XML + * @param filePath file path to read + * @param read whether or not to read and store the files straight away. + * @throws IOException error + * @throws SAXException error + * @throws ParserConfigurationException error + */ + public StreamedCourseXMLReader(String filePath, boolean read) throws IOException, SAXException, ParserConfigurationException, ParseException, StreamedCourseXMLException { + super(filePath); + if (read) { + read(); + } + } + + private void read() throws ParseException, StreamedCourseXMLException { + readRace(); + readParticipants(); + readCourse(); + } + + private void readRace() throws ParseException { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + Element settings = (Element) doc.getElementsByTagName("Race").item(0); + + raceID = Integer.parseInt(getTextValueOfNode(settings, "RaceID")); + raceType = getTextValueOfNode(settings, "RaceType"); + creationTimeDate = dateFormat.parse(getTextValueOfNode(settings, "CreationTimeDate")); + NamedNodeMap raceTimeTag = doc.getElementsByTagName("RaceStartTime").item(0).getAttributes(); + raceStartTime = dateFormat.parse(raceTimeTag.getNamedItem("Time").getTextContent()); + postpone = Boolean.parseBoolean(raceTimeTag.getNamedItem("Postpone").getTextContent()); + } + + private void readParticipants() { + Element nParticipants = (Element) doc.getElementsByTagName("Participants").item(0); + for (int i = 0; i < nParticipants.getChildNodes().getLength(); i++) { + int sourceID; + Node yacht = nParticipants.getChildNodes().item(i); + if (yacht.getNodeName().equals("Yacht")) { + if (exists(yacht, "SourceID")) { + sourceID = Integer.parseInt(yacht.getAttributes().getNamedItem("SourceID").getTextContent()); + participants.put(sourceID, new StreamedBoat(sourceID)); + } + } + } + } + + private void readCourse() throws StreamedCourseXMLException { + readCompoundMarks(); + readCompoundMarkSequence(); + readCourseLimit(); + } + + /** + * Indexes CompoundMark elements by their ID for use in generating the course. + */ + private void readCompoundMarks() { + Element nCourse = (Element) doc.getElementsByTagName("Course").item(0); + for(int i = 0; i < nCourse.getChildNodes().getLength(); i++) { + Node compoundMark = nCourse.getChildNodes().item(i); + if(compoundMark.getNodeName().equals("CompoundMark")) { + marks.put(getCompoundMarkID((Element)compoundMark),(Element)compoundMark); + } + } + } + + /** + * Generates a Marker from the CompoundMark element with given ID. + * @param compoundMarkID index of required CompoundMark element + * @return generated Marker + * @throws StreamedCourseXMLException if CompoundMark element contains unhandled number of marks + * @see seng302.Model.Marker + */ + private Marker getMarker(int compoundMarkID) throws StreamedCourseXMLException { + Element compoundMark = marks.get(compoundMarkID); + NodeList nMarks = compoundMark.getElementsByTagName("Mark"); + Marker marker; + + switch(nMarks.getLength()) { + case 1: marker = new Marker(getCoordinate((Element)nMarks.item(0))); break; + case 2: marker = new Marker(getCoordinate((Element)nMarks.item(0)), getCoordinate((Element)nMarks.item(1))); break; + default: throw new StreamedCourseXMLException(); + } + + return marker; + } + + private GPSCoordinate getCoordinate(Element mark) { + double lat = Double.parseDouble(mark.getAttribute("TargetLat")); + double lon = Double.parseDouble(mark.getAttribute("TargetLng")); + return new GPSCoordinate(lat,lon); + } + + /** + * Reads "compoundMarkID" attribute of CompoundMark or Corner element + * @param element with "compoundMarkID" attribute + * @return value of "compoundMarkID" attribute + */ + private int getCompoundMarkID(Element element) { + return Integer.parseInt(element.getAttribute("CompoundMarkID")); + } + + /** + * Reads "name" attribute of CompoundMark element with corresponding CompoundMarkID + * @param compoundMarkID unique ID for CompoundMark element + * @return value of "name" attribute + */ + private String getCompoundMarkName(int compoundMarkID) { + return marks.get(compoundMarkID).getAttribute("Name"); + } + + /** + * Populates list of legs given CompoundMarkSequence element and referenced CompoundMark elements. + * @throws StreamedCourseXMLException if markers cannot be resolved from CompoundMark + */ + private void readCompoundMarkSequence() throws StreamedCourseXMLException { + Element nCompoundMarkSequence = (Element) doc.getElementsByTagName("CompoundMarkSequence").item(0); + NodeList nCorners = nCompoundMarkSequence.getElementsByTagName("Corner"); + Marker lastMarker = getMarker(getCompoundMarkID((Element)nCorners.item(0))); + String legName = getCompoundMarkName(getCompoundMarkID((Element)nCorners.item(0))); + for(int i = 1; i < nCorners.getLength(); i++) { + Element markXML = (Element)nCorners.item(i); + Marker currentMarker = getMarker(getCompoundMarkID(markXML)); + legs.add(new Leg(legName, lastMarker, currentMarker, i-1)); + lastMarker = currentMarker; + legName = getCompoundMarkName(getCompoundMarkID(markXML)); + } + } + + private void readCourseLimit() { + Element nCourseLimit = (Element) doc.getElementsByTagName("CourseLimit").item(0); + for(int i = 0; i < nCourseLimit.getChildNodes().getLength(); i++) { + Node limit = nCourseLimit.getChildNodes().item(i); + if (limit.getNodeName().equals("Limit")) { + double lat = Double.parseDouble(limit.getAttributes().getNamedItem("Lat").getTextContent()); + double lon = Double.parseDouble(limit.getAttributes().getNamedItem("Lon").getTextContent()); + boundary.add(new GPSCoordinate(lat, lon)); + } + } + + double maxLatitude = boundary.stream().max(Comparator.comparingDouble(GPSCoordinate::getLatitude)).get().getLatitude() + COORDINATEPADDING; + double maxLongitude = boundary.stream().max(Comparator.comparingDouble(GPSCoordinate::getLongitude)).get().getLongitude() + COORDINATEPADDING; + double minLatitude = boundary.stream().min(Comparator.comparingDouble(GPSCoordinate::getLatitude)).get().getLatitude() + COORDINATEPADDING; + double minLongitude = boundary.stream().min(Comparator.comparingDouble(GPSCoordinate::getLongitude)).get().getLongitude() + COORDINATEPADDING; + + mapTopLeft = new GPSCoordinate(minLatitude, minLongitude); + mapBottomRight = new GPSCoordinate(maxLatitude, maxLongitude); + } + + public List getBoundary() { + return boundary; + } + + public GPSCoordinate getMapTopLeft() { + return mapTopLeft; + } + + public GPSCoordinate getMapBottomRight() { + return mapBottomRight; + } + + public List getLegs() { + return legs; + } + + public Double getPadding() { + return COORDINATEPADDING; + } + + public Date getCreationTimeDate() { + return creationTimeDate; + } + + public Date getRaceStartTime() { + return raceStartTime; + } + + public int getRaceID() { + return raceID; + } + + public String getRaceType() { + return raceType; + } + + public boolean isPostpone() { + return postpone; + } + + public Map getParticipants() { + return participants; + } +} diff --git a/visualiser/src/main/java/seng302/Mock/StreamedRace.java b/visualiser/src/main/java/seng302/Mock/StreamedRace.java new file mode 100644 index 00000000..56b6a114 --- /dev/null +++ b/visualiser/src/main/java/seng302/Mock/StreamedRace.java @@ -0,0 +1,56 @@ +package seng302.Mock; + +import javafx.collections.FXCollections; +import seng302.Controllers.RaceController; +import seng302.Model.BoatInRace; +import seng302.Model.Leg; +import seng302.Model.Race; +import seng302.RaceDataSource; + +import java.util.*; + +/** + * Created by jjg64 on 21/04/17. + */ +public class StreamedRace extends Race { + private RaceDataSource raceData; + + public StreamedRace(RaceDataSource raceData, RaceController controller, int scaleFactor) { + super(raceData.getBoats(), raceData.getLegs(), controller, scaleFactor); + this.raceData = raceData; + } + + public void initialiseBoats() { + + } + + /** + * Checks if the boat cannot finish the race + * @return True if boat cannot finish the race + */ + protected boolean doNotFinish() { + return false; + } + + /** + * Checks the position of the boat, this updates the boats current position. + * + * @param boat Boat that the postion is to be updated for. + * @param timeElapsed Time that has elapse since the start of the the race. + * @see BoatInRace + */ + protected void checkPosition(BoatInRace boat, long timeElapsed) { + + } + + /** + * Updates the boat's gps coordinates + * + * @param boat to be updated + * @param millisecondsElapsed time since last update + */ + protected void updatePosition(BoatInRace boat, int millisecondsElapsed) { + + } + +} diff --git a/visualiser/src/main/java/seng302/Model/Boat.java b/visualiser/src/main/java/seng302/Model/Boat.java index 49b5a0f9..a3e269d4 100644 --- a/visualiser/src/main/java/seng302/Model/Boat.java +++ b/visualiser/src/main/java/seng302/Model/Boat.java @@ -27,6 +27,17 @@ public class Boat { this.name = new SimpleStringProperty(name); } + /** + * Boat initialiser which keeps all of the information of the boat. + * + * @param name Name of the Boat. + * @param abbrev nam abbreviation + */ + public Boat(String name, String abbrev) { + this.abbrev = abbrev; + this.name = new SimpleStringProperty(name); + } + /** * @return Name of the boat */ diff --git a/visualiser/src/main/java/seng302/Model/BoatInRace.java b/visualiser/src/main/java/seng302/Model/BoatInRace.java index 520e7b06..6f835593 100644 --- a/visualiser/src/main/java/seng302/Model/BoatInRace.java +++ b/visualiser/src/main/java/seng302/Model/BoatInRace.java @@ -17,25 +17,25 @@ import java.util.concurrent.ConcurrentLinkedQueue; */ public class BoatInRace extends Boat { - private Leg currentLeg; + protected Leg currentLeg; private double scaledVelocity; - private double distanceTravelledInLeg; - private GPSCoordinate currentPosition; - private long timeFinished; - private Color colour; - private boolean finished = false; - private StringProperty currentLegName; - private boolean started = false; - private StringProperty position; - private double heading; - - private Queue track = new ConcurrentLinkedQueue<>(); - private long nextValidTime = 0; - - private static final float BASE_TRACK_POINT_TIME_INTERVAL = 5000; - private static float trackPointTimeInterval = 5000; // every 1 seconds - private final int TRACK_POINT_LIMIT = 10; - private boolean trackVisible = true; + protected double distanceTravelledInLeg; + protected GPSCoordinate currentPosition; + protected long timeFinished; + protected Color colour; + protected boolean finished = false; + protected StringProperty currentLegName; + protected boolean started = false; + protected StringProperty position; + protected double heading; + + protected Queue track = new ConcurrentLinkedQueue<>(); + protected long nextValidTime = 0; + + protected static final float BASE_TRACK_POINT_TIME_INTERVAL = 5000; + protected static float trackPointTimeInterval = 5000; // every 1 seconds + protected final int TRACK_POINT_LIMIT = 10; + protected boolean trackVisible = true; /** * Constructor method. @@ -52,6 +52,20 @@ public class BoatInRace extends Boat { position = new SimpleStringProperty("-"); } + /** + * Constructor method. + * + * @param name Name of the boat. + * @param colour Colour the boat will be displayed as on the map + * @param abbrev of boat + */ + public BoatInRace(String name, Color colour, String abbrev) { + super(name, abbrev); + setColour(colour); + currentLegName = new SimpleStringProperty(""); + position = new SimpleStringProperty("-"); + } + /** * Calculates the azimuth of the travel via map coordinates of the raceMarkers * diff --git a/visualiser/src/main/java/seng302/Model/Marker.java b/visualiser/src/main/java/seng302/Model/Marker.java index 2b7cafbe..118219f1 100644 --- a/visualiser/src/main/java/seng302/Model/Marker.java +++ b/visualiser/src/main/java/seng302/Model/Marker.java @@ -9,7 +9,6 @@ import java.awt.geom.Point2D; * Created by esa46 on 29/03/17. */ public class Marker { - private GPSCoordinate averageGPSCoordinate; private GPSCoordinate mark1; private GPSCoordinate mark2; diff --git a/visualiser/src/main/java/seng302/Model/Race.java b/visualiser/src/main/java/seng302/Model/Race.java index bfc1d518..c033c8a3 100644 --- a/visualiser/src/main/java/seng302/Model/Race.java +++ b/visualiser/src/main/java/seng302/Model/Race.java @@ -65,8 +65,8 @@ public abstract class Race implements Runnable { public abstract void initialiseBoats(); /** - * Randomly generate number to see if boat fails - * @return True if number lower than dnfChance else false + * Checks if the boat cannot finish the race + * @return True if boat cannot finish the race */ protected abstract boolean doNotFinish(); @@ -80,7 +80,7 @@ public abstract class Race implements Runnable { protected abstract void checkPosition(BoatInRace boat, long timeElapsed); /** - * Updates the boat's gps coordinates depending on time elapsed + * Updates the boat's gps coordinates * * @param boat to be updated * @param millisecondsElapsed time since last update diff --git a/visualiser/src/main/java/seng302/Model/RaceClock.java b/visualiser/src/main/java/seng302/Model/RaceClock.java index 6ea62bd3..3dfb5af5 100644 --- a/visualiser/src/main/java/seng302/Model/RaceClock.java +++ b/visualiser/src/main/java/seng302/Model/RaceClock.java @@ -6,48 +6,61 @@ import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import seng302.GPSCoordinate; +import java.time.Duration; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.time.temporal.TemporalAmount; /** * Created by Gondr on 19/04/2017. */ public class RaceClock { - private StringProperty time; - private DateTimeFormatter dateTimeFormatter; - private String timeZone; + private long lastTime; private ZoneId zoneId; + private ZonedDateTime time; + private StringProperty timeString; - public RaceClock(GPSCoordinate gpsCoordinate){ + public RaceClock(ZonedDateTime zonedDateTime) { + this.zoneId = zonedDateTime.getZone(); + this.timeString = new SimpleStringProperty(); + this.time = zonedDateTime; + setTime(time); + } + + public static ZonedDateTime getCurrentZonedDateTime(GPSCoordinate gpsCoordinate) { TimeZoneLookup timeZoneLookup = new TimeZoneLookup(); TimeZoneResult timeZoneResult = timeZoneLookup.getTimeZone(gpsCoordinate.getLatitude(), gpsCoordinate.getLongitude()); - zoneId = ZoneId.of(timeZoneResult.getResult()); - LocalDateTime localDateTime = LocalDateTime.now(zoneId); - ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId); - dateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM HH:mm:ss z"); - // System.out.println(dateTimeFormatter.format(zonedDateTime)); - time = new SimpleStringProperty(dateTimeFormatter.format(zonedDateTime)); - DateTimeFormatter timeZoneFormatter = DateTimeFormatter.ofPattern("z"); - timeZone = timeZoneFormatter.format(zonedDateTime); + ZoneId zone = ZoneId.of(timeZoneResult.getResult()); + return LocalDateTime.now(zone).atZone(zone); } - public void updateTime(){ - LocalDateTime localDateTime = LocalDateTime.now(zoneId); - ZonedDateTime zonedDateTime = localDateTime.atZone(zoneId); - time.setValue(dateTimeFormatter.format(zonedDateTime)); + /** + * Sets time to arbitrary zoned time. + * @param time arbitrary time with timezone. + */ + public void setTime(ZonedDateTime time) { + this.time = time; + this.timeString.set(DateTimeFormatter.ofPattern("dd-MM HH:mm:ss z").format(time)); + this.lastTime = System.currentTimeMillis(); } - public String getTime() { - return time.get(); + /** + * Updates time by duration elapsed since last update. + */ + public void updateTime() { + this.time = this.time.plus(Duration.of(System.currentTimeMillis() - this.lastTime, ChronoUnit.MILLIS)); + this.lastTime = System.currentTimeMillis(); + setTime(time); } - public StringProperty timeProperty() { - return time; + public String getTimeZone() { + return zoneId.toString(); } - public String getTimeZone() { - return timeZone; + public StringProperty timeStringProperty() { + return timeString; } } diff --git a/visualiser/src/main/java/seng302/Model/ResizableRaceCanvas.java b/visualiser/src/main/java/seng302/Model/ResizableRaceCanvas.java index da83b5f1..dd8287dc 100644 --- a/visualiser/src/main/java/seng302/Model/ResizableRaceCanvas.java +++ b/visualiser/src/main/java/seng302/Model/ResizableRaceCanvas.java @@ -318,6 +318,8 @@ public class ResizableRaceCanvas extends Canvas { * Draws boats while race in progress, when leg heading is set. */ public void updateBoats() { + // TODO Remove null when boats are ready + boats = null; if (boats != null) { for (BoatInRace boat : boats) { boolean finished = boat.getCurrentLeg().getName().equals("Finish") || boat.getCurrentLeg().getName().equals("DNF"); diff --git a/visualiser/src/main/java/seng302/RaceDataSource.java b/visualiser/src/main/java/seng302/RaceDataSource.java index 2f562766..82d30b73 100644 --- a/visualiser/src/main/java/seng302/RaceDataSource.java +++ b/visualiser/src/main/java/seng302/RaceDataSource.java @@ -3,6 +3,7 @@ package seng302; import seng302.Model.BoatInRace; import seng302.Model.Leg; +import java.time.ZonedDateTime; import java.util.List; /** @@ -13,7 +14,7 @@ public interface RaceDataSource { List getLegs(); List getBoundary(); - GPSCoordinate getMark(); + ZonedDateTime getZonedDateTime(); GPSCoordinate getMapTopLeft(); GPSCoordinate getMapBottomRight(); } diff --git a/visualiser/src/main/java/seng302/RaceXMLReader.java b/visualiser/src/main/java/seng302/RaceXMLReader.java index f10da6ef..14244417 100644 --- a/visualiser/src/main/java/seng302/RaceXMLReader.java +++ b/visualiser/src/main/java/seng302/RaceXMLReader.java @@ -4,12 +4,11 @@ import javafx.scene.paint.Color; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; -import seng302.Model.BoatInRace; -import seng302.Model.Leg; -import seng302.Model.Marker; +import seng302.Model.*; import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; +import java.time.ZonedDateTime; import java.util.ArrayList; import java.util.List; @@ -272,8 +271,8 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource { return legs; } - public GPSCoordinate getMark() { - return mark; + public ZonedDateTime getZonedDateTime() { + return RaceClock.getCurrentZonedDateTime(mark); } public GPSCoordinate getStartPt1() { diff --git a/visualiser/src/main/java/seng302/XMLReader.java b/visualiser/src/main/java/seng302/XMLReader.java index 810096d3..62aaea2b 100644 --- a/visualiser/src/main/java/seng302/XMLReader.java +++ b/visualiser/src/main/java/seng302/XMLReader.java @@ -2,6 +2,7 @@ package seng302; import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.Node; import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilder; @@ -33,6 +34,10 @@ public abstract class XMLReader { return n.getElementsByTagName(tagName).item(0).getTextContent(); } + public boolean exists(Node node, String attribute) { + return node.getAttributes().getNamedItem(attribute) != null; + } + public String getAttribute(Element n, String attr) { return n.getAttribute(attr); } diff --git a/visualiser/src/main/resources/mockXML/boatXML/boatTest.xml b/visualiser/src/main/resources/mockXML/boatXML/boatTest.xml new file mode 100644 index 00000000..738502a5 --- /dev/null +++ b/visualiser/src/main/resources/mockXML/boatXML/boatTest.xml @@ -0,0 +1,251 @@ + + + + + 2012-05-17T07:49:40+0200 + + 12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/src/main/resources/mockXML/raceXML/raceTest.xml b/visualiser/src/main/resources/mockXML/raceXML/raceTest.xml new file mode 100644 index 00000000..64f644dd --- /dev/null +++ b/visualiser/src/main/resources/mockXML/raceXML/raceTest.xml @@ -0,0 +1,91 @@ + + + + + 11080703 + + Match + + 2011-08-06T13:25:00-0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/src/main/resources/mockXML/regattaXML/regattaTest.xml b/visualiser/src/main/resources/mockXML/regattaXML/regattaTest.xml new file mode 100644 index 00000000..9ec88ccc --- /dev/null +++ b/visualiser/src/main/resources/mockXML/regattaXML/regattaTest.xml @@ -0,0 +1,20 @@ + + + + 3 + + New Zealand Test + + North Head + + -36.82791529 + + 174.81218919 + + 0.00 + + 12 + + 14.1 + + \ No newline at end of file diff --git a/visualiser/src/test/java/seng302/Mock/BoatsXMLTest.java b/visualiser/src/test/java/seng302/Mock/BoatsXMLTest.java new file mode 100644 index 00000000..af025e6d --- /dev/null +++ b/visualiser/src/test/java/seng302/Mock/BoatsXMLTest.java @@ -0,0 +1,49 @@ +package seng302.Mock; + +import org.junit.Before; +import org.junit.Test; +import org.xml.sax.SAXException; + +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.text.ParseException; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * Created by jjg64 on 21/04/17. + */ +public class BoatsXMLTest { + BoatXMLReader boatXMLReader; + + @Before + public void setup() { + try { + boatXMLReader = new BoatXMLReader("mockXML/boatXML/boatTest.xml", false); + } catch (Exception e) { + e.printStackTrace(); + //fail("Cannot find mockXML/raceXML/raceTest.xml in the resources folder"); + } + } + + @Test + public void testInvalidParticipant() { + Map inputParticipants = new HashMap<>(); + inputParticipants.put(420, new StreamedBoat(420)); + boatXMLReader.setParticipants(inputParticipants); + boatXMLReader.read(); + assertEquals(boatXMLReader.getStreamedBoatMap().size(), 0); + } + + @Test + public void testValidParticipant() { + Map inputParticipants = new HashMap<>(); + inputParticipants.put(101, new StreamedBoat(101)); + boatXMLReader.setParticipants(inputParticipants); + boatXMLReader.read(); + assertTrue(boatXMLReader.getStreamedBoatMap().containsKey(101)); + } +} diff --git a/visualiser/src/test/java/seng302/Mock/RegattaXMLTest.java b/visualiser/src/test/java/seng302/Mock/RegattaXMLTest.java index 821e476b..efc54a09 100644 --- a/visualiser/src/test/java/seng302/Mock/RegattaXMLTest.java +++ b/visualiser/src/test/java/seng302/Mock/RegattaXMLTest.java @@ -16,7 +16,7 @@ public class RegattaXMLTest { @Before public void findFile(){ try { - regattaXMLReader = new RegattaXMLReader("mockXML/regattaXML/regattaTest.xml", false); + regattaXMLReader = new RegattaXMLReader("mockXML/regattaXML/regattaTest.xml"); } catch (Exception e) { fail("Cannot find mockXML/regattaXML/regattaTest.xml in the resources folder"); } @@ -24,29 +24,19 @@ public class RegattaXMLTest { @Test public void makeRegattaTest() { - try { - regattaXMLReader = new RegattaXMLReader("mockXML/regattaXML/regattaTest.xml"); - assertNotEquals(regattaXMLReader.getRegatta(), null); - } catch (Exception e) { - fail("Did not make a Regatta object"); - } + assertNotEquals(regattaXMLReader.getRegatta(), null); } @Test public void correctValuesTest() { - try { - regattaXMLReader = new RegattaXMLReader("mockXML/regattaXML/regattaTest.xml"); - Regatta regatta = regattaXMLReader.getRegatta(); - assertEquals(regatta.getRegattaID(), 3); - assertEquals(regatta.getRegattaName(), "New Zealand Test"); - assertEquals(regatta.getCourseName(), "North Head"); - assertEquals(regatta.getCentralLatitude(), -36.82791529, 0.00000001); - assertEquals(regatta.getCentralLongitude(), 174.81218919, 0.00000001); - assertEquals(regatta.getCentralAltitude(), 0.00, 0.00000001); - assertEquals(regatta.getUtcOffset(), 12.0, 0.001); - assertEquals(regatta.getMagneticVariation(), 14.1, 0.001); - } catch (Exception e) { - fail("Did not have the correct values"); - } + Regatta regatta = regattaXMLReader.getRegatta(); + assertEquals(regatta.getRegattaID(), 3); + assertEquals(regatta.getRegattaName(), "New Zealand Test"); + assertEquals(regatta.getCourseName(), "North Head"); + assertEquals(regatta.getCentralLatitude(), -36.82791529, 0.00000001); + assertEquals(regatta.getCentralLongitude(), 174.81218919, 0.00000001); + assertEquals(regatta.getCentralAltitude(), 0.00, 0.00000001); + assertEquals(regatta.getUtcOffset(), 12.0, 0.001); + assertEquals(regatta.getMagneticVariation(), 14.1, 0.001); } } diff --git a/visualiser/src/test/java/seng302/Mock/StreamedRaceTest.java b/visualiser/src/test/java/seng302/Mock/StreamedRaceTest.java new file mode 100644 index 00000000..c7ddb3d3 --- /dev/null +++ b/visualiser/src/test/java/seng302/Mock/StreamedRaceTest.java @@ -0,0 +1,78 @@ +package seng302.Mock; + +import org.junit.Before; +import org.junit.Test; +import seng302.GPSCoordinate; +import seng302.Model.Leg; + +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +/** + * Tests only work on the current version of mockXML/raceXML/raceTest.xml + */ +public class StreamedRaceTest { + StreamedCourseXMLReader streamedCourseXMLReader; + List boundary; + + @Before + public void setup() { + try { + streamedCourseXMLReader = new StreamedCourseXMLReader("mockXML/raceXML/raceTest.xml", true); + boundary = streamedCourseXMLReader.getBoundary(); + } catch (Exception e) { + e.printStackTrace(); + //fail("Cannot find mockXML/raceXML/raceTest.xml in the resources folder"); + } catch (StreamedCourseXMLException e) { + e.printStackTrace(); + } + } + + @Test + public void testAllBoundaryPointsRead() { + assertEquals(boundary.size(), 10); + } + + @Test + public void testBoundaryPointData() { + // First point + assertEquals(boundary.get(0).getLatitude(), -36.8325, 1e-6); + assertEquals(boundary.get(0).getLongitude(), 174.8325, 1e-6); + + // Last point + assertEquals(boundary.get(boundary.size() - 1).getLatitude(), -36.83417, 1e-6); + assertEquals(boundary.get(boundary.size() - 1).getLongitude(), 174.84767, 1e-6); + } + + @Test + public void testMapEdges() { + double maxLatitude = streamedCourseXMLReader.getMapBottomRight().getLatitude() - streamedCourseXMLReader.getPadding(); + double maxLongitude = streamedCourseXMLReader.getMapBottomRight().getLongitude() - streamedCourseXMLReader.getPadding(); + double minLatitude = streamedCourseXMLReader.getMapTopLeft().getLatitude() - streamedCourseXMLReader.getPadding(); + double minLongitude = streamedCourseXMLReader.getMapTopLeft().getLongitude() - streamedCourseXMLReader.getPadding(); + + assertEquals(maxLatitude, -36.81033, 1e-6); + assertEquals(maxLongitude, 174.88217, 1e-6); + assertEquals(minLatitude, -36.83417, 1e-6); + assertEquals(minLongitude, 174.81983, 1e-6); + } + + @Test + public void testRaceSettings() { + + } + + @Test + public void correctLegSequence() { + List legs = streamedCourseXMLReader.getLegs(); + String[] expectedNames = { + "StartLine", + "M1", + "M2", + "Gate" + }; + for(int i = 0; i < legs.size(); i++) assertEquals(expectedNames[i], legs.get(i).getName()); + } +} diff --git a/visualiser/src/test/java/seng302/Model/RaceTest.java b/visualiser/src/test/java/seng302/Model/RaceTest.java index 859e74e6..79024843 100644 --- a/visualiser/src/test/java/seng302/Model/RaceTest.java +++ b/visualiser/src/test/java/seng302/Model/RaceTest.java @@ -1,173 +1,18 @@ package seng302.Model; -import javafx.scene.paint.Color; +import org.junit.Before; import org.junit.Ignore; import org.junit.Test; -import seng302.GPSCoordinate; - -import java.util.ArrayList; -import java.util.Arrays; +import org.mockito.Mock; +import seng302.RaceDataSource; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.*; /** * Created by esa46 on 15/03/17. */ public class RaceTest { - Leg START_LEG = new Leg("Start", new Marker(new GPSCoordinate(0, 0)), new Marker(new GPSCoordinate(1, 1)), 0); - Leg FINISH_LEG = new Leg("Finish", new Marker(new GPSCoordinate(1, 1)), new Marker(new GPSCoordinate(2, 2)), 0); - - @Ignore - @Test - public void timerCanBeDisabled() { - BoatInRace boat1 = new BoatInRace("Test 1", 10000, Color.ALICEBLUE, "t1"); - BoatInRace boat2 = new BoatInRace("Test 2", 10000, Color.BURLYWOOD, "t2"); - BoatInRace[] boats = new BoatInRace[]{boat1, boat2}; - - ArrayList legs = new ArrayList<>(); - legs.add(START_LEG); legs.add(FINISH_LEG); - - ConstantVelocityRace race = new ConstantVelocityRace(boats, legs, null, 5); - race.disableTimer(); - race.setDnfChance(0); - long timeStarted = System.currentTimeMillis(); - race.run(); - - assertTrue(System.currentTimeMillis() - timeStarted < 4000); - } - - @Test - public void checkPositionUpdatesNumberFinishedBoats() { - - BoatInRace finishedBoat = new BoatInRace("Test", 1000, Color.ALICEBLUE, "tt"); - finishedBoat.setDistanceTravelledInLeg(500); - - finishedBoat.setCurrentLeg(FINISH_LEG); - - ArrayList legs = new ArrayList<>(); - legs.add(FINISH_LEG); - - ConstantVelocityRace race = new ConstantVelocityRace(new BoatInRace[1], legs, null, 1); - race.setDnfChance(0); - assertEquals(race.boatsFinished, 0); - - - race.checkPosition(finishedBoat, 100000); - assertEquals(race.boatsFinished, 1); - assertEquals(finishedBoat.getTimeFinished(), 100000); - } - - @Test - public void checkPositionDoesntUpdateNumberFinishedBoats() { - - BoatInRace unFinishedBoat = new BoatInRace("Test", 10, Color.ALICEBLUE, "tt"); - unFinishedBoat.setDistanceTravelledInLeg(0); - - unFinishedBoat.setCurrentLeg(FINISH_LEG); - - ArrayList legs = new ArrayList<>(); - legs.add(FINISH_LEG); - - ConstantVelocityRace race = new ConstantVelocityRace(new BoatInRace[1], legs, null, 1); - race.setDnfChance(0); - assertEquals(race.boatsFinished, 0); - - race.checkPosition(unFinishedBoat, 100); - assertEquals(race.boatsFinished, 0); - } - - @Test - public void distanceTravelledBeforeUpdatingLegIsRetained() { - - ArrayList legs = new ArrayList<>(); - - - legs.add(START_LEG); - legs.add(FINISH_LEG); - - ConstantVelocityRace race = new ConstantVelocityRace(new BoatInRace[1], legs, null, 1); - race.setDnfChance(0); - - BoatInRace unFinishedBoat = new BoatInRace("Test", 10, Color.ALICEBLUE, "tt"); - unFinishedBoat.setDistanceTravelledInLeg(100); - unFinishedBoat.setCurrentLeg(START_LEG); - - race.checkPosition(unFinishedBoat, 100); - assertEquals(unFinishedBoat.getCurrentLeg().getName(), "Finish"); - assertTrue(unFinishedBoat.getDistanceTravelledInLeg() > 0); - assertTrue(unFinishedBoat.getDistanceTravelledInLeg() < 100); - - } - - /*@Test - - //Test temporarily removed as countdown timer now uses animation timer - - public void timerDelaysByHalfSecond() { - - ArrayList legs = new ArrayList<>(); - legs.add(START_LEG); - - ConstantVelocityRace race = new ConstantVelocityRace(new BoatInRace[1], legs, null, 1); - race.PRERACE_TIME = 500; - - long timeStarted = System.currentTimeMillis(); - race.countdownTimer(); - - //assertTrue(System.currentTimeMillis() - timeStarted > 500); - System.out.println(System.currentTimeMillis() - timeStarted); - - }*/ - - @Test - public void scalerScalesVelocityCorrectly() { - - int scaleFactor = 3; - float vel1 = 0; - float vel2 = (float) 1.999; - float vel3 = (float) 32.5; - float vel4 = 500; - BoatInRace boat1 = new BoatInRace("test", vel1, Color.ALICEBLUE, "tt"); - BoatInRace boat2 = new BoatInRace("test", vel2, Color.ALICEBLUE, "tt"); - BoatInRace boat3 = new BoatInRace("test", vel3, Color.ALICEBLUE, "tt"); - BoatInRace boat4 = new BoatInRace("test", vel4, Color.ALICEBLUE, "tt"); - BoatInRace[] boats = new BoatInRace[]{boat1, boat2, boat3, boat4}; - - ArrayList legs = new ArrayList<>(); - legs.add(START_LEG); - - ConstantVelocityRace race = new ConstantVelocityRace(boats, legs, null, scaleFactor); - race.setDnfChance(0); - - assertEquals(race.getStartingBoats().get(0).getScaledVelocity(), vel1 * scaleFactor, 1e-6); - assertEquals(race.getStartingBoats().get(1).getScaledVelocity(), vel2 * scaleFactor, 1e-6); - assertEquals(race.getStartingBoats().get(2).getScaledVelocity(), vel3 * scaleFactor, 1e-6); - assertEquals(race.getStartingBoats().get(3).getScaledVelocity(), vel4 * scaleFactor, 1e-6); - } - - @Test - public void scalerScalesRaceClockTo1MinCorrectly() { - int scaleFactor = 10; - - ArrayList legs = new ArrayList<>(); - legs.add(START_LEG); - - ConstantVelocityRace race = new ConstantVelocityRace(new BoatInRace[5], legs, null, scaleFactor); - race.totalTimeElapsed = 6000; //6 seconds - assertTrue(race.calcTimer().equals("Race clock: 00:01:00")); - } - - @Test - public void scalerScalesRaceClockHoursMinutesAndSecondsCorrectly() { - int scaleFactor = 3; - ArrayList legs = new ArrayList<>(); - legs.add(START_LEG); - - ConstantVelocityRace race = new ConstantVelocityRace(new BoatInRace[5], legs, null, scaleFactor); - race.totalTimeElapsed = 3213000; - assertTrue(race.calcTimer().equals("Race clock: 02:40:39")); - - } } diff --git a/visualiser/src/test/java/seng302/Model/RaceXMLTest.java b/visualiser/src/test/java/seng302/Model/RaceXMLTest.java index e53c9085..618f2ff4 100644 --- a/visualiser/src/test/java/seng302/Model/RaceXMLTest.java +++ b/visualiser/src/test/java/seng302/Model/RaceXMLTest.java @@ -86,7 +86,6 @@ public class RaceXMLTest { assertTrue(raceXMLReader.getLeewardPt2() != null); assertTrue(raceXMLReader.getWindwardPt1() != null); assertTrue(raceXMLReader.getWindwardPt2() != null); - assertTrue(raceXMLReader.getMark() != null); assertTrue(raceXMLReader.getBoundary().size() == 11); } catch (Exception e) { e.printStackTrace(); diff --git a/visualiser/src/test/resources/mockXML/boatXML/boatTest.xml b/visualiser/src/test/resources/mockXML/boatXML/boatTest.xml new file mode 100644 index 00000000..738502a5 --- /dev/null +++ b/visualiser/src/test/resources/mockXML/boatXML/boatTest.xml @@ -0,0 +1,251 @@ + + + + + 2012-05-17T07:49:40+0200 + + 12 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/visualiser/src/test/resources/mockXML/raceXML/raceTest.xml b/visualiser/src/test/resources/mockXML/raceXML/raceTest.xml new file mode 100644 index 00000000..8c19df9a --- /dev/null +++ b/visualiser/src/test/resources/mockXML/raceXML/raceTest.xml @@ -0,0 +1,91 @@ + + + + + 11080703 + + Match + + 2011-08-06T13:25:00-0000 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file