This is the JavaScript source code of the WGS84 Distance, Azimuth and Radius Calculator.
#INCLUDE ControlPanel.inc
#INCLUDE JsgVectMat3.inc
#INCLUDE NewtonSolver.inc
#INCLUDE WGS84.inc
<jscript>
var NDigits = 10;
NumFormatter.SetFormat( 'calc' );
//ControlPanels.Debug = true;
var Formating = {
Lang: 'en',
Format: 'std',
Precision: NDigits,
// choosen units tables
UnitsType: 0, // 0 -> m/m, 1 -> km/m, 2 -> mi/ft, 3 -> ft/ft, 4 -> nmi/ft
LengthUnits: {
Selection: 'Formating.UnitsType',
Units: [ 'm', 'km', 'mi', 'ft', 'nmi' ],
Mults: [ 1, 1000, 1609.344, 0.3048, 1852 ]
},
HeightUnits: {
Selection: 'Formating.UnitsType',
Units: [ 'm', 'm', 'ft', 'ft', 'ft' ],
Mults: [ 1, 1, 0.3048, 0.3048, 0.3048 ]
},
GeoFormatType: 0, // 0 -> x°x'x" N, 1 -> x°x'x", 2 -> x°
GeoFormatNS: {
Selection: 'Formating.GeoFormatType',
Units: [ '', '', '°' ],
Formats: [ 'dmsS', 'dms', 'std' ],
},
GeoFormatEW: {
Selection: 'Formating.GeoFormatType',
Units: [ '', '', '°' ],
Formats: [ 'dmsW', 'dms', 'std' ],
},
Update: function( field ) {
if (!xDef(field)) {
this.Lang = 'en';
this.Format = 'std';
this.Precision = NDigits;
}
if (ControlPanels.MatchesField( field, 'Lang' )) {
NumFormatter.SetLang( this.Lang );
NumFormatter.ExpChar = 'e';
NumFormatter.AltMode = 'sci';
}
if (ControlPanels.MatchesField( field, 'Precision' )) {
this.Precision = Math.round( this.Precision );
if (this.Precision < 3) this.Precision = 3;
if (this.Precision > 13) this.Precision = 13;
NumFormatter.AltPrec = this.Precision;
}
if (this.GeoFormatType == 2) {
// copy global format into geo format
this.GeoFormatNS.Formats[2] = this.Format;
this.GeoFormatEW.Formats[2] = this.Format;
}
ControlPanels.Invalidate();
ControlPanels.Update();
},
};
///////////////////////////////////////////////////////////////////
var WGS84Model = {
Lat1: 0,
Lng1: 0,
Elev1: 0,
X1: 0,
Y1: 0,
Z1: 0,
Lat2: 0,
Lng2: 0,
Elev2: 0,
X2: 0,
Y2: 0,
Z2: 0,
Azim1: 0,
Azim2: 0,
Dist: 0,
LatTest: 0,
LngTest: 0,
AzimTest: 0,
GeocentricRadius: 0,
MeridialRadius: 0,
PrimeVerticalRadius: 0,
DirectionalRadius: 0,
GeocentricRadiusAlt: 0,
MeridialRadiusAlt: 0,
PrimeVerticalRadiusAlt: 0,
DirectionalRadiusAlt: 0,
State: '',
Update: function( field ) {
if (ControlPanels.MatchesField( field, 'Lat1,Lng1,Elev1' )) {
this.UpdateXYZ1();
this.UpdateDistAzim();
} else if (ControlPanels.MatchesField( field, 'X1,Y1,Z1' )) {
this.UpdateLatLngH1();
this.UpdateDistAzim();
}
if (ControlPanels.MatchesField( field, 'Lat2,Lng2,Elev2' )) {
this.UpdateXYZ2();
this.UpdateDistAzim();
} else if (ControlPanels.MatchesField( field, 'X2,Y2,Z2' )) {
this.UpdateLatLngH2();
this.UpdateDistAzim();
} else if (ControlPanels.MatchesField( field, 'Dist,Azim1' )) {
this.UpdateLatLngH2FromAzimDist();
this.UpdateXYZ2();
}
this.GeocentricRadius = WGS84.GeocentricRadius( this.Lat1 );
this.MeridialRadius = WGS84.MeridialRadius( this.Lat1 );
this.PrimeVerticalRadius = WGS84.PrimeVerticalRadius( this.Lat1 );
this.DirectionalRadius = WGS84.DirectionalRadius( this.Azim1, this.Lat1 );
this.GeocentricRadiusAlt = this.GeocentricRadius + this.Elev1;
this.MeridialRadiusAlt = this.MeridialRadius + this.Elev1;
this.PrimeVerticalRadiusAlt = this.PrimeVerticalRadius + this.Elev1;
this.DirectionalRadiusAlt = this.DirectionalRadius + this.Elev1;
// check whether WGS84 functions are correct
var posAzim = WGS84.PositionAzimuthFromPositionAzimuthDistance( this.Lat1, this.Lng1, this.Azim1, this.Dist );
this.LatTest = posAzim.lat;
this.LngTest = posAzim.lng;
this.AzimTest = posAzim.azim;
ControlPanels.Update();
},
UpdateXYZ1: function() {
var ECEF = WGS84.GeoToEcef( this.Lat1, this.Lng1, this.Elev1 );
this.X1 = ECEF[0];
this.Y1 = ECEF[1];
this.Z1 = ECEF[2];
this.State = 'ok';
},
UpdateLatLngH1: function() {
var geo = WGS84.EcefToGeo( [ this.X1, this.Y1, this.Z1 ] );
this.Lat1 = geo.lat;
this.Lng1 = geo.lng;
this.Elev1 = geo.h;
this.State = WGS84.error;
},
UpdateDistAzim: function() {
var distAzim = WGS84.DistanceAzimuthFromLocations( this.Lat1, this.Lng1, this.Lat2, this.Lng2 );
this.Dist = distAzim.dist;
this.Azim1 = distAzim.azim1;
this.Azim2 = distAzim.azim2;
},
UpdateXYZ2: function() {
var ECEF = WGS84.GeoToEcef( this.Lat2, this.Lng2, this.Elev2 );
this.X2 = ECEF[0];
this.Y2 = ECEF[1];
this.Z2 = ECEF[2];
this.State = 'ok';
},
UpdateLatLngH2: function() {
var geo = WGS84.EcefToGeo( [ this.X2, this.Y2, this.Z2 ] );
this.Lat2 = geo.lat;
this.Lng2 = geo.lng;
this.Elev2 = geo.h;
this.State = WGS84.error;
},
UpdateLatLngH2FromAzimDist: function() {
var posAzim = WGS84.PositionAzimuthFromPositionAzimuthDistance( this.Lat1, this.Lng1, this.Azim1, this.Dist );
this.Lat2 = posAzim.lat;
this.Lng2 = posAzim.lng;
this.Azim2 = posAzim.azim;
},
};
</jscript>
{{scroll}}
<jscript>
////////////////////////////////////////////////////////////////////
ControlPanels.NewPanel( {
Name: 'Formating',
ModelRef: 'Formating',
NCols: 2,
OnModelChange: function(field) { Formating.Update(field); },
} ).AddHeader( {
Text: 'Number formating',
ColSpan: 4
} ).AddRadiobuttonField( {
Name: 'Lang',
Label: 'Style',
Items: [
{ Name: 'iso' },
{ Name: 'en' },
{ Name: 'de' },
{ Name: 'ch' },
{ Name: 'calc' },
]
} ).AddTextField( {
Name: 'Precision',
Format: 'fix',
digits: 0,
Inc: 1,
} ).AddRadiobuttonField( {
Name: 'Format',
ColSpan: 3,
Items: [
{ Name: 'std' },
{ Name: 'prec' },
{ Name: 'weak0', Text: 'fix' },
{ Name: 'sci' },
{ Name: 'eng' },
]
} ).AddRadiobuttonField( {
Name: 'UnitsType',
ColSpan: 3,
Label: 'Units',
ValueType: 'int',
Items: [
{
Name: 'm/m (Metric)',
Value: 0
}, {
Name: 'km/m (Metric)',
Value: 1
}, {
Name: 'mi/ft (Imperial)',
Value: 2
}, {
Name: 'ft/ft (Imperial)',
Value: 3
}, {
Name: 'nmi/ft (Aviation)',
Value: 4
}
]
} ).AddRadiobuttonField( {
Name: 'GeoFormatType',
Label: 'Geo Units',
ValueType: 'int',
Items: [
{
Name: 'd°m\'s.s" N/S',
Value: 0
}, {
Name: 'd°m\'s.s"',
Value: 1
}, {
Name: 'd.d°',
Value: 2
}
]
} ).Render();
</jscript>
{{end scroll}}
{{scroll}}
<jscript>
////////////////////////////////////////////////////////////////////
ControlPanels.NewPanel( {
Name: 'Panel1',
ModelRef: 'WGS84Model',
OnModelChange: function(field){ WGS84Model.Update(field); },
PanelFormat: 'InputNormalWidth',
NCols: 3,
Format: 'std',
Digits: NDigits
}
).AddHeader( {
Text: 'Position 1 (Geo or ECEF Coord)',
ColSpan: 6
}
).AddTextField( {
Name: 'Lat1',
Label: 'Lat',
UnitsData: 'Formating.GeoFormatNS',
DigitsRef: 'Formating.Precision',
InputFormat: 'dms',
}
).AddTextField( {
Name: 'Lng1',
Label: 'Long',
UnitsData: 'Formating.GeoFormatEW',
DigitsRef: 'Formating.Precision',
InputFormat: 'dms',
}
).AddTextField( {
Name: 'Elev1',
Label: 'Elev',
UnitsData: 'Formating.HeightUnits',
FormatRef: 'Formating.Format',
DigitsRef: 'Formating.Precision',
}
).AddTextField( {
Name: 'X1',
Label: 'X',
UnitsData: 'Formating.LengthUnits',
FormatRef: 'Formating.Format',
DigitsRef: 'Formating.Precision',
}
).AddTextField( {
Name: 'Y1',
Label: 'Y',
UnitsData: 'Formating.LengthUnits',
FormatRef: 'Formating.Format',
DigitsRef: 'Formating.Precision',
}
).AddTextField( {
Name: 'Z1',
Label: 'Z',
UnitsData: 'Formating.LengthUnits',
FormatRef: 'Formating.Format',
DigitsRef: 'Formating.Precision',
}
).Render();
</jscript>
{{end scroll}}
{{scroll}}
<jscript>
////////////////////////////////////////////////////////////////////
ControlPanels.NewPanel( {
Name: 'Panel2',
ModelRef: 'WGS84Model',
OnModelChange: function(field){ WGS84Model.Update(field); },
PanelFormat: 'InputNormalWidth',
NCols: 3,
Format: 'std',
Digits: NDigits
}
).AddHeader( {
Text: 'Position 2 (Geo or ECEF Coord)',
ColSpan: 6
}
).AddTextField( {
Name: 'Lat2',
Label: 'Lat',
UnitsData: 'Formating.GeoFormatNS',
DigitsRef: 'Formating.Precision',
InputFormat: 'dms',
}
).AddTextField( {
Name: 'Lng2',
Label: 'Long',
UnitsData: 'Formating.GeoFormatEW',
DigitsRef: 'Formating.Precision',
InputFormat: 'dms',
}
).AddTextField( {
Name: 'Elev2',
Label: 'Elev',
UnitsData: 'Formating.HeightUnits',
FormatRef: 'Formating.Format',
DigitsRef: 'Formating.Precision',
}
).AddTextField( {
Name: 'X2',
Label: 'X',
UnitsData: 'Formating.LengthUnits',
FormatRef: 'Formating.Format',
DigitsRef: 'Formating.Precision',
}
).AddTextField( {
Name: 'Y2',
Label: 'Y',
UnitsData: 'Formating.LengthUnits',
FormatRef: 'Formating.Format',
DigitsRef: 'Formating.Precision',
}
).AddTextField( {
Name: 'Z2',
Label: 'Z',
UnitsData: 'Formating.LengthUnits',
FormatRef: 'Formating.Format',
DigitsRef: 'Formating.Precision',
}
).AddTextField( {
Name: 'Dist',
Label: 'Dist',
UnitsData: 'Formating.LengthUnits',
FormatRef: 'Formating.Format',
DigitsRef: 'Formating.Precision',
}
).AddTextField( {
Name: 'Azim1',
Label: 'Azim1',
Units: '°',
}
).AddTextField( {
ReadOnly: true,
Name: 'Azim2',
Label: 'Azim2',
Units: '°',
}
/*
).AddTextField( {
Name: 'LatTest',
Label: 'LatTest',
Units: '°',
UnitsData: 'Formating.GeoFormatNS',
DigitsRef: 'Formating.Precision',
ReadOnly: true,
}
).AddTextField( {
Name: 'LngTest',
Label: 'LngTest',
Units: '°',
UnitsData: 'Formating.GeoFormatEW',
DigitsRef: 'Formating.Precision',
ReadOnly: true,
}
).AddTextField( {
Name: 'AzimTest',
Label: 'AzimTest',
Units: '°',
ReadOnly: true,
}
*/
).Render();
</jscript>
{{end scroll}}
{{scroll}}
<jscript>
////////////////////////////////////////////////////////////////////
ControlPanels.NewPanel( {
Name: 'RadiiAltPanel',
ModelRef: 'WGS84Model',
ReadOnly: true,
PanelFormat: 'InputNormalWidth',
NCols: 2,
Format: 'fix',
Digits: NDigits
} ).AddHeader( {
Text: 'Radius + Elev at Position 1',
ColSpan: 4
} ).AddTextField( {
Name: 'GeocentricRadiusAlt',
Label: 'Geocentric',
UnitsData: 'Formating.LengthUnits',
FormatRef: 'Formating.Format',
DigitsRef: 'Formating.Precision',
} ).AddTextField( {
Name: 'MeridialRadiusAlt',
Label: 'Meridial',
UnitsData: 'Formating.LengthUnits',
FormatRef: 'Formating.Format',
DigitsRef: 'Formating.Precision',
} ).AddTextField( {
Name: 'DirectionalRadiusAlt',
Label: 'Directional',
UnitsData: 'Formating.LengthUnits',
FormatRef: 'Formating.Format',
DigitsRef: 'Formating.Precision',
} ).AddTextField( {
Name: 'PrimeVerticalRadiusAlt',
Label: 'Prime Vertical',
UnitsData: 'Formating.LengthUnits',
FormatRef: 'Formating.Format',
DigitsRef: 'Formating.Precision',
} ).Render();
xOnLoad(
function(){
Formating.Update();
WGS84Model.Update();
}
);