package seng302; import javafx.scene.paint.Color; import org.w3c.dom.*; import org.xml.sax.SAXException; import seng302.Model.Boat; import seng302.Model.BoatInRace; import seng302.Model.Leg; import javax.xml.parsers.ParserConfigurationException; import java.io.IOException; import java.util.ArrayList; /** * Created by fwy13 on 26/03/2017. */ public class RaceXMLReader extends XMLReader{ private ArrayList boats = new ArrayList<>(); private Color[] colors = {Color.BLUEVIOLET, Color.BLACK, Color.RED, Color.ORANGE, Color.DARKOLIVEGREEN, Color.LIMEGREEN};//TODO make this established in xml or come up with a better system. private ArrayList legs = new ArrayList<>(); private GPSCoordinate mark, startPt1, startPt2, finishPt1, finishPt2, leewardPt1, leewardPt2, windwardPt1, windwardPt2; private GPSCoordinate mapTopLeft, mapBottomRight; private ArrayList boundary = new ArrayList<>(); private static double COORDINATEPADDING = 0.0005; public RaceXMLReader(String filePath) throws IOException, SAXException, ParserConfigurationException { this(filePath, true); } public RaceXMLReader(String filePath, boolean read) throws IOException, SAXException, ParserConfigurationException { super(filePath); if (read) { read(); } } private void read(){ readCourse(); readBoats(); readLegs(); } public void readBoats(){ //get all boats NodeList nBoats = doc.getElementsByTagName("boat"); for (int i = 0; i < nBoats.getLength(); i++){ String name = getTextValueOfNode((Element) nBoats.item(i), "name"); String abbrev = getTextValueOfNode((Element) nBoats.item(i), "abbr"); double velo = Double.parseDouble(getTextValueOfNode((Element) nBoats.item(i), "speed")); //System.out.println(String.format("%s, %s, %s",name, abbrev, velo)); BoatInRace boat = new BoatInRace(name, velo, colors[i], abbrev); boat.setCurrentPosition(startPt1); boats.add(boat); } } public void readLegs(){ //get all legs NodeList nLegs = doc.getElementsByTagName("leg"); for (int i = 0; i < nLegs.getLength(); i++){ String label = getTextValueOfNode((Element) nLegs.item(i), "name"); NodeList start = ((Element) nLegs.item(i)).getElementsByTagName("start"); GPSCoordinate startCoord = getCoordinates(start); NodeList finish = ((Element) nLegs.item(i)).getElementsByTagName("finish"); GPSCoordinate finishCoord = getCoordinates(finish); //System.out.println(String.format("%s, %s, %s, %s",label, startCoord, finishCoord, i)); legs.add(new Leg(label, startCoord, finishCoord, i)); } } public void readCourse(){ NodeList nCourse = doc.getElementsByTagName("course"); NodeList nBounds = ((Element)nCourse.item(0)).getElementsByTagName("boundaries"); nBounds = ((Element) nBounds.item(0)).getElementsByTagName("coordinate"); int maxLatitudeIndex = 0; double maxLatitude = -Double.MIN_VALUE; int maxLongitudeIndex = 0; double maxLongitude = -180; int minLatitudeIndex = 0; double minLatitude = Double.MAX_VALUE; int minLongitudeIndex = 0; double minLongitude = Double.MAX_VALUE; for (int i = 0; i < nBounds.getLength(); i++){ boundary.add(getCoordinates((Element) nBounds.item(i))); if (boundary.get(i).getLatitude() > maxLatitude){ maxLatitudeIndex = i; maxLatitude = boundary.get(i).getLatitude(); } if (boundary.get(i).getLatitude() < minLatitude){ minLatitudeIndex = i; minLatitude = boundary.get(i).getLatitude(); } if (boundary.get(i).getLongitude() > maxLongitude){ maxLongitudeIndex = i; maxLongitude = boundary.get(i).getLongitude(); } if (boundary.get(i).getLongitude() < minLongitude){ minLongitudeIndex = i; minLongitude = boundary.get(i).getLongitude(); } } /*System.out.println(nBounds.getLength()); System.out.println(maxLatitude); System.out.println(minLatitude); System.out.println(maxLongitude); System.out.println(minLongitude);*/ double difference = 0;//this will hold the largest difference so we can make the map square. double latitudeDiff = Math.abs(Math.abs(boundary.get(maxLatitudeIndex).getLatitude()) - Math.abs(boundary.get(minLatitudeIndex).getLatitude())); double longitudeDiff = Math.abs(Math.abs(boundary.get(maxLongitudeIndex).getLongitude()) - Math.abs(boundary.get(minLongitudeIndex).getLongitude())); if (latitudeDiff >= longitudeDiff){ difference = latitudeDiff - longitudeDiff; maxLongitude += difference/2; minLongitude -= difference/2; }else{ difference = longitudeDiff - latitudeDiff; maxLatitude += difference/2; minLatitude -= difference/2; } maxLatitude += COORDINATEPADDING; minLatitude -= COORDINATEPADDING; maxLongitude += COORDINATEPADDING; minLongitude -= COORDINATEPADDING; //now create map boundaries //top left canvas point is min logitude, max latitude //bottom right of canvas point is min longitude, max latitude. mapTopLeft = new GPSCoordinate(minLatitude, minLongitude); mapBottomRight = new GPSCoordinate(maxLatitude, maxLongitude); NodeList nMarks = ((Element)nCourse.item(0)).getElementsByTagName("marker"); startPt1 = getCoordinates(nMarks, 0); startPt2 = getCoordinates(nMarks, 0, 1); mark = getCoordinates(nMarks, 1); windwardPt1 = getCoordinates(nMarks, 2); windwardPt2 = getCoordinates(nMarks, 2, 1); leewardPt1 = getCoordinates(nMarks, 3); leewardPt2 = getCoordinates(nMarks, 3, 1); finishPt1 = getCoordinates(nMarks, 4); finishPt2 = getCoordinates(nMarks, 4, 1); } private GPSCoordinate getCoordinates(NodeList start){ return getCoordinates(start, 0); } private GPSCoordinate getCoordinates(NodeList start, int startIndex){ return getCoordinates(start, startIndex, 0); } private GPSCoordinate getCoordinates(NodeList start, int startIndex, int nodeIndex){ NodeList nodeList = ((Element) start.item(startIndex)).getElementsByTagName("coordinate"); Element coord = (Element) nodeList.item(nodeIndex); return getCoordinates(coord); } /** * Returns the coordinate TODO raise exception that runs when the XML is formatted wrongly. * @param coordNode * @return */ private GPSCoordinate getCoordinates(Element coordNode){ double startLat = Double.parseDouble(getTextValueOfNode(coordNode, "latitude")); double startLong = Double.parseDouble(getTextValueOfNode(coordNode, "longitude")); return new GPSCoordinate(startLat, startLong); } public ArrayList getBoats() { return boats; } public ArrayList getLegs() { return legs; } public GPSCoordinate getMark() { return mark; } public GPSCoordinate getStartPt1() { return startPt1; } public GPSCoordinate getStartPt2() { return startPt2; } public GPSCoordinate getFinishPt1() { return finishPt1; } public GPSCoordinate getFinishPt2() { return finishPt2; } public GPSCoordinate getLeewardPt1() { return leewardPt1; } public GPSCoordinate getLeewardPt2() { return leewardPt2; } public GPSCoordinate getWindwardPt1() { return windwardPt1; } public GPSCoordinate getWindwardPt2() { return windwardPt2; } public ArrayList getBoundary() { return boundary; } public GPSCoordinate getMapTopLeft() { return mapTopLeft; } public GPSCoordinate getMapBottomRight() { return mapBottomRight; } }