Meteorite.java (7355B)
1 2 package com.example.project_assignment; 3 4 import android.os.Parcel; 5 import android.os.Parcelable; 6 7 import androidx.annotation.NonNull; 8 9 import com.google.gson.JsonObject; 10 import com.google.gson.annotations.SerializedName; 11 12 public class Meteorite implements Parcelable { 13 private final String name; 14 15 @SerializedName(value = "ID", alternate = "id") 16 private final String id; 17 @SerializedName(value = "size", alternate = "mass") 18 private final String mass; 19 20 private final String category; 21 22 private String location; 23 24 private final String date; 25 26 private JsonObject auxdata; 27 28 private double distance; 29 30 public String getDescription() { 31 return "The meteorite " + name + 32 " has a mass of " + mass + "kg " + 33 "and touched the surface of the earth at " + 34 getDate() + "\n\n" + 35 "It landed at lat: " + getLatitude() + 36 " long: " + getLongitude() + 37 " Roughly " + Math.round(distance) + "km from your location" + 38 "\nIt is part of the category: " + category; 39 } 40 41 @Override 42 public String toString() { 43 return "Meteorite{" + 44 "name='" + name + '\'' + 45 ", id='" + id + '\'' + 46 ", mass='" + mass + '\'' + 47 ", category='" + category + '\'' + 48 ", location='" + location + '\'' + 49 ", latitude='" + getLatitude() + '\'' + 50 ", date='" + date + '\'' + 51 ", longitude='" + getLongitude() + '\'' + 52 ", auxdata=" + auxdata.toString() + 53 ", distance=" + distance + 54 '}'; 55 } 56 57 /** 58 * Used to create parcel for sending Meteorite data as one object throgh intents. 59 */ 60 protected Meteorite(Parcel in) { 61 name = in.readString(); 62 id = in.readString(); 63 mass = in.readString(); 64 category = in.readString(); 65 date = in.readString(); 66 location = in.readString(); 67 distance = in.readDouble(); 68 } 69 70 /** 71 * When Meteorite is unpacked from parcel, use below function. 72 */ 73 public static final Creator<Meteorite> CREATOR = new Creator<Meteorite>() { 74 @Override 75 public Meteorite createFromParcel(Parcel in) { 76 return new Meteorite(in); 77 } 78 79 @Override 80 public Meteorite[] newArray(int size) { 81 return new Meteorite[size]; 82 } 83 }; 84 85 @Override 86 public int describeContents() { 87 return 0; 88 } 89 90 @Override 91 public void writeToParcel(@NonNull Parcel parcel, int i) { 92 parcel.writeString(name); 93 parcel.writeString(id); 94 parcel.writeString(mass); 95 parcel.writeString(category); 96 parcel.writeString(getDate()); 97 parcel.writeString(location); 98 parcel.writeDouble(distance); 99 } 100 101 /** 102 * Return and set distance valeue to the meteorite from coordinate. 103 * Code inspired by: 104 * https://stackoverflow.com/questions/3694380/calculating-distance-between-two-points-using-latitude-longitude 105 * @param extLatitude The external positions latitude. 106 * @param extLongitude The external positions longitude. 107 * @return Return the distance from the meteorite. 108 */ 109 public double generateDistanceFrom(double extLatitude, double extLongitude) { 110 111 double meteoriteLatitude = Double.parseDouble(getLatitude()); 112 double meteoriteLongitude = Double.parseDouble(getLongitude()); 113 114 final int R = 6371; // Radius of the earth 115 116 double latDistance = Math.toRadians(meteoriteLatitude - extLatitude); 117 double lonDistance = Math.toRadians(meteoriteLongitude - extLongitude); 118 double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2) 119 + Math.cos(Math.toRadians(extLatitude)) * Math.cos(Math.toRadians(meteoriteLatitude)) 120 * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2); 121 double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 122 123 double distance = R * c * 1000; // convert to meters 124 125 setDistance(Math.sqrt(distance)); 126 return this.distance; 127 } 128 129 130 /** 131 * Used to filter meteorites using the parameters below, if the current meteorite 132 * does not match the specified criteria. 133 * @param minMass The lowest accepted mass. 134 * @param maxMass The highest accepted mass. 135 * @param minYear The lowest accepted year. 136 * @param maxYear The highest accepted year. 137 * @param maxDistance The furthest accepted distance. 138 * @return true, if all criteria match, else false. 139 */ 140 public boolean matchingFilter(int minMass, int maxMass, int minYear, int maxYear, int maxDistance) { 141 //filter mass 142 if (getMass() < minMass && minMass != 0) { 143 System.out.println("mass not matching filter"); 144 return false; 145 } 146 if (getMass() > maxMass && maxMass != 0) { 147 System.out.println("mass not matching filter"); 148 return false; 149 } 150 //filter year the meteorite fell. 151 if (getDate() != null) { 152 int year = Integer.parseInt(getDate()); 153 if (year < minYear && minYear != 0) { 154 System.out.println("date not matching filter"); 155 return false; 156 } 157 if (year > maxYear && maxYear != 0) { 158 System.out.println("date not matching filter"); 159 return false; 160 } 161 } else { 162 System.out.println("date null"); 163 return false; 164 } 165 166 if (distance > maxDistance && maxDistance != 0) { 167 System.out.println("distance not matching filter"); 168 return false; 169 } 170 171 //if none of the filters trigger, return true 172 return true; 173 } 174 175 /** 176 * Since the date is stored in a dateTime format, truncate the String to only return year before 177 * returning. 178 * @return the year the meteorite landed. 179 */ 180 public String getDate() { 181 if (date == null) { 182 return auxdata.get("date").getAsString().substring(0, 4); 183 } 184 return date; 185 } 186 187 /** 188 * Since both lat and long values are stored in one string, separated by ",", 189 * split them into separate values before returning. 190 * @return latitude. 191 */ 192 public String getLatitude() { 193 String latLong[] = location.split(","); 194 return latLong[0]; 195 } 196 197 /** 198 * Since both lat and long values are stored in one string, separated by ",", 199 * split them into separate values before returning. 200 * @return longitude. 201 */ 202 public String getLongitude() { 203 String latLong[] = location.split(","); 204 return latLong[1]; 205 } 206 207 /** 208 * To more easily handle calculations and comparisons based on mass, 209 * convert the value to int before returning. 210 * @return Int mass. 211 */ 212 public int getMass() { 213 if (mass == null) { 214 return 0; 215 } 216 return Integer.parseInt(mass); 217 } 218 219 public void setDistance(double distance) { 220 this.distance = distance; 221 } 222 223 public double getDistance() { 224 return this.distance; 225 } 226 227 public String getName() { 228 return name; 229 } 230 231 public String getId() { 232 return id; 233 } 234 }