LazMapViewer: Add GreatCirclePainterPlugin by Ekkehard Domning. Refactor some calculation routines in mvGeoMath
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9609 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
320d413df5
commit
06b87dfade
@ -0,0 +1,154 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<CONFIG>
|
||||||
|
<ProjectOptions>
|
||||||
|
<Version Value="12"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<General>
|
||||||
|
<SessionStorage Value="InProjectDir"/>
|
||||||
|
<Title Value="greatcircle_demo"/>
|
||||||
|
<Scaled Value="True"/>
|
||||||
|
<ResourceType Value="res"/>
|
||||||
|
<UseXPManifest Value="True"/>
|
||||||
|
<XPManifest>
|
||||||
|
<DpiAware Value="True"/>
|
||||||
|
</XPManifest>
|
||||||
|
<Icon Value="0"/>
|
||||||
|
</General>
|
||||||
|
<BuildModes>
|
||||||
|
<Item Name="Default" Default="True"/>
|
||||||
|
<Item Name="Debug">
|
||||||
|
<CompilerOptions>
|
||||||
|
<Version Value="11"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<Target>
|
||||||
|
<Filename Value="greatcircle_demo"/>
|
||||||
|
</Target>
|
||||||
|
<SearchPaths>
|
||||||
|
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||||
|
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||||
|
</SearchPaths>
|
||||||
|
<Parsing>
|
||||||
|
<SyntaxOptions>
|
||||||
|
<IncludeAssertionCode Value="True"/>
|
||||||
|
</SyntaxOptions>
|
||||||
|
</Parsing>
|
||||||
|
<CodeGeneration>
|
||||||
|
<Checks>
|
||||||
|
<IOChecks Value="True"/>
|
||||||
|
<RangeChecks Value="True"/>
|
||||||
|
<OverflowChecks Value="True"/>
|
||||||
|
<StackChecks Value="True"/>
|
||||||
|
</Checks>
|
||||||
|
<VerifyObjMethodCallValidity Value="True"/>
|
||||||
|
</CodeGeneration>
|
||||||
|
<Linking>
|
||||||
|
<Debugging>
|
||||||
|
<DebugInfoType Value="dsDwarf3"/>
|
||||||
|
<UseHeaptrc Value="True"/>
|
||||||
|
<TrashVariables Value="True"/>
|
||||||
|
<UseExternalDbgSyms Value="True"/>
|
||||||
|
</Debugging>
|
||||||
|
<Options>
|
||||||
|
<Win32>
|
||||||
|
<GraphicApplication Value="True"/>
|
||||||
|
</Win32>
|
||||||
|
</Options>
|
||||||
|
</Linking>
|
||||||
|
</CompilerOptions>
|
||||||
|
</Item>
|
||||||
|
<Item Name="Release">
|
||||||
|
<CompilerOptions>
|
||||||
|
<Version Value="11"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<Target>
|
||||||
|
<Filename Value="greatcircle_demo"/>
|
||||||
|
</Target>
|
||||||
|
<SearchPaths>
|
||||||
|
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||||
|
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||||
|
</SearchPaths>
|
||||||
|
<CodeGeneration>
|
||||||
|
<SmartLinkUnit Value="True"/>
|
||||||
|
<Optimizations>
|
||||||
|
<OptimizationLevel Value="3"/>
|
||||||
|
</Optimizations>
|
||||||
|
</CodeGeneration>
|
||||||
|
<Linking>
|
||||||
|
<Debugging>
|
||||||
|
<GenerateDebugInfo Value="False"/>
|
||||||
|
<RunWithoutDebug Value="True"/>
|
||||||
|
</Debugging>
|
||||||
|
<LinkSmart Value="True"/>
|
||||||
|
<Options>
|
||||||
|
<Win32>
|
||||||
|
<GraphicApplication Value="True"/>
|
||||||
|
</Win32>
|
||||||
|
</Options>
|
||||||
|
</Linking>
|
||||||
|
</CompilerOptions>
|
||||||
|
</Item>
|
||||||
|
</BuildModes>
|
||||||
|
<PublishOptions>
|
||||||
|
<Version Value="2"/>
|
||||||
|
<UseFileFilters Value="True"/>
|
||||||
|
</PublishOptions>
|
||||||
|
<RunParams>
|
||||||
|
<FormatVersion Value="2"/>
|
||||||
|
</RunParams>
|
||||||
|
<RequiredPackages>
|
||||||
|
<Item>
|
||||||
|
<PackageName Value="lazMapViewerPkg"/>
|
||||||
|
</Item>
|
||||||
|
<Item>
|
||||||
|
<PackageName Value="LCL"/>
|
||||||
|
</Item>
|
||||||
|
</RequiredPackages>
|
||||||
|
<Units>
|
||||||
|
<Unit>
|
||||||
|
<Filename Value="greatcircle_demo.lpr"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
</Unit>
|
||||||
|
<Unit>
|
||||||
|
<Filename Value="main.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<ComponentName Value="MainForm"/>
|
||||||
|
<HasResources Value="True"/>
|
||||||
|
<ResourceBaseClass Value="Form"/>
|
||||||
|
</Unit>
|
||||||
|
</Units>
|
||||||
|
</ProjectOptions>
|
||||||
|
<CompilerOptions>
|
||||||
|
<Version Value="11"/>
|
||||||
|
<PathDelim Value="\"/>
|
||||||
|
<Target>
|
||||||
|
<Filename Value="greatcircle_demo"/>
|
||||||
|
</Target>
|
||||||
|
<SearchPaths>
|
||||||
|
<IncludeFiles Value="$(ProjOutDir)"/>
|
||||||
|
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||||
|
</SearchPaths>
|
||||||
|
<Linking>
|
||||||
|
<Debugging>
|
||||||
|
<DebugInfoType Value="dsDwarf3"/>
|
||||||
|
</Debugging>
|
||||||
|
<Options>
|
||||||
|
<Win32>
|
||||||
|
<GraphicApplication Value="True"/>
|
||||||
|
</Win32>
|
||||||
|
</Options>
|
||||||
|
</Linking>
|
||||||
|
</CompilerOptions>
|
||||||
|
<Debugging>
|
||||||
|
<Exceptions>
|
||||||
|
<Item>
|
||||||
|
<Name Value="EAbort"/>
|
||||||
|
</Item>
|
||||||
|
<Item>
|
||||||
|
<Name Value="ECodetoolError"/>
|
||||||
|
</Item>
|
||||||
|
<Item>
|
||||||
|
<Name Value="EFOpenError"/>
|
||||||
|
</Item>
|
||||||
|
</Exceptions>
|
||||||
|
</Debugging>
|
||||||
|
</CONFIG>
|
@ -0,0 +1,24 @@
|
|||||||
|
program greatcircle_demo;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
uses
|
||||||
|
{$IFDEF UNIX}
|
||||||
|
cthreads,
|
||||||
|
{$ENDIF}
|
||||||
|
{$IFDEF HASAMIGA}
|
||||||
|
athreads,
|
||||||
|
{$ENDIF}
|
||||||
|
Interfaces, // this includes the LCL widgetset
|
||||||
|
Forms, main;
|
||||||
|
|
||||||
|
{$R *.res}
|
||||||
|
|
||||||
|
begin
|
||||||
|
RequireDerivedFormResource:=True;
|
||||||
|
Application.Scaled:=True;
|
||||||
|
Application.Initialize;
|
||||||
|
Application.CreateForm(TMainForm, MainForm);
|
||||||
|
Application.Run;
|
||||||
|
end.
|
||||||
|
|
@ -0,0 +1,542 @@
|
|||||||
|
object MainForm: TMainForm
|
||||||
|
Left = 324
|
||||||
|
Height = 493
|
||||||
|
Top = 119
|
||||||
|
Width = 872
|
||||||
|
Caption = 'Great Circle Plugin Demo'
|
||||||
|
ClientHeight = 493
|
||||||
|
ClientWidth = 872
|
||||||
|
LCLVersion = '4.99.0.0'
|
||||||
|
OnActivate = FormActivate
|
||||||
|
OnCreate = FormCreate
|
||||||
|
object ParamsPanel: TPanel
|
||||||
|
Left = 8
|
||||||
|
Height = 454
|
||||||
|
Top = 8
|
||||||
|
Width = 200
|
||||||
|
Align = alLeft
|
||||||
|
BorderSpacing.Around = 8
|
||||||
|
BevelOuter = bvNone
|
||||||
|
ClientHeight = 454
|
||||||
|
ClientWidth = 200
|
||||||
|
TabOrder = 0
|
||||||
|
object cbCyclicMap: TCheckBox
|
||||||
|
AnchorSideLeft.Control = ParamsPanel
|
||||||
|
AnchorSideTop.Control = ParamsPanel
|
||||||
|
Left = 0
|
||||||
|
Height = 19
|
||||||
|
Top = 0
|
||||||
|
Width = 77
|
||||||
|
Caption = 'Cyclic Map'
|
||||||
|
Checked = True
|
||||||
|
State = cbChecked
|
||||||
|
TabOrder = 0
|
||||||
|
OnChange = cbCyclicMapChange
|
||||||
|
end
|
||||||
|
object cbZOrder: TComboBox
|
||||||
|
AnchorSideLeft.Control = tbSegmentLength
|
||||||
|
AnchorSideTop.Control = cbCyclicMap
|
||||||
|
AnchorSideTop.Side = asrBottom
|
||||||
|
AnchorSideRight.Control = ParamsPanel
|
||||||
|
AnchorSideRight.Side = asrBottom
|
||||||
|
Left = 92
|
||||||
|
Height = 23
|
||||||
|
Top = 27
|
||||||
|
Width = 108
|
||||||
|
Anchors = [akTop, akLeft, akRight]
|
||||||
|
BorderSpacing.Top = 8
|
||||||
|
ItemHeight = 15
|
||||||
|
ItemIndex = 0
|
||||||
|
Items.Strings = (
|
||||||
|
'Canvas'
|
||||||
|
'In front of markers'
|
||||||
|
'Behind markers'
|
||||||
|
)
|
||||||
|
Style = csDropDownList
|
||||||
|
TabOrder = 1
|
||||||
|
Text = 'Canvas'
|
||||||
|
OnChange = cbZOrderChange
|
||||||
|
end
|
||||||
|
object lblZOrder: TLabel
|
||||||
|
AnchorSideLeft.Control = ParamsPanel
|
||||||
|
AnchorSideTop.Control = cbZOrder
|
||||||
|
AnchorSideTop.Side = asrCenter
|
||||||
|
AnchorSideRight.Control = Label2
|
||||||
|
AnchorSideRight.Side = asrBottom
|
||||||
|
Left = 42
|
||||||
|
Height = 15
|
||||||
|
Top = 31
|
||||||
|
Width = 42
|
||||||
|
Anchors = [akTop, akRight]
|
||||||
|
BorderSpacing.Top = 4
|
||||||
|
Caption = 'Z-Order'
|
||||||
|
end
|
||||||
|
object tbSegmentLength: TTrackBar
|
||||||
|
AnchorSideLeft.Control = Label2
|
||||||
|
AnchorSideLeft.Side = asrBottom
|
||||||
|
AnchorSideTop.Control = cbZOrder
|
||||||
|
AnchorSideTop.Side = asrBottom
|
||||||
|
AnchorSideRight.Control = ParamsPanel
|
||||||
|
AnchorSideRight.Side = asrBottom
|
||||||
|
Left = 92
|
||||||
|
Height = 25
|
||||||
|
Top = 58
|
||||||
|
Width = 108
|
||||||
|
Position = 0
|
||||||
|
OnChange = tbSegmentLengthChange
|
||||||
|
Anchors = [akTop, akLeft, akRight]
|
||||||
|
BorderSpacing.Left = 8
|
||||||
|
BorderSpacing.Top = 8
|
||||||
|
TabOrder = 2
|
||||||
|
end
|
||||||
|
object Label2: TLabel
|
||||||
|
AnchorSideLeft.Control = ParamsPanel
|
||||||
|
AnchorSideTop.Control = tbSegmentLength
|
||||||
|
Left = 0
|
||||||
|
Height = 15
|
||||||
|
Top = 58
|
||||||
|
Width = 84
|
||||||
|
Caption = 'Segment length'
|
||||||
|
end
|
||||||
|
object gbPresets: TGroupBox
|
||||||
|
AnchorSideLeft.Control = ParamsPanel
|
||||||
|
AnchorSideTop.Control = GroupBox3
|
||||||
|
AnchorSideTop.Side = asrBottom
|
||||||
|
AnchorSideRight.Control = ParamsPanel
|
||||||
|
AnchorSideRight.Side = asrBottom
|
||||||
|
Left = 0
|
||||||
|
Height = 161
|
||||||
|
Top = 294
|
||||||
|
Width = 200
|
||||||
|
Anchors = [akTop, akLeft, akRight]
|
||||||
|
AutoSize = True
|
||||||
|
BorderSpacing.Top = 8
|
||||||
|
Caption = 'Presets'
|
||||||
|
ChildSizing.LeftRightSpacing = 16
|
||||||
|
ChildSizing.TopBottomSpacing = 8
|
||||||
|
ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
|
||||||
|
ChildSizing.Layout = cclLeftToRightThenTopToBottom
|
||||||
|
ChildSizing.ControlsPerLine = 1
|
||||||
|
ClientHeight = 141
|
||||||
|
ClientWidth = 196
|
||||||
|
TabOrder = 6
|
||||||
|
object btnPresetPolar: TButton
|
||||||
|
Left = 16
|
||||||
|
Height = 25
|
||||||
|
Top = 8
|
||||||
|
Width = 164
|
||||||
|
Caption = 'Polar'
|
||||||
|
TabOrder = 0
|
||||||
|
OnClick = btnPresetPolarClick
|
||||||
|
end
|
||||||
|
object btnPreseEquator: TButton
|
||||||
|
Left = 16
|
||||||
|
Height = 25
|
||||||
|
Top = 33
|
||||||
|
Width = 164
|
||||||
|
Caption = 'Equator'
|
||||||
|
TabOrder = 1
|
||||||
|
OnClick = btnPreseEquatorClick
|
||||||
|
end
|
||||||
|
object btnPresetPorto: TButton
|
||||||
|
Left = 16
|
||||||
|
Height = 25
|
||||||
|
Top = 58
|
||||||
|
Width = 164
|
||||||
|
Caption = 'Porto-PoS'
|
||||||
|
TabOrder = 2
|
||||||
|
OnClick = btnPresetPortoClick
|
||||||
|
end
|
||||||
|
object btnPresetLongestSeaWay: TButton
|
||||||
|
Left = 16
|
||||||
|
Height = 25
|
||||||
|
Top = 83
|
||||||
|
Width = 164
|
||||||
|
Caption = 'Longest sea way'
|
||||||
|
TabOrder = 3
|
||||||
|
OnClick = btnPresetLongestSeaWayClick
|
||||||
|
end
|
||||||
|
object btnLongestEarthWay: TButton
|
||||||
|
Left = 16
|
||||||
|
Height = 25
|
||||||
|
Top = 108
|
||||||
|
Width = 164
|
||||||
|
Caption = 'Longest earth way'
|
||||||
|
TabOrder = 4
|
||||||
|
OnClick = btnLongestEarthWayClick
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object cgOptions: TCheckGroup
|
||||||
|
AnchorSideLeft.Control = ParamsPanel
|
||||||
|
AnchorSideTop.Control = tbSegmentLength
|
||||||
|
AnchorSideTop.Side = asrBottom
|
||||||
|
AnchorSideRight.Control = ParamsPanel
|
||||||
|
AnchorSideRight.Side = asrBottom
|
||||||
|
Left = 0
|
||||||
|
Height = 89
|
||||||
|
Top = 83
|
||||||
|
Width = 200
|
||||||
|
Anchors = [akTop, akLeft, akRight]
|
||||||
|
AutoFill = True
|
||||||
|
AutoSize = True
|
||||||
|
Caption = 'Options'
|
||||||
|
ChildSizing.LeftRightSpacing = 6
|
||||||
|
ChildSizing.TopBottomSpacing = 6
|
||||||
|
ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
|
||||||
|
ChildSizing.EnlargeVertical = crsHomogenousChildResize
|
||||||
|
ChildSizing.ShrinkHorizontal = crsScaleChilds
|
||||||
|
ChildSizing.ShrinkVertical = crsScaleChilds
|
||||||
|
ChildSizing.Layout = cclLeftToRightThenTopToBottom
|
||||||
|
ChildSizing.ControlsPerLine = 1
|
||||||
|
ClientHeight = 69
|
||||||
|
ClientWidth = 196
|
||||||
|
Items.Strings = (
|
||||||
|
'Mark Start'
|
||||||
|
'Mark Center'
|
||||||
|
'Mark Destination'
|
||||||
|
)
|
||||||
|
TabOrder = 3
|
||||||
|
OnItemClick = cgOptionsItemClick
|
||||||
|
Data = {
|
||||||
|
03000000020202
|
||||||
|
}
|
||||||
|
end
|
||||||
|
object gbOrthodromePen: TGroupBox
|
||||||
|
AnchorSideLeft.Control = ParamsPanel
|
||||||
|
AnchorSideTop.Control = cgOptions
|
||||||
|
AnchorSideTop.Side = asrBottom
|
||||||
|
AnchorSideRight.Control = ParamsPanel
|
||||||
|
AnchorSideRight.Side = asrBottom
|
||||||
|
Left = 0
|
||||||
|
Height = 49
|
||||||
|
Top = 180
|
||||||
|
Width = 200
|
||||||
|
Anchors = [akTop, akLeft, akRight]
|
||||||
|
AutoSize = True
|
||||||
|
BorderSpacing.Top = 8
|
||||||
|
Caption = 'Orthodrome Pen'
|
||||||
|
ClientHeight = 29
|
||||||
|
ClientWidth = 196
|
||||||
|
TabOrder = 4
|
||||||
|
object lblOrthodromePenWidth: TLabel
|
||||||
|
AnchorSideLeft.Control = gbOrthodromePen
|
||||||
|
AnchorSideTop.Control = seOrthodromePenWidth
|
||||||
|
AnchorSideTop.Side = asrCenter
|
||||||
|
Left = 16
|
||||||
|
Height = 15
|
||||||
|
Top = 4
|
||||||
|
Width = 32
|
||||||
|
BorderSpacing.Left = 16
|
||||||
|
Caption = 'Width'
|
||||||
|
end
|
||||||
|
object seOrthodromePenWidth: TSpinEdit
|
||||||
|
AnchorSideLeft.Control = lblOrthodromePenWidth
|
||||||
|
AnchorSideLeft.Side = asrBottom
|
||||||
|
AnchorSideTop.Control = clbOrthodromePenColor
|
||||||
|
AnchorSideTop.Side = asrCenter
|
||||||
|
Left = 56
|
||||||
|
Height = 23
|
||||||
|
Top = 0
|
||||||
|
Width = 64
|
||||||
|
Alignment = taRightJustify
|
||||||
|
BorderSpacing.Left = 8
|
||||||
|
BorderSpacing.Right = 8
|
||||||
|
BorderSpacing.Bottom = 6
|
||||||
|
MaxValue = 10
|
||||||
|
MinValue = 1
|
||||||
|
TabOrder = 0
|
||||||
|
Value = 3
|
||||||
|
OnChange = seOrthodromePenWidthChange
|
||||||
|
end
|
||||||
|
object clbOrthodromePenColor: TColorButton
|
||||||
|
AnchorSideLeft.Control = seOrthodromePenWidth
|
||||||
|
AnchorSideLeft.Side = asrBottom
|
||||||
|
AnchorSideTop.Control = seOrthodromePenWidth
|
||||||
|
AnchorSideRight.Control = gbOrthodromePen
|
||||||
|
AnchorSideRight.Side = asrBottom
|
||||||
|
Left = 128
|
||||||
|
Height = 25
|
||||||
|
Top = -1
|
||||||
|
Width = 60
|
||||||
|
Anchors = [akLeft, akRight]
|
||||||
|
BorderSpacing.Right = 8
|
||||||
|
BorderSpacing.Bottom = 8
|
||||||
|
BorderWidth = 2
|
||||||
|
ButtonColorSize = 16
|
||||||
|
ButtonColor = clPurple
|
||||||
|
OnColorChanged = clbOrthodromePenColorColorChanged
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object GroupBox3: TGroupBox
|
||||||
|
AnchorSideLeft.Control = ParamsPanel
|
||||||
|
AnchorSideTop.Control = gbOrthodromePen
|
||||||
|
AnchorSideTop.Side = asrBottom
|
||||||
|
AnchorSideRight.Control = ParamsPanel
|
||||||
|
AnchorSideRight.Side = asrBottom
|
||||||
|
Left = 0
|
||||||
|
Height = 49
|
||||||
|
Top = 237
|
||||||
|
Width = 200
|
||||||
|
Anchors = [akTop, akLeft, akRight]
|
||||||
|
AutoSize = True
|
||||||
|
BorderSpacing.Top = 8
|
||||||
|
Caption = 'Great Circle Pen'
|
||||||
|
ClientHeight = 29
|
||||||
|
ClientWidth = 196
|
||||||
|
TabOrder = 5
|
||||||
|
object lblGreatCirclePenWidth: TLabel
|
||||||
|
AnchorSideLeft.Control = GroupBox3
|
||||||
|
AnchorSideTop.Control = seGreatCirclePenWidth
|
||||||
|
AnchorSideTop.Side = asrCenter
|
||||||
|
Left = 16
|
||||||
|
Height = 15
|
||||||
|
Top = 4
|
||||||
|
Width = 32
|
||||||
|
BorderSpacing.Left = 16
|
||||||
|
Caption = 'Width'
|
||||||
|
end
|
||||||
|
object seGreatCirclePenWidth: TSpinEdit
|
||||||
|
AnchorSideLeft.Control = lblGreatCirclePenWidth
|
||||||
|
AnchorSideLeft.Side = asrBottom
|
||||||
|
AnchorSideTop.Control = GroupBox3
|
||||||
|
Left = 56
|
||||||
|
Height = 23
|
||||||
|
Top = 0
|
||||||
|
Width = 64
|
||||||
|
Alignment = taRightJustify
|
||||||
|
BorderSpacing.Left = 8
|
||||||
|
BorderSpacing.Right = 8
|
||||||
|
BorderSpacing.Bottom = 6
|
||||||
|
MaxValue = 10
|
||||||
|
MinValue = 1
|
||||||
|
TabOrder = 0
|
||||||
|
Value = 1
|
||||||
|
OnChange = seGreatCirclePenWidthChange
|
||||||
|
end
|
||||||
|
object clbGreatCirclePenColor: TColorButton
|
||||||
|
AnchorSideLeft.Control = seGreatCirclePenWidth
|
||||||
|
AnchorSideLeft.Side = asrBottom
|
||||||
|
AnchorSideRight.Control = GroupBox3
|
||||||
|
AnchorSideRight.Side = asrBottom
|
||||||
|
Left = 128
|
||||||
|
Height = 25
|
||||||
|
Top = 0
|
||||||
|
Width = 60
|
||||||
|
Anchors = [akTop, akLeft, akRight]
|
||||||
|
BorderSpacing.Right = 8
|
||||||
|
BorderWidth = 2
|
||||||
|
ButtonColorSize = 16
|
||||||
|
ButtonColor = clBlack
|
||||||
|
OnColorChanged = clbGreatCirclePenColorColorChanged
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object StatusBar: TStatusBar
|
||||||
|
Left = 0
|
||||||
|
Height = 23
|
||||||
|
Top = 470
|
||||||
|
Width = 872
|
||||||
|
Panels = <
|
||||||
|
item
|
||||||
|
Bevel = pbRaised
|
||||||
|
Text = 'Orthodrome (km)'
|
||||||
|
Width = 100
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Width = 60
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Text = 'Rest (km)'
|
||||||
|
Width = 60
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Width = 60
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Bevel = pbRaised
|
||||||
|
Text = 'Start'
|
||||||
|
Width = 40
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Width = 120
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Bevel = pbRaised
|
||||||
|
Text = 'Destination'
|
||||||
|
Width = 70
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Width = 120
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Text = 'Bearing'
|
||||||
|
Width = 50
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Width = 50
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Bevel = pbRaised
|
||||||
|
Text = 'Pt. Cnt'
|
||||||
|
Width = 50
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Width = 50
|
||||||
|
end
|
||||||
|
item
|
||||||
|
Width = 50
|
||||||
|
end>
|
||||||
|
SimplePanel = False
|
||||||
|
end
|
||||||
|
object MapPanel: TPanel
|
||||||
|
Left = 216
|
||||||
|
Height = 470
|
||||||
|
Top = 0
|
||||||
|
Width = 656
|
||||||
|
Align = alClient
|
||||||
|
BevelOuter = bvNone
|
||||||
|
Caption = 'MapPanel'
|
||||||
|
ClientHeight = 470
|
||||||
|
ClientWidth = 656
|
||||||
|
TabOrder = 2
|
||||||
|
object MapView: TMapView
|
||||||
|
Left = 0
|
||||||
|
Height = 443
|
||||||
|
Top = 27
|
||||||
|
Width = 656
|
||||||
|
Align = alClient
|
||||||
|
Cyclic = True
|
||||||
|
DownloadEngine = MapView.BuiltInDLE
|
||||||
|
DrawingEngine = MapView.BuiltInDE
|
||||||
|
Layers = <>
|
||||||
|
Font.Color = clBlack
|
||||||
|
MapProvider = 'OpenStreetMap Standard'
|
||||||
|
PluginManager = MvPluginManager
|
||||||
|
POIImages = ImageList
|
||||||
|
end
|
||||||
|
object lblInfo: TLabel
|
||||||
|
Left = 6
|
||||||
|
Height = 15
|
||||||
|
Top = 6
|
||||||
|
Width = 644
|
||||||
|
Align = alTop
|
||||||
|
Alignment = taCenter
|
||||||
|
BorderSpacing.Around = 6
|
||||||
|
Caption = 'Drag start or destination points with left mouse button'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object MvPluginManager: TMvPluginManager
|
||||||
|
Left = 320
|
||||||
|
Top = 40
|
||||||
|
object MvPluginManagerDraggableMarkerPlugin1: TDraggableMarkerPlugin
|
||||||
|
DraggableMarkerMovedEvent = MvPluginManagerDraggableMarkerPlugin1DraggableMarkerMovedEvent
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object PolarPopupMenu: TPopupMenu
|
||||||
|
Left = 248
|
||||||
|
Top = 328
|
||||||
|
object MenuItem7: TMenuItem
|
||||||
|
Tag = 1
|
||||||
|
Caption = 'Antipodes E / NZ'
|
||||||
|
OnClick = PoleMenuItemClick
|
||||||
|
end
|
||||||
|
object MenuItem1: TMenuItem
|
||||||
|
Tag = 2
|
||||||
|
Caption = 'Start North, Dest South'
|
||||||
|
OnClick = PoleMenuItemClick
|
||||||
|
end
|
||||||
|
object MenuItem2: TMenuItem
|
||||||
|
Tag = 3
|
||||||
|
Caption = 'Dest North, Start South'
|
||||||
|
OnClick = PoleMenuItemClick
|
||||||
|
end
|
||||||
|
object MenuItem3: TMenuItem
|
||||||
|
Tag = 4
|
||||||
|
Caption = 'Start North, Dest free'
|
||||||
|
OnClick = PoleMenuItemClick
|
||||||
|
end
|
||||||
|
object MenuItem4: TMenuItem
|
||||||
|
Tag = 5
|
||||||
|
Caption = 'Start South, Dest free'
|
||||||
|
OnClick = PoleMenuItemClick
|
||||||
|
end
|
||||||
|
object MenuItem5: TMenuItem
|
||||||
|
Tag = 6
|
||||||
|
Caption = 'Dest North, Start free'
|
||||||
|
OnClick = PoleMenuItemClick
|
||||||
|
end
|
||||||
|
object MenuItem6: TMenuItem
|
||||||
|
Tag = 7
|
||||||
|
Caption = 'Dest South, Start Free'
|
||||||
|
OnClick = PoleMenuItemClick
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object ImageList: TImageList
|
||||||
|
Height = 24
|
||||||
|
Scaled = True
|
||||||
|
Width = 24
|
||||||
|
Left = 432
|
||||||
|
Top = 40
|
||||||
|
Bitmap = {
|
||||||
|
4C7A0200000018000000180000003B0700000000000078DACD566D6C54551A3E
|
||||||
|
2DADA4C114C1C50F3E5AB4884BA5441713547691163F881451A844851A2BD568
|
||||||
|
94862EFC80988E49811A7E18D94D2C89BF201A49955ADDD276415A2A0B65DB5A
|
||||||
|
ECCED0292DED0CC5763A9D99FB7D673A1F9D79F63DF78EAED9CD2D1430D9499E
|
||||||
|
E4E4DEF33EE7BDCFFBCE7B1E000C93606262229D904DF803E18F49F075762291
|
||||||
|
48C735E2AD40B1D3A2D1E83255536D82229CB60BF6E1165F4B98C31EB00F8BAA
|
||||||
|
D8120C052B684F1EDF3B55FE6030582C6BB2BDDE571F29BC5C88BC9E3CE4D873
|
||||||
|
90F3630EF22EE4A1D05E88E323C723B22ADB69EF9629E49DA1EBFA9F3B840E6C
|
||||||
|
746F44BA331DAC87813908FF22FC4068279C6348FF3E1D9B7EDC848EB10EF018
|
||||||
|
1E7B2D4D42E3A1975DB26B74B56B3552FA52C0FA89AB8FD04BB848E84E9E719E
|
||||||
|
708621B52515F9EDF9700BEED15028B47932AD78CD4893536557CB1206F70071
|
||||||
|
B892B89C3CC34EE84A7EC359C2698694EF52B0C3BE23A1A8CA49E2C8B2E2D783
|
||||||
|
7A69DD581DE65D9A67E6CC79AF323C36F618BED0BF801017204C08F85CFC1C2B
|
||||||
|
9C2B0C8D582BE13B8679CDF350375497A05A6CB3E2A73EA9DD3DB41B698E34B0
|
||||||
|
4B1437C8B06078011C3107FEFB670FD931FF87F960DFD3BE530C694D69D8EDD8
|
||||||
|
0D5111BFB2E277492E77517F9159472733B47F5F781F56BF3D57F698F9133F6B
|
||||||
|
6478A9FD25B804D7A0157F8FD8132EE82900BB90D499FAA6516FB4E46F141B0D
|
||||||
|
FDB93E9C7FCDD935E8F1F784ADF87BC55EE5D98BCF827532F30CFA8ECFA4CF2C
|
||||||
|
F98F788F80B5D0BE93840686B5E7D6E252E0926CC53F228D74BFDEFB7AC2E8BD
|
||||||
|
0EB30F370C6EB0E45FEF586F6AF377423D4349674962441CB960C5AF69DABE6A
|
||||||
|
773532CF659ABDC1CFF927C307C31F6028328448226260283C049BDB06D64CEF
|
||||||
|
4F98B9673664A2BAAF1AC45169C51F8944FEE40C383D2B3B579A7DF10FB3C733
|
||||||
|
DA3250E028C0CEC19DD839B01305DD05C868CD30756934735FD9BA124E9FD3C3
|
||||||
|
39ACF8E3F17826CDB343C7AE1E8BA536A79ADA9E4EF6786B72DD9CACE789FF70
|
||||||
|
A77E9B8A5A776D8CC7728EC966442C165B48DF78A2B2B712B79FBADDE439F92B
|
||||||
|
70AD9B4C4DD8DF1866D4CF40A5BD92EB728262B3AF67C6D1BEE557C42B3F955E
|
||||||
|
28C5F4A6E926D7CF386EF2B26F19A67F331D25ED257CF68CF098A9CC6741144A
|
||||||
|
2EFA2E4AF967F20D2E03DF24F135A1966155F32A38C61CB2244BA5539DFFA4E3
|
||||||
|
6DA467D94060405ADCB418EC1833F19589450D8BD0EFEF97694F39DF7B237718
|
||||||
|
C5CDA2B9FE979A811A64D567817DC90CF0F5D181A3D074EDAF342F67DFE81D99
|
||||||
|
3C638E5FF6B71D701CC0CCBA99C8FC3A1355F62AD0B30E7AF7BB9BE1FED5BDF0
|
||||||
|
7B9A8BE76DDDB6784577459CEEDE767A967B2BB893F75A2ACDF5755EC9EBE2E0
|
||||||
|
6BFEEC56F127CFB88D788B38F8FA56F1FEE6FE47D56C92A49E1E18D086BBBAB4
|
||||||
|
7067A716EEEF578725496B09064337E57F1445B3B7B7EB91FDFB83D8BE3D8837
|
||||||
|
DED0B1658B86E262153B76C868695122B2ACDD90FFE9EBD370F060082525116C
|
||||||
|
DD1AC12BAF8C63D3A6109E7B4E47418186C71F57B07CB984B23209DDDDCAF5FB
|
||||||
|
9FD0F8CB1E8F365A55358E37DF8CE2EDB7A378EBADA871CEABAF86F1E28B21AC
|
||||||
|
5DAB63D52A95F8652C5D2AD2D9228686D4EBF23FA4C9A9C3874389D2D228DE7B
|
||||||
|
2F86F2F23869318177DE8919676CDE3C8EC2C220D6ACD1B0628582BC3C098B16
|
||||||
|
09B0D9C404C54EEE7FF460695B9B8E77DF0D1B3973DE3D7B12A8AE06BABA1208
|
||||||
|
06417318686D9D205D4278E209050F3F2C61F16281BE258086067952FF238A6A
|
||||||
|
ED9123BC86E3D8B62D4A358D61FFFE38BCDEFFBD7B5DAE385E784133F81F7C50
|
||||||
|
4076B61F7BF78A1045CDD2FF0C0F6BEE0F3FD4515414C26BAF458C6FA8AF8F5B
|
||||||
|
DEEF870E8DFF92FFDCB97ED22F00B75BB1F43F83835A78D72E1DEBD7070D9DB7
|
||||||
|
6E0DC36E4F58F29F3D1BFB45FF7BEFF563C3063F9C4EC5D2FFB85C9AB26B9786
|
||||||
|
679ED1F1FCF341A31FCF9CB1CEBFBE3E82DC5C11F7DD17C05D77F9B071A31F7D
|
||||||
|
7DAAA5FFF17AB5EEBD7BD504EFBDA79FD68D5EDFB72F6CC9BF7DBB6E68B36041
|
||||||
|
0077DE39463D26243C1E7552FF5353A360F56AD9E80D7E4E7EBE86C3872354E3
|
||||||
|
046231201A053C9E043EF9649CEA2A62E1C200EEB9C787F9F3C7F0E9A7E235FD
|
||||||
|
CFE5CBAAA7B858C6238FC878F451997A5CC6934F2AD4B33A3EFE781C1F7D14A2
|
||||||
|
DEE27D63EA3277AECFC8FDA9A77CE8ED55AEED7F54FD505393125BB244C0430F
|
||||||
|
8946FD962D33B174A984254B443CF08060E4FD33F7CC995ED4D549311E7BBDFE
|
||||||
|
E7E041896A173072CCC909E0FEFBCD755656C0E8C5BBEFF661D6AC31AAAB97FE
|
||||||
|
23C294FD0FCD939FCACB45E2F353EFF90C8D39E79C393ECC9E3D86CC4C2FEEB8
|
||||||
|
C38BD252DEF3EAD4FD8F2096389DAAB46E9D9FBE9FF3999C3366789191318AF4
|
||||||
|
F451AACB181C0E459624F9C6FC8FAA970D0E2A526EAE1769691E4C9BE6414A8A
|
||||||
|
078C8DD07F6A14FDFD8A4C7B6EDEFFD4709D460D5E0EBE3E7A94F7A27E6BFC8F
|
||||||
|
5F6D3B7040209D3CA49107555502E8D9ADF53FA27ADE660BC42B2A8438CDC8DF
|
||||||
|
C6FF78551707DDEBFF37FEE7DF82F5EDA1
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,300 @@
|
|||||||
|
unit main;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls,
|
||||||
|
ComCtrls, Menus, Spin,
|
||||||
|
mvMapViewer, mvTypes, mvGPSObj, mvPluginCommon,
|
||||||
|
mvGeoMath, mvPlugins, mvGreatCirclePainterPlugin;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
{ TMainForm }
|
||||||
|
|
||||||
|
TMainForm = class(TForm)
|
||||||
|
btnPresetPolar: TButton;
|
||||||
|
btnPreseEquator: TButton;
|
||||||
|
btnPresetPorto: TButton;
|
||||||
|
btnPresetLongestSeaWay: TButton;
|
||||||
|
btnLongestEarthWay: TButton;
|
||||||
|
cbCyclicMap: TCheckBox;
|
||||||
|
cgOptions: TCheckGroup;
|
||||||
|
clbOrthodromePenColor: TColorButton;
|
||||||
|
clbGreatCirclePenColor: TColorButton;
|
||||||
|
cbZOrder: TComboBox;
|
||||||
|
gbPresets: TGroupBox;
|
||||||
|
gbOrthodromePen: TGroupBox;
|
||||||
|
GroupBox3: TGroupBox;
|
||||||
|
ImageList: TImageList;
|
||||||
|
lblInfo: TLabel;
|
||||||
|
lblZOrder: TLabel;
|
||||||
|
Label2: TLabel;
|
||||||
|
lblOrthodromePenWidth: TLabel;
|
||||||
|
lblGreatCirclePenWidth: TLabel;
|
||||||
|
MapView: TMapView;
|
||||||
|
MenuItem1: TMenuItem;
|
||||||
|
MenuItem2: TMenuItem;
|
||||||
|
MenuItem3: TMenuItem;
|
||||||
|
MenuItem4: TMenuItem;
|
||||||
|
MenuItem5: TMenuItem;
|
||||||
|
MenuItem6: TMenuItem;
|
||||||
|
MenuItem7: TMenuItem;
|
||||||
|
MvPluginManager: TMvPluginManager;
|
||||||
|
MvPluginManagerDraggableMarkerPlugin1: TDraggableMarkerPlugin;
|
||||||
|
ParamsPanel: TPanel;
|
||||||
|
MapPanel: TPanel;
|
||||||
|
PolarPopupMenu: TPopupMenu;
|
||||||
|
seOrthodromePenWidth: TSpinEdit;
|
||||||
|
seGreatCirclePenWidth: TSpinEdit;
|
||||||
|
StatusBar: TStatusBar;
|
||||||
|
tbSegmentLength: TTrackBar;
|
||||||
|
procedure btnPresetPolarClick(Sender: TObject);
|
||||||
|
procedure btnPreseEquatorClick(Sender: TObject);
|
||||||
|
procedure btnPresetPortoClick(Sender: TObject);
|
||||||
|
procedure btnPresetLongestSeaWayClick(Sender: TObject);
|
||||||
|
procedure btnLongestEarthWayClick(Sender: TObject);
|
||||||
|
procedure cbCyclicMapChange(Sender: TObject);
|
||||||
|
procedure cgOptionsItemClick(Sender: TObject; Index: integer);
|
||||||
|
procedure clbOrthodromePenColorColorChanged(Sender: TObject);
|
||||||
|
procedure clbGreatCirclePenColorColorChanged(Sender: TObject);
|
||||||
|
procedure cbZOrderChange(Sender: TObject);
|
||||||
|
procedure FormActivate(Sender: TObject);
|
||||||
|
procedure FormCreate(Sender: TObject);
|
||||||
|
procedure PoleMenuItemClick(Sender: TObject);
|
||||||
|
procedure MvPluginManagerDraggableMarkerPlugin1DraggableMarkerMovedEvent(
|
||||||
|
Sender: TDraggableMarkerPlugin; AMarker: TGPSPoint;
|
||||||
|
AOrgPosition: TRealPoint);
|
||||||
|
procedure seOrthodromePenWidthChange(Sender: TObject);
|
||||||
|
procedure seGreatCirclePenWidthChange(Sender: TObject);
|
||||||
|
procedure tbSegmentLengthChange(Sender: TObject);
|
||||||
|
private
|
||||||
|
FActivated: Boolean;
|
||||||
|
FGreatCirclePainterPlugin : TGreatCirclePainterPlugin;
|
||||||
|
FStartMarker : TGpsPointOfInterest;
|
||||||
|
FDestinationMarker : TGpsPointOfInterest;
|
||||||
|
procedure OnGreatCirclePainterGetCoords(Sender : TGreatCirclePainterPlugin;
|
||||||
|
var FStart, FDestination : TRealPoint);
|
||||||
|
procedure SetMarkerPositions(const AStartLat, AStartLon, ADestLat, ADestLon : Double);
|
||||||
|
procedure OnGreatCirclePainterPluginChange(Sender : TObject);
|
||||||
|
public
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
MainForm: TMainForm;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
{$R *.lfm}
|
||||||
|
|
||||||
|
{ TMainForm }
|
||||||
|
procedure TMainForm.FormCreate(Sender: TObject);
|
||||||
|
|
||||||
|
function AddTraditionalMarker(const ALat, ALon: Double;
|
||||||
|
ACaption: String; const AImgIndex : Integer = -1) : TGpsPointOfInterest;
|
||||||
|
var
|
||||||
|
gpsPt: TGpsPointOfInterest;
|
||||||
|
begin
|
||||||
|
Result := Nil;
|
||||||
|
gpsPt := TGpsPointOfInterest.Create(ALon,ALat);
|
||||||
|
try
|
||||||
|
gpsPt.Name := ACaption;
|
||||||
|
gpsPt.ImageIndex := AImgIndex;
|
||||||
|
MapView.GPSItems.Add(gpsPt, 100);
|
||||||
|
Result := gpsPt;
|
||||||
|
gpsPt := Nil;
|
||||||
|
finally
|
||||||
|
if Assigned(gpsPt) then
|
||||||
|
gpsPt.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
MapView.Active := true;
|
||||||
|
|
||||||
|
FGreatCirclePainterPlugin := TGreatCirclePainterPlugin.Create(MvPluginManager);
|
||||||
|
MvPluginManager.PluginList.Add(FGreatCirclePainterPlugin);
|
||||||
|
FGreatCirclePainterPlugin.ZOrder := gcpzCanvas;
|
||||||
|
FGreatCirclePainterPlugin.OnGetStartAndDestinationCoords:=@OnGreatCirclePainterGetCoords;
|
||||||
|
FGreatCirclePainterPlugin.OnChange := @OnGreatCirclePainterPluginChange;
|
||||||
|
FGreatCirclePainterPlugin.MapView := MapView;
|
||||||
|
FGreatCirclePainterPlugin.GreatCirclePen.Color:= clbGreatCirclePenColor.ButtonColor;
|
||||||
|
FGreatCirclePainterPlugin.GreatCirclePen.Style:= psSolid;
|
||||||
|
FGreatCirclePainterPlugin.GreatCirclePen.Width:= seGreatCirclePenWidth.Value;
|
||||||
|
FGreatCirclePainterPlugin.OrthodromePen.Color:= clbOrthodromePenColor.ButtonColor;
|
||||||
|
FGreatCirclePainterPlugin.OrthodromePen.Style:= psSolid;
|
||||||
|
FGreatCirclePainterPlugin.OrthodromePen.Width:= seOrthodromePenWidth.Value;
|
||||||
|
FStartMarker := AddTraditionalMarker(41.1578,-8.6333, 'Start',0);
|
||||||
|
FDestinationMarker := AddTraditionalMarker(10.6722,-61.5333, 'Destination',1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainForm.SetMarkerPositions(const AStartLat, AStartLon, ADestLat, ADestLon : Double);
|
||||||
|
begin
|
||||||
|
FStartMarker.MoveTo(AStartLon, AStartLat);
|
||||||
|
FDestinationMarker.MoveTo(ADestLon, ADestLat);
|
||||||
|
MapView.Invalidate;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainForm.OnGreatCirclePainterPluginChange(Sender: TObject);
|
||||||
|
var
|
||||||
|
s : String;
|
||||||
|
begin
|
||||||
|
s := Format('%1.3f',[FGreatCirclePainterPlugin.OrthodromeDistance / 1000.0]);
|
||||||
|
StatusBar.Panels[1].Text := s;
|
||||||
|
s := Format('%1.3f',[(EARTH_CIRCUMFERENCE-FGreatCirclePainterPlugin.OrthodromeDistance) / 1000.0]);
|
||||||
|
StatusBar.Panels[3].Text := s;
|
||||||
|
s := Format('%1.6f:%1.6f',[FGreatCirclePainterPlugin.StartLat,FGreatCirclePainterPlugin.StartLon]);
|
||||||
|
StatusBar.Panels[5].Text := s;
|
||||||
|
s := Format('%1.6f:%1.6f',[FGreatCirclePainterPlugin.DestinationLat,FGreatCirclePainterPlugin.DestinationLon]);
|
||||||
|
StatusBar.Panels[7].Text := s;
|
||||||
|
s := Format('%1.2f°',[FGreatCirclePainterPlugin.InitialBearing]);
|
||||||
|
StatusBar.Panels[9].Text := s;
|
||||||
|
StatusBar.Panels[11].Text := IntToStr(FGreatCirclePainterPlugin.GreatCirclePointsCount);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TMainForm.PoleMenuItemClick(Sender: TObject);
|
||||||
|
|
||||||
|
begin
|
||||||
|
if Sender is TMenuItem then
|
||||||
|
begin
|
||||||
|
case TMenuItem(Sender).Tag of
|
||||||
|
1 : SetMarkerPositions(42.496909,-7.026229,-42.496909,172.973771); // Antipodes Spain / New Zealand
|
||||||
|
2 : SetMarkerPositions(90.0,20.0,-90.0,-90.0); // Both Poles, Start North
|
||||||
|
3 : SetMarkerPositions(-90.0,40.0,90.0,-100.0); // Both Poles, Start South
|
||||||
|
4 : SetMarkerPositions(90.0,60.0,48.8582300,2.2945500); // Start North, Dest free
|
||||||
|
5 : SetMarkerPositions(-90.0,80.0,22.2708100,114.1497900); // Start South, Dest free
|
||||||
|
6 : SetMarkerPositions(-33.8707000,151.2082800,90.0,-110.0); // Dest North, Start free
|
||||||
|
7 : SetMarkerPositions(43.6439500,-79.3884000,-90.0,-120.0); // Dest South, Start free
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainForm.cbCyclicMapChange(Sender: TObject);
|
||||||
|
begin
|
||||||
|
MapView.Cyclic := cbCyclicMap.Checked;
|
||||||
|
MapView.Invalidate;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainForm.cgOptionsItemClick(Sender: TObject; Index: integer);
|
||||||
|
var
|
||||||
|
opt : TGreatCirclePainterOptions = [];
|
||||||
|
begin
|
||||||
|
if cgOptions.Checked[0] then
|
||||||
|
Include(opt,gcpoMarkStart);
|
||||||
|
if cgOptions.Checked[1] then
|
||||||
|
Include(opt,gcpoMarkCenter);
|
||||||
|
if cgOptions.Checked[2] then
|
||||||
|
Include(opt,gcpoMarkDestination);
|
||||||
|
FGreatCirclePainterPlugin.Options := opt;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainForm.clbOrthodromePenColorColorChanged(Sender: TObject);
|
||||||
|
begin
|
||||||
|
FGreatCirclePainterPlugin.OrthodromePen.Color := clbOrthodromePenColor.ButtonColor;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainForm.clbGreatCirclePenColorColorChanged(Sender: TObject);
|
||||||
|
begin
|
||||||
|
FGreatCirclePainterPlugin.GreatCirclePen.Color := clbGreatCirclePenColor.ButtonColor;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainForm.btnPresetPolarClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
PolarPopupMenu.PopUp;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainForm.btnPreseEquatorClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
FStartMarker.MoveTo(0.0,0.0);
|
||||||
|
FDestinationMarker.MoveTo(100.0,0.0);
|
||||||
|
MapView.Invalidate;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainForm.btnPresetPortoClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
FStartMarker.MoveTo(-8.6333,41.1578);
|
||||||
|
FDestinationMarker.MoveTo(-61.5333,10.6722);
|
||||||
|
MapView.Invalidate;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainForm.btnPresetLongestSeaWayClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
FStartMarker.MoveTo(DMSToDeg(66,40,0),DMSToDeg(25,17,0));
|
||||||
|
FDestinationMarker.MoveTo(DMSToDeg(162,14,0),DMSToDeg(58,37,0));
|
||||||
|
MapView.Invalidate;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainForm.btnLongestEarthWayClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
// 24◦33′ N, 118◦38′ E
|
||||||
|
// 37◦2′ N, 8◦55′ W
|
||||||
|
FStartMarker.MoveTo(DMSToDeg(118,38,0),DMSToDeg(23,33,0));
|
||||||
|
FDestinationMarker.MoveTo(-DMSToDeg(8,55,0),DMSToDeg(37,2,0));
|
||||||
|
MapView.Invalidate;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainForm.cbZOrderChange(Sender: TObject);
|
||||||
|
begin
|
||||||
|
case cbZOrder.ItemIndex of
|
||||||
|
0 : FGreatCirclePainterPlugin.ZOrder := gcpzCanvas;
|
||||||
|
1 : FGreatCirclePainterPlugin.ZOrder := gcpzInFrontOfMarkers;
|
||||||
|
2 : FGreatCirclePainterPlugin.ZOrder := gcpzBehindMarkers;
|
||||||
|
end;
|
||||||
|
MapView.Invalidate;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainForm.FormActivate(Sender: TObject);
|
||||||
|
begin
|
||||||
|
if not FActivated then
|
||||||
|
begin
|
||||||
|
Constraints.MinHeight := gbPresets.Top + gbPresets.Height +
|
||||||
|
ParamsPanel.BorderSpacing.Around * 2 + Statusbar.Height;
|
||||||
|
Constraints.MinWidth := ParamsPanel.Width + ParamsPanel.BorderSpacing.Around * 2;
|
||||||
|
if Height < Constraints.MinHeight then
|
||||||
|
Height := 0;
|
||||||
|
FActivated := true;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainForm.MvPluginManagerDraggableMarkerPlugin1DraggableMarkerMovedEvent
|
||||||
|
(Sender: TDraggableMarkerPlugin; AMarker: TGPSPoint; AOrgPosition: TRealPoint
|
||||||
|
);
|
||||||
|
begin
|
||||||
|
FGreatCirclePainterPlugin.SetStartAndDestination(
|
||||||
|
FStartMarker.RealPoint, FDestinationMarker.RealPoint
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainForm.seOrthodromePenWidthChange(Sender: TObject);
|
||||||
|
begin
|
||||||
|
FGreatCirclePainterPlugin.OrthodromePen.Width := seOrthodromePenWidth.Value;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainForm.seGreatCirclePenWidthChange(Sender: TObject);
|
||||||
|
begin
|
||||||
|
FGreatCirclePainterPlugin.GreatCirclePen.Width := seGreatCirclePenWidth.Value;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainForm.tbSegmentLengthChange(Sender: TObject);
|
||||||
|
const
|
||||||
|
SegmentLengths : array[0..10] of Integer = (
|
||||||
|
1,2,5,10,20,30,50,70,100,150,200
|
||||||
|
);
|
||||||
|
begin
|
||||||
|
FGreatCirclePainterPlugin.SegmentLength := SegmentLengths[tbSegmentLength.Position];
|
||||||
|
MapView.Invalidate;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TMainForm.OnGreatCirclePainterGetCoords(
|
||||||
|
Sender: TGreatCirclePainterPlugin; var FStart, FDestination: TRealPoint);
|
||||||
|
begin
|
||||||
|
FStart := FStartMarker.RealPoint;
|
||||||
|
FDestination := FDestinationMarker.RealPoint;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
@ -8,7 +8,7 @@
|
|||||||
<Version Value="11"/>
|
<Version Value="11"/>
|
||||||
<SearchPaths>
|
<SearchPaths>
|
||||||
<IncludeFiles Value="source"/>
|
<IncludeFiles Value="source"/>
|
||||||
<OtherUnitFiles Value="source;source/addons/plugins;source/addons/plugins/spreadmarkers;source/addons/plugins/grids;source/addons/plugins/scale"/>
|
<OtherUnitFiles Value="source;source/addons/plugins;source/addons/plugins/spreadmarkers;source/addons/plugins/grids;source/addons/plugins/scale;source/addons/plugins/greatcircle"/>
|
||||||
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
|
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
|
||||||
</SearchPaths>
|
</SearchPaths>
|
||||||
<Other>
|
<Other>
|
||||||
@ -23,7 +23,7 @@
|
|||||||
FPC 3.2.0 or newer required."/>
|
FPC 3.2.0 or newer required."/>
|
||||||
<License Value="Modified LGPL with linking exception, like FreePascal RTL/FCL and Lazarus LCL"/>
|
<License Value="Modified LGPL with linking exception, like FreePascal RTL/FCL and Lazarus LCL"/>
|
||||||
<Version Minor="2" Release="7"/>
|
<Version Minor="2" Release="7"/>
|
||||||
<Files Count="33">
|
<Files Count="34">
|
||||||
<Item1>
|
<Item1>
|
||||||
<Filename Value="source/mvcache.pas"/>
|
<Filename Value="source/mvcache.pas"/>
|
||||||
<UnitName Value="mvCache"/>
|
<UnitName Value="mvCache"/>
|
||||||
@ -157,6 +157,10 @@ FPC 3.2.0 or newer required."/>
|
|||||||
<Filename Value="source/mvengine_mapreg.inc"/>
|
<Filename Value="source/mvengine_mapreg.inc"/>
|
||||||
<Type Value="Include"/>
|
<Type Value="Include"/>
|
||||||
</Item33>
|
</Item33>
|
||||||
|
<Item34>
|
||||||
|
<Filename Value="source/addons/plugins/greatcircle/mvgreatcirclepainterplugin.pas"/>
|
||||||
|
<UnitName Value="mvGreatCirclePainterPlugin"/>
|
||||||
|
</Item34>
|
||||||
</Files>
|
</Files>
|
||||||
<CompatibilityMode Value="True"/>
|
<CompatibilityMode Value="True"/>
|
||||||
<RequiredPkgs Count="2">
|
<RequiredPkgs Count="2">
|
||||||
|
@ -15,7 +15,7 @@ uses
|
|||||||
mvMapViewerPathEditForm, mvMapViewerPathEditDsgForm, mvDLECache,
|
mvMapViewerPathEditForm, mvMapViewerPathEditDsgForm, mvDLECache,
|
||||||
mvPluginEditors, mvClassRegistration, mvPluginCommon, mvPlugins,
|
mvPluginEditors, mvClassRegistration, mvPluginCommon, mvPlugins,
|
||||||
mvspreadmarker_plugin, uInactivityAlarmTimer, mvMapGridPlugin,
|
mvspreadmarker_plugin, uInactivityAlarmTimer, mvMapGridPlugin,
|
||||||
mvMapScalePlugin, LazarusPackageIntf;
|
mvMapScalePlugin, mvGreatCirclePainterPlugin, LazarusPackageIntf;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -69,6 +69,19 @@ begin
|
|||||||
Result := round(IntPower(2, AZoomLevel));
|
Result := round(IntPower(2, AZoomLevel));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ Protected version of arcin which does not crash when the argument is outside
|
||||||
|
domain due to round-off error. }
|
||||||
|
function SafeArcsin(x: Double): Double;
|
||||||
|
begin
|
||||||
|
if x >= +1.0 then
|
||||||
|
Result := pi * 0.5
|
||||||
|
else
|
||||||
|
if x <= -1.0 then
|
||||||
|
Result := -pi * 0.5
|
||||||
|
else
|
||||||
|
Result := arcsin(x);
|
||||||
|
end;
|
||||||
|
|
||||||
{ Calculation of distance on a sphere
|
{ Calculation of distance on a sphere
|
||||||
https://stackoverflow.com/questions/73608975/pascal-delphi-11-formula-for-distance-in-meters-between-two-decimal-gps-point
|
https://stackoverflow.com/questions/73608975/pascal-delphi-11-formula-for-distance-in-meters-between-two-decimal-gps-point
|
||||||
}
|
}
|
||||||
@ -76,24 +89,24 @@ end;
|
|||||||
function HaversineAngle(Lat1, Lon1, Lat2, Lon2: Double): Double;
|
function HaversineAngle(Lat1, Lon1, Lat2, Lon2: Double): Double;
|
||||||
var
|
var
|
||||||
latFrom, latTo, lonDiff: Double;
|
latFrom, latTo, lonDiff: Double;
|
||||||
dx, dy, dz, arg: Double;
|
sinLatFrom, cosLatFrom: Double;
|
||||||
|
sinLatTo, cosLatTo: Double;
|
||||||
|
sinLonDiff, cosLonDiff: Double;
|
||||||
|
dx, dy, dz: Double;
|
||||||
begin
|
begin
|
||||||
lonDiff := Lon1 - Lon2;
|
lonDiff := Lon1 - Lon2;
|
||||||
latFrom := Lat1;
|
latFrom := Lat1;
|
||||||
latTo := Lat2;
|
latTo := Lat2;
|
||||||
|
|
||||||
dz := sin(latFrom) - sin(latTo);
|
SinCos(latFrom, sinLatFrom, cosLatFrom);
|
||||||
dx := cos(lonDiff) * cos(latFrom) - cos(latTo);
|
SinCos(latTo, sinLatTo, cosLatTo);
|
||||||
dy := sin(lonDiff) * cos(latFrom);
|
SinCos(lonDiff, sinLonDiff, cosLonDiff);
|
||||||
|
|
||||||
arg := sqrt(sqr(dx) + sqr(dy) + sqr(dz)) / 2.0;
|
dz := sinlatFrom - sinlatTo;
|
||||||
if arg >= 1.0 then
|
dx := coslonDiff * coslatFrom - coslatTo;
|
||||||
Result := pi
|
dy := sinlonDiff * coslatFrom;
|
||||||
else
|
|
||||||
if arg <= -1.0 then
|
Result := SafeArcsin(sqrt(sqr(dx) + sqr(dy) + sqr(dz)) / 2.0) * 2.0;
|
||||||
Result := -pi
|
|
||||||
else
|
|
||||||
Result := arcsin(arg) * 2.0;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Angles in degrees
|
// Angles in degrees
|
||||||
@ -167,12 +180,20 @@ end;
|
|||||||
function CalcBearing(Lat1, Lon1, Lat2, Lon2: Double): Double;
|
function CalcBearing(Lat1, Lon1, Lat2, Lon2: Double): Double;
|
||||||
var
|
var
|
||||||
latFrom, latTo, lonDiff: Double;
|
latFrom, latTo, lonDiff: Double;
|
||||||
|
sin_LatFrom, cos_LatFrom: Double;
|
||||||
|
sin_LatTo, cos_LatTo: Double;
|
||||||
|
sin_LonDiff, cos_LonDiff: Double;
|
||||||
begin
|
begin
|
||||||
lonDiff := DegToRad(Lon2 - Lon1);
|
lonDiff := DegToRad(Lon2 - Lon1);
|
||||||
latFrom := DegToRad(Lat1);
|
latFrom := DegToRad(Lat1);
|
||||||
latTo := DegToRad(Lat2);
|
latTo := DegToRad(Lat2);
|
||||||
Result := ArcTan2(Sin(lonDiff) * Cos(latTo),
|
|
||||||
Cos(latFrom) * Sin(latTo) - Sin(latFrom) * Cos(latTo) * Cos(lonDiff));
|
SinCos(lonDiff, sin_LonDiff, cos_LonDiff);
|
||||||
|
SinCos(latFrom, sin_LatFrom, cos_LatFrom);
|
||||||
|
SinCos(latTo, sin_LatTo, cos_LatTo);
|
||||||
|
|
||||||
|
Result := ArcTan2(sin_LonDiff * cos_LatTo,
|
||||||
|
cos_LatFrom * sin_LatTo - sin_LatFrom * cos_LatTo * cos_LonDiff);
|
||||||
Result := RadToDeg(Result);
|
Result := RadToDeg(Result);
|
||||||
if Result < 0.0 then
|
if Result < 0.0 then
|
||||||
Result := Result + 360.0;
|
Result := Result + 360.0;
|
||||||
@ -186,16 +207,25 @@ procedure CalcLatLon(const Lat1, Lon1, ADist, ABearing: Double; out Lat2,
|
|||||||
Lon2: Double);
|
Lon2: Double);
|
||||||
var
|
var
|
||||||
latFrom, lonFrom, brng, aD: Double;
|
latFrom, lonFrom, brng, aD: Double;
|
||||||
|
sin_LatFrom, cos_LatFrom: Double;
|
||||||
|
sin_LonFrom, cos_LonFrom: Double;
|
||||||
|
sin_brng, cos_brng: Double;
|
||||||
|
sin_aD, cos_aD: Double;
|
||||||
begin
|
begin
|
||||||
latFrom := DegToRad(Lat1);
|
latFrom := DegToRad(Lat1);
|
||||||
lonFrom := DegToRad(Lon1);
|
lonFrom := DegToRad(Lon1);
|
||||||
brng := DegToRad(ABearing);
|
brng := DegToRad(ABearing);
|
||||||
aD := ADist / EARTH_EQUATORIAL_RADIUS;
|
aD := ADist / EARTH_EQUATORIAL_RADIUS;
|
||||||
Lat2 := ArcSin(Sin(latFrom) * Cos(aD) + Cos(latFrom) * Sin(aD) * Cos(brng));
|
|
||||||
Lon2 := lonFrom + ArcTan2(Sin(brng) * Sin(aD) * Cos(latFrom),
|
SinCos(latFrom, sin_LatFrom, cos_LatFrom);
|
||||||
Cos(aD) - Sin(latFrom) * Sin(Lat2));
|
SinCos(lonFrom, sin_lonFrom, cos_lonFrom);
|
||||||
|
SinCos(brng, sin_brng, cos_brng);
|
||||||
|
SinCos(aD, sin_aD, cos_aD);
|
||||||
|
|
||||||
|
Lat2 := SafeArcSin(sin_LatFrom * cos_aD + cos_LatFrom * sin_aD * cos_brng);
|
||||||
|
Lon2 := lonFrom + ArcTan2(sin_brng * sin_aD * cos_latFrom, cos_aD - sin_latFrom * Sin(Lat2));
|
||||||
Lat2 := RadToDeg(Lat2);
|
Lat2 := RadToDeg(Lat2);
|
||||||
Lon2 := NormalizeLon(RadToDeg(Lon2));
|
Lon2 := {%H-}NormalizeLon(RadToDeg(Lon2));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Calculate midpoint Lat,Lon by given start point Lat1,Lon1 and end point
|
{ Calculate midpoint Lat,Lon by given start point Lat1,Lon1 and end point
|
||||||
@ -205,6 +235,7 @@ procedure CalcMidpoint(const Lat1, Lon1, Lat2, Lon2: Double; out Lat,
|
|||||||
Lon: Double);
|
Lon: Double);
|
||||||
var
|
var
|
||||||
latFrom, lonDiff, latTo, lonTo, Bx, By: Double;
|
latFrom, lonDiff, latTo, lonTo, Bx, By: Double;
|
||||||
|
sin_latFrom, cos_latFrom: Double;
|
||||||
begin
|
begin
|
||||||
lonDiff := DegToRad(Lon2 - Lon1);
|
lonDiff := DegToRad(Lon2 - Lon1);
|
||||||
latFrom := DegToRad(Lat1);
|
latFrom := DegToRad(Lat1);
|
||||||
@ -212,10 +243,13 @@ begin
|
|||||||
lonTo := DegToRad(Lon2);
|
lonTo := DegToRad(Lon2);
|
||||||
Bx := Cos(latTo) * Cos(lonDiff);
|
Bx := Cos(latTo) * Cos(lonDiff);
|
||||||
By := Cos(latTo) * Sin(lonDiff);
|
By := Cos(latTo) * Sin(lonDiff);
|
||||||
Lat := ArcTan2(Sin(latFrom) + Sin(latTo), Sqrt(Sqr(Cos(latFrom) + Bx) + Sqr(By)));
|
|
||||||
Lon := lonTo + ArcTan2(By, Cos(latFrom) + By);
|
SinCos(latFrom, sin_latFrom, cos_latFrom);
|
||||||
|
|
||||||
|
Lat := ArcTan2(sin_latFrom + Sin(latTo), Sqrt(Sqr(cos_latFrom + Bx) + Sqr(By)));
|
||||||
|
Lon := lonTo + ArcTan2(By, cos_latFrom + By);
|
||||||
Lat := RadToDeg(Lat);
|
Lat := RadToDeg(Lat);
|
||||||
Lon := NormalizeLon(RadToDeg(Lon));
|
Lon := {%H-}NormalizeLon(RadToDeg(Lon));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Calculate intermediate point Lat,Lon by given start point Lat1,Lon1, end point
|
{ Calculate intermediate point Lat,Lon by given start point Lat1,Lon1, end point
|
||||||
@ -227,6 +261,9 @@ procedure CalcIntermedPoint(const Lat1, Lon1, Lat2, Lon2, AFrac: Double; out
|
|||||||
var
|
var
|
||||||
latFrom, lonFrom, latTo, lonTo: Double;
|
latFrom, lonFrom, latTo, lonTo: Double;
|
||||||
A, B, aD, X, Y, Z: Double;
|
A, B, aD, X, Y, Z: Double;
|
||||||
|
sin_latFrom, cos_latFrom: Double;
|
||||||
|
sin_lonFrom, cos_lonFrom: Double;
|
||||||
|
sin_latTo, cos_latTo: Double;
|
||||||
begin
|
begin
|
||||||
if (Lat1 = Lat2) and (Lon1 = Lon2) or (AFrac < 0.001) then
|
if (Lat1 = Lat2) and (Lon1 = Lon2) or (AFrac < 0.001) then
|
||||||
begin
|
begin
|
||||||
@ -245,15 +282,20 @@ begin
|
|||||||
lonFrom := DegToRad(Lon1);
|
lonFrom := DegToRad(Lon1);
|
||||||
latTo := DegToRad(Lat2);
|
latTo := DegToRad(Lat2);
|
||||||
lonTo := DegToRad(Lon2);
|
lonTo := DegToRad(Lon2);
|
||||||
|
|
||||||
|
SinCos(latFrom, sin_LatFrom, cos_LatFrom);
|
||||||
|
SinCos(lonFrom, sin_LonFrom, cos_lonFrom);
|
||||||
|
SinCos(latTo, sin_latTo, cos_latTo);
|
||||||
|
|
||||||
A := Sin((1.0 - AFrac) * aD) / Sin(aD);
|
A := Sin((1.0 - AFrac) * aD) / Sin(aD);
|
||||||
B := Sin(AFrac * aD) / Sin(aD);
|
B := Sin(AFrac * aD) / Sin(aD);
|
||||||
X := A * Cos(latFrom) * Cos(lonFrom) + B * Cos(latTo) * Cos(lonTo);
|
X := A * cos_latFrom * cos_lonFrom + B * cos_latTo * Cos(lonTo);
|
||||||
Y := A * Cos(latFrom) * Sin(lonFrom) + B * Cos(latTo) * Sin(lonTo);
|
Y := A * cos_latFrom * sin_lonFrom + B * cos_latTo * Sin(lonTo);
|
||||||
Z := A * Sin(latFrom) + B * Sin(latTo);
|
Z := A * sin_latFrom + B * sin_latTo;
|
||||||
Lat := ArcTan2(Z, Sqrt(Sqr(X) + Sqr(Y)));
|
Lat := ArcTan2(Z, Sqrt(Sqr(X) + Sqr(Y)));
|
||||||
Lon := ArcTan2(Y, X);
|
Lon := ArcTan2(Y, X);
|
||||||
Lat := RadToDeg(Lat);
|
Lat := RadToDeg(Lat);
|
||||||
Lon := NormalizeLon(RadToDeg(Lon));
|
Lon := {%H-}NormalizeLon(RadToDeg(Lon));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function NormalizeLon(const Lon: Double): Double;
|
function NormalizeLon(const Lon: Double): Double;
|
||||||
|
Loading…
Reference in New Issue
Block a user