diff --git a/Praktikum3/NaviConsole/navi.cpp b/Praktikum3/NaviConsole/navi.cpp new file mode 100644 index 0000000000000000000000000000000000000000..81fb7745ac95a6bc1db4cc3a05eea7c3aa408cd8 --- /dev/null +++ b/Praktikum3/NaviConsole/navi.cpp @@ -0,0 +1,526 @@ +#include "navi.h" +#include "adresse.h" +#include "pointofinterest.h" +#include "navidaten.h" +#include <iomanip> +#include <fstream> +#include <sstream> +#include <cstdio> +#include <iostream> + +using namespace std; + +Navi::Navi() +{ + // Ort 1 + adresseAnlegen(49.866260592008715, 8.640719058535762,"h_da FBI", "Schoefferstrasse", "8", "64295", "Darmstadt"); + // Ort 2 + pointOfInterestAnlegen(37.8199067, -122.47858, "Golden Gate Bridge", "Sehenswuerdigkeit", "San Francisco"); + // Ort 3 + adresseAnlegen(-30.050450429460213, -51.222995260791016, "Ronaldinho Gaucho", "Avenida Bastian", "508", "90130", "Porto Alegre"); + // Ort 4 + pointOfInterestAnlegen(49.64142801005189, 8.641502570005786, "Big Doener", "Imbiss", "Heppenheim"); + // Ort 5 + adresseAnlegen(-37.8005036, 144.9672196, "Michael Balzary", "Lygon Street", "178", "3053", "Melbourne"); + // Ort 6 + pointOfInterestAnlegen(43.1900784, 5.649135, "Santa Gusta", "Campingplatz", "Suedfrankreich"); + // Ort 7 + adresseAnlegen(52.373283393129014, 4.899157156353251, "Barrie Butsers", "Monnikenstraat", "1", "1012", "Amsterdam"); + // Ort 8 + pointOfInterestAnlegen(34.1340991, -118.321652, "Hollywood Sign", "Sehenswuerdigkeit", "Hollywood Hills"); + // Ort 9 + adresseAnlegen(35.167275195597924, 135.48913593627927, "Shigeru Miyamoto", "Honoda", "319", "622-8651", "Kyoto"); + // Ort 10 + pointOfInterestAnlegen(40.74106216430664, -73.98960876464844, "Flatiron Building", "Sehenswuerdigkeit", "New York City"); +} + + +Navi::~Navi() { + for (NaviDaten* data : daten) { + delete data; + } +} + +void Navi::runNavigation(){ + Navi navi; + navi.zeigeMenue(); +} +void Navi::adresseAnlegen(double breitengrad, double laengengrad, const std::string& name, const std::string& strasse, const std::string& hausnummer, const std::string& postleitzahl, const std::string& stadt) { + daten.push_back(new Adresse(breitengrad, laengengrad, name, strasse, hausnummer, postleitzahl, stadt)); +} + +void Navi::pointOfInterestAnlegen(double breitengrad, double laengengrad, const std::string& name, const std::string& kategorie, const std::string& bemerkung) { + daten.push_back(new PointOfInterest(breitengrad, laengengrad, name, kategorie, bemerkung)); +} + +void Navi::zeigeKarte() const { + // Header der Tabelle ausgeben + cout << setw(3) << "ID" << " | " + << setw(4) << "Typ" << " | " + << setw(20) << left << "Name" << " | " + << setw(12) << right << "Latitude" << " | " + << setw(13) << right << "Longitude" << " | " + << "Parameters" << endl; + + cout << string(90, '-') << endl; // Trennlinie + + // Jeden Ort in der Tabelle ausgeben + for (const NaviDaten* data : daten) { + cout << setw(3) << data->getID() << " | "; + + const Adresse* adresse = dynamic_cast<const Adresse*>(data); + if (adresse) { + cout << setw(4) << "Adr" << " | " + << setw(20) << left << adresse->getName() << " | " + << setw(12) << right << fixed << setprecision(6) << adresse->getBG() << " | " + << setw(13) << right << fixed << setprecision(6) << adresse->getLG() << " | " + << adresse->getStrasse() << " " << adresse->getHausnummer() << ", " << adresse->getPostleitzahl() << " " << adresse->getStadt(); + } else { + const PointOfInterest* poi = dynamic_cast<const PointOfInterest*>(data); + if (poi) { + cout << setw(4) << "PoI" << " | " + << setw(20) << left << poi->getName() << " | " + << setw(12) << right << fixed << setprecision(6) << poi->getBG() << " | " + << setw(13) << right << fixed << setprecision(6) << poi->getLG() << " | " + << poi->getKategorie() << ", " << poi->getBemerkung(); + } + } + cout << endl; + } +} + + + +NaviDaten *Navi::getOrtByID(int id) const { + for (NaviDaten *data : daten) { + if (data->getID() == id) { + return data; + } + } + return nullptr; +} + + + + +void Navi::exportiereKarte(const std::string& dateiname) const { + ofstream datei(dateiname, ios::binary); + if (!datei) { + cerr << "Fehler beim Öffnen der Datei zum Schreiben." << endl; + return; + } + + int ortSize = daten.size(); + datei.write(reinterpret_cast<char*>(&ortSize), sizeof(ortSize)); + for (NaviDaten* datenpunkt : daten) { + int id = datenpunkt->getID(); + datei.write(reinterpret_cast<char*>(&id), sizeof(id)); + + double laengengrad = datenpunkt->getLG(); + datei.write(reinterpret_cast<char*>(&laengengrad), sizeof(laengengrad)); + + double breitengrad = datenpunkt->getBG(); + datei.write(reinterpret_cast<char*>(&breitengrad), sizeof(breitengrad)); + + bool istAdresse = typeid(*datenpunkt) == typeid(Adresse); + datei.write(reinterpret_cast<char*>(&istAdresse), sizeof(istAdresse)); + + if (istAdresse) { + Adresse* adresse = dynamic_cast<Adresse*>(datenpunkt); + std::string name = adresse->getName(); // Hinzugefügt: Name abrufen + size_t stringSize = name.length() + 1; // Hinzugefügt: Größe des Namens + datei.write(reinterpret_cast<char*>(&stringSize), sizeof(stringSize)); + datei.write(name.c_str(), stringSize); + datei.write("\0", 1); + + std::string strasse = adresse->getStrasse(); + stringSize = strasse.length() + 1; + datei.write(reinterpret_cast<char*>(&stringSize), sizeof(stringSize)); + datei.write(strasse.c_str(), stringSize); + datei.write("\0", 1); + + std::string hausnummer = adresse->getHausnummer(); + stringSize = hausnummer.length() + 1; + datei.write(reinterpret_cast<char*>(&stringSize), sizeof(stringSize)); + datei.write(hausnummer.c_str(), stringSize); + datei.write("\0", 1); + + std::string postleitzahl = adresse->getPostleitzahl(); + stringSize = postleitzahl.length() + 1; + datei.write(reinterpret_cast<char*>(&stringSize), sizeof(stringSize)); + datei.write(postleitzahl.c_str(), stringSize); + datei.write("\0", 1); + + std::string stadt = adresse->getStadt(); + stringSize = stadt.length() + 1; + datei.write(reinterpret_cast<char*>(&stringSize), sizeof(stringSize)); + datei.write(stadt.c_str(), stringSize); + datei.write("\0", 1); + } else { + PointOfInterest* poi = dynamic_cast<PointOfInterest*>(datenpunkt); + std::string name = poi->getName(); // Hinzugefügt: Name abrufen + size_t stringSize = name.length() + 1; // Hinzugefügt: Größe des Namens + datei.write(reinterpret_cast<char*>(&stringSize), sizeof(stringSize)); + datei.write(name.c_str(), stringSize); + datei.write("\0", 1); + + std::string kategorie = poi->getKategorie(); + stringSize = kategorie.length() + 1; + datei.write(reinterpret_cast<char*>(&stringSize), sizeof(stringSize)); + datei.write(kategorie.c_str(), stringSize); + datei.write("\0", 1); + + std::string bemerkung = poi->getBemerkung(); + stringSize = bemerkung.length() + 1; + datei.write(reinterpret_cast<char*>(&stringSize), sizeof(stringSize)); + datei.write(bemerkung.c_str(), stringSize); + datei.write("\0", 1); + } + } + + datei.close(); +} + +void Navi::importiereKarte(const std::string& dateiname) { + for (NaviDaten* datenpunkt : daten) { + delete datenpunkt; + } + + daten.clear(); + ifstream datei(dateiname, ios::binary); + if (!datei) { + cerr << "Fehler beim Öffnen der Datei zum Lesen." << endl; + return; + } + + int id, ortSize; + double laengengrad, breitengrad; + size_t stringSize; + char terminator = '\0'; + + datei.read(reinterpret_cast<char*>(&ortSize), sizeof(ortSize)); + for (int i = 0; i < ortSize; i++) { + datei.read(reinterpret_cast<char*>(&id), sizeof(id)); + datei.read(reinterpret_cast<char*>(&laengengrad), sizeof(laengengrad)); + datei.read(reinterpret_cast<char*>(&breitengrad), sizeof(breitengrad)); + + bool istAdresse; + datei.read(reinterpret_cast<char*>(&istAdresse), sizeof(istAdresse)); + + char strBuffer[160] = {}; + + if (istAdresse) { + std::string name, strasse, hausnummer, postleitzahl, stadt; + + datei.read(reinterpret_cast<char*>(&stringSize), sizeof(stringSize)); + datei.read(strBuffer, stringSize); + name = strBuffer; + datei.read(reinterpret_cast<char*>(&terminator),1); + + datei.read(reinterpret_cast<char*>(&stringSize), sizeof(stringSize)); + datei.read(strBuffer, stringSize); + strasse = strBuffer; + datei.read(reinterpret_cast<char*>(&terminator),1); + + datei.read(reinterpret_cast<char*>(&stringSize), sizeof(stringSize)); + datei.read(strBuffer, stringSize); + hausnummer = strBuffer; + datei.read(reinterpret_cast<char*>(&terminator),1); + + datei.read(reinterpret_cast<char*>(&stringSize), sizeof(stringSize)); + datei.read(strBuffer, stringSize); + postleitzahl = strBuffer; + datei.read(reinterpret_cast<char*>(&terminator),1); + + datei.read(reinterpret_cast<char*>(&stringSize), sizeof(stringSize)); + datei.read(strBuffer, stringSize); + stadt = strBuffer; + datei.read(reinterpret_cast<char*>(&terminator),1); + + Adresse* adresse = new Adresse(laengengrad, breitengrad, name, strasse, hausnummer, postleitzahl, stadt); // Hinzugefügt: Name + adresse->setID(id); + daten.push_back(adresse); + } else { + std::string name, kategorie, bemerkung; + + datei.read(reinterpret_cast<char*>(&stringSize), sizeof(stringSize)); + datei.read(strBuffer, stringSize); + name = strBuffer; + datei.read(reinterpret_cast<char*>(&terminator),1); + + datei.read(reinterpret_cast<char*>(&stringSize), sizeof(stringSize)); + datei.read(strBuffer, stringSize); + kategorie = strBuffer; + datei.read(reinterpret_cast<char*>(&terminator),1); + + datei.read(reinterpret_cast<char*>(&stringSize), sizeof(stringSize)); + datei.read(strBuffer, stringSize); + bemerkung = strBuffer; + datei.read(reinterpret_cast<char*>(&terminator),1); + + PointOfInterest* poi = new PointOfInterest(laengengrad, breitengrad, name, kategorie, bemerkung); + poi->setID(id); + daten.push_back(poi); + } + } + + datei.close(); +} + + + +void Navi::exportiereKarteCSV(const std::string& dateiname) { + ofstream datei(dateiname); + if (!datei) { + cerr << "Fehler beim Öffnen der Datei zum Schreiben." << endl; + return; + } + + for (NaviDaten* datenpunkt : daten) { + datei << datenpunkt->getID() << "," + << datenpunkt->getLG() << "," + << datenpunkt->getBG(); + + if (Adresse* adresse = dynamic_cast<Adresse*>(datenpunkt)) { + datei << "," << "Adresse" << "," + << adresse->getName() << "," // Hinzugefügt: Name + << adresse->getStrasse() << "," + << adresse->getHausnummer() << "," + << adresse->getPostleitzahl() << "," + << adresse->getStadt(); + } else if (PointOfInterest* poi = dynamic_cast<PointOfInterest*>(datenpunkt)) { + datei << "," << "PointOfInterest" << "," + << poi->getName() << "," // Hinzugefügt: Name + << poi->getKategorie() << "," + << poi->getBemerkung(); + } + + datei << "\n"; + } + + datei.close(); +} + +void Navi::importiereKarteCSV(const std::string& dateiname) { + ifstream datei(dateiname); + if (!datei) { + cerr << "Fehler beim Öffnen der Datei zum Lesen." << endl; + return; + } + + for (NaviDaten* datenpunkt : daten) { + delete datenpunkt; + } + daten.clear(); + + std::string zeile; + while (std::getline(datei, zeile)) { + std::stringstream ss(zeile); + std::string feld; + + int id; + double laengengrad, breitengrad; + std::string typ; + + std::getline(ss, feld, ','); + id = std::stoi(feld); + + std::getline(ss, feld, ','); + laengengrad = std::stod(feld); + + std::getline(ss, feld, ','); + breitengrad = std::stod(feld); + + std::getline(ss, typ, ','); + + if (typ == "Adresse") { + std::string name, strasse, hausnummer, postleitzahl, stadt; + + std::getline(ss, name, ','); // Hinzugefügt: Name + std::getline(ss, strasse, ','); + std::getline(ss, hausnummer, ','); + std::getline(ss, postleitzahl, ','); + std::getline(ss, stadt, ','); + + Adresse* adresse = new Adresse(laengengrad, breitengrad, name, strasse, hausnummer, postleitzahl, stadt); + adresse->setID(id); + daten.push_back(adresse); + } else if (typ == "PointOfInterest") { + std::string name, kategorie, bemerkung; + + std::getline(ss, name, ','); // Hinzugefügt: Name + std::getline(ss, kategorie, ','); + std::getline(ss, bemerkung, ','); + + PointOfInterest* poi = new PointOfInterest(laengengrad, breitengrad, name, kategorie, bemerkung); + poi->setID(id); + daten.push_back(poi); + } + } + + datei.close(); +} + + + + +void Navi::zeigeMenue(){ + while (true) { + + int auswahl; + cout << "Navigationssystem" << endl; + cout << endl; + cout << "(1) Ort anlegen " << endl; + cout << "(2) Karte anzeigen " << endl; + cout << "(3) Entfernung berechnen " << endl; + cout << "(4) Karte exportieren/importieren " << endl; + cout << "(0) Programm verlassen " << endl; + cin >> auswahl; + + switch (auswahl) { + case 1:{ + // Ort anlegen + double laengengrad, breitengrad; + char auswahl; + cout << "Adresse (A) oder Point of Interest (P) anlegen? " << endl; + cin >> auswahl; + + cout << "Geben Sie den Laengengrad und den Breitengrad des Ortes ein: " << endl; + cin >> laengengrad >> breitengrad; + + if (auswahl == 'A' || auswahl == 'a') { + string name, strasse, hausnummer, postleitzahl, stadt; + cin.ignore(); + cout << "Geben Sie den Namen, die Strasse, die Hausnummer, die Postleitzahl und die Stadt der Adresse ein: "; + getline(cin, name); + getline(cin, strasse); + getline(cin, hausnummer); + getline(cin, postleitzahl); + getline(cin, stadt); + adresseAnlegen(laengengrad, breitengrad, name, strasse, hausnummer, postleitzahl, stadt); + cout << "Adresse wurde erfolgreich angelegt." << endl; + } else if (auswahl == 'P' || auswahl == 'p') { + string name, kategorie, bemerkung; + cin.ignore(); + cout << "Geben Sie den Namen, die Kategorie und die Bemerkung des Points of Interest ein: "; + getline(cin, name); + getline(cin, kategorie); + getline(cin, bemerkung); + pointOfInterestAnlegen(laengengrad, breitengrad, name, kategorie, bemerkung); + cout << "Point of Interest wurde erfolgreich angelegt." << endl; + } else { + cout << "Ungültige Auswahl, bitte erneut eingeben." << endl; + } + break; + } + case 2:{ + // Karte anzeigen + zeigeKarte(); + break; + } + case 3: { + // Entfernungen berechnen + int id1, id2; + cout << "Geben Sie die ID des ersten Ortes ein: "; + cin >> id1; + cout << "Geben Sie die ID des zweiten Ortes ein: "; + cin >> id2; + + Ort *ort1 = getOrtByID(id1); + Ort *ort2 = getOrtByID(id2); + + if (ort1 && ort2) { + double entfernung = ort1->berechneEntfernung(*ort2); + cout << "Die Entfernung zwischen Ort " << id1 << " und Ort " << id2 << " betraegt: " << entfernung << " km." << endl; + } else { + cout << "Mindestens einer der eingegebenen IDs ist ungültig." << endl; + } + break; + } + case 4: { + // Karte exportieren/importieren + int subAuswahl; + cout << "(1) Karte exportieren .bin-Format " << endl; + cout << "(2) Karte importieren .bin-Format " << endl; + cout << "(3) Karte exportieren CSV-Format " << endl; + cout << "(4) Karte importieren CSV-Format " << endl; + cout << "(5) Karte Bin exportieren und CSV importieren " << endl; + cin >> subAuswahl; + switch (subAuswahl) { + case 1: { + // Karte exportieren bin + string dateiname; + cin.ignore(); + cout << "Geben Sie den Dateinamen für den Export ein: "; + getline(cin, dateiname); + exportiereKarte(dateiname); + cout << "Karte wurde erfolgreich exportiert." << endl; + break; + } + case 2: { + // Karte importieren bin + string dateiname; + cin.ignore(); + cout << "Geben Sie den Dateinamen für den Import ein: "; + getline(cin, dateiname); + importiereKarte(dateiname); + cout << "Karte wurde erfolgreich importiert." << endl; + break; + } + case 3: { + // Karte exportieren csv + string dateiname; + cin.ignore(); + cout << "Geben Sie den Dateinamen für den Export ein: "; + getline(cin, dateiname); + exportiereKarteCSV(dateiname); + cout << "Karte wurde erfolgreich exportiert." << endl; + break; + } + case 4: { + // Karte importieren csv + string dateiname; + cin.ignore(); + cout << "Geben Sie den Dateinamen für den Import ein: "; + getline(cin, dateiname); + importiereKarteCSV(dateiname); + cout << "Karte wurde erfolgreich importiert." << endl; + break; + } + + case 5: { + // Karte Bin exportieren und CSV importieren + string binDateiname, csvDateiname; + cin.ignore(); + cout << "Geben Sie den Dateinamen für den Export im Binärformat ein: "; + getline(cin, binDateiname); + exportiereKarte(binDateiname); + cout << "Karte wurde erfolgreich im Binärformat exportiert." << endl; + + cout << "Geben Sie den Dateinamen für den Import im CSV-Format ein: "; + getline(cin, csvDateiname); + exportiereKarteCSV(csvDateiname); + cout << "Karte wurde erfolgreich im CSV-Format importiert." << endl; + break; + } + + + + default: { + cout << "Ungültige Auswahl, bitte erneut eingeben." << endl; + break; + } + } + break; + } + case 0:{ + // Programm verlassen + + } + default:{ + cout << "Ungültige Eingabe. Bitte versuchen Sie es erneut." << endl; + break; + } + } +} +}