
    'j                    >   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dld,ZAe@jB        dfdd-dmd2ZCdnd5ZDeegef         ZEde=d6<    G d7 d+          ZFdod9ZGdpd:ZHdqd<ZIdrd=ZJdsdtdAZKe9d#fdudCZLdvdFZMdwdIZNdJ ZOe9d#fdxdKZPdydLZQdzdMZRd{d|dOZSd}dRZTd~dTZUd~dUZVdVZWdWZX ejY        dXeXdYz  eWdYz  z  z
            ZZej[        dZz  Z\ej]        dZz  Z^ej]        d[z  Z_dd^Z`dddaZadddeZbddhZcddkZddS )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dS )r#   zPolygon conversion types as :class:`IntEnum`.

    Attributes:
        HATCH:
        POLYLINE:
        HATCH_AND_POLYLINE:
        MPOLYGON:

                N)__name__
__module____qualname____doc__r4   r=   HATCH_AND_POLYLINEr<        J/DATA/AppData/hermes/venv/lib/python3.11/site-packages/ezdxf/addons/geo.pyr#   r#   S   s/          EHHHHrL   r#   Fentity'Union[DXFGraphic, Iterable[DXFGraphic]]distancefloatforce_line_stringboolreturnr"   c                :    t                               | ||          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)rN   rP   rR   s      rM   r   r   d   s      %%fh8IJJJrL   post_processgeo_mappingrX   Optional[PostProcessFunc]Iterator[DXFGraphic]c               b    t                               |                               |||          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`

    rW   )r"   parseto_dxf_entities)rY   polygon
dxfattribsrX   s       rM   r    r    w   s5    N >>+&&66, 7   rL   entitiesIterable[DXFGraphic]c              #     K   | D ]I}t          |t                    r|j        s|j        r|V  *|                                t
          v r|V  JdS )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)ra   es     rM   r!   r!      sp         a"" 	 1#3 YY[[///GGG rL   TFuncc                      e Zd ZdZd,d-dZed.d
            Zed/d            Zed             Z	d0dZ
e
Zed/d            Zd1dZd2dZd3d4dZd3d4dZd5dZd5dZd6dZeedfd7d&            Zej        dfdd'd8d+ZdS )9r"   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

       rY   r?   placesintc                "    || _         || _        d S N)_rootrm   )selfrY   rm   s      rM   __init__zGeoProxy.__init__   s     
rL   rT   r   c                `    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__)hasattrru   r]   )clsrY   s     rM   r]   zGeoProxy.parse   s7     ; 344 	8%7Ks5%%&&&rL   c                    | j         S rp   rq   rr   s    rM   rootzGeoProxy.root   s
    zrL   c                6    | j                             d          S )z7Property returns the top level entity type or ``None``.r$   )rq   getrz   s    rM   geotypezGeoProxy.geotype   s     z~~f%%%rL   c                *    t          j        |           S )zReturns a deep copy.)copydeepcopyrz   s    rM   __copy__zGeoProxy.__copy__   s    }T"""rL   c                6    t          | j        | j                  S )zWReturns the ``__geo_interface__`` compatible mapping as
        :class:`dict`.
        )_rebuildrq   rm   rz   s    rM   ru   zGeoProxy.__geo_interface__   s    
 
DK000rL   Iterator[GeoMapping]c              #  D   K   dfd | j                   E d{V  dS )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", ...).

        noder?   rT   r   c              3  t  K   | t                    }|t          k    r#| t                   D ]} |          E d {V  d S |t          k    r#| t                   D ]} |          E d {V  d S |t
          k    r<| t                   }|t                    t          k    r |          E d {V  d S |V  d S | V  d S rp   TYPEFEATURE_COLLECTIONFEATURESGEOMETRY_COLLECTION
GEOMETRIESFEATUREGEOMETRY)r   type_featurer-   _iters       rM   r   z GeoProxy.__iter__.<locals>._iter   s     JE***#H~ . .G$uW~~--------. .--- $Z 0 / /H$uX......../ /'!!>D>%888$uX........."NNNNN




rL   N)r   r?   rT   r   ry   )rr   r   s    @rM   __iter__zGeoProxy.__iter__   sQ      	 	 	 	 	 	" 5$$$$$$$$$$$rL   funcCallable[[GeoProxy], bool]Nonec                Z    dfddfd | j                   s	i | _         dS dS )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.

        rT   rS   c           	         g }| t                    D ]=} t          t          |t           |i                    r|                    |           >|| t           <   t	          t          |                    S rp   )COORDINATESr"   r   appendrS   len)r{   r   r%   rN   r   s       rM   multi_entityz%GeoProxy.filter.<locals>.multi_entity  st    K{+ / /4${F!CDDEE /&&v... +DK(()))rL   c                   | t                    }|t          k    rHfd| t                   D             | t          <   t          t	          | t                                       S |t
          k    rHfd| t                   D             | t          <   t          t	          | t                                       S |t          k    rG | 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 )Nc                *    g | ]} |          |S rK   rK   ).0r   checks     rM   
<listcomp>z2GeoProxy.filter.<locals>.check.<locals>.<listcomp>  s6     " " " 'UU7^^"" " "rL   c                *    g | ]} |          |S rK   rK   )r   r-   r   s     rM   r   z2GeoProxy.filter.<locals>.check.<locals>.<listcomp>  s6     $ $ $!)x$$ $ $rL   )r   r   r   rS   r   r   r   r   r   MULTI_POINTr5   MULTI_LINE_STRINGLINE_STRINGMULTI_POLYGONPOLYGONr"   )r{   r   r   r   r   s     rM   r   zGeoProxy.filter.<locals>.check  sn   JE***" " " "+/>" " "X CX//000---$ $ $ $-1*-=$ $ $Z  CZ 011222'!!385h3H3H!PhbXDN++++%%#|D%000+++#|D+666-''#|D'222tHTNN+++rL   N)rT   rS   ry   )rr   r   r   r   s    `@@rM   filterzGeoProxy.filter  sv    	* 	* 	* 	* 	* 	*	, 	, 	, 	, 	, 	, 	, 	,0 uTZ   	DJJJ	 	rL   NOptional[TFunc]c                B    |t           }|                     |           dS )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rr   r   s     rM   globe_to_mapzGeoProxy.globe_to_map2  &    $ <%D

4rL   c                B    |t           }|                     |           dS )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   crsr   c                :    |                      |j                   dS )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rr   r   s     rM   
crs_to_wcszGeoProxy.crs_to_wcs^  s     	

3*+++++rL   c                :    |                      |j                   dS )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   rj   c                X    dfd}|                                  D ]} ||           dS )zApply the transformation function `func` recursive to all
        coordinates.

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

        rN   r?   c                R    fd | t                              | t           <   d S )Nc                `    t          | t                    r |           S fd| D             S )Nc                &    g | ]} |          S rK   rK   )r   cr   s     rM   r   zFGeoProxy.apply.<locals>.process.<locals>.transform.<locals>.<listcomp>  s!    999QIIaLL999rL   )rd   r   )coordsr   r   s    rM   r   z2GeoProxy.apply.<locals>.process.<locals>.transform  s=    fd++ :4<<'9999&9999rL   )r   )rN   r   r   s    @rM   processzGeoProxy.apply.<locals>.process  sC    : : : : : : #,)F;,?"@"@F;rL   N)rN   r?   )r   )rr   r   r   rN   s    `  rM   r   zGeoProxy.apply  sY    	A 	A 	A 	A 	A 	A mmoo 	 	FGFOOOO	 	rL   FrN   rO   rP   rQ   rR   rS   c                    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.

        )rd   r   mapping
collection)rw   rN   rP   rR   ms        rM   rV   zGeoProxy.from_dxf_entities  sJ    $ fj)) 	@*;<<AA68->??As1vvrL   rW   rX   rZ   r[   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k    rt          d           t          pi           t          | j                  D ]X\  }}|                    t
                    } |||                    t                              D ]}|r |||           |V  YdS )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`

        vertexr	   rT   r   c                r    t          t          t          j        d                    }| |j        _        |S )Nr5   r`   )r   r   r   newdxflocation)r   pointr`   s     rM   r   z'GeoProxy.to_dxf_entities.<locals>.point  s0    G
 K K KLLE!'EILrL   verticesr   c                    t          t          t          j        d                    }|                    | d           |S )Nr>   r   xy)format)r   r   r   r   append_points)r   polyliner`   s     rM   
lwpolylinez,GeoProxy.to_dxf_entities.<locals>.lwpolyline  sF    GKLLL H ""8D"999OrL   exteriorlistholesr[   c              3     K   t           j        k    r | |          V  d S t           j        z  r | |          V  t           j        z  r| g|z   D ]} |          V  d S d S rp   )r#   r<   r4   r=   )r   r   pathhatch_r   	mpolygon_r_   s      rM   polygon_z*GeoProxy.to_dxf_entities.<locals>.polygon_  s      +444i%00000 *00 .fXu-----*33 +%J. + +D$*T******+ ++ +rL   rg   strr   c                (   t          t          t          j        |                     }t          j        |j        _        |j        	                    |t          j
                   |D ](}|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)rg   r   r   dxf_polygonholer`   s        rM   dxf_polygon_z.GeoProxy.to_dxf_entities.<locals>.dxf_polygon_  s     z7;w:+V+V+VWWK*/*EKO'// < 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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 |          V  d S | t          k    r |          V  d S | t          k    r|\  }} ||          E d {V  d S | t          k    r|D ]} |          V  d S | t          k    r|D ]} |          V  d S | t
          k    r|D ]}|\  }} ||          E d {V  d S d S rp   )r5   r   r   r   r   r   )r   r%   r   r   datar   r   r   s        rM   rN   z(GeoProxy.to_dxf_entities.<locals>.entity  sf     ~~eK(((((((+%% j-------'!!"-%#8He44444444444+%%' & &D%++%%%%& &+++' + +D$*T******+ +-''' 9 9D&*OHe'x%8888888888 ('9 9rL   rB   rE   zinvalid value for polygon: N)r   r	   rT   r   )r   r	   rT   r   )r   r   r   r   rT   r[   )rg   r   r   r	   r   r	   rT   r   )r   r	   r   r	   rT   r   )rT   r[   )
ValueErrordictiter_featuresrq   r}   r   r   )rr   r_   r`   rX   rN   r   r-   r   ri   r   r   r   r   r   r   s    ``      @@@@@@rM   r^   zGeoProxy.to_dxf_entities  s     J	 	 	 	 	 	
	 	 	 	 	 	
	+ 
	+ 
	+ 
	+ 
	+ 
	+ 
	+ 
	+ 
	+	 	 	 	 	 		: 	: 	: 	: 	: 	:	= 	= 	= 	= 	= 	=	9 	9 	9 	9 	9 	9 	9 	9& Q;;'A++D7DDEEE**++
!.tz!:!: 	 	GXLL&&EVE8<<#<#<==   - LG,,,	 	rL   rl   )rY   r?   rm   rn   )rY   r?   rT   r   )rT   r?   )rT   r"   )rT   r   )r   r   rT   r   rp   )r   r   rT   r   )r   r   rT   r   )r   rj   rT   r   rN   rO   rP   rQ   rR   rS   rT   r"   )rX   rZ   rT   r[   )rF   rG   rH   rI   rs   classmethodr]   propertyr{   r~   r   r   ru   r   r   r   r   r   r   r   MAX_FLATTENING_DISTANCErV   r#   r4   r^   rK   rL   rM   r"   r"      s              
' 
' 
' [
'    X & & X&# # # # D1 1 1 X1% % % %:) ) ) )V    ,    ,	, 	, 	, 	," " " ":   *  2"'	    [2 "'m
 37m m m m m m m mrL   'Iterator[tuple[GeoMapping, GeoMapping]]c              #  B   K   i dfd |           E d{V  dS )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.

    r   r?   rT   r   c              3    K   | t                    }|t          k    r#| t                   D ]} |          E d {V  d S |t          k    r#| t                   D ]} |          E d {V  d S |t
          k    r@| | t                   }|t                    t          k    r |          E d {V  d S |fV  d S | fV  d S rp   r   )r   r   r   r-   current_featurer.   s       rM   r.   ziter_features.<locals>.features-  s.      T
&&&> - -#8G,,,,,,,,,,- -))) , . .#8H----------. .g"OH~H~!444#8H-----------%x//////!4''''''rL   N)r   r?   rT   r   rK   )rY   r   r.   s    @@rM   r   r   #  s\       #%O( ( ( ( ( ( (( x$$$$$$$$$$$rL   c                   t          j        |           } |                     t                    }|t	          dt           d          |t
          k    rJ|                     t                    }|rd |D             | t          <   nt	          dt           d          |t          k    rJ|                     t                    }|rd |D             | t          <   nt	          dt           d          |t          k    rXt          | v r7|                     t                    }|rt          |          nd| t          <   nt	          dt           d	          |t          t          t          t          t           t"          hv r|                     t$                    }|t	          dt$           d
| d          |t          k    rt'          |          }no|t          t          fv rt'          j        |          }nJ|t          k    rt+          |          }n/|t           k    rd |D             }n|t"          k    rd |D             }|| t$          <   nt-          d| d          | S )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.c                ,    g | ]}t          |          S rK   r]   r   fs     rM   r   zparse.<locals>.<listcomp>S  s    $@$@$@!U1XX$@$@$@rL   zMissing key "z" in FeatureCollection.c                ,    g | ]}t          |          S rK   r   r   gs     rM   r   zparse.<locals>.<listcomp>Z  s    &D&D&DAuQxx&D&D&DrL   z" in GeometryCollection.z" in Feature.z" in .c                6    g | ]}t          j        |          S rK   r   r   r   vs     rM   r   zparse.<locals>.<listcomp>w  s     ===A49Q<<===rL   c                ,    g | ]}t          |          S rK   )_parse_polygonr  s     rM   r   zparse.<locals>.<listcomp>y  s     BBB>!,,BBBrL   zInvalid type "z".)r   r   r}   r   r   r   r   r   r   r   r   r]   r5   r   r   r   r   r   r   r   r   r	  	TypeError)rY   r   r.   r,   r-   r%   s         rM   r]   r]   D  sv    -,,KOOD!!E}<$<<<==="""??8,, 	P$@$@x$@$@$@K!!NXNNNOOO	%	%	% __Z00
 	S&D&D&D&D&DK
##QZQQQRRR	'		 {"""x00H7?$IE(OOOTK!!DXDDDEEE	 
 
 "ook22G[GGuGGGHHHE>>{++KK{K000)K00KKg(55KK'''=====KKm##BBkBBBK#.K  2222333rL   r	   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   )rd   r	   r   r   numbersReal)r%   
first_items     rM   _is_coordinate_sequencer    s    
 k8,, 97888
;17888QJ
:!7888jmW\222rL   c                    t          |           r| }g }n| d         }| dd         }t          j        |          d |D             fS )z8Returns polygon definition as tuple (exterior, [holes]).r   rB   Nc                6    g | ]}t          j        |          S rK   r  )r   hs     rM   r   z"_parse_polygon.<locals>.<listcomp>  s      = = =!1 = = =rL   )r  r   r   )r%   r   r   s      rM   r	  r	    sX    {++  q>ABB9X = =u = = ===rL   rl   rm   rn   c                  	
 dfddfd	d	fd

fdt          |           }|t                   }|t          k    r!d |t                   D             |t          <   n`|t          k    r!d |t
                   D             |t
          <   n4|t          k    r$t          |t                             |t          <   n|t          k    r3|t                   }|j        r 	|          n
 |          |t          <   n|t          t          fv r!|t                   } 
|          |t          <   n|t          k    r;g }|t                   D ] }|                     
|                     !||t          <   nP|t           k    r |t                    |t          <   n,|t"          k    r!fd|t                   D             |t          <   |S )zrReturns ``__geo_interface__`` compatible mapping as :class:`dict` from
    compiled internal representation.

    r  r   rT   tuple[float, float]c                X    t          | j                  t          | j                  fS rp   )roundxyr  rm   s    rM   	vertex_2dz_rebuild.<locals>.vertex_2d  s&    QS&!!5f#5#555rL   tuple[float, float, float]c                    t          | j                  t          | j                  t          | j                  fS rp   )r  r  r  zr  s    rM   	vertex_3dz_rebuild.<locals>.vertex_3d  s4    QS&!!5f#5#5uQS&7I7IIIrL   r   Sequence[Vec3]6list[tuple[float, float] | tuple[float, float, float]]c                n    t          d | D                       rfd| D             S fd| D             S )Nc              3  $   K   | ]}|j         V  d S rp   )r  r  s     rM   	<genexpr>z-_rebuild.<locals>.vertices.<locals>.<genexpr>  s$      ##qqs######rL   c                &    g | ]} |          S rK   rK   )r   r  r  s     rM   r   z._rebuild.<locals>.vertices.<locals>.<listcomp>  s!    111QIIaLL111rL   c                &    g | ]} |          S rK   rK   )r   r  r  s     rM   r   z._rebuild.<locals>.vertices.<locals>.<listcomp>  s!    ---		!---rL   )any)r   r  r  s    rM   r   z_rebuild.<locals>.vertices  sX     ##F##### 	21111&1111----f----rL   c                (    fd| g|z   D             S )Nc                &    g | ]} |          S rK   rK   )r   ringr   s     rM   r   z._rebuild.<locals>._polygon.<locals>.<listcomp>  s!    >>>4>>>rL   rK   )r   r   r   s     rM   _polygonz_rebuild.<locals>._polygon  s&     ?>>>H:+=>>>>rL   c                ,    g | ]}t          |          S rK   r   r   s     rM   r   z_rebuild.<locals>.<listcomp>  s    "P"P"P18A;;"P"P"PrL   c                ,    g | ]}t          |          S rK   r,  r  s     rM   r   z_rebuild.<locals>.<listcomp>  s    $T$T$TQXa[[$T$T$TrL   c                .    g | ]\  }} ||          S rK   rK   )r   r   r   r*  s      rM   r   z_rebuild.<locals>.<listcomp>  s6     &
 &
 &
*9(EHHXu%%&
 &
 &
rL   )r  r   rT   r  )r  r   rT   r  )r   r  rT   r   )r   r   r   r   r   r   r   r   r   r5   r   r  r   r   r   r   r   r   )rY   rm   geo_interfacer   r  r%   liner*  r  r  r   s    `     @@@@rM   r   r     sA   6 6 6 6 6 6J J J J J J. . . . . . .? ? ? ? ?
 %%M$E""""P"Ph8O"P"P"Ph	%	%	%$T$T-
:S$T$T$Tj!!	'		"*=+B"C"Ch	%+&56S%JYYq\\\iillk""	;,	,	,#K0%-Xk%:%:k""	#	#	#!+. 	/ 	/Dxx~~....%0k""	'		%-X}[/I%Jk""	-		&
 &
 &
 &
=J;=W&
 &
 &
k" rL   r   c                   |                                  }t          | t                    rt          t          t
          | j        j        iS t          | t                    r%t          | j        j
        | j        j        g          S t          | t                    r^| j        s| j        rAt          |           }t!          |                    |                    }t%          ||          S t'          d          t          | t(                    rAt          |           }t!          |                    |                    }t%          ||          S |dv r0t%          t!          |                     |                    |          S |dv r$t%          |                     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)rg   rd   r   r   r5   r   r   r   r   line_string_mappingstartendr   rf   re   r   r   
flattening_line_string_or_polygon_mappingr
  r   wcs_verticesr   _hatch_as_polygon)rN   rP   rR   rg   r   pointss         rM   r   r     s   , nnG&%   !e[&**=>>	FD	!	! !"FJ$4fjn#EFFF	FH	%	% !  	DF$9 	DV$$D$//(3344F26;LMMMBCCC	FJ	'	' !  dooh//00.v7HIII	:	:	:.""8,,--/@
 
 	
 
0	0	0.d++->
 
 	
 
FJ	'	' ! 3DEEE   rL   r:  
list[Vec3]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   r3  is_linear_ringpolygon_mapping)r:  rR   len_s      rM   r7  r7    so    v;;Daxx0111qyy%y"6***&!! 	/"62...&v...rL   hatchr   c                   d	fd}d	fd| j         j        j        |                                 | j         j        }t          | j                            |                    }t          |          }|dk    r$t          | 
                                 d          |d         }|dk    s|t          j        k    r ||          }t          ||          S |rf ||          }t          ||          g}	|dd          D ]0}
 ||
          }|	                    t          ||                     1t          |	          S g }t!          |          D ]?\  }} |          }|                    t#          |fd|D                                  @t          |          dk    rt          |          S |d         S )
NrT   r;  c                <    t          |           } |          S rp   r   )boundaryr   	elevationocspath_to_verticess     rM   boundary_to_verticesz/_hatch_as_polygon.<locals>.boundary_to_vertices  s%    '#yAA%%%rL   c                p    |                                   t          |                                         S rp   )r2  r   r6  )r   rP   s    rM   rG  z+_hatch_as_polygon.<locals>.path_to_vertices  s*    

DOOH--...rL   r   z without any boundary path.rB   c                &    g | ]} |          S rK   rK   )r   r   rG  s     rM   r   z%_hatch_as_polygon.<locals>.<listcomp>@  s%    ,V,V,V-=-=d-C-C,V,V,VrL   )rT   r;  )r   rE  r  rF  r   r   r   rendering_pathsr   r   rg   r   HATCH_STYLE_IGNOREr7  r   join_multi_single_type_mappings_boundaries_to_polygonsr>  )r@  rP   rR   rH  r   
boundariescountr   r:  r,   r   polygonsr   rE  rF  rG  s    `           @@@rM   r9  r9    s0   & & & & & & & &/ / / / / / 	#%I
))++C)'K ek11+>>??J
OOEzzEMMOOHHHIII!}Hzz[E$<<<%%h//.v7HIII 	))(33F9&BSTTUJ"122  --d33!!3F<MNN    3:>>> H#::sI#V#V  %))(33#F,V,V,V,VPU,V,V,VWW    8}}q  6x@@@A;rL   c              #     K   fd| D             }t          |          D ]"}|d         }|d |dd          D             fV  #d S )Nc              3  :   K   | ]}t          |          V  d S rp   rC  )r   rD  rE  rF  s     rM   r#  z*_boundaries_to_polygons.<locals>.<genexpr>H  sA        ?G 3	::     rL   r   c                    g | ]
}|d          S )r   rK   r   r   s     rM   r   z+_boundaries_to_polygons.<locals>.<listcomp>N  s    999Ta999rL   rB   )r   )rO  rF  rE  r   r_   r   s    ``   rM   rN  rN  G  s          KU  E *%00 : :1:99WQRR[99999999: :rL   c                    fd| D             }t          d |D                       }t          |          dk    rt          |          S t          |          S )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                2    g | ]}t          |          S rK   )r   )r   ri   rP   rR   s     rM   r   zcollection.<locals>.<listcomp>g  s&    CCCQH/	0	0CCCrL   c              3  0   K   | ]}|t                    V  d S rp   )r   r  s     rM   r#  zcollection.<locals>.<genexpr>h  s&      ##A$######rL   rB   )setr   geometry_collection_mappingrM  )ra   rP   rR   r   typess    ``  rM   r   r   Q  sj    , 	DCCCC(CCCA#######E
5zzA~~*1---.q111rL   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   r3  r3  o  s     +{F33rL   c                D    | d                              | d                   S )Nr   )iscloser]  s    rM   r=  r=    s    !9VBZ(((rL   Tc                Z   t          |           dk     rt          dt          |                      | d                             | d                   s|                     | d                    t	          |           r|r|                                  n|s|                                  | 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   r_  )r   r   r`  r   r   reverse)r:  ccws     rM   linear_ringrd    s     6{{Q?#f++??@@@!9VBZ(( !fQi    ((  	NN 	NNMrL   r   list[list[Vec3]]c                |    t          | d          }|rd |D             }||f}n|g f}t          t          t          |iS )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rc  c                0    g | ]}t          |d           S )Frg  )rd  rU  s     rM   r   z#polygon_mapping.<locals>.<listcomp>  s%    @@@$Tu---@@@rL   )rd  r   r   r   )r:  r   r   ringss       rM   r>  r>    sY    4 6t,,,H @@%@@@%"gU rL   Iterable[GeoMapping]c                   t                      }t                      }| D ]B}|                    |t                              |                    |t
                              Ct          |          dk    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)rY  r   addr   r   r   r   r
  r   r   tuple)r,   r[  r   r  s       rM   rM  rM    s     EEE66D $ $		!D'AkN####
5zzA~~6#e**66777	UqvvgeQ/dCCrL   c                F    t           t          t          t          |           iS )z>Returns multiple geometries as a "GeometryCollection" mapping.)r   r   r   r   )r,   s    rM   rZ  rZ    s    %z4
3C3CDDrL   iRa gQ?XAg      ?rC   g       @g      @r   r   c                P    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!     %hj(*==>>>rL   ư>tolc                R    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   rr  s     rM   r   r     s#     %hj(*cBBCCCrL   dr   sc                V    | t          |          dz  z   t          |          dz  z   }|S )z6Convert degree, minutes, seconds into decimal degrees.<     )rQ   )rt  r   ru  dds       rM   dms2ddrz    s*    	
U1XX]	U1XX_	,BIrL   ry  r  c                ^    t          | dz  d          \  }}t          |d          \  }}|||fS )z6Convert decimal degrees into degree, minutes, seconds.rx  rw  )divmod)ry  r   ru  rt  s       rM   dd2dmsr}  	  s5    "t)R  DAq!R==DAqa7NrL   r   r   c                    |                     t                    }|dS |                     d          }|r|| j        _        dS dS )zsReference implementation for a :func:`post_process` function.

    .. seealso::

        :func:`dxf_entities`

    Nlayer)r}   
PROPERTIESr   r  )rN   r   r0   r  s       rM   assign_layersr    sS     Z((JNN7##E ! 
! !rL   r   )rY   r?   rX   rZ   rT   r[   )ra   rb   rT   r[   )rY   r?   rT   r   )rY   r?   rT   r?   )r%   r	   rT   rS   )r%   r	   rT   r	   r   )rY   r?   rm   rn   rT   r?   )rN   r   rP   rQ   rR   rS   rT   r?   )r:  r;  rR   rS   )r@  r   rP   rQ   rR   rS   rT   r?   )ra   rb   rP   rQ   rR   rS   rT   r?   )r:  r;  rT   r?   )r:  r;  )T)r:  r;  rT   r;  )r:  r;  r   re  rT   r?   )r,   rj  rT   r?   )r   r   rT   r   )rq  )r   r   rr  rQ   rT   r   )r   r   )rt  rQ   r   rQ   ru  rQ   rT   rQ   )ry  rQ   rT   r  )rN   r   r   r?   rT   r   )erI   
__future__r   typingr   r   r   r   r   r	   r
   r   r   typing_extensionsr   r   r  r   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   r  r   r   rh   r   r?   __annotations__r@   IntEnumr#   r   r4   r    r!   rj   r"   r   r]   r  r	  r   r   r7  r9  rN  r   r3  r=  rd  r>  rM  rZ  WGS84_SEMI_MAJOR_AXISWGS84_SEMI_MINOR_AXISsqrtWGS84_ELLIPSOID_ECCENTRICri   CONST_E2pi
CONST_PI_2
CONST_PI_4r   r   rz  r}  r  rK   rL   rM   <module>r     s|  
 
 
 # " " " " "
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 . - - - - - - -                  S R R R R R R R R R H H H H H H H H H H H H H H - - - - - -       " " " " " " P
O
O% 
* 


(       'sCx0
 0 0 0 0%z:&>&DE E E E E       & .#K K K K K* #)
 /3) ) ) ) ) )X	 	 	 	 TFDL) ) ) ) )n n n n n n n nb% % % %B9 9 9 9x3 3 3 3> > > >1 1 1 1 1l .#3! 3! 3! 3! 3!l
/ 
/ 
/ 
/3 3 3 3l: : : .#2 2 2 2 2<4 4 4 4") ) ) )    *# # # #LD D D D$E E E E   $ %DI

"%:A%=
==   6C<Ws]
Ws]

? 
? 
? 
?D D D D D       ! ! ! ! ! !rL   