
    Og7L                       U d dl mZ d dl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mZmZ d dlmZmZ d dlmZmZ dd	lmZ dd
lmZmZmZmZ ddl m!Z! ddl"m#Z# ddgZ$dZ% G d de      Z&dZ'dZ(dZ)dZ*dZ+ G d de&      Z,ed%d&d       Z-ee.e/e.gee.ef   f   Z0de1d<   eege
e/e/f   f   Z2de1d<   e	e
e/e/f      Z3de1d<   e	e3   Z4de1d<   d'dZ5d(dZ6d)d*d Z7 G d! de&      Z8d+d"Z9	 	 	 	 	 	 	 	 	 	 d,d#Z:	 	 	 	 	 	 	 	 d-d$Z;y).    )annotations)IterableSequenceno_type_checkAnyCallableDictListTuple)	TypeAliasoverrideN)Vec2world_mercator_to_gps)Commandnesting)orient_pathssingle_paths   )Color)BackendInterfaceBkPath2d
BkPoints2d	ImageData)Configuration)BackendPropertiesCustomJSONBackendGeoJSONBackenda~  
JSON content = [entity, entity, ...]

entity = {
    "type": point | lines | path | filled-paths | filled-polygon,
    "properties": {
        "color": "#RRGGBBAA",
        "stroke-width": 0.25, # in mm
        "layer": "name"
    },
    "geometry": depends on "type"
}
DXF linetypes (DASH, DOT, ...) are resolved into solid lines.

A single point:
point = {
    "type": "point",
    "properties": {...},
    "geometry": [x, y]
}

Multiple lines with common properties:
lines = {
    "type": "lines",
    "properties": {...},
    "geometry": [
        (x0, y0, x1, y1),  # 1. line
        (x0, y0, x1, y1),  # 2. line
        ....
    ]
}
Lines can contain points where x0 == x1 and y0 == y1!

A single linear path without filling:
path = {
    "type": "path",
    "properties": {...},
    "geometry": [path-command, ...]
}

SVG-like path structure:
- The first path-command is always an absolute move to "M"
- The "M" command does not appear inside a path, each path is a continuouse geometry 
  (no multi-paths).

path-command = 
    ("M", x, y) = absolute move to
    ("L", x, y) = absolute line to
    ("Q", x0, y0, x1, y1) = absolute quadratice Bezier curve to
    - (x0, y0) = control point
    - (x1, y1) = end point
    ("C", x0, y0, x1, y1, x2, y2) = absolute cubic Bezier curve to
    - (x0, y0) = control point 1
    - (x1, y1) = control point 2
    - (x2, y2) = end point
    ("Z",) = close path

Multiple filled paths:

Exterior paths and holes are mixed and NOT oriented by default (clockwise or 
counter-clockwise) - PyQt and SVG have no problem with that structure but matplotlib 
requires oriented paths.  When oriented paths are required the CustomJSONBackend can 
orient the paths on demand.

filled-paths = {
    "type": "filled-paths",
    "properties": {...},
    "geometry": [
        [path-command, ...],  # 1. path
        [path-command, ...],  # 2. path  
        ...
    ]
}

A single filled polygon:
A polygon is explicitly closed, so first vertex == last vertex is guaranteed.
filled-polygon = {
    "type": "filled-polygon",
    "properties": {...},
    "geometry": [
        (x0, y0),
        (x1, y1),
        (x2, y2),
        ...
    ]
}

c                      e Zd ZddZej
                  dd       ZddddZedd       Z	edd       Z
edd       Zedd	       Zedd
       Zedd       Zedd       Zy)_JSONBackendc                J    g | _         d| _        d| _        d| _        d| _        y )Ng{Gz?皙?g      ?        )	_entitiesmax_sagittamin_lineweightlineweight_scalingfixed_lineweightselfs    ^/var/www/html/public_html/myphp/venv/lib/python3.12/site-packages/ezdxf/addons/drawing/json.py__init__z_JSONBackend.__init__p   s+    /1""% !$    c                     y N r(   s    r*   get_json_dataz_JSONBackend.get_json_dataz   s    $'r,      indentc               L    t        j                  | j                         |      S )z$Returns the result as a JSON string.r2   )jsondumpsr0   )r)   r3   s     r*   
get_stringz_JSONBackend.get_string|   s    zz$,,.v>>r,   c                    |j                   r#|j                   dz  dz  }t        d|      | _         |j                  | _        | j                  dk(  r| j                   | _        |j                  | _        y )Ngffffff9@i,  r!   r"   )r%   maxr&   r'   max_flattening_distancer$   )r)   configmin_lineweight_mms      r*   	configurez_JSONBackend.configure   si       & 5 5 <s B"%d,=">D"(";";""c)$($7$7D!!99r,   c                8    | j                   j                          y r.   )r#   clearr(   s    r*   r?   z_JSONBackend.clear   s    r,   c                     y r.   r/   )r)   
image_data
propertiess      r*   
draw_imagez_JSONBackend.draw_image       r,   c                     y r.   r/   )r)   colors     r*   set_backgroundz_JSONBackend.set_background   rD   r,   c                     y r.   r/   r(   s    r*   finalizez_JSONBackend.finalize   rD   r,   c                     y r.   r/   )r)   entityrB   s      r*   enter_entityz_JSONBackend.enter_entity   rD   r,   c                     y r.   r/   )r)   rK   s     r*   exit_entityz_JSONBackend.exit_entity   rD   r,   NreturnNone)rP   r   )r3   z	int | strrP   str)r;   r   rP   rQ   )rA   r   rB   r   rP   rQ   )rF   r   rP   rQ   )__name__
__module____qualname__r+   abcabstractmethodr0   r7   r   r=   r?   rC   rG   rI   rL   rN   r/   r,   r*   r   r   o   s    $ 	' '01 ? 	: 	:            r,   r   MLQCZc                       e Zd ZdZdd fdZedd       Z	 	 	 	 	 	 ddZddZedd       Z	edd       Z
e	 	 	 	 	 	 dd       Zedd	       Ze	 	 	 	 	 	 dd
       Ze	 	 	 	 	 	 dd       Z xZS )r   a  Creates a JSON-like output with a custom JSON scheme.  This scheme supports
    curved shapes by a SVG-path like structure and coordinates are not limited in
    any way.  This backend can be used to send geometries from a web-backend to a
    frontend.

    The JSON scheme is documented in the source code:

    https://github.com/mozman/ezdxf/blob/master/src/ezdxf/addons/drawing/json.py

    Args:
        orient_paths: orient exterior and hole paths on demand, exterior paths have
            counter-clockwise orientation and holes have clockwise orientation.

    **Class Methods**

    .. automethod:: get_json_data

    .. automethod:: get_string

    .. versionadded:: 1.3.0

    c                0    t         |           || _        y r.   )superr+   r   )r)   r   	__class__s     r*   r+   zCustomJSONBackend.__init__   s    (r,   c                    | j                   S )z1Returns the result as a JSON-like data structure.)r#   r(   s    r*   r0   zCustomJSONBackend.get_json_data   s     ~~r,   c                f    |sy | j                   j                  || j                  |      |d       y )NtyperB   geometry)r#   appendmake_properties_dict)r)   entity_typere   rB   s       r*   
add_entityzCustomJSONBackend.add_entity   s5     #"77
C$	
r,   c                    | j                   r| j                   }n-t        | j                  |j                  | j                  z        }|j
                  t        |d      |j                  dS )Nr1   rF   zstroke-widthlayerr'   r9   r%   
lineweightr&   rF   roundrl   r)   rB   stroke_widths      r*   rg   z&CustomJSONBackend.make_properties_dict   sd      00L##Z%:%:T=T=T%TL  %%!,2%%
 	
r,   c                V    | j                  d|j                  |j                  g|       y )Npointri   xyr)   posrB   s      r*   
draw_pointzCustomJSONBackend.draw_point   s    #%%<r,   c                    | j                  d|j                  |j                  |j                  |j                  fg|       y )Nlinesrt   )r)   startendrB   s       r*   	draw_linezCustomJSONBackend.draw_line   s.    577EGGSUUCEE"B!CZPr,   c                    t        |      }t        |      dk(  ry | j                  d|D cg c]3  \  }}|j                  |j                  |j                  |j                  f5 c}}|       y c c}}w )Nr   r{   )listlenri   ru   rv   )r)   r{   rB   ses        r*   draw_solid_linesz"CustomJSONBackend.draw_solid_lines   sV     Uu:?5!I41a133QSS!##"6!I:V!Is   8A.c                <    | j                  dt        |      |       y )Npath)ri   make_json_path)r)   r   rB   s      r*   	draw_pathzCustomJSONBackend.draw_path   s    t 4jAr,   c                   t        |      }t        |      dk(  ry | j                  rt        |      }nt        |      }g }|D ]*  }t        |      s|j	                  t        |d             , |r| j                  d||       y y )Nr   T)closezfilled-paths)r   r   r   r   rf   r   ri   )r)   pathsrB   
json_pathsr   s        r*   draw_filled_pathsz#CustomJSONBackend.draw_filled_paths   s     Uu:? 'E !'E "
 	DD4y!!.T"BC	D OONJ
C r,   c                   |j                         }t        |      dk  ry |d   j                  |d         s|j                  |d          | j	                  d|D cg c]  }|j
                  |j                  f c}|       y c c}w )N   r   zfilled-polygon)verticesr   iscloserf   ri   ru   rv   )r)   pointsrB   r   vs        r*   draw_filled_polygonz%CustomJSONBackend.draw_filled_polygon  sp      &0x=1{""8B<0OOHQK((x*H!ACC:*H*U*Hs   B
FrO   )rP   zlist[dict[str, Any]])rh   rR   re   zSequence[Any]rB   r   )rB   r   rP   dict[str, Any]rx   r   rB   r   rP   rQ   r|   r   r}   r   rB   r   rP   rQ   r{   zIterable[tuple[Vec2, Vec2]]rB   r   rP   rQ   r   r   rB   r   rP   rQ   r   zIterable[BkPath2d]rB   r   rP   rQ   r   r   rB   r   rP   rQ   )rS   rT   rU   __doc__r+   r   r0   ri   rg   ry   r~   r   r   r   r   __classcell__r`   s   @r*   r   r      s   .)  

*7
EV

 = = Q Q W0W>OW	W W B B D'D5FD	D D$ V V.?V	V Vr,   c           
        t        |       dk(  rg S | j                  }t        |j                  |j                  fg}| j                         D ]  }|j                  }|j                  t        j                  k(  r-|j                  t        |j                  |j                  f       Z|j                  t        j                  k(  r-|j                  t        |j                  |j                  f       |j                  t        j                  k(  rP|j                  }|j                  t        |j                  |j                  |j                  |j                  f       |j                  t        j                   k(  s0|j"                  }|j$                  }|j                  t&        |j                  |j                  |j                  |j                  |j                  |j                  f        |r|j                  t(               |S )Nr   )r   r|   MOVE_TO_ABSru   rv   commandsr}   rd   r   MOVE_TOrf   LINE_TOLINE_TO_ABS	CURVE3_TOctrlQUAD_TO_ABS	CURVE4_TOctrl1ctrl2CUBIC_TO_ABS
CLOSE_PATH)r   r   r}   r   cmdc1c2s          r*   r   r     sW   
4yA~	

C"CEE35512H}} Rgg88w&OO[#%%78XX(OO[#%%78XX***BOO["$$ceeSUUCDXX***BBOO\244rttRTT355#%%PQR 
#Or,   r   PropertiesMakerTransformFuncRingGeoJsonPolygonc                "    | t        |d      |dS )a  Returns the property dict::

        {
            "color": color,
            "stroke-width": stroke_width,
            "layer": layer,
        }

    Returning an empty dict prevents properties in the GeoJSON output and also avoids
    wraping entities into "Feature" objects.
    r1   rk   )ro   )rF   rq   rl   s      r*   properties_makerr   >  s     lA. r,   c                2    | j                   | j                  fS )zsDummy transformation function.  Does not apply any transformations and
    just returns the input coordinates.
    )ru   rv   )locations    r*   no_transformr   Q  s     JJ

##r,   c                     d fd}|S )aG  Returns a function to 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:
        tol: accuracy for latitude calculation

    c                F    t        | j                  | j                        S )zITransforms WGS84 World Mercator EPSG:3395 coordinates to WGS84 EPSG:4326.)r   ru   rv   )r   tols    r*   
_transformz7make_world_mercator_to_gps_function.<locals>._transformc  s    $XZZSAAr,   r   r   rP   ztuple[float, float]r/   )r   r   s   ` r*   #make_world_mercator_to_gps_functionr   X  s    B r,   c                       e Zd ZdZeef	 	 	 	 	 d fdZedd       ZddZ	ddZ
edd       Zedd       Ze	 	 	 	 	 	 dd       Zedd	       Ze	 	 	 	 	 	 dd
       Ze	 	 	 	 	 	 dd       Z xZS )r   a1  Creates a JSON-like output according the `GeoJSON`_ scheme.
    GeoJSON uses a geographic coordinate reference system, World Geodetic
    System 1984 `EPSG:4326 <https://epsg.io/4326>`_, and units of decimal degrees.

    - Latitude: -90 to +90 (South/North)
    - Longitude: -180 to +180 (East/West)

    So most DXF files will produce invalid coordinates and it is the job of the
    **package-user** to provide a function to transfrom the input coordinates to
    EPSG:4326!  The :class:`~ezdxf.addons.drawing.recorder.Recorder` and
    :class:`~ezdxf.addons.drawing.recorder.Player` classes can help to detect the
    extents of the DXF content.

    Default implementation:

    .. autofunction:: no_transform

    Factory function to make a transform function from WGS84 World Mercator
    `EPSG:3395 <https://epsg.io/3395>`_  coordinates to WGS84 (GPS) 
    `EPSG:4326 <https://epsg.io/4326>`_.

    .. autofunction:: make_world_mercator_to_gps_function

    The GeoJSON format supports only straight lines so curved shapes are flattened to
    polylines and polygons.

    The properties are handled as a foreign member feature and is therefore not defined
    in the GeoJSON specs.  It is possible to provide a custom function to create these
    property objects.

    Default implementation:

    .. autofunction:: properties_maker


    Args:
        properties_maker: function to create a properties dict.

    **Class Methods**

    .. automethod:: get_json_data

    .. automethod:: get_string

    .. versionadded:: 1.3.0
    
    .. _GeoJSON: https://geojson.org/
    c                >    t         |           || _        || _        y r.   )r_   r+   _properties_dict_maker_transform_function)r)   r   transform_funcr`   s      r*   r+   zGeoJSONBackend.__init__  s     
 	&6##1 r,   c                    t        | j                        dk(  ri S | j                  d   d   dk(  }|rd| j                  dS d| j                  dS )zMReturns the result as a JSON-like data structure according the GeoJSON specs.r   rd   FeatureFeatureCollection)rd   featuresGeometryCollection)rd   
geometries)r   r#   )r)   using_featuress     r*   r0   zGeoJSONBackend.get_json_data  sS     t~~!#I*62i?/T^^LL0OOr,   c                    |sy  | j                   | j                  |       }|r | j                  j                  d||d       y | j                  j                  |       y )Nr   rc   )r   make_propertiesr#   rf   )r)   rK   rB   properties_dicts       r*   ri   zGeoJSONBackend.add_entity  sa    *E$*E*E!!*-+
 NN!!%"1 & NN!!&)r,   c                    | j                   r| j                   }n-t        | j                  |j                  | j                  z        }|j
                  t        |d      |j                  fS )Nr1   rm   rp   s      r*   r   zGeoJSONBackend.make_properties  s^      00L##Z%:%:T=T=T%TL   %a"8*:J:JKKr,   c           
     l    | j                  t        dt        | j                  |                  |       y )NPoint)ri   geojson_objectr   r   rw   s      r*   ry   zGeoJSONBackend.draw_point  s*    7D)A)A#)F$GH*	
r,   c           	     p    | j                   }| j                  t        d ||       ||      g      |       y )N
LineString)r   ri   r   )r)   r|   r}   rB   tfs        r*   r~   zGeoJSONBackend.draw_line  s3    %%<"U)RW)=>	
r,   c                    t        |      }t        |      dk(  ry | j                  }|D cg c]  \  }} ||       ||      f }}}| j                  t	        d|      |       y c c}}w )Nr   MultiLineString)r   r   r   ri   r   )r)   r{   rB   r   r   r   
json_liness          r*   r   zGeoJSONBackend.draw_solid_lines  sd     Uu:?%%167Ar!uben7
7'8*EzR 8s   A&c                    t        |      dk(  ry | j                  }|j                  | j                        D cg c]
  } ||       }}| j	                  t        d|      |       y c c}w )Nr   )distancer   )r   r   
flatteningr$   ri   r   )r)   r   rB   r   r   r   s         r*   r   zGeoJSONBackend.draw_path  s^    t9>%%#'??D<L<L?#MNaBqENN|X>
K Os   A(c                   t        |      }t        |      dk(  ry g }|D ]?  }t        |      s|j                  t        || j                  | j
                               A |r| j                  t        d|      |       y y )Nr   )r$   r   MultiPolygon)r   r   extendgeojson_polygonsr$   r   ri   r   )r)   r   rB   polygonsr   s        r*   r   z GeoJSONBackend.draw_filled_paths  s|     Uu:?)+ 	D4y$$*:*:t?W?W	 OON>8DjQ r,   c                   |j                         }t        |      dk  ry |d   j                  |d         s|j                  |d          | j                  }| j                  t        d|D cg c]
  } ||       c}g      |       y c c}w )Nr   r   r   Polygon)r   r   r   rf   r   ri   r   )r)   r   rB   r   r   r   s         r*   r   z"GeoJSONBackend.draw_filled_polygon  s}      &0x=1{""8B<0OOHQK(%%9x'@!1'@&ABJ	
'@s   ,B	)r   r   r   r   rP   rQ   )rP   r   )rK   r   rB   r   )rB   r   rP   ztuple[str, float, str]r   r   r   r   r   r   )rS   rT   rU   r   r   r   r+   r   r0   ri   r   ry   r~   r   r   r   r   r   r   s   @r*   r   r   i  s   /f -=(42)2 &2 
	2 P P*"L 
 

 
 
 S0S>OS	S S L L R'R5FR	R R$ 
 
.?
	
 
r,   c                    | |dS )N)rd   coordinatesr/   )namer   s     r*   r   r     s    55r,   c                4   | j                   rt        d      | j                  |      D cg c]
  } ||       }}| j                  s#| j                  }|j                   ||             | j                         }|r|r|s|r|j                          |S c c}w )a#  Returns a linear ring according to the GeoJSON specs.

    -  A linear ring is a closed LineString with four or more positions.
    -  The first and last positions are equivalent, and they MUST contain
       identical values; their representation SHOULD also be identical.
    -  A linear ring is the boundary of a surface or the boundary of a
       hole in a surface.
    -  A linear ring MUST follow the right-hand rule with respect to the
       area it bounds, i.e., exterior rings are counterclockwise, and
       holes are clockwise.

    zmulti-paths not allowed)has_sub_paths	TypeErrorr   	is_closedr|   rf   has_clockwise_orientationreverse)r   is_holer$   r   r   r   r|   	clockwises           r*   geojson_ringr     s     122%)__[%ABbeBHB>>

5	"..0I	7yO Cs   Bc           
     6   | j                         }t        |      dk(  rg S t        |      dk(  rt        |d   d||      ggS t        j                  |      }g }|D ]  }t        |d   d||      g}t        |      dkD  r|d   }t        |t              r|j                  t        |d||             Vt        |t        t        f      r?|D ]:  }	t        |	t        t        f      r|	d   }	|j                  t        |	d||             < |j                  |        |S )zReturns a list of polygons, where each polygon is a list of an exterior path and
    optional holes e.g. [[ext0, hole0, hole1], [ext1], [ext2, hole0], ...].

    r   r   FT)
	sub_pathsr   r   r   make_polygon_structure
isinstancer   rf   tupler   )
r   r$   r   r   r   r   polygongeojson_polygonholesholes
             r*   r   r   ,  s-    !% 0I
9~	
9~ilE;CDEE--i8H-/ 1UK<+
 w<! AJE%*&&|E4b'QR%%/! VD!$6#Aw#**<dKQS+TU	V 	0%1& r,   r   )r   r   rP   z	list[Any])rF   rR   rq   floatrl   rR   rP   r   r   )gư>)r   r   rP   r   )r   rR   r   r   rP   r   )
r   r   r   boolr$   r   r   r   rP   r   )r   r   r$   r   r   r   rP   zlist[GeoJsonPolygon])<
__future__r   typingr   r   r   r   r   r	   r
   r   typing_extensionsr   r   rV   r5   
ezdxf.mathr   r   
ezdxf.pathr   r   ezdxf.npshapesr   r   
type_hintsr   backendr   r   r   r   r;   r   rB   r   __all__CUSTOM_JSON_SPECSr   r   r   r   r   r   r   r   rR   r   r   __annotations__r   r   r   r   r   r   r   r   r   r   r/   r,   r*   <module>r     sz   # V V V 1 
  2 ' 5  F F ! )  0
1W t3# 3l 
lV lV^  0 &sE3&7c3h&GH H#TFE%,,?$?@y @uUE\*+i + !J	 &&$"a
\ a
H6
!05;H	6"
"!&",9""r,   