
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9337 8e941d3f-bd1b-0410-a28a-d453659cc2b4
297 lines
7.2 KiB
ObjectPascal
297 lines
7.2 KiB
ObjectPascal
unit gpslistform;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
{$WARN 6058 off : Call to subroutine "$1" marked as inline is not inlined}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls,
|
|
ExtCtrls, Buttons, StdCtrls, mvGpsObj, mvMapViewer;
|
|
|
|
const
|
|
// IDs of GPS items
|
|
_CLICKED_POINTS_ = 10;
|
|
_TRACK_POINTS_ = 20;
|
|
|
|
type
|
|
|
|
{ TGPSListViewer }
|
|
|
|
TGPSListViewer = class(TForm)
|
|
BtnDeletePoint: TBitBtn;
|
|
BtnGoToPoint: TBitBtn;
|
|
BtnClose: TBitBtn;
|
|
BtnCalcDistance: TButton;
|
|
BtnSavePts: TButton;
|
|
BtnLoadTrack: TButton;
|
|
ListView: TListView;
|
|
OpenDialog: TOpenDialog;
|
|
Panel1: TPanel;
|
|
SaveDialog: TSaveDialog;
|
|
procedure BtnCalcDistanceClick(Sender: TObject);
|
|
procedure BtnCloseClick(Sender: TObject);
|
|
procedure BtnDeletePointClick(Sender: TObject);
|
|
procedure BtnGoToPointClick(Sender: TObject);
|
|
procedure BtnSavePtsClick(Sender: TObject);
|
|
procedure BtnLoadTrackClick(Sender: TObject);
|
|
private
|
|
FViewer: TMapView;
|
|
FList: TGpsObjList;
|
|
procedure SetViewer(AValue: TMapView);
|
|
protected
|
|
procedure Populate;
|
|
|
|
public
|
|
destructor Destroy; override;
|
|
property MapViewer: TMapView read FViewer write SetViewer;
|
|
|
|
end;
|
|
|
|
var
|
|
GPSListViewer: TGPSListViewer;
|
|
|
|
implementation
|
|
|
|
{$R *.lfm}
|
|
|
|
uses
|
|
mvTypes, mvGeoMath, mvEngine,
|
|
globals;
|
|
|
|
destructor TGPSListViewer.Destroy;
|
|
begin
|
|
FList.Free;
|
|
inherited;
|
|
end;
|
|
|
|
procedure TGPSListViewer.Populate;
|
|
var
|
|
i: Integer;
|
|
item: TListItem;
|
|
gpsObj: TGpsObj;
|
|
area: TRealArea;
|
|
begin
|
|
if FViewer = nil then begin
|
|
ListView.Items.Clear;
|
|
exit;
|
|
end;
|
|
|
|
FViewer.GPSItems.GetArea(area);
|
|
FList.Free;
|
|
FList := FViewer.GPSItems.GetObjectsInArea(area);
|
|
ListView.Items.BeginUpdate;
|
|
try
|
|
ListView.Items.Clear;
|
|
for i:=0 to FList.Count-1 do begin
|
|
gpsObj := FList[i];
|
|
item := ListView.Items.Add;
|
|
if gpsObj is TGpsPoint then begin
|
|
item.SubItems.Add(gpsObj.Name);
|
|
item.Subitems.Add(LatToStr(TGpsPoint(gpsObj).Lat, true));
|
|
item.Subitems.Add(LonToStr(TGpsPoint(gpsObj).Lon, true));
|
|
end;
|
|
end;
|
|
finally
|
|
ListView.Items.EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TGPSListViewer.BtnCloseClick(Sender: TObject);
|
|
begin
|
|
Close;
|
|
end;
|
|
|
|
procedure TGPSListViewer.BtnCalcDistanceClick(Sender: TObject);
|
|
type
|
|
TCoordRec = record
|
|
Lon: Double;
|
|
Lat: Double;
|
|
Name: String;
|
|
end;
|
|
var
|
|
i, iChecked: Integer;
|
|
item: TListItem;
|
|
rPt: TRealPoint;
|
|
CoordArr: array[0..1] of TCoordRec;
|
|
begin
|
|
// count checked items
|
|
iChecked := 0;
|
|
for i:=0 to ListView.Items.Count - 1 do begin
|
|
if ListView.Items.Item[i].Checked then Inc(iChecked);
|
|
end;
|
|
|
|
if iChecked <> 2 then begin
|
|
ShowMessage('Please select 2 items to calculate the distance.');
|
|
exit;
|
|
end;
|
|
|
|
iChecked := 0;
|
|
for i:=0 to ListView.Items.Count - 1 do begin
|
|
if ListView.Items.Item[i].Checked then begin
|
|
item := ListView.Items[i];
|
|
if TryStrToGps(item.SubItems[2], rPt.Lon) and TryStrToGps(item.SubItems[1], rPt.Lat) then
|
|
begin
|
|
CoordArr[iChecked].Lon := rPt.Lon;
|
|
CoordArr[iChecked].Lat := rPt.Lat;
|
|
CoordArr[iChecked].Name:= item.SubItems[0];
|
|
Inc(iChecked);
|
|
end;
|
|
end;
|
|
end;
|
|
// show distance between selected items
|
|
ShowMessage(Format('Distance between %s and %s is: %.2n %s.', [
|
|
CoordArr[0].Name, CoordArr[1].Name,
|
|
CalcGeoDistance(CoordArr[0].Lat, CoordArr[0].Lon, CoordArr[1].Lat, CoordArr[1].Lon, DistanceUnit, esEllipsoid),
|
|
DistanceUnit_Names[DistanceUnit]
|
|
]));
|
|
end;
|
|
|
|
procedure TGPSListViewer.BtnDeletePointClick(Sender: TObject);
|
|
var
|
|
gpsObj: TGpsObj;
|
|
i: Integer;
|
|
rPt: TRealPoint;
|
|
item: TListItem;
|
|
begin
|
|
if ListView.Selected <> nil then begin
|
|
gpsObj := FList[ListView.Selected.Index];
|
|
ListView.Selected.Free;
|
|
FViewer.GpsItems.Clear(_CLICKED_POINTS_);
|
|
for i:=0 to ListView.Items.Count-1 do begin
|
|
item := ListView.Items[i];
|
|
if TryStrToGps(item.SubItems[2], rPt.Lon) and TryStrToGps(item.SubItems[1], rPt.Lat) then
|
|
begin
|
|
gpsObj := TGpsPoint.CreateFrom(rPt);
|
|
gpsObj.Name := item.SubItems[0];
|
|
FViewer.GPSItems.Add(gpsObj, _CLICKED_POINTS_);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TGPSListViewer.BtnGoToPointClick(Sender: TObject);
|
|
var
|
|
gpsPt: TGpsPoint;
|
|
gpsObj: TGpsObj;
|
|
begin
|
|
if ListView.Selected <> nil then begin
|
|
gpsObj := FList[ListView.Selected.Index];
|
|
if gpsObj is TGpsPoint then begin
|
|
gpsPt := TGpsPoint(gpsObj);
|
|
if Assigned(FViewer) then FViewer.Center := gpsPt.RealPoint;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TGPSListViewer.BtnSavePtsClick(Sender: TObject);
|
|
var
|
|
i: Integer;
|
|
gpsPt: TGpsPoint;
|
|
gpsObj: TGpsObj;
|
|
L: TStrings;
|
|
s: String;
|
|
begin
|
|
if (OpenDialog.FileName <> '') and (SaveDialog.FileName = '') then
|
|
SaveDialog.FileName := OpenDialog.FileName;
|
|
if SaveDialog.FileName <> '' then
|
|
SaveDialog.InitialDir := ExtractFileDir(SaveDialog.FileName);
|
|
if not SaveDialog.Execute then exit;
|
|
|
|
L := TStringList.Create;
|
|
try
|
|
s := 'Index'#9'Name'#9'Longitude'#9'Latitude';
|
|
L.Add(s);
|
|
for i:=0 to FList.Count-1 do begin
|
|
gpsObj := FList[i];
|
|
if gpsObj is TGpsPoint then begin
|
|
gpsPt := TGpsPoint(gpsObj);
|
|
s := Format('%d'#9'%s'#9'%s'#9'%s', [
|
|
i, gpsPt.Name, LonToStr(gpsPt.Lon, true), LatToStr(gpsPt.Lat, true)
|
|
]);
|
|
L.Add(s);
|
|
end;
|
|
L.SaveToFile(SaveDialog.FileName);
|
|
end;
|
|
finally
|
|
L.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TGPSListViewer.BtnLoadTrackClick(Sender: TObject);
|
|
var
|
|
L: TStrings;
|
|
gpsTrack: TGpsTrack;
|
|
gpsPt: TGpsPoint;
|
|
sa: TStringArray;
|
|
lon, lat: Double;
|
|
i: Integer;
|
|
item: TListItem;
|
|
begin
|
|
if (SaveDialog.FileName <> '') and (OpenDialog.FileName = '') then
|
|
OpenDialog.FileName := SaveDialog.FileName;
|
|
if OpenDialog.FileName <> '' then
|
|
OpenDialog.InitialDir := ExtractFileDir(OpenDialog.FileName);
|
|
if not OpenDialog.Execute then exit;
|
|
|
|
// Create a gpsTrack, read the track points, and add the track to the viewer.
|
|
gpsTrack := TGpsTrack.Create;
|
|
L := TStringList.Create;
|
|
try
|
|
L.LoadFromFile(OpenDialog.FileName);
|
|
for i := 1 to L.Count - 1 do // i=1 --> skip header line
|
|
begin
|
|
if L[i] = '' then Continue;
|
|
sa := L[i].Split(#9);
|
|
if TryStrToGps(sa[2], lon) and TryStrToGps(sa[3], lat) then
|
|
begin
|
|
gpsPt := TGpsPoint.Create(lon, lat);
|
|
gpsPt.Name := sa[1];
|
|
gpsTrack.Points.Add(gpsPt);
|
|
end;
|
|
end;
|
|
FViewer.GPSItems.Add(gpsTrack, _TRACK_POINTS_);
|
|
FViewer.Center := gpsPt.RealPoint;
|
|
finally
|
|
L.Free;
|
|
end;
|
|
|
|
// The track points are needed internally in the FList --> copy the track points
|
|
FList.Free;
|
|
FList := TGPSObjList.Create(false);
|
|
for i := 0 to gpsTrack.Points.Count - 1do
|
|
begin
|
|
gpsPt := gpsTrack.Points[i];
|
|
FList.Add(gpsPt);
|
|
end;
|
|
|
|
// Display the track points in the ListView
|
|
ListView.Items.BeginUpdate;
|
|
try
|
|
ListView.Items.Clear;
|
|
for i:=0 to gpsTrack.Points.Count - 1 do
|
|
begin
|
|
gpsPt := gpsTrack.Points[i];
|
|
item := ListView.Items.Add;
|
|
item.SubItems.Add(gpsPt.Name);
|
|
item.SubItems.Add(LatToStr(gpsPt.Lat, true));
|
|
item.SubItems.Add(LonToStr(gpsPt.Lon, true));
|
|
end;
|
|
finally
|
|
ListView.Items.EndUpdate;
|
|
end;
|
|
|
|
end;
|
|
|
|
procedure TGPSListViewer.SetViewer(AValue: TMapView);
|
|
begin
|
|
if FViewer = AValue then
|
|
exit;
|
|
FViewer := AValue;
|
|
Populate;
|
|
end;
|
|
|
|
end.
|
|
|