#pragma once /** * \file NETGeographicLib/PolygonArea.h * \brief Header for NETGeographicLib::PolygonArea class * * NETGeographicLib is copyright (c) Scott Heiman (2013) * GeographicLib is Copyright (c) Charles Karney (2010-2012) * and licensed under the MIT/X11 License. * For more information, see * https://geographiclib.sourceforge.io/ **********************************************************************/ namespace NETGeographicLib { ref class Geodesic; /** * \brief .NET wrapper for GeographicLib::PolygonArea and PolygonAreaExact. * * This class allows .NET applications to access GeographicLib::PolygonArea. * * This computes the area of a geodesic polygon using the method given * Section 6 of * - C. F. F. Karney, * * Algorithms for geodesics, * J. Geodesy 87, 43--55 (2013); * DOI: * 10.1007/s00190-012-0578-z; * addenda: * geod-addenda.html. * * This class lets you add vertices one at a time to the polygon. The area * and perimeter are accumulated in two times the standard floating point * precision to guard against the loss of accuracy with many-sided polygons. * At any point you can ask for the perimeter and area so far. There's an * option to treat the points as defining a polyline instead of a polygon; in * that case, only the perimeter is computed. * * C# Example: * \include example-PolygonArea.cs * Managed C++ Example: * \include example-PolygonArea.cpp * Visual Basic Example: * \include example-PolygonArea.vb * * INTERFACE DIFFERENCES:
* The EquatorialRadius and Flattening functions are implemented as properties. **********************************************************************/ public ref class PolygonArea { private: // a pointer to the unmanaged GeographicLib::PolygonArea GeographicLib::PolygonArea* m_pPolygonArea; // the finalize frees the unmanaged memory when the object is destroyed. !PolygonArea(void); public: /** * Constructor for PolygonArea. * * @param[in] earth the Geodesic object to use for geodesic calculations. * @param[in] polyline if true that treat the points as defining a polyline * instead of a polygon. **********************************************************************/ PolygonArea(Geodesic^ earth, bool polyline ); /** * Constructor for PolygonArea that assumes a WGS84 ellipsoid. * * @param[in] polyline if true that treat the points as defining a polyline * instead of a polygon. **********************************************************************/ PolygonArea(const bool polyline ); /** * The destructor calls the finalizer. **********************************************************************/ ~PolygonArea() { this->!PolygonArea(); } /** * Clear PolygonArea, allowing a new polygon to be started. **********************************************************************/ void Clear(); /** * Add a point to the polygon or polyline. * * @param[in] lat the latitude of the point (degrees). * @param[in] lon the longitude of the point (degrees). * * \e lat should be in the range [−90°, 90°]. **********************************************************************/ void AddPoint(double lat, double lon); /** * Add an edge to the polygon or polyline. * * @param[in] azi azimuth at current point (degrees). * @param[in] s distance from current point to next point (meters). * * This does nothing if no points have been added yet. Use * PolygonArea::CurrentPoint to determine the position of the new * vertex. **********************************************************************/ void AddEdge(double azi, double s); /** * Return the results so far. * * @param[in] reverse if true then clockwise (instead of counter-clockwise) * traversal counts as a positive area. * @param[in] sign if true then return a signed result for the area if * the polygon is traversed in the "wrong" direction instead of returning * the area for the rest of the earth. * @param[out] perimeter the perimeter of the polygon or length of the * polyline (meters). * @param[out] area the area of the polygon (meters2); only set * if \e polyline is false in the constructor. * @return the number of points. **********************************************************************/ unsigned Compute(bool reverse, bool sign, [System::Runtime::InteropServices::Out] double% perimeter, [System::Runtime::InteropServices::Out] double% area); /** * Return the results assuming a tentative final test point is added; * however, the data for the test point is not saved. This lets you report * a running result for the perimeter and area as the user moves the mouse * cursor. Ordinary floating point arithmetic is used to accumulate the * data for the test point; thus the area and perimeter returned are less * accurate than if PolygonArea::AddPoint and PolygonArea::Compute are * used. * * @param[in] lat the latitude of the test point (degrees). * @param[in] lon the longitude of the test point (degrees). * @param[in] reverse if true then clockwise (instead of counter-clockwise) * traversal counts as a positive area. * @param[in] sign if true then return a signed result for the area if * the polygon is traversed in the "wrong" direction instead of returning * the area for the rest of the earth. * @param[out] perimeter the approximate perimeter of the polygon or length * of the polyline (meters). * @param[out] area the approximate area of the polygon * (meters2); only set if polyline is false in the * constructor. * @return the number of points. * * \e lat should be in the range [−90°, 90°]. **********************************************************************/ unsigned TestPoint(double lat, double lon, bool reverse, bool sign, [System::Runtime::InteropServices::Out] double% perimeter, [System::Runtime::InteropServices::Out] double% area); /** * Return the results assuming a tentative final test point is added via an * azimuth and distance; however, the data for the test point is not saved. * This lets you report a running result for the perimeter and area as the * user moves the mouse cursor. Ordinary floating point arithmetic is used * to accumulate the data for the test point; thus the area and perimeter * returned are less accurate than if PolygonArea::AddEdge and * PolygonArea::Compute are used. * * @param[in] azi azimuth at current point (degrees). * @param[in] s distance from current point to final test point (meters). * @param[in] reverse if true then clockwise (instead of counter-clockwise) * traversal counts as a positive area. * @param[in] sign if true then return a signed result for the area if * the polygon is traversed in the "wrong" direction instead of returning * the area for the rest of the earth. * @param[out] perimeter the approximate perimeter of the polygon or length * of the polyline (meters). * @param[out] area the approximate area of the polygon * (meters2); only set if polyline is false in the * constructor. * @return the number of points. **********************************************************************/ unsigned TestEdge(double azi, double s, bool reverse, bool sign, [System::Runtime::InteropServices::Out] double% perimeter, [System::Runtime::InteropServices::Out] double% area); /** \name Inspector functions **********************************************************************/ ///@{ /** * @return \e a the equatorial radius of the ellipsoid (meters). This is * the value inherited from the Geodesic object used in the constructor. **********************************************************************/ property double EquatorialRadius { double get(); } /** * @return \e f the flattening of the ellipsoid. This is the value * inherited from the Geodesic object used in the constructor. **********************************************************************/ property double Flattening { double get(); } /** * Report the previous vertex added to the polygon or polyline. * * @param[out] lat the latitude of the point (degrees). * @param[out] lon the longitude of the point (degrees). * * If no points have been added, then NaNs are returned. Otherwise, \e lon * will be in the range [−180°, 180°). **********************************************************************/ void CurrentPoint([System::Runtime::InteropServices::Out] double% lat, [System::Runtime::InteropServices::Out] double% lon); ///@} }; //************************************************************************* // PolygonAreaExact //************************************************************************* ref class GeodesicExact; public ref class PolygonAreaExact { private: // a pointer to the unmanaged GeographicLib::PolygonArea GeographicLib::PolygonAreaExact* m_pPolygonArea; // the finalize frees the unmanaged memory when the object is destroyed. !PolygonAreaExact(void); public: /** * Constructor for PolygonArea. * * @param[in] earth the Geodesic object to use for geodesic calculations. * @param[in] polyline if true that treat the points as defining a polyline * instead of a polygon. **********************************************************************/ PolygonAreaExact(GeodesicExact^ earth, bool polyline ); /** * Constructor for PolygonArea that assumes a WGS84 ellipsoid. * * @param[in] polyline if true that treat the points as defining a polyline * instead of a polygon. **********************************************************************/ PolygonAreaExact(const bool polyline ); /** * The destructor calls the finalizer. **********************************************************************/ ~PolygonAreaExact() { this->!PolygonAreaExact(); } /** * Clear PolygonArea, allowing a new polygon to be started. **********************************************************************/ void Clear(); /** * Add a point to the polygon or polyline. * * @param[in] lat the latitude of the point (degrees). * @param[in] lon the longitude of the point (degrees). * * \e lat should be in the range [−90°, 90°]. **********************************************************************/ void AddPoint(double lat, double lon); /** * Add an edge to the polygon or polyline. * * @param[in] azi azimuth at current point (degrees). * @param[in] s distance from current point to next point (meters). * * This does nothing if no points have been added yet. Use * PolygonArea::CurrentPoint to determine the position of the new * vertex. **********************************************************************/ void AddEdge(double azi, double s); /** * Return the results so far. * * @param[in] reverse if true then clockwise (instead of counter-clockwise) * traversal counts as a positive area. * @param[in] sign if true then return a signed result for the area if * the polygon is traversed in the "wrong" direction instead of returning * the area for the rest of the earth. * @param[out] perimeter the perimeter of the polygon or length of the * polyline (meters). * @param[out] area the area of the polygon (meters2); only set * if \e polyline is false in the constructor. * @return the number of points. **********************************************************************/ unsigned Compute(bool reverse, bool sign, [System::Runtime::InteropServices::Out] double% perimeter, [System::Runtime::InteropServices::Out] double% area); /** * Return the results assuming a tentative final test point is added; * however, the data for the test point is not saved. This lets you report * a running result for the perimeter and area as the user moves the mouse * cursor. Ordinary floating point arithmetic is used to accumulate the * data for the test point; thus the area and perimeter returned are less * accurate than if PolygonArea::AddPoint and PolygonArea::Compute are * used. * * @param[in] lat the latitude of the test point (degrees). * @param[in] lon the longitude of the test point (degrees). * @param[in] reverse if true then clockwise (instead of counter-clockwise) * traversal counts as a positive area. * @param[in] sign if true then return a signed result for the area if * the polygon is traversed in the "wrong" direction instead of returning * the area for the rest of the earth. * @param[out] perimeter the approximate perimeter of the polygon or length * of the polyline (meters). * @param[out] area the approximate area of the polygon * (meters2); only set if polyline is false in the * constructor. * @return the number of points. * * \e lat should be in the range [−90°, 90°]. **********************************************************************/ unsigned TestPoint(double lat, double lon, bool reverse, bool sign, [System::Runtime::InteropServices::Out] double% perimeter, [System::Runtime::InteropServices::Out] double% area); /** * Return the results assuming a tentative final test point is added via an * azimuth and distance; however, the data for the test point is not saved. * This lets you report a running result for the perimeter and area as the * user moves the mouse cursor. Ordinary floating point arithmetic is used * to accumulate the data for the test point; thus the area and perimeter * returned are less accurate than if PolygonArea::AddEdge and * PolygonArea::Compute are used. * * @param[in] azi azimuth at current point (degrees). * @param[in] s distance from current point to final test point (meters). * @param[in] reverse if true then clockwise (instead of counter-clockwise) * traversal counts as a positive area. * @param[in] sign if true then return a signed result for the area if * the polygon is traversed in the "wrong" direction instead of returning * the area for the rest of the earth. * @param[out] perimeter the approximate perimeter of the polygon or length * of the polyline (meters). * @param[out] area the approximate area of the polygon * (meters2); only set if polyline is false in the * constructor. * @return the number of points. **********************************************************************/ unsigned TestEdge(double azi, double s, bool reverse, bool sign, [System::Runtime::InteropServices::Out] double% perimeter, [System::Runtime::InteropServices::Out] double% area); /** \name Inspector functions **********************************************************************/ ///@{ /** * @return \e a the equatorial radius of the ellipsoid (meters). This is * the value inherited from the Geodesic object used in the constructor. **********************************************************************/ property double EquatorialRadius { double get(); } /** * @return \e f the flattening of the ellipsoid. This is the value * inherited from the Geodesic object used in the constructor. **********************************************************************/ property double Flattening { double get(); } /** * Report the previous vertex added to the polygon or polyline. * * @param[out] lat the latitude of the point (degrees). * @param[out] lon the longitude of the point (degrees). * * If no points have been added, then NaNs are returned. Otherwise, \e lon * will be in the range [−180°, 180°). **********************************************************************/ void CurrentPoint([System::Runtime::InteropServices::Out] double% lat, [System::Runtime::InteropServices::Out] double% lon); ///@} }; //************************************************************************* // PolygonAreaRhumb //************************************************************************* ref class Rhumb; public ref class PolygonAreaRhumb { private: // a pointer to the unmanaged GeographicLib::PolygonArea GeographicLib::PolygonAreaRhumb* m_pPolygonArea; // the finalize frees the unmanaged memory when the object is destroyed. !PolygonAreaRhumb(void); public: /** * Constructor for PolygonArea. * * @param[in] earth the Geodesic object to use for geodesic calculations. * @param[in] polyline if true that treat the points as defining a polyline * instead of a polygon. **********************************************************************/ PolygonAreaRhumb(Rhumb^ earth, bool polyline ); /** * Constructor for PolygonArea that assumes a WGS84 ellipsoid. * * @param[in] polyline if true that treat the points as defining a polyline * instead of a polygon. **********************************************************************/ PolygonAreaRhumb(const bool polyline ); /** * The destructor calls the finalizer. **********************************************************************/ ~PolygonAreaRhumb() { this->!PolygonAreaRhumb(); } /** * Clear PolygonArea, allowing a new polygon to be started. **********************************************************************/ void Clear(); /** * Add a point to the polygon or polyline. * * @param[in] lat the latitude of the point (degrees). * @param[in] lon the longitude of the point (degrees). * * \e lat should be in the range [−90°, 90°]. **********************************************************************/ void AddPoint(double lat, double lon); /** * Add an edge to the polygon or polyline. * * @param[in] azi azimuth at current point (degrees). * @param[in] s distance from current point to next point (meters). * * This does nothing if no points have been added yet. Use * PolygonArea::CurrentPoint to determine the position of the new * vertex. **********************************************************************/ void AddEdge(double azi, double s); /** * Return the results so far. * * @param[in] reverse if true then clockwise (instead of counter-clockwise) * traversal counts as a positive area. * @param[in] sign if true then return a signed result for the area if * the polygon is traversed in the "wrong" direction instead of returning * the area for the rest of the earth. * @param[out] perimeter the perimeter of the polygon or length of the * polyline (meters). * @param[out] area the area of the polygon (meters2); only set * if \e polyline is false in the constructor. * @return the number of points. **********************************************************************/ unsigned Compute(bool reverse, bool sign, [System::Runtime::InteropServices::Out] double% perimeter, [System::Runtime::InteropServices::Out] double% area); /** * Return the results assuming a tentative final test point is added; * however, the data for the test point is not saved. This lets you report * a running result for the perimeter and area as the user moves the mouse * cursor. Ordinary floating point arithmetic is used to accumulate the * data for the test point; thus the area and perimeter returned are less * accurate than if PolygonArea::AddPoint and PolygonArea::Compute are * used. * * @param[in] lat the latitude of the test point (degrees). * @param[in] lon the longitude of the test point (degrees). * @param[in] reverse if true then clockwise (instead of counter-clockwise) * traversal counts as a positive area. * @param[in] sign if true then return a signed result for the area if * the polygon is traversed in the "wrong" direction instead of returning * the area for the rest of the earth. * @param[out] perimeter the approximate perimeter of the polygon or length * of the polyline (meters). * @param[out] area the approximate area of the polygon * (meters2); only set if polyline is false in the * constructor. * @return the number of points. * * \e lat should be in the range [−90°, 90°]. **********************************************************************/ unsigned TestPoint(double lat, double lon, bool reverse, bool sign, [System::Runtime::InteropServices::Out] double% perimeter, [System::Runtime::InteropServices::Out] double% area); /** * Return the results assuming a tentative final test point is added via an * azimuth and distance; however, the data for the test point is not saved. * This lets you report a running result for the perimeter and area as the * user moves the mouse cursor. Ordinary floating point arithmetic is used * to accumulate the data for the test point; thus the area and perimeter * returned are less accurate than if PolygonArea::AddEdge and * PolygonArea::Compute are used. * * @param[in] azi azimuth at current point (degrees). * @param[in] s distance from current point to final test point (meters). * @param[in] reverse if true then clockwise (instead of counter-clockwise) * traversal counts as a positive area. * @param[in] sign if true then return a signed result for the area if * the polygon is traversed in the "wrong" direction instead of returning * the area for the rest of the earth. * @param[out] perimeter the approximate perimeter of the polygon or length * of the polyline (meters). * @param[out] area the approximate area of the polygon * (meters2); only set if polyline is false in the * constructor. * @return the number of points. **********************************************************************/ unsigned TestEdge(double azi, double s, bool reverse, bool sign, [System::Runtime::InteropServices::Out] double% perimeter, [System::Runtime::InteropServices::Out] double% area); /** \name Inspector functions **********************************************************************/ ///@{ /** * @return \e a the equatorial radius of the ellipsoid (meters). This is * the value inherited from the Geodesic object used in the constructor. **********************************************************************/ property double EquatorialRadius { double get(); } /** * @return \e f the flattening of the ellipsoid. This is the value * inherited from the Geodesic object used in the constructor. **********************************************************************/ property double Flattening { double get(); } /** * Report the previous vertex added to the polygon or polyline. * * @param[out] lat the latitude of the point (degrees). * @param[out] lon the longitude of the point (degrees). * * If no points have been added, then NaNs are returned. Otherwise, \e lon * will be in the range [−180°, 180°). **********************************************************************/ void CurrentPoint([System::Runtime::InteropServices::Out] double% lat, [System::Runtime::InteropServices::Out] double% lon); ///@} }; } // namespace NETGeographicLib