package de.edotzlaff.detection; | package de.edotzlaff.detection; | ||||
import android.os.Build; | |||||
import android.util.Log; | |||||
import androidx.annotation.RequiresApi; | |||||
import androidx.fragment.app.FragmentActivity; | import androidx.fragment.app.FragmentActivity; | ||||
import android.os.Bundle; | import android.os.Bundle; | ||||
import com.google.android.gms.maps.model.BitmapDescriptorFactory; | import com.google.android.gms.maps.model.BitmapDescriptorFactory; | ||||
import com.google.android.gms.maps.model.LatLng; | import com.google.android.gms.maps.model.LatLng; | ||||
import com.google.android.gms.maps.model.MarkerOptions; | import com.google.android.gms.maps.model.MarkerOptions; | ||||
import de.edotzlaff.detection.detektion.Detektionssignal; | |||||
import de.edotzlaff.detection.detektion.Epizentrum; | |||||
import de.edotzlaff.detection.detektion.Erdbeben; | |||||
import java.util.ArrayList; | |||||
import java.util.Objects; | |||||
public class EarthquakeLocation extends FragmentActivity implements OnMapReadyCallback { | public class EarthquakeLocation extends FragmentActivity implements OnMapReadyCallback { | ||||
private GoogleMap mMap; | private GoogleMap mMap; | ||||
private static final String TAGEPIZENTRUM = "Epizentrum"; | |||||
@Override | @Override | ||||
protected void onCreate(Bundle savedInstanceState) { | protected void onCreate(Bundle savedInstanceState) { | ||||
//TODO Jan | //TODO Jan | ||||
@RequiresApi(api = Build.VERSION_CODES.O) | |||||
public Epizentrum ermittleEpizentrum(DataSnapshot data) | |||||
{ | |||||
Erdbeben erdbeben = new Erdbeben(); | |||||
erdbeben.addDetektionssignalList(mapToDetektionssignale(data)); | |||||
Epizentrum epizentrum = new Epizentrum(); | |||||
epizentrum = erdbeben.ermittleEpizentrum(); | |||||
if(Objects.isNull(epizentrum)) | |||||
{ | |||||
Log.i(TAGEPIZENTRUM, "Kein Epizentrum vorhanden"); | |||||
} | |||||
else | |||||
{ | |||||
Log.i(TAGEPIZENTRUM, "Epizentrum konnte ermittelt werden, Koordinaten: " + epizentrum.getKoordinaten().getX() + " " + epizentrum.getKoordinaten().getY()); | |||||
} | |||||
return epizentrum; | |||||
} | |||||
public ArrayList<Detektionssignal> mapToDetektionssignale(DataSnapshot data) | |||||
{ | |||||
ArrayList<Detektionssignal> detektionssignale = new ArrayList<>(); | |||||
for(data.child("overviewnodes").getChildernKey) | |||||
{ | |||||
Detektionssignal detektionssignal = new Detektionssignal(); | |||||
detektionssignal.setAnkunftsZeit(); | |||||
detektionssignal.setDeviceId(); | |||||
detektionssignal.setKoordinaten(data.child("overviewnodes").child("IDG" + f).child("d_breitengrad").getValue().toString(), | |||||
data.child("overviewnodes").child("IDG" + f).child("e_laengengrad").getValue().toString()); | |||||
detektionssignal.setGeschwErdbeben(); | |||||
detektionssignale.add(detektionssignal); | |||||
} | |||||
return detektionssignale; | |||||
} | |||||
//################################################################## ^^^^ Calculate Epicenter ^^^^ ####################################################################### | //################################################################## ^^^^ Calculate Epicenter ^^^^ ####################################################################### | ||||
//########################################################################################################################################################################## | //########################################################################################################################################################################## | ||||
package de.edotzlaff.detection.detektion; | |||||
import de.edotzlaff.detection.detektion.berechnung.mathObjekte.Koordinaten; | |||||
import java.time.LocalDateTime; | |||||
public class Detektionssignal { | |||||
public String deviceId; | |||||
public String getDeviceId() { | |||||
return deviceId; | |||||
} | |||||
public void setDeviceId(String deviceId) { | |||||
this.deviceId = deviceId; | |||||
} | |||||
public Koordinaten getKoordinaten() { | |||||
return koordinaten; | |||||
} | |||||
public void setKoordinaten(Koordinaten koordinaten) { | |||||
this.koordinaten = koordinaten; | |||||
} | |||||
public int getGeschwErdbeben() { | |||||
return geschwErdbeben; | |||||
} | |||||
public void setGeschwErdbeben(int geschwErdbeben) { | |||||
this.geschwErdbeben = geschwErdbeben; | |||||
} | |||||
public LocalDateTime getAnkunftsZeit() { | |||||
return ankunftsZeit; | |||||
} | |||||
public void setAnkunftsZeit(LocalDateTime ankunftsZeit) { | |||||
this.ankunftsZeit = ankunftsZeit; | |||||
} | |||||
public Koordinaten koordinaten; | |||||
public int geschwErdbeben; | |||||
public LocalDateTime ankunftsZeit; | |||||
} |
package de.edotzlaff.detection.detektion; | |||||
import de.edotzlaff.detection.detektion.berechnung.mathObjekte.Koordinaten; | |||||
import java.time.LocalDateTime; | |||||
public class Epizentrum { | |||||
public Koordinaten koordinaten; | |||||
public LocalDateTime entstehungsZeitpunkt; | |||||
public Koordinaten getKoordinaten() { | |||||
return koordinaten; | |||||
} | |||||
public void setKoordinaten(Koordinaten koordinaten) { | |||||
this.koordinaten = koordinaten; | |||||
} | |||||
public LocalDateTime getEntstehungsZeitpunkt() { | |||||
return entstehungsZeitpunkt; | |||||
} | |||||
public void setEntstehungsZeitpunkt(LocalDateTime entstehungsZeitpunkt) { | |||||
this.entstehungsZeitpunkt = entstehungsZeitpunkt; | |||||
} | |||||
} |
package de.edotzlaff.detection.detektion; | |||||
import android.os.Build; | |||||
import androidx.annotation.RequiresApi; | |||||
import de.edotzlaff.detection.detektion.berechnung.Endpunkt; | |||||
import de.edotzlaff.detection.detektion.berechnung.EndpunktVerbindung; | |||||
import de.edotzlaff.detection.detektion.berechnung.EpizentrumRechnung; | |||||
import java.util.ArrayList; | |||||
import java.util.HashMap; | |||||
import java.util.Objects; | |||||
public class Erdbeben { | |||||
public int geschwErdbeben = 1; | |||||
private Epizentrum epizentrum; | |||||
private EpizentrumRechnung epizentrumRechnung; | |||||
private HashMap<String, Detektionssignal> nutzerDaten; | |||||
public Erdbeben() { | |||||
nutzerDaten = new HashMap<>(); | |||||
epizentrumRechnung = new EpizentrumRechnung(); | |||||
epizentrum = new Epizentrum(); | |||||
} | |||||
public int addDetektionssignal(Detektionssignal detektionssignal) { | |||||
nutzerDaten.put(detektionssignal.getDeviceId(), detektionssignal); | |||||
return nutzerDaten.size(); | |||||
} | |||||
public void addDetektionssignalList(ArrayList<Detektionssignal> detektionssignale) | |||||
{ | |||||
for (int i = 0; i< detektionssignale.size(); i++) | |||||
{ | |||||
nutzerDaten.put(detektionssignale.get(i).getDeviceId(),detektionssignale.get(i)); | |||||
} | |||||
} | |||||
@RequiresApi(api = Build.VERSION_CODES.O) | |||||
public Epizentrum ermittleEpizentrum() { | |||||
ArrayList<Detektionssignal> rechenListe = new ArrayList<>(); | |||||
nutzerDaten.forEach((key, value) -> rechenListe.add(value)); | |||||
//Initialisierung der Rechung - First Element mit delta r + alle möglichen EndpunktKombinationen (einfach) | |||||
ArrayList<Endpunkt> berechnungsEndpunkte = epizentrumRechnung.initEndpunkte(rechenListe); | |||||
ArrayList<EndpunktVerbindung> endpunktKonbinationen = epizentrumRechnung.ermittleEndpunktKonbinationen(berechnungsEndpunkte); | |||||
//ToDo Vernünftiger Endpunkt überlegen bzw. bis wann abgebrochen wird -> Umzug in Berechnungs | |||||
for (int i = 0; i <= 600; i++) { | |||||
if (epizentrumRechnung.genuegendSchnittpunktevorhanden(endpunktKonbinationen)) { | |||||
epizentrum = epizentrumRechnung.ueberpruefeObEpizentrum(endpunktKonbinationen); | |||||
//ToDo set EnstehungsZeitpunkt -> (Bezugszeit, Koord, Koord, v;) | |||||
if (!Objects.isNull(epizentrum)) { | |||||
System.out.println("Epizentrum ermittelt"); | |||||
epizentrum.setEntstehungsZeitpunkt( | |||||
epizentrumRechnung.berechneEntstehungsZeitpunkt( | |||||
nutzerDaten.get(berechnungsEndpunkte.get(0).getNutzer()), epizentrum.getKoordinaten())); | |||||
return epizentrum; | |||||
} | |||||
} | |||||
epizentrumRechnung.erhoheRadius(berechnungsEndpunkte); | |||||
} | |||||
return null; | |||||
} | |||||
} |
package de.edotzlaff.detection.detektion.berechnung; | |||||
import de.edotzlaff.detection.detektion.berechnung.mathObjekte.Kreis; | |||||
public class Endpunkt { | |||||
public String nutzer; | |||||
public String getNutzer() { | |||||
return nutzer; | |||||
} | |||||
public void setNutzer(String nutzer) { | |||||
this.nutzer = nutzer; | |||||
} | |||||
public Kreis getKreis() { | |||||
return kreis; | |||||
} | |||||
public void setKreis(Kreis kreis) { | |||||
this.kreis = kreis; | |||||
} | |||||
public Kreis kreis; | |||||
public Endpunkt(String nutzer) | |||||
{ | |||||
this.nutzer = nutzer; | |||||
} | |||||
public void erhoeheRadius(double deltaR) | |||||
{ | |||||
kreis.setRadius(kreis.getRadius() + deltaR); | |||||
} | |||||
} |
package de.edotzlaff.detection.detektion.berechnung; | |||||
import de.edotzlaff.detection.detektion.berechnung.mathObjekte.Schnittpunkt; | |||||
import java.util.ArrayList; | |||||
public class EndpunktVerbindung { | |||||
public Endpunkt endpunkt1; | |||||
public Endpunkt endpunkt2; | |||||
public Endpunkt getEndpunkt1() { | |||||
return endpunkt1; | |||||
} | |||||
public void setEndpunkt1(Endpunkt endpunkt1) { | |||||
this.endpunkt1 = endpunkt1; | |||||
} | |||||
public Endpunkt getEndpunkt2() { | |||||
return endpunkt2; | |||||
} | |||||
public void setEndpunkt2(Endpunkt endpunkt2) { | |||||
this.endpunkt2 = endpunkt2; | |||||
} | |||||
public ArrayList<Schnittpunkt> getSchnittpunkte() { | |||||
return schnittpunkte; | |||||
} | |||||
public void setSchnittpunkte(ArrayList<Schnittpunkt> schnittpunkte) { | |||||
this.schnittpunkte = schnittpunkte; | |||||
} | |||||
public ArrayList<Schnittpunkt> schnittpunkte; | |||||
public EndpunktVerbindung(Endpunkt endpunkt1, Endpunkt endpunkt2) | |||||
{ | |||||
this.endpunkt1 = endpunkt1; | |||||
this.endpunkt2 = endpunkt2; | |||||
} | |||||
} |
package de.edotzlaff.detection.detektion.berechnung; | |||||
import android.os.Build; | |||||
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 { | |||||
private static final double SCHRITTWEITE = 0.02; | |||||
private static final double MAX_ABSTAND = 0.009; | |||||
private static final int DOUBLESTELLEN = 8; | |||||
@RequiresApi(api = Build.VERSION_CODES.O) | |||||
public ArrayList<Endpunkt> initEndpunkte(ArrayList<Detektionssignal> detektionssignal) { | |||||
Detektionssignal nahegelegensteMessung = detektionssignal.get(0); | |||||
ArrayList<Endpunkt> arrBerechnungsObjekte = new ArrayList<>(); | |||||
for (int i = 1; i < detektionssignal.size(); i++) { | |||||
if (detektionssignal.get(i).getAnkunftsZeit().isBefore(nahegelegensteMessung.getAnkunftsZeit())) { | |||||
nahegelegensteMessung = detektionssignal.get(i); | |||||
} | |||||
} | |||||
for (Detektionssignal aufzeichnung : detektionssignal) { | |||||
int zeitunterschied = aufzeichnung.getAnkunftsZeit().getHour() * 3600 + aufzeichnung.getAnkunftsZeit().getMinute() * 60 + aufzeichnung.getAnkunftsZeit().getSecond() | |||||
- nahegelegensteMessung.getAnkunftsZeit().getHour() * 3600 - nahegelegensteMessung.getAnkunftsZeit().getMinute() * 60 - nahegelegensteMessung.getAnkunftsZeit().getSecond(); | |||||
double startradius = zeitunterschied * aufzeichnung.getGeschwErdbeben(); | |||||
Endpunkt tempEndpunkt = new Endpunkt(aufzeichnung.getDeviceId()); | |||||
Kreis k = new Kreis(aufzeichnung.getKoordinaten().getX(), aufzeichnung.getKoordinaten().getY(), startradius); | |||||
tempEndpunkt.setKreis(k); | |||||
arrBerechnungsObjekte.add(tempEndpunkt); | |||||
} | |||||
return arrBerechnungsObjekte; | |||||
} | |||||
public ArrayList<Schnittpunkt> berechneKreisSchnittpunkte(Kreis kreis1, Kreis kreis2) { | |||||
ArrayList<Schnittpunkt> 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<EndpunktVerbindung> endpunktVerbindungen) { | |||||
for (EndpunktVerbindung endpunktVerbindung : endpunktVerbindungen) { | |||||
ArrayList<Schnittpunkt> templist; | |||||
templist = berechneKreisSchnittpunkte(endpunktVerbindung.getEndpunkt1().getKreis(), endpunktVerbindung.getEndpunkt2().getKreis()); | |||||
if (templist.isEmpty()) { | |||||
return false; | |||||
} | |||||
endpunktVerbindung.setSchnittpunkte(templist); | |||||
} | |||||
return true; | |||||
} | |||||
public Epizentrum ueberpruefeObEpizentrum(ArrayList<EndpunktVerbindung> endpunktVerbindungen) { | |||||
int counter; | |||||
ArrayList<Schnittpunkt> 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(); | |||||
tempEpizentrum.setKoordinaten(berechneEpizentrumKoordinaten(schnittpunkte)); | |||||
return tempEpizentrum; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
public Koordinaten berechneEpizentrumKoordinaten(ArrayList<Schnittpunkt> schnittpunkte) { | |||||
double x = 0; | |||||
double y = 0; | |||||
for (Schnittpunkt s : schnittpunkte) { | |||||
x+= s.getKoordinaten().getX(); | |||||
y+= s.getKoordinaten().getY(); | |||||
} | |||||
return new Koordinaten(new BigDecimal(x/schnittpunkte.size()).setScale(DOUBLESTELLEN, RoundingMode.HALF_UP).doubleValue(), | |||||
new BigDecimal(y/schnittpunkte.size()).setScale(DOUBLESTELLEN, RoundingMode.HALF_UP).doubleValue()); | |||||
} | |||||
public ArrayList<EndpunktVerbindung> ermittleEndpunktKonbinationen(ArrayList<Endpunkt> tempBerechungsObjekte) { | |||||
ArrayList<EndpunktVerbindung> verbindungen = new ArrayList<>(); | |||||
Set<Set<Endpunkt>> combinations = Sets.combinations(ImmutableSet.copyOf(tempBerechungsObjekte), 2); | |||||
for (Set<Endpunkt> tempEndpunkt : combinations) { | |||||
ArrayList<Endpunkt> helpArrayToGetValues = new ArrayList<>(tempEndpunkt); | |||||
EndpunktVerbindung endpunktVerbindung = new EndpunktVerbindung(helpArrayToGetValues.get(0), helpArrayToGetValues.get(1)); | |||||
verbindungen.add(endpunktVerbindung); | |||||
} | |||||
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); | |||||
} | |||||
public void erhoheRadius(ArrayList<Endpunkt> tempEndpunktListe) { | |||||
for (Endpunkt b : tempEndpunktListe) { | |||||
b.erhoeheRadius(SCHRITTWEITE); | |||||
} | |||||
} | |||||
} |
package de.edotzlaff.detection.detektion.berechnung.mathObjekte; | |||||
public class Koordinaten { | |||||
public double x; | |||||
public double y; | |||||
public double getX() { | |||||
return x; | |||||
} | |||||
public void setX(double x) { | |||||
this.x = x; | |||||
} | |||||
public double getY() { | |||||
return y; | |||||
} | |||||
public void setY(double y) { | |||||
this.y = y; | |||||
} | |||||
public Koordinaten(double x, double y) | |||||
{ | |||||
this.x = x; | |||||
this.y = y; | |||||
} | |||||
public void setLocation(double x, double y) | |||||
{ | |||||
this.x = x; | |||||
this.y = y; | |||||
} | |||||
} |
package de.edotzlaff.detection.detektion.berechnung.mathObjekte; | |||||
public class Kreis { | |||||
public Koordinaten mittelPunkt; | |||||
public double radius; | |||||
public Kreis(double x, double y, double radius) { | |||||
mittelPunkt = new Koordinaten(x,y); | |||||
this.radius = radius; | |||||
} | |||||
public Koordinaten getMittelPunkt() { | |||||
return mittelPunkt; | |||||
} | |||||
public void setMittelPunkt(Koordinaten mittelPunkt) { | |||||
this.mittelPunkt = mittelPunkt; | |||||
} | |||||
public double getRadius() { | |||||
return radius; | |||||
} | |||||
public void setRadius(double radius) { | |||||
this.radius = radius; | |||||
} | |||||
} |
package de.edotzlaff.detection.detektion.berechnung.mathObjekte; | |||||
public class Schnittpunkt { | |||||
public Koordinaten koordinaten; | |||||
public Schnittpunkt(double x, double y) { | |||||
koordinaten = new Koordinaten(x,y); | |||||
} | |||||
public Koordinaten getKoordinaten() { | |||||
return koordinaten; | |||||
} | |||||
public void setKoordinaten(Koordinaten koordinaten) { | |||||
this.koordinaten = koordinaten; | |||||
} | |||||
} |