Skip to content

Commit

Permalink
Merge branch 'feature/506510-BuscarAPartirDeCoordenadas' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
CanalesRRC committed Nov 20, 2024
2 parents 39e2de6 + 3d549e1 commit 33c0471
Show file tree
Hide file tree
Showing 11 changed files with 21,413 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,17 @@ public void onSearchStationsWithFilters(String provincia,String municipio, Strin
*/
public void onCoordinatesButtonClicked();

/**
* Filtra una lista de gasolineras segun su proximidad a un punto de referencia
* especificado por coordenadas y una distancia maxima. Las gasolineras que cumplan
* con el criterio se almacenan en una nueva lista y se actualiza la vista con
* los resultados.
*
* @param longitud Longitud del punto de referencia en grados.
* @param latitud Latitud del punto de referencia en grados.
* @param distancia Distancia máxima permitida en kilómetros para incluir una gasolinera.
*/
public void searchWithCoordinates(Double longitud, Double latitud, int distancia);



}

/**
Expand Down Expand Up @@ -164,9 +171,12 @@ public interface View {
*/
public void showOrdenarPopUp();


public void showCoordinatesPopUp();

/**
* Muestra un cuadro de dialogo emergente que permite al usuario ingresar las coordenadas
* de longitud y latitud, asi como seleccionar una distancia mediante un slider.
* El dialog tambien muestra las coordenadas guardadas previamente si estan disponibles.
*/
public void showCoordinatesPopUp();

/**
* Actualiza el spinner de municipios con una lista proporcionada.
Expand All @@ -175,6 +185,5 @@ public interface View {
* @param municipios La lista de municipios para poblar el spinner.
*/
public void updateMunicipiosSpinner(List<Municipio> municipios);

}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package es.unican.gasolineras.activities.main;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import es.unican.gasolineras.common.IFiltros;
import es.unican.gasolineras.model.Gasolinera;
import es.unican.gasolineras.model.IDProvincias;
Expand All @@ -25,6 +25,8 @@ public class MainPresenter implements IMainContract.Presenter {
@Setter
private IFiltros filtros;
private List<Gasolinera> gasolinerasFiltradas;
private List<Gasolinera> gasolinerasCoordenadas;
private boolean IsFiltro = true;

/**
* @see IMainContract.Presenter#init(IMainContract.View)
Expand Down Expand Up @@ -70,13 +72,17 @@ public void onFilterButtonClicked() {
public void onSearchStationsWithFilters(String provincia, String municipio, String companhia,
List<String> combustibles, boolean abierto) {

List<Gasolinera> gasolinerasFiltradas = gasolineras;
List<Gasolinera> gasolinerasFiltradas;
if (IsFiltro) {
gasolinerasFiltradas = gasolineras;
} else{
gasolinerasFiltradas = gasolinerasCoordenadas;
}

String finalProvincia = "-".equals(provincia) ? null : provincia;
String finalMunicipio = ("-".equals(municipio) || municipio.isEmpty()) ? null : municipio;
String finalCompanhia = "-".equals(companhia) ? null : companhia;


if (finalProvincia != null) {
gasolinerasFiltradas = filtros.filtrarPorProvinciaYMunicipio(gasolinerasFiltradas,
finalProvincia, finalMunicipio);
Expand All @@ -94,7 +100,7 @@ public void onSearchStationsWithFilters(String provincia, String municipio, Stri

// Guarda la lista filtrada para utilizarla en la ordenación
this.gasolinerasFiltradas = gasolinerasFiltradas;

IsFiltro = true;
view.showStations(gasolinerasFiltradas);
view.showLoadCorrect(gasolinerasFiltradas.size());
}
Expand Down Expand Up @@ -126,14 +132,19 @@ public void onFailure(Throwable e) {
@Override
public void onOrdenarButtonClicked() { view.showOrdenarPopUp(); }


/**s
/**
* @see IMainContract.Presenter#ordenarGasolinerasPorPrecio(String combustible, String orden)
*/
@Override
public void ordenarGasolinerasPorPrecio(String combustible, String orden) {
// Usa la lista filtrada
List<Gasolinera> gasolinerasAOrdenar = this.gasolinerasFiltradas;
List<Gasolinera> gasolinerasAOrdenar;
if(IsFiltro){
gasolinerasAOrdenar = this.gasolinerasFiltradas;
}else{

gasolinerasAOrdenar = this.gasolinerasCoordenadas;
}

// Determinamos el comparador básico según el tipo de combustible
Comparator<Gasolinera> comparator = (g1, g2) -> {
Expand Down Expand Up @@ -167,64 +178,85 @@ public void ordenarGasolinerasPorPrecio(String combustible, String orden) {
gasolinerasAOrdenar.sort(comparator);
// Mostramos la lista ordenada
view.showStations(gasolinerasAOrdenar);

}

/**
* @see IMainContract.Presenter#onCoordinatesButtonClicked()
*/
@Override
public void onCoordinatesButtonClicked() {view.showCoordinatesPopUp();}

/**
* @see IMainContract.Presenter#searchWithCoordinates(Double longitud, Double latitud, int distancia)
*/
@Override
public void searchWithCoordinates(Double longitud, Double latitud, int distancia){
// Crear una nueva lista para almacenar las gasolineras filtradas
List<Gasolinera> gasolinerasFiltradasCoordenadas = new ArrayList<>();

List<Gasolinera> gasolinerasFiltradas = this.gasolineras;

for(Gasolinera g: gasolinerasFiltradas){

String longitudStr = g.getLongitud(); // Obtener longitud como String
String latitudStr = g.getLatitud(); // Obtener latitud como String
// Convertir a Double
for (Gasolinera g : this.gasolinerasFiltradas) {
// Obtener y convertir las coordenadas de la gasolinera
String longitudStr = g.getLongitud().replace(",", ".");
String latitudStr = g.getLatitud().replace(",", ".");
Double longitudGasolinera = Double.parseDouble(longitudStr);
Double latitudGasolinera = Double.parseDouble(latitudStr);

if(!estaEnCoordenadas(longitud, latitud, distancia, longitudGasolinera, latitudGasolinera)){
gasolinerasFiltradas.remove(g);
// Verificar si la gasolinera está dentro de la distancia
if (estaEnCoordenadas(longitud, latitud, distancia, longitudGasolinera, latitudGasolinera)) {
gasolinerasFiltradasCoordenadas.add(g); // Añadir si cumple el criterio
}
}

this.gasolineras = gasolinerasFiltradas;

view.showStations(gasolinerasFiltradas);

view.showLoadCorrect(gasolinerasFiltradas.size());


this.gasolinerasCoordenadas = gasolinerasFiltradasCoordenadas;
IsFiltro = false;
// Actualizar la vista con las gasolineras filtradas
view.showStations(gasolinerasFiltradasCoordenadas);
view.showLoadCorrect(gasolinerasFiltradasCoordenadas.size());
}

private boolean estaEnCoordenadas(Double longitudSelec, Double latitudSelec, int distancia, Double longitudGasolinera, Double latitudGasolinera){
final double RADIO_TIERRA_KM = 6371.0; // Radio de la Tierra en kilómetros
/**
* Determina si una ubicacion especificada por las coordenadas de una gasolinera
* se encuentra dentro de una distancia especifica desde un punto de seleccion.
* Utiliza la formula del haversine para calcular la distancia entre dos puntos
* en la superficie de una esfera (aproximadamente la Tierra).
*
* @param longitudSelec Longitud del punto de referencia en grados.
* @param latitudSelec Latitud del punto de referencia en grados.
* @param distancia Distancia maxima permitida en kilometros.
* @param longitudGasolinera Longitud de la gasolinera en grados.
* @param latitudGasolinera Latitud de la gasolinera en grados.
* @return true si la gasolinera está dentro de la distancia especificada
* desde el punto de referencia; false de lo contrario.
*/
private boolean estaEnCoordenadas(Double longitudSelec, Double latitudSelec, int distancia, Double longitudGasolinera, Double latitudGasolinera) {
final int RADIO_TIERRA = 6371000; // Radio de la Tierra en metros

// Verifica que las coordenadas no sean nulas o extremas
if (longitudSelec == null || latitudSelec == null || longitudGasolinera == null || latitudGasolinera == null) {
return false; // Coordenadas inválidas
}

// Convertir todas las coordenadas a radianes
// Convertir las coordenadas de grados a radianes
double latitudSelecRad = Math.toRadians(latitudSelec);
double longitudSelecRad = Math.toRadians(longitudSelec);
double latitudGasolineraRad = Math.toRadians(latitudGasolinera);
double longitudGasolineraRad = Math.toRadians(longitudGasolinera);

// Diferencias entre las coordenadas
double dLat = latitudGasolineraRad - latitudSelecRad;
double dLon = longitudGasolineraRad - longitudSelecRad;
double diferenciaLatitud = latitudGasolineraRad - latitudSelecRad;
double diferenciaLongitud = longitudGasolineraRad - longitudSelecRad;

// Fórmula de Haversine
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
// Fórmula del haversine
double a = Math.sin(diferenciaLatitud / 2) * Math.sin(diferenciaLatitud / 2)
+ Math.cos(latitudSelecRad) * Math.cos(latitudGasolineraRad)
* Math.sin(dLon / 2) * Math.sin(dLon / 2);
* Math.sin(diferenciaLongitud / 2) * Math.sin(diferenciaLongitud / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

// Calcular la distancia en kilómetros
double distanciaCalculada = RADIO_TIERRA_KM * c;

// Comprobar si la distancia calculada está dentro del radio especificado
return distanciaCalculada <= distancia;
// Distancia en metros
double distanciaEntrePuntos = RADIO_TIERRA * c;

// Comparar la distancia calculada con la distancia permitida (convertida a metros)
return distanciaEntrePuntos <= distancia * 1000;
}

/**
Expand Down
Loading

0 comments on commit 33c0471

Please sign in to comment.