
    Og                       U d Z ddlmZ ddlmZmZmZmZmZm	Z	m
Z
mZmZ ddlmZmZ ddlZddlZddlZddlZddlmZmZmZmZmZ ddlmZmZmZ ddlmZm Z m!Z!m"Z"m#Z# dd	l$m%Z% dd
l&m'Z' ddlm(Z( g dZ)dZ*dZ+dZ,dZ-dZ.dZ/dZ0dZ1dZ2dZ3dZ4dZ5dZ6dZ7dZ8dZ9h dZ:ee;ef   Z<de=d<   eee<gdf   Z>de=d <    G d! d"ej~                        Z@e9d#f	 	 	 	 	 	 	 dFd%ZAe@j                  dfdd&	 	 	 	 	 dGd'ZCdHd(ZDeegef   ZEde=d)<    G d* d$      ZFdId+ZGdJd,ZHdKd-ZIdLd.ZJdMdNd/ZKe9d#f	 	 	 	 	 	 	 dOd0ZLdPd1ZM	 	 	 	 	 	 	 	 dQd2ZNd3 ZOe9d#f	 	 	 	 	 	 	 dRd4ZPdSd5ZQdTd6ZRdUdVd7ZSdWd8ZTdXd9ZUdXd:ZVd;ZWd<ZX ej                  d=eXd>z  eWd>z  z  z
        ZZej                  d?z  Z\ej                  d?z  Z^ej                  d@z  Z_dYdAZ`dZd[dBZad\d]dCZbd^dDZcd_dEZdy)`aQ  
Implementation of the `__geo_interface__`: https://gist.github.com/sgillies/2217756

Which is also supported by Shapely: https://pypi.org/project/Shapely/

Type definitions see GeoJson Standard: https://tools.ietf.org/html/rfc7946
and examples : https://tools.ietf.org/html/rfc7946#appendix-A

GeoJSON Linter: https://geojsonlint.com/

    )annotations)	IterableIteratorUnioncastCallableSequenceOptionalAnyMutableMapping)	TypeAliasSelfN)Vec3has_clockwise_orientationMatrix44world_mercator_to_gpsgps_to_world_mercator)	make_pathfrom_hatch_boundary_pathmake_polygon_structure)
DXFGraphic
LWPolylinePointPolylineLine)
DXFPolygon)const)factory)proxydxf_entitiesgfilterGeoProxyPolygonConversiontypecoordinatesr   
MultiPoint
LineStringMultiLineStringPolygonMultiPolygonGeometryCollection
geometriesgeometryfeaturesFeature
propertiesFeatureCollectiong?>   ARCLINEHATCHPOINTSOLIDTRACE3DFACECIRCLESPLINEELLIPSEMPOLYGONPOLYLINE
LWPOLYLINEr   
GeoMappingPostProcessFuncc                       e Zd ZdZdZdZdZdZy)r#   zPolygon conversion types as :class:`IntEnum`.

    Attributes:
        HATCH:
        POLYLINE:
        HATCH_AND_POLYLINE:
        MPOLYGON:

                N)__name__
__module____qualname____doc__r4   r=   HATCH_AND_POLYLINEr<        U/var/www/html/public_html/myphp/venv/lib/python3.12/site-packages/ezdxf/addons/geo.pyr#   r#   S   s     EHHrL   r#   Fr"   c                0    t         j                  | ||      S )a  Returns a :class:`GeoProxy` object.

    Args:
        entity: a single DXF entity or iterable of DXF entities
        distance: maximum flattening distance for curve approximations
        force_line_string: by default this function returns Polygon objects for
            closed geometries like CIRCLE, SOLID, closed POLYLINE and so on,
            by setting argument `force_line_string` to ``True``, this entities
            will be returned as LineString objects.

    )r"   from_dxf_entities)entitydistanceforce_line_strings      rM   r   r   d   s      %%fh8IJJrL   post_processc               P    t         j                  |       j                  |||      S )aG  Returns ``__geo_interface__`` mappings as DXF entities.

    The enum `polygon` determines the method to convert polygons,
    use :attr:`PolygonConversion.HATCH` for :class:`~ezdxf.entities.Hatch` entity,
    :attr:`PolygonConversion.POLYLINE` for :class:`~ezdxf.entities.LWPolyline` or
    :attr:`PolygonConversion.HATCH_AND_POLYLINE` for both.
    Option :attr:`PolygonConversion.POLYLINE` returns for the exterior path and each hole
    a separated :class:`LWPolyline` entity. The :class:`Hatch` entity supports holes,
    but has no explicit borderline.

    Yields :class:`Hatch` always before :class:`LWPolyline` entities.

    :attr:`PolygonConversion.MPOLYGON` support was added in v0.16.6, which is
    like a :class:`~ezdxf.entities.Hatch` entity  with additional borderlines,
    but the MPOLYGON entity is not a core DXF entity and DXF viewers,
    applications and libraries my not support this entity. The DXF attribute
    `color` defines the borderline color and `fill_color` the color of the
    solid filling.

    The returned DXF entities can be added to a layout by the
    :meth:`Layout.add_entity` method.

    Args:
        geo_mapping: ``__geo__interface__`` mapping as :class:`dict` or a Python
            object with a :attr:`__geo__interface__` property
        polygon: see :class:`PolygonConversion`
        dxfattribs: dict with additional DXF attributes
        post_process: post process function of type :class:`PostProcessFunc` that get the
            created DXF entity and the geo mapping as input, see reference implementation
            :func:`assign_layers`

    rS   )r"   parseto_dxf_entities)geo_mappingpolygon
dxfattribsrT   s       rM   r    r    w   s-    N >>+&66, 7  rL   c              #     K   | D ]K  }t        |t              r|j                  s|j                  s,| 1|j	                         t
        v sH| M yw)zuFilter DXF entities from iterable `entities`, which are incompatible to
    the ``__geo_reference__`` interface.
    N)
isinstancer   is_2d_polylineis_3d_polylinedxftypeSUPPORTED_DXF_TYPES)entitieses     rM   r!   r!      sK       a"1#3#3YY[//Gs   .AAATFuncc                      e Zd ZdZdddZedd       Zedd       Zed        Z	ddZ
e
Zedd       ZddZdd	ZdddZdddZddZddZddZeedf	 	 	 	 	 	 	 dd       Zej.                  d
fd
d	 	 	 d dZy
)!r"   a  Stores the ``__geo_interface__`` mapping in a parsed and compiled form.

    Stores coordinates as :class:`Vec3` objects and represents "Polygon"
    always as tuple (exterior, holes) even without holes.

    The GeoJSON specification recommends 6 decimal places for latitude and
    longitude which equates to roughly 10cm of precision. You may need
    slightly more for certain applications, 9 decimal places would be
    sufficient for professional survey-grade GPS coordinates.

    Args:
        geo_mapping: parsed and compiled ``__geo_interface__`` mapping
        places: decimal places to round for ``__geo_interface__`` export

    c                     || _         || _        y N)_rootplaces)selfrX   rh   s      rM   __init__zGeoProxy.__init__   s     
rL   c                T    t        |d      r|j                  } | t        |            S )aE  Parse and compile a ``__geo_interface__`` mapping as :class:`dict`
        or a Python object with a ``__geo_interface__`` property, does some
        basic syntax checks, converts all coordinates into :class:`Vec3`
        objects, represents "Polygon" always as tuple (exterior, holes) even
        without holes.

        __geo_interface__)hasattrrl   rV   )clsrX   s     rM   rV   zGeoProxy.parse   s*     ; 34%77K5%&&rL   c                    | j                   S rf   rg   ri   s    rM   rootzGeoProxy.root   s    zzrL   c                8    | j                   j                  d      S )z7Property returns the top level entity type or ``None``.r$   )rg   getrq   s    rM   geotypezGeoProxy.geotype   s     zz~~f%%rL   c                ,    t        j                  |       S )zReturns a deep copy.)copydeepcopyrq   s    rM   __copy__zGeoProxy.__copy__   s    }}T""rL   c                B    t        | j                  | j                        S )zWReturns the ``__geo_interface__`` compatible mapping as
        :class:`dict`.
        )_rebuildrg   rh   rq   s    rM   rl   zGeoProxy.__geo_interface__   s    
 

DKK00rL   c              #  R   K   dfd | j                         E d{    y7 w)a+  Iterate over all geometry entities.

        Yields only "Point", "LineString", "Polygon", "MultiPoint",
        "MultiLineString" and "MultiPolygon" objects, returns the content of
        "GeometryCollection", "FeatureCollection" and "Feature" as geometry
        objects ("Point", ...).

        c              3  D  K   | t            }|t        k(  r| t           D ]  } |      E d {     y |t        k(  r| t           D ]  } |      E d {     y |t
        k(  r/| t           }|t            t        k(  r |      E d {    y | y |  y 7 l7 F7 wrf   TYPEFEATURE_COLLECTIONFEATURESGEOMETRY_COLLECTION
GEOMETRIESFEATUREGEOMETRY)nodetype_featurer-   _iters       rM   r   z GeoProxy.__iter__.<locals>._iter   s     JE**#H~ .G$W~--.-- $Z 0 /H$X../'!>D>%88$X.."N
 . / /s3   *B B'B B4B 
BB B B N)r   r?   returnIterator[GeoMapping]rp   )ri   r   s    @rM   __iter__zGeoProxy.__iter__   s      	" $$$s   '%'c                Z    dfddfd | j                         si | _         yy)zRemoves all mappings for which `func()` returns ``False``.
        The function only has to handle Point, LineString and Polygon entities,
        other entities like MultiPolygon are divided into separate entities
        also any collection.

        c           	         g }| t            D ]1  } t        t        |t         |i            s!|j                  |       3 || t         <   t	        t        |            S rf   )COORDINATESr"   r   appendboollen)rr   r   r%   rP   funcs       rM   multi_entityz%GeoProxy.filter.<locals>.multi_entity  s\    K{+ /${F!CDE&&v./ !,DK())rL   c                t   | t            }|t        k(  rB| t           D cg c]  } |      s| c}| t        <   t        t	        | t                       S |t
        k(  rB| t           D cg c]  } |      s| c}| t        <   t        t	        | t                       S |t        k(  r3 | t                 r	| t           ni | t        <   t        | t                 S |t        k(  r | t              S |t        k(  r | t              S |t        k(  r | t              S  t        |             S c c}w c c}w rf   )r   r   r   r   r   r   r   r   r   MULTI_POINTr5   MULTI_LINE_STRINGLINE_STRINGMULTI_POLYGONPOLYGONr"   )rr   r   r   r-   checkr   r   s       rM   r   zGeoProxy.filter.<locals>.check  s   JE**+/>" 'U7^G"X CX/00---1*-=$!)xH$Z  CZ 0122'!38h3HhbXDN+++%#D%00++#D+66-'#D'22HTN++'"
$s   D0D0*D58D5N)r   r   rp   )ri   r   r   r   s    `@@rM   filterzGeoProxy.filter  s'    	*	,0 TZZ DJ !rL   Nc                6    |t         }| j                  |       y)a  Transform all coordinates recursive from globe representation
        in longitude and latitude in decimal degrees into 2D map representation
        in meters.

        Default is WGS84 `EPSG:4326 <https://epsg.io/4326>`_ (GPS) to WGS84
        `EPSG:3395 <https://epsg.io/3395>`_ World Mercator function
        :func:`wgs84_4326_to_3395`.

        Use the `pyproj <https://pypi.org/project/pyproj/>`_ package to write
        a custom projection function as needed.

        Args:
            func: custom transformation function, which takes one
                :class:`Vec3` object as argument and returns the result as
                a :class:`Vec3` object.

        N)wgs84_4326_to_3395applyri   r   s     rM   globe_to_mapzGeoProxy.globe_to_map2      $ <%D

4rL   c                6    |t         }| j                  |       y)a  Transform all coordinates recursive from 2D map representation in
        meters into globe representation as longitude and latitude in decimal
        degrees.

        Default is WGS84 `EPSG:3395 <https://epsg.io/3395>`_ World Mercator
        to WGS84 `EPSG:4326 <https://epsg.io/4326>`_ GPS function
        :func:`wgs84_3395_to_4326`.

        Use the `pyproj <https://pypi.org/project/pyproj/>`_ package to write
        a custom projection function as needed.

        Args:
            func: custom transformation function, which takes one
                :class:`Vec3` object as argument and returns the result as
                a :class:`Vec3` object.

        N)wgs84_3395_to_4326r   r   s     rM   map_to_globezGeoProxy.map_to_globeH  r   rL   c                :    | j                  |j                         y)a  Transform all coordinates recursive from CRS into
        :ref:`WCS` coordinates by transformation matrix `crs` inplace,
        see also :meth:`GeoProxy.wcs_to_crs`.

        Args:
            crs: transformation matrix of type :class:`~ezdxf.math.Matrix44`

        N)r   ucs_vertex_from_wcsri   crss     rM   
crs_to_wcszGeoProxy.crs_to_wcs^  s     	

3**+rL   c                :    | j                  |j                         y)a  Transform all coordinates recursive from :ref:`WCS` coordinates into
        Coordinate Reference System (CRS) by transformation matrix `crs`
        inplace.

        The CRS is defined by the :class:`~ezdxf.entities.GeoData` entity,
        get the :class:`GeoData` entity from the modelspace by method
        :meth:`~ezdxf.layouts.Modelspace.get_geodata`.
        The CRS transformation matrix can be acquired form the :class:`GeoData`
        object by :meth:`~ezdxf.entities.GeoData.get_crs_transformation` method:

        .. code:: Python

            doc = ezdxf.readfile('file.dxf')
            msp = doc.modelspace()
            geodata = msp.get_geodata()
            if geodata:
                matrix, axis_ordering = geodata.get_crs_transformation()

        If `axis_ordering` is ``False`` the CRS is not compatible with the
        ``__geo_interface__`` or GeoJSON (see chapter 3.1.1).

        Args:
            crs: transformation matrix of type :class:`~ezdxf.math.Matrix44`

        N)r   	transformr   s     rM   
wcs_to_crszGeoProxy.wcs_to_crsi  s    6 	

3==!rL   c                L    dfd}| j                         D ]
  } ||        y)zApply the transformation function `func` recursive to all
        coordinates.

        Args:
            func: transformation function as Callable[[Vec3], Vec3]

        c                @    fd | t                  | t         <   y )Nc                j    t        | t              r |       S | D cg c]
  } |       c}S c c}w rf   )r\   r   )coordscr   r   s     rM   r   z2GeoProxy.apply.<locals>.process.<locals>.transform  s/    fd+<'289QIaL999s   0)r   )rP   r   r   s    @rM   processzGeoProxy.apply.<locals>.process  s    : #,F;,?"@F;rL   N)rP   r?   )r   )ri   r   r   rP   s    `  rM   r   zGeoProxy.apply  s'    	A mmo 	FFO	rL   Fc                h    t        |t              rt        |||      }nt        |||      } | |      S )a  Constructor from a single DXF entity or an iterable of DXF entities.

        Args:
            entity: DXF entity or entities
            distance: maximum flattening distance for curve approximations
            force_line_string: by default this function returns Polygon objects for
                closed geometries like CIRCLE, SOLID, closed POLYLINE and so on,
                by setting argument `force_line_string` to ``True``, this entities
                will be returned as LineString objects.

        )r\   r   mapping
collection)rn   rP   rQ   rR   ms        rM   rO   zGeoProxy.from_dxf_entities  s5    $ fj)*;<A68->?A1vrL   rS   c             #    	
K   dfddfdd
fd	 	 	 	 	 	 	 	 dfd	d	fd
d	fddfd}dk  sd	kD  rt        d
       t        xs i       t        | j                        D ]J  \  }}|j	                  t
              } |||j	                  t                    D ]  }|r	 |||       |  L yw)a  Returns stored ``__geo_interface__`` mappings as DXF entities.

        The `polygon` argument determines the method to convert polygons,
        use 1 for :class:`~ezdxf.entities.Hatch` entity, 2 for
        :class:`~ezdxf.entities.LWPolyline` or 3 for both.
        Option 2 returns for the exterior path and each hole a separated
        :class:`LWPolyline` entity. The :class:`Hatch` entity supports holes,
        but has no explicit borderline.

        Yields :class:`Hatch` always before :class:`LWPolyline` entities.

        :class:`~ezdxf.entities.MPolygon` support was added in v0.16.6, which is
        like a :class:`~ezdxf.entities.Hatch` entity  with additional borderlines,
        but the MPOLYGON entity is not a core DXF entity and DXF viewers,
        applications and libraries my not support this entity. The DXF attribute
        `color` defines the borderline color and `fill_color` the color of the
        solid filling.

        The returned DXF entities can be added to a layout by the
        :meth:`Layout.add_entity` method.

        Args:
            polygon: see :class:`PolygonConversion`
            dxfattribs: dict with additional DXF attributes
            post_process: post process function of type :class:`PostProcesFunc` that get the
                created DXF entity and the geo mapping as input, see reference implementation
                :func:`assign_layers`

        c                t    t        t        t        j                  d            }| |j                  _        |S )Nr5   rZ   )r   r   r   newdxflocation)vertexpointrZ   s     rM   r   z'GeoProxy.to_dxf_entities.<locals>.point  s+    G
 KLE!'EIILrL   c                x    t        t        t        j                  d            }|j	                  | d       |S )Nr>   r   xy)format)r   r   r   r   append_points)verticespolylinerZ   s     rM   
lwpolylinez,GeoProxy.to_dxf_entities.<locals>.lwpolyline  s7    GKKLH ""8D"9OrL   c              3     K   t         j                  k(  r | |       y t         j                  z  r | |       t         j                  z  r| g|z   D ]  } |        y y wrf   )r#   r<   r4   r=   )exteriorholespathhatch_r   	mpolygon_rY   s      rM   polygon_z*GeoProxy.to_dxf_entities.<locals>.polygon_  sy     +444%00 *000Xu--*333%J. +D$T**+ 4s   A(A+c                J   t        t        t        j                  |             }t        j
                  |j                  _        |j                  j                  |t        j                         |D ]-  }|j                  j                  |t        j                         / |S )Nr   )flags)r   r   r   r   r   HATCH_STYLE_OUTERMOSTr   hatch_stylepathsadd_polyline_pathBOUNDARY_PATH_EXTERNALBOUNDARY_PATH_OUTERMOST)r_   r   r   dxf_polygonholerZ   s        rM   dxf_polygon_z.GeoProxy.to_dxf_entities.<locals>.dxf_polygon_  s     z7;;w:+VWK*/*E*EKOO'// < < 0   !!33 = = 4  rL   c                     d| |      S )Nr4   rK   r   r   r   s     rM   r   z(GeoProxy.to_dxf_entities.<locals>.hatch_  s    599rL   c                     d| |      S )Nr<   rK   r   s     rM   r   z+GeoProxy.to_dxf_entities.<locals>.mpolygon_  s    
He<<rL   c              3  `  K   | t         k(  r |       y | t        k(  r |       y | t        k(  r|\  }} ||      E d {    y | t        k(  r|D ]  } |        y | t        k(  r|D ]  } |        y | t
        k(  r|D ]  }|\  }} ||      E d {     y y 7 c7 
wrf   )r5   r   r   r   r   r   )r   r%   r   r   datar   r   r   s        rM   rP   z(GeoProxy.to_dxf_entities.<locals>.entity  s     ~K((+% --'!"-%#He444+%' &D+%&++' +D$T**+-'' 9D&*OHe'%8889 ( 5 9s%   AB.B*AB.!B,"	B.,B.rB   rE   zinvalid value for polygon: N)r   r	   r   r   )r   r	   r   r   )r   listr   r   r   Iterator[DXFGraphic])r_   strr   r	   r   r	   r   r   )r   r	   r   r	   r   r   )r   r   )
ValueErrordictiter_featuresrg   rt   r   r   )ri   rY   rZ   rT   rP   r   r-   r   rb   r   r   r   r   r   r   s    ``      @@@@@@rM   rW   zGeoProxy.to_dxf_entities  s     J	
	
	+ 
	+		$,	5=			:	=	9& Q;'A+:7)DEE**+
!.tzz!: 	GXLL&EE8<<#<=  G,	s   CC   )rX   r?   rh   int)rX   r?   r   r   )r   r?   )r   r"   )r   r   )r   zCallable[[GeoProxy], bool]r   Nonerf   )r   zOptional[TFunc]r   r   )r   r   r   r   )r   rc   r   r   rP   z'Union[DXFGraphic, Iterable[DXFGraphic]]rQ   floatrR   r   r   r"   )rT   Optional[PostProcessFunc]r   r   )rF   rG   rH   rI   rj   classmethodrV   propertyrr   ru   ry   rw   rl   r   r   r   r   r   r   r   MAX_FLATTENING_DISTANCErO   r#   r4   rW   rK   rL   rM   r"   r"      s     
' 
'   & &# D1 1%:)V,,	,":*  2"'	7   	
 
 2 "''m
 37m
 0m 
mrL   c              #  F   K   i dfd |       E d{    y7 w)a,  Yields all geometries of a ``__geo_mapping__`` as (`feature`, `geometry`) tuples.

    If no feature is defined the `feature` value is an empty ``dict``. When a `feature`
    contains `GeometryCollections`, the function yields for each sub-geometry a separate
    (`feature`, `geometry`) tuple.

    c              3  P  K   | t            }|t        k(  r| t           D ]  } |      E d {     y |t        k(  r| t           D ]  } |      E d {     y |t
        k(  r3| | t           }|t            t        k(  r |      E d {    y |f y | f y 7 r7 L7 wrf   r~   )r   r   r   r-   current_featurer.   s       rM   r.   ziter_features.<locals>.features-  s      T
&&> -#G,,,-)) , .#H---.g"OH~H~!44#H---%x//!4'' - .
 .s3   *B&B 'B&B"6B&B$B&"B&$B&N)r   r?   r   'Iterator[tuple[GeoMapping, GeoMapping]]rK   )rX   r   r.   s    @@rM   r   r   #  s#      #%O(( $$$s   !!c                   t        j                  |       } | j                  t              }|t	        dt         d      |t
        k(  rL| j                  t              }|r"|D cg c]  }t        |       c}| t        <   | S t	        dt         d      |t        k(  rL| j                  t              }|r"|D cg c]  }t        |       c}| t        <   | S t	        dt         d      |t        k(  rHt        | v r-| j                  t              }|rt        |      nd| t        <   | S t	        dt         d      |t        t        t        t        t         t"        hv r| j                  t$              }|t	        dt$         d| d	      |t        k(  rt'        |      }n|t        t        fv rt'        j(                  |      }nb|t        k(  rt+        |      }nM|t         k(  r#|D cg c]  }t'        j(                  |       }}n!|t"        k(  r|D cg c]  }t+        |       }}|| t$        <   | S t-        d
| d      c c}w c c}w c c}w c c}w )zParse ``__geo_interface__`` convert all coordinates into
    :class:`Vec3` objects, Polygon['coordinates'] is always a
    tuple (exterior, holes), holes maybe an empty list.

    NzRequired key "z" not found.zMissing key "z" in FeatureCollection.z" in GeometryCollection.z" in Feature.z" in .zInvalid type "z".)rw   rx   rt   r   r   r   r   rV   r   r   r   r   r5   r   r   r   r   r   r   r   r   _parse_polygon	TypeError)	rX   r   r.   fr,   gr-   r%   vs	            rM   rV   rV   D  s?    --,KOOD!E}>$|<==""??8,7?$@!U1X$@K!T Q }XJ6MNOO	%	% __Z0
9C&DAuQx&DK
#F C }ZL8PQRR	'	 {""x0H7?E(OTK!6 3 }XJmDEE	 
 "ook2}[MugQGHHE>{+K{K00))K0Kg(5K''1<=A499Q<=K=m#6AB>!,BKB#.K   .r233S %A 'E: >Bs   $H?9I%I	Ic                    t        | t              st        d      t        |       dk(  rt        d      | d   }t        |      dk(  rt        d      t        |d   t        j
                        S )zReturns ``True`` for a sequence of coordinates like [(0, 0), (1, 0)]
    and ``False`` for a sequence of sequences:
    [[(0, 0), (1, 0)], [(2, 0), (3, 0)]]
    zInvalid coordinate sequence.r   )r\   r	   r   r   numbersReal)r%   
first_items     rM   _is_coordinate_sequencer     si    
 k8,788
;1788QJ
:!788jmW\\22rL   c                    t        |       r| }g }n
| d   }| dd }t        j                  |      |D cg c]  }t        j                  |       c}fS c c}w )z8Returns polygon definition as tuple (exterior, [holes]).r   rB   N)r   r   r   )r%   r   r   hs       rM   r   r     sR    {+q>AB99Xu =!1 === =s   Ac           	     `   dfdfd}t        |       }|t           }|t        k(  r)|t           D cg c]  }t	        |       c}|t        <   |S |t
        k(  r)|t           D cg c]  }t	        |       c}|t        <   |S |t        k(  rt	        |t                 |t        <   |S |t        k(  r|t           } |      |t        <   |S |t        t        fv r(|t           }|D cg c]
  } |       c}|t        <   |S |t        k(  r7g }|t           D ]'  }	|j                  |	D cg c]
  } |       c}       ) |S |t        k(  r ||t            |t        <   |S |t         k(  r*|t           D 
cg c]  \  }
} ||
|       c}}
|t        <   |S c c}w c c}w c c}w c c}w c c}}
w )zrReturns ``__geo_interface__`` compatible mapping as :class:`dict` from
    compiled internal representation.

    c                \    t        | j                        t        | j                        fS rf   )roundxy)r   rh   s    rM   pntz_rebuild.<locals>.pnt  s$    QSS&!5f#555rL   c           
     n    | g|z   D cg c]  }|D cg c]
  } |       c} c}}S c c}w c c}}w rf   rK   )r   r   ringr   r  s       rM   _polygonz_rebuild.<locals>._polygon  s2     5=:3EF4&AQ&FF&Fs   	1,11)r   r   r   ztuple[float, float])r   r   r   r   r{   r   r   r   r   r5   r   r   r   r   r   r   r   )rX   rh   r  geo_interfacer   r   r   r   r%   liner   r   r  s    `          @rM   r{   r{     s   6G
 %M$E""8Eh8O"P18A;"Ph* ) 
%	%:G
:S$TQXa[$Tj!& % 
'	"*=+B"Ch" ! 
%+&%(Vk"  
;,	,#K06A%Bc!f%Bk"  
#	#!+. 	7D51A56	7  
'	%-}[/I%Jk"
 	 
-	=J;=W&
*9(EHXu%&
k" + #Q$T &C  6&
s   F(F(F )F%
6F*c                B   | j                         }t        | t              r&t        t        t
        | j                  j                  iS t        | t              r5t        | j                  j                  | j                  j                  g      S t        | t              rT| j                  s| j                  r1t        |       }t!        |j#                  |            }t%        ||      S t'        d      t        | t(              r1t        |       }t!        |j#                  |            }t%        ||      S |dv r$t%        t!        | j#                  |            |      S |dv rt%        | j+                  d      |      S t        | t,              rt/        | ||      S t'        |      )a  Create the compiled ``__geo_interface__`` mapping as :class:`dict`
    for the given DXF `entity`, all coordinates are :class:`Vec3` objects and
    represents "Polygon" always as tuple (exterior, holes) even without holes.


    Internal API - result is **not** a valid ``_geo_interface__`` mapping!

    Args:
        entity: DXF entity
        distance: maximum flattening distance for curve approximations
        force_line_string: by default this function returns Polygon objects for
            closed geometries like CIRCLE, SOLID, closed POLYLINE and so on,
            by setting argument `force_line_string` to ``True``, this entities
            will be returned as LineString objects.

    z$Polymesh and Polyface not supported.>   r2   r9   r:   r;   >   r6   r7   r8   T)close)r_   r\   r   r   r5   r   r   r   r   line_string_mappingstartendr   r^   r]   r   r   
flattening_line_string_or_polygon_mappingr   r   wcs_verticesr   _hatch_as_polygon)rP   rQ   rR   r_   r   pointss         rM   r   r     se   , nnG&% e[&***=*=>>	FD	!"FJJ$4$4fjjnn#EFF	FH	%  F$9$9V$D$//(34F26;LMMBCC	FJ	' dooh/0.v7HII	:	:.""8,-/@
 	
 
0	0.d+->
 	
 
FJ	' 3DEE  rL   c                    t        |       }|dk  rt        d      |dk(  s|rt        |       S t        |       rt	        | g       S t        |       S )NrC   zInvalid vertex count.)r   r   r  is_linear_ringpolygon_mapping)r  rR   len_s      rM   r  r    sS    v;Dax011qy%"6**&!"62..&v..rL   c                4   dfd}dfd| j                   j                  j                  | j                         | j                   j                  }t        | j                  j                  |            }t        |      }|dk(  rt        | j                          d      |d   }|dk(  s|t        j                  k(  r ||      }t        ||      S |rM ||      }t        ||      g}	|dd  D ]%  }
 ||
      }|	j                  t        ||             ' t        |	      S g }t!        |      D ]<  \  }} |      }|j                  t#        ||D 
cg c]
  }
 |
       c}
             > t        |      dkD  rt        |      S |d   S c c}
w )Nc                .    t        |       } |      S rf   r   )boundaryr   	elevationocspath_to_verticess     rM   boundary_to_verticesz/_hatch_as_polygon.<locals>.boundary_to_vertices	  s    '#yA%%rL   c                X    | j                          t        | j                              S rf   )r  r   r  )r   rQ   s    rM   r  z+_hatch_as_polygon.<locals>.path_to_vertices  s     

DOOH-..rL   r   z without any boundary path.rB   )r   
list[Vec3])r   r  zr  r   r   r   rendering_pathsr   r   r_   r   HATCH_STYLE_IGNOREr  r   join_multi_single_type_mappings_boundaries_to_polygonsr  )hatchrQ   rR   r   r   
boundariescountr   r  r,   r   polygonsr   r  r  r  s    `           @@@rM   r  r    s   &/ 		##%%I
))+C))''K ekk11+>?J
OEzEMMO,,GHII!}Hz[E$<$<<%h/.v7HII)(3F9&BSTUJ"12 -d3!!3F<MN
 3:>> H#::sI#V %)(3#FPU,V-=d-C,VW
 8}q 6x@@A;	 -Ws   Fc              #     K   fd| D        }t        |      D ]!  }|d   }||dd  D cg c]  }|d   	 c}f # y c c}w w)Nc              3  8   K   | ]  }t        |        y wrf   r  ).0r  r  r  s     rM   	<genexpr>z*_boundaries_to_polygons.<locals>.<genexpr>=  s       ?G 3	:s   r   rB   )r   )r)  r  r  r   rY   r   r   s    ``    rM   r'  r'  <  sZ     KUE *%0 :1:WQR[9Ta999: :s   (AAAc                    | D cg c]  }t        |||       }}t        d |D              }t        |      dkD  rt        |      S t	        |      S c c}w )a;  Create the ``__geo_interface__`` mapping as :class:`dict` for the
    given DXF `entities`, see https://gist.github.com/sgillies/2217756

    Returns a "MultiPoint", "MultiLineString" or "MultiPolygon" collection if
    all entities return the same GeoJSON type ("Point", "LineString", "Polygon")
    else a "GeometryCollection".

    Internal API - result is **not** a valid ``_geo_interface__`` mapping!

    Args:
        entities: iterable of DXF entities
        distance: maximum flattening distance for curve approximations
        force_line_string: by default this function returns "Polygon" objects for
            closed geometries like CIRCLE, SOLID, closed POLYLINE and so on,
            by setting argument `force_line_string` to ``True``, this entities
            will be returned as "LineString" objects.
    c              3  .   K   | ]  }|t              y wrf   )r   )r.  r   s     rM   r/  zcollection.<locals>.<genexpr>]  s     #A$#s   rB   )r   setr   geometry_collection_mappingr&  )ra   rQ   rR   rb   r   typess         rM   r   r   F  sY    , ;CCQH/	0CAC###E
5zA~*1--.q11 	Ds   Ac                &    t         t        t        | iS )zReturns a "LineString" mapping.

    .. code::

        {
            "type": "LineString",
            "coordinates": [
                (100.0, 0.0),
                (101.0, 1.0)
            ]
        }
    )r   r   r   r  s    rM   r  r  d  s     +{F33rL   c                0    | d   j                  | d         S )Nr   )iscloser6  s    rM   r  r  u  s    !9VBZ((rL   c                   t        |       dk  rt        dt        |              | d   j                  | d         s| j                  | d          t	        |       r|r| j                          | S |s| j                          | S )zReturn `points` as linear ring (last vertex == first vertex),
    argument `ccw` defines the winding orientation, ``True`` for counter-clock
    wise and ``False`` for clock wise.

    rD   zInvalid vertex count: r   r8  )r   r   r9  r   r   reverse)r  ccws     rM   linear_ringr=  |  s|     6{Q1#f+?@@!9VBZ(fQi  (NN
 M NNMrL   c                    t        | d      }|r|D cg c]  }t        |d       }}||f}n|g f}t        t        t        |iS c c}w )a8  Returns a "Polygon" mapping.

    .. code::

        {
            "type": "Polygon",
            "coordinates": [
                 [
                     (100.0, 0.0),
                     (101.0, 0.0),
                     (101.0, 1.0),
                     (100.0, 1.0),
                     (100.0, 0.0)
                 ],
                 [
                     (100.8, 0.8),
                     (100.8, 0.2),
                     (100.2, 0.2),
                     (100.2, 0.8),
                     (100.8, 0.8)
                 ]
            ]
        }
    T)r<  F)r=  r   r   r   )r  r   r   r   ringss        rM   r  r    sY    4 6t,H:?@$Tu-@@%"gU 	 As   Ac                L   t               }t               }| D ]2  }|j                  |t                  |j	                  |t
                  4 t        |      dkD  rt        dt        |             t        |      dk(  r
t               S t        dt        |      d   z   t
        |iS )zdReturns multiple geometries as a "MultiPoint", "MultiLineString" or
    "MultiPolygon" mapping.
    rB   zType mismatch: r   Multi)r2  r   addr   r   r   r   r   r   r   tuple)r,   r4  r   r   s       rM   r&  r&    s     EE6D $		!D'AkN#$ 5zA~/#e*677	UqvgeQ/dCCrL   c                8    t         t        t        t        |       iS )z>Returns multiple geometries as a "GeometryCollection" mapping.)r   r   r   r   )r,   s    rM   r3  r3    s    %z4
3CDDrL   iRa gQ?XAg      ?rC   g       @g      @c                T    t        t        | j                  | j                              S )a  Transform WGS84 `EPSG:4326 <https://epsg.io/4326>`_ location given as
    latitude and longitude in decimal degrees as used by GPS into World Mercator
    cartesian 2D coordinates in meters `EPSG:3395 <https://epsg.io/3395>`_.

    Args:
        location: :class:`Vec3` object, x-attribute represents the longitude
            value (East-West) in decimal degrees and the y-attribute
            represents the latitude value (North-South) in decimal degrees.
    )r   r   r  r  )r   s    rM   r   r     s     %hjj(**=>>rL   c                V    t        t        | j                  | j                  |            S )ak  Transform WGS84 World Mercator `EPSG:3395 <https://epsg.io/3395>`_
    location given as cartesian 2D coordinates x, y in meters into WGS84 decimal
    degrees as longitude and latitude `EPSG:4326 <https://epsg.io/4326>`_ as
    used by GPS.

    Args:
        location: :class:`Vec3` object, z-axis is ignored
        tol: accuracy for latitude calculation

    )r   r   r  r  )r   tols     rM   r   r     s!     %hjj(**cBCCrL   c                F    | t        |      dz  z   t        |      dz  z   }|S )z6Convert degree, minutes, seconds into decimal degrees.<     )r   )dr   sdds       rM   dms2ddrN    s&    	
U1X]	U1X_	,BIrL   c                N    t        | dz  d      \  }}t        |d      \  }}|||fS )z6Convert decimal degrees into degree, minutes, seconds.rJ  rI  )divmod)rM  r   rL  rK  s       rM   dd2dmsrQ    s0    "t)R DAq!R=DAqa7NrL   c                ~    |j                  t              }|y|j                  d      }|r|| j                  _        yy)zsReference implementation for a :func:`post_process` function.

    .. seealso::

        :func:`dxf_entities`

    Nlayer)rt   
PROPERTIESr   rS  )rP   r   r0   rS  s       rM   assign_layersrU    s=     Z(JNN7#E 

 rL   r   )rX   r?   rT   r   r   r   )ra   Iterable[DXFGraphic]r   r   )rX   r?   r   r   )rX   r?   r   r?   )r%   r	   r   r   )r%   r	   r   r	   r   )rX   r?   rh   r   r   r?   )rP   r   rQ   r   rR   r   r   r?   )r  r"  rR   r   )r(  r   rQ   r   rR   r   r   r?   )ra   rV  rQ   r   rR   r   r   r?   )r  r"  r   r?   )r  r"  )T)r  r"  r   r"  )r  r"  r   zlist[list[Vec3]]r   r?   )r,   zIterable[GeoMapping]r   r?   )r   r   r   r   )gư>)r   r   rG  r   r   r   )r   r   )rK  r   r   r   rL  r   r   r   )rM  r   r   ztuple[float, float, float])rP   r   r   r?   r   r   )erI   
__future__r   typingr   r   r   r   r   r	   r
   r   r   typing_extensionsr   r   r   rw   mathenum
ezdxf.mathr   r   r   r   r   
ezdxf.pathr   r   r   ezdxf.entitiesr   r   r   r   r   ezdxf.entities.polygonr   ezdxf.lldxfr   r   __all__r   r   r5   r   r   r   r   r   r   r   r   r   r   rT  r   r   r`   r   r?   __annotations__r@   IntEnumr#   r   r4   r    r!   rc   r"   r   rV   r   r   r{   r   r  r  r'  r   r  r  r=  r  r&  r3  WGS84_SEMI_MAJOR_AXISWGS84_SEMI_MINOR_AXISsqrtWGS84_ELLIPSOID_ECCENTRICrb   CONST_E2pi
CONST_PI_2
CONST_PI_4r   r   rN  rQ  rU  rK   rL   rM   <module>rl     s  
 #
 
 
 .      S R H H -  " P% 
* 


(     'sCx0
I 0%z:&>&DE E & .#K3KK K 	K* ##)
 /3))
 ,) )X	 TFDL)y )n nb%B9x3>&V .#3!3!3! 3! 	3!l
/33!&3;?33l: .#2"22 2 	2<4")*#LD$E   $ %DII

"%:A%=
==  66C<WWs]
WWs]

?D!rL   