function [NavAid_inside] = Database_Segment_filter(DataBase_file, lat0, lon0, latf, lonf, A, From_Name, To_Name, Save_Folder)

%% ---------------------------------------------------------------------------------
% Version:      22/09/2015   
% (c):          Vicente Calabuig Simón
%               vicasim@etsid.upv.es
%
% 1.- Utilidad:
%
%       Un punto inicial (lat0, lon0) y un punto final (latf, lonf) forman un segmento de recta.
%
%       Un área rectangular queda definida por la longitud de dicho segmento (L) y una anchura (A).
%       
%       La utilidad de ésta función es realizar el siguiente filtrado:
%
%       1) Seleccionar de la base de datos '3_12_13_Database_Lat_Sorted.dat' todas aquellas radioayudas que 
%          estén dentro del área rectangular anterior.
%
%       OACI 8168 - V2, pág 539, apartado c)
%       2) Excluir del subconjunto anterior todas aquellas radioayudas cuya distancia a la derrota de diseño
%          sea inferior a 3 NM (5.6 Km)         
%       
%       Se escribirá en un fichero .txt la base de datos filtrada (de forma que pueda cargarse rápidamente para usos posteriores)
%
% 2.- Parámetros de entrada:
%
%       Database_file: Base de datos que va a utilizarse en el proceso de filtrado.
%
%       lat0 : latitud del punto inicial (º)                latf : latitud del punto final (º)
%       lon0 : longitud del punto inicial (º)               lonf : longitud del punto final (º)
%       
%       A : Anchura transversal al segmento de recta definido por los puntos anteriores (Km)
%
%       From_Name : Nombre identificativo del punto inicial.
%       To_Name   : Nombre identificativo del punto final.
%
%       Save_folder : Nombre de la carpeta en la que se desea guardar el fichero de texto
%
% 3.- Parámetros de salida:
%    
%       NavAid_inside               : Cell que contiene la base de datos filtrada para el  área de interés. 
%                                            
%
% 4.- Ejemplo de uso:
%
%   Ruta : Valencia --> Madrid 
%
%   lat0 =  39.4894;     lon0 = -0.4816;           latf = 40.4722;      lonf =  -3.5608;             A =  300;    
%   [NavAid_inside] = Database_Segment_filter('3_12_13_Database_Lat_Sorted.dat', lat0, lon0, latf, lonf, A, 'LEVC', 'LEMD', 'Filtros_Offline')
%   [NavAid_inside] = Database_Segment_filter('3_12_13_Database_Lat_Sorted.dat', lat0, lon0, latf, lonf, A, 0, 0, 'Filtros_Offline')
%
%  Ruta : Madrid --> Barcelona
%
%   lat0 =  40.4722;     lon0 = -3.5608;            latf = 41.2969;      lonf =  2.0783;      A = 300; 
%   [NavAid_inside] = Database_Segment_filter('3_12_13_Database_Lat_Sorted.dat', lat0, lon0, latf, lonf, 300, 'LEMD', 'LEBL', 'Filtros_Offline');
%    
%% -----------------------------------------------------------------------------------------------------------------------

% FILTRO 1 : RADIOAYUDAS EN LA REGIÓN DE INTERÉS
% FASE 1 ) PLOT DE LA REGION DE INTERES
% Asumiendo la simplificacion de 'Tierra Plana' : 1 grado latitud  ~ 110 Km | 1 grado longitud ~ 111 Km     
latDeg2Km = 110;   lonDeg2Km = 111;          Km2LatDeg = 1/latDeg2Km;    Km2LonDeg = 1/lonDeg2Km;     
           

% Trabaremos ahora en unidades de distancia (Km)
x0 = lat0 * latDeg2Km ;     y0 = lon0 * lonDeg2Km ;             P0 = [x0, y0];              %Km
xf = latf * latDeg2Km ;     yf = lonf * lonDeg2Km;              Pf = [xf, yf];              %Km

% Conversiones de unidades
r2d = 180/pi;       d2r = pi/180;
alpha = atan (  ( xf - x0 ) / ( yf - y0 )  ) *r2d;

% Segmentos paralelos a la linea central:
    % Segmento paralelo superior:
x1s =  ( x0 - (A/2)*sind (alpha) );        y1s = ( y0 + (A/2)*cosd(alpha) ) ;        X1S = [ x1s,  y1s ];
x2s =  ( xf - (A/2)*sind (alpha) );        y2s = ( yf + (A/2)*cosd(alpha) ) ;        X2S = [ x1s,  y1s ];
    % Segmento paralelo inferior:
x1i =  ( x0 + (A/2)*sind (alpha) );        y1i = ( y0 - (A/2)*cosd(alpha) ) ;        X1i = [ x1i,  y1i ];
x2i =  ( xf + (A/2)*sind (alpha) );        y2i = ( yf - (A/2)*cosd(alpha) ) ;        X2i = [ x1i,  y1i ];

% Vectores genereales X e Y con las coordenadas de TODOS los puntos de interes
% El órden será : P0, Pf, PSi, PSd, Pii, Pid

X = [x0, xf, x1s, x2s, x1i, x2i];
Y = [y0, yf, y1s, y2s, y1i, y2i];

% Plot del escenario:
for i = 1:6
    if     (0 < i && i <= 2)
        plot( X(i), Y(i),     '^blue','LineWidth',1.5);      hold on;   
    elseif (2 < i && i <= 6)
        plot( X(i), Y(i),     'oblack','LineWidth',1.3);     hold on;
    end    
end
% Linea central
plot ( [ x0, xf ], [ y0, yf ],       '--blue', 'LineWidth',1.5);
% Segmentos paralelos
plot ( [ x1s, x2s ], [ y1s, y2s ],       '-black');     plot ( [ x1i, x2i ], [ y1i, y2i ],       '-black');
% Segmentos transversales
plot ( [ x1s, x1i ], [ y1s, y1i ],       '-black');     plot ( [ x2s, x2i ], [ y2s, y2i ],       '-black');
axis square

hold on;

% FASE 2 ) CHECK DE RADIOAYUDAS EN LA REGION

% Rectángulo definido por los 4 vértices: (x1i, y1i)    / (x2i, y2i)   /   (x2s, y2s) /   (x1s, y1s)

xv = [x1i;  x2i;  x2s;  x1s];     xv = [xv; xv(1)];     % Ojo al 'orden' necesario para cerrar el polígono
yv = [y1i;  y2i;  y2s;  y1s];     yv = [yv; yv(1)];

% Cargamos en memoria las radioayudas 1 a 1; y realizamos el proceso de comprobación
Index_inside = [];      x_inside = [];      y_inside =[];       NavAid_inside = [];

% Optimizamos la busqueda acotando los grados de latitud de interés:
m_lat = min(lat0, latf);    M_lat = max(lat0, latf);    Delta_lat = (A/2)*Km2LatDeg;  

lat_busqueda_min = floor(m_lat - Delta_lat);
lat_busqueda_max = ceil(M_lat  + Delta_lat);
[Indice_min] = Buscar_Indice(lat_busqueda_min, 0);     % Si fuera neceseario, se redonderia hacia ABAJO
[Indice_max] = Buscar_Indice(lat_busqueda_max, 1);     %Si fuera neceseario, se redonderia hacia ARRIBA

for i = Indice_min : Indice_max        % Longitud de 3_12_13_Database_Lat_Sorted.dat
    [NavAid_i] = Reading_Database(DataBase_file, i, i);   
    
    [NAtype, NAlat, NAlon, NAalt,  NAfreq, NArange] = Get_NavAid_Data(NavAid_i);
    
    xKm = NAlat * latDeg2Km;    yKm = NAlon * lonDeg2Km;
    
    % FILTRO 1: PERTENENCIA A LA REGIÓN POLIGONAL DE INTERÉS
    
    plot (xKm, yKm,'ogreen','LineWidth',2);                 % Check visual
    hold on;
    
    in = inpolygon(xKm,yKm,xv,yv);  
    
     % FILTRO 2 : EXCLUSIÓN DE RADIAYUDAS SITUADAS A MENOS DE 3 NM (5.6 Km) DE LA DERROTA DE DISEÑO
     d_2D_valid = 1;
    
    % Simplificación al caso 2D, por desconocimiento de la altura con la que se pretende recorrer la ruta de diseño
    % Se trata simplemente de calcular la distancia de un punto (radioayuda i-ésima) a un segmento de recta
    
    % Punto inicial del segmento:        x0        y0      z0 = 0;     %Km
    z0 = 0;          X0 = [x0, y0, z0];

    % Punto final del segmento:          xf        yf      zf = 0;     %Km
    zf = 0;         XF = [xf, yf, zf];

    % Coordenadas radioayudas i-ésima    xKm        yKm      zKm = 0;  %Km
    zKm = 0;        P = [xKm, yKm, zKm];
    
    % Algoritmo de cálculo de la distancia 2D:
    a = X0 - XF;      b = P - XF;               d_2D = norm(cross(a,b)) / norm(a);

    % Exclusión en caso de que d_2D < 5.6 Km
    if d_2D > 5.6
        d_2D_valid = 1;
    else
        d_2D_valid = 0;
    end
    
    % Aplicación simultánea de los filtros 1 y 2
    if (in && d_2D_valid)
        Index_inside = [Index_inside;  i];
        x_inside     = [x_inside; xKm];
        y_inside     = [y_inside; yKm];
        
        NavAid_inside = [NavAid_inside; NavAid_i];
        
    end
    fclose('all');      % Evita el error  'too many files open'.
end

% ELMINACIÓN de radioayudas con las MISMAS COORDENADAS:
[NAtype, NAlat, NAlon, NAalt,  NAfreq, NArange, NAid] = Get_NavAid_Data(NavAid_inside);
for i = 1: size(NavAid_inside, 1)
    eliminado = 0;
    j = 1;
    while (1 - eliminado)
        if j > size(NavAid_inside, 1) || i > size(NavAid_inside, 1)
            break; 
        end
        if i ~= j && NAlat(i) == NAlat(j) && NAlon(i) == NAlon(j)
             NavAid_inside(j) = [];
            [NAtype, NAlat, NAlon, NAalt,  NAfreq, NArange, NAid] = Get_NavAid_Data(NavAid_inside);
             eliminado = 1;
        end
        j = j+1;
    end 
end

% ELIMINACIÓN de radioayudas con el MISMO IDENTIFICADOR:
[NAtype, NAlat, NAlon, NAalt,  NAfreq, NArange, NAid] = Get_NavAid_Data(NavAid_inside);
for i = 1: size(NAid, 1)
    eliminado = 0;      
    j = 1;
    while (1 - eliminado)
        if j>size(NAid, 1) || i>size(NAid, 1)
            break; 
        end
        if i ~= j && strcmp( NAid(j), NAid(i))
            NavAid_inside(j) = [];
           [NAtype, NAlat, NAlon, NAalt,  NAfreq, NArange, NAid] = Get_NavAid_Data(NavAid_inside);
            eliminado = 1;
        end
        j = j+1;
    end
end

% ESCRITURA EN UN FICHERO .txt DE LAS RADIOAYUDAS FILTRADAS
tiempo = clock;        hora = num2str(tiempo(4));     mins = num2str(tiempo(5));

if      (~ischar(From_Name))*(~ischar(To_Name))
    txt_Name = ['FROM ','[',num2str(lat0), ' ; ',num2str(lon0),'] ','TO ','[',num2str(latf),' ; ',num2str(lonf),'] '...
    'A ',num2str(A),'___',Date, '_', hora, '_', mins, '.txt']; 
elseif  (ischar(From_Name))*(~ischar(To_Name))
    txt_Name = ['FROM ',From_Name,' ','[',num2str(lat0), ' ; ',num2str(lon0),'] ','TO ','[',num2str(latf),' ; ',num2str(lonf),'] '...
    'A ',num2str(A),'___',Date, '_', hora, '_', mins, '.txt']; 
elseif (~ischar(From_Name))*(ischar(To_Name))
    txt_Name = ['FROM ','[',num2str(lat0), ' ; ',num2str(lon0),'] ','TO ',To_Name,' ','[',num2str(latf),' ; ',num2str(lonf),'] '...
    'A ',num2str(A),'___',Date, '_', hora, '_', mins, '.txt']; 
elseif (ischar(From_Name))*(ischar(To_Name))
    txt_Name = ['FROM ',From_Name,' ','[',num2str(lat0), ' ; ',num2str(lon0),'] ','TO ',To_Name,' ','[',num2str(latf),' ; ',num2str(lonf),'] '...
    'A ',num2str(A),'___',Date, '_', hora, '_', mins, '.txt']; 
end

CellArray2TextFile(txt_Name,NavAid_inside);
% Movemos el .txt generado a la carpeta escogida:

F = exist(Save_Folder);
if F == 0
   mkdir(pwd, Save_Folder)  % Creamos la carpeta si no existe previamente
   addpath(Save_Folder);
end

if ispc
    Save_Folder_Path   = [pwd, '/',Save_Folder];
else
    Save_Folder_Path   = [pwd, '\',Save_Folder];
end
movefile(txt_Name, Save_Folder_Path);

