commit 1fe8d71338a88ea1d5e90a19ae4bb34026c2247c
parent a7c319cfb5dacdad1606d54d0009e887683ad0be
Author: Martin J. Klöckner <mjkloeckner@gmail.com>
Date: Sun, 23 Jun 2024 14:59:22 -0300
Merge pull request #17 from mjkloeckner/distance-in-km
Distance in km
Diffstat:
| M | barrio.cpp | | | 41 | ++++++++++++++++++++++++++--------------- |
| M | barrio.h | | | 2 | +- |
| M | menu.cpp | | | 201 | +++++++++++++++++++++++++++++++++++++++++++++++++------------------------------ |
3 files changed, 153 insertions(+), 91 deletions(-)
diff --git a/barrio.cpp b/barrio.cpp
@@ -32,27 +32,29 @@ double Barrio::getDistancia(double x1,double y1,double x2,double y2){ //CONSIGAN
return std::sqrt(dX*dX + dY*dY);
}
-Parada *Barrio::paradaMasCercana(double coordX, double coordY,List<Parada*>* paradasAux) { //CONSIGNA 2
+// lon -> X; lat -> Y;
+Parada *Barrio::paradaMasCercana(double lon, double lat) { //CONSIGNA 2
double distancia;
- double distanciaMinima;
+ double distanciaMin;
+
Parada *resultado, *aux;
resultado = aux = NULL;
- paradasAux->startCursor();
- while(paradasAux->forwardCursor()){
- Parada *aux = paradasAux->getCursorData();
+ this->paradas->startCursor();
+ while(this->paradas->forwardCursor()){
+ aux = this->paradas->getCursorData();
if(resultado == NULL) {
resultado = aux;
- distanciaMinima = getDistancia(coordX, coordY, aux->getCoordX(), aux->getCoordY());
+ distanciaMin = getDistancia(lon, lat, aux->getCoordX(), aux->getCoordY());
}
else {
- distancia = getDistancia(coordX,coordY,aux->getCoordX(),aux->getCoordY());
+ distancia = getDistancia(lon, lat, aux->getCoordX(),aux->getCoordY());
- if(distancia < distanciaMinima) {
+ if(distancia < distanciaMin) {
resultado = aux;
- distanciaMinima = distancia;
+ distanciaMin = distancia;
}
}
}
@@ -60,7 +62,11 @@ Parada *Barrio::paradaMasCercana(double coordX, double coordY,List<Parada*>* par
return resultado;
}
-bool Barrio::lineaEnParada(int linea, std::vector<int> *listaDeLineas ) { //CONSIGNA 3
+bool Barrio::lineaEnParada(int linea, std::vector<int> *listaDeLineas) { //CONSIGNA 3
+ if(listaDeLineas == NULL) {
+ return false;
+ }
+
for(size_t i = 0; i < listaDeLineas->size(); ++i) {
if((*listaDeLineas)[i] == linea) {
return true;
@@ -71,7 +77,7 @@ bool Barrio::lineaEnParada(int linea, std::vector<int> *listaDeLineas ) { //CONS
}
List<Parada*> *Barrio::listaDeParadasPorLinea(int linea) { //CONSIGNA 3
- Parada *paradaActual;
+ Parada *parada;
List<Parada*> *resultado;
std::vector<int> *listaDeLineas;
@@ -79,15 +85,20 @@ List<Parada*> *Barrio::listaDeParadasPorLinea(int linea) { //CONSIGNA 3
this->paradas->startCursor();
while(this->paradas->forwardCursor()){
- paradaActual = this->paradas->getCursorData();
- listaDeLineas = paradaActual->getLineas();
+ parada = this->paradas->getCursorData();
+ listaDeLineas = parada->getLineas();
if(lineaEnParada(linea, listaDeLineas)) {
- resultado->insert(paradaActual);
+ resultado->insert(parada);
}
}
- return resultado->getSize() == 0 ? NULL : resultado;
+ if(resultado->getSize() == 0) {
+ delete resultado;
+ return NULL;
+ }
+
+ return resultado;
}
unsigned int Barrio::getCantidadDeParadasPorLinea(int linea) { //CONSIGNA 4
diff --git a/barrio.h b/barrio.h
@@ -58,7 +58,7 @@ public:
/*
* pos: devuelve la parada mas cercana a una coordenada dada
*/
- Parada *paradaMasCercana(double coordX, double coordY, List<Parada*>* paradasAux);
+ Parada *paradaMasCercana(double coordX, double coordY);
/*
* pre: recibe el numero de una Linea
diff --git a/menu.cpp b/menu.cpp
@@ -8,6 +8,7 @@
#include <vector>
#include <cmath>
#include <iomanip>
+#include <cctype>
double getDistancia(double x1, double y1, double x2, double y2);
@@ -48,11 +49,11 @@ Parada *Menu::paradaMasCercanaPorCoordenada(double coordX, double coordY) {
barrio = this->barrios->getCursorData();
if(res == NULL) {
- res = barrio->paradaMasCercana(coordX, coordY, barrio->getParadas());
+ res = barrio->paradaMasCercana(coordX, coordY);
distanciaMin = getDistancia(coordX, coordY, res->getCoordX(), res->getCoordY());
}
else {
- parada = barrio->paradaMasCercana(coordX, coordY, barrio->getParadas());
+ parada = barrio->paradaMasCercana(coordX, coordY);
distancia = getDistancia(coordX, coordY, parada->getCoordX(), parada->getCoordY());
if(distanciaMin > distancia) {
@@ -61,16 +62,8 @@ Parada *Menu::paradaMasCercanaPorCoordenada(double coordX, double coordY) {
}
}
}
- return res;
-}
-void Menu::agregarElementosDeLista(List<Parada*>* listaAux, List<Parada*>* listaResultado) {
- listaAux->startCursor();
- while(listaAux->forwardCursor()) {
- Parada *paradaAux = listaAux->getCursorData();
-
- listaResultado->insert(paradaAux);
- }
+ return res;
}
void Menu::imprimirParadasPorLinea(List<Parada*> *listaDeParadas) {
@@ -95,24 +88,36 @@ void Menu::imprimirParadasPorLinea(List<Parada*> *listaDeParadas) {
}
}
+void Menu::agregarElementosDeLista(List<Parada*>* lista, List<Parada*>* resultado) {
+ Parada *parada;
+
+ lista->startCursor();
+ while(lista->forwardCursor()) {
+ parada = lista->getCursorData();
+
+ resultado->insert(parada);
+ }
+}
+
+
List<Parada*> *Menu::paradasPorLinea(int linea) {
- List<Parada*> *listaAux = new List<Parada*>;
- List<Parada*> *resultado = new List<Parada*>;
+ List<Parada*> *paradas, *resultado;
+ Barrio *barrio;
+
+ resultado = new List<Parada*>;
this->barrios->startCursor();
while(this->barrios->forwardCursor()){
- Barrio *barrioAux = this->barrios->getCursorData();
-
- listaAux = barrioAux->listaDeParadasPorLinea(linea);
-
- std::cout << "listaAux->getSize(): " << listaAux->getSize() << "\n";
- // agregarElementosDeLista(listaAux, resultado);
+ barrio = this->barrios->getCursorData();
+ paradas = barrio->listaDeParadasPorLinea(linea);
+ agregarElementosDeLista(paradas, resultado);
}
if(resultado->getSize() == 0) {
delete resultado;
return NULL;
}
+
return resultado;
}
@@ -130,8 +135,6 @@ void Menu::agregarElementoSinRepetir(std::vector<int> *lineas, std::vector<int>
lineas->push_back((*vectorLineasAux)[i]);
}
}
-
- return;
}
void Menu::lineasPorParada(List<Parada*> *paradas) {
@@ -153,7 +156,7 @@ void Menu::imprimirCantidadParadasPorLinea(std::vector<int>* lineas){
for(size_t i=0; i < lineas->size(); i++) {
paradas = paradasPorLinea((*lineas)[i]);
if(paradas == NULL) {
- std::cout << "no hay paradas de la liena especificada\n";
+ std::cout << "no hay paradas de la liena `" << (*lineas)[i] << " `\n";
continue;
}
std::cout << (*lineas)[i] <<" : " << paradas->getSize() <<std::endl;
@@ -182,6 +185,15 @@ Menu::Menu() {
this->coordX = this->coordY = 0.0f;
}
+std::string strToLowercase(std::string str) {
+ std::string res;
+ for(size_t i = 0; i < str.size(); ++i) {
+ res += std::tolower(str[i]);
+ }
+
+ return res;
+}
+
void delSurroundingChar(std::string &str, char c) {
str.erase(0, 1);
str[str.size() - 1] = '\0';
@@ -252,7 +264,7 @@ Barrio *Menu::getBarrioPorNombre(std::string nombre) {
while(this->barrios->forwardCursor()) {
barrio = this->barrios->getCursorData();
- if(barrio->getNombre() == nombre) {
+ if(strToLowercase(barrio->getNombre()) == strToLowercase(nombre)) {
res = this->barrios->getCursorData();
break;
}
@@ -296,31 +308,31 @@ double getDistancia(double x1, double y1, double x2, double y2) {
}
void ordenarParadasPorDistanciaACoordenada(List<Parada*> *paradas, double x, double y) {
- Node<Parada*> *actual;
- Node<Parada*> *minimo;
- Node<Parada*> *siguiente;
- double distanciaActual, distanciaSiguiente;
+ Node<Parada*> *actual, *min, *sig;
+ Parada *tmp;
+
+ double distActual, distSig;
paradas->startCursor();
while(paradas->forwardCursor()) {
actual = paradas->getCursor();
- minimo = actual;
- siguiente = actual->getNext();
+ min = actual;
+ sig = actual->getNext();
- distanciaActual = getDistancia(actual->getData()->getCoordX(), actual->getData()->getCoordY(), x, y);
+ distActual = getDistancia(actual->getData()->getCoordX(), actual->getData()->getCoordY(), x, y);
- while (siguiente != NULL) {
- distanciaSiguiente = getDistancia(siguiente->getData()->getCoordX(), siguiente->getData()->getCoordY(), x, y);
- if (distanciaSiguiente < distanciaActual) {
- minimo = siguiente;
+ while (sig != NULL) {
+ distSig = getDistancia(sig->getData()->getCoordX(), sig->getData()->getCoordY(), x, y);
+ if (distSig < distActual) {
+ min = sig;
}
- siguiente = siguiente->getNext();
+ sig = sig->getNext();
}
- if (minimo != actual) {
- Parada *temp = actual->getData();
- actual->setData(minimo->getData());
- minimo->setData(temp);
+ if (min != actual) {
+ tmp = actual->getData();
+ actual->setData(min->getData());
+ min->setData(tmp);
}
}
}
@@ -418,11 +430,14 @@ void Menu::cargarDatos() {
void Menu::mostrarMenu() {
bool terminarPrograma = false;
- std::string opcion;
int linea;
double lat, lon; // lat -> Y; lon -> X;
- double distanciaEnKm;
- std::string barrio, barrioNombre, lineaAImprimir, distanciaUnidad;
+ double distancia, distanciaEnKm;
+
+ std::string opcion, barrioNombre, lineaAImprimir, distanciaUnidad;
+ List<Parada*> *paradas, *paradasDeLaLinea;
+ Parada *actual;
+ Barrio *barrio;
while(!terminarPrograma) {
std::cout << "`\033[1m1\033[22m` Cantidad de paradas por barrio\n";
@@ -478,7 +493,7 @@ void Menu::mostrarMenu() {
break;
}
- distanciaEnKm = getDistanciaEnKilometros(lon, lat, parada->getCoordY(), parada->getCoordX());
+ distanciaEnKm = getDistanciaEnKilometros(lon, lat, parada->getCoordX(), parada->getCoordY());
if(distanciaEnKm < 1) {
distanciaEnKm *= 1000.0f;
@@ -493,7 +508,7 @@ void Menu::mostrarMenu() {
<< " " << distanciaUnidad << "\n";
break;
case '3':
- List<Parada*> *paradas;
+ // TODO: verificar que `linea` sea validas
do {
std::cin.clear();
@@ -554,54 +569,90 @@ void Menu::mostrarMenu() {
// imprimirCantidadParadasPorLinea(this->lineas);
break;
case '5':
- /*
- * [X] 0: obtener del usuario `barrio`, `linea` y `coordenadas`
- * [X] 1: iterar sobre los barrios para hallar el `barrio`
- * [X] 2: crear una lista de las paradas en el `barrio` que contienen la `linea`
- * [X] 3: ordenar la lista de menor a mayor con respecto a la distancia a `coordenadas`
- */
+ // std::cout << "barrio> ";
+ // std::cin >> barrioNombre;
+ barrioNombre.assign("CONSTITUCION");
- // std::cout << "Indique el Barrio: ";
- // std::cin.ignore(1);
- // std::getline(std::cin, barrio, '\n');
- barrioNombre = "CONSTITUCION";
-
- // std::cout<<"Indique la Linea: ";
- // std::cin >> this->linea;
- this->linea = 12;
+ /*
+ do {
+ std::cin.clear();
+ std::string line;
+ std::getline(std::cin, line);
+ std::cout << "linea> ";
+ std::cin >> linea;
+ } while(std::cin.fail());
+
+ // TODO: verificar que `latitud` y `longitud` sean validas
+ do {
+ std::cin.clear();
+ std::string line;
+ std::getline(std::cin, line);
+ std::cout << "latitud> ";
+ std::cin >> lat;
+ } while(std::cin.fail());
- // std::cout<<"Indique la coordenada en X: ";
- // std::cin >> lon;
- lon = -58.0f;
+ do {
+ std::cin.clear();
+ std::string line;
+ std::getline(std::cin, line);
+ std::cout << "longitud> ";
+ std::cin >> lon;
+ } while(std::cin.fail());
- // std::cout<<"Indique la coordenada en Y: ";
- // std::cin >> lat;
- lat = -34.0f;
+ */
+ if((barrio = getBarrioPorNombre(barrioNombre)) == NULL) {
+ std::cout << "No se encontro el barrio `" << barrioNombre << "`\n";
+ break;
+ }
- Barrio *barrio;
- List<Parada*> *paradasDeLaLinea;
+ linea = 12;
+ lat = -54.0;
+ lon = -34.0;
- barrio = getBarrioPorNombre(barrioNombre);
- paradasDeLaLinea = barrio->listaDeParadasPorLinea(this->linea);
+ paradasDeLaLinea = barrio->listaDeParadasPorLinea(linea);
+ if(paradasDeLaLinea == NULL) {
+ std::cout << "La linea `" << linea
+ << "` no tiene paradas en el barrio `" << barrioNombre << "`\n";
+ break;
+ }
- // ordenar de mayor a menor `paradasDeLaLinea`
+ // ordenar de mayor a menor distancia a `lat, lon` la lista `paradasDeLaLinea`
ordenarParadasPorDistanciaACoordenada(paradasDeLaLinea, lon, lat);
- Parada *actual;
+ std::cout << std::endl;
+ std::cout.fill(' ');
+ std::cout << std::left << std::setw(18) << std::left << "Direccion"
+ << std::right << std::setw(35) << "Distancia en Kilometros"
+ << std::right << std::setw(30) << "Coordenadas (lat, lon)" << std::endl;
+ std::cout.fill('=');
+ std::cout << std::left << std::setw(83) << std::left << "=" << std::endl;
paradasDeLaLinea->startCursor();
while(paradasDeLaLinea->forwardCursor()) {
actual = paradasDeLaLinea->getCursorData();
- // distancia = getDistancia(actual->getCoordX(), actual->getCoordY(), lon, lat);
- distanciaEnKm = getDistanciaEnKilometros(lon, lat, actual->getCoordY(), actual->getCoordX());
+ distancia = getDistancia(actual->getCoordX(), actual->getCoordY(), lon, lat);
+ distanciaEnKm = getDistanciaEnKilometros(lon, lat, actual->getCoordX(), actual->getCoordY());
+
+ std::string coord;
+ coord += actual->getCoordX();
+ // coord += "(";
+ // coord += actual->getCoordY();
std::cout.fill('.');
- std::cout << std::left << std::setw(25) << actual->getDireccion()
+ std::cout << std::left << std::setw(33) << actual->getDireccion()
<< std::right << std::setw(20)
<< std::fixed << std::setprecision(2)
- << distanciaEnKm << " (" << actual->getCoordX() << ", " << actual->getCoordY()
- << ")" << std::endl;
+ << distanciaEnKm;
+
+ std::cout.fill('.');
+ std::cout << std::right << std::setw(10) << std::setprecision(4)
+ << "(" << actual->getCoordX();
+
+ std::cout.fill(' ');
+ std::cout << "," << std::right << std::setw(10) << std::setprecision(4)
+ << actual->getCoordY() << ")" << std::endl;
}
+ std::cout << std::endl;
delete paradasDeLaLinea;
break;