Refactored the setup for MarkObjects (now renamed Markers) and made the CompoundMark + Mark + GeoPoint classes the standard across all classes instead of GateMark + SingleMark + Mark.

#refactor
This commit is contained in:
Calum
2017-07-31 02:19:19 +12:00
parent 6cae338c1e
commit f1ad03e913
32 changed files with 452 additions and 756 deletions
+31
View File
@@ -0,0 +1,31 @@
package seng302.model;
/**
* A class represent Geo location (latitude, lnggitude).
* Created by Haoming on 15/5/2017
*/
public class GeoPoint {
private double lat, lng;
public GeoPoint(double lat, double lng) {
this.lat = lat;
this.lng = lng;
}
public double getLat() {
return lat;
}
public void setLat(double lat) {
this.lat = lat;
}
public double getLng() {
return lng;
}
public void setLng(double lng) {
this.lng = lng;
}
}
+2 -13
View File
@@ -3,27 +3,16 @@ package seng302.model;
/**
* Stores data on the border of a race
*/
public class Limit {
public class Limit extends GeoPoint {
private Integer seqID;
private Double lat;
private Double lng;
public Limit(Integer seqID, Double lat, Double lng) {
super(lat, lng);
this.seqID = seqID;
this.lat = lat;
this.lng = lng;
}
public Integer getSeqID() {
return seqID;
}
public Double getLat() {
return lat;
}
public Double getLng() {
return lng;
}
}
-1
View File
@@ -14,7 +14,6 @@ import javafx.beans.property.ReadOnlyLongWrapper;
import javafx.scene.paint.Color;
import seng302.gameServer.GameState;
import seng302.model.mark.Mark;
import seng302.utilities.GeoPoint;
/**
* Yacht class for the racing boat.
@@ -0,0 +1,86 @@
package seng302.model.mark;
import com.sun.deploy.util.StringUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CompoundMark {
private int compoundMarkId;
private String name;
private List<Mark> marks = new ArrayList<>();
public CompoundMark(int markID, String name) {
this.compoundMarkId = markID;
this.name = name;
}
public void addSubMarks(Mark... marks) {
this.marks.addAll(Arrays.asList(marks));
}
public void addSubMarks(List<Mark> marks) {
this.marks.addAll(marks);
}
/**
* Prints out compoundMark's info and its marks, good for testing
* @return a string showing its details
*/
@Override
public String toString(){
String info = String.format("CompoundMark: %d (%s), [", compoundMarkId, name);
info += StringUtils.join(marks, ", ") + "]";
return info;
}
public int getId() {
return compoundMarkId;
}
public void setId (int markID) {
this.compoundMarkId = markID;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* Returns the mark contained in the compound mark. Marks are numbered 1 to n;
* @param singleMarkId the id of the desired mark contained in this compound mark.
* @return the desired mark. Returns null if the ID is not in range (1, NUM_MARKS)
*/
public Mark getSubMark(int singleMarkId) {
try {
return marks.get(singleMarkId - 1);
} catch (IndexOutOfBoundsException e) {
return null;
}
}
/**
* Returns whether or not this CompoundMark is a Gate. It is generally cleaner to program to a
* specific singleMark or the list of marks.
*
* @return True if the compound mark is a gate, false otherwise.
*/
public boolean isGate () {
return marks.size() > 1;
}
/**
* Returns the list of marks in the compoundMark
*
* @return All marks contained in this mark.
*/
public List<Mark> getMarks () {
return marks;
}
}
@@ -1,4 +1,4 @@
package seng302.model;
package seng302.model.mark;
/**
* Stores the data for the cornering of a mark.
@@ -1,49 +0,0 @@
package seng302.model.mark;
/**
* To represent a gate mark which contains two single marks.
* Created by ptg19 on 16/03/17.
* Modified by Haoming Yin (hyi25) on 17/3/2017.
*/
public class GateMark extends Mark {
private SingleMark singleMark1;
private SingleMark singleMark2;
/**
* Create an instance of Gate Mark which contains two single mark
* @param name the name of the gate mark
* @param singleMark1 one single mark inside of the gate mark
* @param singleMark2 the second mark inside of the gate mark
*/
public GateMark(String name, MarkType type, SingleMark singleMark1, SingleMark singleMark2, double latitude, double longitude, int compoundMarkID) {
super(name, type, latitude, longitude, compoundMarkID);
this.singleMark1 = singleMark1;
this.singleMark2 = singleMark2;
}
public SingleMark getSingleMark1() {
return singleMark1;
}
public void setSingleMark1(SingleMark singleMark1) {
this.singleMark1 = singleMark1;
}
public SingleMark getSingleMark2() {
return singleMark2;
}
public void setSingleMark2(SingleMark singleMark2) {
this.singleMark2 = singleMark2;
}
public double getLatitude(){
return (this.getSingleMark1().getLatitude());
}
public double getLongitude(){
return (this.getSingleMark1().getLongitude());
}
}
+41 -110
View File
@@ -1,113 +1,46 @@
package seng302.model.mark;
import java.util.ArrayList;
import java.util.List;
import seng302.model.GeoPoint;
/**
* An abstract class to represent general marks
* Created by Haoming Yin (hyi25) on 17/3/17.
*/
public abstract class Mark {
public class Mark extends GeoPoint {
@FunctionalInterface
public interface PositionListener {
void notifyPositionChange(Mark mark, double lat, double lon);
}
private int seqID;
private String name;
private MarkType markType;
private double latitude;
private double longitude;
private int id;
private int compoundMarkID;
private int sourceID;
private List<PositionListener> positionListeners = new ArrayList<>();
/**
* Create a mark instance by passing its name and type
* @param name the name of the mark
* @param markType the type of mark. either GATE_MARK or SINGLE_MARK.
*/
public Mark (String name, MarkType markType, int sourceID, int compoundMarkID) {
public Mark(String name, double lat, double lng, int sourceID) {
super(lat, lng);
this.name = name;
this.markType = markType;
this.id = sourceID;
this.compoundMarkID = compoundMarkID;
}
public Mark(String name, MarkType markType, double latitude, double longitude, int compoundMarkID) {
this.name = name;
this.markType = markType;
this.latitude = latitude;
this.longitude = longitude;
this.id = 0;
this.compoundMarkID = compoundMarkID;
this.sourceID = sourceID;
}
/**
* Calculated the heading in radians from first Mark to the second Mark.
*
* @param pointOne First Mark
* @param pointTwo Second Mark
* @return Heading in radians
* Prints out mark's info and its geo location, good for testing
* @return a string showing its details
*/
public static Double calculateHeadingRad(Mark pointOne, Mark pointTwo) {
Double longitude1 = pointOne.getLongitude();
Double longitude2 = pointTwo.getLongitude();
Double latitude1 = pointOne.getLatitude();
Double latitude2 = pointTwo.getLatitude();
return calculateHeadingRad(latitude1, longitude1, latitude2, longitude2);
@Override
public String toString() {
return String.format("Mark%d: %s, source: %d, lat: %f, lng: %f", seqID, name, sourceID, getLat(), getLng());
}
/**
* Calculate the heading in radians from geographical location with latitude1, longitude 1 to
* geographical latitude2, longitude 2
*
* @param longitude1 Longitude of first point in degrees
* @param longitude2 Longitude of second point in degrees
* @param latitude1 Latitude of first point in degrees
* @param latitude2 Latitude of first point in degrees
* @return Heading in radians
*/
public static double calculateHeadingRad(Double latitude1, Double longitude1, Double latitude2,
Double longitude2) {
latitude1 = Math.toRadians(latitude1);
latitude2 = Math.toRadians(latitude2);
Double longDiff = Math.toRadians(longitude2 - longitude1);
Double y = Math.sin(longDiff) * Math.cos(latitude2);
Double x =
Math.cos(latitude1) * Math.sin(latitude2) - Math.sin(latitude1) * Math.cos(latitude2)
* Math.cos(longDiff);
return Math.atan2(y, x);
public int getSeqID() {
return seqID;
}
/**
* Calculates the distance in meters from the first Mark to a second Mark
*
* @param pointOne First Mark
* @param pointTwo Second Mark
* @return Distance in meters
*/
public static Double calculateDistance(Mark pointOne, Mark pointTwo) {
Double longitude1 = pointOne.getLongitude();
Double longitude2 = pointTwo.getLongitude();
Double latitude1 = pointOne.getLatitude();
Double latitude2 = pointTwo.getLatitude();
return calculateDistance(latitude1, longitude1, latitude2, longitude2);
}
/**
* Calculate the distance in meters from geographical location with latitude1, longitude 1 to
* geographical latitude2, longitude 2
*
* @param longitude1 Longitude of first point in degrees
* @param longitude2 Longitude of second point in degrees
* @param latitude1 Latitude of first point in degrees
* @param latitude2 Latitude of first point in degrees
* @return Distance in meters
*/
public static Double calculateDistance(Double latitude1, Double longitude1, Double latitude2,
Double longitude2) {
Double theta = longitude1 - longitude2;
Double dist = Math.sin(Math.toRadians(latitude1)) * Math.sin(Math.toRadians(latitude2)) +
Math.cos(Math.toRadians(latitude1)) * Math.cos(Math.toRadians(latitude2)) *
Math.cos(Math.toRadians(theta));
dist = Math.acos(dist);
dist = Math.toDegrees(dist);
dist = dist * 60
* 1.1508; //nautical mile (distance between two degrees) * (degrees in a minute)
dist = dist * 1609.344; //ratio of miles to metres
return dist;
public void setSeqID(int seqID) {
this.seqID = seqID;
}
public String getName() {
@@ -118,31 +51,29 @@ public abstract class Mark {
this.name = name;
}
public MarkType getMarkType() {
return markType;
public int getSourceID() {
return sourceID;
}
public void setMarkType(MarkType markType) {
this.markType = markType;
public void setSourceID(int sourceID) {
this.sourceID = sourceID;
}
public double getLatitude() {
return latitude;
public void updatePosition (double lat, double lon) {
this.setLat(lat);
this.setLng(lon);
for (PositionListener listener : positionListeners) {
listener.notifyPositionChange(this, lat, lon);
}
}
public double getLongitude() {
return longitude;
public void addPositionListener (PositionListener listener) {
positionListeners.add(listener);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getCompoundMarkID() {
return compoundMarkID;
public void removePositionListener (PositionListener listener) {
positionListeners.remove(listener);
}
}
@@ -1,9 +0,0 @@
package seng302.model.mark;
/**
* To represent two types of mark
* Created by Haoming Yin (hyi25) on 17/3/17.
*/
public enum MarkType {
SINGLE_MARK, OPEN_GATE
}
@@ -1,34 +0,0 @@
package seng302.model.mark;
/**
* Represents the marker as a single mark
*
* Created by Haoming Yin (hyi25) on 17/3/2017
*/
public class SingleMark extends Mark {
private double lat;
private double lon;
private String name;
/**
* Represents a marker
*
* @param name, the name of the marker*
* @param lat, the latitude of the marker
* @param lon, the longitude of the marker
*/
public SingleMark(String name, double lat, double lon, int sourceID, int compoundMarkID) {
super(name, MarkType.SINGLE_MARK, sourceID, compoundMarkID);
this.lat = lat;
this.lon = lon;
}
public double getLatitude() {
return this.lat;
}
public double getLongitude() {
return this.lon;
}
}
@@ -3,9 +3,9 @@ package seng302.model.stream.xml.parser;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import seng302.model.Corner;
import seng302.model.Limit;
import seng302.model.mark.Mark;
import seng302.model.mark.CompoundMark;
import seng302.model.mark.Corner;
/**
* Process a Document object containing race data in XML format and stores the data.
@@ -13,20 +13,18 @@ import seng302.model.mark.Mark;
public class RaceXMLData {
private List<Integer> participants;
private Map<Integer, Mark> compoundMarks;
private Map<Integer, CompoundMark> compoundMarks;
private List<Corner> markSequence;
private List<Limit> courseLimit;
private Map<Integer, Mark> individualMarks;
public RaceXMLData(List<Integer> participants, List<Mark> compoundMarks, List<Corner> markSequence,
List<Limit> courseLimit) {
public RaceXMLData(List<Integer> participants, List<CompoundMark> compoundMarks,
List<Corner> markSequence, List<Limit> courseLimit) {
this.participants = participants;
this.markSequence = markSequence;
this.courseLimit = courseLimit;
this.compoundMarks = new HashMap<>();
for (Mark mark : compoundMarks)
this.compoundMarks.put(mark.getId(), mark);
for (Mark mark : compoundMarks) {
for (CompoundMark cMark : compoundMarks) {
this.compoundMarks.put(cMark.getId(), cMark);
}
}
@@ -34,7 +32,7 @@ public class RaceXMLData {
return participants;
}
public Map<Integer, Mark> getCompoundMarks() {
public Map<Integer, CompoundMark> getCompoundMarks() {
return compoundMarks;
}
@@ -45,4 +43,5 @@ public class RaceXMLData {
public List<Limit> getCourseLimit() {
return courseLimit;
}
}