NETGeographicLib 1.52
Loading...
Searching...
No Matches
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 * https://geographiclib.sourceforge.io/
11 **********************************************************************/
12
13namespace 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="https://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="https://doi.org/10.1007/s00190-012-0578-z">
28 * 10.1007/s00190-012-0578-z</a>;
29 * addenda: <a href="https://geographiclib.sourceforge.io/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 EquatorialRadius 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;].
94 **********************************************************************/
95 void AddPoint(double lat, double lon);
96
97 /**
98 * Add an edge to the polygon or polyline.
99 *
100 * @param[in] azi azimuth at current point (degrees).
101 * @param[in] s distance from current point to next point (meters).
102 *
103 * This does nothing if no points have been added yet. Use
104 * PolygonArea::CurrentPoint to determine the position of the new
105 * vertex.
106 **********************************************************************/
107 void AddEdge(double azi, double s);
108
109 /**
110 * Return the results so far.
111 *
112 * @param[in] reverse if true then clockwise (instead of counter-clockwise)
113 * traversal counts as a positive area.
114 * @param[in] sign if true then return a signed result for the area if
115 * the polygon is traversed in the "wrong" direction instead of returning
116 * the area for the rest of the earth.
117 * @param[out] perimeter the perimeter of the polygon or length of the
118 * polyline (meters).
119 * @param[out] area the area of the polygon (meters<sup>2</sup>); only set
120 * if \e polyline is false in the constructor.
121 * @return the number of points.
122 **********************************************************************/
123 unsigned Compute(bool reverse, bool sign,
124 [System::Runtime::InteropServices::Out] double% perimeter,
125 [System::Runtime::InteropServices::Out] double% area);
126
127 /**
128 * Return the results assuming a tentative final test point is added;
129 * however, the data for the test point is not saved. This lets you report
130 * a running result for the perimeter and area as the user moves the mouse
131 * cursor. Ordinary floating point arithmetic is used to accumulate the
132 * data for the test point; thus the area and perimeter returned are less
133 * accurate than if PolygonArea::AddPoint and PolygonArea::Compute are
134 * used.
135 *
136 * @param[in] lat the latitude of the test point (degrees).
137 * @param[in] lon the longitude of the test point (degrees).
138 * @param[in] reverse if true then clockwise (instead of counter-clockwise)
139 * traversal counts as a positive area.
140 * @param[in] sign if true then return a signed result for the area if
141 * the polygon is traversed in the "wrong" direction instead of returning
142 * the area for the rest of the earth.
143 * @param[out] perimeter the approximate perimeter of the polygon or length
144 * of the polyline (meters).
145 * @param[out] area the approximate area of the polygon
146 * (meters<sup>2</sup>); only set if polyline is false in the
147 * constructor.
148 * @return the number of points.
149 *
150 * \e lat should be in the range [&minus;90&deg;, 90&deg;].
151 **********************************************************************/
152 unsigned TestPoint(double lat, double lon, bool reverse, bool sign,
153 [System::Runtime::InteropServices::Out] double% perimeter,
154 [System::Runtime::InteropServices::Out] double% area);
155
156 /**
157 * Return the results assuming a tentative final test point is added via an
158 * azimuth and distance; however, the data for the test point is not saved.
159 * This lets you report a running result for the perimeter and area as the
160 * user moves the mouse cursor. Ordinary floating point arithmetic is used
161 * to accumulate the data for the test point; thus the area and perimeter
162 * returned are less accurate than if PolygonArea::AddEdge and
163 * PolygonArea::Compute are used.
164 *
165 * @param[in] azi azimuth at current point (degrees).
166 * @param[in] s distance from current point to final test point (meters).
167 * @param[in] reverse if true then clockwise (instead of counter-clockwise)
168 * traversal counts as a positive area.
169 * @param[in] sign if true then return a signed result for the area if
170 * the polygon is traversed in the "wrong" direction instead of returning
171 * the area for the rest of the earth.
172 * @param[out] perimeter the approximate perimeter of the polygon or length
173 * of the polyline (meters).
174 * @param[out] area the approximate area of the polygon
175 * (meters<sup>2</sup>); only set if polyline is false in the
176 * constructor.
177 * @return the number of points.
178 **********************************************************************/
179 unsigned TestEdge(double azi, double s, bool reverse, bool sign,
180 [System::Runtime::InteropServices::Out] double% perimeter,
181 [System::Runtime::InteropServices::Out] double% area);
182
183 /** \name Inspector functions
184 **********************************************************************/
185 ///@{
186 /**
187 * @return \e a the equatorial radius of the ellipsoid (meters). This is
188 * the value inherited from the Geodesic object used in the constructor.
189 **********************************************************************/
190 property double EquatorialRadius { double get(); }
191
192 /**
193 * @return \e f the flattening of the ellipsoid. This is the value
194 * inherited from the Geodesic object used in the constructor.
195 **********************************************************************/
196 property double Flattening { double get(); }
197
198 /**
199 * Report the previous vertex added to the polygon or polyline.
200 *
201 * @param[out] lat the latitude of the point (degrees).
202 * @param[out] lon the longitude of the point (degrees).
203 *
204 * If no points have been added, then NaNs are returned. Otherwise, \e lon
205 * will be in the range [&minus;180&deg;, 180&deg;).
206 **********************************************************************/
207 void CurrentPoint([System::Runtime::InteropServices::Out] double% lat,
208 [System::Runtime::InteropServices::Out] double% lon);
209 ///@}
210 };
211
212 //*************************************************************************
213 // PolygonAreaExact
214 //*************************************************************************
215 ref class GeodesicExact;
216
217 public ref class PolygonAreaExact
218 {
219 private:
220 // a pointer to the unmanaged GeographicLib::PolygonArea
221 GeographicLib::PolygonAreaExact* m_pPolygonArea;
222
223 // the finalize frees the unmanaged memory when the object is destroyed.
224 !PolygonAreaExact(void);
225 public:
226
227 /**
228 * Constructor for PolygonArea.
229 *
230 * @param[in] earth the Geodesic object to use for geodesic calculations.
231 * @param[in] polyline if true that treat the points as defining a polyline
232 * instead of a polygon.
233 **********************************************************************/
234 PolygonAreaExact(GeodesicExact^ earth, bool polyline );
235
236 /**
237 * Constructor for PolygonArea that assumes a WGS84 ellipsoid.
238 *
239 * @param[in] polyline if true that treat the points as defining a polyline
240 * instead of a polygon.
241 **********************************************************************/
242 PolygonAreaExact(const bool polyline );
243
244 /**
245 * The destructor calls the finalizer.
246 **********************************************************************/
248 { this->!PolygonAreaExact(); }
249
250 /**
251 * Clear PolygonArea, allowing a new polygon to be started.
252 **********************************************************************/
253 void Clear();
254
255 /**
256 * Add a point to the polygon or polyline.
257 *
258 * @param[in] lat the latitude of the point (degrees).
259 * @param[in] lon the longitude of the point (degrees).
260 *
261 * \e lat should be in the range [&minus;90&deg;, 90&deg;].
262 **********************************************************************/
263 void AddPoint(double lat, double lon);
264
265 /**
266 * Add an edge to the polygon or polyline.
267 *
268 * @param[in] azi azimuth at current point (degrees).
269 * @param[in] s distance from current point to next point (meters).
270 *
271 * This does nothing if no points have been added yet. Use
272 * PolygonArea::CurrentPoint to determine the position of the new
273 * vertex.
274 **********************************************************************/
275 void AddEdge(double azi, double s);
276
277 /**
278 * Return the results so far.
279 *
280 * @param[in] reverse if true then clockwise (instead of counter-clockwise)
281 * traversal counts as a positive area.
282 * @param[in] sign if true then return a signed result for the area if
283 * the polygon is traversed in the "wrong" direction instead of returning
284 * the area for the rest of the earth.
285 * @param[out] perimeter the perimeter of the polygon or length of the
286 * polyline (meters).
287 * @param[out] area the area of the polygon (meters<sup>2</sup>); only set
288 * if \e polyline is false in the constructor.
289 * @return the number of points.
290 **********************************************************************/
291 unsigned Compute(bool reverse, bool sign,
292 [System::Runtime::InteropServices::Out] double% perimeter,
293 [System::Runtime::InteropServices::Out] double% area);
294
295 /**
296 * Return the results assuming a tentative final test point is added;
297 * however, the data for the test point is not saved. This lets you report
298 * a running result for the perimeter and area as the user moves the mouse
299 * cursor. Ordinary floating point arithmetic is used to accumulate the
300 * data for the test point; thus the area and perimeter returned are less
301 * accurate than if PolygonArea::AddPoint and PolygonArea::Compute are
302 * used.
303 *
304 * @param[in] lat the latitude of the test point (degrees).
305 * @param[in] lon the longitude of the test point (degrees).
306 * @param[in] reverse if true then clockwise (instead of counter-clockwise)
307 * traversal counts as a positive area.
308 * @param[in] sign if true then return a signed result for the area if
309 * the polygon is traversed in the "wrong" direction instead of returning
310 * the area for the rest of the earth.
311 * @param[out] perimeter the approximate perimeter of the polygon or length
312 * of the polyline (meters).
313 * @param[out] area the approximate area of the polygon
314 * (meters<sup>2</sup>); only set if polyline is false in the
315 * constructor.
316 * @return the number of points.
317 *
318 * \e lat should be in the range [&minus;90&deg;, 90&deg;].
319 **********************************************************************/
320 unsigned TestPoint(double lat, double lon, bool reverse, bool sign,
321 [System::Runtime::InteropServices::Out] double% perimeter,
322 [System::Runtime::InteropServices::Out] double% area);
323
324 /**
325 * Return the results assuming a tentative final test point is added via an
326 * azimuth and distance; however, the data for the test point is not saved.
327 * This lets you report a running result for the perimeter and area as the
328 * user moves the mouse cursor. Ordinary floating point arithmetic is used
329 * to accumulate the data for the test point; thus the area and perimeter
330 * returned are less accurate than if PolygonArea::AddEdge and
331 * PolygonArea::Compute are used.
332 *
333 * @param[in] azi azimuth at current point (degrees).
334 * @param[in] s distance from current point to final test point (meters).
335 * @param[in] reverse if true then clockwise (instead of counter-clockwise)
336 * traversal counts as a positive area.
337 * @param[in] sign if true then return a signed result for the area if
338 * the polygon is traversed in the "wrong" direction instead of returning
339 * the area for the rest of the earth.
340 * @param[out] perimeter the approximate perimeter of the polygon or length
341 * of the polyline (meters).
342 * @param[out] area the approximate area of the polygon
343 * (meters<sup>2</sup>); only set if polyline is false in the
344 * constructor.
345 * @return the number of points.
346 **********************************************************************/
347 unsigned TestEdge(double azi, double s, bool reverse, bool sign,
348 [System::Runtime::InteropServices::Out] double% perimeter,
349 [System::Runtime::InteropServices::Out] double% area);
350
351 /** \name Inspector functions
352 **********************************************************************/
353 ///@{
354 /**
355 * @return \e a the equatorial radius of the ellipsoid (meters). This is
356 * the value inherited from the Geodesic object used in the constructor.
357 **********************************************************************/
358 property double EquatorialRadius { double get(); }
359
360 /**
361 * @return \e f the flattening of the ellipsoid. This is the value
362 * inherited from the Geodesic object used in the constructor.
363 **********************************************************************/
364 property double Flattening { double get(); }
365
366 /**
367 * Report the previous vertex added to the polygon or polyline.
368 *
369 * @param[out] lat the latitude of the point (degrees).
370 * @param[out] lon the longitude of the point (degrees).
371 *
372 * If no points have been added, then NaNs are returned. Otherwise, \e lon
373 * will be in the range [&minus;180&deg;, 180&deg;).
374 **********************************************************************/
375 void CurrentPoint([System::Runtime::InteropServices::Out] double% lat,
376 [System::Runtime::InteropServices::Out] double% lon);
377 ///@}
378 };
379
380 //*************************************************************************
381 // PolygonAreaRhumb
382 //*************************************************************************
383 ref class Rhumb;
384
385 public ref class PolygonAreaRhumb
386 {
387 private:
388 // a pointer to the unmanaged GeographicLib::PolygonArea
389 GeographicLib::PolygonAreaRhumb* m_pPolygonArea;
390
391 // the finalize frees the unmanaged memory when the object is destroyed.
392 !PolygonAreaRhumb(void);
393 public:
394
395 /**
396 * Constructor for PolygonArea.
397 *
398 * @param[in] earth the Geodesic object to use for geodesic calculations.
399 * @param[in] polyline if true that treat the points as defining a polyline
400 * instead of a polygon.
401 **********************************************************************/
402 PolygonAreaRhumb(Rhumb^ earth, bool polyline );
403
404 /**
405 * Constructor for PolygonArea that assumes a WGS84 ellipsoid.
406 *
407 * @param[in] polyline if true that treat the points as defining a polyline
408 * instead of a polygon.
409 **********************************************************************/
410 PolygonAreaRhumb(const bool polyline );
411
412 /**
413 * The destructor calls the finalizer.
414 **********************************************************************/
416 { this->!PolygonAreaRhumb(); }
417
418 /**
419 * Clear PolygonArea, allowing a new polygon to be started.
420 **********************************************************************/
421 void Clear();
422
423 /**
424 * Add a point to the polygon or polyline.
425 *
426 * @param[in] lat the latitude of the point (degrees).
427 * @param[in] lon the longitude of the point (degrees).
428 *
429 * \e lat should be in the range [&minus;90&deg;, 90&deg;].
430 **********************************************************************/
431 void AddPoint(double lat, double lon);
432
433 /**
434 * Add an edge to the polygon or polyline.
435 *
436 * @param[in] azi azimuth at current point (degrees).
437 * @param[in] s distance from current point to next point (meters).
438 *
439 * This does nothing if no points have been added yet. Use
440 * PolygonArea::CurrentPoint to determine the position of the new
441 * vertex.
442 **********************************************************************/
443 void AddEdge(double azi, double s);
444
445 /**
446 * Return the results so far.
447 *
448 * @param[in] reverse if true then clockwise (instead of counter-clockwise)
449 * traversal counts as a positive area.
450 * @param[in] sign if true then return a signed result for the area if
451 * the polygon is traversed in the "wrong" direction instead of returning
452 * the area for the rest of the earth.
453 * @param[out] perimeter the perimeter of the polygon or length of the
454 * polyline (meters).
455 * @param[out] area the area of the polygon (meters<sup>2</sup>); only set
456 * if \e polyline is false in the constructor.
457 * @return the number of points.
458 **********************************************************************/
459 unsigned Compute(bool reverse, bool sign,
460 [System::Runtime::InteropServices::Out] double% perimeter,
461 [System::Runtime::InteropServices::Out] double% area);
462
463 /**
464 * Return the results assuming a tentative final test point is added;
465 * however, the data for the test point is not saved. This lets you report
466 * a running result for the perimeter and area as the user moves the mouse
467 * cursor. Ordinary floating point arithmetic is used to accumulate the
468 * data for the test point; thus the area and perimeter returned are less
469 * accurate than if PolygonArea::AddPoint and PolygonArea::Compute are
470 * used.
471 *
472 * @param[in] lat the latitude of the test point (degrees).
473 * @param[in] lon the longitude of the test point (degrees).
474 * @param[in] reverse if true then clockwise (instead of counter-clockwise)
475 * traversal counts as a positive area.
476 * @param[in] sign if true then return a signed result for the area if
477 * the polygon is traversed in the "wrong" direction instead of returning
478 * the area for the rest of the earth.
479 * @param[out] perimeter the approximate perimeter of the polygon or length
480 * of the polyline (meters).
481 * @param[out] area the approximate area of the polygon
482 * (meters<sup>2</sup>); only set if polyline is false in the
483 * constructor.
484 * @return the number of points.
485 *
486 * \e lat should be in the range [&minus;90&deg;, 90&deg;].
487 **********************************************************************/
488 unsigned TestPoint(double lat, double lon, bool reverse, bool sign,
489 [System::Runtime::InteropServices::Out] double% perimeter,
490 [System::Runtime::InteropServices::Out] double% area);
491
492 /**
493 * Return the results assuming a tentative final test point is added via an
494 * azimuth and distance; however, the data for the test point is not saved.
495 * This lets you report a running result for the perimeter and area as the
496 * user moves the mouse cursor. Ordinary floating point arithmetic is used
497 * to accumulate the data for the test point; thus the area and perimeter
498 * returned are less accurate than if PolygonArea::AddEdge and
499 * PolygonArea::Compute are used.
500 *
501 * @param[in] azi azimuth at current point (degrees).
502 * @param[in] s distance from current point to final test point (meters).
503 * @param[in] reverse if true then clockwise (instead of counter-clockwise)
504 * traversal counts as a positive area.
505 * @param[in] sign if true then return a signed result for the area if
506 * the polygon is traversed in the "wrong" direction instead of returning
507 * the area for the rest of the earth.
508 * @param[out] perimeter the approximate perimeter of the polygon or length
509 * of the polyline (meters).
510 * @param[out] area the approximate area of the polygon
511 * (meters<sup>2</sup>); only set if polyline is false in the
512 * constructor.
513 * @return the number of points.
514 **********************************************************************/
515 unsigned TestEdge(double azi, double s, bool reverse, bool sign,
516 [System::Runtime::InteropServices::Out] double% perimeter,
517 [System::Runtime::InteropServices::Out] double% area);
518
519 /** \name Inspector functions
520 **********************************************************************/
521 ///@{
522 /**
523 * @return \e a the equatorial radius of the ellipsoid (meters). This is
524 * the value inherited from the Geodesic object used in the constructor.
525 **********************************************************************/
526 property double EquatorialRadius { double get(); }
527
528 /**
529 * @return \e f the flattening of the ellipsoid. This is the value
530 * inherited from the Geodesic object used in the constructor.
531 **********************************************************************/
532 property double Flattening { double get(); }
533
534 /**
535 * Report the previous vertex added to the polygon or polyline.
536 *
537 * @param[out] lat the latitude of the point (degrees).
538 * @param[out] lon the longitude of the point (degrees).
539 *
540 * If no points have been added, then NaNs are returned. Otherwise, \e lon
541 * will be in the range [&minus;180&deg;, 180&deg;).
542 **********************************************************************/
543 void CurrentPoint([System::Runtime::InteropServices::Out] double% lat,
544 [System::Runtime::InteropServices::Out] double% lon);
545 ///@}
546 };
547} // namespace NETGeographicLib
.NET wrapper for GeographicLib::GeodesicExact.
Definition: GeodesicExact.h:87
.NET wrapper for GeographicLib::Geodesic.
Definition: Geodesic.h:171
void AddEdge(double azi, double s)
unsigned Compute(bool reverse, bool sign, [System::Runtime::InteropServices::Out] double% perimeter, [System::Runtime::InteropServices::Out] double% area)
PolygonAreaExact(GeodesicExact^ earth, bool polyline)
PolygonAreaExact(const bool polyline)
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 TestPoint(double lat, double lon, bool reverse, bool sign, [System::Runtime::InteropServices::Out] double% perimeter, [System::Runtime::InteropServices::Out] double% area)
void CurrentPoint([System::Runtime::InteropServices::Out] double% lat, [System::Runtime::InteropServices::Out] double% lon)
unsigned Compute(bool reverse, bool sign, [System::Runtime::InteropServices::Out] double% perimeter, [System::Runtime::InteropServices::Out] double% area)
PolygonAreaRhumb(const bool polyline)
PolygonAreaRhumb(Rhumb^ earth, bool polyline)
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)
void AddEdge(double azi, double s)
void AddPoint(double lat, double lon)
void CurrentPoint([System::Runtime::InteropServices::Out] double% lat, [System::Runtime::InteropServices::Out] double% lon)
.NET wrapper for GeographicLib::PolygonArea and PolygonAreaExact.
Definition: PolygonArea.h:50
void AddPoint(double lat, double lon)
void CurrentPoint([System::Runtime::InteropServices::Out] double% lat, [System::Runtime::InteropServices::Out] double% lon)
unsigned Compute(bool reverse, bool sign, [System::Runtime::InteropServices::Out] double% perimeter, [System::Runtime::InteropServices::Out] double% area)
unsigned TestPoint(double lat, double lon, bool reverse, bool sign, [System::Runtime::InteropServices::Out] double% perimeter, [System::Runtime::InteropServices::Out] double% area)
void AddEdge(double azi, double s)
PolygonArea(Geodesic^ earth, bool polyline)
PolygonArea(const bool polyline)
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::Rhumb.
Definition: Rhumb.h:65