diff --git a/components/lazmapviewer/examples/elevations/main.pas b/components/lazmapviewer/examples/elevations/main.pas
index 1c5ecd987..0aebb61fc 100644
--- a/components/lazmapviewer/examples/elevations/main.pas
+++ b/components/lazmapviewer/examples/elevations/main.pas
@@ -7,8 +7,8 @@ interface
uses
Classes, SysUtils, LazFileUtils,
LCLIntf, Forms, Controls, Graphics, Dialogs, StdCtrls,
- ExtCtrls, Grids, Buttons, mvMapViewer, mvTypes, mvEngine, Types, mvGpsObj,
- mvDrawingEngine;
+ ExtCtrls, Grids, Buttons, Types,
+ mvMapViewer, mvTypes, mvGeoMath, mvEngine, mvGpsObj, mvDrawingEngine;
type
{ TMainForm }
diff --git a/components/lazmapviewer/examples/flights/main.lfm b/components/lazmapviewer/examples/flights/main.lfm
index b08fb0b93..916af5e77 100644
--- a/components/lazmapviewer/examples/flights/main.lfm
+++ b/components/lazmapviewer/examples/flights/main.lfm
@@ -6,9 +6,10 @@ object MainForm: TMainForm
Caption = 'Flights - LazMapViewer'
ClientHeight = 662
ClientWidth = 942
+ ShowHint = True
+ LCLVersion = '3.99.0.0'
OnCreate = FormCreate
OnDestroy = FormDestroy
- ShowHint = True
object MapView: TMapView
Left = 0
Height = 662
@@ -27823,192 +27824,33 @@ object MainForm: TMainForm
MapCenter.Longitude = -87.9081388888889
MapCenter.Latitude = 41.9769444444444
POIImage.Data = {
- 36170000424D36170000000000003600000028000000200000002E0000000100
- 2000000000000017000064000000640000000000000000000000FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FD560000FC4CFFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000F1110000FEE70000FEE10000
- EA0CFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FE9A0000FFFF0000FFFF0000
- FE8FFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF000000FB3E0000FEFE0000FFFF0000FFFF0000
- FEFC0000FB35FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF000000DB070000FED70000FFFF0000FFFF0000FFFF0000
- FFFF0000FECF0000C004FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF000000FE800000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FD75FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF000000F9290000FEF90000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FEF50000F821FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00000080020000FEC30000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FEB8FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF000000FD660000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FD5CFFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000
- F5180000FEEF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FEEA0000F213FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000
- FEAA0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FE9FFFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FC4C0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEFE0000FC42FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000EA0C0000FEE10000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEDB0000E309FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FE900000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FE86FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FB350000FEFC0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEFA0000
- FA2DFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF000000C0040000FED00000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FEC700008002FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF000000FD770000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FD6CFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF000000F8230000FEF80000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FEF50000F61CFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF000000FECF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FEC8FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF000000FE820000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FD79FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF000000F9270000FEFD0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FEFD0000F822FFFFFF00FFFFFF00FFFFFF00FFFF
- FF000000FEA70000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FEF70000FEB50000FE810000FD670000FD670000
- FE810000FEB50000FEF70000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FEA7FFFFFF00FFFFFF00FFFFFF000000
- FB340000FEFE0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FEFD0000FE920000F213FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF000000F2130000FE920000FEFD0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FEFE0000FB34FFFFFF00FFFFFF000000
- FEAC0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FEF60000FC4DFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF000000FC4D0000FEF60000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEACFFFFFF000000F3150000
- FEFA0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEFE0000
- FC54FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FC540000FEFE0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEFA0000F3150000FD610000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEA2FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FEA20000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FD610000FEA00000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEFD0000F823FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000F8230000FEFD0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEA00000FECD0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEC5FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FEC50000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FECD0000FEEC0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FE8CFFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FE8C0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEEC0000FEFA0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FD72FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FD720000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEFA0000FEF70000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FD75FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FD750000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEF70000FEE80000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FE95FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FE950000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEE80000FEC50000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FED5FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FED50000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEC50000FE940000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FB37FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FB370000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FE940000FC520000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEC00000
- 8002FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00000080020000FEC00000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FC520000E60A0000
- FEF20000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FD7EFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FD7E0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEF20000E60AFFFFFF000000
- FE950000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FEFE0000FD7F00008002FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00000080020000FD7F0000FEFE0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FE95FFFFFF00FFFFFF000000
- F8200000FEF80000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FEC30000FB3DFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF000000FB3D0000FEC30000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FEF80000F820FFFFFF00FFFFFF00FFFF
- FF000000FE830000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FEDB0000FE9C0000FD7E0000FD7E0000
- FE9C0000FEDB0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FE83FFFFFF00FFFFFF00FFFFFF00FFFF
- FF000000DB070000FECC0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FECC0000DB07FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF000000F71F0000FEE40000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FEE40000F71FFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF000000FA2B0000FEE50000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FEE50000FA2BFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF000000F8210000FECD0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FECE0000F821FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000DB070000FE850000FEF90000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEF90000FE850000
- DB07FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000F8230000
- FE990000FEF30000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FEF30000FE990000F823FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF000000EA0C0000FD570000FE980000FEC70000FEEB0000FEF90000FEF90000
- FEEB0000FEC70000FE980000FD570000EA0CFFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
+ 4503000089504E470D0A1A0A0000000D49484452000000200000002E08060000
+ 0049701B840000030C49444154789CB5983B68145114867F4410C54644B0107C
+ 152262A7A4D2C2DA3422DAD8D868631510B1D1688855409104A2088634819056
+ B00C488845626C82C55662A29204C40DC96ED66CD6F38F77976B76E6DCC7CC14
+ 077667CEF9FFEF3EE6CC03AD560B3EB1021C6C023777805189598955892D13AB
+ E6D8287398EBABEB4CA803A745F895C47A92EE11CC650D6BA3012AC03E1119E4
+ 087D8D5340383B83D40A0210F29352381F6B9C02F2899A5E000DE09C142C1765
+ 6E412C535B05A801C72571A968730B62891EA90066CDE7CA32B720E6EC3DD101
+ 901303012215893772C93D62F0378F05D40FFC07201BE4841CAC7B147EF8035C
+ CADAD13CC71C0F9D3A3D3B007260C451B023237DDC0FEC715DD7CC612E6B1C9A
+ 2309C077E080FCA96AC99C66DFCED68EA44607A8D21BDBC03547E2B4CFC8D366
+ 82B59A36BD39FDC35A92AC6B4FA8B9B5277A1C831B26C08C92B0186B6E5D5D8B
+ 8AFE0C137EBA364A4E80CC0D4E6F26D494CD773F2F40A2910D5023404301E82B
+ 00A04F016810604D49182A60098614FD3568B7DD6483E607D036F93C13C69484
+ A6CF534D5698A7A9A6A23FC635BAEDB856C7738C7E5CD3A637D68123DA46644F
+ 978E753DD49C35DAFD809EF46E934E39666153047B03CC7B59E3D09C6AFDFB97
+ B4CC0B1E77AFA6C4CB2A7038CB98E798A3AD7B7B56E9D90130B330A115D9CD43
+ E29DC41359C3BB0CFE36C7329BDA2E8D89B66F07600B38E3222F22CC9575AA0B
+ C0CCC2D3B20164C61EDA9E5DEB28100B258EFEE36EBF2E00D33C9CCF8711E61B
+ 9BC0312780B9813C2861EAEFA579A5024C037B85F87381A39FCD7AAC4B0530BD
+ E1A2146E1760DE9057B2F3593E99006643BE2800E099E6A102F04383087CCD61
+ 5EF906EC8F06307DFD6AA4396F62575CFA4E00B3149311006F7DB4BD003680A3
+ 22F82BC07C45BB69050398DE7027E09ABFE5ABEB0D605EB57CDE7CDFFB6A0601
+ 30E48E7956FB68C5769BF52DA81000B321FB95A90F7E910906309F72BEA48C7E
+ 812DBC740086B4E9CBF6231C5B365B778C561480598AD716C0F3589D6880DFC0
+ 2131FEC1561DF26DB83000866CBA1B49ABCEA1F117D2B9A057721AC774000000
+ 0049454E44AE426082
}
POIImages = ilPOIs
POIImagesWidth = 32
@@ -28031,8 +27873,8 @@ object MainForm: TMainForm
TabOrder = 1
object PgData: TTabSheet
Caption = 'Tracking'
- ClientHeight = 627
- ClientWidth = 312
+ ClientHeight = 634
+ ClientWidth = 310
object ZoomTrackBar: TTrackBar
AnchorSideLeft.Control = PgData
AnchorSideTop.Control = LblZoom
@@ -28041,12 +27883,12 @@ object MainForm: TMainForm
AnchorSideRight.Side = asrBottom
Left = 2
Height = 40
- Top = 23
- Width = 308
+ Top = 21
+ Width = 306
Min = 1
- OnChange = ZoomTrackBarChange
Position = 4
TickMarks = tmBoth
+ OnChange = ZoomTrackBarChange
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 2
BorderSpacing.Right = 2
@@ -28056,9 +27898,9 @@ object MainForm: TMainForm
AnchorSideLeft.Control = PgData
AnchorSideTop.Control = PgData
Left = 6
- Height = 17
+ Height = 15
Top = 6
- Width = 43
+ Width = 35
BorderSpacing.Left = 6
BorderSpacing.Top = 6
Caption = 'Zoom:'
@@ -28071,9 +27913,9 @@ object MainForm: TMainForm
AnchorSideRight.Control = PgData
AnchorSideRight.Side = asrBottom
Left = 6
- Height = 73
- Top = 71
- Width = 300
+ Height = 70
+ Top = 69
+ Width = 298
Anchors = [akTop, akLeft, akRight]
AutoSize = True
BorderSpacing.Left = 6
@@ -28081,17 +27923,17 @@ object MainForm: TMainForm
BorderSpacing.Right = 6
BorderSpacing.InnerBorder = 4
Caption = 'Mouse position'
- ClientHeight = 54
- ClientWidth = 296
+ ClientHeight = 50
+ ClientWidth = 294
TabOrder = 1
object lblMouseLon: TLabel
AnchorSideLeft.Control = gbMouse
AnchorSideTop.Control = lblMouseLat
AnchorSideTop.Side = asrBottom
Left = 8
- Height = 17
- Top = 29
- Width = 68
+ Height = 15
+ Top = 27
+ Width = 54
BorderSpacing.Left = 8
BorderSpacing.Top = 4
Caption = 'Longitude'
@@ -28101,9 +27943,9 @@ object MainForm: TMainForm
AnchorSideLeft.Control = gbMouse
AnchorSideTop.Control = gbMouse
Left = 8
- Height = 17
+ Height = 15
Top = 4
- Width = 57
+ Width = 43
BorderSpacing.Left = 8
BorderSpacing.Top = 4
BorderSpacing.Bottom = 8
@@ -28116,10 +27958,10 @@ object MainForm: TMainForm
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = gbMouse
AnchorSideRight.Side = asrBottom
- Left = 235
- Height = 17
- Top = 29
- Width = 45
+ Left = 244
+ Height = 15
+ Top = 27
+ Width = 34
Alignment = taRightJustify
Anchors = [akTop, akRight]
BorderSpacing.Top = 4
@@ -28132,10 +27974,10 @@ object MainForm: TMainForm
AnchorSideTop.Control = gbMouse
AnchorSideRight.Control = gbMouse
AnchorSideRight.Side = asrBottom
- Left = 235
- Height = 17
+ Left = 244
+ Height = 15
Top = 4
- Width = 45
+ Width = 34
Alignment = taRightJustify
Anchors = [akTop, akRight]
BorderSpacing.Top = 4
@@ -28152,25 +27994,25 @@ object MainForm: TMainForm
AnchorSideRight.Control = gbMouse
AnchorSideRight.Side = asrBottom
Left = 6
- Height = 73
- Top = 152
- Width = 300
+ Height = 70
+ Top = 147
+ Width = 298
Anchors = [akTop, akLeft, akRight]
AutoSize = True
BorderSpacing.Top = 8
BorderSpacing.InnerBorder = 4
Caption = 'Center'
- ClientHeight = 54
- ClientWidth = 296
+ ClientHeight = 50
+ ClientWidth = 294
TabOrder = 2
object lblCenterLon: TLabel
AnchorSideLeft.Control = gbCenter
AnchorSideTop.Control = lblCenterLat
AnchorSideTop.Side = asrBottom
Left = 8
- Height = 17
- Top = 29
- Width = 68
+ Height = 15
+ Top = 27
+ Width = 54
BorderSpacing.Left = 8
BorderSpacing.Top = 4
Caption = 'Longitude'
@@ -28180,9 +28022,9 @@ object MainForm: TMainForm
AnchorSideLeft.Control = gbCenter
AnchorSideTop.Control = gbCenter
Left = 8
- Height = 17
+ Height = 15
Top = 4
- Width = 57
+ Width = 43
BorderSpacing.Left = 8
BorderSpacing.Top = 4
BorderSpacing.Bottom = 8
@@ -28195,10 +28037,10 @@ object MainForm: TMainForm
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = gbCenter
AnchorSideRight.Side = asrBottom
- Left = 235
- Height = 17
- Top = 29
- Width = 45
+ Left = 244
+ Height = 15
+ Top = 27
+ Width = 34
Alignment = taRightJustify
Anchors = [akTop, akRight]
BorderSpacing.Top = 4
@@ -28211,10 +28053,10 @@ object MainForm: TMainForm
AnchorSideTop.Control = gbCenter
AnchorSideRight.Control = gbCenter
AnchorSideRight.Side = asrBottom
- Left = 235
- Height = 17
+ Left = 244
+ Height = 15
Top = 4
- Width = 45
+ Width = 34
Alignment = taRightJustify
Anchors = [akTop, akRight]
BorderSpacing.Top = 4
@@ -28230,9 +28072,9 @@ object MainForm: TMainForm
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = plInfo
Left = 6
- Height = 231
- Top = 233
- Width = 298
+ Height = 246
+ Top = 225
+ Width = 296
Anchors = [akTop, akLeft, akRight, akBottom]
AutoFillColumns = True
BorderSpacing.Top = 8
@@ -28248,12 +28090,12 @@ object MainForm: TMainForm
item
Title.Alignment = taCenter
Title.Caption = 'Latitude'
- Width = 105
+ Width = 111
end
item
Title.Alignment = taCenter
Title.Caption = 'Longitude'
- Width = 106
+ Width = 111
end>
FixedCols = 0
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goRowSelect, goSmoothScroll]
@@ -28262,8 +28104,8 @@ object MainForm: TMainForm
OnDblClick = sgTracksDblClick
ColWidths = (
70
- 105
- 106
+ 111
+ 111
)
end
object pnlFlightControl: TPanel
@@ -28274,8 +28116,8 @@ object MainForm: TMainForm
AnchorSideBottom.Side = asrBottom
Left = 0
Height = 50
- Top = 577
- Width = 312
+ Top = 584
+ Width = 310
Anchors = [akLeft, akRight, akBottom]
BevelOuter = bvNone
ChildSizing.LeftRightSpacing = 5
@@ -28288,13 +28130,13 @@ object MainForm: TMainForm
ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 99
ClientHeight = 50
- ClientWidth = 312
+ ClientWidth = 310
TabOrder = 4
object btnPlay: TSpeedButton
Left = 5
Height = 40
Top = 5
- Width = 65
+ Width = 66
Glyph.Data = {
36040000424D3604000000000000360000002800000010000000100000000100
2000000000000004000064000000640000000000000000000000000000000000
@@ -28334,10 +28176,10 @@ object MainForm: TMainForm
OnClick = btnPlayClick
end
object btnPause: TSpeedButton
- Left = 75
+ Left = 76
Height = 40
Top = 5
- Width = 65
+ Width = 66
Glyph.Data = {
36040000424D3604000000000000360000002800000010000000100000000100
2000000000000004000064000000640000000000000000000000000000000000
@@ -28377,10 +28219,10 @@ object MainForm: TMainForm
OnClick = btnPauseClick
end
object btnStop: TSpeedButton
- Left = 145
+ Left = 147
Height = 40
Top = 5
- Width = 65
+ Width = 67
Glyph.Data = {
36040000424D3604000000000000360000002800000010000000100000000100
2000000000000004000064000000640000000000000000000000000000000000
@@ -28420,10 +28262,10 @@ object MainForm: TMainForm
OnClick = btnStopClick
end
object btnWarp: TSpeedButton
- Left = 215
+ Left = 219
Height = 40
Top = 5
- Width = 92
+ Width = 86
Caption = 'Warp+'
OnClick = btnWarpClick
end
@@ -28433,8 +28275,8 @@ object MainForm: TMainForm
AnchorSideBottom.Control = pnlFlightControl
Left = 6
Height = 33
- Top = 536
- Width = 298
+ Top = 543
+ Width = 296
Anchors = [akLeft, akRight, akBottom]
BorderSpacing.Bottom = 8
TabOrder = 5
@@ -28446,11 +28288,11 @@ object MainForm: TMainForm
AnchorSideBottom.Control = pnlWarpInfo
Left = 6
Height = 72
- Top = 464
- Width = 298
+ Top = 471
+ Width = 296
Anchors = [akLeft, akRight, akBottom]
ClientHeight = 72
- ClientWidth = 298
+ ClientWidth = 296
Color = clCream
ParentBackground = False
ParentColor = False
@@ -28459,7 +28301,7 @@ object MainForm: TMainForm
Left = 6
Height = 60
Top = 6
- Width = 286
+ Width = 284
Align = alClient
AutoSize = False
BorderSpacing.Around = 5
@@ -28473,16 +28315,16 @@ object MainForm: TMainForm
AnchorSideBottom.Control = plInfo
AnchorSideBottom.Side = asrBottom
Left = 4
- Height = 21
- Top = 47
- Width = 114
+ Height = 19
+ Top = 49
+ Width = 90
Anchors = [akLeft, akBottom]
BorderSpacing.Around = 3
Caption = 'Follow tightly'
Checked = True
- OnChange = cbTightFollowChange
State = cbChecked
TabOrder = 0
+ OnChange = cbTightFollowChange
end
end
end
diff --git a/components/lazmapviewer/examples/flights/main.pas b/components/lazmapviewer/examples/flights/main.pas
index 58e7c42e2..5c2ddfe38 100644
--- a/components/lazmapviewer/examples/flights/main.pas
+++ b/components/lazmapviewer/examples/flights/main.pas
@@ -71,7 +71,7 @@ implementation
{$R *.lfm}
uses
- LCLType, Math, FPImage, DateUtils, mvEngine;
+ LCLType, Math, FPImage, DateUtils, mvGeoMath, mvEngine;
type
diff --git a/components/lazmapviewer/examples/fulldemo/globals.pas b/components/lazmapviewer/examples/fulldemo/globals.pas
index 8b78a2f20..cd22de77d 100644
--- a/components/lazmapviewer/examples/fulldemo/globals.pas
+++ b/components/lazmapviewer/examples/fulldemo/globals.pas
@@ -5,7 +5,7 @@ unit globals;
interface
uses
- Classes, SysUtils, mvEngine;
+ Classes, SysUtils, mvGeoMath, mvEngine;
type
TPOIMode = (pmDefaultDrawing, pmDefaultImage, pmImageList, pmCustomDrawing);
diff --git a/components/lazmapviewer/examples/fulldemo/gpslistform.pas b/components/lazmapviewer/examples/fulldemo/gpslistform.pas
index 47a4a4292..ded5332f8 100644
--- a/components/lazmapviewer/examples/fulldemo/gpslistform.pas
+++ b/components/lazmapviewer/examples/fulldemo/gpslistform.pas
@@ -57,7 +57,7 @@ implementation
{$R *.lfm}
uses
- mvTypes, mvEngine,
+ mvTypes, mvGeoMath, mvEngine,
globals;
destructor TGPSListViewer.Destroy;
@@ -143,7 +143,7 @@ begin
// 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),
+ CalcGeoDistance(CoordArr[0].Lat, CoordArr[0].Lon, CoordArr[1].Lat, CoordArr[1].Lon, DistanceUnit, esEllipsoid),
DistanceUnit_Names[DistanceUnit]
]));
end;
diff --git a/components/lazmapviewer/examples/fulldemo/main.pas b/components/lazmapviewer/examples/fulldemo/main.pas
index 0d62bf6fa..ec5510fae 100644
--- a/components/lazmapviewer/examples/fulldemo/main.pas
+++ b/components/lazmapviewer/examples/fulldemo/main.pas
@@ -15,7 +15,7 @@ uses
Classes, SysUtils, Types, Forms, Controls, Graphics, Dialogs, ExtCtrls,
StdCtrls, ComCtrls, Buttons, IntfGraphics, PrintersDlgs,
Grids, ExtDlgs,
- mvGeoNames, mvMapViewer, mvTypes, mvGpsObj, mvDrawingEngine,
+ mvGeoMath, mvGeoNames, mvMapViewer, mvTypes, mvGpsObj, mvDrawingEngine,
{$IFDEF WITH_ADDONS}ConfigFrame_with_Addons{$ELSE}ConfigFrame{$ENDIF};
type
diff --git a/components/lazmapviewer/examples/trackdemo/main.lfm b/components/lazmapviewer/examples/trackdemo/main.lfm
index e6e1e95ec..f6557ad26 100644
--- a/components/lazmapviewer/examples/trackdemo/main.lfm
+++ b/components/lazmapviewer/examples/trackdemo/main.lfm
@@ -24,192 +24,33 @@ object MainForm: TMainForm
Font.Pitch = fpVariable
MapProvider = 'Google Maps'
POIImage.Data = {
- 36170000424D36170000000000003600000028000000200000002E0000000100
- 2000000000000017000064000000640000000000000000000000FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FD560000FC4CFFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000F1110000FEE70000FEE10000
- EA0CFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FE9A0000FFFF0000FFFF0000
- FE8FFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF000000FB3E0000FEFE0000FFFF0000FFFF0000
- FEFC0000FB35FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF000000DB070000FED70000FFFF0000FFFF0000FFFF0000
- FFFF0000FECF0000C004FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF000000FE800000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FD75FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF000000F9290000FEF90000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FEF50000F821FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00000080020000FEC30000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FEB8FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF000000FD660000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FD5CFFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000
- F5180000FEEF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FEEA0000F213FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000
- FEAA0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FE9FFFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FC4C0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEFE0000FC42FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000EA0C0000FEE10000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEDB0000E309FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FE900000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FE86FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FB350000FEFC0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEFA0000
- FA2DFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF000000C0040000FED00000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FEC700008002FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF000000FD770000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FD6CFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF000000F8230000FEF80000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FEF50000F61CFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF000000FECF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FEC8FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF000000FE820000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FD79FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF000000F9270000FEFD0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FEFD0000F822FFFFFF00FFFFFF00FFFFFF00FFFF
- FF000000FEA70000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FEF70000FEB50000FE810000FD670000FD670000
- FE810000FEB50000FEF70000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FEA7FFFFFF00FFFFFF00FFFFFF000000
- FB340000FEFE0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FEFD0000FE920000F213FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF000000F2130000FE920000FEFD0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FEFE0000FB34FFFFFF00FFFFFF000000
- FEAC0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FEF60000FC4DFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF000000FC4D0000FEF60000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEACFFFFFF000000F3150000
- FEFA0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEFE0000
- FC54FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FC540000FEFE0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEFA0000F3150000FD610000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEA2FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FEA20000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FD610000FEA00000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEFD0000F823FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000F8230000FEFD0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEA00000FECD0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEC5FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FEC50000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FECD0000FEEC0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FE8CFFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FE8C0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEEC0000FEFA0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FD72FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FD720000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEFA0000FEF70000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FD75FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FD750000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEF70000FEE80000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FE95FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FE950000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEE80000FEC50000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FED5FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FED50000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEC50000FE940000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FB37FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FB370000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FE940000FC520000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEC00000
- 8002FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00000080020000FEC00000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FC520000E60A0000
- FEF20000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FD7EFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FD7E0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEF20000E60AFFFFFF000000
- FE950000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FEFE0000FD7F00008002FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00000080020000FD7F0000FEFE0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FE95FFFFFF00FFFFFF000000
- F8200000FEF80000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FEC30000FB3DFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF000000FB3D0000FEC30000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FEF80000F820FFFFFF00FFFFFF00FFFF
- FF000000FE830000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FEDB0000FE9C0000FD7E0000FD7E0000
- FE9C0000FEDB0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FE83FFFFFF00FFFFFF00FFFFFF00FFFF
- FF000000DB070000FECC0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FECC0000DB07FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF000000F71F0000FEE40000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FEE40000F71FFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF000000FA2B0000FEE50000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FEE50000FA2BFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF000000F8210000FECD0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FECE0000F821FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000DB070000FE850000FEF90000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FEF90000FE850000
- DB07FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000F8230000
- FE990000FEF30000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000FFFF0000
- FFFF0000FFFF0000FFFF0000FFFF0000FEF30000FE990000F823FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
- FF000000EA0C0000FD570000FE980000FEC70000FEEB0000FEF90000FEF90000
- FEEB0000FEC70000FE980000FD570000EA0CFFFFFF00FFFFFF00FFFFFF00FFFF
- FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00
+ 4503000089504E470D0A1A0A0000000D49484452000000200000002E08060000
+ 0049701B840000030C49444154789CB5983B68145114867F4410C54644B0107C
+ 152262A7A4D2C2DA3422DAD8D868631510B1D1688855409104A2088634819056
+ B00C488845626C82C55662A29204C40DC96ED66CD6F38F77976B76E6DCC7CC14
+ 077667CEF9FFEF3EE6CC03AD560B3EB1021C6C023777805189598955892D13AB
+ E6D8287398EBABEB4CA803A745F895C47A92EE11CC650D6BA3012AC03E1119E4
+ 087D8D5340383B83D40A0210F29352381F6B9C02F2899A5E000DE09C142C1765
+ 6E412C535B05A801C72571A968730B62891EA90066CDE7CA32B720E6EC3DD101
+ 901303012215893772C93D62F0378F05D40FFC07201BE4841CAC7B147EF8035C
+ CADAD13CC71C0F9D3A3D3B007260C451B023237DDC0FEC715DD7CC612E6B1C9A
+ 2309C077E080FCA96AC99C66DFCED68EA44607A8D21BDBC03547E2B4CFC8D366
+ 82B59A36BD39FDC35A92AC6B4FA8B9B5277A1C831B26C08C92B0186B6E5D5D8B
+ 8AFE0C137EBA364A4E80CC0D4E6F26D494CD773F2F40A2910D5023404301E82B
+ 00A04F016810604D49182A60098614FD3568B7DD6483E607D036F93C13C69484
+ A6CF534D5698A7A9A6A23FC635BAEDB856C7738C7E5CD3A637D68123DA46644F
+ 978E753DD49C35DAFD809EF46E934E39666153047B03CC7B59E3D09C6AFDFB97
+ B4CC0B1E77AFA6C4CB2A7038CB98E798A3AD7B7B56E9D90130B330A115D9CD43
+ E29DC41359C3BB0CFE36C7329BDA2E8D89B66F07600B38E3222F22CC9575AA0B
+ C0CCC2D3B20164C61EDA9E5DEB28100B258EFEE36EBF2E00D33C9CCF8711E61B
+ 9BC0312780B9813C2861EAEFA579A5024C037B85F87381A39FCD7AAC4B0530BD
+ E1A2146E1760DE9057B2F3593E99006643BE2800E099E6A102F04383087CCD61
+ 5EF906EC8F06307DFD6AA4396F62575CFA4E00B3149311006F7DB4BD003680A3
+ 22F82BC07C45BB69050398DE7027E09ABFE5ABEB0D605EB57CDE7CDFFB6A0601
+ 30E48E7956FB68C5769BF52DA81000B321FB95A90F7E910906309F72BEA48C7E
+ 812DBC740086B4E9CBF6231C5B365B778C561480598AD716C0F3589D6880DFC0
+ 2131FEC1561DF26DB83000866CBA1B49ABCEA1F117D2B9A057721AC774000000
+ 0049454E44AE426082
}
POITextBgColor = clCream
UseThreads = True
diff --git a/components/lazmapviewer/examples/trackdemo/main.pas b/components/lazmapviewer/examples/trackdemo/main.pas
index d713a9d68..ce69615cb 100644
--- a/components/lazmapviewer/examples/trackdemo/main.pas
+++ b/components/lazmapviewer/examples/trackdemo/main.pas
@@ -6,7 +6,7 @@ interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls,
- Grids, StdCtrls, ColorBox, mvMapViewer, mvGpsObj;
+ Grids, StdCtrls, ColorBox, mvMapViewer, mvGeoMath, mvGpsObj;
type
diff --git a/components/lazmapviewer/lazmapviewerpkg.lpk b/components/lazmapviewer/lazmapviewerpkg.lpk
index ae869fb3d..40d9b08e2 100644
--- a/components/lazmapviewer/lazmapviewerpkg.lpk
+++ b/components/lazmapviewer/lazmapviewerpkg.lpk
@@ -20,7 +20,7 @@
-
+
@@ -108,6 +108,10 @@
+
+
+
+
diff --git a/components/lazmapviewer/lazmapviewerpkg.pas b/components/lazmapviewer/lazmapviewerpkg.pas
index 66f5f3ff2..a54a42ca5 100644
--- a/components/lazmapviewer/lazmapviewerpkg.pas
+++ b/components/lazmapviewer/lazmapviewerpkg.pas
@@ -11,7 +11,7 @@ uses
mvCache, mvDownloadEngine, mvDragObj, mvEngine, mvGeoNames, mvGpsObj,
mvJobQueue, mvJobs, mvMapProvider, mvTypes, mvMapViewer, mvExtraData,
mvDLEFpc, mvMapViewerReg, mvGPX, mvDrawingEngine, mvDE_IntfGraphics,
- mvDLEWin, mvMapViewerPropEdits, mvLayersPropEditForm, mvDE_LCL,
+ mvDLEWin, mvMapViewerPropEdits, mvLayersPropEditForm, mvDE_LCL, mvgeomath,
LazarusPackageIntf;
implementation
diff --git a/components/lazmapviewer/source/mvengine.pas b/components/lazmapviewer/source/mvengine.pas
index b72ba1742..3003f9274 100644
--- a/components/lazmapviewer/source/mvengine.pas
+++ b/components/lazmapviewer/source/mvengine.pas
@@ -21,13 +21,7 @@ interface
uses
Classes, SysUtils, IntfGraphics, Controls, Math, GraphType, FPImage,
- mvTypes, mvJobQueue, mvMapProvider, mvDownloadEngine, mvCache, mvDragObj;
-
-const
- EARTH_EQUATORIAL_RADIUS = 6378137;
- EARTH_POLAR_RADIUS = 6356752.3142;
- EARTH_CIRCUMFERENCE = 2 * pi * EARTH_EQUATORIAL_RADIUS;
- EARTH_ECCENTRICITY = sqrt(1 - sqr(EARTH_POLAR_RADIUS / EARTH_EQUATORIAL_RADIUS));
+ mvTypes, mvGeoMath, mvJobQueue, mvMapProvider, mvDownloadEngine, mvCache, mvDragObj;
type
TDrawTileEvent = procedure (const TileId: TTileId; X,Y: integer;
@@ -42,8 +36,6 @@ type
TTileIdArray = Array of TTileId;
- TDistanceUnits = (duMeters, duKilometers, duMiles);
-
{ TMapWindow }
TMapWindow = Record
@@ -215,33 +207,19 @@ type
property OnZoomChange: TNotifyEvent read FOnZoomChange write FOnZoomChange;
end;
-function RealPoint(Lat, Lon: Double): TRealPoint;
-function NormalizeLon(const Lon: Double): Double; inline;
+// The following functions have been moved to mvGeoMath and will be removed here sooner or later...
+function DMSToDeg(Deg, Min: Word; Sec: Double): Double; deprecated 'Use function in unit mvGeoMath';
+function GPSToDMS(Angle: Double): string; deprecated 'Use function in unit mvGeoMath';
+function GPSToDMS(Angle: Double; AFormatSettings: TFormatSettings): string; deprecated 'Use function in unit mvGeoMath';
-function HaversineDist(Lat1, Lon1, Lat2, Lon2, Radius: Double): Double;
-function CalcGeoDistance(Lat1, Lon1, Lat2, Lon2: double;
- AUnits: TDistanceUnits = duKilometers): double;
+function LatToStr(ALatitude: Double; DMS: Boolean): String; deprecated 'Use function in unit mvGeoMath';
+function LatToStr(ALatitude: Double; DMS: Boolean; AFormatSettings: TFormatSettings): String; deprecated 'Use function in unit mvGeoMath';
+function LonToStr(ALongitude: Double; DMS: Boolean): String; deprecated 'Use function in unit mvGeoMath';
+function LonToStr(ALongitude: Double; DMS: Boolean; AFormatSettings: TFormatSettings): String; deprecated 'Use function in unit mvGeoMath';
+function TryStrToGps(const AValue: String; out ADeg: Double): Boolean; deprecated 'Use function in unit mvGeoMath';
+function TryStrDMSToDeg(const AValue: String; out ADeg: Double): Boolean; deprecated 'Use function in unit mvGeoMath';
-function CalcBearing(Lat1, Lon1, Lat2, Lon2: Double): Double;
-procedure CalcLatLon(const Lat1, Lon1, ADist, ABearing: Double; out Lat2, Lon2: Double);
-procedure CalcMidpoint(const Lat1, Lon1, Lat2, Lon2: Double; out Lat, Lon: Double);
-procedure CalcIntermedPoint(const Lat1, Lon1, Lat2, Lon2, AFrac: Double; out Lat, Lon: Double);
-
-
-function DMSToDeg(Deg, Min: Word; Sec: Double): Double;
-function GPSToDMS(Angle: Double): string;
-function GPSToDMS(Angle: Double; AFormatSettings: TFormatSettings): string;
-
-function LatToStr(ALatitude: Double; DMS: Boolean): String;
-function LatToStr(ALatitude: Double; DMS: Boolean; AFormatSettings: TFormatSettings): String;
-function LonToStr(ALongitude: Double; DMS: Boolean): String;
-function LonToStr(ALongitude: Double; DMS: Boolean; AFormatSettings: TFormatSettings): String;
-function TryStrToGps(const AValue: String; out ADeg: Double): Boolean;
-function TryStrDMSToDeg(const AValue: String; out ADeg: Double): Boolean;
-
-procedure SplitGps(AValue: Double; out ADegs, AMins, ASecs: Double);
-
-function ZoomFactor(AZoomLevel: Integer): Int64;
+function ZoomFactor(AZoomLevel: Integer): Int64; deprecated 'Use function in unit mvGeoMath';
var
HERE_AppID: String = '';
@@ -249,8 +227,6 @@ var
OpenWeatherMap_ApiKey: String = '';
ThunderForest_ApiKey: String = '';
- DMS_Decimals: Integer = 1;
-
implementation
@@ -258,25 +234,6 @@ uses
Forms, TypInfo, laz2_xmlread, laz2_xmlwrite, laz2_dom,
mvJobs, mvGpsObj;
-const
- _K = 1024;
- _M = _K*_K;
- _G = _K*_M;
- ZOOM_FACTOR: array[0..32] of Int64 = (
- 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, // 0..9
- _K, 2*_K, 4*_K, 8*_K, 16*_K, 32*_K, 64*_K, 128*_K, 256*_K, 512*_K, // 10..19
- _M, 2*_M, 4*_M, 8*_M, 16*_M, 32*_M, 64*_M, 128*_M, 256*_M, 512*_M, // 20..29
- _G, 2*_G, 4*_G // 30..32
- );
-
-function ZoomFactor(AZoomLevel: Integer): Int64;
-begin
- if (AZoomLevel >= Low(ZOOM_FACTOR)) and (AZoomLevel < High(ZOOM_FACTOR)) then
- Result := ZOOM_FACTOR[AZoomLevel]
- else
- Result := round(IntPower(2, AZoomLevel));
-end;
-
type
{ TEnvTile }
@@ -1474,492 +1431,56 @@ begin
MapWin.MapProvider := MP; // Restore the old Map Provider
end;
-//------------------------------------------------------------------------------
+{------------------------------------------------------------------------------}
-function RealPoint(Lat, Lon: Double): TRealPoint;
+function DMSToDeg(Deg, Min: Word; Sec: Double): Double;
begin
- Result.Lon := Lon;
- Result.Lat := Lat;
-end;
-
-procedure SplitGps(AValue: Double; out ADegs, AMins: Double);
-begin
- AValue := abs(AValue);
- AMins := frac(AValue) * 60;
- if abs(AMins - 60) < 1E-3 then
- begin
- AMins := 0;
- ADegs := trunc(AValue) + 1;
- end else
- ADegs := trunc(AValue);
- if AValue < 0 then
- ADegs := -ADegs;
-end;
-
-procedure SplitGps(AValue: Double; out ADegs, AMins, ASecs: Double);
-begin
- SplitGps(AValue, ADegs, AMins);
- ASecs := frac(AMins) * 60;
- AMins := trunc(AMins);
- if abs(ASecs - 60) < 1E-3 then
- begin
- ASecs := 0;
- AMins := AMins + 1;
- if abs(AMins - 60) < 1e-3 then
- begin
- AMins := 0;
- ADegs := ADegs + 1;
- end;
- end;
- if AValue < 0 then
- ADegs := -ADegs;
+ Result := mvGeoMath.DMSToDeg(Deg, Min, Sec);
end;
function GPSToDMS(Angle: Double): string;
begin
- Result := GPSToDMS(Angle, DefaultFormatSettings);
+ Result := mvGeoMath.GPSToDMS(Angle);
end;
function GPSToDMS(Angle: Double; AFormatSettings: TFormatSettings): string;
-var
- deg, min, sec: Double;
begin
- SplitGPS(Angle, deg, min, sec);
- Result := Format('%.0f° %.0f'' %.*f"', [deg, min, DMS_Decimals, sec], AFormatSettings);
+ Result := mvGeoMath.GPSToDMS(Angle, AFormatSettings);
end;
function LatToStr(ALatitude: Double; DMS: Boolean): String;
begin
- Result := LatToStr(ALatitude, DMS, DefaultFormatSettings);
+ Result := mvGeoMath.LatToStr(ALatitude, DMS);
end;
function LatToStr(ALatitude: Double; DMS: Boolean; AFormatSettings: TFormatSettings): String;
begin
- if DMS then
- Result := GPSToDMS(abs(ALatitude), AFormatSettings)
- else
- Result := Format('%.6f°',[abs(ALatitude)], AFormatSettings);
- if ALatitude > 0 then
- Result := Result + ' N'
- else
- if ALatitude < 0 then
- Result := Result + ' S';
+ Result := mvGeoMath.LatToStr(ALatitude, DMS, AFormatSettings);
end;
function LonToStr(ALongitude: Double; DMS: Boolean): String;
begin
- Result := LonToStr(ALongitude, DMS, DefaultFormatSettings);
+ Result := mvGeoMath.LonToStr(ALongitude, DMS);
end;
function LonToStr(ALongitude: Double; DMS: Boolean; AFormatSettings: TFormatSettings): String;
begin
- if DMS then
- Result := GPSToDMS(abs(ALongitude), AFormatSettings)
- else
- Result := Format('%.6f°', [abs(ALongitude)], AFormatSettings);
- if ALongitude > 0 then
- Result := Result + ' E'
- else if ALongitude < 0 then
- Result := Result + ' W';
+ Result := mvGeoMath.LonToStr(ALongitude, DMS, AFormatSettings);
end;
-{ Combines up to three parts of a GPS coordinate string (degrees, minutes, seconds)
- to a floating-point degree value. The parts are separated by non-numeric
- characters:
-
- three parts ---> d m s ---> d and m must be integer, s can be float
- two parts ---> d m ---> d must be integer, s can be float
- one part ---> d ---> d can be float
-
- Each part can exhibit a unit identifier, such as °, ', or ". BUT: they are
- ignored. This means that an input string 50°30" results in the output value 50.5
- although the second part is marked as seconds, not minutes!
-
- Hemisphere suffixes ('N', 'S', 'E', 'W') are supported at the end of the input string.
-}
function TryStrToGps(const AValue: String; out ADeg: Double): Boolean;
-const
- NUMERIC_CHARS = ['0'..'9', '.', ',', '-', '+'];
-var
- mins, secs: Double;
- i, j, len: Integer;
- n: Integer;
- s: String = '';
- res: Integer;
- sgn: Double;
begin
- Result := false;
-
- ADeg := NaN;
- mins := 0;
- secs := 0;
-
- if AValue = '' then
- exit;
-
- len := Length(AValue);
- i := len;
- while (i >= 1) and (AValue[i] = ' ') do dec(i);
- sgn := 1.0;
- if (AValue[i] in ['S', 's', 'W', 'w']) then sgn := -1;
-
- // skip leading non-numeric characters
- i := 1;
- while (i <= len) and not (AValue[i] in NUMERIC_CHARS) do
- inc(i);
-
- // extract first value: degrees
- SetLength(s, len);
- j := 1;
- n := 0;
- while (i <= len) and (AValue[i] in NUMERIC_CHARS) do begin
- if AValue[i] = ',' then s[j] := '.' else s[j] := AValue[i];
- inc(i);
- inc(j);
- inc(n);
- end;
- if n > 0 then begin
- SetLength(s, n);
- val(s, ADeg, res);
- if res <> 0 then
- exit;
- end;
-
- // skip non-numeric characters between degrees and minutes
- while (i <= len) and not (AValue[i] in NUMERIC_CHARS) do
- inc(i);
-
- // extract second value: minutes
- SetLength(s, len);
- j := 1;
- n := 0;
- while (i <= len) and (AValue[i] in NUMERIC_CHARS) do begin
- if AValue[i] = ',' then s[j] := '.' else s[j] := AValue[i];
- inc(i);
- inc(j);
- inc(n);
- end;
- if n > 0 then begin
- SetLength(s, n);
- val(s, mins, res);
- if (res <> 0) or (mins < 0) then
- exit;
- end;
-
- // skip non-numeric characters between minutes and seconds
- while (i <= len) and not (AValue[i] in NUMERIC_CHARS) do
- inc(i);
-
- // extract third value: seconds
- SetLength(s, len);
- j := 1;
- n := 0;
- while (i <= len) and (AValue[i] in NUMERIC_CHARS) do begin
- if AValue[i] = ',' then s[j] := '.' else s[j] := AValue[i];
- inc(i);
- inc(j);
- inc(n);
- end;
- if n > 0 then begin
- SetLength(s, n);
- val(s, secs, res);
- if (res <> 0) or (secs < 0) then
- exit;
- end;
-
- // If the string contains seconds then minutes and deegrees must be integers
- if (secs <> 0) and ((frac(ADeg) > 0) or (frac(mins) > 0)) then
- exit;
- // If the string does not contain seconds then degrees must be integer.
- if (secs = 0) and (mins <> 0) and (frac(ADeg) > 0) then
- exit;
-
- // If the string contains minutes, but no seconds, then the degrees must be integer.
- Result := (mins >= 0) and (mins < 60) and (secs >= 0) and (secs < 60);
-
- // A similar check should be made for the degrees range, but since this is
- // different for latitude and longitude the check is skipped here.
- if Result then
- ADeg := sgn * (abs(ADeg) + mins / 60 + secs / 3600);
+ Result := mvGeoMath.TryStrToGps(AValue, ADeg);
end;
-{ Convert Lat/Lon string to degrees.
-
- Recognized formats:
-
- Degrees, Minutes and Seconds:
- DDD°MM'SS.S"
- 32°18'23.1"N 122°36'52.5"W
-
- Degrees and Decimal Minutes:
- DDD° MM.MMM'
- 32°18.385'N 122°36.875'W
-
- Decimal Degrees:
- DDD.DDDDD°
- 32.30642°N 122.61458°W
- +32.30642 -122.61458
-}
function TryStrDMSToDeg(const AValue: String; out ADeg: Double): Boolean;
-const
- NUMERIC_CHARS = ['0'..'9', '.', ',', '-', '+'];
- WS_CHARS = [' '];
-var
- I, Len, N: Integer;
- S: String;
- D, Minutes, Seconds: Double;
- R: Word;
- Last, Neg: Boolean;
-
- function EOL: Boolean; inline;
- begin
- Result := Len < I;
- end;
-
- procedure SkipWS; inline;
- begin
- while not EOL and (AValue[I] in WS_CHARS) do
- Inc(I);
- end;
-
- function NextNum: String;
- begin
- Result := '';
- SkipWS;
- while not EOL and (AValue[I] in NUMERIC_CHARS) do
- begin
- if AValue[I] = ','
- then Result := Result + '.'
- else Result := Result + AValue[I];
- Inc(I);
- end;
- end;
-
begin
- Result := False;
- ADeg := NaN;
- Len := Length(AValue);
- I := 1;
-
- // Degrees
- S := NextNum;
- if S = '' then
- Exit;
- Val(S, ADeg, R);
- if R > 0 then
- Exit;
-
- // It must be the only part if negative or fractional
- Neg := ADeg < 0.0;
- Last := Neg or (Frac(ADeg) > 0.0);
-
- // Eat the degree symbol if present
- if not EOL and (Utf8CodePointLen(@AValue[I], 2, False) = 2)
- and (AValue[I] = #$c2) and (AValue[I + 1] = #$b0)
- then
- Inc(I, 2);
-
- Minutes := 0.0;
- Seconds := 0.0;
-
- N := 1;
- while not (EOL or Last) and (N < 3) do
- begin
- S := NextNum;
- if S = '' then
- Break
- else
- begin
- Val(S, D, R);
- // Invalid part or negative one
- if (R > 0) or (D < 0.0) then
- Exit;
- // No more parts when fractional
- Last := Frac(D) > 0.0;
- if not EOL then
- case AValue[I] of
- '''': // Munutes suffix
- begin
- Minutes := D;
- Inc(I); // Eat the '
- end;
- '"': // Seconds suffix
- begin
- Seconds := D;
- Last := True; // Last part
- Inc(I); // Eat the "
- end;
- otherwise
- if N = 1
- then Minutes := D
- else Seconds := D;
- end;
- end;
- Inc(N);
- end;
-
- // Merge parts
- ADeg := ADeg + Minutes / 60 + Seconds / 3600;
-
- // Check for N-S and E-W designators
- SkipWS;
- if not (EOL or Neg) and (AValue[I] in ['S', 's', 'W', 'w', 'N', 'n', 'E', 'e']) then
- begin
- if AValue[I] in ['S', 's', 'W', 'w']
- then ADeg := -1 * ADeg;
- Inc(I);
- end;
- SkipWS;
-
- // It must be entirely consumed
- Result := EOL;
+ Result := mvGeoMath.TryStrDMSToDeg(AValue, ADeg);
end;
-// https://stackoverflow.com/questions/73608975/pascal-delphi-11-formula-for-distance-in-meters-between-two-decimal-gps-point
-function HaversineDist(Lat1, Lon1, Lat2, Lon2, Radius: Double): Double;
-var
- latFrom, latTo, lonDiff: Double;
- dx, dy, dz: Double;
+function ZoomFactor(AZoomLevel: Integer): Int64;
begin
- lonDiff := DegToRad(Lon1 - Lon2);
- latFrom := DegToRad(Lat1);
- latTo := DegToRad(Lat2);
-
- dz := sin(latFrom) - sin(latTo);
- dx := cos(lonDiff) * cos(latFrom) - cos(latTo);
- dy := sin(lonDiff) * cos(latFrom);
-
- Result := arcsin(sqrt(sqr(dx) + sqr(dy) + sqr(dz)) / 2) * Radius * 2;
-end;
-
-
-{ Returns the direct distance (air-line) between two geo coordinates
- If latitude NOT between -90°..+90° and longitude NOT between -180°..+180°
- the function returns NaN.
- Usage: CalcGeoDistance(51.53323, -2.90130, 51.29442, -2.27275, duKilometers);
-}
-function CalcGeoDistance(Lat1, Lon1, Lat2, Lon2: double;
- AUnits: TDistanceUnits = duKilometers): double;
-begin
- // Validate
- if (Lat1 < -90.0) or (Lat1 > 90.0) then exit(NaN);
- if (Lat2 < -90.0) or (Lat2 > 90.0) then exit(NaN);
-
- Result := HaversineDist(Lat1, Lon1, Lat2, Lon2, EARTH_EQUATORIAL_RADIUS);
- case AUnits of
- duMeters: ;
- duKilometers: Result := Result * 1E-3;
- duMiles: Result := Result * 0.62137E-3;
- end;
-end;
-
-{ Calculate initial bearing (in °) from the start point Lat1,Lon1 to
- the end point Lat2,Lon2. No parameter checks, result normalized to 0°..360°.
-}
-function CalcBearing(Lat1, Lon1, Lat2, Lon2: Double): Double;
-var
- latFrom, latTo, lonDiff: Double;
-begin
- lonDiff := DegToRad(Lon2 - Lon1);
- latFrom := DegToRad(Lat1);
- latTo := DegToRad(Lat2);
- Result := ArcTan2(Sin(lonDiff) * Cos(latTo),
- Cos(latFrom) * Sin(latTo) - Sin(latFrom) * Cos(latTo) * Cos(lonDiff));
- Result := RadToDeg(Result);
- if Result < 0.0 then
- Result := Result + 360.0;
-end;
-
-{ Calculate end point Lat2,Lon2 by given start point Lat1,Lon1, distance
- ADist (in meters) and bearing ABearing (in °). No parameter checks,
- result Lon2 normalized to -180°..180°.
-}
-procedure CalcLatLon(const Lat1, Lon1, ADist, ABearing: Double; out Lat2,
- Lon2: Double);
-var
- latFrom, lonFrom, brng, aD: Double;
-begin
- latFrom := DegToRad(Lat1);
- lonFrom := DegToRad(Lon1);
- brng := DegToRad(ABearing);
- 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),
- Cos(aD) - Sin(latFrom) * Sin(Lat2));
- Lat2 := RadToDeg(Lat2);
- Lon2 := NormalizeLon(RadToDeg(Lon2));
-end;
-
-{ Calculate midpoint Lat,Lon by given start point Lat1,Lon1 and end point
- Lat2,Lon2. No parameter checks, result Lon normalized to -180°..180°.
-}
-procedure CalcMidpoint(const Lat1, Lon1, Lat2, Lon2: Double; out Lat,
- Lon: Double);
-var
- latFrom, lonDiff, latTo, lonTo, Bx, By: Double;
-begin
- lonDiff := DegToRad(Lon2 - Lon1);
- latFrom := DegToRad(Lat1);
- latTo := DegToRad(Lat2);
- lonTo := DegToRad(Lon2);
- Bx := Cos(latTo) * Cos(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);
- Lat := RadToDeg(Lat);
- Lon := NormalizeLon(RadToDeg(Lon));
-end;
-
-{ Calculate intermediate point Lat,Lon by given start point Lat1,Lon1, end point
- Lat2,Lon2 and fraction AFrac (0.0-1.0). No parameter checks for
- Lat1,Lon1,Lat2 and Lon2. Result Lon normalized to -180°..180°.
-}
-procedure CalcIntermedPoint(const Lat1, Lon1, Lat2, Lon2, AFrac: Double; out
- Lat, Lon: Double);
-var
- latFrom, lonFrom, latTo, lonTo: Double;
- A, B, aD, X, Y, Z: Double;
-begin
- if (Lat1 = Lat2) and (Lon1 = Lon2) or (AFrac < 0.001) then
- begin
- Lat := Lat1;
- Lon := Lon1;
- Exit;
- end;
- if AFrac > 0.999 then
- begin
- Lat := Lat2;
- Lon := Lon2;
- Exit;
- end;
- aD := CalcGeoDistance(Lat1, Lon1, Lat2, Lon2) / EARTH_EQUATORIAL_RADIUS;
- latFrom := DegToRad(Lat1);
- lonFrom := DegToRad(Lon1);
- latTo := DegToRad(Lat2);
- lonTo := DegToRad(Lon2);
- A := Sin((1.0 - AFrac) * aD) / Sin(aD);
- B := Sin(AFrac * aD) / Sin(aD);
- X := A * Cos(latFrom) * Cos(lonFrom) + B * Cos(latTo) * Cos(lonTo);
- Y := A * Cos(latFrom) * Sin(lonFrom) + B * Cos(latTo) * Sin(lonTo);
- Z := A * Sin(latFrom) + B * Sin(latTo);
- Lat := ArcTan2(Z, Sqrt(Sqr(X) + Sqr(Y)));
- Lon := ArcTan2(Y, X);
- Lat := RadToDeg(Lat);
- Lon := NormalizeLon(RadToDeg(Lon));
-end;
-
-function NormalizeLon(const Lon: Double): Double;
-begin
- if InRange(Lon, -180.0, 180.0)
- then Result := Lon
- else Result := FMod(Lon + 540.0, 360.0) - 180.0;
-end;
-
-{ Converts an angle given as degrees, minutes and seconds to a single
- floating point degrees value. }
-function DMSToDeg(Deg, Min: Word; Sec: Double): Double;
-begin
- Result := Deg + Min/60.0 + Sec/3600.0;
+ Result := mvGeoMath.ZoomFactor(AZoomLevel);
end;
end.
diff --git a/components/lazmapviewer/source/mvgeomath.pas b/components/lazmapviewer/source/mvgeomath.pas
new file mode 100644
index 000000000..1e5bf7e08
--- /dev/null
+++ b/components/lazmapviewer/source/mvgeomath.pas
@@ -0,0 +1,601 @@
+unit mvGeoMath;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, Math;
+
+const
+ EARTH_EQUATORIAL_RADIUS = 6378137;
+ EARTH_POLAR_RADIUS = 6356752.3142;
+ EARTH_CIRCUMFERENCE = 2 * pi * EARTH_EQUATORIAL_RADIUS;
+ EARTH_ECCENTRICITY = sqrt(1 - sqr(EARTH_POLAR_RADIUS / EARTH_EQUATORIAL_RADIUS));
+ EARTH_FLATTENING = 1.0 - EARTH_POLAR_RADIUS / EARTH_EQUATORIAL_RADIUS;
+
+ DMS_Decimals: Integer = 1;
+
+type
+ TDistanceUnits = (duMeters, duKilometers, duMiles);
+ TEarthShape = (esSphere, esEllipsoid);
+
+function NormalizeLon(const Lon: Double): Double; inline;
+
+function HaversineDist(Lat1, Lon1, Lat2, Lon2, Radius: Double): Double;
+function LambertsDist(Lat1, Lon1, Lat2, Lon2, Radius, Flattening: Double): Double;
+function CalcGeoDistance(Lat1, Lon1, Lat2, Lon2: double;
+ AUnits: TDistanceUnits = duKilometers; AShape: TEarthShape = esSphere): double;
+
+function CalcBearing(Lat1, Lon1, Lat2, Lon2: Double): Double;
+procedure CalcLatLon(const Lat1, Lon1, ADist, ABearing: Double; out Lat2, Lon2: Double);
+procedure CalcMidpoint(const Lat1, Lon1, Lat2, Lon2: Double; out Lat, Lon: Double);
+procedure CalcIntermedPoint(const Lat1, Lon1, Lat2, Lon2, AFrac: Double; out Lat, Lon: Double);
+
+function DMSToDeg(Deg, Min: Word; Sec: Double): Double;
+function GPSToDMS(Angle: Double): string;
+function GPSToDMS(Angle: Double; AFormatSettings: TFormatSettings): string;
+
+function LatToStr(ALatitude: Double; DMS: Boolean): String;
+function LatToStr(ALatitude: Double; DMS: Boolean; AFormatSettings: TFormatSettings): String;
+function LonToStr(ALongitude: Double; DMS: Boolean): String;
+function LonToStr(ALongitude: Double; DMS: Boolean; AFormatSettings: TFormatSettings): String;
+function TryStrToGps(const AValue: String; out ADeg: Double): Boolean;
+function TryStrDMSToDeg(const AValue: String; out ADeg: Double): Boolean;
+
+procedure SplitGps(AValue: Double; out ADegs, AMins, ASecs: Double);
+
+function ZoomFactor(AZoomLevel: Integer): Int64;
+
+
+implementation
+
+const
+ _K = 1024;
+ _M = _K*_K;
+ _G = _K*_M;
+ ZOOM_FACTOR: array[0..32] of Int64 = (
+ 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, // 0..9
+ _K, 2*_K, 4*_K, 8*_K, 16*_K, 32*_K, 64*_K, 128*_K, 256*_K, 512*_K, // 10..19
+ _M, 2*_M, 4*_M, 8*_M, 16*_M, 32*_M, 64*_M, 128*_M, 256*_M, 512*_M, // 20..29
+ _G, 2*_G, 4*_G // 30..32
+ );
+
+function ZoomFactor(AZoomLevel: Integer): Int64;
+begin
+ if (AZoomLevel >= Low(ZOOM_FACTOR)) and (AZoomLevel < High(ZOOM_FACTOR)) then
+ Result := ZOOM_FACTOR[AZoomLevel]
+ else
+ Result := round(IntPower(2, AZoomLevel));
+end;
+
+{ Calculation of distance on a sphere
+ https://stackoverflow.com/questions/73608975/pascal-delphi-11-formula-for-distance-in-meters-between-two-decimal-gps-point
+}
+// angles in radians
+function HaversineAngle(Lat1, Lon1, Lat2, Lon2: Double): Double;
+var
+ latFrom, latTo, lonDiff: Double;
+ dx, dy, dz: Double;
+begin
+ lonDiff := Lon1 - Lon2;
+ latFrom := Lat1;
+ latTo := Lat2;
+
+ dz := sin(latFrom) - sin(latTo);
+ dx := cos(lonDiff) * cos(latFrom) - cos(latTo);
+ dy := sin(lonDiff) * cos(latFrom);
+
+ Result := arcsin(sqrt(sqr(dx) + sqr(dy) + sqr(dz)) / 2.0) * 2.0;
+end;
+
+// Angles in degrees
+function HaversineDist(Lat1, Lon1, Lat2, Lon2, Radius: Double): Double;
+begin
+ Result := HaversineAngle(DegToRad(Lat1), DegToRad(Lon1), DegToRad(Lat2), DegToRad(Lon2)) * Radius;
+end;
+
+{ Calculation of distance on an ellipsoid
+ https://en.wikipedia.org/wiki/Geographical_distance
+}
+// Angles in degrees
+function LambertsDist(Lat1, Lon1, Lat2, Lon2, Radius, Flattening: Double): Double;
+var
+ reducedLat1, reducedLat2, sigma: Double;
+ P, Q: Double;
+ X, Y: Double;
+ sinP, cosP, sinQ, cosQ: Double;
+ sinSigma, sinSigma2, cosSigma2: Double;
+begin
+ Lat1 := DegToRad(Lat1);
+ Lon1 := DegToRad(Lon1);
+ Lat2 := DegToRad(Lat2);
+ Lon2 := DegToRad(Lon2);
+ reducedLat1 := arctan((1.0 - flattening) * tan(Lat1));
+ reducedLat2 := arctan((1.0 - flattening) * tan(Lat2));
+ sigma := HaversineAngle(reducedLat1, Lon1, reducedLat2, Lon2);
+ P := (reducedLat1 + reducedLat2) * 0.5;
+ Q := (reducedLat2 - reducedLat1) * 0.5;
+ SinCos(P, sinP, cosP);
+ SinCos(Q, sinQ, cosQ);
+ SinCos(sigma*0.5, sinSigma2, cosSigma2);
+ sinSigma := sin(sigma);
+ X := (sigma - sinSigma) * sqr(sinP * cosQ / cosSigma2);
+ Y := (sigma + sinSigma) * sqr(cosP * sinQ / sinSigma2);
+ Result := (sigma - 0.5*Flattening*(X + Y)) * Radius;
+end;
+
+
+{ Returns the direct distance (air-line) between two geo coordinates
+ If latitude is NOT between -90°..+90° and longitude is NOT between -180°..+180°
+ the function returns NaN.
+
+ Usage example:
+ CalcGeoDistance(51.53323, -2.90130, 51.29442, -2.27275, duKilometers, esEllipsoid);
+}
+function CalcGeoDistance(Lat1, Lon1, Lat2, Lon2: double;
+ AUnits: TDistanceUnits = duKilometers; AShape: TEarthShape = esSphere): double;
+begin
+ // Validate
+ if (Lat1 < -90.0) or (Lat1 > 90.0) then exit(NaN);
+ if (Lat2 < -90.0) or (Lat2 > 90.0) then exit(NaN);
+
+ case AShape of
+ esSphere:
+ Result := HaversineDist(Lat1, Lon1, Lat2, Lon2, EARTH_EQUATORIAL_RADIUS);
+ esEllipsoid:
+ Result := LambertsDist(Lat1, Lon1, Lat2, Lon2, EARTH_EQUATORIAL_RADIUS, EARTH_FLATTENING);
+ end;
+
+ case AUnits of
+ duMeters: ;
+ duKilometers: Result := Result * 0.001;
+ duMiles: Result := Result * 0.62137E-3;
+ end;
+end;
+
+{ Calculate initial bearing (in °) from the start point Lat1,Lon1 to
+ the end point Lat2,Lon2. No parameter checks, result normalized to 0°..360°.
+}
+function CalcBearing(Lat1, Lon1, Lat2, Lon2: Double): Double;
+var
+ latFrom, latTo, lonDiff: Double;
+begin
+ lonDiff := DegToRad(Lon2 - Lon1);
+ latFrom := DegToRad(Lat1);
+ latTo := DegToRad(Lat2);
+ Result := ArcTan2(Sin(lonDiff) * Cos(latTo),
+ Cos(latFrom) * Sin(latTo) - Sin(latFrom) * Cos(latTo) * Cos(lonDiff));
+ Result := RadToDeg(Result);
+ if Result < 0.0 then
+ Result := Result + 360.0;
+end;
+
+{ Calculate end point Lat2,Lon2 by given start point Lat1,Lon1, distance
+ ADist (in meters) and bearing ABearing (in °). No parameter checks,
+ result Lon2 normalized to -180°..180°.
+}
+procedure CalcLatLon(const Lat1, Lon1, ADist, ABearing: Double; out Lat2,
+ Lon2: Double);
+var
+ latFrom, lonFrom, brng, aD: Double;
+begin
+ latFrom := DegToRad(Lat1);
+ lonFrom := DegToRad(Lon1);
+ brng := DegToRad(ABearing);
+ 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),
+ Cos(aD) - Sin(latFrom) * Sin(Lat2));
+ Lat2 := RadToDeg(Lat2);
+ Lon2 := NormalizeLon(RadToDeg(Lon2));
+end;
+
+{ Calculate midpoint Lat,Lon by given start point Lat1,Lon1 and end point
+ Lat2,Lon2. No parameter checks, result Lon normalized to -180°..180°.
+}
+procedure CalcMidpoint(const Lat1, Lon1, Lat2, Lon2: Double; out Lat,
+ Lon: Double);
+var
+ latFrom, lonDiff, latTo, lonTo, Bx, By: Double;
+begin
+ lonDiff := DegToRad(Lon2 - Lon1);
+ latFrom := DegToRad(Lat1);
+ latTo := DegToRad(Lat2);
+ lonTo := DegToRad(Lon2);
+ Bx := Cos(latTo) * Cos(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);
+ Lat := RadToDeg(Lat);
+ Lon := NormalizeLon(RadToDeg(Lon));
+end;
+
+{ Calculate intermediate point Lat,Lon by given start point Lat1,Lon1, end point
+ Lat2,Lon2 and fraction AFrac (0.0-1.0). No parameter checks for
+ Lat1,Lon1,Lat2 and Lon2. Result Lon normalized to -180°..180°.
+}
+procedure CalcIntermedPoint(const Lat1, Lon1, Lat2, Lon2, AFrac: Double; out
+ Lat, Lon: Double);
+var
+ latFrom, lonFrom, latTo, lonTo: Double;
+ A, B, aD, X, Y, Z: Double;
+begin
+ if (Lat1 = Lat2) and (Lon1 = Lon2) or (AFrac < 0.001) then
+ begin
+ Lat := Lat1;
+ Lon := Lon1;
+ Exit;
+ end;
+ if AFrac > 0.999 then
+ begin
+ Lat := Lat2;
+ Lon := Lon2;
+ Exit;
+ end;
+ aD := CalcGeoDistance(Lat1, Lon1, Lat2, Lon2) / EARTH_EQUATORIAL_RADIUS;
+ latFrom := DegToRad(Lat1);
+ lonFrom := DegToRad(Lon1);
+ latTo := DegToRad(Lat2);
+ lonTo := DegToRad(Lon2);
+ A := Sin((1.0 - AFrac) * aD) / Sin(aD);
+ B := Sin(AFrac * aD) / Sin(aD);
+ X := A * Cos(latFrom) * Cos(lonFrom) + B * Cos(latTo) * Cos(lonTo);
+ Y := A * Cos(latFrom) * Sin(lonFrom) + B * Cos(latTo) * Sin(lonTo);
+ Z := A * Sin(latFrom) + B * Sin(latTo);
+ Lat := ArcTan2(Z, Sqrt(Sqr(X) + Sqr(Y)));
+ Lon := ArcTan2(Y, X);
+ Lat := RadToDeg(Lat);
+ Lon := NormalizeLon(RadToDeg(Lon));
+end;
+
+function NormalizeLon(const Lon: Double): Double;
+begin
+ if InRange(Lon, -180.0, 180.0)
+ then Result := Lon
+ else Result := FMod(Lon + 540.0, 360.0) - 180.0;
+end;
+
+{ Converts an angle given as degrees, minutes and seconds to a single
+ floating point degrees value. }
+function DMSToDeg(Deg, Min: Word; Sec: Double): Double;
+begin
+ Result := Deg + Min/60.0 + Sec/3600.0;
+end;
+
+procedure SplitGps(AValue: Double; out ADegs, AMins: Double);
+begin
+ AValue := abs(AValue);
+ AMins := frac(AValue) * 60;
+ if abs(AMins - 60) < 1E-3 then
+ begin
+ AMins := 0;
+ ADegs := trunc(AValue) + 1;
+ end else
+ ADegs := trunc(AValue);
+ if AValue < 0 then
+ ADegs := -ADegs;
+end;
+
+procedure SplitGps(AValue: Double; out ADegs, AMins, ASecs: Double);
+begin
+ SplitGps(AValue, ADegs, AMins);
+ ASecs := frac(AMins) * 60;
+ AMins := trunc(AMins);
+ if abs(ASecs - 60) < 1E-3 then
+ begin
+ ASecs := 0;
+ AMins := AMins + 1;
+ if abs(AMins - 60) < 1e-3 then
+ begin
+ AMins := 0;
+ ADegs := ADegs + 1;
+ end;
+ end;
+ if AValue < 0 then
+ ADegs := -ADegs;
+end;
+
+function GPSToDMS(Angle: Double): string;
+begin
+ Result := GPSToDMS(Angle, DefaultFormatSettings);
+end;
+
+function GPSToDMS(Angle: Double; AFormatSettings: TFormatSettings): string;
+var
+ deg, min, sec: Double;
+begin
+ SplitGPS(Angle, deg, min, sec);
+ Result := Format('%.0f° %.0f'' %.*f"', [deg, min, DMS_Decimals, sec], AFormatSettings);
+end;
+
+function LatToStr(ALatitude: Double; DMS: Boolean): String;
+begin
+ Result := LatToStr(ALatitude, DMS, DefaultFormatSettings);
+end;
+
+function LatToStr(ALatitude: Double; DMS: Boolean; AFormatSettings: TFormatSettings): String;
+begin
+ if DMS then
+ Result := GPSToDMS(abs(ALatitude), AFormatSettings)
+ else
+ Result := Format('%.6f°',[abs(ALatitude)], AFormatSettings);
+ if ALatitude > 0 then
+ Result := Result + ' N'
+ else
+ if ALatitude < 0 then
+ Result := Result + ' S';
+end;
+
+function LonToStr(ALongitude: Double; DMS: Boolean): String;
+begin
+ Result := LonToStr(ALongitude, DMS, DefaultFormatSettings);
+end;
+
+function LonToStr(ALongitude: Double; DMS: Boolean; AFormatSettings: TFormatSettings): String;
+begin
+ if DMS then
+ Result := GPSToDMS(abs(ALongitude), AFormatSettings)
+ else
+ Result := Format('%.6f°', [abs(ALongitude)], AFormatSettings);
+ if ALongitude > 0 then
+ Result := Result + ' E'
+ else if ALongitude < 0 then
+ Result := Result + ' W';
+end;
+
+{ Combines up to three parts of a GPS coordinate string (degrees, minutes, seconds)
+ to a floating-point degree value. The parts are separated by non-numeric
+ characters:
+
+ three parts ---> d m s ---> d and m must be integer, s can be float
+ two parts ---> d m ---> d must be integer, s can be float
+ one part ---> d ---> d can be float
+
+ Each part can exhibit a unit identifier, such as °, ', or ". BUT: they are
+ ignored. This means that an input string 50°30" results in the output value 50.5
+ although the second part is marked as seconds, not minutes!
+
+ Hemisphere suffixes ('N', 'S', 'E', 'W') are supported at the end of the input string.
+}
+function TryStrToGps(const AValue: String; out ADeg: Double): Boolean;
+const
+ NUMERIC_CHARS = ['0'..'9', '.', ',', '-', '+'];
+var
+ mins, secs: Double;
+ i, j, len: Integer;
+ n: Integer;
+ s: String = '';
+ res: Integer;
+ sgn: Double;
+begin
+ Result := false;
+
+ ADeg := NaN;
+ mins := 0;
+ secs := 0;
+
+ if AValue = '' then
+ exit;
+
+ len := Length(AValue);
+ i := len;
+ while (i >= 1) and (AValue[i] = ' ') do dec(i);
+ sgn := 1.0;
+ if (AValue[i] in ['S', 's', 'W', 'w']) then sgn := -1;
+
+ // skip leading non-numeric characters
+ i := 1;
+ while (i <= len) and not (AValue[i] in NUMERIC_CHARS) do
+ inc(i);
+
+ // extract first value: degrees
+ SetLength(s, len);
+ j := 1;
+ n := 0;
+ while (i <= len) and (AValue[i] in NUMERIC_CHARS) do begin
+ if AValue[i] = ',' then s[j] := '.' else s[j] := AValue[i];
+ inc(i);
+ inc(j);
+ inc(n);
+ end;
+ if n > 0 then begin
+ SetLength(s, n);
+ val(s, ADeg, res);
+ if res <> 0 then
+ exit;
+ end;
+
+ // skip non-numeric characters between degrees and minutes
+ while (i <= len) and not (AValue[i] in NUMERIC_CHARS) do
+ inc(i);
+
+ // extract second value: minutes
+ SetLength(s, len);
+ j := 1;
+ n := 0;
+ while (i <= len) and (AValue[i] in NUMERIC_CHARS) do begin
+ if AValue[i] = ',' then s[j] := '.' else s[j] := AValue[i];
+ inc(i);
+ inc(j);
+ inc(n);
+ end;
+ if n > 0 then begin
+ SetLength(s, n);
+ val(s, mins, res);
+ if (res <> 0) or (mins < 0) then
+ exit;
+ end;
+
+ // skip non-numeric characters between minutes and seconds
+ while (i <= len) and not (AValue[i] in NUMERIC_CHARS) do
+ inc(i);
+
+ // extract third value: seconds
+ SetLength(s, len);
+ j := 1;
+ n := 0;
+ while (i <= len) and (AValue[i] in NUMERIC_CHARS) do begin
+ if AValue[i] = ',' then s[j] := '.' else s[j] := AValue[i];
+ inc(i);
+ inc(j);
+ inc(n);
+ end;
+ if n > 0 then begin
+ SetLength(s, n);
+ val(s, secs, res);
+ if (res <> 0) or (secs < 0) then
+ exit;
+ end;
+
+ // If the string contains seconds then minutes and deegrees must be integers
+ if (secs <> 0) and ((frac(ADeg) > 0) or (frac(mins) > 0)) then
+ exit;
+ // If the string does not contain seconds then degrees must be integer.
+ if (secs = 0) and (mins <> 0) and (frac(ADeg) > 0) then
+ exit;
+
+ // If the string contains minutes, but no seconds, then the degrees must be integer.
+ Result := (mins >= 0) and (mins < 60) and (secs >= 0) and (secs < 60);
+
+ // A similar check should be made for the degrees range, but since this is
+ // different for latitude and longitude the check is skipped here.
+ if Result then
+ ADeg := sgn * (abs(ADeg) + mins / 60 + secs / 3600);
+end;
+
+{ Convert Lat/Lon string to degrees.
+
+ Recognized formats:
+
+ Degrees, Minutes and Seconds:
+ DDD°MM'SS.S"
+ 32°18'23.1"N 122°36'52.5"W
+
+ Degrees and Decimal Minutes:
+ DDD° MM.MMM'
+ 32°18.385'N 122°36.875'W
+
+ Decimal Degrees:
+ DDD.DDDDD°
+ 32.30642°N 122.61458°W
+ +32.30642 -122.61458
+}
+function TryStrDMSToDeg(const AValue: String; out ADeg: Double): Boolean;
+const
+ NUMERIC_CHARS = ['0'..'9', '.', ',', '-', '+'];
+ WS_CHARS = [' '];
+var
+ I, Len, N: Integer;
+ S: String;
+ D, Minutes, Seconds: Double;
+ R: Word;
+ Last, Neg: Boolean;
+
+ function EOL: Boolean; inline;
+ begin
+ Result := Len < I;
+ end;
+
+ procedure SkipWS; inline;
+ begin
+ while not EOL and (AValue[I] in WS_CHARS) do
+ Inc(I);
+ end;
+
+ function NextNum: String;
+ begin
+ Result := '';
+ SkipWS;
+ while not EOL and (AValue[I] in NUMERIC_CHARS) do
+ begin
+ if AValue[I] = ','
+ then Result := Result + '.'
+ else Result := Result + AValue[I];
+ Inc(I);
+ end;
+ end;
+
+begin
+ Result := False;
+ ADeg := NaN;
+ Len := Length(AValue);
+ I := 1;
+
+ // Degrees
+ S := NextNum;
+ if S = '' then
+ Exit;
+ Val(S, ADeg, R);
+ if R > 0 then
+ Exit;
+
+ // It must be the only part if negative or fractional
+ Neg := ADeg < 0.0;
+ Last := Neg or (Frac(ADeg) > 0.0);
+
+ // Eat the degree symbol if present
+ if not EOL and (Utf8CodePointLen(@AValue[I], 2, False) = 2)
+ and (AValue[I] = #$c2) and (AValue[I + 1] = #$b0)
+ then
+ Inc(I, 2);
+
+ Minutes := 0.0;
+ Seconds := 0.0;
+
+ N := 1;
+ while not (EOL or Last) and (N < 3) do
+ begin
+ S := NextNum;
+ if S = '' then
+ Break
+ else
+ begin
+ Val(S, D, R);
+ // Invalid part or negative one
+ if (R > 0) or (D < 0.0) then
+ Exit;
+ // No more parts when fractional
+ Last := Frac(D) > 0.0;
+ if not EOL then
+ case AValue[I] of
+ '''': // Munutes suffix
+ begin
+ Minutes := D;
+ Inc(I); // Eat the '
+ end;
+ '"': // Seconds suffix
+ begin
+ Seconds := D;
+ Last := True; // Last part
+ Inc(I); // Eat the "
+ end;
+ otherwise
+ if N = 1
+ then Minutes := D
+ else Seconds := D;
+ end;
+ end;
+ Inc(N);
+ end;
+
+ // Merge parts
+ ADeg := ADeg + Minutes / 60 + Seconds / 3600;
+
+ // Check for N-S and E-W designators
+ SkipWS;
+ if not (EOL or Neg) and (AValue[I] in ['S', 's', 'W', 'w', 'N', 'n', 'E', 'e']) then
+ begin
+ if AValue[I] in ['S', 's', 'W', 'w']
+ then ADeg := -1 * ADeg;
+ Inc(I);
+ end;
+ SkipWS;
+
+ // It must be entirely consumed
+ Result := EOL;
+end;
+
+
+end.
+
diff --git a/components/lazmapviewer/source/mvgpsobj.pas b/components/lazmapviewer/source/mvgpsobj.pas
index b9068ee2f..a7850ab06 100644
--- a/components/lazmapviewer/source/mvgpsobj.pas
+++ b/components/lazmapviewer/source/mvgpsobj.pas
@@ -16,7 +16,8 @@ unit mvGpsObj;
interface
uses
- Classes, SysUtils, Graphics, fgl, mvtypes, contnrs, syncobjs;
+ Classes, SysUtils, Graphics, fgl, contnrs, syncobjs,
+ mvTypes, mvGeoMath;
const
NO_ELE = -10000000;
@@ -1013,6 +1014,21 @@ begin
Result := FDateTime <> NO_DATE;
end;
+function TGPSPoint.DistanceInKmFrom(OtherPt: TGPSPoint;
+ UseElevation: Boolean = true): Double;
+var
+ lat1, lon1, lat2, lon2: Double;
+ dElev: Double;
+begin
+ Result := CalcGeoDistance(Lat, Lon, OtherPt.Lat, OtherPt.Lon, duKilometers, esEllipsoid);
+ if UseElevation and HasElevation and OtherPt.HasElevation and (FElevation <> OtherPt.Elevation) then
+ begin
+ dElev := (FElevation - OtherPt.Elevation) * 0.001; // Elevation is given in meters
+ Result := sqrt(sqr(dElev) + sqr(Result));
+ end;
+end;
+
+(*
function TGPSPoint.DistanceInKmFrom(OtherPt: TGPSPoint;
UseElevation: boolean = true): double;
var
@@ -1031,7 +1047,13 @@ begin
t3 := cos(lon1 - lon2);
t4 := t2 * t3;
t5 := t1 + t4;
- rad_dist := arctan(-t5/sqrt(-t5 * t5 +1)) + 2 * arctan(1);
+ if t5 >= 1.0 then
+ rad_dist := 0.0
+ else
+ if t5 <= 1.0 then
+ rad_dist := pi
+ else
+ rad_dist := arctan(-t5/sqrt(-t5 * t5 + 1)) + 2 * arctan(1);
result := (rad_dist * 3437.74677 * 1.1508) * 1.6093470878864446;
if UseElevation and (FElevation <> OtherPt.FElevation) then
if (HasElevation) and (OtherPt.HasElevation) then
@@ -1041,6 +1063,7 @@ begin
Result := sqrt(DiffEle*DiffEle + result*result);
end;
end;
+*)
procedure TGPSPoint.MoveTo(ALon, ALat: Double; AElevation: double = NO_ELE;
ADateTime: TDateTime = NO_DATE);
diff --git a/components/lazmapviewer/source/mvmapviewer.pas b/components/lazmapviewer/source/mvmapviewer.pas
index c04fda1a1..5b0290eee 100644
--- a/components/lazmapviewer/source/mvmapviewer.pas
+++ b/components/lazmapviewer/source/mvmapviewer.pas
@@ -29,8 +29,8 @@ interface
uses
Classes, SysUtils, Controls, GraphType, Graphics, FPImage, IntfGraphics,
Forms, ImgList, LCLVersion, fgl,
- MvTypes, MvGPSObj, MvEngine, MvMapProvider, MvDownloadEngine, MvDrawingEngine,
- mvCache, mvExtraData;
+ MvTypes, MvGeoMath, MvGPSObj, MvCache, MvExtraData, MvEngine, MvMapProvider,
+ MvDownloadEngine, MvDrawingEngine;
Type
diff --git a/components/lazmapviewer/source/mvmapviewerpropedits.pas b/components/lazmapviewer/source/mvmapviewerpropedits.pas
index 064996e99..a760a32e1 100644
--- a/components/lazmapviewer/source/mvmapviewerpropedits.pas
+++ b/components/lazmapviewer/source/mvmapviewerpropedits.pas
@@ -78,8 +78,9 @@ procedure Register;
implementation
uses
- Dialogs, IDEWindowIntf, mvMapViewer, mvGpsObj, mvLayersPropEditForm, mvEngine,
- StrUtils;
+ Dialogs, IDEWindowIntf,
+ StrUtils,
+ mvGeoMath, mvMapViewer, mvGpsObj, mvLayersPropEditForm, mvEngine;
const
NONE = '(none)';
diff --git a/components/lazmapviewer/source/mvtypes.pas b/components/lazmapviewer/source/mvtypes.pas
index d492a2da6..aa65e99d9 100644
--- a/components/lazmapviewer/source/mvtypes.pas
+++ b/components/lazmapviewer/source/mvtypes.pas
@@ -63,6 +63,8 @@ Type
function Union(const Area: TRealArea): TRealArea;
end;
+function RealPoint(Lat, Lon: Double): TRealPoint;
+
implementation
@@ -276,6 +278,12 @@ begin
Self.Lat := RadToDeg(AValue);
end;
+function RealPoint(Lat, Lon: Double): TRealPoint;
+begin
+ Result.Lon := Lon;
+ Result.Lat := Lat;
+end;
+
{ TRealArea
diff --git a/components/lazmapviewer/unittests/mapviewer_tests.lpi b/components/lazmapviewer/unittests/mapviewer_tests.lpi
index d1052f947..781bf4388 100644
--- a/components/lazmapviewer/unittests/mapviewer_tests.lpi
+++ b/components/lazmapviewer/unittests/mapviewer_tests.lpi
@@ -8,7 +8,6 @@
-
@@ -41,7 +40,7 @@
-
+
diff --git a/components/lazmapviewer/unittests/mapviewer_tests.lpr b/components/lazmapviewer/unittests/mapviewer_tests.lpr
index 7f9e335e4..76a6ee5a2 100644
--- a/components/lazmapviewer/unittests/mapviewer_tests.lpr
+++ b/components/lazmapviewer/unittests/mapviewer_tests.lpr
@@ -4,7 +4,7 @@ program mapviewer_tests;
uses
Interfaces, Forms, GuiTestRunner,
- mvtests_engine, mvtests_types;
+ mvtests_geomath, mvtests_types;
{$R *.res}
diff --git a/components/lazmapviewer/unittests/mvtests_engine.pas b/components/lazmapviewer/unittests/mvtests_geomath.pas
similarity index 94%
rename from components/lazmapviewer/unittests/mvtests_engine.pas
rename to components/lazmapviewer/unittests/mvtests_geomath.pas
index 63b84ea27..9b0a30523 100644
--- a/components/lazmapviewer/unittests/mvtests_engine.pas
+++ b/components/lazmapviewer/unittests/mvtests_geomath.pas
@@ -1,4 +1,4 @@
-unit mvtests_engine;
+unit mvtests_geomath;
{$mode objfpc}{$H+}
@@ -8,7 +8,7 @@ uses
Classes, SysUtils, fpcunit, testutils, testregistry;
type
- TMvTests_Engine= class(TTestCase)
+ TMvTests_GeoMath = class(TTestCase)
published
procedure Test_Distance;
procedure Test_LatToStr_DMS;
@@ -22,7 +22,7 @@ type
implementation
uses
- Math, mvEngine;
+ Math, mvGeoMath;
type
TDistanceRec = record
@@ -94,7 +94,7 @@ const
var
PointFormatsettings: TFormatSettings;
-procedure TMvTests_Engine.Test_Distance;
+procedure TMvTests_GeoMath.Test_Distance;
const
TOLERANCE = 2;
RADIUS = 6378; // Earth radius in km, as used by the references
@@ -110,7 +110,7 @@ begin
);
end;
-procedure TMvTests_Engine.Test_LatToStr_Deg;
+procedure TMvTests_GeoMath.Test_LatToStr_Deg;
const
NO_DMS = false;
var
@@ -125,7 +125,7 @@ begin
);
end;
-procedure TMvTests_Engine.Test_LatToStr_DMS;
+procedure TMvTests_GeoMath.Test_LatToStr_DMS;
const
NEED_DMS = true;
var
@@ -140,7 +140,7 @@ begin
);
end;
-procedure TMvTests_Engine.Test_LonToStr_Deg;
+procedure TMvTests_GeoMath.Test_LonToStr_Deg;
const
NO_DMS = false;
var
@@ -155,7 +155,7 @@ begin
);
end;
-procedure TMvTests_Engine.Test_LonToStr_DMS;
+procedure TMvTests_GeoMath.Test_LonToStr_DMS;
const
NEED_DMS = true;
var
@@ -170,7 +170,7 @@ begin
);
end;
-procedure TMvTests_Engine.Test_SplitGPS;
+procedure TMvTests_GeoMath.Test_SplitGPS;
const
TOLERANCE = 1e-5;
var
@@ -218,7 +218,7 @@ begin
end;
end;
-procedure TMvTests_Engine.Test_ZoomFactor;
+procedure TMvTests_GeoMath.Test_ZoomFactor;
var
z: Integer;
f: Extended;
@@ -236,6 +236,6 @@ initialization
PointFormatSettings.DecimalSeparator := '.';
DMS_Decimals := 4;
- RegisterTest(TMvTests_Engine);
+ RegisterTest(TMvTests_GeoMath);
end.
diff --git a/components/lazmapviewer/unittests/mvtests_types.pas b/components/lazmapviewer/unittests/mvtests_types.pas
index 7a5841f00..64b00838a 100644
--- a/components/lazmapviewer/unittests/mvtests_types.pas
+++ b/components/lazmapviewer/unittests/mvtests_types.pas
@@ -9,7 +9,7 @@ uses
type
- TMvTestsArea= class(TTestCase)
+ TMvTests_Area= class(TTestCase)
published
procedure Test_PointInArea;
procedure Test_Intersection;
@@ -28,7 +28,7 @@ begin
]);
end;
-procedure TMvTestsArea.Test_PointInArea;
+procedure TMvTests_Area.Test_PointInArea;
var
counter: Integer;
a: TRealArea;
@@ -123,7 +123,7 @@ begin
);
end;
-procedure TMvTestsArea.Test_Union;
+procedure TMvTests_Area.Test_Union;
var
counter: Integer;
a, b, expected, actual: TRealArea;
@@ -298,7 +298,7 @@ begin
);
end;
-procedure TMvTestsArea.Test_Intersection;
+procedure TMvTests_Area.Test_Intersection;
var
counter: Integer;
a, b, expected, actual: TRealArea;
@@ -430,7 +430,7 @@ end;
initialization
- RegisterTest(TMvTestsArea);
+ RegisterTest(TMvTests_Area);
end.