LazMapViewer: Preparation for new OPM version 1.0

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9722 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz 2025-04-11 14:17:21 +00:00
parent 5dc6af3267
commit 689d323d5c
12 changed files with 523 additions and 151 deletions

View File

@ -15,9 +15,6 @@
</General>
<BuildModes>
<Item Name="Default" Default="True"/>
<SharedMatrixOptions Count="1">
<Item1 ID="966991393514" Modes="Default" Value="-gw3"/>
</SharedMatrixOptions>
</BuildModes>
<PublishOptions>
<Version Value="2"/>

View File

@ -17,7 +17,7 @@ uses
begin
RequireDerivedFormResource := True;
Application.Scaled := True;
Application.Scaled:=True;
{$PUSH}{$WARN 5044 OFF}
Application.MainFormOnTaskbar := True;
{$POP}

View File

@ -26,6 +26,11 @@
<Mode Name="default"/>
</BuildModes>
</Target>
<Target FileName="examples\fulldemo\mapviewer_demo_with_addons.lpi">
<BuildModes>
<Mode Name="default"/>
</BuildModes>
</Target>
<Target FileName="examples\gpstilelayer_demo\GPSTileLayer_Demo.lpi">
<BuildModes>
<Mode Name="Default"/>

View File

@ -15,7 +15,7 @@
</CompilerOptions>
<Description Value="Add-on to LazMapViewer: Contains the drawing engine based on the BGRABitmap library."/>
<License Value="modified LGPL with linking exception, like FreePascal RTL/FCL and Lazarus LCL"/>
<Version Minor="2" Release="7"/>
<Version Major="1"/>
<Files Count="1">
<Item1>
<Filename Value="source\addons\bgra_drawingengine\mvde_bgra.pas"/>

View File

@ -15,7 +15,7 @@
</CompilerOptions>
<Description Value="Add-on to LazMapViewer: Contains the drawing engine based on the RGBGraphics package."/>
<License Value="modified LGPL with linking exception, like FreePascal RTL/FCL and Lazarus LCL"/>
<Version Minor="2" Release="7"/>
<Version Major="1"/>
<Files Count="1">
<Item1>
<Filename Value="source\addons\rgbgraphics_drawingengine\mvde_rgbgraphics.pas"/>

View File

@ -15,7 +15,7 @@
</CompilerOptions>
<Description Value="Add-on to LazMapViewer: Contains the download engine based on the Synapse library."/>
<License Value="modified LGPL with linking exception, like FreePascal RTL/FCL and Lazarus LCL"/>
<Version Minor="2" Release="7"/>
<Version Major="1"/>
<Files Count="1">
<Item1>
<Filename Value="source\addons\synapse_downloadengine\mvdlesynapse.pas"/>

View File

@ -22,7 +22,7 @@
FPC 3.2.0 or newer required."/>
<License Value="Modified LGPL with linking exception, like FreePascal RTL/FCL and Lazarus LCL"/>
<Version Minor="2" Release="7"/>
<Version Major="1"/>
<Files Count="36">
<Item1>
<Filename Value="source/mvcache.pas"/>

View File

@ -1,3 +1,39 @@
{-------------------------------------------------------------------------------
mvPlugins.pas
License: modified LGPL with linking exception (like RTL, FCL and LCL)
See the file COPYING.modifiedLGPL.txt, included in the Lazarus distribution,
for details about the license.
See also: https://wiki.lazarus.freepascal.org/FPC_modified_LGPL
--------------------------------------------------------------------------------
This unit contains several basic general-purpose plugins:
- TCenterMarkerPlugin
Draws a cross in the center of the visible map window.
- TTileInfoPlugin
Draws boundary lines around each tile image from which the overall map is
composed, and displays the x and y indices, as well as the zoom level, of
each tile in the map provider's repository.
- TLinkedMapsPlugin
Links two (or more) mapviews such that each zooming or panning operation in
one mapview is transferred to the other maps so that always the same
view of the total map is visible in all maps.
- TLegalNoticePlugin
Displays a clickable notice at the border of a mapview showing from which
provider this map was downloaded. A click is supposed to open the privider's
"Copyright and License" page in the internet.
- TUserDefinedPlugin
A plugin without special purpose. It merely provides events in which the
user can execute specific handlers.
-------------------------------------------------------------------------------}
unit mvPlugins;
{$mode objfpc}{$H+}

View File

@ -5,7 +5,7 @@
(C) 2014 ti_dic@hotmail.com
(C) 2019 Werner Pamler (user wp at Lazarus forum https://forum.lazarus.freepascal.org)
(C) 2023 Yuliyan Ivanov (user alpine at Lazarus forum https://forum.lazarus.freepascal.org)
(C) 2024 Ekkehard Domning (edo-at-domis.de)
(C) 2024 Ekkehard Domning (edo at domis.de)
License: modified LGPL with linking exception (like RTL, FCL and LCL)
@ -17,7 +17,7 @@
// "Deprecated" warnings:
// - function names containing "LonLat" were copied and named to contain "LatLon"
// (will be removed in v1.0)
// (will be removed after v1.0)
unit mvMapViewer;

View File

@ -1,33 +1,33 @@
object MapViewerPathEditForm: TMapViewerPathEditForm
Left = 1036
Height = 227
Height = 332
Top = 315
Width = 413
AutoSize = True
BorderStyle = bsSizeToolWin
Caption = 'MapViewer Path Editor'
ClientHeight = 227
ClientHeight = 332
ClientWidth = 413
LCLVersion = '4.99.0.0'
OnActivate = FormActivate
OnShow = FormShow
object pnlFrame: TPanel
Left = 0
Height = 157
Height = 268
Top = 28
Width = 413
Align = alClient
BevelOuter = bvNone
ClientHeight = 157
ClientHeight = 268
ClientWidth = 413
TabOrder = 0
TabOrder = 1
object lblSelectedLayer: TLabel
AnchorSideTop.Control = cbSelectedLayer
AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = cbSelectedLayer
Left = 32
Left = 40
Height = 15
Top = 127
Top = 7
Width = 31
Alignment = taRightJustify
Anchors = [akTop, akRight]
@ -36,55 +36,55 @@ object MapViewerPathEditForm: TMapViewerPathEditForm
ParentColor = False
end
object cbSelectedLayer: TComboBox
AnchorSideTop.Control = pnlSel
AnchorSideTop.Side = asrBottom
AnchorSideTop.Control = pnlFrame
AnchorSideRight.Control = pnlFrame
AnchorSideRight.Side = asrBottom
Left = 68
Left = 76
Height = 23
Top = 123
Width = 342
Top = 3
Width = 334
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Top = 6
BorderSpacing.Top = 3
BorderSpacing.Right = 3
BorderSpacing.Bottom = 6
BorderSpacing.Bottom = 3
ItemHeight = 15
ParentColor = True
ParentShowHint = False
ReadOnly = True
ShowHint = True
TabOrder = 0
TabOrder = 1
OnDropDown = cbSelectedLayerDropDown
OnSelect = cbSelectedLayerSelect
end
object pnlSel: TPanel
AnchorSideLeft.Control = pnlFrame
AnchorSideTop.Control = pnlFrame
AnchorSideTop.Control = cbSelectedLayer
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = pnlFrame
AnchorSideRight.Side = asrBottom
Left = 3
Height = 114
Top = 3
Height = 211
Top = 29
Width = 407
Anchors = [akTop, akLeft, akRight]
AutoSize = True
BorderSpacing.Around = 3
BevelInner = bvRaised
BevelOuter = bvLowered
ClientHeight = 114
ClientHeight = 211
ClientWidth = 407
TabOrder = 1
TabOrder = 0
object lblSelectedPt: TLabel
AnchorSideLeft.Control = pnlSel
AnchorSideTop.Control = cbSelectedPt
AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = cbSelectedPt
Left = 14
Left = 18
Height = 15
Top = 9
Width = 51
Alignment = taRightJustify
BorderSpacing.Left = 12
BorderSpacing.Left = 16
BorderSpacing.Right = 6
Caption = 'Selection:'
ParentColor = False
@ -95,10 +95,10 @@ object MapViewerPathEditForm: TMapViewerPathEditForm
AnchorSideTop.Control = pnlSel
AnchorSideRight.Control = pnlSel
AnchorSideRight.Side = asrBottom
Left = 71
Left = 75
Height = 23
Top = 5
Width = 331
Width = 327
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Top = 3
BorderSpacing.Right = 3
@ -109,13 +109,13 @@ object MapViewerPathEditForm: TMapViewerPathEditForm
ShowHint = True
TabOrder = 0
end
object lblLat: TLabel
object lblLatitude: TLabel
AnchorSideLeft.Control = pnlSel
AnchorSideTop.Control = cbLat
AnchorSideTop.Control = edLatitude
AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = lblSelectedPt
AnchorSideRight.Side = asrBottom
Left = 19
Left = 23
Height = 15
Top = 35
Width = 46
@ -125,31 +125,31 @@ object MapViewerPathEditForm: TMapViewerPathEditForm
Caption = 'Latitude:'
ParentColor = False
end
object cbLat: TEdit
object edLatitude: TEdit
AnchorSideLeft.Control = cbSelectedPt
AnchorSideTop.Control = cbSelectedPt
AnchorSideTop.Side = asrBottom
AnchorSideRight.Side = asrBottom
Left = 71
Left = 75
Height = 23
Top = 31
Width = 115
Width = 125
BorderSpacing.Top = 3
BorderSpacing.Right = 3
BorderSpacing.Bottom = 3
ParentShowHint = False
ShowHint = True
TabOrder = 1
OnEditingDone = cbLatLonEditingDone
OnEnter = cbLatEnter
OnExit = cbLatLonExit
OnEditingDone = edLatLonEditingDone
OnEnter = edLatitudeEnter
OnExit = edEditExit
end
object lblLon: TLabel
AnchorSideTop.Control = cbLon
object lblLongitude: TLabel
AnchorSideTop.Control = edLongitude
AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = lblSelectedPt
AnchorSideRight.Side = asrBottom
Left = 8
Left = 12
Height = 15
Top = 61
Width = 57
@ -159,41 +159,42 @@ object MapViewerPathEditForm: TMapViewerPathEditForm
Caption = 'Longitude:'
ParentColor = False
end
object cbLon: TEdit
object edLongitude: TEdit
AnchorSideLeft.Control = lblSelectedPt
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = cbLat
AnchorSideTop.Control = edLatitude
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = pnlSel
AnchorSideRight.Side = asrBottom
Left = 71
Left = 75
Height = 23
Top = 57
Width = 115
Width = 125
BorderSpacing.Right = 3
BorderSpacing.Bottom = 3
ParentShowHint = False
ShowHint = True
TabOrder = 2
OnEditingDone = cbLatLonEditingDone
OnEnter = cbLonEnter
OnExit = cbLatLonExit
OnEditingDone = edLatLonEditingDone
OnEnter = edLongitudeEnter
OnExit = edEditExit
end
object edCaption: TEdit
AnchorSideLeft.Control = cbLon
AnchorSideTop.Control = cbLon
AnchorSideLeft.Control = edLongitude
AnchorSideTop.Control = edDateTime
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = pnlSel
AnchorSideRight.Side = asrBottom
Left = 71
Left = 75
Height = 23
Top = 83
Width = 331
Top = 135
Width = 327
Anchors = [akTop, akLeft, akRight]
AutoSize = False
BorderSpacing.Top = 3
BorderSpacing.Right = 3
BorderSpacing.Bottom = 6
TabOrder = 3
TabOrder = 4
OnEditingDone = edCaptionEditingDone
end
object lblCaption: TLabel
@ -201,28 +202,134 @@ object MapViewerPathEditForm: TMapViewerPathEditForm
AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = lblSelectedPt
AnchorSideRight.Side = asrBottom
Left = 20
Left = 24
Height = 15
Top = 87
Top = 139
Width = 45
Alignment = taRightJustify
Anchors = [akTop, akRight]
BorderSpacing.Left = 6
Caption = 'Caption:'
end
object lblElevation: TLabel
AnchorSideTop.Control = edElevation
AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = lblSelectedPt
AnchorSideRight.Side = asrBottom
Left = 18
Height = 15
Top = 87
Width = 51
Alignment = taRightJustify
Anchors = [akTop, akRight]
BorderSpacing.Left = 6
Caption = 'Elevation:'
ParentColor = False
end
object edElevation: TEdit
AnchorSideLeft.Control = lblSelectedPt
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = edLongitude
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = pnlSel
AnchorSideRight.Side = asrBottom
Left = 75
Height = 23
Top = 83
Width = 125
BorderSpacing.Right = 3
BorderSpacing.Bottom = 3
ParentShowHint = False
ShowHint = True
TabOrder = 3
OnEditingDone = edElevationEditingDone
OnEnter = edElevationEnter
OnExit = edEditExit
end
object lblMeters: TLabel
AnchorSideLeft.Control = edElevation
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = edElevation
AnchorSideTop.Side = asrCenter
Left = 203
Height = 15
Top = 87
Width = 11
BorderSpacing.Left = 3
Caption = 'm'
end
object lblDateTime: TLabel
AnchorSideTop.Control = edDateTime
AnchorSideTop.Side = asrCenter
AnchorSideRight.Control = lblSelectedPt
AnchorSideRight.Side = asrBottom
Left = 13
Height = 15
Top = 113
Width = 56
Alignment = taRightJustify
Anchors = [akTop, akRight]
BorderSpacing.Left = 6
Caption = 'Date/time:'
ParentColor = False
end
object edDateTime: TEdit
AnchorSideLeft.Control = cbSelectedPt
AnchorSideTop.Control = edElevation
AnchorSideTop.Side = asrBottom
Left = 75
Height = 23
Top = 109
Width = 125
BorderSpacing.Bottom = 3
TabOrder = 5
OnEditingDone = edDateTimeEditingDone
OnEnter = edDateTimeEnter
OnExit = edEditExit
end
object cmbImageIndex: TComboBox
AnchorSideLeft.Control = edLongitude
AnchorSideTop.Control = edCaption
AnchorSideTop.Side = asrBottom
AnchorSideRight.Side = asrBottom
Left = 75
Height = 42
Top = 164
Width = 100
BorderSpacing.Right = 3
BorderSpacing.Bottom = 3
ItemHeight = 36
ReadOnly = True
Style = csOwnerDrawFixed
TabOrder = 6
OnCloseUp = cmbImageIndexCloseUp
OnDrawItem = cmbImageIndexDrawItem
OnExit = edEditExit
end
object lblImageIndex: TLabel
AnchorSideTop.Control = cmbImageIndex
AnchorSideRight.Control = lblSelectedPt
AnchorSideRight.Side = asrBottom
Left = 33
Height = 15
Top = 164
Width = 36
Anchors = [akTop, akRight]
Caption = 'Image:'
end
end
end
object pnlInfo: TPanel
Left = 0
Height = 39
Top = 188
Height = 36
Top = 296
Width = 413
Align = alBottom
AutoSize = True
BevelOuter = bvNone
ClientHeight = 39
ClientHeight = 36
ClientWidth = 413
TabOrder = 1
TabOrder = 2
object lblInfoTitle: TLabel
AnchorSideLeft.Control = pnlInfo
AnchorSideTop.Control = pnlInfo
@ -230,10 +337,9 @@ object MapViewerPathEditForm: TMapViewerPathEditForm
AnchorSideBottom.Side = asrBottom
Left = 6
Height = 15
Top = 3
Top = 0
Width = 59
BorderSpacing.Left = 6
BorderSpacing.Top = 3
BorderSpacing.Right = 6
Caption = 'lblInfotitle'
Font.Style = [fsBold]
@ -246,7 +352,7 @@ object MapViewerPathEditForm: TMapViewerPathEditForm
AnchorSideTop.Side = asrBottom
Left = 6
Height = 15
Top = 18
Top = 15
Width = 55
BorderSpacing.Bottom = 6
Caption = 'lblInfoText'
@ -261,11 +367,11 @@ object MapViewerPathEditForm: TMapViewerPathEditForm
ButtonHeight = 28
ButtonWidth = 28
Caption = 'ToolBar'
EdgeBorders = []
EdgeBorders = [ebBottom]
Images = ilImages
ParentShowHint = False
ShowHint = True
TabOrder = 2
TabOrder = 0
object tbSelect: TToolButton
Left = 1
Top = 0
@ -321,16 +427,6 @@ object MapViewerPathEditForm: TMapViewerPathEditForm
Action = actZoomOut
end
end
object Bevel: TBevel
Left = 3
Height = 3
Top = 185
Width = 407
Align = alBottom
BorderSpacing.Left = 3
BorderSpacing.Right = 3
Shape = bsTopLine
end
object alEditActions: TActionList
Images = ilImages
Left = 128

View File

@ -5,8 +5,9 @@ unit mvMapViewerPathEditForm;
interface
uses
Classes, SysUtils, Math, Forms, Controls, Graphics, Dialogs, StdCtrls, ComCtrls,
ExtCtrls, Buttons, ActnList, mvMapViewer, mvGpsObj, mvTypes, Types;
Classes, SysUtils, DateUtils, Math,
Forms, Controls, LCLType, Graphics, Dialogs, StdCtrls, ComCtrls,
ExtCtrls, Buttons, ActnList, EditBtn, mvMapViewer, mvGpsObj, mvTypes, Types;
type
@ -24,18 +25,24 @@ type
actZoomOut: TAction;
actZoomIn: TAction;
alEditActions: TActionList;
Bevel: TBevel;
cbLon: TEdit;
cmbImageIndex: TComboBox;
edDateTime: TEdit;
edLongitude: TEdit;
edElevation: TEdit;
cbSelectedLayer: TComboBox;
cbSelectedPt: TEdit;
cbLat: TEdit;
edLatitude: TEdit;
edCaption: TEdit;
ilImages: TImageList;
lblImageIndex: TLabel;
lblDateTime: TLabel;
lblMeters: TLabel;
lblInfoText: TLabel;
lblInfoTitle: TLabel;
lblCaption: TLabel;
lblLat: TLabel;
lblLon: TLabel;
lblLatitude: TLabel;
lblLongitude: TLabel;
lblElevation: TLabel;
lblSelectedLayer: TLabel;
lblSelectedPt: TLabel;
pnlSel: TPanel;
@ -60,13 +67,20 @@ type
procedure actSelectExecute(Sender: TObject);
procedure actZoomInExecute(Sender: TObject);
procedure actZoomOutExecute(Sender: TObject);
procedure cbLatLonEditingDone(Sender: TObject);
procedure cbLatEnter(Sender: TObject);
procedure cbLatLonExit(Sender: TObject);
procedure cbLonEnter(Sender: TObject);
procedure cbSelectedLayerDropDown(Sender: TObject);
procedure cbSelectedLayerSelect(Sender: TObject);
procedure cmbImageIndexCloseUp(Sender: TObject);
procedure cmbImageIndexDrawItem(Control: TWinControl; Index: Integer;
ARect: TRect; State: TOwnerDrawState);
procedure edCaptionEditingDone(Sender: TObject);
procedure edDateTimeEditingDone(Sender: TObject);
procedure edDateTimeEnter(Sender: TObject);
procedure edEditExit(Sender: TObject);
procedure edElevationEditingDone(Sender: TObject);
procedure edLatLonEditingDone(Sender: TObject);
procedure edElevationEnter(Sender: TObject);
procedure edLatitudeEnter(Sender: TObject);
procedure edLongitudeEnter(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure FormShow(Sender: TObject);
private
@ -125,6 +139,14 @@ const
'Area mode|Click to add point, CTRL-click to add last point.' // pemAddArea
);
ELEVATION_FORMAT = '0'; // no decimal places
DATETIME_FORMAT = 'ddddd t'; // short date & short time format
IMG_MARGIN = 2;
sNone = '(none)';
sNotSelected = '(not selected)';
sVarying = '(varying)';
type
TPersistentAccess = class(TPersistent);
@ -315,48 +337,6 @@ begin
end;
end;
procedure TMapViewerPathEditForm.cbLatLonEditingDone(Sender: TObject);
var
E: TEdit;
Deg: Double;
R: Boolean;
P: TMapPoint;
IsLat: Boolean;
begin
E := Sender as TEdit;
if not E.Modified then
Exit;
R := TryStrDMSToDeg(E.Text, Deg);
if not R then
raise EArgumentException.Create('Invalid value.');
// Assignment
IsLat := Sender = cbLat;
for P in MapView.EditMark.Selection.Points do
begin
if IsLat
then P.Latitude := Deg
else P.Longitude := Deg;
ObjectModified(P, '');
end;
end;
procedure TMapViewerPathEditForm.cbLatEnter(Sender: TObject);
begin
cbLat.Caption := LatToStr(MapView.EditMark.CurrentPoint.Latitude,
mvoLatLonInDMS in MapView.Options);
end;
procedure TMapViewerPathEditForm.cbLatLonExit(Sender: TObject);
begin
UpdateControls;
end;
procedure TMapViewerPathEditForm.cbLonEnter(Sender: TObject);
begin
cbLon.Caption := LonToStr(MapView.EditMark.CurrentPoint.Longitude,
mvoLatLonInDMS in MapView.Options);
end;
procedure TMapViewerPathEditForm.cbSelectedLayerDropDown(Sender: TObject);
begin
UpdateLayerItems;
@ -370,6 +350,52 @@ begin
UpdateControls;
end;
procedure TMapViewerPathEditForm.cmbImageIndexCloseUp(Sender: TObject);
var
cmb: TComboBox;
P: TMapPoint;
begin
cmb := Sender as TComboBox;
for P in MapView.EditMark.Selection.Points do
begin
if (P is TMapPointOfInterest) then
begin
if cmb.ItemIndex = -1 then
TMapPointOfInterest(P).ImageIndex := -1
else
TMapPointOfInterest(P).ImageIndex := cmb.ItemIndex - 1;
ObjectModified(P, '');
end;
end;
end;
procedure TMapViewerPathEditForm.cmbImageIndexDrawItem(Control: TWinControl;
Index: Integer; ARect: TRect; State: TOwnerDrawState);
var
cmb: TCombobox;
h: Integer;
begin
cmb := Control as TComboBox;
cmb.Canvas.Font.Assign(cmb.Font);
h := cmb.Canvas.TextHeight('Tgj');
if (odFocused in State) then
begin
cmb.Canvas.Brush.Color := clHighlight;
cmb.Canvas.Font.Color := clHighlightText;
end else
begin
cmb.Canvas.Brush.Color := clWindow;
cmb.Canvas.Font.Color := clWindowText;
end;
if not (odBackgroundPainted in State) then
cmb.Canvas.FillRect(ARect);
InflateRect(ARect, -IMG_MARGIN, -IMG_MARGIN);
if Index <= 0 then
cmb.Canvas.TextOut(ARect.Left, (ARect.Top + ARect.Bottom - h) div 2, sNone)
else
FMapView.POIImages.Draw(cmb.Canvas, ARect.Left, ARect.Top, Index - 1);
end;
procedure TMapViewerPathEditForm.edCaptionEditingDone(Sender: TObject);
var
E: TEdit;
@ -388,6 +414,126 @@ begin
end;
end;
procedure TMapViewerPathEditForm.edDateTimeEditingDone(Sender: TObject);
var
E: TEdit;
dateVal: TDate;
timeVal: TTime;
dt: TDateTime;
P: TMapPoint;
sa: TStringArray;
begin
E := Sender as TEdit;
if not E.Modified then
exit;
if E.Text = '' then
dt := NO_DATE
else
begin
sa := String(E.Text).Split(' ');
if sa[0] <> '' then
begin
if not TryStrToDate(sa[0], dateVal) then
dateVal := NO_DATE
end;
if sa[1] <> '' then
begin
if not TryStrToTime(sa[1], timeVal) then
timeVal := 0.0;
end;
if dateVal <> NO_DATE then
dt := dateVal + timeVal
else
dt := NO_DATE;
end;
for P in MapView.EditMark.Selection.Points do
begin
P.DateTime := dt;
ObjectModified(P, '');
end;
end;
procedure TMapViewerPathEditForm.edDateTimeEnter(Sender: TObject);
begin
if MapView.EditMark.CurrentPoint.DateTime = NO_DATE then
edDateTime.Text := ''
else
edDateTime.Text := FormatDateTime(DATETIME_FORMAT, MapView.EditMark.CurrentPoint.DateTime);
end;
procedure TMapViewerPathEditForm.edElevationEditingDone(Sender: TObject);
var
E: TEdit;
elev: Double;
P: TMapPoint;
begin
E := Sender as TEdit;
if not E.Modified then
exit;
if E.Text = '' then
elev := NO_ELEVATION
else
if not TryStrToFloat(E.Text, elev) then
raise EArgumentException.Create('Invalid value.');
for P in MapView.EditMark.Selection.Points do
begin
P.Elevation := elev;
ObjectModified(P, '');
end;
end;
procedure TMapViewerPathEditForm.edElevationEnter(Sender: TObject);
begin
if MapView.EditMark.CurrentPoint.Elevation = NO_ELEVATION then
edElevation.Text := ''
else
edElevation.Text := FormatFloat(ELEVATION_FORMAT, MapView.EditMark.CurrentPoint.Elevation);
end;
procedure TMapViewerPathEditForm.edLatitudeEnter(Sender: TObject);
begin
edLatitude.Text := LatToStr(MapView.EditMark.CurrentPoint.Latitude,
mvoLatLonInDMS in MapView.Options);
end;
procedure TMapViewerPathEditForm.edLatLonEditingDone(Sender: TObject);
var
E: TEdit;
Deg: Double;
R: Boolean;
P: TMapPoint;
IsLat: Boolean;
begin
E := Sender as TEdit;
if not E.Modified then
Exit;
R := TryStrDMSToDeg(E.Text, Deg);
if not R then
raise EArgumentException.Create('Invalid value.');
// Assignment
IsLat := Sender = edLatitude;
for P in MapView.EditMark.Selection.Points do
begin
if IsLat
then P.Latitude := Deg
else P.Longitude := Deg;
ObjectModified(P, '');
end;
end;
procedure TMapViewerPathEditForm.edEditExit(Sender: TObject);
begin
UpdateControls;
end;
procedure TMapViewerPathEditForm.edLongitudeEnter(Sender: TObject);
begin
edLongitude.Caption := LonToStr(MapView.EditMark.CurrentPoint.Longitude,
mvoLatLonInDMS in MapView.Options);
end;
procedure TMapViewerPathEditForm.FormActivate(Sender: TObject);
var
w: Integer;
@ -395,7 +541,7 @@ begin
if not FActivated then
begin
AutoSize := false;
w := MaxValue([lblSelectedPt.Width, lblLat.Width, lblLon.Width, lblCaption.Width]);
w := MaxValue([lblSelectedPt.Width, lblLatitude.Width, lblLongitude.Width, lblCaption.Width]);
cbSelectedPt.Left := w + lblSelectedPt.BorderSpacing.Left + lblSelectedPt.BorderSpacing.Right;
cbSelectedLayer.Left := cbSelectedPt.Left + pnlSel.Left;
AutoSize := true;
@ -780,17 +926,20 @@ end;
procedure TMapViewerPathEditForm.UpdateControls;
var
P, P0: TMapPoint;
P: TMapPoint;
P0: TMapPoint = nil;
PtTxt: String;
i: Integer;
PtCnt: Integer = 0;
HaveView, HaveLayer, HaveSel, HavePt: Boolean;
VaryingLat, VaryingLon: Boolean;
HaveView, HaveLayer, HaveSel, HavePt, HaveImg: Boolean;
VaryingLat, VaryingLon, VaryingElev, VaryingDateTime: Boolean;
Erasable: Boolean = False;
begin
HaveView := Assigned(MapView);
HaveSel := HaveView and MapView.EditMark.HasSelection;
HavePt := HaveSel and (MapView.EditMark.Selection[0] is TMapPoint);
HaveLayer := Assigned(MapLayer);
HaveImg := HavePt and Assigned(MapView.POIImages) and (MapView.POIImages.Count > 0);
if not HaveLayer then
begin
@ -803,21 +952,22 @@ begin
if HaveView
then Caption := MapView.Name + ': ' + TMapView.ClassName
else Caption := TMapView.ClassName + ' (Not selected)';
else Caption := TMapView.ClassName + ' ' + sNotSelected;
// Update layer name
if HaveLayer
then cbSelectedLayer.Text := MapItemCaption(MapLayer)
else cbSelectedLayer.Text := '(none)';
else cbSelectedLayer.Text := sNone;
cbSelectedLayer.Hint := cbSelectedLayer.Text;
// Update currently selected point
PtTxt := '(none)';
PtTxt := sNone;
if HavePt then
begin
for P in MapView.EditMark.Selection.Points do
Inc(PtCnt);
P0 := TMapPoint(MapView.EditMark.Selection[0]);
haveImg := HaveImg and (P0 is TMapPointOfInterest);
VaryingLat := False;
for P in MapView.EditMark.Selection.Points.Skip(1) do
@ -835,16 +985,54 @@ begin
Break;
end;
VaryingElev := False;
for P in MapView.EditMark.Selection.Points.Skip(1) do
if P.Elevation <> P0.Elevation then
begin
VaryingElev := True;
Break;
end;
VaryingDateTime := False;
for P in MapView.EditMark.Selection.Points.Skip(1) do
if P.DateTime <> P0.DateTime then
begin
VaryingDateTime := True;
Break;
end;
if VaryingLat
then cbLat.Caption := '(varying)'
else cbLat.Caption := LatToStr(P0.Latitude, mvoLatLonInDMS in MapView.Options);
then edLatitude.Text := sVarying
else edLatitude.Text := LatToStr(P0.Latitude, mvoLatLonInDMS in MapView.Options);
if VaryingLon
then cbLon.Caption := '(varying)'
else cbLon.Caption := LonToStr(P0.Longitude, mvoLatLonInDMS in MapView.Options);
then edLongitude.Text := sVarying
else edLongitude.Text := LonToStr(P0.Longitude, mvoLatLonInDMS in MapView.Options);
if VaryingElev
then edElevation.Text := sVarying
else if P0.Elevation = NO_ELEVATION
then edElevation.Text := ''
else edElevation.Text := FormatFloat(ELEVATION_FORMAT, P0.Elevation);
if VaryingDateTime
then edDateTime.Text := sVarying
else if P0.DateTime = NO_DATE
then edDateTime.Text := ''
else edDateTime.Text := FormatDateTime(DATETIME_FORMAT, P0.DateTime);
edCaption.Text := P0.Caption;
if HaveImg then
begin
cmbImageIndex.ItemHeight := MapView.POIImages.Height + 2 * IMG_MARGIN;
cmbImageIndex.Items.Clear;
for i := 0 to MapView.POIImages.Count do // missing -1 intentional!
cmbImageIndex.Items.Add(IntToStr(i));
cmbImageIndex.ItemIndex := TMapPointOfInterest(P0).ImageIndex + 1;
end else
cmbImageIndex.Items.Clear;
FPointCnt := PtCnt;
if PtCnt > 0 then
begin
@ -863,20 +1051,31 @@ begin
else
begin
FPointCnt := 0;
cbLat.Caption := '';
cbLon.Caption := '';
edLatitude.Text := '';
edLongitude.Text := '';
edElevation.Text := '';
edCaption.Text := '';
edDateTime.Text := '';
cmbImageIndex.ItemIndex := -1;
cmbImageIndex.Items.Clear;
end;
cbSelectedPt.Text := PtTxt;
cbSelectedPt.Hint := PtTxt;
cbLat.Enabled := HavePt;
lblLat.Enabled := HavePt;
cbLon.Enabled := HavePt;
lblLon.Enabled := HavePt;
edLatitude.Enabled := HavePt;
lblLatitude.Enabled := HavePt;
edLongitude.Enabled := HavePt;
lblLongitude.Enabled := HavePt;
edElevation.Enabled := HavePt;
lblElevation.Enabled := HavePt;
lblMeters.Enabled := HavePt;
edDateTime.Enabled := HavePt;
lblDateTime.Enabled := HavePt;
edCaption.Enabled := HavePt and (P0 is TMapPointOfInterest);
lblCaption.Enabled := edCaption.Enabled;
cmbImageIndex.Enabled := HaveImg;
lblImageIndex.Enabled := HaveImg;
// Update actions
actZoomIn.Enabled := HaveView and (MapView.Zoom < MapView.ZoomMax);

View File

@ -1,3 +1,42 @@
{-------------------------------------------------------------------------------
mvPluginCommon.pas
License: modified LGPL with linking exception (like RTL, FCL and LCL)
See the file COPYING.modifiedLGPL.txt, included in the Lazarus distribution,
for details about the license.
See also: https://wiki.lazarus.freepascal.org/FPC_modified_LGPL
--------------------------------------------------------------------------------
This unit provides a common infra-structure for all plugins:
- TMvCustomPlugin
the ancestor of all plugins. Provides virtual methods which hook into the
MapView's main events and can be overridden by descendant plugins
- TMvPlugin
A descendant of TMvCustomPlugin publishing some properties
- TMvDrawPlugin
A TMvPlugin-descendant dedicated to drawing purposes. It provides Pen,
Font, BackgroundColor and BackgroundOpacity properties to be used.
- TMvMarkerPlugin
Another TMvPlugin-descandent, now dedicated to cooperation with
TGPSPoints and TMapPoints ("markers") added to a MapView.
- TMvMultiMapsPlugin
Descending from TMvCustomPlugin, specialized to handle multiple mapviews.
- TMvMultiMapsDrawPlugin
Combines properties of TMvMultiMapsPlugin and TMvDrawPlugin
- TMvPluginManager
A descendant of TMvCustomPluginManager to cooperate between plugins an
mapview.
-------------------------------------------------------------------------------}
unit mvPluginCommon;
{$mode objfpc}{$H+}
@ -154,7 +193,6 @@ type
end;
{ TMvMultiMapsPluginData }
const
DefaultMultiMapsMapViewEnabled = True;
@ -207,6 +245,7 @@ type
property Enabled;
end;
{ TMvMultiMapsDrawPlugin }
TMvMultiMapsDrawPlugin = class(TMvMultiMapsPlugin)