LazMapViewer: Add methods DeleteSelectedPoints, ConvertSelectedPointsToMapArea and ConvertSelectedPointsToMapTrack to TMarkerSelectAndDragPlugin
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9690 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
56cae39588
commit
a036319196
@ -59,12 +59,8 @@
|
||||
<Linking>
|
||||
<Debugging>
|
||||
<DebugInfoType Value="dsDwarf3"/>
|
||||
<UseHeaptrc Value="True"/>
|
||||
</Debugging>
|
||||
<Options>
|
||||
<Win32>
|
||||
<GraphicApplication Value="True"/>
|
||||
</Win32>
|
||||
</Options>
|
||||
</Linking>
|
||||
</CompilerOptions>
|
||||
<Debugging>
|
||||
|
@ -14,7 +14,6 @@ object MainForm: TMainForm
|
||||
Top = 0
|
||||
Width = 653
|
||||
Align = alClient
|
||||
Cyclic = True
|
||||
DownloadEngine = MapView.BuiltInDLE
|
||||
DrawingEngine = MapView.BuiltInDE
|
||||
Layers = <>
|
||||
@ -153,6 +152,46 @@ object MainForm: TMainForm
|
||||
TabOrder = 2
|
||||
OnChange = cbMultiSelectChange
|
||||
end
|
||||
object Button1: TButton
|
||||
AnchorSideLeft.Control = rgClickMode
|
||||
AnchorSideLeft.Side = asrBottom
|
||||
AnchorSideTop.Control = rgClickMode
|
||||
Left = 520
|
||||
Height = 25
|
||||
Top = 8
|
||||
Width = 109
|
||||
AutoSize = True
|
||||
BorderSpacing.Left = 8
|
||||
Caption = 'Delete selection'
|
||||
TabOrder = 3
|
||||
OnClick = Button1Click
|
||||
end
|
||||
object Button2: TButton
|
||||
AnchorSideLeft.Control = Button1
|
||||
AnchorSideTop.Control = Button1
|
||||
AnchorSideTop.Side = asrBottom
|
||||
Left = 520
|
||||
Height = 25
|
||||
Top = 33
|
||||
Width = 111
|
||||
AutoSize = True
|
||||
Caption = 'Convert to track'
|
||||
TabOrder = 4
|
||||
OnClick = Button2Click
|
||||
end
|
||||
object Button3: TButton
|
||||
AnchorSideLeft.Control = Button1
|
||||
AnchorSideTop.Control = Button2
|
||||
AnchorSideTop.Side = asrBottom
|
||||
Left = 520
|
||||
Height = 25
|
||||
Top = 58
|
||||
Width = 107
|
||||
AutoSize = True
|
||||
Caption = 'Convert to area'
|
||||
TabOrder = 5
|
||||
OnClick = Button3Click
|
||||
end
|
||||
end
|
||||
object PluginManager: TMvPluginManager
|
||||
Left = 401
|
||||
|
@ -15,6 +15,9 @@ type
|
||||
|
||||
TMainForm = class(TForm)
|
||||
Bevel1: TBevel;
|
||||
Button1: TButton;
|
||||
Button2: TButton;
|
||||
Button3: TButton;
|
||||
cgPointTypes: TCheckGroup;
|
||||
cbMultiSelect: TCheckBox;
|
||||
Label1: TLabel;
|
||||
@ -24,6 +27,9 @@ type
|
||||
MapView: TMapView;
|
||||
PluginManager: TMvPluginManager;
|
||||
rgClickMode: TRadioGroup;
|
||||
procedure Button1Click(Sender: TObject);
|
||||
procedure Button2Click(Sender: TObject);
|
||||
procedure Button3Click(Sender: TObject);
|
||||
procedure cgPointTypesItemClick(Sender: TObject; Index: integer);
|
||||
procedure cbMultiSelectChange(Sender: TObject);
|
||||
procedure FormCreate(Sender: TObject);
|
||||
@ -111,6 +117,24 @@ procedure TMainForm.FormCreate(Sender: TObject);
|
||||
TMapTrackPoint(track.Points.Add).RealPoint := APoints[i];
|
||||
end;
|
||||
|
||||
procedure AddMapArea(const APoints: TRealPointArray);
|
||||
var
|
||||
layer: TMapLayer;
|
||||
area: TMapArea;
|
||||
i: Integer;
|
||||
begin
|
||||
if MapView.Layers.Count = 0 then
|
||||
layer := MapView.Layers.Add as TMapLayer
|
||||
else
|
||||
layer := MapView.Layers[0];
|
||||
area := layer.Areas.Add as TMapArea;
|
||||
area.Caption := 'Test area';
|
||||
area.FillColor := clBlue;
|
||||
area.Opacity := 0.5;
|
||||
for i := 0 to High(APoints) do
|
||||
TMapAreaPoint(area.Points.Add).RealPoint := APoints[i];
|
||||
end;
|
||||
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
@ -125,6 +149,8 @@ begin
|
||||
AddGPSTrack([RealPoint(-20,20), RealPoint(20, 0), RealPoint(-20,-20)]);
|
||||
AddMapTrack([RealPoint(20,20), RealPoint(-20,0), RealPoint(20,-20)]);
|
||||
|
||||
AddMapArea ([RealPoint(60, -45), RealPoint(70, -48), RealPoint(64, -35)]);
|
||||
|
||||
Plugin := TMarkerSelectAndDragPlugin.Create(PluginManager);
|
||||
|
||||
for i := 0 to cgPointTypes.Items.Count-1 do
|
||||
@ -148,6 +174,30 @@ begin
|
||||
Plugin.PointTypes := pointTypes;
|
||||
end;
|
||||
|
||||
procedure TMainForm.Button1Click(Sender: TObject);
|
||||
begin
|
||||
Plugin.DeleteSelectedPoints(MapView);
|
||||
end;
|
||||
|
||||
procedure TMainForm.Button2Click(Sender: TObject);
|
||||
begin
|
||||
with Plugin.ConvertSelectedPointsToMapTrack(MapView, MapView.Layers[0]) do
|
||||
begin
|
||||
LineColor := clGreen;
|
||||
LineWidth := 1.0;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainForm.Button3Click(Sender: TObject);
|
||||
begin
|
||||
with Plugin.ConvertSelectedPointsToMapArea(MapView, MapView.Layers[0]) do
|
||||
begin
|
||||
FillColor := clBlack;
|
||||
LineColor := clBlack;
|
||||
Opacity := 0.5;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainForm.cbMultiSelectChange(Sender: TObject);
|
||||
begin
|
||||
Plugin.MultiSelect := cbMultiSelect.Checked;
|
||||
|
@ -107,11 +107,12 @@ type
|
||||
FSelection: TGPSPointList;
|
||||
FOrigSelection: array of TRealPoint; // Selection before dragging starts
|
||||
FOnDrawPoint: TMarkerDrawPointEvent;
|
||||
FOnSelect: TNotifyEvent;
|
||||
FOnSelectionChange: TNotifyEvent;
|
||||
procedure SetMultiSelect(AValue: Boolean);
|
||||
protected
|
||||
procedure AddToSelection(AMapView: TMapView; APoint: TGPSPoint);
|
||||
procedure DoSelect(AMapView: TMapView);
|
||||
procedure DeleteFromList(AMapView: TMapView; APoint: TGPSPoint);
|
||||
procedure DoSelectionChange(AMapView: TMapView);
|
||||
procedure DragStart(AMapView: TMapView);
|
||||
procedure DragTo(AMapView: TMapView; X, Y: Integer);
|
||||
procedure DragEnd(AMapView: TMapView);
|
||||
@ -131,13 +132,16 @@ type
|
||||
public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
function ConvertSelectedPointsToMapArea(AMapView: TMapView; ALayer: TMapLayer): TMapArea;
|
||||
function ConvertSelectedPointsToMapTrack(AMapView: TMapView; ALayer: TMapLayer): TMapTrack;
|
||||
procedure DeleteSelectedPoints(AMapView: TMapView);
|
||||
property Selection: TGPSPointList read FSelection;
|
||||
published
|
||||
property ClickMode: TMarkerClickMode read FClickMode write FClickMode default mcmAddToSelection;
|
||||
property DragCursor: TCursor read FDragCursor write FDragCursor default crSizeAll;
|
||||
property MultiSelect: Boolean read FMultiSelect write SetMultiSelect default false;
|
||||
property OnDrawPoint: TMarkerDrawPointEvent read FOnDrawPoint write FOnDrawPoint;
|
||||
property OnSelect: TNotifyEvent read FOnSelect write FOnSelect;
|
||||
property OnSelectionChange: TNotifyEvent read FOnSelectionChange write FOnSelectionChange;
|
||||
end;
|
||||
|
||||
|
||||
@ -354,6 +358,29 @@ end;
|
||||
|
||||
{ TMarkerSelectAndDragPlugin }
|
||||
|
||||
type
|
||||
TMarkerData = record
|
||||
Lat, Lon: Double;
|
||||
Elevation: Double;
|
||||
DateTime: TDateTime;
|
||||
end;
|
||||
|
||||
function GPSPointToMarkerData(P: TGPSPoint): TMarkerData;
|
||||
begin
|
||||
Result.Lat := P.Lat;
|
||||
Result.Lon := P.Lon;
|
||||
Result.Elevation := P.Elevation;
|
||||
Result.DateTime := P.DateTime;
|
||||
end;
|
||||
|
||||
procedure MarkerDataToGPSPoint(M: TMarkerData; P: TGPSPoint);
|
||||
begin
|
||||
P.Lat := M.Lat;
|
||||
P.Lon := M.Lon;
|
||||
P.Elevation := M.Elevation;
|
||||
P.DateTime := M.DateTime;
|
||||
end;
|
||||
|
||||
constructor TMarkerSelectAndDragPlugin.Create(AOwner: TComponent);
|
||||
begin
|
||||
inherited;
|
||||
@ -384,7 +411,51 @@ begin
|
||||
FSelection.Clear;
|
||||
FSelection.Add(APoint);
|
||||
end;
|
||||
DoSelect(AMapView);
|
||||
DoSelectionChange(AMapView);
|
||||
end;
|
||||
|
||||
function TMarkerSelectAndDragPlugin.ConvertSelectedPointsToMapArea(
|
||||
AMapView: TMapView; ALayer: TMapLayer): TMapArea;
|
||||
var
|
||||
M: TMarkerData;
|
||||
P: TMapPoint;
|
||||
begin
|
||||
if FSelection.Count < 2 then
|
||||
raise EMvPluginException.Create('Selection must contain at least 3 points');
|
||||
|
||||
Result := ALayer.Areas.Add as TMapArea;
|
||||
while FSelection.Count > 0 do
|
||||
begin
|
||||
M := GPSPointToMarkerData(FSelection[0]);
|
||||
DeleteFromList(AMapView, FSelection[0]);
|
||||
FSelection.Delete(0);
|
||||
P := Result.Points.Add as TMapPoint;
|
||||
MarkerDataToGPSPoint(M, TGPSPoint(P.GPSObj));
|
||||
end;
|
||||
Update;
|
||||
DoSelectionChange(AMapView);
|
||||
end;
|
||||
|
||||
function TMarkerSelectAndDragPlugin.ConvertSelectedPointsToMapTrack(
|
||||
AMapView: TMapView; ALayer: TMapLayer): TMapTrack;
|
||||
var
|
||||
M: TMarkerData;
|
||||
P: TMapPoint;
|
||||
begin
|
||||
if FSelection.Count < 2 then
|
||||
raise EMvPluginException.Create('Selection must contain at least 2 points');
|
||||
|
||||
Result := ALayer.Tracks.Add as TMapTrack;
|
||||
while FSelection.Count > 0 do
|
||||
begin
|
||||
M := GPSPointToMarkerData(FSelection[0]);
|
||||
DeleteFromList(AMapView, FSelection[0]);
|
||||
FSelection.Delete(0);
|
||||
P := Result.Points.Add as TMapPoint;
|
||||
MarkerDataToGPSPoint(M, TGPSPoint(P.GPSObj));
|
||||
end;
|
||||
Update;
|
||||
DoSelectionChange(AMapView);
|
||||
end;
|
||||
|
||||
procedure TMarkerSelectAndDragPlugin.AfterDrawObjects(AMapView: TMapView;
|
||||
@ -394,10 +465,22 @@ begin
|
||||
DrawSelection(AMapView);
|
||||
end;
|
||||
|
||||
procedure TMarkerSelectAndDragPlugin.DoSelect(AMapView: TMapView);
|
||||
procedure TMarkerSelectAndDragPlugin.DeleteSelectedPoints(AMapView: TMapView);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
if Assigned(FOnSelect) then
|
||||
FOnSelect(AMapView);
|
||||
for i := FSelection.Count-1 downto 0 do
|
||||
begin
|
||||
DeleteFromList(AMapView, FSelection[i]);
|
||||
FSelection.Delete(i);
|
||||
end;
|
||||
Update;
|
||||
end;
|
||||
|
||||
procedure TMarkerSelectAndDragPlugin.DoSelectionChange(AMapView: TMapView);
|
||||
begin
|
||||
if Assigned(FOnSelectionChange) then
|
||||
FOnSelectionChange(AMapView);
|
||||
end;
|
||||
|
||||
procedure TMarkerSelectAndDragPlugin.DragStart(AMapView: TMapView);
|
||||
@ -406,7 +489,7 @@ var
|
||||
begin
|
||||
AMapView.Cursor := DragCursor;
|
||||
FDragging := true;
|
||||
// Save original selection point coordinates in case it must be restored later.
|
||||
// Save original selection point coordinates in case they must be restored later.
|
||||
SetLength(FOrigSelection, FSelection.Count);
|
||||
for i := 0 to High(FOrigSelection) do
|
||||
FOrigSelection[i] := FSelection[i].RealPoint;
|
||||
@ -467,7 +550,7 @@ begin
|
||||
DE.PenColor := clRed;
|
||||
DE.PenStyle := psSolid;
|
||||
DE.PenWidth := 2;
|
||||
DE.BrushColor := clWhite;
|
||||
DE.BrushColor := clBlack;
|
||||
DE.BrushStyle := bsSolid;
|
||||
markerSize := AMapView.Scale96ToFont(MARKER_SIZE);
|
||||
for i := 0 to FSelection.Count - 1 do
|
||||
@ -476,7 +559,7 @@ begin
|
||||
begin
|
||||
// The last point is marked as being "focused"
|
||||
DE.PenWidth := 3;
|
||||
DE.BrushColor := clBlack;
|
||||
DE.BrushColor := clLime;
|
||||
inc(markerSize, 1);
|
||||
end;
|
||||
P := AMapView.LatLonToScreen(FSelection[i].RealPoint);
|
||||
@ -559,6 +642,100 @@ begin
|
||||
DragEnd(AMapView);
|
||||
end;
|
||||
|
||||
{ Searches for the given point in all the point lists of the mapviewer
|
||||
(GPSItems, Layers, Tracks, Areas, POIs). If found, the point is removed
|
||||
from the list and destroyed. }
|
||||
procedure TMarkerSelectAndDragPlugin.DeleteFromList(AMapView: TMapView;
|
||||
APoint: TGPSPoint);
|
||||
var
|
||||
i, j, k: Integer;
|
||||
gpsLayer: TGPSObjectList;
|
||||
gpsPolyline: TGPSPolyLine;
|
||||
item: TGPSObj;
|
||||
p: TMapPoint;
|
||||
mapLayer: TMapLayer;
|
||||
mapTrack: TMapTrack;
|
||||
mapArea: TMapArea;
|
||||
|
||||
function IsSamePoint(AItem: TGPSObj): Boolean;
|
||||
begin
|
||||
Result := (AItem is TGPSPoint) and TGPSPoint(AItem).RealPoint.Equal(APoint.RealPoint);
|
||||
end;
|
||||
|
||||
begin
|
||||
// Check the 10 layers of GPSItems
|
||||
for i := 0 to 9 do
|
||||
begin
|
||||
gpsLayer := AMapView.GPSLayer[i];
|
||||
for j := 0 to gpsLayer.Count-1 do
|
||||
begin
|
||||
item := gpsLayer[j];
|
||||
if IsSamePoint(item) then
|
||||
begin
|
||||
gpsLayer.Delete(item);
|
||||
exit;
|
||||
end;
|
||||
if (item is TGPSPolyline) then
|
||||
begin
|
||||
gpsPolyLine := TGPSPolyLine(item);
|
||||
for k := 0 to gpsPolyLine.Points.Count-1 do
|
||||
begin
|
||||
item := gpsPolyLine.Points[k];
|
||||
if IsSamePoint(item) then
|
||||
begin
|
||||
gpsPolyLine.Points.Delete(k);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
// Check the map layers
|
||||
for i := 0 to AMapView.Layers.Count-1 do
|
||||
begin
|
||||
mapLayer := AMapView.Layers[i];
|
||||
// Points of interest?
|
||||
for j := 0 to mapLayer.PointsOfInterest.Count-1 do
|
||||
begin
|
||||
p := mapLayer.PointsOfInterest[j];
|
||||
if IsSamePoint(p.GPSObj) then
|
||||
begin
|
||||
mapLayer.PointsOfInterest.Delete(j);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
// Tracks?
|
||||
for j := 0 to mapLayer.Tracks.Count-1 do
|
||||
begin
|
||||
mapTrack := mapLayer.Tracks[j];
|
||||
for k := 0 to mapTrack.Points.Count-1 do
|
||||
begin
|
||||
p := mapTrack.Points[k];
|
||||
if IsSamePoint(p.GPSObj) then
|
||||
begin
|
||||
mapTrack.Points.Delete(k);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
// Areas?
|
||||
for j := 0 to mapLayer.Areas.Count-1 do
|
||||
begin
|
||||
mapArea := mapLayer.Areas[j];
|
||||
for k := 0 to mapArea.Points.Count-1 do
|
||||
begin
|
||||
p := mapArea.Points[k];
|
||||
if IsSamePoint(p.GPSObj) then
|
||||
begin
|
||||
mapArea.Points.Delete(k);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMarkerSelectAndDragPlugin.SetMultiSelect(AValue: Boolean);
|
||||
begin
|
||||
if FMultiSelect = AValue then exit;
|
||||
@ -584,7 +761,7 @@ begin
|
||||
FSelection.Add(APoint);
|
||||
end else
|
||||
FSelection.Delete(idx);
|
||||
DoSelect(AMapView);
|
||||
DoSelectionChange(AMapView);
|
||||
end;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user