
    i.!              
       R   S r SSKrSSKrSSKrSSKrSSKrSSKJr  SSK	r
SSKJr  SSKJr  SrSr\\-  rS\
R"                  S	\
R"                  4S
 jrS\R                  S	\R                  4S jrS rS rS\S\S\S\S\4
S jrSS\S\S\S\4S jjrS rS r\S:X  a  \" 5         gg)a   
Tile 2048x2048 images into 512x512 crops and export road graphs as GeoJSON.

For each region_X:
  - Splits region_X_sat.png and region_X_gt.png into a 4x4 grid of 512x512 crops
  - Clips the road graph (region_X_refine_gt_graph.p) to each tile
  - Writes GeoJSON LineStrings in tile-local pixel coordinates

Output structure mirrors input splits, e.g.:
  <output_dir>/train/1/region_0_tile_r0_c0_sat.png
  <output_dir>/train/1/region_0_tile_r0_c0_gt.png
  <output_dir>/train/1/region_0_tile_r0_c0_roads.geojson
    N)Path)Image)tqdmi   i   binary_maskreturnc           
      V   U S:  R                  [        R                  5      nSnU(       Ga|  SnS GHi  n[        R                  " USSS9nUSS2SS24   nUS	S
2SS24   nUS	S
2SS	24   nUSS2SS	24   nUSS	2SS	24   n	USS	2SS24   n
USS	2S	S
24   nUSS2S	S
24   nUS	S
2S	S
24   nXgXXXU/	nXg-   U-   U	-   U
-   U-   U-   U-   n[        R                  " U5      n[        S5       H7  nUUU   S:H  UUS-      S:H  -  R                  [        R                  5      -  nM9     US:H  US:  -  US:*  -  US:H  -  nUS:X  a  Xh-  U
-  S:H  nX-  U-  S:H  nOXh-  U-  S:H  nXj-  U-  S:H  nUU-  U-  n[        R                  " U5      (       d  GMb  SUU'   SnGMl     U(       a  GM|  U$ )zKReturn a 1-pixel-wide skeleton for a binary mask using Zhang-Suen thinning.r   TF)r      r	   constantmodeN         )astypenpuint8pad
zeros_likerangeany)r   imgchangedstepr   p1p2p3p4p5p6p7p8p9	neighborsbaicommonm1m2removes                         8/mnt/vision/data/Global-Scale-Road-Dataset/make_crops.pyzhang_suen_thinningr.      s   ?
"
"288
,CG
D&&aj1CQrT1R4ZBSbS!B$YBSbS!"WBQrT12XBQRVBQR2XBQR"WBQrT3B3YBSbS#2#XB<I"r!B&+b025Ab!A1Xy|q(Yq1u-=-BCKKBHHUU  Ag!q&)Q!V4Q?Fqyglq(glq(glq(glq(b[2%Fvvf~~F;  'B J    mask_imgc                    [         R                  " U 5      nUR                  S:X  a  US   n[        US:  R	                  [         R
                  5      5      n[        R                  " US-  R	                  [         R
                  5      SS9$ )zNBinarize and skeletonize a mask tile, returning an 8-bit single-channel image.   ).r   r      Lr   )r   arrayndimr.   r   r   r   	fromarray)r0   arrskels      r-   skeletonize_mask_imager:   H   se    
((8
C
xx1}&ka//9:D??D3J..rxx8sCCr/   c                   ^^^^^^^^ Su  mmmmUUUUUUUU4S jnU u  pxUu  pU" Xx5      U" X5      p X-  (       d  Xx4X44$ X-  (       a  gU(       a  UOUnUT-  (       a  X:w  a
  TU-
  X-
  -  OSnTXX-
  -  -   nnOjUT-  (       a  X:w  a
  TU-
  X-
  -  OSnTXX-
  -  -   nnOCUT-  (       a  X:w  a
  TU-
  X-
  -  OSnX~X-
  -  -   TnnOX:w  a
  TU-
  X-
  -  OSnX~X-
  -  -   TnnX:X  a  UUpU" Xx5      nOUUpU" X5      nM  )z
Clip line segment p1->p2 to the axis-aligned box [x0,x1) x [y0,y1).
Returns clipped (p1', p2') or None if fully outside.
Uses Cohen-Sutherland algorithm.
)r	   r      r   c                 j   > SnU T:  a  UT-  nOU T:  a  UT-  nUT	:  a  UT-  nU$ UT
:  a  UT-  nU$ )Nr    )xycBOTTOMLEFTRIGHTTOPx0x1y0y1s      r-   codeclip_edge_to_tile.<locals>.codeY   sV    r6IAVJAr6KA  VHAr/   Nr   r>   )r   r   rF   rH   rG   rI   rJ   axaybxbycacbrA   tr?   r@   rB   rC   rD   rE   s     ````           @@@@r-   clip_edge_to_tilerS   Q   sI     *D%
 
 FBFB"\4<
8bX%%7B"t8)+bRW%qArM)qAqY)+bRW%qArM)qAqZ)+bRW%qARW%rqAq)+bRW%qARW%rqA7bBbB1 r/   c           
         U[         -  nU[         -  nU[         -   nU[         -   n/ n[        5       nU R                  5        H  u  pU
 H  n[        X5      [	        X5      4nX;   a  M   UR                  U5        [        XX4XV5      nUc  MC  Uu  pUS   U-
  US   U-
  /nUS   U-
  US   U-
  /nUR                  SSUU/S.0 S.5        M     M     SUS.$ )	z
Build a GeoJSON FeatureCollection of road edges clipped to tile (row, col).
Coordinates are in tile-local pixels: (0,0) = top-left of tile.
r   r	   Feature
LineString)typecoordinates)rW   geometry
propertiesFeatureCollection)rW   features)	TILE_SIZEsetitemsminmaxaddrS   append)graphrowcolrF   rH   rG   rI   r\   seennoder%   nbedge_keyclippedpapblocal_palocal_pbs                     r-   graph_to_geojson_tilerp      s    
 
yB	yB	iB	iBH5D ;;=BDs4}5HHHX'""AGFB1
BqEBJ/H1
BqEBJ/HOO!($,h#7 !   ). (X>>r/   
graph_pathsat_pathgt_pathout_dirskeletonize_gtc                    UR                   R                  SS5      n[        U S5       n[        R                  " U5      nS S S 5        [
        R                  " U5      n[
        R                  " U5      n	[        [        5       H  n
[        [        5       H  nU[        -  nU
[        -  nXU[        -   U[        -   4nU SU
 SU 3nUR                  U5      R                  X? S3-  5        U	R                  U5      nU(       a  [        U5      nUR                  X? S3-  5        [        WX5      n[        X? S3-  S	5       n[        R                  " UU5        S S S 5        M     M     g ! , (       d  f       GN2= f! , (       d  f       M  = f)
N_sat rb_tile_r_cz_sat.png_gt.pngz_roads.geojsonw)stemreplaceopenpickleloadr   r   GRIDr]   cropsaver:   rp   jsondump)rq   rr   rs   rt   ru   prefixfrd   satgtre   rf   rF   rH   boxtaggt_tilegeojsons                     r-   process_regionr      sK   ]]""62.F 
j$	1A 
  **X
C	G	BT{;CyByB2	>2	>:CHGC53%0C HHSMw5)99:ggclG09LLU'?23 ,E3<Gg%~ 66<		'1% =<   
 	. =<s   E+E=+
E:=
F
split_rootout_rootworkersc           	         / n[        U R                  5       5       H  nUR                  5       (       d  M  XR                  -  nUR	                  SSS9  [        UR                  S5      5      nU(       d  M[  U Ho  nUR                  R                  SS5      n	XY S3-  n
XY S3-  nU
R                  5       (       d  MD  UR                  5       (       d  M[  UR                  XXU45        Mq     M     [        U R                  5      n[        R                  " U5       n[        [        UR                  [         U5      [#        U5      US95        S S S 5        g ! , (       d  f       g = f)	NT)parentsexist_okz	*_sat.pngrw   rx   r|   z_refine_gt_graph.p)totaldesc)sortediterdiris_dirnamemkdirglobr~   r   existsrc   strmpPoollistr   imap_unordered_process_region_starlen)r   r   r   ru   jobscity_dirout_city	sat_filesrr   r   rs   rq   r   pools                 r-   process_splitr      s   D:--/0  mm+td38==56	!H]]**626F87!33G!h.@$AAJ~~J$5$5$7$7Z7nUV " 1" zD		TT$%%&:DATY]^_ 
		s   2E
E$c                      [        U 6   g ! [         a+  n[        SU S    SU 3[        R                  S9   S nAg S nAff = f)Nz
  [error] r	   z: file)r   	Exceptionprintsysstderr)argses     r-   r   r      s>    < <
47)2aS)

;<s    
A !;A c                  b   [         R                  " SS9n U R                  S[        SS9  U R                  S[        SS9  U R                  SS	/ S
QSS9  U R                  S[        SSS9  U R                  SSSS9  U R                  5       nUR                  (       + nUR                   Hz  nUR                  U-  nUR                  5       (       d  [        SU S3[        R                  S9  ME  UR                  U-  n[        SU SU 35        [        XEUR                  US9  M|     [        S5        g )NzFTile Global-Scale dataset into 512x512 crops with GeoJSON road graphs.)descriptiondataset_rootz2Path to dataset root (contains train/, val/, etc.))rW   helpoutput_rootzPath to write tiled outputsz--splits+)trainvalzin-domain-testout_of_domainz&Which splits to process (default: all))nargsdefaultr   z	--workersr   z0Number of parallel worker processes (default: 8))rW   r   r   z--no-skeletonize-gt
store_truez-Disable skeletonization and keep raw GT crops)actionr   z[skip] z
 not foundr   zProcessing z -> )r   ru   zDone.)argparseArgumentParseradd_argumentr   int
parse_argsno_skeletonize_gtsplitsr   r   r   r   r   r   r   r   )parserr   ru   split
split_pathout_paths         r-   mainr      s3   $$1yzF
T8lm
D7TU

#7jE  G
#q?qr
-lL  ND///N&&.
  ""GJ<z2D##e+E7$xj12jDLLQ_`  
'Nr/   __main__)r   T)__doc__r   r   multiprocessingr   r   r   pathlibr   numpyr   PILr   r   r]   	FULL_SIZEr   ndarrayr.   r:   rS   rp   boolr   r   r   r   r   __name__r>   r/   r-   <module>r      s        
    		I&RZZ &BJJ &RDU[[ DU[[ D0f$?N&t &t &d &T &cg &>`d `d `S `VZ `0<0 zF r/   