unit ufUbicacion;

interface

uses
  // uhtmlverdoc,
  Windows, Messages, SysUtils, Math, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, jpeg, ExtCtrls, StdCtrls, xMatDefs, uVHorarioMet;

type
  TfUbicacion = class(TForm)
    Panel1: TPanel;
    Label4: TLabel;
    Label5: TLabel;
    lbl_longlat: TLabel;
    Shape2: TShape;
    eLatitud: TEdit;
    eLongitud: TEdit;
    ScrollBox1: TScrollBox;
    Image1: TImage;
    Shape1: TShape;
    Timer1: TTimer;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    PaintBox1: TPaintBox;
    Button5: TButton;
    Timer2: TTimer;
    Button6: TButton;
    Button7: TButton;
    procedure Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Integer);
    procedure Image1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure Timer1Timer(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Shape2MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure FormResize(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button5Click(Sender: TObject);
    procedure Timer2Timer(Sender: TObject);
    procedure Button6Click(Sender: TObject);
    procedure Button7Click(Sender: TObject);
  private
    { Private declarations }
    flg_salir: boolean;
  public
    { Public declarations }

    Latitud, Longitud: double;

    vientos: TVientosHorarios;

    procedure UbicarCirculo( Latitud, Longitud: double );
    procedure CalcLatLong( var Latitud, Longitud: double; x, y: integer );
    procedure CalcXY( var X, Y : integer; Latitud, Longitud: double );
    procedure CentrarMapa;

    procedure SetDatos( Latitud, Longitud: double );
    procedure GetDatos( var Latitud, Longitud: double );


  end;


implementation

{$R *.dfm}


procedure TfUbicacion.SetDatos( Latitud, Longitud: double );
begin
  Self.Latitud:= Latitud;
  Self.Longitud:= Longitud;
  flg_salir:= false;
end;
procedure TfUbicacion.GetDatos( var Latitud, Longitud: double );
begin
  Latitud:= self.Latitud;
  Longitud:= self.Longitud;
end;


const
// definición de constantes para mapeo de posición
// sobre el mapa de Uruguay

// mapa grande
//  x1= 145.0; y1= 856.0;
//  x2= 785.0; y2= 854.0;
//  x3= 129.0; y3= 84.0;
//  x4= 793.0; y4= 83.0;

// mapa chico
  x1= 69.0; y1= 410.0;
  x2= 374.0; y2= 409.0;
  x3= 61.0; y3= 40.0;
  x4= 381.0; y4= 41.0;

  long1= 58.0;
  lat1=	30.0;

  long2= 54.0;
  lat2= 34.0;

  u1x= x2 - x1;
  u1y= y2 - y1;
  u2x= x4 - x3;
  u2y= y4 - y3;

  w1x= x3 - x1;
  w1y= y3 - y1;

  dux= u1x - u2x;
  duy= u1y - u2y;

  CA= w1x* duy - w1y * dux;





procedure TfUbicacion.CalcXY( var X, Y : integer; Latitud, Longitud: double );
var
  alfa, beta: double;
  Ax, Ay, ux, uy: double;

begin
  beta:= (Latitud-lat2)/(lat1- lat2);
  alfa:= (Longitud- long1)/(long2- long1);
  Ax:= x1 + beta * w1x;
  Ay:= y1 + beta * w1y;
  ux:= (1-beta) * u1x + beta * u2x;
  uy:= (1-beta) * u1y + beta * u2y;

  X:= round( Ax + alfa*ux );
  Y:= round( Ay + alfa*uy );
end;



procedure TfUbicacion.Button1Click(Sender: TObject);
begin
  flg_salir:= true;
 modalresult:= 1;
end;

procedure TfUbicacion.Button2Click(Sender: TObject);
begin
 flg_salir:= true;
 modalresult:= 2;
end;

procedure TfUbicacion.Button3Click(Sender: TObject);
begin
  // htmlverdoc( 'ubicaciongeografica' );
end;

procedure TfUbicacion.Button4Click(Sender: TObject);
var
  dt1, dt2: TDateTime;
begin
// hacemos coincider la capa con el mapa
  paintbox1.Width:= image1.Width;
  paintbox1.Height:= image1.Height;
  paintbox1.Left:= image1.Left;
  paintbox1.Top:= image1.Top;

// inicializamos
  dt1:= vientos.dtInicial;
  dt2:= vientos.dtFinal;
  if dt1 >= dt2 then
  begin
    writeln('dt1: ', DateTimeToStr( dt1 ) );
    writeln('dt2: ', DateTimeToStr( dt2 ) );
    showmessage( 'NO hay una venta común a todos los archivos. No es posible simular' );
    exit;
  end;

// los ponemos todos al inicio.
  vientos.init_iActual( dt1 );

// dibujamos los vientos
  vientos.Draw( paintbox1.Canvas, CalcXY, 1, 4 );

  timer2.Enabled:= true;
end;

procedure TfUbicacion.Button5Click(Sender: TObject);
begin
  vientos.Draw( paintbox1.Canvas, CalcXY, 2, 4 );
  vientos.inc_iActual;
  vientos.Draw( paintbox1.Canvas, CalcXY, 1, 4 );
end;

procedure TfUbicacion.Button6Click(Sender: TObject);
begin
   timer2.Enabled:= not timer2.Enabled;
end;

procedure TfUbicacion.Button7Click(Sender: TObject);
begin
  vientos.WriteSeriesToXLT( 'vientos_fp03V80-2MW.xlt');
end;

procedure TfUbicacion.CalcLatLong( var Latitud, Longitud: double; x, y: integer );
var
  CB, CC, dPx, dPy, Ax, Ay, ux, uy, alfa, beta: double;
begin
  dPx:= x1 - x;
  dPy:= y1 - y;
  CB:= w1x*u2y+dpx*duy-( w1y*u2x+dpy*dux );
  CC:= dpx*u2y-dpy*u2x;

  if EsCero( CA ) then
    beta:= -CC / CB
  else
    beta:= (-CB + sqrt( CB*CB- 4* CA * CC ))/ ( 2* CA );

  Ax:= x1 + beta * w1x;
  Ay:= y1 + beta * w1y;

  dpx:= x - Ax;
  dpy:= y - Ay;

  ux:= (1-beta) * u1x + beta * u2x;
  uy:= (1-beta) * u1y + beta * u2y;

  alfa:= ( dpx * ux + dpy * uy ) / ( ux*ux+ uy*uy );

  Latitud:= (1-beta) * lat2 + beta * lat1;
  Longitud:= ( 1- alfa ) * long1 + alfa * long2;

  lbl_longlat.caption:= ' Long: '+FloatToStrF( Longitud, ffFixed, 5,1 )+'º, Lat:'+FloatToStrF( Latitud, ffFixed, 5, 1 )+'º';

end;





procedure TfUbicacion.UbicarCirculo( Latitud, Longitud: double );
var
  X,Y: integer;
begin
  CalcXY(X, Y, Latitud, Longitud );
  shape1.Top:= Y + Image1.Top - shape1.Height div 2;
  shape1.Left:= X + Image1.Left - shape1.Width div 2;
  eLatitud.Text:= FloatToStrF( Latitud, ffFixed, 5,1 );
  eLongitud.Text:= FloatToStrF( Longitud, ffFixed, 5,1 );
end;




procedure TfUbicacion.CentrarMapa;
var
  X,Y: integer;
  sx, sy: integer;

begin
  CalcXY(x, y, latitud, longitud );

  sx:= round( (x - scrollbox1.width div 2) / Self.Image1.Width  * ScrollBox1.HorzScrollBar.Range  );
  sy:= round( (y - scrollbox1.height div 2) / Self.Image1.Height * ScrollBox1.VertScrollBar.Range );

  sx:= max( 0, min( sx, ScrollBox1.HorzScrollBar.Range ));
  sy:= max( 0, min( sy, ScrollBox1.VertScrollBar.Range ));
  ScrollBox1.HorzScrollBar.Position:= sx;
  ScrollBox1.VertScrollBar.Position:= sy;
end;


procedure TfUbicacion.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  if vientos <> nil then
  begin
    vientos.Free;
    vientos:= nil;
  end;
end;

procedure TfUbicacion.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
  k: integer;

begin
  CanClose:= true;
  if flg_salir then  exit;

  k:=  application.messagebox( '¿Desea guardar los cambios?', 'Confirmación', MB_YESNOCANCEL );
  case k of
  IDYES: modalresult:= 1; // salir y guardar
  IDNO: modalresult:= 2; // salir pero no guardar
  IDCANCEL: CanClose:= false;
  else
    Canclose:= false;
  end;


end;


procedure TfUbicacion.FormCreate(Sender: TObject);
begin
  timer1.Enabled:= true;
  vientos:= nil;
end;

procedure TfUbicacion.FormResize(Sender: TObject);
begin
  CentrarMapa;
end;

procedure TfUbicacion.FormShow(Sender: TObject);
begin
  Self.Timer1.Enabled:= true;
end;

procedure TfUbicacion.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  CalcLatLong( Latitud, Longitud, X, Y );
  UbicarCirculo( Latitud, Longitud );
end;

procedure TfUbicacion.Image1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  tx, ty: integer;
  Latitud, Longitud: double;
begin
    CalcLatLong( Latitud, Longitud, X, Y );
    CalcXY( tx, ty, Latitud, Longitud );
end;

procedure TfUbicacion.Shape2MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  CentrarMapa;
end;

procedure TfUbicacion.Timer1Timer(Sender: TObject);
begin
  Timer1.Enabled:= false;
  UbicarCirculo( Latitud, Longitud );
  CentrarMapa;
end;

procedure TfUbicacion.Timer2Timer(Sender: TObject);
begin
  timer2.Enabled:= false;
  Button5Click(Sender);
  if vientos.cnt_xeof = 0 then
    timer2.Enabled:= true;


end;

end.
