Skip to content

Commit fab0b06

Browse files
committed
Optimization for Gnomonic and GonmonicData
1 parent b857abe commit fab0b06

File tree

3 files changed

+72
-82
lines changed

3 files changed

+72
-82
lines changed

GeographicLib/GeodesicData.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,62 +25,62 @@ public sealed class GeodesicData
2525
/// <summary>
2626
/// latitude of point 1 (degrees).
2727
/// </summary>
28-
public double lat1;
28+
public double lat1 { get; set; }
2929

3030
/// <summary>
3131
/// longitude of point 1 (degrees).
3232
/// </summary>
33-
public double lon1;
33+
public double lon1 { get; set; }
3434

3535
/// <summary>
3636
/// azimuth at point 1 (degrees).
3737
/// </summary>
38-
public double azi1;
38+
public double azi1 { get; set; }
3939

4040
/// <summary>
4141
/// latitude of point 2 (degrees).
4242
/// </summary>
43-
public double lat2;
43+
public double lat2 { get; set; }
4444

4545
/// <summary>
4646
/// longitude of point 2 (degrees).
4747
/// </summary>
48-
public double lon2;
48+
public double lon2 { get; set; }
4949

5050
/// <summary>
5151
/// azimuth at point 2 (degrees).
5252
/// </summary>
53-
public double azi2;
53+
public double azi2 { get; set; }
5454

5555
/// <summary>
5656
/// distance between point 1 and point 2 (meters).
5757
/// </summary>
58-
public double s12;
58+
public double s12 { get; set; }
5959

6060
/// <summary>
6161
/// arc length on the auxiliary sphere between point 1 and point 2 (degrees).
6262
/// </summary>
63-
public double a12;
63+
public double a12 { get; set; }
6464

6565
/// <summary>
6666
/// reduced length of geodesic (meters).
6767
/// </summary>
68-
public double m12;
68+
public double m12 { get; set; }
6969

7070
/// <summary>
7171
/// geodesic scale of point 2 relative to point 1 (dimensionless).
7272
/// </summary>
73-
public double M12;
73+
public double M12 { get; set; }
7474

7575
/// <summary>
7676
/// geodesic scale of point 1 relative to point 2 (dimensionless).
7777
/// </summary>
78-
public double M21;
78+
public double M21 { get; set; }
7979

8080
/// <summary>
8181
/// Area under the geodesic (meters<sup>2</sup>).
8282
/// </summary>
83-
public double S12;
83+
public double S12 { get; set; }
8484

8585
/// <summary>
8686
/// Initialize all the fields to Double.NaN.

GeographicLib/Gnomonic.cs

Lines changed: 49 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
namespace GeographicLib
1414
{
1515

16-
/**
17-
* Gnomonic projection.
16+
/*
1817
* <p>
1918
* <i>Note: Gnomonic.java has been ported to Java from its C++ equivalent
2019
* Gnomonic.cpp, authored by C. F. F. Karney and licensed under MIT/X11
@@ -136,25 +135,24 @@ namespace GeographicLib
136135
* </pre>
137136
*/
138137

138+
/// <summary>
139+
/// Gnomonic projection.
140+
/// </summary>
139141
public readonly struct Gnomonic
140142
{
141143
private static readonly double eps_ = 0.01 * Math.Sqrt(GeoMath.Epsilon);
142144
private const int numit_ = 10;
143145

144-
private readonly Geodesic _earth;
145-
private readonly double _a, _f;
146+
public Geodesic Earth { get; }
146147

147-
/**
148-
* Constructor for Gnomonic.
149-
* <p>
150-
* @param earth the {@link Geodesic} object to use for geodesic
151-
* calculations.
152-
*/
148+
/// <summary>
149+
/// Constructor for Gnomonic.
150+
/// </summary>
151+
/// <param name="earth">earth the <see cref="GeographicLib.Geodesic"/> object to use for geodesic calculations
152+
/// </param>
153153
public Gnomonic(Geodesic earth)
154154
{
155-
_earth = earth;
156-
_a = _earth.MajorRadius;
157-
_f = _earth.Flattening;
155+
this.Earth = earth;
158156
}
159157

160158
/**
@@ -181,23 +179,22 @@ public Gnomonic(Geodesic earth)
181179
*/
182180
public GnomonicData Forward(double lat0, double lon0, double lat, double lon)
183181
{
184-
GeodesicData inv =
185-
_earth.Inverse(lat0, lon0, lat, lon,
186-
GeodesicMask.AZIMUTH | GeodesicMask.GEODESICSCALE |
187-
GeodesicMask.REDUCEDLENGTH);
188-
GnomonicData fwd =
189-
new GnomonicData(lat0, lon0, lat, lon, Double.NaN, Double.NaN,
190-
inv.azi2, inv.M12);
182+
GeodesicData inv = Earth.Inverse(
183+
lat0, lon0, lat, lon,
184+
GeodesicMask.AZIMUTH | GeodesicMask.GEODESICSCALE | GeodesicMask.REDUCEDLENGTH);
191185

192186
if (inv.M12 > 0)
193187
{
194-
double rho = inv.m12 / inv.M12;
195-
Pair p = GeoMath.Sincosd(inv.azi1);
196-
fwd.x = rho * p.First;
197-
fwd.y = rho * p.Second;
188+
var rho = inv.m12 / inv.M12;
189+
var p = GeoMath.Sincosd(inv.azi1);
190+
var x = rho * p.First;
191+
var y = rho * p.Second;
192+
return new GnomonicData(lat0, lon0, lat, lon, x, y, inv.azi2, inv.M12);
193+
}
194+
else
195+
{
196+
return new GnomonicData(lat0, lon0, lat, lon, Double.NaN, Double.NaN, inv.azi2, inv.M12);
198197
}
199-
200-
return fwd;
201198
}
202199

203200
/**
@@ -226,20 +223,19 @@ public GnomonicData Forward(double lat0, double lon0, double lat, double lon)
226223
*/
227224
public GnomonicData Reverse(double lat0, double lon0, double x, double y)
228225
{
229-
GnomonicData rev =
230-
new GnomonicData(lat0, lon0, Double.NaN, Double.NaN, x, y, Double.NaN,
231-
Double.NaN);
232226

233-
double azi0 = GeoMath.Atan2d(x, y);
234-
double rho = GeoMath.Hypot(x, y);
235-
double s = _a * Math.Atan(rho / _a);
236-
bool little = rho <= _a;
227+
var azi0 = GeoMath.Atan2d(x, y);
228+
var rho = GeoMath.Hypot(x, y);
229+
var s = this.MajorRadius * Math.Atan(rho / this.MajorRadius);
230+
var little = rho <= this.MajorRadius;
237231

238232
if (!little)
233+
{
239234
rho = 1 / rho;
235+
}
240236

241-
GeodesicLine line =
242-
_earth.Line(lat0, lon0, azi0, GeodesicMask.LATITUDE
237+
var line =
238+
Earth.Line(lat0, lon0, azi0, GeodesicMask.LATITUDE
243239
| GeodesicMask.LONGITUDE | GeodesicMask.AZIMUTH
244240
| GeodesicMask.DISTANCE_IN | GeodesicMask.REDUCEDLENGTH
245241
| GeodesicMask.GEODESICSCALE);
@@ -249,46 +245,48 @@ public GnomonicData Reverse(double lat0, double lon0, double x, double y)
249245

250246
while (count-- > 0)
251247
{
252-
pos =
253-
line.Position(s, GeodesicMask.LONGITUDE | GeodesicMask.LATITUDE
248+
pos = line.Position(s,
249+
GeodesicMask.LONGITUDE | GeodesicMask.LATITUDE
254250
| GeodesicMask.AZIMUTH | GeodesicMask.DISTANCE_IN
255251
| GeodesicMask.REDUCEDLENGTH
256252
| GeodesicMask.GEODESICSCALE);
257253

258254
if (trip > 0)
255+
{
259256
break;
257+
}
260258

261-
double ds =
262-
little ? ((pos.m12 / pos.M12) - rho) * pos.M12 * pos.M12
263-
: (rho - (pos.M12 / pos.m12)) * pos.m12 * pos.m12;
259+
double ds = little ? ((pos.m12 / pos.M12) - rho) * pos.M12 * pos.M12
260+
: (rho - (pos.M12 / pos.m12)) * pos.m12 * pos.m12;
264261
s -= ds;
265262

266-
if (Math.Abs(ds) <= eps_ * _a)
263+
if (Math.Abs(ds) <= eps_ * this.MajorRadius)
264+
{
267265
trip++;
266+
}
268267
}
269268

270269
if (trip == 0)
271-
return rev;
272-
273-
rev.lat = pos.lat2;
274-
rev.lon = pos.lon2;
275-
rev.azi = pos.azi2;
276-
rev.rk = pos.M12;
277-
278-
return rev;
270+
{
271+
return new GnomonicData(lat0, lon0, Double.NaN, Double.NaN, x, y, Double.NaN, Double.NaN);
272+
}
273+
else
274+
{
275+
return new GnomonicData(lat0, lon0, pos.lat2, pos.lon2, x, y, pos.azi2, pos.M12);
276+
}
279277
}
280278

281279
/**
282280
* @return <i>a</i> the equatorial radius of the ellipsoid (meters). This is
283281
* the value inherited from the Geodesic object used in the constructor.
284282
**********************************************************************/
285-
public double MajorRadius => _a;
283+
public double MajorRadius => this.Earth.MajorRadius;
286284

287285
/**
288286
* @return <i>f</i> the flattening of the ellipsoid. This is
289287
* the value inherited from the Geodesic object used in the constructor.
290288
**********************************************************************/
291-
public double Flattening => _f;
289+
public double Flattening => this.Earth.Flattening;
292290
}
293291

294292
}

GeographicLib/GnomonicData.cs

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,48 +23,40 @@ namespace GeographicLib
2323
* and it always includes the fields <i>x</i>, <i>y</i>, <i>azi</i>. and
2424
* <i>rk</i>.
2525
**********************************************************************/
26-
public sealed class GnomonicData
26+
public readonly struct GnomonicData
2727
{
2828
/**
2929
* latitude of center point of projection (degrees).
3030
**********************************************************************/
31-
public double lat0 { get; set; }
31+
public double lat0 { get; }
3232
/**
3333
* longitude of center point of projection (degrees).
3434
**********************************************************************/
35-
public double lon0 { get; set; }
35+
public double lon0 { get; }
3636
/**
3737
* latitude of point (degrees).
3838
**********************************************************************/
39-
public double lat { get; set; }
39+
public double lat { get; }
4040
/**
4141
* longitude of point (degrees).
4242
**********************************************************************/
43-
public double lon { get; set; }
43+
public double lon { get; }
4444
/**
4545
* easting of point (meters).
4646
**********************************************************************/
47-
public double x { get; set; }
47+
public double x { get; }
4848
/**
4949
* northing of point (meters).
5050
**********************************************************************/
51-
public double y { get; set; }
51+
public double y { get; }
5252
/**
5353
* azimuth of geodesic at point (degrees).
5454
**********************************************************************/
55-
public double azi { get; set; }
55+
public double azi { get; }
5656
/**
5757
* reciprocal of azimuthal scale at point.
5858
**********************************************************************/
59-
public double rk { get; set; }
60-
61-
/**
62-
* Initialize all the fields to Double.NaN.
63-
**********************************************************************/
64-
public GnomonicData()
65-
{
66-
lat0 = lon0 = lat = lon = x = y = azi = rk = Double.NaN;
67-
}
59+
public double rk { get; }
6860

6961
/**
7062
* Constructor initializing all the fields for gnomonic projection of a point
@@ -88,8 +80,8 @@ public GnomonicData()
8880
* @param rk
8981
* reciprocal of azimuthal scale at point.
9082
*/
91-
public GnomonicData(double lat0, double lon0, double lat, double lon,
92-
double x, double y, double azi, double rk)
83+
public GnomonicData(double lat0 = double.NaN, double lon0 = double.NaN, double lat = double.NaN, double lon = double.NaN,
84+
double x = double.NaN, double y = double.NaN, double azi = double.NaN, double rk = double.NaN)
9385
{
9486
this.lat0 = lat0;
9587
this.lon0 = lon0;

0 commit comments

Comments
 (0)