NETGeographicLib  1.38
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Pages
PolygonArea.h
Go to the documentation of this file.
1 #pragma once
2 /**
3  * \file NETGeographicLib/PolygonArea.h
4  * \brief Header for NETGeographicLib::PolygonArea class
5  *
6  * NETGeographicLib is copyright (c) Scott Heiman (2013)
7  * GeographicLib is Copyright (c) Charles Karney (2010-2012)
8  * <charles@karney.com> and licensed under the MIT/X11 License.
9  * For more information, see
10  * http://geographiclib.sourceforge.net/
11  **********************************************************************/
12 
13 namespace NETGeographicLib
14 {
15  ref class Geodesic;
16  /**
17  * \brief .NET wrapper for GeographicLib::PolygonArea and PolygonAreaExact.
18  *
19  * This class allows .NET applications to access GeographicLib::PolygonArea.
20  *
21  * This computes the area of a geodesic polygon using the method given
22  * Section 6 of
23  * - C. F. F. Karney,
24  * <a href="http://dx.doi.org/10.1007/s00190-012-0578-z">
25  * Algorithms for geodesics</a>,
26  * J. Geodesy <b>87</b>, 43--55 (2013);
27  * DOI: <a href="http://dx.doi.org/10.1007/s00190-012-0578-z">
28  * 10.1007/s00190-012-0578-z</a>;
29  * addenda: <a href="http://geographiclib.sf.net/geod-addenda.html">
30  * geod-addenda.html</a>.
31  *
32  * This class lets you add vertices one at a time to the polygon. The area
33  * and perimeter are accumulated in two times the standard floating point
34  * precision to guard against the loss of accuracy with many-sided polygons.
35  * At any point you can ask for the perimeter and area so far. There's an
36  * option to treat the points as defining a polyline instead of a polygon; in
37  * that case, only the perimeter is computed.
38  *
39  * C# Example:
40  * \include example-PolygonArea.cs
41  * Managed C++ Example:
42  * \include example-PolygonArea.cpp
43  * Visual Basic Example:
44  * \include example-PolygonArea.vb
45  *
46  * <B>INTERFACE DIFFERENCES:</B><BR>
47  * The MajorRadius and Flattening functions are implemented as properties.
48  **********************************************************************/
49  public ref class PolygonArea
50  {
51  private:
52  // a pointer to the unmanaged GeographicLib::PolygonArea
53  GeographicLib::PolygonArea* m_pPolygonArea;
54 
55  // the finalize frees the unmanaged memory when the object is destroyed.
56  !PolygonArea(void);
57  public:
58 
59  /**
60  * Constructor for PolygonArea.
61  *
62  * @param[in] earth the Geodesic object to use for geodesic calculations.
63  * @param[in] polyline if true that treat the points as defining a polyline
64  * instead of a polygon.
65  **********************************************************************/
66  PolygonArea(Geodesic^ earth, bool polyline );
67 
68  /**
69  * Constructor for PolygonArea that assumes a WGS84 ellipsoid.
70  *
71  * @param[in] polyline if true that treat the points as defining a polyline
72  * instead of a polygon.
73  **********************************************************************/
74  PolygonArea(const bool polyline );
75 
76  /**
77  * The destructor calls the finalizer.
78  **********************************************************************/
80  { this->!PolygonArea(); }
81 
82  /**
83  * Clear PolygonArea, allowing a new polygon to be started.
84  **********************************************************************/
85  void Clear();
86 
87  /**
88  * Add a point to the polygon or polyline.
89  *
90  * @param[in] lat the latitude of the point (degrees).
91  * @param[in] lon the longitude of the point (degrees).
92  *
93  * \e lat should be in the range [&minus;90&deg;, 90&deg;] and \e
94  * lon should be in the range [&minus;540&deg;, 540&deg;).
95  **********************************************************************/
96  void AddPoint(double lat, double lon);
97 
98  /**
99  * Add an edge to the polygon or polyline.
100  *
101  * @param[in] azi azimuth at current point (degrees).
102  * @param[in] s distance from current point to next point (meters).
103  *
104  * \e azi should be in the range [&minus;540&deg;, 540&deg;). This does
105  * nothing if no points have been added yet. Use PolygonArea::CurrentPoint
106  * to determine the position of the new vertex.
107  **********************************************************************/
108  void AddEdge(double azi, double s);
109 
110  /**
111  * Return the results so far.
112  *
113  * @param[in] reverse if true then clockwise (instead of counter-clockwise)
114  * traversal counts as a positive area.
115  * @param[in] sign if true then return a signed result for the area if
116  * the polygon is traversed in the "wrong" direction instead of returning
117  * the area for the rest of the earth.
118  * @param[out] perimeter the perimeter of the polygon or length of the
119  * polyline (meters).
120  * @param[out] area the area of the polygon (meters<sup>2</sup>); only set
121  * if \e polyline is false in the constructor.
122  * @return the number of points.
123  **********************************************************************/
124  unsigned Compute(bool reverse, bool sign,
125  [System::Runtime::InteropServices::Out] double% perimeter,
126  [System::Runtime::InteropServices::Out] double% area);
127 
128  /**
129  * Return the results assuming a tentative final test point is added;
130  * however, the data for the test point is not saved. This lets you report
131  * a running result for the perimeter and area as the user moves the mouse
132  * cursor. Ordinary floating point arithmetic is used to accumulate the
133  * data for the test point; thus the area and perimeter returned are less
134  * accurate than if PolygonArea::AddPoint and PolygonArea::Compute are
135  * used.
136  *
137  * @param[in] lat the latitude of the test point (degrees).
138  * @param[in] lon the longitude of the test point (degrees).
139  * @param[in] reverse if true then clockwise (instead of counter-clockwise)
140  * traversal counts as a positive area.
141  * @param[in] sign if true then return a signed result for the area if
142  * the polygon is traversed in the "wrong" direction instead of returning
143  * the area for the rest of the earth.
144  * @param[out] perimeter the approximate perimeter of the polygon or length
145  * of the polyline (meters).
146  * @param[out] area the approximate area of the polygon
147  * (meters<sup>2</sup>); only set if polyline is false in the
148  * constructor.
149  * @return the number of points.
150  *
151  * \e lat should be in the range [&minus;90&deg;, 90&deg;] and \e
152  * lon should be in the range [&minus;540&deg;, 540&deg;).
153  **********************************************************************/
154  unsigned TestPoint(double lat, double lon, bool reverse, bool sign,
155  [System::Runtime::InteropServices::Out] double% perimeter,
156  [System::Runtime::InteropServices::Out] double% area);
157 
158  /**
159  * Return the results assuming a tentative final test point is added via an
160  * azimuth and distance; however, the data for the test point is not saved.
161  * This lets you report a running result for the perimeter and area as the
162  * user moves the mouse cursor. Ordinary floating point arithmetic is used
163  * to accumulate the data for the test point; thus the area and perimeter
164  * returned are less accurate than if PolygonArea::AddEdge and
165  * PolygonArea::Compute are used.
166  *
167  * @param[in] azi azimuth at current point (degrees).
168  * @param[in] s distance from current point to final test point (meters).
169  * @param[in] reverse if true then clockwise (instead of counter-clockwise)
170  * traversal counts as a positive area.
171  * @param[in] sign if true then return a signed result for the area if
172  * the polygon is traversed in the "wrong" direction instead of returning
173  * the area for the rest of the earth.
174  * @param[out] perimeter the approximate perimeter of the polygon or length
175  * of the polyline (meters).
176  * @param[out] area the approximate area of the polygon
177  * (meters<sup>2</sup>); only set if polyline is false in the
178  * constructor.
179  * @return the number of points.
180  *
181  * \e azi should be in the range [&minus;540&deg;, 540&deg;).
182  **********************************************************************/
183  unsigned TestEdge(double azi, double s, bool reverse, bool sign,
184  [System::Runtime::InteropServices::Out] double% perimeter,
185  [System::Runtime::InteropServices::Out] double% area);
186 
187  /** \name Inspector functions
188  **********************************************************************/
189  ///@{
190  /**
191  * @return \e a the equatorial radius of the ellipsoid (meters). This is
192  * the value inherited from the Geodesic object used in the constructor.
193  **********************************************************************/
194  property double MajorRadius { double get(); }
195 
196  /**
197  * @return \e f the flattening of the ellipsoid. This is the value
198  * inherited from the Geodesic object used in the constructor.
199  **********************************************************************/
200  property double Flattening { double get(); }
201 
202  /**
203  * Report the previous vertex added to the polygon or polyline.
204  *
205  * @param[out] lat the latitude of the point (degrees).
206  * @param[out] lon the longitude of the point (degrees).
207  *
208  * If no points have been added, then NaNs are returned. Otherwise, \e lon
209  * will be in the range [&minus;180&deg;, 180&deg;).
210  **********************************************************************/
211  void CurrentPoint([System::Runtime::InteropServices::Out] double% lat,
212  [System::Runtime::InteropServices::Out] double% lon);
213  ///@}
214  };
215 
216  //*************************************************************************
217  // PolygonAreaExact
218  //*************************************************************************
219  ref class GeodesicExact;
220 
221  public ref class PolygonAreaExact
222  {
223  private:
224  // a pointer to the unmanaged GeographicLib::PolygonArea
225  GeographicLib::PolygonAreaExact* m_pPolygonArea;
226 
227  // the finalize frees the unmanaged memory when the object is destroyed.
228  !PolygonAreaExact(void);
229  public:
230 
231  /**
232  * Constructor for PolygonArea.
233  *
234  * @param[in] earth the Geodesic object to use for geodesic calculations.
235  * @param[in] polyline if true that treat the points as defining a polyline
236  * instead of a polygon.
237  **********************************************************************/
238  PolygonAreaExact(GeodesicExact^ earth, bool polyline );
239 
240  /**
241  * Constructor for PolygonArea that assumes a WGS84 ellipsoid.
242  *
243  * @param[in] polyline if true that treat the points as defining a polyline
244  * instead of a polygon.
245  **********************************************************************/
246  PolygonAreaExact(const bool polyline );
247 
248  /**
249  * The destructor calls the finalizer.
250  **********************************************************************/
252  { this->!PolygonAreaExact(); }
253 
254  /**
255  * Clear PolygonArea, allowing a new polygon to be started.
256  **********************************************************************/
257  void Clear();
258 
259  /**
260  * Add a point to the polygon or polyline.
261  *
262  * @param[in] lat the latitude of the point (degrees).
263  * @param[in] lon the longitude of the point (degrees).
264  *
265  * \e lat should be in the range [&minus;90&deg;, 90&deg;] and \e
266  * lon should be in the range [&minus;540&deg;, 540&deg;).
267  **********************************************************************/
268  void AddPoint(double lat, double lon);
269 
270  /**
271  * Add an edge to the polygon or polyline.
272  *
273  * @param[in] azi azimuth at current point (degrees).
274  * @param[in] s distance from current point to next point (meters).
275  *
276  * \e azi should be in the range [&minus;540&deg;, 540&deg;). This does
277  * nothing if no points have been added yet. Use PolygonArea::CurrentPoint
278  * to determine the position of the new vertex.
279  **********************************************************************/
280  void AddEdge(double azi, double s);
281 
282  /**
283  * Return the results so far.
284  *
285  * @param[in] reverse if true then clockwise (instead of counter-clockwise)
286  * traversal counts as a positive area.
287  * @param[in] sign if true then return a signed result for the area if
288  * the polygon is traversed in the "wrong" direction instead of returning
289  * the area for the rest of the earth.
290  * @param[out] perimeter the perimeter of the polygon or length of the
291  * polyline (meters).
292  * @param[out] area the area of the polygon (meters<sup>2</sup>); only set
293  * if \e polyline is false in the constructor.
294  * @return the number of points.
295  **********************************************************************/
296  unsigned Compute(bool reverse, bool sign,
297  [System::Runtime::InteropServices::Out] double% perimeter,
298  [System::Runtime::InteropServices::Out] double% area);
299 
300  /**
301  * Return the results assuming a tentative final test point is added;
302  * however, the data for the test point is not saved. This lets you report
303  * a running result for the perimeter and area as the user moves the mouse
304  * cursor. Ordinary floating point arithmetic is used to accumulate the
305  * data for the test point; thus the area and perimeter returned are less
306  * accurate than if PolygonArea::AddPoint and PolygonArea::Compute are
307  * used.
308  *
309  * @param[in] lat the latitude of the test point (degrees).
310  * @param[in] lon the longitude of the test point (degrees).
311  * @param[in] reverse if true then clockwise (instead of counter-clockwise)
312  * traversal counts as a positive area.
313  * @param[in] sign if true then return a signed result for the area if
314  * the polygon is traversed in the "wrong" direction instead of returning
315  * the area for the rest of the earth.
316  * @param[out] perimeter the approximate perimeter of the polygon or length
317  * of the polyline (meters).
318  * @param[out] area the approximate area of the polygon
319  * (meters<sup>2</sup>); only set if polyline is false in the
320  * constructor.
321  * @return the number of points.
322  *
323  * \e lat should be in the range [&minus;90&deg;, 90&deg;] and \e
324  * lon should be in the range [&minus;540&deg;, 540&deg;).
325  **********************************************************************/
326  unsigned TestPoint(double lat, double lon, bool reverse, bool sign,
327  [System::Runtime::InteropServices::Out] double% perimeter,
328  [System::Runtime::InteropServices::Out] double% area);
329 
330  /**
331  * Return the results assuming a tentative final test point is added via an
332  * azimuth and distance; however, the data for the test point is not saved.
333  * This lets you report a running result for the perimeter and area as the
334  * user moves the mouse cursor. Ordinary floating point arithmetic is used
335  * to accumulate the data for the test point; thus the area and perimeter
336  * returned are less accurate than if PolygonArea::AddEdge and
337  * PolygonArea::Compute are used.
338  *
339  * @param[in] azi azimuth at current point (degrees).
340  * @param[in] s distance from current point to final test point (meters).
341  * @param[in] reverse if true then clockwise (instead of counter-clockwise)
342  * traversal counts as a positive area.
343  * @param[in] sign if true then return a signed result for the area if
344  * the polygon is traversed in the "wrong" direction instead of returning
345  * the area for the rest of the earth.
346  * @param[out] perimeter the approximate perimeter of the polygon or length
347  * of the polyline (meters).
348  * @param[out] area the approximate area of the polygon
349  * (meters<sup>2</sup>); only set if polyline is false in the
350  * constructor.
351  * @return the number of points.
352  *
353  * \e azi should be in the range [&minus;540&deg;, 540&deg;).
354  **********************************************************************/
355  unsigned TestEdge(double azi, double s, bool reverse, bool sign,
356  [System::Runtime::InteropServices::Out] double% perimeter,
357  [System::Runtime::InteropServices::Out] double% area);
358 
359  /** \name Inspector functions
360  **********************************************************************/
361  ///@{
362  /**
363  * @return \e a the equatorial radius of the ellipsoid (meters). This is
364  * the value inherited from the Geodesic object used in the constructor.
365  **********************************************************************/
366  property double MajorRadius { double get(); }
367 
368  /**
369  * @return \e f the flattening of the ellipsoid. This is the value
370  * inherited from the Geodesic object used in the constructor.
371  **********************************************************************/
372  property double Flattening { double get(); }
373 
374  /**
375  * Report the previous vertex added to the polygon or polyline.
376  *
377  * @param[out] lat the latitude of the point (degrees).
378  * @param[out] lon the longitude of the point (degrees).
379  *
380  * If no points have been added, then NaNs are returned. Otherwise, \e lon
381  * will be in the range [&minus;180&deg;, 180&deg;).
382  **********************************************************************/
383  void CurrentPoint([System::Runtime::InteropServices::Out] double% lat,
384  [System::Runtime::InteropServices::Out] double% lon);
385  ///@}
386  };
387 } // namespace NETGeographicLib
unsigned Compute(bool reverse, bool sign, [System::Runtime::InteropServices::Out] double% perimeter, [System::Runtime::InteropServices::Out] double% area)
unsigned TestEdge(double azi, double s, bool reverse, bool sign, [System::Runtime::InteropServices::Out] double% perimeter, [System::Runtime::InteropServices::Out] double% area)
void AddPoint(double lat, double lon)
unsigned Compute(bool reverse, bool sign, [System::Runtime::InteropServices::Out] double% perimeter, [System::Runtime::InteropServices::Out] double% area)
void AddEdge(double azi, double s)
PolygonAreaExact(GeodesicExact^ earth, bool polyline)
.NET wrapper for GeographicLib::PolygonArea and PolygonAreaExact.
Definition: PolygonArea.h:49
void CurrentPoint([System::Runtime::InteropServices::Out] double% lat, [System::Runtime::InteropServices::Out] double% lon)
unsigned TestPoint(double lat, double lon, bool reverse, bool sign, [System::Runtime::InteropServices::Out] double% perimeter, [System::Runtime::InteropServices::Out] double% area)
unsigned TestEdge(double azi, double s, bool reverse, bool sign, [System::Runtime::InteropServices::Out] double% perimeter, [System::Runtime::InteropServices::Out] double% area)
.NET wrapper for GeographicLib::Geodesic.
Definition: Geodesic.h:167
PolygonArea(Geodesic^ earth, bool polyline)
void AddPoint(double lat, double lon)
unsigned TestPoint(double lat, double lon, bool reverse, bool sign, [System::Runtime::InteropServices::Out] double% perimeter, [System::Runtime::InteropServices::Out] double% area)
.NET wrapper for GeographicLib::GeodesicExact.
Definition: GeodesicExact.h:86
void AddEdge(double azi, double s)
void CurrentPoint([System::Runtime::InteropServices::Out] double% lat, [System::Runtime::InteropServices::Out] double% lon)