LazMapViewer: Remove duplicate distance calculation in TGPSPoint. Had to move some general-purpose geo-math routines to a new units mvGeoMath. Old functions kept in mvEngine, but marked as deprecated.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9337 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
e545177bc3
commit
93167ada8b
@ -7,8 +7,8 @@ interface
|
|||||||
uses
|
uses
|
||||||
Classes, SysUtils, LazFileUtils,
|
Classes, SysUtils, LazFileUtils,
|
||||||
LCLIntf, Forms, Controls, Graphics, Dialogs, StdCtrls,
|
LCLIntf, Forms, Controls, Graphics, Dialogs, StdCtrls,
|
||||||
ExtCtrls, Grids, Buttons, mvMapViewer, mvTypes, mvEngine, Types, mvGpsObj,
|
ExtCtrls, Grids, Buttons, Types,
|
||||||
mvDrawingEngine;
|
mvMapViewer, mvTypes, mvGeoMath, mvEngine, mvGpsObj, mvDrawingEngine;
|
||||||
|
|
||||||
type
|
type
|
||||||
{ TMainForm }
|
{ TMainForm }
|
||||||
|
@ -6,9 +6,10 @@ object MainForm: TMainForm
|
|||||||
Caption = 'Flights - LazMapViewer'
|
Caption = 'Flights - LazMapViewer'
|
||||||
ClientHeight = 662
|
ClientHeight = 662
|
||||||
ClientWidth = 942
|
ClientWidth = 942
|
||||||
|
ShowHint = True
|
||||||
|
LCLVersion = '3.99.0.0'
|
||||||
OnCreate = FormCreate
|
OnCreate = FormCreate
|
||||||
OnDestroy = FormDestroy
|
OnDestroy = FormDestroy
|
||||||
ShowHint = True
|
|
||||||
object MapView: TMapView
|
object MapView: TMapView
|
||||||
Left = 0
|
Left = 0
|
||||||
Height = 662
|
Height = 662
|
||||||
@ -27823,192 +27824,33 @@ object MainForm: TMainForm
|
|||||||
MapCenter.Longitude = -87.9081388888889
|
MapCenter.Longitude = -87.9081388888889
|
||||||
MapCenter.Latitude = 41.9769444444444
|
MapCenter.Latitude = 41.9769444444444
|
||||||
POIImage.Data = {
|
POIImage.Data = {
|
||||||
36170000424D36170000000000003600000028000000200000002E0000000100
|
4503000089504E470D0A1A0A0000000D49484452000000200000002E08060000
|
||||||
2000000000000017000064000000640000000000000000000000FFFFFF00FFFF
|
0049701B840000030C49444154789CB5983B68145114867F4410C54644B0107C
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
152262A7A4D2C2DA3422DAD8D868631510B1D1688855409104A2088634819056
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FD560000FC4CFFFF
|
B00C488845626C82C55662A29204C40DC96ED66CD6F38F77976B76E6DCC7CC14
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
077667CEF9FFEF3EE6CC03AD560B3EB1021C6C023777805189598955892D13AB
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
E6D8287398EBABEB4CA803A745F895C47A92EE11CC650D6BA3012AC03E1119E4
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
087D8D5340383B83D40A0210F29352381F6B9C02F2899A5E000DE09C142C1765
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000F1110000FEE70000FEE10000
|
6E412C535B05A801C72571A968730B62891EA90066CDE7CA32B720E6EC3DD101
|
||||||
EA0CFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
901303012215893772C93D62F0378F05D40FFC07201BE4841CAC7B147EF8035C
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
CADAD13CC71C0F9D3A3D3B007260C451B023237DDC0FEC715DD7CC612E6B1C9A
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
2309C077E080FCA96AC99C66DFCED68EA44607A8D21BDBC03547E2B4CFC8D366
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FE9A0000FFFF0000FFFF0000
|
82B59A36BD39FDC35A92AC6B4FA8B9B5277A1C831B26C08C92B0186B6E5D5D8B
|
||||||
FE8FFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
8AFE0C137EBA364A4E80CC0D4E6F26D494CD773F2F40A2910D5023404301E82B
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
00A04F016810604D49182A60098614FD3568B7DD6483E607D036F93C13C69484
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
A6CF534D5698A7A9A6A23FC635BAEDB856C7738C7E5CD3A637D68123DA46644F
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF000000FB3E0000FEFE0000FFFF0000FFFF0000
|
978E753DD49C35DAFD809EF46E934E39666153047B03CC7B59E3D09C6AFDFB97
|
||||||
FEFC0000FB35FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
B4CC0B1E77AFA6C4CB2A7038CB98E798A3AD7B7B56E9D90130B330A115D9CD43
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
E29DC41359C3BB0CFE36C7329BDA2E8D89B66F07600B38E3222F22CC9575AA0B
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
C0CCC2D3B20164C61EDA9E5DEB28100B258EFEE36EBF2E00D33C9CCF8711E61B
|
||||||
FF00FFFFFF00FFFFFF000000DB070000FED70000FFFF0000FFFF0000FFFF0000
|
9BC0312780B9813C2861EAEFA579A5024C037B85F87381A39FCD7AAC4B0530BD
|
||||||
FFFF0000FECF0000C004FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
E1A2146E1760DE9057B2F3593E99006643BE2800E099E6A102F04383087CCD61
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
5EF906EC8F06307DFD6AA4396F62575CFA4E00B3149311006F7DB4BD003680A3
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
22F82BC07C45BB69050398DE7027E09ABFE5ABEB0D605EB57CDE7CDFFB6A0601
|
||||||
FF00FFFFFF00FFFFFF000000FE800000FFFF0000FFFF0000FFFF0000FFFF0000
|
30E48E7956FB68C5769BF52DA81000B321FB95A90F7E910906309F72BEA48C7E
|
||||||
FFFF0000FFFF0000FD75FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
812DBC740086B4E9CBF6231C5B365B778C561480598AD716C0F3589D6880DFC0
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
2131FEC1561DF26DB83000866CBA1B49ABCEA1F117D2B9A057721AC774000000
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
0049454E44AE426082
|
||||||
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
|
|
||||||
}
|
}
|
||||||
POIImages = ilPOIs
|
POIImages = ilPOIs
|
||||||
POIImagesWidth = 32
|
POIImagesWidth = 32
|
||||||
@ -28031,8 +27873,8 @@ object MainForm: TMainForm
|
|||||||
TabOrder = 1
|
TabOrder = 1
|
||||||
object PgData: TTabSheet
|
object PgData: TTabSheet
|
||||||
Caption = 'Tracking'
|
Caption = 'Tracking'
|
||||||
ClientHeight = 627
|
ClientHeight = 634
|
||||||
ClientWidth = 312
|
ClientWidth = 310
|
||||||
object ZoomTrackBar: TTrackBar
|
object ZoomTrackBar: TTrackBar
|
||||||
AnchorSideLeft.Control = PgData
|
AnchorSideLeft.Control = PgData
|
||||||
AnchorSideTop.Control = LblZoom
|
AnchorSideTop.Control = LblZoom
|
||||||
@ -28041,12 +27883,12 @@ object MainForm: TMainForm
|
|||||||
AnchorSideRight.Side = asrBottom
|
AnchorSideRight.Side = asrBottom
|
||||||
Left = 2
|
Left = 2
|
||||||
Height = 40
|
Height = 40
|
||||||
Top = 23
|
Top = 21
|
||||||
Width = 308
|
Width = 306
|
||||||
Min = 1
|
Min = 1
|
||||||
OnChange = ZoomTrackBarChange
|
|
||||||
Position = 4
|
Position = 4
|
||||||
TickMarks = tmBoth
|
TickMarks = tmBoth
|
||||||
|
OnChange = ZoomTrackBarChange
|
||||||
Anchors = [akTop, akLeft, akRight]
|
Anchors = [akTop, akLeft, akRight]
|
||||||
BorderSpacing.Left = 2
|
BorderSpacing.Left = 2
|
||||||
BorderSpacing.Right = 2
|
BorderSpacing.Right = 2
|
||||||
@ -28056,9 +27898,9 @@ object MainForm: TMainForm
|
|||||||
AnchorSideLeft.Control = PgData
|
AnchorSideLeft.Control = PgData
|
||||||
AnchorSideTop.Control = PgData
|
AnchorSideTop.Control = PgData
|
||||||
Left = 6
|
Left = 6
|
||||||
Height = 17
|
Height = 15
|
||||||
Top = 6
|
Top = 6
|
||||||
Width = 43
|
Width = 35
|
||||||
BorderSpacing.Left = 6
|
BorderSpacing.Left = 6
|
||||||
BorderSpacing.Top = 6
|
BorderSpacing.Top = 6
|
||||||
Caption = 'Zoom:'
|
Caption = 'Zoom:'
|
||||||
@ -28071,9 +27913,9 @@ object MainForm: TMainForm
|
|||||||
AnchorSideRight.Control = PgData
|
AnchorSideRight.Control = PgData
|
||||||
AnchorSideRight.Side = asrBottom
|
AnchorSideRight.Side = asrBottom
|
||||||
Left = 6
|
Left = 6
|
||||||
Height = 73
|
Height = 70
|
||||||
Top = 71
|
Top = 69
|
||||||
Width = 300
|
Width = 298
|
||||||
Anchors = [akTop, akLeft, akRight]
|
Anchors = [akTop, akLeft, akRight]
|
||||||
AutoSize = True
|
AutoSize = True
|
||||||
BorderSpacing.Left = 6
|
BorderSpacing.Left = 6
|
||||||
@ -28081,17 +27923,17 @@ object MainForm: TMainForm
|
|||||||
BorderSpacing.Right = 6
|
BorderSpacing.Right = 6
|
||||||
BorderSpacing.InnerBorder = 4
|
BorderSpacing.InnerBorder = 4
|
||||||
Caption = 'Mouse position'
|
Caption = 'Mouse position'
|
||||||
ClientHeight = 54
|
ClientHeight = 50
|
||||||
ClientWidth = 296
|
ClientWidth = 294
|
||||||
TabOrder = 1
|
TabOrder = 1
|
||||||
object lblMouseLon: TLabel
|
object lblMouseLon: TLabel
|
||||||
AnchorSideLeft.Control = gbMouse
|
AnchorSideLeft.Control = gbMouse
|
||||||
AnchorSideTop.Control = lblMouseLat
|
AnchorSideTop.Control = lblMouseLat
|
||||||
AnchorSideTop.Side = asrBottom
|
AnchorSideTop.Side = asrBottom
|
||||||
Left = 8
|
Left = 8
|
||||||
Height = 17
|
Height = 15
|
||||||
Top = 29
|
Top = 27
|
||||||
Width = 68
|
Width = 54
|
||||||
BorderSpacing.Left = 8
|
BorderSpacing.Left = 8
|
||||||
BorderSpacing.Top = 4
|
BorderSpacing.Top = 4
|
||||||
Caption = 'Longitude'
|
Caption = 'Longitude'
|
||||||
@ -28101,9 +27943,9 @@ object MainForm: TMainForm
|
|||||||
AnchorSideLeft.Control = gbMouse
|
AnchorSideLeft.Control = gbMouse
|
||||||
AnchorSideTop.Control = gbMouse
|
AnchorSideTop.Control = gbMouse
|
||||||
Left = 8
|
Left = 8
|
||||||
Height = 17
|
Height = 15
|
||||||
Top = 4
|
Top = 4
|
||||||
Width = 57
|
Width = 43
|
||||||
BorderSpacing.Left = 8
|
BorderSpacing.Left = 8
|
||||||
BorderSpacing.Top = 4
|
BorderSpacing.Top = 4
|
||||||
BorderSpacing.Bottom = 8
|
BorderSpacing.Bottom = 8
|
||||||
@ -28116,10 +27958,10 @@ object MainForm: TMainForm
|
|||||||
AnchorSideTop.Side = asrBottom
|
AnchorSideTop.Side = asrBottom
|
||||||
AnchorSideRight.Control = gbMouse
|
AnchorSideRight.Control = gbMouse
|
||||||
AnchorSideRight.Side = asrBottom
|
AnchorSideRight.Side = asrBottom
|
||||||
Left = 235
|
Left = 244
|
||||||
Height = 17
|
Height = 15
|
||||||
Top = 29
|
Top = 27
|
||||||
Width = 45
|
Width = 34
|
||||||
Alignment = taRightJustify
|
Alignment = taRightJustify
|
||||||
Anchors = [akTop, akRight]
|
Anchors = [akTop, akRight]
|
||||||
BorderSpacing.Top = 4
|
BorderSpacing.Top = 4
|
||||||
@ -28132,10 +27974,10 @@ object MainForm: TMainForm
|
|||||||
AnchorSideTop.Control = gbMouse
|
AnchorSideTop.Control = gbMouse
|
||||||
AnchorSideRight.Control = gbMouse
|
AnchorSideRight.Control = gbMouse
|
||||||
AnchorSideRight.Side = asrBottom
|
AnchorSideRight.Side = asrBottom
|
||||||
Left = 235
|
Left = 244
|
||||||
Height = 17
|
Height = 15
|
||||||
Top = 4
|
Top = 4
|
||||||
Width = 45
|
Width = 34
|
||||||
Alignment = taRightJustify
|
Alignment = taRightJustify
|
||||||
Anchors = [akTop, akRight]
|
Anchors = [akTop, akRight]
|
||||||
BorderSpacing.Top = 4
|
BorderSpacing.Top = 4
|
||||||
@ -28152,25 +27994,25 @@ object MainForm: TMainForm
|
|||||||
AnchorSideRight.Control = gbMouse
|
AnchorSideRight.Control = gbMouse
|
||||||
AnchorSideRight.Side = asrBottom
|
AnchorSideRight.Side = asrBottom
|
||||||
Left = 6
|
Left = 6
|
||||||
Height = 73
|
Height = 70
|
||||||
Top = 152
|
Top = 147
|
||||||
Width = 300
|
Width = 298
|
||||||
Anchors = [akTop, akLeft, akRight]
|
Anchors = [akTop, akLeft, akRight]
|
||||||
AutoSize = True
|
AutoSize = True
|
||||||
BorderSpacing.Top = 8
|
BorderSpacing.Top = 8
|
||||||
BorderSpacing.InnerBorder = 4
|
BorderSpacing.InnerBorder = 4
|
||||||
Caption = 'Center'
|
Caption = 'Center'
|
||||||
ClientHeight = 54
|
ClientHeight = 50
|
||||||
ClientWidth = 296
|
ClientWidth = 294
|
||||||
TabOrder = 2
|
TabOrder = 2
|
||||||
object lblCenterLon: TLabel
|
object lblCenterLon: TLabel
|
||||||
AnchorSideLeft.Control = gbCenter
|
AnchorSideLeft.Control = gbCenter
|
||||||
AnchorSideTop.Control = lblCenterLat
|
AnchorSideTop.Control = lblCenterLat
|
||||||
AnchorSideTop.Side = asrBottom
|
AnchorSideTop.Side = asrBottom
|
||||||
Left = 8
|
Left = 8
|
||||||
Height = 17
|
Height = 15
|
||||||
Top = 29
|
Top = 27
|
||||||
Width = 68
|
Width = 54
|
||||||
BorderSpacing.Left = 8
|
BorderSpacing.Left = 8
|
||||||
BorderSpacing.Top = 4
|
BorderSpacing.Top = 4
|
||||||
Caption = 'Longitude'
|
Caption = 'Longitude'
|
||||||
@ -28180,9 +28022,9 @@ object MainForm: TMainForm
|
|||||||
AnchorSideLeft.Control = gbCenter
|
AnchorSideLeft.Control = gbCenter
|
||||||
AnchorSideTop.Control = gbCenter
|
AnchorSideTop.Control = gbCenter
|
||||||
Left = 8
|
Left = 8
|
||||||
Height = 17
|
Height = 15
|
||||||
Top = 4
|
Top = 4
|
||||||
Width = 57
|
Width = 43
|
||||||
BorderSpacing.Left = 8
|
BorderSpacing.Left = 8
|
||||||
BorderSpacing.Top = 4
|
BorderSpacing.Top = 4
|
||||||
BorderSpacing.Bottom = 8
|
BorderSpacing.Bottom = 8
|
||||||
@ -28195,10 +28037,10 @@ object MainForm: TMainForm
|
|||||||
AnchorSideTop.Side = asrBottom
|
AnchorSideTop.Side = asrBottom
|
||||||
AnchorSideRight.Control = gbCenter
|
AnchorSideRight.Control = gbCenter
|
||||||
AnchorSideRight.Side = asrBottom
|
AnchorSideRight.Side = asrBottom
|
||||||
Left = 235
|
Left = 244
|
||||||
Height = 17
|
Height = 15
|
||||||
Top = 29
|
Top = 27
|
||||||
Width = 45
|
Width = 34
|
||||||
Alignment = taRightJustify
|
Alignment = taRightJustify
|
||||||
Anchors = [akTop, akRight]
|
Anchors = [akTop, akRight]
|
||||||
BorderSpacing.Top = 4
|
BorderSpacing.Top = 4
|
||||||
@ -28211,10 +28053,10 @@ object MainForm: TMainForm
|
|||||||
AnchorSideTop.Control = gbCenter
|
AnchorSideTop.Control = gbCenter
|
||||||
AnchorSideRight.Control = gbCenter
|
AnchorSideRight.Control = gbCenter
|
||||||
AnchorSideRight.Side = asrBottom
|
AnchorSideRight.Side = asrBottom
|
||||||
Left = 235
|
Left = 244
|
||||||
Height = 17
|
Height = 15
|
||||||
Top = 4
|
Top = 4
|
||||||
Width = 45
|
Width = 34
|
||||||
Alignment = taRightJustify
|
Alignment = taRightJustify
|
||||||
Anchors = [akTop, akRight]
|
Anchors = [akTop, akRight]
|
||||||
BorderSpacing.Top = 4
|
BorderSpacing.Top = 4
|
||||||
@ -28230,9 +28072,9 @@ object MainForm: TMainForm
|
|||||||
AnchorSideRight.Side = asrBottom
|
AnchorSideRight.Side = asrBottom
|
||||||
AnchorSideBottom.Control = plInfo
|
AnchorSideBottom.Control = plInfo
|
||||||
Left = 6
|
Left = 6
|
||||||
Height = 231
|
Height = 246
|
||||||
Top = 233
|
Top = 225
|
||||||
Width = 298
|
Width = 296
|
||||||
Anchors = [akTop, akLeft, akRight, akBottom]
|
Anchors = [akTop, akLeft, akRight, akBottom]
|
||||||
AutoFillColumns = True
|
AutoFillColumns = True
|
||||||
BorderSpacing.Top = 8
|
BorderSpacing.Top = 8
|
||||||
@ -28248,12 +28090,12 @@ object MainForm: TMainForm
|
|||||||
item
|
item
|
||||||
Title.Alignment = taCenter
|
Title.Alignment = taCenter
|
||||||
Title.Caption = 'Latitude'
|
Title.Caption = 'Latitude'
|
||||||
Width = 105
|
Width = 111
|
||||||
end
|
end
|
||||||
item
|
item
|
||||||
Title.Alignment = taCenter
|
Title.Alignment = taCenter
|
||||||
Title.Caption = 'Longitude'
|
Title.Caption = 'Longitude'
|
||||||
Width = 106
|
Width = 111
|
||||||
end>
|
end>
|
||||||
FixedCols = 0
|
FixedCols = 0
|
||||||
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goRowSelect, goSmoothScroll]
|
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goRowSelect, goSmoothScroll]
|
||||||
@ -28262,8 +28104,8 @@ object MainForm: TMainForm
|
|||||||
OnDblClick = sgTracksDblClick
|
OnDblClick = sgTracksDblClick
|
||||||
ColWidths = (
|
ColWidths = (
|
||||||
70
|
70
|
||||||
105
|
111
|
||||||
106
|
111
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
object pnlFlightControl: TPanel
|
object pnlFlightControl: TPanel
|
||||||
@ -28274,8 +28116,8 @@ object MainForm: TMainForm
|
|||||||
AnchorSideBottom.Side = asrBottom
|
AnchorSideBottom.Side = asrBottom
|
||||||
Left = 0
|
Left = 0
|
||||||
Height = 50
|
Height = 50
|
||||||
Top = 577
|
Top = 584
|
||||||
Width = 312
|
Width = 310
|
||||||
Anchors = [akLeft, akRight, akBottom]
|
Anchors = [akLeft, akRight, akBottom]
|
||||||
BevelOuter = bvNone
|
BevelOuter = bvNone
|
||||||
ChildSizing.LeftRightSpacing = 5
|
ChildSizing.LeftRightSpacing = 5
|
||||||
@ -28288,13 +28130,13 @@ object MainForm: TMainForm
|
|||||||
ChildSizing.Layout = cclLeftToRightThenTopToBottom
|
ChildSizing.Layout = cclLeftToRightThenTopToBottom
|
||||||
ChildSizing.ControlsPerLine = 99
|
ChildSizing.ControlsPerLine = 99
|
||||||
ClientHeight = 50
|
ClientHeight = 50
|
||||||
ClientWidth = 312
|
ClientWidth = 310
|
||||||
TabOrder = 4
|
TabOrder = 4
|
||||||
object btnPlay: TSpeedButton
|
object btnPlay: TSpeedButton
|
||||||
Left = 5
|
Left = 5
|
||||||
Height = 40
|
Height = 40
|
||||||
Top = 5
|
Top = 5
|
||||||
Width = 65
|
Width = 66
|
||||||
Glyph.Data = {
|
Glyph.Data = {
|
||||||
36040000424D3604000000000000360000002800000010000000100000000100
|
36040000424D3604000000000000360000002800000010000000100000000100
|
||||||
2000000000000004000064000000640000000000000000000000000000000000
|
2000000000000004000064000000640000000000000000000000000000000000
|
||||||
@ -28334,10 +28176,10 @@ object MainForm: TMainForm
|
|||||||
OnClick = btnPlayClick
|
OnClick = btnPlayClick
|
||||||
end
|
end
|
||||||
object btnPause: TSpeedButton
|
object btnPause: TSpeedButton
|
||||||
Left = 75
|
Left = 76
|
||||||
Height = 40
|
Height = 40
|
||||||
Top = 5
|
Top = 5
|
||||||
Width = 65
|
Width = 66
|
||||||
Glyph.Data = {
|
Glyph.Data = {
|
||||||
36040000424D3604000000000000360000002800000010000000100000000100
|
36040000424D3604000000000000360000002800000010000000100000000100
|
||||||
2000000000000004000064000000640000000000000000000000000000000000
|
2000000000000004000064000000640000000000000000000000000000000000
|
||||||
@ -28377,10 +28219,10 @@ object MainForm: TMainForm
|
|||||||
OnClick = btnPauseClick
|
OnClick = btnPauseClick
|
||||||
end
|
end
|
||||||
object btnStop: TSpeedButton
|
object btnStop: TSpeedButton
|
||||||
Left = 145
|
Left = 147
|
||||||
Height = 40
|
Height = 40
|
||||||
Top = 5
|
Top = 5
|
||||||
Width = 65
|
Width = 67
|
||||||
Glyph.Data = {
|
Glyph.Data = {
|
||||||
36040000424D3604000000000000360000002800000010000000100000000100
|
36040000424D3604000000000000360000002800000010000000100000000100
|
||||||
2000000000000004000064000000640000000000000000000000000000000000
|
2000000000000004000064000000640000000000000000000000000000000000
|
||||||
@ -28420,10 +28262,10 @@ object MainForm: TMainForm
|
|||||||
OnClick = btnStopClick
|
OnClick = btnStopClick
|
||||||
end
|
end
|
||||||
object btnWarp: TSpeedButton
|
object btnWarp: TSpeedButton
|
||||||
Left = 215
|
Left = 219
|
||||||
Height = 40
|
Height = 40
|
||||||
Top = 5
|
Top = 5
|
||||||
Width = 92
|
Width = 86
|
||||||
Caption = 'Warp+'
|
Caption = 'Warp+'
|
||||||
OnClick = btnWarpClick
|
OnClick = btnWarpClick
|
||||||
end
|
end
|
||||||
@ -28433,8 +28275,8 @@ object MainForm: TMainForm
|
|||||||
AnchorSideBottom.Control = pnlFlightControl
|
AnchorSideBottom.Control = pnlFlightControl
|
||||||
Left = 6
|
Left = 6
|
||||||
Height = 33
|
Height = 33
|
||||||
Top = 536
|
Top = 543
|
||||||
Width = 298
|
Width = 296
|
||||||
Anchors = [akLeft, akRight, akBottom]
|
Anchors = [akLeft, akRight, akBottom]
|
||||||
BorderSpacing.Bottom = 8
|
BorderSpacing.Bottom = 8
|
||||||
TabOrder = 5
|
TabOrder = 5
|
||||||
@ -28446,11 +28288,11 @@ object MainForm: TMainForm
|
|||||||
AnchorSideBottom.Control = pnlWarpInfo
|
AnchorSideBottom.Control = pnlWarpInfo
|
||||||
Left = 6
|
Left = 6
|
||||||
Height = 72
|
Height = 72
|
||||||
Top = 464
|
Top = 471
|
||||||
Width = 298
|
Width = 296
|
||||||
Anchors = [akLeft, akRight, akBottom]
|
Anchors = [akLeft, akRight, akBottom]
|
||||||
ClientHeight = 72
|
ClientHeight = 72
|
||||||
ClientWidth = 298
|
ClientWidth = 296
|
||||||
Color = clCream
|
Color = clCream
|
||||||
ParentBackground = False
|
ParentBackground = False
|
||||||
ParentColor = False
|
ParentColor = False
|
||||||
@ -28459,7 +28301,7 @@ object MainForm: TMainForm
|
|||||||
Left = 6
|
Left = 6
|
||||||
Height = 60
|
Height = 60
|
||||||
Top = 6
|
Top = 6
|
||||||
Width = 286
|
Width = 284
|
||||||
Align = alClient
|
Align = alClient
|
||||||
AutoSize = False
|
AutoSize = False
|
||||||
BorderSpacing.Around = 5
|
BorderSpacing.Around = 5
|
||||||
@ -28473,16 +28315,16 @@ object MainForm: TMainForm
|
|||||||
AnchorSideBottom.Control = plInfo
|
AnchorSideBottom.Control = plInfo
|
||||||
AnchorSideBottom.Side = asrBottom
|
AnchorSideBottom.Side = asrBottom
|
||||||
Left = 4
|
Left = 4
|
||||||
Height = 21
|
Height = 19
|
||||||
Top = 47
|
Top = 49
|
||||||
Width = 114
|
Width = 90
|
||||||
Anchors = [akLeft, akBottom]
|
Anchors = [akLeft, akBottom]
|
||||||
BorderSpacing.Around = 3
|
BorderSpacing.Around = 3
|
||||||
Caption = 'Follow tightly'
|
Caption = 'Follow tightly'
|
||||||
Checked = True
|
Checked = True
|
||||||
OnChange = cbTightFollowChange
|
|
||||||
State = cbChecked
|
State = cbChecked
|
||||||
TabOrder = 0
|
TabOrder = 0
|
||||||
|
OnChange = cbTightFollowChange
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -71,7 +71,7 @@ implementation
|
|||||||
{$R *.lfm}
|
{$R *.lfm}
|
||||||
|
|
||||||
uses
|
uses
|
||||||
LCLType, Math, FPImage, DateUtils, mvEngine;
|
LCLType, Math, FPImage, DateUtils, mvGeoMath, mvEngine;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ unit globals;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, mvEngine;
|
Classes, SysUtils, mvGeoMath, mvEngine;
|
||||||
|
|
||||||
type
|
type
|
||||||
TPOIMode = (pmDefaultDrawing, pmDefaultImage, pmImageList, pmCustomDrawing);
|
TPOIMode = (pmDefaultDrawing, pmDefaultImage, pmImageList, pmCustomDrawing);
|
||||||
|
@ -57,7 +57,7 @@ implementation
|
|||||||
{$R *.lfm}
|
{$R *.lfm}
|
||||||
|
|
||||||
uses
|
uses
|
||||||
mvTypes, mvEngine,
|
mvTypes, mvGeoMath, mvEngine,
|
||||||
globals;
|
globals;
|
||||||
|
|
||||||
destructor TGPSListViewer.Destroy;
|
destructor TGPSListViewer.Destroy;
|
||||||
@ -143,7 +143,7 @@ begin
|
|||||||
// show distance between selected items
|
// show distance between selected items
|
||||||
ShowMessage(Format('Distance between %s and %s is: %.2n %s.', [
|
ShowMessage(Format('Distance between %s and %s is: %.2n %s.', [
|
||||||
CoordArr[0].Name, CoordArr[1].Name,
|
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]
|
DistanceUnit_Names[DistanceUnit]
|
||||||
]));
|
]));
|
||||||
end;
|
end;
|
||||||
|
@ -15,7 +15,7 @@ uses
|
|||||||
Classes, SysUtils, Types, Forms, Controls, Graphics, Dialogs, ExtCtrls,
|
Classes, SysUtils, Types, Forms, Controls, Graphics, Dialogs, ExtCtrls,
|
||||||
StdCtrls, ComCtrls, Buttons, IntfGraphics, PrintersDlgs,
|
StdCtrls, ComCtrls, Buttons, IntfGraphics, PrintersDlgs,
|
||||||
Grids, ExtDlgs,
|
Grids, ExtDlgs,
|
||||||
mvGeoNames, mvMapViewer, mvTypes, mvGpsObj, mvDrawingEngine,
|
mvGeoMath, mvGeoNames, mvMapViewer, mvTypes, mvGpsObj, mvDrawingEngine,
|
||||||
{$IFDEF WITH_ADDONS}ConfigFrame_with_Addons{$ELSE}ConfigFrame{$ENDIF};
|
{$IFDEF WITH_ADDONS}ConfigFrame_with_Addons{$ELSE}ConfigFrame{$ENDIF};
|
||||||
|
|
||||||
type
|
type
|
||||||
|
@ -24,192 +24,33 @@ object MainForm: TMainForm
|
|||||||
Font.Pitch = fpVariable
|
Font.Pitch = fpVariable
|
||||||
MapProvider = 'Google Maps'
|
MapProvider = 'Google Maps'
|
||||||
POIImage.Data = {
|
POIImage.Data = {
|
||||||
36170000424D36170000000000003600000028000000200000002E0000000100
|
4503000089504E470D0A1A0A0000000D49484452000000200000002E08060000
|
||||||
2000000000000017000064000000640000000000000000000000FFFFFF00FFFF
|
0049701B840000030C49444154789CB5983B68145114867F4410C54644B0107C
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
152262A7A4D2C2DA3422DAD8D868631510B1D1688855409104A2088634819056
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FD560000FC4CFFFF
|
B00C488845626C82C55662A29204C40DC96ED66CD6F38F77976B76E6DCC7CC14
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
077667CEF9FFEF3EE6CC03AD560B3EB1021C6C023777805189598955892D13AB
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
E6D8287398EBABEB4CA803A745F895C47A92EE11CC650D6BA3012AC03E1119E4
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
087D8D5340383B83D40A0210F29352381F6B9C02F2899A5E000DE09C142C1765
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000F1110000FEE70000FEE10000
|
6E412C535B05A801C72571A968730B62891EA90066CDE7CA32B720E6EC3DD101
|
||||||
EA0CFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
901303012215893772C93D62F0378F05D40FFC07201BE4841CAC7B147EF8035C
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
CADAD13CC71C0F9D3A3D3B007260C451B023237DDC0FEC715DD7CC612E6B1C9A
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
2309C077E080FCA96AC99C66DFCED68EA44607A8D21BDBC03547E2B4CFC8D366
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF000000FE9A0000FFFF0000FFFF0000
|
82B59A36BD39FDC35A92AC6B4FA8B9B5277A1C831B26C08C92B0186B6E5D5D8B
|
||||||
FE8FFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
8AFE0C137EBA364A4E80CC0D4E6F26D494CD773F2F40A2910D5023404301E82B
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
00A04F016810604D49182A60098614FD3568B7DD6483E607D036F93C13C69484
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
A6CF534D5698A7A9A6A23FC635BAEDB856C7738C7E5CD3A637D68123DA46644F
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF000000FB3E0000FEFE0000FFFF0000FFFF0000
|
978E753DD49C35DAFD809EF46E934E39666153047B03CC7B59E3D09C6AFDFB97
|
||||||
FEFC0000FB35FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
B4CC0B1E77AFA6C4CB2A7038CB98E798A3AD7B7B56E9D90130B330A115D9CD43
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
E29DC41359C3BB0CFE36C7329BDA2E8D89B66F07600B38E3222F22CC9575AA0B
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
C0CCC2D3B20164C61EDA9E5DEB28100B258EFEE36EBF2E00D33C9CCF8711E61B
|
||||||
FF00FFFFFF00FFFFFF000000DB070000FED70000FFFF0000FFFF0000FFFF0000
|
9BC0312780B9813C2861EAEFA579A5024C037B85F87381A39FCD7AAC4B0530BD
|
||||||
FFFF0000FECF0000C004FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
E1A2146E1760DE9057B2F3593E99006643BE2800E099E6A102F04383087CCD61
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
5EF906EC8F06307DFD6AA4396F62575CFA4E00B3149311006F7DB4BD003680A3
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
22F82BC07C45BB69050398DE7027E09ABFE5ABEB0D605EB57CDE7CDFFB6A0601
|
||||||
FF00FFFFFF00FFFFFF000000FE800000FFFF0000FFFF0000FFFF0000FFFF0000
|
30E48E7956FB68C5769BF52DA81000B321FB95A90F7E910906309F72BEA48C7E
|
||||||
FFFF0000FFFF0000FD75FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
812DBC740086B4E9CBF6231C5B365B778C561480598AD716C0F3589D6880DFC0
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
2131FEC1561DF26DB83000866CBA1B49ABCEA1F117D2B9A057721AC774000000
|
||||||
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
|
0049454E44AE426082
|
||||||
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
|
|
||||||
}
|
}
|
||||||
POITextBgColor = clCream
|
POITextBgColor = clCream
|
||||||
UseThreads = True
|
UseThreads = True
|
||||||
|
@ -6,7 +6,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls,
|
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls,
|
||||||
Grids, StdCtrls, ColorBox, mvMapViewer, mvGpsObj;
|
Grids, StdCtrls, ColorBox, mvMapViewer, mvGeoMath, mvGpsObj;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
<Description Value="Component for viewing maps (Google, OpenStreetMap, etc). This is a fork of MapViewer by ti_dic (https://sourceforge.net/p/roadbook/code/ci/master/tree/mapviewer/) which itself is based on the MapViewer by Maciej Kaczkowski (https://github.com/maciejkaczkowski/mapviewer)."/>
|
<Description Value="Component for viewing maps (Google, OpenStreetMap, etc). This is a fork of MapViewer by ti_dic (https://sourceforge.net/p/roadbook/code/ci/master/tree/mapviewer/) which itself is based on the MapViewer by Maciej Kaczkowski (https://github.com/maciejkaczkowski/mapviewer)."/>
|
||||||
<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="21">
|
<Files Count="22">
|
||||||
<Item1>
|
<Item1>
|
||||||
<Filename Value="source/mvcache.pas"/>
|
<Filename Value="source/mvcache.pas"/>
|
||||||
<UnitName Value="mvCache"/>
|
<UnitName Value="mvCache"/>
|
||||||
@ -108,6 +108,10 @@
|
|||||||
<HasRegisterProc Value="True"/>
|
<HasRegisterProc Value="True"/>
|
||||||
<UnitName Value="mvDE_LCL"/>
|
<UnitName Value="mvDE_LCL"/>
|
||||||
</Item21>
|
</Item21>
|
||||||
|
<Item22>
|
||||||
|
<Filename Value="source/mvgeomath.pas"/>
|
||||||
|
<UnitName Value="mvgeomath"/>
|
||||||
|
</Item22>
|
||||||
</Files>
|
</Files>
|
||||||
<CompatibilityMode Value="True"/>
|
<CompatibilityMode Value="True"/>
|
||||||
<RequiredPkgs Count="2">
|
<RequiredPkgs Count="2">
|
||||||
|
@ -11,7 +11,7 @@ uses
|
|||||||
mvCache, mvDownloadEngine, mvDragObj, mvEngine, mvGeoNames, mvGpsObj,
|
mvCache, mvDownloadEngine, mvDragObj, mvEngine, mvGeoNames, mvGpsObj,
|
||||||
mvJobQueue, mvJobs, mvMapProvider, mvTypes, mvMapViewer, mvExtraData,
|
mvJobQueue, mvJobs, mvMapProvider, mvTypes, mvMapViewer, mvExtraData,
|
||||||
mvDLEFpc, mvMapViewerReg, mvGPX, mvDrawingEngine, mvDE_IntfGraphics,
|
mvDLEFpc, mvMapViewerReg, mvGPX, mvDrawingEngine, mvDE_IntfGraphics,
|
||||||
mvDLEWin, mvMapViewerPropEdits, mvLayersPropEditForm, mvDE_LCL,
|
mvDLEWin, mvMapViewerPropEdits, mvLayersPropEditForm, mvDE_LCL, mvgeomath,
|
||||||
LazarusPackageIntf;
|
LazarusPackageIntf;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
@ -21,13 +21,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, IntfGraphics, Controls, Math, GraphType, FPImage,
|
Classes, SysUtils, IntfGraphics, Controls, Math, GraphType, FPImage,
|
||||||
mvTypes, mvJobQueue, mvMapProvider, mvDownloadEngine, mvCache, mvDragObj;
|
mvTypes, mvGeoMath, 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));
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TDrawTileEvent = procedure (const TileId: TTileId; X,Y: integer;
|
TDrawTileEvent = procedure (const TileId: TTileId; X,Y: integer;
|
||||||
@ -42,8 +36,6 @@ type
|
|||||||
|
|
||||||
TTileIdArray = Array of TTileId;
|
TTileIdArray = Array of TTileId;
|
||||||
|
|
||||||
TDistanceUnits = (duMeters, duKilometers, duMiles);
|
|
||||||
|
|
||||||
{ TMapWindow }
|
{ TMapWindow }
|
||||||
|
|
||||||
TMapWindow = Record
|
TMapWindow = Record
|
||||||
@ -215,33 +207,19 @@ type
|
|||||||
property OnZoomChange: TNotifyEvent read FOnZoomChange write FOnZoomChange;
|
property OnZoomChange: TNotifyEvent read FOnZoomChange write FOnZoomChange;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function RealPoint(Lat, Lon: Double): TRealPoint;
|
// The following functions have been moved to mvGeoMath and will be removed here sooner or later...
|
||||||
function NormalizeLon(const Lon: Double): Double; inline;
|
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 LatToStr(ALatitude: Double; DMS: Boolean): String; deprecated 'Use function in unit mvGeoMath';
|
||||||
function CalcGeoDistance(Lat1, Lon1, Lat2, Lon2: double;
|
function LatToStr(ALatitude: Double; DMS: Boolean; AFormatSettings: TFormatSettings): String; deprecated 'Use function in unit mvGeoMath';
|
||||||
AUnits: TDistanceUnits = duKilometers): double;
|
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;
|
function ZoomFactor(AZoomLevel: Integer): Int64; deprecated 'Use function in unit mvGeoMath';
|
||||||
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;
|
|
||||||
|
|
||||||
var
|
var
|
||||||
HERE_AppID: String = '';
|
HERE_AppID: String = '';
|
||||||
@ -249,8 +227,6 @@ var
|
|||||||
OpenWeatherMap_ApiKey: String = '';
|
OpenWeatherMap_ApiKey: String = '';
|
||||||
ThunderForest_ApiKey: String = '';
|
ThunderForest_ApiKey: String = '';
|
||||||
|
|
||||||
DMS_Decimals: Integer = 1;
|
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@ -258,25 +234,6 @@ uses
|
|||||||
Forms, TypInfo, laz2_xmlread, laz2_xmlwrite, laz2_dom,
|
Forms, TypInfo, laz2_xmlread, laz2_xmlwrite, laz2_dom,
|
||||||
mvJobs, mvGpsObj;
|
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
|
type
|
||||||
|
|
||||||
{ TEnvTile }
|
{ TEnvTile }
|
||||||
@ -1474,492 +1431,56 @@ begin
|
|||||||
MapWin.MapProvider := MP; // Restore the old Map Provider
|
MapWin.MapProvider := MP; // Restore the old Map Provider
|
||||||
end;
|
end;
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
{------------------------------------------------------------------------------}
|
||||||
|
|
||||||
function RealPoint(Lat, Lon: Double): TRealPoint;
|
function DMSToDeg(Deg, Min: Word; Sec: Double): Double;
|
||||||
begin
|
begin
|
||||||
Result.Lon := Lon;
|
Result := mvGeoMath.DMSToDeg(Deg, Min, Sec);
|
||||||
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;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GPSToDMS(Angle: Double): string;
|
function GPSToDMS(Angle: Double): string;
|
||||||
begin
|
begin
|
||||||
Result := GPSToDMS(Angle, DefaultFormatSettings);
|
Result := mvGeoMath.GPSToDMS(Angle);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function GPSToDMS(Angle: Double; AFormatSettings: TFormatSettings): string;
|
function GPSToDMS(Angle: Double; AFormatSettings: TFormatSettings): string;
|
||||||
var
|
|
||||||
deg, min, sec: Double;
|
|
||||||
begin
|
begin
|
||||||
SplitGPS(Angle, deg, min, sec);
|
Result := mvGeoMath.GPSToDMS(Angle, AFormatSettings);
|
||||||
Result := Format('%.0f° %.0f'' %.*f"', [deg, min, DMS_Decimals, sec], AFormatSettings);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function LatToStr(ALatitude: Double; DMS: Boolean): String;
|
function LatToStr(ALatitude: Double; DMS: Boolean): String;
|
||||||
begin
|
begin
|
||||||
Result := LatToStr(ALatitude, DMS, DefaultFormatSettings);
|
Result := mvGeoMath.LatToStr(ALatitude, DMS);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function LatToStr(ALatitude: Double; DMS: Boolean; AFormatSettings: TFormatSettings): String;
|
function LatToStr(ALatitude: Double; DMS: Boolean; AFormatSettings: TFormatSettings): String;
|
||||||
begin
|
begin
|
||||||
if DMS then
|
Result := mvGeoMath.LatToStr(ALatitude, DMS, AFormatSettings);
|
||||||
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;
|
end;
|
||||||
|
|
||||||
function LonToStr(ALongitude: Double; DMS: Boolean): String;
|
function LonToStr(ALongitude: Double; DMS: Boolean): String;
|
||||||
begin
|
begin
|
||||||
Result := LonToStr(ALongitude, DMS, DefaultFormatSettings);
|
Result := mvGeoMath.LonToStr(ALongitude, DMS);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function LonToStr(ALongitude: Double; DMS: Boolean; AFormatSettings: TFormatSettings): String;
|
function LonToStr(ALongitude: Double; DMS: Boolean; AFormatSettings: TFormatSettings): String;
|
||||||
begin
|
begin
|
||||||
if DMS then
|
Result := mvGeoMath.LonToStr(ALongitude, DMS, AFormatSettings);
|
||||||
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;
|
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;
|
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
|
begin
|
||||||
Result := false;
|
Result := mvGeoMath.TryStrToGps(AValue, ADeg);
|
||||||
|
|
||||||
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;
|
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;
|
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
|
begin
|
||||||
Result := Len < I;
|
Result := mvGeoMath.TryStrDMSToDeg(AValue, ADeg);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure SkipWS; inline;
|
function ZoomFactor(AZoomLevel: Integer): Int64;
|
||||||
begin
|
begin
|
||||||
while not EOL and (AValue[I] in WS_CHARS) do
|
Result := mvGeoMath.ZoomFactor(AZoomLevel);
|
||||||
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;
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
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;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
601
components/lazmapviewer/source/mvgeomath.pas
Normal file
601
components/lazmapviewer/source/mvgeomath.pas
Normal file
@ -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.
|
||||||
|
|
@ -16,7 +16,8 @@ unit mvGpsObj;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, Graphics, fgl, mvtypes, contnrs, syncobjs;
|
Classes, SysUtils, Graphics, fgl, contnrs, syncobjs,
|
||||||
|
mvTypes, mvGeoMath;
|
||||||
|
|
||||||
const
|
const
|
||||||
NO_ELE = -10000000;
|
NO_ELE = -10000000;
|
||||||
@ -1013,6 +1014,21 @@ begin
|
|||||||
Result := FDateTime <> NO_DATE;
|
Result := FDateTime <> NO_DATE;
|
||||||
end;
|
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;
|
function TGPSPoint.DistanceInKmFrom(OtherPt: TGPSPoint;
|
||||||
UseElevation: boolean = true): double;
|
UseElevation: boolean = true): double;
|
||||||
var
|
var
|
||||||
@ -1031,6 +1047,12 @@ begin
|
|||||||
t3 := cos(lon1 - lon2);
|
t3 := cos(lon1 - lon2);
|
||||||
t4 := t2 * t3;
|
t4 := t2 * t3;
|
||||||
t5 := t1 + t4;
|
t5 := t1 + t4;
|
||||||
|
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);
|
rad_dist := arctan(-t5/sqrt(-t5 * t5 + 1)) + 2 * arctan(1);
|
||||||
result := (rad_dist * 3437.74677 * 1.1508) * 1.6093470878864446;
|
result := (rad_dist * 3437.74677 * 1.1508) * 1.6093470878864446;
|
||||||
if UseElevation and (FElevation <> OtherPt.FElevation) then
|
if UseElevation and (FElevation <> OtherPt.FElevation) then
|
||||||
@ -1041,6 +1063,7 @@ begin
|
|||||||
Result := sqrt(DiffEle*DiffEle + result*result);
|
Result := sqrt(DiffEle*DiffEle + result*result);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
*)
|
||||||
|
|
||||||
procedure TGPSPoint.MoveTo(ALon, ALat: Double; AElevation: double = NO_ELE;
|
procedure TGPSPoint.MoveTo(ALon, ALat: Double; AElevation: double = NO_ELE;
|
||||||
ADateTime: TDateTime = NO_DATE);
|
ADateTime: TDateTime = NO_DATE);
|
||||||
|
@ -29,8 +29,8 @@ interface
|
|||||||
uses
|
uses
|
||||||
Classes, SysUtils, Controls, GraphType, Graphics, FPImage, IntfGraphics,
|
Classes, SysUtils, Controls, GraphType, Graphics, FPImage, IntfGraphics,
|
||||||
Forms, ImgList, LCLVersion, fgl,
|
Forms, ImgList, LCLVersion, fgl,
|
||||||
MvTypes, MvGPSObj, MvEngine, MvMapProvider, MvDownloadEngine, MvDrawingEngine,
|
MvTypes, MvGeoMath, MvGPSObj, MvCache, MvExtraData, MvEngine, MvMapProvider,
|
||||||
mvCache, mvExtraData;
|
MvDownloadEngine, MvDrawingEngine;
|
||||||
|
|
||||||
Type
|
Type
|
||||||
|
|
||||||
|
@ -78,8 +78,9 @@ procedure Register;
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Dialogs, IDEWindowIntf, mvMapViewer, mvGpsObj, mvLayersPropEditForm, mvEngine,
|
Dialogs, IDEWindowIntf,
|
||||||
StrUtils;
|
StrUtils,
|
||||||
|
mvGeoMath, mvMapViewer, mvGpsObj, mvLayersPropEditForm, mvEngine;
|
||||||
|
|
||||||
const
|
const
|
||||||
NONE = '(none)';
|
NONE = '(none)';
|
||||||
|
@ -63,6 +63,8 @@ Type
|
|||||||
function Union(const Area: TRealArea): TRealArea;
|
function Union(const Area: TRealArea): TRealArea;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function RealPoint(Lat, Lon: Double): TRealPoint;
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@ -276,6 +278,12 @@ begin
|
|||||||
Self.Lat := RadToDeg(AValue);
|
Self.Lat := RadToDeg(AValue);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function RealPoint(Lat, Lon: Double): TRealPoint;
|
||||||
|
begin
|
||||||
|
Result.Lon := Lon;
|
||||||
|
Result.Lat := Lat;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TRealArea
|
{ TRealArea
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
<Title Value="mapviewer_tests"/>
|
<Title Value="mapviewer_tests"/>
|
||||||
<ResourceType Value="res"/>
|
<ResourceType Value="res"/>
|
||||||
<UseXPManifest Value="True"/>
|
<UseXPManifest Value="True"/>
|
||||||
<Icon Value="0"/>
|
|
||||||
</General>
|
</General>
|
||||||
<BuildModes>
|
<BuildModes>
|
||||||
<Item Name="Default" Default="True"/>
|
<Item Name="Default" Default="True"/>
|
||||||
@ -41,7 +40,7 @@
|
|||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
</Unit>
|
</Unit>
|
||||||
<Unit>
|
<Unit>
|
||||||
<Filename Value="mvtests_engine.pas"/>
|
<Filename Value="mvtests_geomath.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
</Unit>
|
</Unit>
|
||||||
</Units>
|
</Units>
|
||||||
|
@ -4,7 +4,7 @@ program mapviewer_tests;
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Interfaces, Forms, GuiTestRunner,
|
Interfaces, Forms, GuiTestRunner,
|
||||||
mvtests_engine, mvtests_types;
|
mvtests_geomath, mvtests_types;
|
||||||
|
|
||||||
{$R *.res}
|
{$R *.res}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
unit mvtests_engine;
|
unit mvtests_geomath;
|
||||||
|
|
||||||
{$mode objfpc}{$H+}
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
@ -8,7 +8,7 @@ uses
|
|||||||
Classes, SysUtils, fpcunit, testutils, testregistry;
|
Classes, SysUtils, fpcunit, testutils, testregistry;
|
||||||
|
|
||||||
type
|
type
|
||||||
TMvTests_Engine= class(TTestCase)
|
TMvTests_GeoMath = class(TTestCase)
|
||||||
published
|
published
|
||||||
procedure Test_Distance;
|
procedure Test_Distance;
|
||||||
procedure Test_LatToStr_DMS;
|
procedure Test_LatToStr_DMS;
|
||||||
@ -22,7 +22,7 @@ type
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Math, mvEngine;
|
Math, mvGeoMath;
|
||||||
|
|
||||||
type
|
type
|
||||||
TDistanceRec = record
|
TDistanceRec = record
|
||||||
@ -94,7 +94,7 @@ const
|
|||||||
var
|
var
|
||||||
PointFormatsettings: TFormatSettings;
|
PointFormatsettings: TFormatSettings;
|
||||||
|
|
||||||
procedure TMvTests_Engine.Test_Distance;
|
procedure TMvTests_GeoMath.Test_Distance;
|
||||||
const
|
const
|
||||||
TOLERANCE = 2;
|
TOLERANCE = 2;
|
||||||
RADIUS = 6378; // Earth radius in km, as used by the references
|
RADIUS = 6378; // Earth radius in km, as used by the references
|
||||||
@ -110,7 +110,7 @@ begin
|
|||||||
);
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMvTests_Engine.Test_LatToStr_Deg;
|
procedure TMvTests_GeoMath.Test_LatToStr_Deg;
|
||||||
const
|
const
|
||||||
NO_DMS = false;
|
NO_DMS = false;
|
||||||
var
|
var
|
||||||
@ -125,7 +125,7 @@ begin
|
|||||||
);
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMvTests_Engine.Test_LatToStr_DMS;
|
procedure TMvTests_GeoMath.Test_LatToStr_DMS;
|
||||||
const
|
const
|
||||||
NEED_DMS = true;
|
NEED_DMS = true;
|
||||||
var
|
var
|
||||||
@ -140,7 +140,7 @@ begin
|
|||||||
);
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMvTests_Engine.Test_LonToStr_Deg;
|
procedure TMvTests_GeoMath.Test_LonToStr_Deg;
|
||||||
const
|
const
|
||||||
NO_DMS = false;
|
NO_DMS = false;
|
||||||
var
|
var
|
||||||
@ -155,7 +155,7 @@ begin
|
|||||||
);
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMvTests_Engine.Test_LonToStr_DMS;
|
procedure TMvTests_GeoMath.Test_LonToStr_DMS;
|
||||||
const
|
const
|
||||||
NEED_DMS = true;
|
NEED_DMS = true;
|
||||||
var
|
var
|
||||||
@ -170,7 +170,7 @@ begin
|
|||||||
);
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMvTests_Engine.Test_SplitGPS;
|
procedure TMvTests_GeoMath.Test_SplitGPS;
|
||||||
const
|
const
|
||||||
TOLERANCE = 1e-5;
|
TOLERANCE = 1e-5;
|
||||||
var
|
var
|
||||||
@ -218,7 +218,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMvTests_Engine.Test_ZoomFactor;
|
procedure TMvTests_GeoMath.Test_ZoomFactor;
|
||||||
var
|
var
|
||||||
z: Integer;
|
z: Integer;
|
||||||
f: Extended;
|
f: Extended;
|
||||||
@ -236,6 +236,6 @@ initialization
|
|||||||
PointFormatSettings.DecimalSeparator := '.';
|
PointFormatSettings.DecimalSeparator := '.';
|
||||||
DMS_Decimals := 4;
|
DMS_Decimals := 4;
|
||||||
|
|
||||||
RegisterTest(TMvTests_Engine);
|
RegisterTest(TMvTests_GeoMath);
|
||||||
end.
|
end.
|
||||||
|
|
@ -9,7 +9,7 @@ uses
|
|||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
TMvTestsArea= class(TTestCase)
|
TMvTests_Area= class(TTestCase)
|
||||||
published
|
published
|
||||||
procedure Test_PointInArea;
|
procedure Test_PointInArea;
|
||||||
procedure Test_Intersection;
|
procedure Test_Intersection;
|
||||||
@ -28,7 +28,7 @@ begin
|
|||||||
]);
|
]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMvTestsArea.Test_PointInArea;
|
procedure TMvTests_Area.Test_PointInArea;
|
||||||
var
|
var
|
||||||
counter: Integer;
|
counter: Integer;
|
||||||
a: TRealArea;
|
a: TRealArea;
|
||||||
@ -123,7 +123,7 @@ begin
|
|||||||
);
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMvTestsArea.Test_Union;
|
procedure TMvTests_Area.Test_Union;
|
||||||
var
|
var
|
||||||
counter: Integer;
|
counter: Integer;
|
||||||
a, b, expected, actual: TRealArea;
|
a, b, expected, actual: TRealArea;
|
||||||
@ -298,7 +298,7 @@ begin
|
|||||||
);
|
);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMvTestsArea.Test_Intersection;
|
procedure TMvTests_Area.Test_Intersection;
|
||||||
var
|
var
|
||||||
counter: Integer;
|
counter: Integer;
|
||||||
a, b, expected, actual: TRealArea;
|
a, b, expected, actual: TRealArea;
|
||||||
@ -430,7 +430,7 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
RegisterTest(TMvTestsArea);
|
RegisterTest(TMvTests_Area);
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user