o
    2c.                     @   sB   d Z ddlZddlmZ ddlmZ ddlmZ G dd dZdS )a  Define the :class:`~geographiclib.polygonarea.PolygonArea` class

The constructor initializes a empty polygon.  The available methods are

  * :meth:`~geographiclib.polygonarea.PolygonArea.Clear` reset the
    polygon
  * :meth:`~geographiclib.polygonarea.PolygonArea.AddPoint` add a vertex
    to the polygon
  * :meth:`~geographiclib.polygonarea.PolygonArea.AddEdge` add an edge
    to the polygon
  * :meth:`~geographiclib.polygonarea.PolygonArea.Compute` compute the
    properties of the polygon
  * :meth:`~geographiclib.polygonarea.PolygonArea.TestPoint` compute the
    properties of the polygon with a tentative additional vertex
  * :meth:`~geographiclib.polygonarea.PolygonArea.TestEdge` compute the
    properties of the polygon with a tentative additional edge

The public attributes for this class are

  * :attr:`~geographiclib.polygonarea.PolygonArea.earth`
    :attr:`~geographiclib.polygonarea.PolygonArea.polyline`
    :attr:`~geographiclib.polygonarea.PolygonArea.area0`
    :attr:`~geographiclib.polygonarea.PolygonArea.num`
    :attr:`~geographiclib.polygonarea.PolygonArea.lat1`
    :attr:`~geographiclib.polygonarea.PolygonArea.lon1`

    N)Math)Accumulator)Geodesicc                   @   s   e Zd ZdZedd Zedd Zedd Zedd	 ZdddZ	dd Z
dd Zdd ZdddZdddZdddZdS )PolygonAreazArea of a geodesic polygonc                 C   sz   t | |\}}t | } t |}|dkr+| d  k r |ks)n | dkr+|dkr+dS |dk r;|d  k r:| kr;dS  dS )z/Count crossings of prime meridian for AddPoint.r      )r   AngDiffAngNormalize)lon1lon2lon12_ r   O/var/www/html/gps/gps/lib/python3.10/site-packages/geographiclib/polygonarea.py_transit7   s   

zPolygonArea._transitc                 C   sV   t | d} t |d}d|  krdk rn ndndd|   kr'dk r(d S  d S )z.Count crossings of prime meridian for AddEdge.g     @r   ih  r   r   	remainder)r
   r   r   r   r   _transitdirectD   s   zPolygonArea._transitdirectc                 C   s   |  | |d@ r| |  dk rdnd| d  |s |   |r@|  |d kr1| |  n'|  | d kr?| | n|  |krM| |  n|  dk rX| | d|   S )z)Reduce accumulator area to allowed range.r   r   r              )	RemainderAddSumNegateareaarea0	crossingsreversesignr   r   r   _areareduceAM   s   
"

zPolygonArea._areareduceAc                 C   s   t | |} |d@ r| | dk rdnd| d 7 } |s| d9 } |r=| |d kr.| |8 } d|  S | | d kr9| |7 } d|  S | |krI| |8 } d|  S | dk rQ| |7 } d|  S )z$Reduce double area to allowed range.r   r   r   r   r   r   r   r   r   r   _areareduceBd   s"   	zPolygonArea._areareduceBFc                 C   s   || _ 	 || _	 dtj |j | _	 tjtjB tj	B | jr tj
ntjtjB B | _| js/t | _t | _d| _	 tj| _	 tj| _	 d| _tj | _| _dS )zConstruct a PolygonArea object

    :param earth: a :class:`~geographiclib.geodesic.Geodesic` object
    :param polyline: if true, treat object as a polyline instead of a polygon

    Initially the polygon has no vertices.
       r   N)earthpolylinemathpi_c2r   r   LATITUDE	LONGITUDEDISTANCEEMPTYAREALONG_UNROLL_maskr   _areasum_perimetersumnumnanlat1r
   
_crossings_lat0_lon0)selfr#   r$   r   r   r   __init__{   s,   	

zPolygonArea.__init__c                 C   sH   d| _ d| _| js| jd | jd tj | _ | _	 | _
| _dS )zReset to empty polygon.r   N)r1   r4   r$   r/   Setr0   r%   r2   r5   r6   r3   r
   )r7   r   r   r   Clear   s
   zPolygonArea.Clearc              
   C   s   | j dkr| | _| _| | _| _n8| j| j| j||| j\
}}}}}}}}}}| j	| | j
sD| j	| |  jt| j|7  _|| _|| _|  j d7  _ dS )zAdd the next vertex to the polygon

    :param lat: the latitude of the point in degrees
    :param lon: the longitude of the point in degrees

    This adds an edge from the current vertex to the new vertex.
    r   r   N)r1   r5   r3   r6   r
   r#   _GenInverser.   r0   r   r$   r/   r4   r   r   )r7   latlonr   s12S12r   r   r   AddPoint   s   
	zPolygonArea.AddPointc              	   C   s   | j dkrF| j| j| j|d|| j\	}}}}}}}}}| j| | js7| j	| |  j
t| j|7  _
|| _|| _|  j d7  _ dS dS )zAdd the next edge to the polygon

    :param azi: the azimuth at the current the point in degrees
    :param s: the length of the edge in meters

    This specifies the new vertex in terms of the edge from the current
    vertex.

    r   Fr   N)r1   r#   
_GenDirectr3   r
   r.   r0   r   r$   r/   r4   r   r   )r7   azisr   r<   r=   r?   r   r   r   AddEdge   s   
zPolygonArea.AddEdgeTc           
   
   C   s   | j rtj}| jdk rd}| j sd}| j||fS | j r&| j }| j||fS | j| j| j	| j
| j| j\
}}}}}}}}}}| j|}t| j}|| | jt| j	| j }	t|| j|	||}| j||fS )a  Compute the properties of the polygon

    :param reverse: if true then clockwise (instead of
      counter-clockwise) traversal counts as a positive area
    :param 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
    :return: a tuple of number, perimeter (meters), area (meters^2)

    Arbitrarily complex polygons are allowed.  In the case of
    self-intersecting polygons the area is accumulated "algebraically",
    e.g., the areas of the 2 loops in a figure-8 polygon will partially
    cancel.

    If the object is a polygon (and not a polyline), the perimeter
    includes the length of a final edge connecting the current point to
    the initial point.  If the object is a polyline, then area is nan.

    More points can be added to the polygon after this call.

    r   r   )r$   r%   r2   r1   r0   r   r#   r;   r3   r
   r5   r6   r.   r   r/   r   r4   r   r   r    r   )
r7   r   r   r   	perimeterr   r>   r?   tempsumr   r   r   r   Compute   s&   




zPolygonArea.Computec                 C   sH  | j rtj}| jdkrd}| j sd}d||fS | j }| j r!dn| j }| j}| jd }	| j r4dgnddgD ]T}
| j	|
dkrD| j
n||
dkrL| jn||
dkrT| jn||
dkr\| jn|| j\
}}}}}}}}}}||7 }| j s||7 }|t|
dkr| jn||
dkr| jn|7 }q8| j r|	||fS t|| j|||}|	||fS )a  Compute the properties for a tentative additional vertex

    :param lat: the latitude of the point in degrees
    :param lon: the longitude of the point in degrees
    :param reverse: if true then clockwise (instead of
      counter-clockwise) traversal counts as a positive area
    :param 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
    :return: a tuple of number, perimeter (meters), area (meters^2)

    r   r   r   )r$   r%   r2   r1   r0   r   r/   r4   r#   r;   r3   r
   r5   r6   r.   r   r   r!   r   )r7   r<   r=   r   r   r   rE   rF   r   r1   ir   r>   r?   r   r   r   	TestPoint   s6   



  

zPolygonArea.TestPointc              
   C   s  | j dkrdtjtjfS | j d }| j | }| jr!||tjfS | j }| j}| j	| j
| j|d|| j\	}	}
}}	}	}	}	}	}||7 }|t| j|7 }| j|
|| j| j| j\
}	}}	}	}	}	}	}	}	}||7 }||7 }|t|| j7 }t|| j|||}|||fS )a  Compute the properties for a tentative additional edge

    :param azi: the azimuth at the current the point in degrees
    :param s: the length of the edge in meters
    :param reverse: if true then clockwise (instead of
      counter-clockwise) traversal counts as a positive area
    :param 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
    :return: a tuple of number, perimeter (meters), area (meters^2)

    r   r   F)r1   r%   r2   r0   r   r$   r/   r4   r#   rA   r3   r
   r.   r   r   r;   r5   r6   r   r!   r   )r7   rB   rC   r   r   r1   rE   rF   r   r   r<   r=   r?   r>   r   r   r   r   TestEdge#  s.   



zPolygonArea.TestEdgeN)F)FT)__name__
__module____qualname____doc__staticmethodr   r   r    r!   r8   r:   r@   rD   rG   rI   rJ   r   r   r   r   r   4   s"    






+)r   )	rN   r%   geographiclib.geomathr   geographiclib.accumulatorr   geographiclib.geodesicr   r   r   r   r   r   <module>   s    .