Merge branch 'splitIntoTwoModules' into visualiserAndDataLink

# Conflicts:
#	visualiser/src/main/java/seng302/Model/ResizableRaceCanvas.java
main
Joseph Gardner 9 years ago
commit 3d284c4a2b

@ -6,6 +6,7 @@ import seng302.Model.BoatInRace;
/**
* Constants that are used throughout the program
* Created by Erika on 19-Mar-17.
* @deprecated please use XML for constant data
*/
public class Constants {

@ -125,7 +125,6 @@ public class RaceController extends Controller {
raceMap.widthProperty().bind(canvasBase.widthProperty());
raceMap.heightProperty().bind(canvasBase.heightProperty());
//raceMap.setBoats(newRace.getStartingBoats());
raceMap.setRaceBoundaries(raceData.getBoundary());
raceMap.drawRaceMap();
raceMap.setVisible(true);

@ -3,6 +3,7 @@ package seng302.Mock;
import seng302.GPSCoordinate;
import seng302.Model.BoatInRace;
import seng302.Model.Leg;
import seng302.Model.Marker;
import seng302.Model.RaceClock;
import seng302.RaceDataSource;
@ -58,12 +59,14 @@ public class StreamedCourse implements RaceDataSource {
return streamedCourseXMLReader.getLegs();
}
public List<Marker> getMarkers() { return streamedCourseXMLReader.getMarkers(); }
public List<GPSCoordinate> getBoundary() {
return streamedCourseXMLReader.getBoundary();
}
public ZonedDateTime getZonedDateTime() {
return RaceClock.getCurrentZonedDateTime(regattaXMLReader.getRegatta().getGPSCoordinate());
return streamedCourseXMLReader.getRaceStartTime();
}
public GPSCoordinate getMapTopLeft() {

@ -1,5 +1,6 @@
package seng302.Mock;
import org.joda.time.DateTime;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
@ -15,20 +16,23 @@ import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
/**
* Created by jjg64 on 21/04/17.
*/
public class StreamedCourseXMLReader extends XMLReader {
private static double COORDINATEPADDING = 0.0005;
private static double COORDINATEPADDING = 0.000;
private GPSCoordinate mapTopLeft, mapBottomRight;
private List<GPSCoordinate> boundary = new ArrayList<>();
private Map<Integer,Element> marks = new HashMap<>();
private Map<Integer,Element> compoundMarks = new HashMap<>();
private Map<Integer, StreamedBoat> participants = new HashMap<>();
private List<Leg> legs = new ArrayList<>();
Date creationTimeDate;
Date raceStartTime;
private List<Marker> markers = new ArrayList<>();
ZonedDateTime creationTimeDate;
ZonedDateTime raceStartTime;
int raceID;
String raceType;
boolean postpone;
@ -66,14 +70,14 @@ public class StreamedCourseXMLReader extends XMLReader {
}
private void readRace() throws ParseException {
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("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"));
creationTimeDate = ZonedDateTime.parse(getTextValueOfNode(settings, "CreationTimeDate"), dateFormat);
NamedNodeMap raceTimeTag = doc.getElementsByTagName("RaceStartTime").item(0).getAttributes();
raceStartTime = dateFormat.parse(raceTimeTag.getNamedItem("Time").getTextContent());
raceStartTime = ZonedDateTime.parse(raceTimeTag.getNamedItem("Time").getTextContent(), dateFormat);
postpone = Boolean.parseBoolean(raceTimeTag.getNamedItem("Postpone").getTextContent());
}
@ -98,14 +102,17 @@ public class StreamedCourseXMLReader extends XMLReader {
}
/**
* Indexes CompoundMark elements by their ID for use in generating the course.
* Indexes CompoundMark elements by their ID for use in generating the course, and populates list of Markers.
* @see seng302.Model.Marker
*/
private void readCompoundMarks() {
private void readCompoundMarks() throws StreamedCourseXMLException {
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);
int compoundMarkID = getCompoundMarkID((Element) compoundMark);
compoundMarks.put(compoundMarkID, (Element)compoundMark);
markers.add(getMarker(compoundMarkID));
}
}
}
@ -114,11 +121,11 @@ public class StreamedCourseXMLReader extends XMLReader {
* 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
* @throws StreamedCourseXMLException if CompoundMark element contains unhandled number of compoundMarks
* @see seng302.Model.Marker
*/
private Marker getMarker(int compoundMarkID) throws StreamedCourseXMLException {
Element compoundMark = marks.get(compoundMarkID);
Element compoundMark = compoundMarks.get(compoundMarkID);
NodeList nMarks = compoundMark.getElementsByTagName("Mark");
Marker marker;
@ -152,7 +159,7 @@ public class StreamedCourseXMLReader extends XMLReader {
* @return value of "name" attribute
*/
private String getCompoundMarkName(int compoundMarkID) {
return marks.get(compoundMarkID).getAttribute("Name");
return compoundMarks.get(compoundMarkID).getAttribute("Name");
}
/**
@ -184,6 +191,7 @@ public class StreamedCourseXMLReader extends XMLReader {
}
}
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;
@ -209,15 +217,17 @@ public class StreamedCourseXMLReader extends XMLReader {
return legs;
}
public List<Marker> getMarkers() { return markers; }
public Double getPadding() {
return COORDINATEPADDING;
}
public Date getCreationTimeDate() {
public ZonedDateTime getCreationTimeDate() {
return creationTimeDate;
}
public Date getRaceStartTime() {
public ZonedDateTime getRaceStartTime() {
return raceStartTime;
}

@ -37,6 +37,14 @@ public class Marker {
return mark2;
}
/**
* Returns true if mark consists of two points, e.g. it is a gate.
* @return boolean
*/
public boolean isCompoundMark() {
return mark1 != mark2;
}
public GPSCoordinate getAverageGPSCoordinate() {
return averageGPSCoordinate;
}

@ -43,7 +43,7 @@ public class RaceClock {
*/
public void setTime(ZonedDateTime time) {
this.time = time;
this.timeString.set(DateTimeFormatter.ofPattern("dd-MM HH:mm:ss z").format(time));
this.timeString.set(DateTimeFormatter.ofPattern("HH:mm:ss dd/MM/YYYY Z").format(time));
this.lastTime = System.currentTimeMillis();
}

@ -22,13 +22,13 @@ public class ResizableRaceCanvas extends Canvas {
private GraphicsContext gc;
private RaceMap map;
private List<BoatInRace> boats;
private RaceDataSource raceData;
private boolean raceAnno = true;
private boolean annoName = true;
private boolean annoAbbrev = true;
private boolean annoSpeed = true;
private boolean annoPath = true;
private ArrayList<GPSCoordinate> raceBoundaries;
private List<GPSCoordinate> raceBoundaries;
private List<Marker> markers;
double[] xpoints = {}, ypoints = {};
public ResizableRaceCanvas(RaceDataSource raceData) {
@ -41,9 +41,11 @@ public class ResizableRaceCanvas extends Canvas {
double long1 = raceData.getMapTopLeft().getLongitude();
double lat2 = raceData.getMapBottomRight().getLatitude();
double long2 = raceData.getMapBottomRight().getLongitude();
setMap(new RaceMap(lat1, long1, lat2, long2, (int) getWidth(), (int) getHeight()));
this.raceData = raceData;
this.raceBoundaries = raceData.getBoundary();
this.markers = raceData.getMarkers();
}
/**
@ -209,6 +211,22 @@ public class ResizableRaceCanvas extends Canvas {
gc.fillPolygon(xpoints, ypoints, xpoints.length);
}
/**
* Draw race markers
*/
public void drawMarkers() {
for(Marker marker: markers) {
GraphCoordinate mark1 = this.map.convertGPS(marker.getMark1());
if(marker.isCompoundMark()) {
GraphCoordinate mark2 = this.map.convertGPS(marker.getMark2());
// TODO - improve colour coding of markers
displayLine(mark1, mark2, Color.GREEN);
} else {
displayPoint(mark1, Color.GREEN);
}
}
}
/**
* Draws the Race Map
*/
@ -225,67 +243,16 @@ public class ResizableRaceCanvas extends Canvas {
this.map.setHeight((int) height);
this.map.setWidth((int) width);
//finish line
gc.setLineWidth(2);
drawBoundaries();
drawPoints();
drawMarkers();
updateBoats();
//display wind direction arrow - specify origin point and angle - angle now set to random angle
displayArrow(new GraphCoordinate((int) getWidth() - 40, 40), 150);
}
private void drawPoints() {
// GraphCoordinate finishLineCoord1 = this.map.convertGPS(Constants.finishLineMarker1);
// GraphCoordinate finishLineCoord2 = this.map.convertGPS(Constants.finishLineMarker2);
// displayLine(finishLineCoord1, finishLineCoord2, Color.DARKRED);
// //marks
// GraphCoordinate markCoord = this.map.convertGPS(Constants.mark1);
// GraphCoordinate windwardGate1 = this.map.convertGPS(Constants.windwardGate1);
// GraphCoordinate windwardGate2 = this.map.convertGPS(Constants.windwardGate2);
// GraphCoordinate leewardGate1 = this.map.convertGPS(Constants.leewardGate1);
// GraphCoordinate leewardGate2 = this.map.convertGPS(Constants.leewardGate2);
// displayMark(markCoord, Color.GOLD);
// displayLine(windwardGate1, windwardGate2, Color.DARKCYAN);
// displayLine(leewardGate1, leewardGate2, Color.DARKVIOLET);
// //start line
// GraphCoordinate startline1 = this.map.convertGPS(Constants.startLineMarker1);
// GraphCoordinate startline2 = this.map.convertGPS(Constants.startLineMarker2);
//
// displayLine(startline1, startline2, Color.GREEN);
for (Leg leg : raceData.getLegs()) {
boolean hasStart = false;
boolean hasEnd = false;
GraphCoordinate start1 = null;
GraphCoordinate start2 = null;
GraphCoordinate end1 = null;
GraphCoordinate end2 = null;
String legName = leg.getName().toLowerCase();
if (leg.getStartMarker() != null) {
start1 = this.map.convertGPS(leg.getStartMarker().getMark1());
start2 = this.map.convertGPS(leg.getStartMarker().getMark2());
hasStart = true;
} if (leg.getEndMarker() != null) {
end1 = this.map.convertGPS(leg.getEndMarker().getMark1());
end2 = this.map.convertGPS(leg.getEndMarker().getMark2());
hasEnd = true;
}
if (legName.contains("line") || legName.contains("gate")) {
if (hasStart && start1 != null && start2 != null) displayLine(start1, start2, Color.BLACK);
if (hasEnd && start1 != null && start2 != null) displayLine(end1, end2, Color.BLACK);
} else if (hasStart && start1 != null && start2 != null) {
if (legName.contains("start")) displayLine(start1, start2, Color.BLACK);
else displayMark(start1, Color.BLACK);
}
else if (hasEnd && end1 != null && end2 != null) {
if (legName.contains("finish")) displayLine(end1, end2, Color.BLACK);
else displayMark(end1, Color.BLACK);
}
}
}
/**
* Draws a boat at a certain GPSCoordinate
*
@ -356,7 +323,7 @@ public class ResizableRaceCanvas extends Canvas {
*/
public void updateBoats() {
// TODO Remove null when boats are ready
//boats = null;
boats = null;
if (boats != null) {
for (BoatInRace boat : boats) {
boolean finished = boat.getCurrentLeg().getName().equals("Finish") || boat.getCurrentLeg().getName().equals("DNF");

@ -2,6 +2,7 @@ package seng302;
import seng302.Model.BoatInRace;
import seng302.Model.Leg;
import seng302.Model.Marker;
import java.time.ZonedDateTime;
import java.util.List;
@ -12,6 +13,7 @@ import java.util.List;
public interface RaceDataSource {
List<BoatInRace> getBoats();
List<Leg> getLegs();
List<Marker> getMarkers();
List<GPSCoordinate> getBoundary();
ZonedDateTime getZonedDateTime();

@ -14,6 +14,7 @@ import java.util.List;
/**
* Created by fwy13 on 26/03/2017.
* @deprecated use {@link seng302.Mock.StreamedCourseXMLReader}
*/
public class RaceXMLReader extends XMLReader implements RaceDataSource {
private List<BoatInRace> boats = new ArrayList<>();
@ -263,6 +264,11 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource {
return new GPSCoordinate(startLat, startLong);
}
@Override
public List<Marker> getMarkers() {
return null;
}
public List<BoatInRace> getBoats() {
return boats;
}

@ -1,13 +1,16 @@
package seng302.Mock;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import seng302.GPSCoordinate;
import seng302.Model.Leg;
import seng302.Model.Marker;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
@ -75,4 +78,21 @@ public class StreamedRaceTest {
};
for(int i = 0; i < legs.size(); i++) assertEquals(expectedNames[i], legs.get(i).getName());
}
/**
* raceTest.xml is not compliant with this test. Markers are positioned far out of bounds.
*/
@Test
public void markersWithinRaceBoundaries() {
GPSCoordinate topLeft = streamedCourseXMLReader.getMapTopLeft();
GPSCoordinate bottomRight = streamedCourseXMLReader.getMapBottomRight();
for(Marker marker: streamedCourseXMLReader.getMarkers()) {
GPSCoordinate centre = marker.getAverageGPSCoordinate();
assertTrue(centre.getLatitude() < bottomRight.getLatitude());
assertTrue(centre.getLatitude() > topLeft.getLatitude());
assertTrue(centre.getLongitude() > bottomRight.getLongitude());
assertTrue(centre.getLongitude() < topLeft.getLongitude());
}
}
}

Loading…
Cancel
Save