
    .i#                        d Z ddlZddlZddlZddlmZ ddlZddlZ	ddl
mZ ddlZddlmZ dZd Zd4dZ	 d5d	Zed
k(  r+ ej,                  d      Zej1                  dd       ej1                  ddde d       ej3                         Zej6                  j9                         Z	  eej:                        Zedz   dZ" ed      ez  e dz  Z# ed      ez  e de" dz  Z$e#jJ                  Z&e#jO                         s e de#         ejB                  d       e$jO                         s e de$         ejB                  d        e dejQ                          d         ejR                  e#d!"      Z* ejR                  e$d#e" "      Z+g d$Z,g d%Z-e,D  cg c]  } | e*j\                  v s|  c} Z/e-D  cg c]  } | e*j\                  v s|  c} Z0 e d&e/         e d'e0        e/D ]/  Z1 ee*e+je                         e1d(      \  Z3Z4 ee3e4e1ee&e"dd)*       1 e0D ]/  Z1 ee*e+je                         e1d+(      \  Z3Z4 ee3e4e1ee&e"d+d)*       1 dZ5 ed      ez  e d,z  Z6e6jO                         r*	  ejR                  e6d-"      Z5 e d.e6jn                          e5e,D  cg c]  } | e5j\                  v s|  c} Z:e-D  cg c]  } | e5j\                  v s|  c} Z; e d0e:         e d1e;        e:D ]/  Z1 ee5e+je                         e1d(      \  Z3Z4 ee3e4e1ee&e"dd2*       1 e;D ]/  Z1 ee5e+je                         e1d+(      \  Z3Z4 ee3e4e1ee&e"d+d2*       1  e d3       yy# e$ r(Z e de         ejB                  d       Y dZ[dZ[ww xY wc c} w c c} w # e8$ rZ9 e d/e9        Y dZ9[9dZ9[9ww xY wc c} w c c} w )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                     | xs t        j                  t              }|t        dt         d      	 t	        |      S # t        $ r}t        d| dt         d      |d}~ww xY w)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$Fc                     t        d| d       t        j                  | |dd      }|rRd }|j                  d      |   j	                  |      j                         }|j                  || did	
       | d}njt        j                  ||   d      ||<   |j                  d      |   j                         j                         }|j                  || did	
       | d}|j                  |d	dd      }||fS )z'Aggregate road attribute per grid cell.u   📊 Aggregating z per grid cell...inner
intersects)how	predicatec                 x    | j                         }|j                  s|j                  d   S t        j                  S )Nr   )modeemptyilocnpnan)xmode_seriess     r   	mode_funcz'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 YYud<HF	L ../599)DPPRen5tDV5> }}VD\(Ct../5::<HHJen5tDV5> ::g$F:SD>r    c                 ^   t        j                  d      \  }}	|j                  j                  d       |	j                  d       | j	                         j
                  }
|r+|j                          d|j                          d| d| d}n'|j                          d|j                          d| d}t        d| d	| d
|xs d d       |r| |   j                         j                         }t        |      dkD  rd}nd}| j                  ||	dd|ddd|t        |D cg c]  }t        |       c}      dddd       |
j                  |	dd       n| |   j                         j                  s)t        j                   | |   j                         ddg      nd\  }}t#        j$                  d      j'                         }|j)                  d       | j                  ||d|	d|||d d!d"ddd#	       |
j                  |	dd       |	j+                  |d$d%&       |	j-                  d'       t        j.                          || d(| d)| d*z  }t        j0                  |d+d,|j3                         -       t        j4                  |       t        d.|j6                          y c c}w )/N)   
   )figsizewhiteu    — z (z, )u   
🔎 Plotting z heatmap for z grid (layer=r6   z)...   tab20Set2Tr   )gRQ?   z
upper left)bbox_to_anchorloctitlelabelszNo Data)colorlabel)columnaxlegendr9   cmap	linewidthlegend_kwdsmissing_kwdsblackg      ?)rO   rL   rR      _   )r   rG   inferno)rL   g333333?g{Gz?)rM   shrinkpad)	rN   rQ   rR   rO   rP   vminvmaxrS   rT      r@   )fontsizerZ   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)r7   r<   r8   statesave_dir
size_labelr9   
layer_namefigrO   state_outlinerJ   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8n++-446{aII 			"+# +!>+Q#a&+!>?	 !" 	 	
( 	b3? PTT\~OdOdOfOlOlR%%d8n&;&;&=2wGrx
d%%i0557w' 			"&#dC " 	 	
  	b3?LLL,GGENUG1TF)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   ❌ rG   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: )r9   r6   )r9   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,   pandasr2   matplotlib.pyplotpyplotrf   numpyr   
matplotlibr   r
   r   r=   r   __name__ArgumentParserparseradd_argument
parse_argsargsr~   lowerr   r   errr+   exitr   gdf_path	grid_pathparentr   existsrl   	read_filer6   r7   numeric_attrscategorical_attrsr#   available_numericavailable_categoricalr8   ru   grid_aggr<   r   buildings_pathr}   	Exceptioneb_available_numericb_available_categorical)as   0r   <module>r      s    	 
       + $@ VZR2p z$X$$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CMM(*;<E3==E**>?D
 DMc %2HMqQ%--5GMH(9P(91Q%--=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-Q1	@Q@Q;Qq-R.?"Z.?1	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`   *M-  N4N?N"N"<)N' +O?O
O
O
-N2NN'O,N==O