Select Git revision
CustomCamera.js
-
Herman Andersen Dyrkorn authoredHerman Andersen Dyrkorn authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
ruter.cpp 11.61 KiB
/**
* Kode-fil for ruter-klassen
*
* @file ruter.cpp
* @author Sondre Sand & Frederik Simonsen
*/
#include <fstream>
#include <iostream>
#include <map>
#include "LesData3.h"
#include "ruter.h"
#include "rute.h"
#include "bane.h"
#include "buss.h"
#include "const.h"
#include "stoppesteder.h"
using namespace std;
extern Stoppesteder gStoppestederBase; // Henter inn globalt objekt
/**
* Sletter allokert minne i Ruter-mappet
*/
Ruter::~Ruter() {
for (auto it = rutene.begin(); it != rutene.end(); it++)
delete it->second; // Sletter det tilpekte
rutene.clear(); // Tømmer mappet for pekere
}
/**
* Sjekker om et gitt ruteNr finnes i datastrukturen
*
* @param ruteNr - Et ruteNr som skal sjekkes om finnes eller ei
* @return true - Rutenr finnes i datastrukturen
* @return false - Rutenr finnes ikke i datastrukturen
*/
bool Ruter::ruteNrFinnes(const int ruteNr) {
return rutene.count(ruteNr);
}
/**
* endreRute()
*/
void Ruter::endreRute() {
int ruteNr;
char valg;
if (!rutene.empty()) { // Hvis det finnes ruter registrert:
ruteNr = lesInt("Rutenr", MINRUTER, MAXRUTER);
if (ruteNrFinnes(ruteNr)) { // Hvis rutenummeret finnes:
auto ruten = rutene.find(ruteNr); // Iterator til rett rute
ruten->second->skrivKort(); // Skriver egen info
ruten->second->skrivRute(Fram); // Skriver ruta
cout << '\n';
// Leser valg fra bruker:
valg = lesChar("F(jerne intervall) eller S(mette inn)");
// Looper til lovlig valg fra bruker:
while (valg != 'F' && valg != 'S') {
cout << "\nUgyldig valg, prøv igjen. F og S er gyldig\n";
valg = lesChar("F(jerne intervall) eller S(mette inn)");
}
switch (valg) { // Sender til rett funksjon etter brukervalg:
case 'F': ruten->second->fjernStopp(); break;
case 'S': ruten->second->smettStopp(); break;
}
} else // Rutenummeret finnes ikke:
cout << "\nIngen ruter registrert med dette nummeret.\n\n";
} else // Ingen ruter registrert:
cout << "\nIngen ruter registrert i programmet.\n\n";
}
/**
* Funksjon som håndterer ulike menyvalg fra bruker
*
* @see Ruter::skrivMeny()
* @see Ruter::nyRute()
* @see Ruter::skrivAlle()
* @see Ruter::endreRute()
* @see Ruter::ruteBeskrivelse()
* @see Ruter::ruteTabell()
*/
void Ruter::handling() {
char valg;
skrivMeny();
valg = lesChar("\nKommando");
switch (valg) {
case 'N': nyRute(); break;
case 'A': skrivAlle(); break;
case 'E': endreRute(); break;
case 'B': ruteBeskrivelse(); break;
case 'T': ruteTabell(); break;
default: cout << "\nUlovlig kommando!\n"; break;
}
}
/**
* Leser informasjon om ruter fra fil
*/
void Ruter::lesFraFil() {
int key, // Rutenr, nøkkel til unik rute
antRuter; // antall ruter å lese
char ruteType; // U (=buss), A (=bane)
ifstream innfil("ruter.dta"); // Åpner aktuell fil
if (innfil) { // Hvis filen funnet:
cout << "Leser fra filen 'ruter.dta'...\n";
innfil >> antRuter; innfil.ignore(); // Leser antall ruter
innfil >> key; // Prøver å lese første port
while (!innfil.eof()) { // Så lenge ikke slutt på fil:
innfil >> ruteType; innfil.ignore();
switch (ruteType) { // Oppretter korrekt type objekt:
case 'U': rutene[key] = new Buss(innfil); break;
case 'A': rutene[key] = new Bane(innfil); break;
}
innfil >> key; // Forsøker å lese neste post:
}
innfil.close(); // Lukker aktuell fil
} else // Filen finnes ikke / kunne ikke åpnes:
cout << "\nFant ikke filen 'ruter.dta'...\n";
}
/**
* Lager ny rute og putter den inn der det skal
* så lenge ruten har mer enn 1 stopp.
*
* @see Ruter::ruteNrFinnes(...)
* @see Rute::lesData()
* @see Bane::lesData()
* @see Buss::lesData()
* @see Rute::erListeGyldig()
* @see Ruter::ruteBeskrivelse(...)
* @see Rute::slettData()
*/
void Ruter::nyRute() {
int ruteNr;
char ruteType;
Rute* nyRute = nullptr;
if (!gStoppestederBase.tom()) { // Hvis det finnes stoppesteder registrert:
ruteNr = lesInt("Rutenr", MINRUTER, MAXRUTER);
// Hvis ikke duplikat rutenr blir skrevet inn:
if (!ruteNrFinnes(ruteNr)) {
ruteType = lesChar("Rutetype b(A)ne eller b(U)ss");
// Looper til lovlig valg av rutetype blir lest inn:
while (ruteType != 'A' && ruteType != 'U') {
cout << "\nUgyldig valg, prøv igjen.\n";
ruteType = lesChar("Rutetype b(A)ne eller b(U)ss");
}
switch (ruteType) { // Oppretter korrekt type objekt:
case 'A': nyRute = new Bane; nyRute->lesData(); break;
case 'U': nyRute = new Buss; nyRute->lesData(); break;
}
if (nyRute->erListeGyldig()) { // Hvis >1 stopp på ruten:
rutene[ruteNr] = nyRute; // Lagrer ruten
cout << "\nNy rute er lagt til:\n";
ruteBeskrivelse(ruteNr); // Skriver ut ruten
} else {
nyRute->slettData(); // <1 stopp, sletter ruten
delete nyRute; // Sletter peker, ved ugyldig rute
}
} else // Rutenummer er duplikat:
cout << "\nRutenummeret finnes fra før. Kan ikke legge til rute.\n\n";
} else // Hvis ingen stoppesteder registrert:
cout << "\nIngen stopper registrert i datastrukturen, kan derfor ikke "
<< "opprette ny rute for øyeblikket.\n\n";
}
/**
* Ber om et rutenummer, skriver ut gitt rute
*
* @see Rute::skrivBeskrivelse()
* @see Buss::skrivBeskrivelse()
* @see Bane::skrivBeskrivelse()
*/
void Ruter::ruteBeskrivelse() {
int ruteNr;
ruteNr = lesInt("\nRutenr", MINRUTER, MAXRUTER);
auto it = rutene.find(ruteNr); // Forsøker å finne aktuelt rutenr:
if (it != rutene.end()) { // Funn, skriver ut ruten
it->second->skrivBeskrivelse();
} else // Hvis rutenr ikke finnes i datastrukturen:
cout << "\nRuten med dette rutenr eksisterer ikke..\n";
}
/**
* skriver ut rute fra medsendt nummer (som garantert finnes).
* brukes for å skrive rute når den først blir laget.
*
* @param ruteNr Rutenummeret til ruten som skal skrives ut
* @see Rute::skrivBeskrivelse()
* @see Bane::skrivBeskrivelse()
* @see Buss::skrivBeskrivelse()
*/
void Ruter::ruteBeskrivelse(const int ruteNr){
auto it = rutene.find(ruteNr);
it->second->skrivBeskrivelse();
}
/**
* Tilbyr bruker å opprette en rutetabell for et angitt stoppested
* hvor tid skal regnes om fra rutens startstoppested uavhengig
* om ruten skrives "forlengs" eller "baklengs"
*
* @see Ruter::ruteNrFinnes(...)
* @see Rute::skriveRetninger()
* @see Rute::skrivKort()
* @see Bane::skrivKort()
* @see Buss::skrivKort()
* @see Rute:skrivRute(...)
* @see Rute::hentNavn(...)
* @see Stoppesteder::byttBokstaver(...)
* @see Stoppesteder::finnEntydig(...)
* @see Stoppesteder::hentIndeksVhaNavn(...)
* @see Rute::finnesStopp(...)
* @see Rute::finnDifferanse(...)
* @see Rute::ruteTabell(...)
*/
void Ruter::ruteTabell() {
int ruteNr,
stoppNr,
diff; // Antall min fra faktisk stoppested til startstoppested
char valg;
string navn,
startSted;
if (!rutene.empty()) { // Hvis det er registrert ruter:
ruteNr = lesInt("Rutenr", MINRUTER, MAXRUTER);
if (ruteNrFinnes(ruteNr)) { // Hvis rutenummeret finnes:
auto ruten = rutene.find(ruteNr); // Iterator til riktig rute
ruten->second->skrivRetninger(); // Skriver kort info om ruten
valg = lesChar("Rutetabell for retningen (F/T)");
// Looper til lovlig valg av retning:
while (valg != 'F' && valg != 'T') {
cout << "\nUgyldig valg, prøv igjen.\n";
valg = lesChar("Rutetabell for retningen (F/T)");
}
ruten->second->skrivKort(); // Skriver info om rutetypen
switch (valg) { // Skriver hele ruten og henter navn
// på første stoppested på ruten avhengig
// av retning bruker ønsker å se:
case 'F': ruten->second->skrivRute(Fram);
startSted = ruten->second->hentNavn(Fram); break;
case 'T': ruten->second->skrivRute(Tilbake);
startSted = ruten->second->hentNavn(Tilbake); break;
}
cout << "\n\nRutetabell for stoppestedet (navn): ";
getline(cin, navn);
navn = gStoppestederBase.byttBokstaver(navn); // bytter æøåÆØÅ
navn = gStoppestederBase.finnEntydig(navn); // Sjekker for entydighet
if (navn.size() > 0) { // Hvis navn er entydig:
// Henter stoppestedets unike nr:
stoppNr = gStoppestederBase.hentIndeksVhaNavn(navn) + 1;
//Hvis stoppestedet finnes på ruten:
if (ruten->second->finnesStopp(stoppNr)) {
switch (valg) {
case 'F': diff =
ruten->second->finnDifferanse(stoppNr, Fram);
break;
// Henter differanse ved retning fram
case 'T': diff =
ruten->second->finnDifferanse(stoppNr, Tilbake);
break;
// Henter differanse ved retning tilbake
}
// Leser inn rutetabellen og skriver den ut:
ruten->second->ruteTabell(diff, startSted, navn);
} else // Hvis stoppet ikke finnes på ruten:
cout << "\nStoppestedet " << navn << " finnes ikke "
<< "på denne ruten!\n\n";
} else // Ikke entydig stoppestedsnavn:
cout << "\nIngen entydige stoppestedsnavn funnet\n\n";
} else // Hvis rutenummeret ikke finnes:
cout << "\nDette rutenummeret er ikke registrert.\n\n";
} else // Hvis ingen ruter registrert:
cout << "\nIngen ruter registrert i programmet.\n\n";
}
/**
* Skriver alle rutene i datastrukturen
*
* @see Rute::skrivData()
*/
void Ruter::skrivAlle() {
cout << "\nFølgende ruter finnes:\n";
for (const auto & [ruteNr, rute] : rutene) { // For hver rute:
cout << ruteNr << ' '; // Skriver rutenr
rute->skrivData(); // Ruten skriver egne data
cout << '\n';
}
cout << '\n';
}
/**
* Skriver rutermenyen
*/
void Ruter::skrivMeny() {
cout << "\nFølgende kommandoer er tilgjengelige:\n"
<< "\tN - Ny rute\n"
<< "\tA - Skriv alle ruter\n"
<< "\tE - Endre en rute\n"
<< "\tB - Beskrivelse av en rute\n"
<< "\tT - Rutetabell for et stoppested\n";
}
/**
* Skriver informasjon om ruter til fil
*
* @see Rute::skrivTilFil(...)
* @see Bane::skrivTilFil(...)
* @see Buss::skrivTilFil(...)
*/
void Ruter::skrivTilFil() {
ofstream utfil("ruter.dt2"); // Åpner aktuell fil for skriving
cout << "\nSkriver til filen 'ruter.dt2'...\n";
utfil << rutene.size() << '\n'; // Skriver ut antall ruter
for (const auto & val : rutene) { // For hver rute:
utfil << val.first << ' '; // Skriver rutenr
(val.second)->skrivTilFil(utfil); // Ruten skriver seg selv til fil
}
utfil.close(); // Lukker fil for skriving
}