o
    +zh                     @   s   d Z ddlZddlZddlmZ ddlmZmZ ddlm	Z	 dd Z
dd	 Zd
d Zdd Zd ddZdd Zdd Zdd Zdd Zd ddZd ddZdd Zdd ZdS )!u   
교량 상태평가용 데이터 처리 모듈 (개선된 1방향/2방향 균열 분류)
부재명, 부재위치, 손상내용, 균열폭, 손상물량 데이터를 상태평가용으로 피벗
    N)defaultdict)normalize_componentsort_components)trim_dataframe_str_columnsc           
   
   C   s   t | } zG| d |k| d |k@ | d |k@ }| | }|jsEdD ]$}|| jv rDtj|| dd }|jsD| dkrDt|   W S q t|}|W S  t	yh }	 zt
d|	  t|W  Y d	}	~	S d	}	~	ww )
uQ   업로드한 파일의 균열폭 열에서 데이터를 추출 (개선된 버전)	   부재명   부재위치   손상내용u	   균열폭u   균열폭
(㎜)zCrack Widthu
   균열 폭coerceerrorsr   u   균열폭 추출 중 오류: N)r   emptycolumnspd
to_numericdropnamaxfloat$extract_crack_width_from_description	Exceptionprint)
dfcomponent_namepositiondamage_descmaskmatched_datacolcrack_widths
desc_widthe r!   I/home/skpark/git/infrasmart_work/infrasmart/utils/condition_evaluation.py&extract_crack_width_from_uploaded_data   s,   



r#   c                 C   s   d| vrdS d| v sd| v rdS d| v sd| v rdS d	| v s"d
| v r$dS g d}|D ]}t || }|rIt|d}d| v rE|d   S |  S q*d| v rPdS dS )u6   손상내용에서 균열폭 추출 (개선된 방식)   균열Nu   0.3㎜미만u   0.3mm미만皙?u   0.3㎜이상u   0.3mm이상333333?u   0.5㎜이상u   0.5mm이상      ?)u   (\d+(?:\.\d+)?)\s*(?:mm|㎜)u$   균열\((\d+(?:\.\d+)?)(?:mm|㎜)?\)u   폭[=:]\s*(\d+(?:\.\d+)?)u"   (\d+(?:\.\d+)?)(?:mm|㎜)\s*이상u"   (\d+(?:\.\d+)?)(?:mm|㎜)\s*미만   u   미만      망상균열皙?)researchr   group)r   patternspatternmatchwidthr!   r!   r"   r   +   s(   r   c                 C   s  zd|v r| d j jddd}n7d|v r6| d j jddd| d j jdddB | d j jdddB }nd|v rF| d j jddd}nd	|v r_| d j jd	dd| d j jd
ddB }nd|v sgd|v r|| d j jddd| d j jdddB }nd|v sd|v r| d j jddd| d j jdddB | d j jdddB }nd|v sd|v rC| d j jddd| d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB }n| d |k}|dkrl|| d  |k@ | d! j jd"dd@ | d! j jd#dd @ }n|| d  |k@ | d! j jd#dd@ }| | }|jstj|d$ d%d& }d|v sd|v r|dkr|}| D ]U\}	}
|
d! }d'|
v r|
d'd( nd(}d"|v r|d)krd#|vrtj|
d$ d%d&}t	|r|d*kr|| |d+  }t
d,| d-| d.| d/|d+   q|}d|v rt
d0| d1| d2| d3|d    nd|v r2t
d4| d1| d2| d3|d    nd|v rLt
d5| d1| d2| d3|d    n{d	|v rft
d6| d1| d2| d3|d    nad|v spd|v rt
d7| d1| d2| d3|d    nBd|v sd|v rt
d8| d1| d2| d3|d    n#d|v sd|v sd|v rt
d9| d1| d2| d3|d    t	|rt|W S d*W S W d*S  ty } zt
d:|  W Y d;}~d*S d;}~ww )<u;   해당 경간의 균열율 계산 (모든 균열의 합계)   거더r   Fna	   가로보	   세로보   격벽   기초   신축이음   이음장치   교면포장   포장   배수시설	   배수구	   배수관   난간   연석   방호울타리	   방호벽	   방음벽	   방음판   방음   방호	   중분대   중앙분리대   가드레일   낙석   차광	   경계석   투석방지망   1방향r   r   r$   r*      손상물량r
   r   u   단위 mr   g      ?u)   교면포장 1방향 균열 0.25 적용: u
   , 단위: u   , 원래값: u   , 조정값: u"   거더 균열율 계산 - 위치: u
   , 방향: u   , 물량합계: u   , 포함된 부재: u%   가로보 균열율 계산 - 위치: u"   기초 균열율 계산 - 위치: u(   신축이음 균열율 계산 - 위치: u(   교면포장 균열율 계산 - 위치: u(   배수시설 균열율 계산 - 위치: u(   난간연석 균열율 계산 - 위치: u   균열율 계산 중 오류: N)strcontainsr   r   r   sumiterrowsgetlowernotnullr   uniquer   r   )r   r   r   crack_directioncomponent_maskr   r   total_quantityadjusted_quantity_rowr   unitrow_quantityr    r!   r!   r"   calculate_crack_ratio_for_spanQ   s   	






$
*
*
*
***(rd   c              
   C   s  zd|v r| d j jddd}n;d|v r6| d j jddd| d j jdddB | d j jdddB }nd|v rF| d j jddd}nd	|v r_| d j jd	dd| d j jd
ddB }nd|v sgd|v r|| d j jddd| d j jdddB }nd|v sd|v r| d j jddd| d j jdddB | d j jdddB }nd|v sd|v sd|v rG| d j jddd| d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB }n| d |k}|dkrp|| d  |k@ | d! j jd"dd@ | d! j jd#dd @ }n|| d  |k@ | d! j jd#dd@ }| | }|jrW d$S |d%krtj|d& d'd( }t|s|d$krW d)S d$}d}	| D ]\}
}d|v r| d j jddd| d  |k@ | d! |d! k@ }nd|v r
| d j jddd| d j jdddB | d j jdddB | d  |k@ | d! |d! k@ }nPd	|v r3| d j jd	dd| d j jd
ddB | d  |k@ | d! |d! k@ }n'd|v s=d|v r`| d j jddd| d j jdddB | d  |k@ | d! |d! k@ }nd|v sjd|v r| d j jddd| d j jdddB | d j jdddB | d  |k@ | d! |d! k@ }nd|v sd|v rF| d j jddd| d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d  |k@ | d! |d! k@ }n| d |k| d  |k@ | d! |d! k@ }| | }d}|jsd*D ]0}|| jv rtj|| d'd(	 }|js|
 d$krt|
 }t
||}d+}	d+} nqf|st|d! }|d)ur|d$krt
||}q|d%krtj|d& d'd( }t|r|d$kr|	s|d$krW d,S |d$kr|W S d)W S W d)S |W S  ty } ztd-|  W Y d)}~d$S d)}~ww ).u(   해당 경간의 최대 균열폭 계산r3   r   Fr4   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   r   r   r$   r*   r      2방향rQ   r
   r   Nr	   Tr%   u$   최대 균열폭 계산 중 오류: )rT   rU   r   r   r   rV   isnarW   r   r   r   r   r   notnar   r   )r   r   r   r\   r]   r   r   r^   	max_widthhas_explicit_crack_widthr`   ra   mask_rowmatched_row_datafound_in_columnr   r   r2   r    r!   r!   r"   get_max_crack_width_for_span   s~  	












	






rm   c                    s    dv rt}|durd|t|dS ddddS tfdddD r2dvr2d	d
dS  rd v s@d v s@d v rg d}tfdddD rTdddS tfdddD rddd
dS tfdddD rtdddS tfdddD rdddS dddS  rd v sd v sd  v sd! v sd" v sd# v sd$ v rg d%}tfd&d|D rdv rd'ddS d(ddS g d)}tfd*d|D rdv rd+ddS d,ddS dv rd'ddS d(ddS  r:d- v sd. v r:g d/}tfd0d|D rd1ddS tfd2dd3D r+dv r&d4ddS d5ddS dv r5d4ddS d1ddS  rGd6 v rGd7ddS  rfd8 v sTd9 v rftfd:dd;D red<ddS ntfd=dd;D rwd>ddS  rt fd?dd@D rtfdAddBD rdCddS dDv rdEvrdDddS tfdFddGD rdHddS tfdIddJD sd<ddS tfdKddLD rdCddS tfdMddND rdEvrdDddS d<ddS )Ou   상태평가용 손상 분류 (교대, 교각의 경우 누수를 표면손상에 포함, 기초의 경우 균열 외 단면손상으로 분류, 신축이음의 경우 본체/후타재 분류, 교량받침의 경우 본체/콘크리트 분류, 배수시설의 경우 모든 손상 포함)r$   N)typecrack_widthseverityunknownc                 3       | ]}| v V  qd S Nr!   .0keywordr   r!   r"   	<genexpr>      z1classify_damage_for_evaluation.<locals>.<genexpr>)   철근부식   철근노출u   잡철근노출rz   high)rn   rp   r>   r?   r@   )   막힘   토사퇴적   퇴적   탈락   파손r$      부식   누수	   이물질u   청소불량   적치   길이부족   설치불량   망실	   미설치c                 3   rr   rs   r!   rt   rw   r!   r"   rx     ry   )r}   r~   r   r   u   배수구막힘mediumc                 3   rr   rs   r!   rt   rw   r!   r"   rx     ry   )r   r   r   r   u   배수구파손c                 3   rr   rs   r!   rt   rw   r!   r"   rx     ry   )r   u   새어나옴u   배수구누수c                 3   rr   rs   r!   rt   rw   r!   r"   rx     ry   )r   r   u   배수관설치불량u   배수시설기타손상   받침   교량받침   받침장치   탄성받침   고무받침   강재받침	   베어링)
r   u   도장박리u   도장탈락   도장   본체u   편기	   고무재   볼트   앵커   너트c                 3   rr   rs   r!   rt   rw   r!   r"   rx     ry   u   본체_균열u   본체_단면손상)   콘크리트   모르타르u	   모르타u   받침콘크리트u   받침모르타르c                 3   rr   rs   r!   rt   rw   r!   r"   rx     ry   u   콘크리트_균열u   콘크리트_단면손상r:   r;   )r   r   r   u   유간r   r~   r   r:   r;   r   r   u   노화c                 3   rr   rs   r!   rt   rw   r!   r"   rx     ry   u   본체_손상c                 3   rr   rs   r!   rt   rw   r!   r"   rx     ry   )u   후타r   r   u   고정r   r   u   후타재_균열u   후타재_단면손상r9   u   단면손상   교대   교각c                 3   rr   rs   r!   rt   rw   r!   r"   rx     ry   )r   u   백태u   침출   표면손상c                 3   rr   rs   r!   rt   rw   r!   r"   rx     ry   r   c                 3   rr   rs   r!   ru   compr   r!   r"   rx     ry   )
rA   rB   rH   rG   rK   rL   rM   rI   rJ   rO   c                 3   rr   rs   r!   rt   rw   r!   r"   rx     ry   )r   rG   rA   rL   u   도장손상r   u   철근c                 3   rr   rs   r!   rt   rw   r!   r"   rx     ry   )r   r   r   u   지주u   연결재손상c                 3   rr   rs   r!   rt   rw   r!   r"   rx     ry   )r$   r{   rz   c                 3   rr   rs   r!   rt   rw   r!   r"   rx     ry   )r   u	   페인트u	   페이트c                 3   rr   rs   r!   rt   rw   r!   r"   rx     ry   )r   u   녹)stripr   get_crack_severityany)r   r   ro   drainage_keywordsbody_keywordsconcrete_keywordsr!   )r   r   r"   classify_damage_for_evaluations  s   





<




















"

r   c                 C   s@   | du rdS | dkrdS | dkrdS | dkrdS | d	krd
S dS )u$   균열폭에 따른 심각도 분류Nrq         ?very_severer'   severer&   moderater+   minor
very_minorr!   )ro   r!   r!   r"   r     s   r   c           
      C   s  d}d}d}d}d}| D ]<}|d dkr.| dd}| dd}|r't||}|r-||7 }q|d dkr7d}q|d d	kr@d}q|d d
krHd}qd}	|dkrRd}	n|dkr\t|	d}	n|dkrft|	d}	n	|dkrot|	d}	|rvt|	d}	|r}t|	d}	|rt|	d}	|	S )u^   손상 데이터를 기반으로 상태등급 계산 (개선된 1방향/2방향 균열 지원)r   Frn   r$   ro   crack_ratior   Trz   r   Ar   Er'   Dr&   Cr+   B)rX   r   )
damage_datamax_crack_widthtotal_crack_ratiohas_surface_damagehas_rebar_corrosionhas_leakagedamagero   r   grader!   r!   r"   calculate_condition_grade  sJ   




r   c                 C   s  | d j jddd| d j jdddB }|dkr'| | d j jddd| @  S |dkr:| | d j jddd| @  S |d	krc| d j jd	dd| d j jd
ddB | d j jdddB }| || @  S |dkrv| | d j jddd| @  S |dkr| | d j jddd| @  S |dkr| d j jddd| d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB | d j jdddB }t| ||B   | ||B  S |dkr| | d j jddd| @  S |dkr| d j jddd| d j jdddB }| || @  S |dkr4| d j jddd| d j jdddB }| || @  S |dkr^| d j jddd| d j jdddB | d j jdddB }| || @  S |dkr | d j jddd| d j jdddB | d j jdddB | d j jdddB | d j jd ddB | d j jd!ddB | d j jd"ddB | d j jd#ddB | d j jd$ddB | d j jd%ddB | d j jd&ddB | d j jd'ddB | d j jd(ddB | d j jd)ddB | d j jd*ddB }| || @  S | S )+u}   부재 유형별로 데이터 필터링 (손상내용명에 '받침' 또는 '전단키' 포함 시 교량받침으로 분류)r   r   Fr4   u	   전단키	   바닥판r   r3   r6   r7   r8   r   r   r   r   r   r   r   r   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   )rT   rU   r   )r   component_filterbearing_damage_mask
basic_maskbasic_bearing_maskr!   r!   r"   filter_data_by_component_type8  s   



	
r   c                    s   g d}d v r| | d j jdddd S d v s1d v s1d	 v s1d
 v s1d v s1d v s1d v r>| | d j jdddd S d v sFd v rS| | d j jdddd S t fdd|D }|rm| | d j jdddd S | | d j jdddd S )u7   부재명에 따라 적절한 부재위치만 필터링)r   r3   r6   r7   r8   r<   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   rI   rJ   rK   rL   rM   rN   rO   r9   r   z^[ap]\d*F)caser5   r   r   r   r   r   r   r   r:   r;   c                 3   rr   rs   r!   r   r   r!   r"   rx     ry   z0filter_positions_by_component.<locals>.<genexpr>z^s\d+)rT   r1   r   )r   r   span_componentsis_span_componentr!   r   r"   filter_positions_by_component  s   8r   c                 C   s  |   } | d t| d< tj| d ddd| d< |r"t| |} t| d  }i }|D ]}| | d |k }t	||}t
|d  }i ddddddd	d
||< g }|D ]}d|v rw| d jjddd| d |k@ }	| |	 }
| }nod|v r| d jjddd| d jjdddB | d jjdddB | d |k@ }| | }
| }n?d|v r| d jjddd| d jjdddB | d |k@ }| | }
| }nd|v sd|v r| d jjddd| d jjdddB | d |k@ }| | }
| }nd|v sd|v r*| d jjddd| d jjdddB | d jjdddB | d |k@ }| | }
| }nd|v s9d|v s9d|v r| d jjddd| d jjdddB | d jjdddB | d jjdddB | d jjdddB | d jjdddB | d jjdddB | d jjdddB | d jjd ddB | d jjd!ddB | d jjd"ddB | d jjd#ddB | d jjd$ddB | d jjd%ddB | d jjd&ddB | d |k@ }| | }
| }n
||d |k }
|}t|||d'}t|||d'}t|||d(}t|||d(}g ||||i dd)}|
 D ]H\}}t|d* |}|d |d+< |d* |d,< |d- d.krW|d/ | || |d- }||d0 vrKd|d0 |< |d0 |  |d+ 7  < q|dksc|dkrd.||d'|d1| d2|d3d4d5}|d/ | || |dur|dks|dkr|dur|nd}d.||d(||durd6| d2|d3d4nd7|d3d4d5}|d/ | || t|d/ |d8< ||| d9 |< t|| d: d; ||| d: d;< |dur|| d: d< }|du r||| d: d<< nt|||| d: d<< t|| d: d= ||| d: d=< t|| d: d> ||| d: d>< qXt||| d: d8< t||| d: d?< q.|S )@uX   상태평가용 피벗 테이블 생성 (개선된 1방향/2방향 균열 분류 적용)r   rQ   r
   r   r   r   Nr   )max_crack_width_1dmax_crack_width_2dcrack_ratio_1dcrack_ratio_2dtotal_damage_countcondition_grade)	positionssummaryr3   Fr4   r6   r7   r8   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   re   )damagescrack_width_1dcrack_width_2dr   r   damage_quantitiesr   r   quantityoriginal_descrn   r$   r   r   u   1방향 균열 (최대폭: u   mm, 균열율: .2f))rn   ro   r   	directionr   r   u   2방향 균열 (최대폭: u   2방향 균열 (균열율: r   r   r   r   r   r   r   r   )copyastyperT   r   r   fillnar   r   r[   r   sortedrU   rm   rd   rW   r   appendr   r   len)r   r   
componentsevaluation_data	componentcomponent_dfr   all_damagesr   all_girder_maskpos_dffull_dfall_crossbeam_maskall_expansion_maskall_pavement_maskall_drainage_maskall_railing_maskr   r   r   r   position_datar`   ra   damage_infodamage_typecrack_info_1dcrack_width_displaycrack_info_2d
current_2dr!   r!   r"   #generate_condition_evaluation_pivot  sJ  




 



	



*


r   c              	   C   s  d}|r|d| d7 }n|d7 }|d7 }|d7 }|d7 }|d7 }|d	7 }|d
7 }|   D ]\}}|d }|dd}|du rAd}|dkrGdn|d}|dd}|du sY|dkr\d}	n|d}	|dd}
|
du rld}
|
dkrrdn|
d}|dd}|du rd}|dkrdn|d}|dd}|du rd}|dkrdnt|}|dd}|du rd}|d7 }|d| d7 }|d| d7 }|d| d7 }|d|	 d7 }|d| d7 }|d| d7 }|d|  d7 }|d7 }q-|d7 }|   D ]\}}|d| d 7 }|d7 }|d!7 }|d7 }|d"7 }|d
7 }|d#   D ]\}}t|d$ D ]\}}|dkrHt|d$ }|d7 }|d%| d&| d7 }n|d7 }|d'}|du s[|dkr^d}n|d}|d(d)}|du rod)}|d* d+kr|d,d}|dkr|dnd}n|d-d}|du rd}|dkrdn|d}|d| d7 }|d| d7 }|d| d7 }|dkr|dd}|du rd}|d%| d&|  d7 }|d7 }q)q|d7 }q|d.7 }|d/7 }|S )0uY   상태평가 결과를 HTML 테이블로 생성 (개선된 1방향/2방향 균열 표시)z,<div class="condition-evaluation-container">z<h3>u    상태평가 결과</h3>u#   <h3>전체 상태평가 결과</h3>u&   <h4>부재별 상태평가 요약</h4>z<div class="table-container">z#<table class="table table-striped">z<thead><tr>u   <th>부재명</th><th>1방향 최대균열폭(mm)</th><th>1방향 균열율</th><th>2방향 최대균열폭(mm)</th><th>2방향 균열율</th><th>손상 개소</th><th>상태등급</th>z</tr></thead><tbody>r   r   r   N-z.1fr   r   r   r   r   r   r   z<tr>z<td><strong>z</strong></td>z<td>z</td>z</tr>z</tbody></table></div>z<h5 class="mt-4">u    상세 평가</h5>z<table class="table table-sm">ut   <th>부재위치</th><th>손상내용</th><th>균열폭(mm)</th><th>균열율/손상물량</th><th>상태등급</th>r   r   z<td rowspan="z">ro   r   rR   rn   r$   r   r   </div>a  
    <style>
        .condition-evaluation-container {
            margin: 20px 0;
        }
        .badge {
            padding: 5px 10px;
            border-radius: 3px;
            font-weight: bold;
            color: white;
        }
        .grade-a { background-color: #28a745; }
        .grade-b { background-color: #17a2b8; }
        .grade-c { background-color: #ffc107; color: #212529; }
        .grade-d { background-color: #fd7e14; }
        .grade-e { background-color: #dc3545; }
    </style>
    )itemsrX   rT   rY   	enumerater   )r   r   htmlr   datar   r   max_crack_width_1d_strr   max_crack_width_2d_strr   crack_ratio_1d_strr   crack_ratio_2d_strr   total_damage_count_strr   r   pos_datair   rowspanro   crack_width_strr   r   quantity_strr   r!   r!   r"   "generate_condition_evaluation_htmlg  s   







*r  c                 C   s    t | } t| |}t||}|S )u%   부재별 상태평가표 HTML 생성)r   r   r  )r   component_typer   r   r!   r!   r"   +generate_component_specific_evaluation_html  s   

r  c                 C   sb   t | } 	 g d}d}|D ]}t| |}|js*|d7 }|t| |7 }|d7 }|d7 }q|d7 }|S )N)r   r3   r6   r   r   r   r9   r:   r<   r>   rA   z'<div class="all-component-evaluations">z*<div class="component-evaluation-section">r   z<hr style="margin: 30px 0;">)r   r   r   r  )r   component_typesall_htmlr  filtered_dfr!   r!   r"   "generate_all_component_evaluations  s   
r  rs   )__doc__pandasr   r,   collectionsr   utils.commonr   r   r   r#   r   rd   rm   r   r   r   r   r   r   r  r  r  r!   r!   r!   r"   <module>   s,    &p 
3~7M
 
G 