
    .i#                        S 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r	SSK
Jr  SSKrSSKJr  SrS rS4S jr S5S	 jr\S
:X  Ga-  \R,                  " SS9r\R1                  SSS9  \R1                  SSS\ S3S9  \R3                  5       r\R6                  R9                  5       r \" \R:                  5      r\S-   S3r"\" S5      \-  \ S3-  r#\" S5      \-  \ S\" S3-  r$\#RJ                  r&\#RO                  5       (       d  \ " S\# 35        \RB                  " S5        \$RO                  5       (       d  \ " S\$ 35        \RB                  " S5        \ " S\RQ                  5        S 35        \RR                  " \#S!S"9r*\RR                  " \$S#\" 3S"9r+/ S$Qr,/ S%Qr-\, V s/ s H  o \*R\                  ;   d  M  U PM     sn r/\- V s/ s H  o \*R\                  ;   d  M  U PM     sn r0\ " S&\/ 35        \ " S'\0 35        \/ H*  r1\" \*\+Re                  5       \1SS(9u  r3r4\" \3\4\1\\&\"SS)S*9  M,     \0 H*  r1\" \*\+Re                  5       \1S+S(9u  r3r4\" \3\4\1\\&\"S+S)S*9  M,     Sr5\" S5      \-  \ S,3-  r6\6RO                  5       (       a'   \RR                  " \6S-S"9r5\ " S.\6Rn                   35        \5b  \, V s/ s H  o \5R\                  ;   d  M  U PM     sn r:\- V s/ s H  o \5R\                  ;   d  M  U PM     sn r;\ " S0\: 35        \ " S1\; 35        \: H*  r1\" \5\+Re                  5       \1SS(9u  r3r4\" \3\4\1\\&\"SS2S*9  M,     \; H*  r1\" \5\+Re                  5       \1S+S(9u  r3r4\" \3\4\1\\&\"S+S2S*9  M,     \ " S35        gg! \ a(  r\ " S\ 35        \RB                  " S5         SrCGNSrCff = fs  sn f s  sn f ! \8 a  r9\ " S/\9 35         Sr9C9GNSr9C9ff = fs  sn f s  sn f )6z
Generate heatmaps for all key OSM road attributes aggregated per grid cell.

Enhancements:
 - Aggregates attributes per grid cell (mean for numeric, mode for categorical)
 - Uses grid resolution in output filenames
 - Handles missing data gracefully
    N)Path)	colormapsGRID_CELL_SIZE_METERSc                     U =(       d    [         R                  " [        5      nUc  [        S[         S35      e [	        U5      $ ! [         a  n[        SU S[         S35      UeSnAff = f)z8Resolve cell size from CLI args or environment variable.Nz8Cell size must be passed as an argument or provided via .zInvalid cell size 'z'. Provide an integer or set )osgetenvCELL_SIZE_ENV_VAR
ValueErrorint)explicit_value	raw_valueexcs      6/data2/heatmap/scripts/visualize_all_attribute_grid.pyresolve_cell_sizer      s}    >")),=">IFGXFYYZ[
 	
9~ !),IJ[I\\]^
	s   
A 
A,A''A,Fc                    [        SU S35        [        R                  " XSSS9nU(       aN  S nUR                  S5      U   R	                  U5      R                  5       nUR                  X" S30S	S
9  U S3nOb[        R                  " XB   SS9XB'   UR                  S5      U   R                  5       R                  5       nUR                  X" S30S	S
9  U S3nUR                  US	SSS9nX4$ )z'Aggregate road attribute per grid cell.u   📊 Aggregating z per grid cell...inner
intersects)how	predicatec                     U R                  5       nUR                  (       d  UR                  S   $ [        R                  $ )Nr   )modeemptyilocnpnan)xmode_seriess     r   	mode_func'aggregate_attributes.<locals>.mode_func3   s/    &&(K.9.?.?;##A&KRVVK    index_right_modeT)columnsinplacecoerce)errors_meanleft)
left_indexright_onr   )printgpdsjoingroupbyaggreset_indexrenamepd
to_numericmeanmerge)roadsgridattrcategoricaljoinedr   groupedattr_cols           r   aggregate_attributesr>   *   s    	dV#4
56 YYu<HF	L ../599)DPPRen5tDV5> }}V\(C../5::<HHJen5tDV5> ::g$F:SD>r!   c                 `   [         R                  " SS9u  pUR                  R                  S5        U	R                  S5        U R	                  5       R
                  n
U(       a+  UR                  5        SUR                  5        SU SU S3nO'UR                  5        SUR                  5        SU S3n[        SU S	U S
U=(       d    S S35        U(       a  X   R                  5       R                  5       n[        U5      S:  a  SnOSnU R                  UU	SSUSSSU[        U Vs/ s H  n[        U5      PM     sn5      S.SSS.S9  U
R                  U	SSS9  OX   R                  5       R                  (       d)  [        R                   " X   R                  5       SS/5      OSu  nn["        R$                  " S5      R'                  5       nUR)                  SS9  U R                  UUSU	SUUUS S!S".SSS.S#9	  U
R                  U	SSS9  U	R+                  US$S%S&9  U	R-                  S'5        [         R.                  " 5         XC S(U S)U S*3-  n[         R0                  " US+S,UR3                  5       S-9  [         R4                  " U5        [        S.UR6                   35        g s  snf )/N)   
   )figsizewhiteu    — z (z, )u   
🔎 Plotting z heatmap for z grid (layer=r7   z)...   tab20Set2Tr   )gRQ?   z
upper left)bbox_to_anchorloctitlelabelszNo Data)colorlabel)columnaxlegendr:   cmap	linewidthlegend_kwdsmissing_kwdsblackg      ?)rP   rM   rS      _   )r   rH   inferno)rM   g333333?g{Gz?)rN   shrinkpad)	rO   rR   rS   rP   rQ   vminvmaxrT   rU      rA   )fontsizer[   off_	_heatmap_z.pngi,  tight)dpibbox_inches	facecoloru   💾 Saved heatmap: )pltsubplotspatchset_facecolordissolveboundary
capitalizer,   dropnauniquelenplotsortedstrr   r   nanpercentiler   get_cmapcopyset_bad	set_titleaxistight_layoutsavefigget_facecolorclosename)r8   r=   r9   statesave_dir
size_labelr:   
layer_namefigrP   state_outlinerK   unique_vals	cmap_namevr\   r]   cmap_objout_paths                      r   plot_attribute_heatmapr   I   s    ll8,GC IIG$W MMO,,M##%&eDOO,=+>bBzlZ[\##%&eDOO,=+>bAN	TF-
|=I^W^H__c
den++-446{aII 			"+# +!>+Q#a&+!>?	 !" 	 	
( 	b3? PT~OdOdOfOlOlR%%dn&;&;&=2wGrx
d%%i0557w' 			"&#dC " 	 	
  	b3?LLL,GGENG1TF)J<tDDHKKcw#BSBSBUVIIcN	 
01W "?s   ,J+__main__z3Generate grid-based attribute heatmaps for a state.)descriptionr   zState name (e.g., alabama).)help	cell_size?z.Grid cell size in meters. Defaults to env var z
 if unset.)nargsr   u   ❌ rH   i  kmOSM_State_Filesz_roads_projected.gpkg_grid_z.gpkgu   ❌ Roads file not found: u   ❌ Grid file not found: u$   📦 Loading road and grid data for z...roads_projected)layergrid_)laneswidthheightzbuilding:levels)surfacematerialbridgetunnelr   highwaybuildingu   📊 Road numeric attributes: u"   🎨 Road categorical attributes: )r:   r7   )r:   r   Tz_buildings_projected.gpkgbuildings_projectedu   📦 Loaded buildings data: u'   ⚠️ Failed to load buildings layer: u"   📊 Building numeric attributes: u&   🎨 Building categorical attributes: 	buildingsu>   
✅ All grid-based attribute heatmaps generated successfully!)F)FN)<__doc__argparser   syspathlibr   	geopandasr-   pandasr3   matplotlib.pyplotpyplotrg   numpyr   
matplotlibr   r
   r   r>   r   __name__ArgumentParserparseradd_argument
parse_argsargsr   lowerr   r   errr,   exitr   gdf_path	grid_pathparentr   existsrm   	read_filer7   r8   numeric_attrscategorical_attrsr$   available_numericavailable_categoricalr9   rv   grid_aggr=   r   buildings_pathr~   	Exceptioneb_available_numericb_available_categorical)as   0r   <module>r      s    	 
       + $@ VZR2p z$$IF &CD
%%6$7zC   DJJE%dnn5	 tO$B'J%&.E7:O1PPH&'%/UG6*U2SSIH??*8*56))56	01A1A1C0DC
HIMM(*;<E==E**>?D
 DMc %2HMq%--5GMH(9P(91%--=OQ(9P	*+<*=
>?	./D.E
FG!1%dX]^(x4*bgt{| " &1%dX\](x4*bfsz{ & I+,u4%@Y7ZZN	An<QRI01D1D0EFG *7R-Q	@Q@Q;Qq-R.?"Z.?	HYHYCY1.?"Z23F2GHI67N6OPQ'D!5id`e!fHh"8XtUHjfk  yD  E ( ,D!5id`d!eHh"8XtUHjfj  xC  D , 

KLk    SEl8 IP,  	A;A3?@@	A S"Zs`   $M2 N#5N#N(N(&N- .OOO)O2N 8NN -O	3OO	