Calculate terrain XY coordinates from mouse click on TChart

TeeChart VCL for Borland/CodeGear/Embarcadero RAD Studio, Delphi and C++ Builder.
Post Reply
AeroSys
Newbie
Newbie
Posts: 17
Joined: Tue Mar 01, 2005 5:00 am
Location: Saint Paul, MN
Contact:

Calculate terrain XY coordinates from mouse click on TChart

Post by AeroSys » Fri Jan 05, 2007 8:54 pm

I have written a mapping application uses a Tchart where I have plotted several series of data that represent ground points and Aerial camera XY stations. On this graph, I would like to be able to click anywhere on the screen and then get the real world XY ground (terrain) coordinates of where the mouse was when the user clicked the screen. I did a search in the forum and found suggested code which I modified as follows:

procedure TfrmGraphBackend.Chart1MouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
Terrain_X, Terrain_Y : double;
msg : string;
begin
If (AeroMatchUsed) then
begin
if (AutoCorrelate) then
begin
If (Button = mbRight) then
begin
Terrain_X := chart1.Axes.Bottom.CalcXPosValue(X);
Terrain_Y := chart1.Axes.Left.CalcYPosValue(Y);

msg := Format('Clicked at: X = %14.3f (meters), Y = %14.3f (meters)',
[Terrain_X,Terrain_Y]);

ShowMessage( msg );
end;
end;
end;
end;

Unfortunately, this does not compute the correct XY coordinates. When a I click on a known camera station symbol that is displayed in an existing plotted series, I get the following (incorrect) coordinates:

X = -197492 Y = 1328142

Where the true coordinates should be (approximately) :

X = 628810 Y = 4761040

Is it possible to make a call to one of Tcharts native methods to compute the correct coordinates?

Another possibility is to compute a coordinate transformation using a simple 2-dimensional conformal coordinate transformation. For a given chart, the user would have to click on 2 diagonally opposition known points to compute a transformation from the Chart1 axis coordinate to the real world system, but would this change if the user changed the zoom setting on the chart?

Thanks in advance,

Matt

Narcís
Site Admin
Site Admin
Posts: 14730
Joined: Mon Jun 09, 2003 4:00 am
Location: Banyoles, Catalonia
Contact:

Post by Narcís » Mon Jan 08, 2007 8:22 am

Hi Matt,

As you already said in an e-mail you already solved that issue, don't you? You may be interested in posting the solution so that other users can benefit from it.

Thanks in advance.
Best Regards,
Narcís Calvet / Development & Support
Steema Software
Avinguda Montilivi 33, 17003 Girona, Catalonia
Tel: 34 972 218 797
http://www.steema.com
Image Image Image Image Image Image
Instructions - How to post in this forum

AeroSys
Newbie
Newbie
Posts: 17
Joined: Tue Mar 01, 2005 5:00 am
Location: Saint Paul, MN
Contact:

Post by AeroSys » Mon Jan 08, 2007 3:57 pm

Hi all (again),

I made some searches in the forum and found another similar question that gave me an idea, so i wrote two small routines that now give me the values that i need (see below in blue). What I am wrestling with now is how or which mouse click action to associate with this calculation. I tried the right mouse click, but that is already paired with panning. A double click would be OK, but that is also paired with zooming using a marque, which is redundant with a simple mouse click and drag. So I think I would like to disable ( unlink) the double click from the zooming, but need to retain the ability to zoom via click and drag. How does one unlink or trap the present double click action?

Thanks in advance,

Matt


var //globals

pts_2d : TpointArray;
Trans2D : TcoordTrans2D;
coef_a : double;
coef_b : double;
coef_c : double;
coef_d : double;

procedure TfrmGraphBackend.Chart1DblClick(Sender: TObject);
var
Terrain_X, Terrain_Y : double;
X,Y : double;
msg : string;
begin
If (AeroMatchUsed) then
begin
if (AutoCorrelate) then
begin
ComputeScaleRealWorld;
X := MouseX;
Y := MouseY;
Terrain_X := (coef_a * X) - (coef_b * Y) + coef_c;
Terrain_Y := (coef_a * Y) + (coef_b * X) + coef_d;
end;
end;
end;

procedure TfrmGraphBackend.ComputeScaleRealWorld;
var
x1,x2,y1,y2 : double;
cx1,cx2,cy1,cy2 : double;
begin
x1 := Chart1.Series[21].XValue[0];
y1 := Chart1.Series[21].YValue[0];
x2 := Chart1.Series[21].XValue[NumPht-1];
y2 := Chart1.Series[21].YValue[NumPht-1];
//-----------------------------------------
cx1 := Chart1.Series[21].CalcXPos(0);
cy1 := Chart1.Series[21].CalcYPos(0);
cx2 := Chart1.Series[21].CalcXPos(NumPht-1);
cy2 := Chart1.Series[21].CalcYPos(NumPht-1);
//---------------------------------------------
setLength(pts_2d,2);
//-----------------------
pts_2d[0].ID := '0';
pts_2d[0].used := true;
pts_2d[0].X[1] := cx1;
pts_2d[0].X[2] := x1;
pts_2d[0].Y[1] := cy1;
pts_2d[0].Y[2] := y1;
//-----------------------
pts_2d[1].ID := '1';
pts_2d[1].used := true;
pts_2d[1].X[1] := cx2;
pts_2d[1].X[2] := x2;
pts_2d[1].Y[1] := cy2;
pts_2d[1].Y[2] := y2;
//------------------------
Trans2D := TcoordTrans2D.Create(1,2,'C',pts_2d);
Trans2D.solve;
coef_a := trans2D.params[0];
coef_b := trans2D.params[1];
coef_c := trans2D.params[2];
coef_d := trans2D.params[3];
end;

Pep
Site Admin
Site Admin
Posts: 3303
Joined: Fri Nov 14, 2003 5:00 am
Contact:

Post by Pep » Tue Jan 16, 2007 2:10 am

Hi Matt,

have you tried to add an "Abort" after the ShowMessage has been called ?

Code: Select all

procedure TForm1.Chart1DblClick(Sender: TObject);
begin
  //....
  showmessage('message..');
  Abort;
end;

Post Reply