Implemented marker visualisation from XML in ResizableRaceCanvas
- Replaced and deprecated Constants - Added getMarkers to RaceDataSource interface - Added boundary testing for source data #story[782]
This commit is contained in:
@@ -6,6 +6,7 @@ import seng302.Model.BoatInRace;
|
|||||||
/**
|
/**
|
||||||
* Constants that are used throughout the program
|
* Constants that are used throughout the program
|
||||||
* Created by Erika on 19-Mar-17.
|
* Created by Erika on 19-Mar-17.
|
||||||
|
* @deprecated please use XML for constant data
|
||||||
*/
|
*/
|
||||||
public class Constants {
|
public class Constants {
|
||||||
|
|
||||||
|
|||||||
@@ -125,7 +125,6 @@ public class RaceController extends Controller {
|
|||||||
raceMap.widthProperty().bind(canvasBase.widthProperty());
|
raceMap.widthProperty().bind(canvasBase.widthProperty());
|
||||||
raceMap.heightProperty().bind(canvasBase.heightProperty());
|
raceMap.heightProperty().bind(canvasBase.heightProperty());
|
||||||
//raceMap.setBoats(newRace.getStartingBoats());
|
//raceMap.setBoats(newRace.getStartingBoats());
|
||||||
raceMap.setRaceBoundaries(raceData.getBoundary());
|
|
||||||
raceMap.drawRaceMap();
|
raceMap.drawRaceMap();
|
||||||
raceMap.setVisible(true);
|
raceMap.setVisible(true);
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package seng302.Mock;
|
|||||||
import seng302.GPSCoordinate;
|
import seng302.GPSCoordinate;
|
||||||
import seng302.Model.BoatInRace;
|
import seng302.Model.BoatInRace;
|
||||||
import seng302.Model.Leg;
|
import seng302.Model.Leg;
|
||||||
|
import seng302.Model.Marker;
|
||||||
import seng302.Model.RaceClock;
|
import seng302.Model.RaceClock;
|
||||||
import seng302.RaceDataSource;
|
import seng302.RaceDataSource;
|
||||||
|
|
||||||
@@ -58,6 +59,8 @@ public class StreamedCourse implements RaceDataSource {
|
|||||||
return streamedCourseXMLReader.getLegs();
|
return streamedCourseXMLReader.getLegs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Marker> getMarkers() { return streamedCourseXMLReader.getMarkers(); }
|
||||||
|
|
||||||
public List<GPSCoordinate> getBoundary() {
|
public List<GPSCoordinate> getBoundary() {
|
||||||
return streamedCourseXMLReader.getBoundary();
|
return streamedCourseXMLReader.getBoundary();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,12 +21,13 @@ import java.util.*;
|
|||||||
* Created by jjg64 on 21/04/17.
|
* Created by jjg64 on 21/04/17.
|
||||||
*/
|
*/
|
||||||
public class StreamedCourseXMLReader extends XMLReader {
|
public class StreamedCourseXMLReader extends XMLReader {
|
||||||
private static double COORDINATEPADDING = 0.0005;
|
private static double COORDINATEPADDING = 0.000;
|
||||||
private GPSCoordinate mapTopLeft, mapBottomRight;
|
private GPSCoordinate mapTopLeft, mapBottomRight;
|
||||||
private List<GPSCoordinate> boundary = new ArrayList<>();
|
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 Map<Integer, StreamedBoat> participants = new HashMap<>();
|
||||||
private List<Leg> legs = new ArrayList<>();
|
private List<Leg> legs = new ArrayList<>();
|
||||||
|
private List<Marker> markers = new ArrayList<>();
|
||||||
Date creationTimeDate;
|
Date creationTimeDate;
|
||||||
Date raceStartTime;
|
Date raceStartTime;
|
||||||
int raceID;
|
int raceID;
|
||||||
@@ -98,14 +99,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);
|
Element nCourse = (Element) doc.getElementsByTagName("Course").item(0);
|
||||||
for(int i = 0; i < nCourse.getChildNodes().getLength(); i++) {
|
for(int i = 0; i < nCourse.getChildNodes().getLength(); i++) {
|
||||||
Node compoundMark = nCourse.getChildNodes().item(i);
|
Node compoundMark = nCourse.getChildNodes().item(i);
|
||||||
if(compoundMark.getNodeName().equals("CompoundMark")) {
|
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 +118,11 @@ public class StreamedCourseXMLReader extends XMLReader {
|
|||||||
* Generates a Marker from the CompoundMark element with given ID.
|
* Generates a Marker from the CompoundMark element with given ID.
|
||||||
* @param compoundMarkID index of required CompoundMark element
|
* @param compoundMarkID index of required CompoundMark element
|
||||||
* @return generated Marker
|
* @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
|
* @see seng302.Model.Marker
|
||||||
*/
|
*/
|
||||||
private Marker getMarker(int compoundMarkID) throws StreamedCourseXMLException {
|
private Marker getMarker(int compoundMarkID) throws StreamedCourseXMLException {
|
||||||
Element compoundMark = marks.get(compoundMarkID);
|
Element compoundMark = compoundMarks.get(compoundMarkID);
|
||||||
NodeList nMarks = compoundMark.getElementsByTagName("Mark");
|
NodeList nMarks = compoundMark.getElementsByTagName("Mark");
|
||||||
Marker marker;
|
Marker marker;
|
||||||
|
|
||||||
@@ -152,7 +156,7 @@ public class StreamedCourseXMLReader extends XMLReader {
|
|||||||
* @return value of "name" attribute
|
* @return value of "name" attribute
|
||||||
*/
|
*/
|
||||||
private String getCompoundMarkName(int compoundMarkID) {
|
private String getCompoundMarkName(int compoundMarkID) {
|
||||||
return marks.get(compoundMarkID).getAttribute("Name");
|
return compoundMarks.get(compoundMarkID).getAttribute("Name");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -184,6 +188,7 @@ public class StreamedCourseXMLReader extends XMLReader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double maxLatitude = boundary.stream().max(Comparator.comparingDouble(GPSCoordinate::getLatitude)).get().getLatitude() + COORDINATEPADDING;
|
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 maxLongitude = boundary.stream().max(Comparator.comparingDouble(GPSCoordinate::getLongitude)).get().getLongitude() + COORDINATEPADDING;
|
||||||
double minLatitude = boundary.stream().min(Comparator.comparingDouble(GPSCoordinate::getLatitude)).get().getLatitude() + COORDINATEPADDING;
|
double minLatitude = boundary.stream().min(Comparator.comparingDouble(GPSCoordinate::getLatitude)).get().getLatitude() + COORDINATEPADDING;
|
||||||
@@ -209,6 +214,8 @@ public class StreamedCourseXMLReader extends XMLReader {
|
|||||||
return legs;
|
return legs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Marker> getMarkers() { return markers; }
|
||||||
|
|
||||||
public Double getPadding() {
|
public Double getPadding() {
|
||||||
return COORDINATEPADDING;
|
return COORDINATEPADDING;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,14 @@ public class Marker {
|
|||||||
return mark2;
|
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() {
|
public GPSCoordinate getAverageGPSCoordinate() {
|
||||||
return averageGPSCoordinate;
|
return averageGPSCoordinate;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ public class ResizableRaceCanvas extends Canvas {
|
|||||||
private boolean annoAbbrev = true;
|
private boolean annoAbbrev = true;
|
||||||
private boolean annoSpeed = true;
|
private boolean annoSpeed = true;
|
||||||
private boolean annoPath = true;
|
private boolean annoPath = true;
|
||||||
private ArrayList<GPSCoordinate> raceBoundaries;
|
private List<GPSCoordinate> raceBoundaries;
|
||||||
|
private List<Marker> markers;
|
||||||
double[] xpoints = {}, ypoints = {};
|
double[] xpoints = {}, ypoints = {};
|
||||||
|
|
||||||
public ResizableRaceCanvas(RaceDataSource raceData) {
|
public ResizableRaceCanvas(RaceDataSource raceData) {
|
||||||
@@ -40,7 +41,11 @@ public class ResizableRaceCanvas extends Canvas {
|
|||||||
double long1 = raceData.getMapTopLeft().getLongitude();
|
double long1 = raceData.getMapTopLeft().getLongitude();
|
||||||
double lat2 = raceData.getMapBottomRight().getLatitude();
|
double lat2 = raceData.getMapBottomRight().getLatitude();
|
||||||
double long2 = raceData.getMapBottomRight().getLongitude();
|
double long2 = raceData.getMapBottomRight().getLongitude();
|
||||||
|
|
||||||
setMap(new RaceMap(lat1, long1, lat2, long2, (int) getWidth(), (int) getHeight()));
|
setMap(new RaceMap(lat1, long1, lat2, long2, (int) getWidth(), (int) getHeight()));
|
||||||
|
|
||||||
|
this.raceBoundaries = raceData.getBoundary();
|
||||||
|
this.markers = raceData.getMarkers();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -206,6 +211,22 @@ public class ResizableRaceCanvas extends Canvas {
|
|||||||
gc.fillPolygon(xpoints, ypoints, xpoints.length);
|
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
|
* Draws the Race Map
|
||||||
*/
|
*/
|
||||||
@@ -222,26 +243,9 @@ public class ResizableRaceCanvas extends Canvas {
|
|||||||
this.map.setHeight((int) height);
|
this.map.setHeight((int) height);
|
||||||
this.map.setWidth((int) width);
|
this.map.setWidth((int) width);
|
||||||
|
|
||||||
//finish line
|
|
||||||
gc.setLineWidth(2);
|
gc.setLineWidth(2);
|
||||||
drawBoundaries();
|
drawBoundaries();
|
||||||
GraphCoordinate finishLineCoord1 = this.map.convertGPS(Constants.finishLineMarker1);
|
drawMarkers();
|
||||||
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);
|
|
||||||
|
|
||||||
updateBoats();
|
updateBoats();
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package seng302;
|
|||||||
|
|
||||||
import seng302.Model.BoatInRace;
|
import seng302.Model.BoatInRace;
|
||||||
import seng302.Model.Leg;
|
import seng302.Model.Leg;
|
||||||
|
import seng302.Model.Marker;
|
||||||
|
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -12,6 +13,7 @@ import java.util.List;
|
|||||||
public interface RaceDataSource {
|
public interface RaceDataSource {
|
||||||
List<BoatInRace> getBoats();
|
List<BoatInRace> getBoats();
|
||||||
List<Leg> getLegs();
|
List<Leg> getLegs();
|
||||||
|
List<Marker> getMarkers();
|
||||||
List<GPSCoordinate> getBoundary();
|
List<GPSCoordinate> getBoundary();
|
||||||
|
|
||||||
ZonedDateTime getZonedDateTime();
|
ZonedDateTime getZonedDateTime();
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import java.util.List;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by fwy13 on 26/03/2017.
|
* Created by fwy13 on 26/03/2017.
|
||||||
|
* @deprecated use {@link seng302.Mock.StreamedCourseXMLReader}
|
||||||
*/
|
*/
|
||||||
public class RaceXMLReader extends XMLReader implements RaceDataSource {
|
public class RaceXMLReader extends XMLReader implements RaceDataSource {
|
||||||
private List<BoatInRace> boats = new ArrayList<>();
|
private List<BoatInRace> boats = new ArrayList<>();
|
||||||
@@ -263,6 +264,11 @@ public class RaceXMLReader extends XMLReader implements RaceDataSource {
|
|||||||
return new GPSCoordinate(startLat, startLong);
|
return new GPSCoordinate(startLat, startLong);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Marker> getMarkers() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public List<BoatInRace> getBoats() {
|
public List<BoatInRace> getBoats() {
|
||||||
return boats;
|
return boats;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
package seng302.Mock;
|
package seng302.Mock;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import seng302.GPSCoordinate;
|
import seng302.GPSCoordinate;
|
||||||
import seng302.Model.Leg;
|
import seng302.Model.Leg;
|
||||||
|
import seng302.Model.Marker;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
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());
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user