package de.edotzlaff.detection.detektion.berechnung; import android.location.Location; import android.nfc.Tag; import android.os.Build; import android.util.Log; import androidx.annotation.RequiresApi; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; import de.edotzlaff.detection.detektion.Detektionssignal; import de.edotzlaff.detection.detektion.Epizentrum; import de.edotzlaff.detection.detektion.berechnung.mathObjekte.Koordinaten; import de.edotzlaff.detection.detektion.berechnung.mathObjekte.Kreis; import de.edotzlaff.detection.detektion.berechnung.mathObjekte.Schnittpunkt; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Set; public class EpizentrumRechnung { //ToDo Schrittweite und Abstand auf Szenario anpassen private static final double SCHRITTWEITE = 0.000050; private static final double MAX_ABSTAND = 0.000058; private static final int DOUBLESTELLEN = 24; private static final int SCHLEIFENDURCHLAUFTE = 5000; private static final String TAG = "EPIZENTRUMRECHNUNG"; @RequiresApi(api = Build.VERSION_CODES.O) public ArrayList initEndpunkte(ArrayList detektionssignal, Detektionssignal ersteMessung) { ArrayList arrBerechnungsObjekte = new ArrayList<>(); for (Detektionssignal aufzeichnung : detektionssignal) { int zeitunterschied = aufzeichnung.getAnkunftsZeit().getHour() * 3600 + aufzeichnung.getAnkunftsZeit().getMinute() * 60 + aufzeichnung.getAnkunftsZeit().getSecond() - ersteMessung.getAnkunftsZeit().getHour() * 3600 - ersteMessung.getAnkunftsZeit().getMinute() * 60 - ersteMessung.getAnkunftsZeit().getSecond(); double startradius = zeitunterschied * aufzeichnung.getGeschwErdbeben()*0.0000114130224932113000000; Log.i(TAG, "Init Daten: " + aufzeichnung.getDeviceId() + "Startradius: " + startradius); Endpunkt tempEndpunkt = new Endpunkt(aufzeichnung.getDeviceId()); Kreis k = new Kreis(aufzeichnung.getKoordinaten().getX(), aufzeichnung.getKoordinaten().getY(), startradius); tempEndpunkt.setKreis(k); arrBerechnungsObjekte.add(tempEndpunkt); } Log.i(TAG, "Daten Erfolgreich initialisiert"); return arrBerechnungsObjekte; } @RequiresApi(api = Build.VERSION_CODES.O) public Detektionssignal ermittleErstesDetektionssignal(ArrayList detektionssignale) { Detektionssignal erstesDetektionssignal = detektionssignale.get(0); for (int i = 1; i < detektionssignale.size(); i++) { if (detektionssignale.get(i).getAnkunftsZeit().isBefore(erstesDetektionssignal.getAnkunftsZeit())) { erstesDetektionssignal = detektionssignale.get(i); } } Log.i(TAG, "Test"); return erstesDetektionssignal; } public ArrayList berechneKreisSchnittpunkte(Kreis kreis1, Kreis kreis2) { ArrayList schnittpunkte = new ArrayList<>(); double dx = kreis2.getMittelPunkt().getX() - kreis1.getMittelPunkt().getX(); double dy = kreis2.getMittelPunkt().getY() - kreis1.getMittelPunkt().getY(); double c = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); double x = ((Math.pow(kreis1.getRadius(), 2) + Math.pow(c, 2) - Math.pow(kreis2.getRadius(), 2))) / (2 * c); double y = Math.pow(kreis1.getRadius(), 2) - Math.pow(x, 2); //Kein Schnittpunkt vorhanden if (y < 0) { return schnittpunkte; } if (y > 0) { y = Math.sqrt(y); } double ex0 = dx / c; double ex1 = dy / c; double ey0 = -ex1; Schnittpunkt s1 = new Schnittpunkt(kreis1.getMittelPunkt().getX() + x * ex0, kreis1.getMittelPunkt().getY() + x * ex1); //Genau ein Schnittpunkt vorhanden if (y == 0) { schnittpunkte.add(s1); return schnittpunkte; } Schnittpunkt s2 = new Schnittpunkt(s1.getKoordinaten().getX() - y * ey0, s1.getKoordinaten().getY() - y * ex0); s1.getKoordinaten().setLocation(s1.getKoordinaten().getX() + y * ey0, s1.getKoordinaten().getY() + y * ex0); schnittpunkte.add(s1); schnittpunkte.add(s2); return schnittpunkte; } public boolean genuegendSchnittpunktevorhanden(ArrayList endpunktVerbindungen) { //Log.i(TAG,"Überprüfe ob genügend Schnittpunkte vorhanden sind"); //Log.i(TAG,"Radius: "+ Double.toString(endpunktVerbindungen.get(0).getEndpunkt1().getKreis().getRadius())); for (EndpunktVerbindung endpunktVerbindung : endpunktVerbindungen) { ArrayList templist; templist = berechneKreisSchnittpunkte(endpunktVerbindung.getEndpunkt1().getKreis(), endpunktVerbindung.getEndpunkt2().getKreis()); if (templist.isEmpty()) { return false; } endpunktVerbindung.setSchnittpunkte(templist); } return true; } public Epizentrum ueberpruefeObEpizentrum(ArrayList endpunktVerbindungen) { int counter; ArrayList schnittpunkte = new ArrayList<>(); for (Schnittpunkt s1 : endpunktVerbindungen.get(0).getSchnittpunkte()) { counter = 0; for (int i = 1; i < endpunktVerbindungen.size(); i++) { boolean bereitsSchnittpunktErmittelt = false; for (Schnittpunkt s2 : endpunktVerbindungen.get(i).getSchnittpunkte()) { double abstand = Math.sqrt( Math.pow(s2.getKoordinaten().getX() - s1.getKoordinaten().getX(), 2) + Math.pow(s2.getKoordinaten().getY() - s1.getKoordinaten().getY(), 2)); if (abstand < MAX_ABSTAND && !bereitsSchnittpunktErmittelt) { bereitsSchnittpunktErmittelt = true; counter++; schnittpunkte.add(s2); } if (counter == endpunktVerbindungen.size() - 1) { schnittpunkte.add(s1); Epizentrum tempEpizentrum = new Epizentrum(); Koordinaten koordinaten = (berechneEpizentrumKoordinaten(schnittpunkte)); tempEpizentrum.setKoordinaten(koordinaten); Log.i(TAG, "Epizentrumkoord: " + tempEpizentrum.getKoordinaten().getX() + " " + tempEpizentrum.getKoordinaten().getY()); return tempEpizentrum; } } } } return null; } public Koordinaten berechneEpizentrumKoordinaten(ArrayList schnittpunkte) { Log.i(TAG, "Berechne Epizentrum Koordinaten"); double x = 0; double y = 0; for (Schnittpunkt s : schnittpunkte) { x+= s.getKoordinaten().getX(); y+= s.getKoordinaten().getY(); } x = new BigDecimal(x/schnittpunkte.size()).setScale(DOUBLESTELLEN, RoundingMode.HALF_UP).doubleValue()*0.999308681; y = new BigDecimal(y/schnittpunkte.size()).setScale(DOUBLESTELLEN, RoundingMode.HALF_UP).doubleValue()*1.000831381; return new Koordinaten(x,y); } public ArrayList ermittleEndpunktKonbinationen(ArrayList tempBerechungsObjekte) { ArrayList verbindungen = new ArrayList<>(); Set> combinations = Sets.combinations(ImmutableSet.copyOf(tempBerechungsObjekte), 2); for (Set tempEndpunkt : combinations) { ArrayList helpArrayToGetValues = new ArrayList<>(tempEndpunkt); EndpunktVerbindung endpunktVerbindung = new EndpunktVerbindung(helpArrayToGetValues.get(0), helpArrayToGetValues.get(1)); verbindungen.add(endpunktVerbindung); } Log.i(TAG, "Endpunkteverbindungen Erfolgreich festgelegt, Anzahl: " + verbindungen.size()); return verbindungen; } @RequiresApi(api = Build.VERSION_CODES.O) public LocalDateTime berechneEntstehungsZeitpunkt(Detektionssignal detektionssignal, Koordinaten koordEpi) { double abstand = Math.sqrt( Math.pow(detektionssignal.getKoordinaten().getX() - koordEpi.getX(), 2) + Math.pow(detektionssignal.getKoordinaten().getY() - koordEpi.getY(), 2)); int sec = (int) abstand/ detektionssignal.geschwErdbeben; return detektionssignal.getAnkunftsZeit().minusSeconds(sec); } @RequiresApi(api = Build.VERSION_CODES.O) public LocalDateTime berechneEntstehungsZeitpunktLongLatt(Detektionssignal detektionssignal, Koordinaten koordEpi) { float[] results = new float[1]; Location.distanceBetween(detektionssignal.getKoordinaten().getX(), detektionssignal.getKoordinaten().getY(), koordEpi.getX(), koordEpi.getY(), results); float distanceInMeters = results[0]; int sec = (int) distanceInMeters/ detektionssignal.geschwErdbeben; return detektionssignal.getAnkunftsZeit().minusSeconds(sec); } public void erhoheRadius(ArrayList tempEndpunktListe) { for (Endpunkt b : tempEndpunktListe) { b.erhoeheRadius(SCHRITTWEITE); } } }