Spaces:
Sleeping
Sleeping
Update pilecaps_adr.py
Browse files- pilecaps_adr.py +68 -630
pilecaps_adr.py
CHANGED
|
@@ -24,6 +24,7 @@ import Dropbox_TSA_API
|
|
| 24 |
import tsadropboxretrieval
|
| 25 |
from collections import Counter
|
| 26 |
from unidecode import unidecode
|
|
|
|
| 27 |
|
| 28 |
def textLists(img,dataDoc):
|
| 29 |
allTexts = texts_from_pdf(dataDoc)
|
|
@@ -197,7 +198,7 @@ def ConnectBeamLines(smalldashesOut, maxLineGap=0):
|
|
| 197 |
thresh=20
|
| 198 |
point=0.2
|
| 199 |
maxLineGap=40
|
| 200 |
-
|
| 201 |
green1=cv2.bitwise_not(smalldashesOut)
|
| 202 |
smalldashesOut=cv2.cvtColor(smalldashesOut,cv2.COLOR_GRAY2BGR)
|
| 203 |
imgLines= cv2.HoughLinesP(green1,point,np.pi/180,thresh,minLineLength=25,maxLineGap =maxLineGap) #try 180
|
|
@@ -232,19 +233,19 @@ def allpreSteps(imgOriginal,num=0):
|
|
| 232 |
return green2
|
| 233 |
else:
|
| 234 |
#imgDark with no dashed lines or small dashes
|
| 235 |
-
|
| 236 |
imgDark1=getImgDark(noCircles)
|
| 237 |
-
|
| 238 |
img4,imgBW,max,min=DashedPreprocessing(imgOriginal,noCircles)
|
| 239 |
imgDarkNoDashedLines=removeDashedLines(img4,imgDark1,max,min) #do preprocessing on normal img , and draw on darkimg
|
| 240 |
imgBW0 = cv2.cvtColor(imgBW, cv2.COLOR_BGR2GRAY)
|
| 241 |
imgDarkNoDashedLines = cv2.cvtColor(imgDarkNoDashedLines, cv2.COLOR_GRAY2BGR)
|
| 242 |
imgDarkNoDashedLines,smalldashesOut0=removeSmallDashes(imgDarkNoDashedLines,imgBW0)
|
| 243 |
-
|
| 244 |
#imgOld no small dashes - for oring purposes
|
| 245 |
imgoldG = cv2.cvtColor(imgold, cv2.COLOR_GRAY2BGR)
|
| 246 |
imgoldnoDashes,_=removeSmallDashes(cv2.bitwise_not(imgoldG),imgBW0,1)
|
| 247 |
-
|
| 248 |
#to connect leader lines after removing dashed lines and circles
|
| 249 |
Nodashedlines=removeDashedLines(img4,imgBW,max,min)
|
| 250 |
imgCopy,smalldashesOut=removeSmallDashes(imgOriginal,Nodashedlines)
|
|
@@ -259,7 +260,7 @@ def allpreSteps(imgOriginal,num=0):
|
|
| 259 |
green2=cv2.medianBlur(green2,5)
|
| 260 |
# cv2_imshow(green2)
|
| 261 |
imgoldnoDashes=cv2.medianBlur(imgoldnoDashes,5)
|
| 262 |
-
|
| 263 |
return green2 , cv2.bitwise_not(imgoldnoDashes)
|
| 264 |
|
| 265 |
|
|
@@ -469,49 +470,49 @@ def preprocess(green22,imgoldnodashes,dataDoc,imgtransparent1,img,number,green2,
|
|
| 469 |
BlackmaskA=cv2.erode(BlackmaskA,kernel, iterations=1)
|
| 470 |
contoursA, hier1 = cv2.findContours(BlackmaskA, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
|
| 471 |
finalcntsA.append(contoursA)
|
| 472 |
-
|
| 473 |
-
|
| 474 |
-
|
| 475 |
-
|
| 476 |
-
|
| 477 |
-
|
| 478 |
-
|
| 479 |
-
|
| 480 |
-
|
| 481 |
-
|
| 482 |
-
|
| 483 |
-
|
| 484 |
-
|
| 485 |
-
|
| 486 |
-
|
| 487 |
-
|
| 488 |
-
cntsx,hierx= cv2.findContours(xx, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
|
| 489 |
-
if len(cntsx)>0:
|
| 490 |
-
hierx=hierx[0]
|
| 491 |
-
xx=cv2.bitwise_and(outlinesDotIN,outlinesDotIN,mask=xx)
|
| 492 |
cntsx,hierx= cv2.findContours(xx, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
|
| 493 |
if len(cntsx)>0:
|
| 494 |
-
|
|
|
|
| 495 |
cntsx,hierx= cv2.findContours(xx, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
|
| 496 |
if len(cntsx)>0:
|
| 497 |
-
|
| 498 |
-
|
| 499 |
-
|
| 500 |
-
|
| 501 |
-
|
| 502 |
-
|
| 503 |
-
|
| 504 |
-
|
| 505 |
-
|
| 506 |
-
|
| 507 |
-
perimeter
|
| 508 |
-
|
| 509 |
-
|
| 510 |
-
|
| 511 |
-
|
| 512 |
-
|
| 513 |
-
|
| 514 |
-
openClosedFlag
|
|
|
|
|
|
|
|
|
|
| 515 |
|
| 516 |
return tuple(finalcntsP),tuple(finalcntsA), perimeters , shapetxts , imgtransparent1 ,ArrthreshCnt , texts, iddk
|
| 517 |
|
|
@@ -625,9 +626,9 @@ def allLevelsofColor(BlackmaskDetected,img,levelonly, invertedmask,color,finalCo
|
|
| 625 |
for othercolor in finalColorArray:
|
| 626 |
# othercolor2=hexRGB(othercolor)
|
| 627 |
othercolor2=[othercolor[0],othercolor[1],othercolor[2]]
|
| 628 |
-
|
| 629 |
if othercolor2!=color:
|
| 630 |
-
|
| 631 |
masked0=DetectColor(firstLevel,othercolor)[0]
|
| 632 |
pil_image0=Image.fromarray(masked0)
|
| 633 |
extrema0 = pil_image0.convert("L").getextrema()
|
|
@@ -873,7 +874,8 @@ def drawAllContours(dataDoc,img,number,finalColorArray,ratioarea,ratioperim , pa
|
|
| 873 |
if passed ==0:
|
| 874 |
if SimilarAreaDictionary['Color'].loc[i] == [rgbcolor[0],rgbcolor[1],rgbcolor[2]] and ( SimilarAreaDictionary['Rounded'].loc[i] <= areaPerimeterMax and SimilarAreaDictionary['Rounded'].loc[i] >= areaPerimeterMin) :
|
| 875 |
if (SimilarAreaDictionary['Width'].loc[i] <=widthMax and SimilarAreaDictionary['Width'].loc[i] >= widthMin) and (SimilarAreaDictionary['Height'].loc[i] <= heightMax and SimilarAreaDictionary['Height'].loc[i] >= heightMin ) or (SimilarAreaDictionary['Width'].loc[i] <=heightMax and SimilarAreaDictionary['Width'].loc[i] >= heightMin) and (SimilarAreaDictionary['Height'].loc[i] <= widthMax and SimilarAreaDictionary['Height'].loc[i] >= widthMin ) :
|
| 876 |
-
|
|
|
|
| 877 |
for t in texts:
|
| 878 |
if "GB" not in t or "RC" not in t or "PC" not in t:
|
| 879 |
if t not in SimilarAreaDictionary['Texts'].loc[i]:
|
|
@@ -900,7 +902,8 @@ def drawAllContours(dataDoc,img,number,finalColorArray,ratioarea,ratioperim , pa
|
|
| 900 |
annot11 = page.add_polyline_annot( points=shapee) # 'Polygon'
|
| 901 |
annot11.set_border(width=0.2, dashes=[3])
|
| 902 |
annot1.set_colors(stroke=color ,fill=None)
|
| 903 |
-
|
|
|
|
| 904 |
# annot.set_line_ends(fitz.PDF_ANNOT_LE_DIAMOND, fitz.PDF_ANNOT_LE_CIRCLE)
|
| 905 |
annot11.update()
|
| 906 |
pFlagDF=1
|
|
@@ -908,8 +911,8 @@ def drawAllContours(dataDoc,img,number,finalColorArray,ratioarea,ratioperim , pa
|
|
| 908 |
annot1 = page.add_polyline_annot( points=shape) # 'Polygon'
|
| 909 |
annot1.set_border(width=0.2 ,dashes=[3])
|
| 910 |
annot1.set_colors(stroke=color , fill=None)
|
| 911 |
-
|
| 912 |
-
|
| 913 |
SimilarAreaDictionary['Total Perimeter'].loc[i]+=perimeterr
|
| 914 |
SimilarAreaDictionary['Perimeter'].loc[i]=perimeterr
|
| 915 |
SimilarAreaDictionary['Total Length'].loc[i]+=lengthShape
|
|
@@ -921,7 +924,8 @@ def drawAllContours(dataDoc,img,number,finalColorArray,ratioarea,ratioperim , pa
|
|
| 921 |
annot.set_border(width=0.2)
|
| 922 |
annot.set_colors(stroke=color, fill= color )
|
| 923 |
annot.set_opacity(0.5)
|
| 924 |
-
|
|
|
|
| 925 |
# annot.set_line_ends(fitz.PDF_ANNOT_LE_DIAMOND, fitz.PDF_ANNOT_LE_CIRCLE)
|
| 926 |
annot.update()
|
| 927 |
|
|
@@ -1010,7 +1014,8 @@ def drawAllContours(dataDoc,img,number,finalColorArray,ratioarea,ratioperim , pa
|
|
| 1010 |
if passed ==0:
|
| 1011 |
if ( SimilarAreaDictionary['Rounded'].loc[i] <= areaPerimeterMax and SimilarAreaDictionary['Rounded'].loc[i] >= areaPerimeterMin) :
|
| 1012 |
if (SimilarAreaDictionary['Width'].loc[i] <=widthMax and SimilarAreaDictionary['Width'].loc[i] >= widthMin) and (SimilarAreaDictionary['Height'].loc[i] <= heightMax and SimilarAreaDictionary['Height'].loc[i] >= heightMin ) or (SimilarAreaDictionary['Width'].loc[i] <=heightMax and SimilarAreaDictionary['Width'].loc[i] >= heightMin) and (SimilarAreaDictionary['Height'].loc[i] <= widthMax and SimilarAreaDictionary['Height'].loc[i] >= widthMin ) :
|
| 1013 |
-
|
|
|
|
| 1014 |
for t in texts:
|
| 1015 |
if "GB" not in t or "RC" not in t or "PC" not in t:
|
| 1016 |
if t not in SimilarAreaDictionary['Texts'].loc[i]:
|
|
@@ -1037,7 +1042,8 @@ def drawAllContours(dataDoc,img,number,finalColorArray,ratioarea,ratioperim , pa
|
|
| 1037 |
annot11 = page.add_polyline_annot( points=shapee) # 'Polygon'
|
| 1038 |
annot11.set_border(width=0.2, dashes=[3])
|
| 1039 |
annot1.set_colors(stroke=color ,fill=None)
|
| 1040 |
-
|
|
|
|
| 1041 |
# annot.set_line_ends(fitz.PDF_ANNOT_LE_DIAMOND, fitz.PDF_ANNOT_LE_CIRCLE)
|
| 1042 |
annot11.update()
|
| 1043 |
pFlagDF=1
|
|
@@ -1045,7 +1051,8 @@ def drawAllContours(dataDoc,img,number,finalColorArray,ratioarea,ratioperim , pa
|
|
| 1045 |
annot1 = page.add_polyline_annot( points=shape) # 'Polygon'
|
| 1046 |
annot1.set_border(width=0.2 ,dashes=[3])
|
| 1047 |
annot1.set_colors(stroke=color ,fill=None)
|
| 1048 |
-
|
|
|
|
| 1049 |
SimilarAreaDictionary['Total Perimeter'].loc[i]+=perimeterr
|
| 1050 |
SimilarAreaDictionary['Perimeter'].loc[i]=perimeterr
|
| 1051 |
SimilarAreaDictionary['Total Length'].loc[i]+=lengthShape
|
|
@@ -1057,7 +1064,8 @@ def drawAllContours(dataDoc,img,number,finalColorArray,ratioarea,ratioperim , pa
|
|
| 1057 |
annot.set_border(width=0.2)
|
| 1058 |
annot.set_colors(stroke=color, fill= color )
|
| 1059 |
annot.set_opacity(0.5)
|
| 1060 |
-
|
|
|
|
| 1061 |
# annot.set_line_ends(fitz.PDF_ANNOT_LE_DIAMOND, fitz.PDF_ANNOT_LE_CIRCLE)
|
| 1062 |
annot.update()
|
| 1063 |
|
|
@@ -1104,8 +1112,7 @@ def drawAllContours(dataDoc,img,number,finalColorArray,ratioarea,ratioperim , pa
|
|
| 1104 |
for annot in page.annots():
|
| 1105 |
list1.loc[len(list1)] =annot.info
|
| 1106 |
|
| 1107 |
-
|
| 1108 |
-
gc,spreadsheet_service,spreadsheetId, spreadsheet_url , namepathArr=legendGoogleSheets(SimilarAreaDictionary , path,pdfpath)
|
| 1109 |
return imgPerimeter1,image_new1,SimilarAreaDictionary, colorsUsed , spreadsheet_url , spreadsheetId , list1 , pdflink , areas_Perimeters , namepathArr
|
| 1110 |
|
| 1111 |
######################################################
|
|
@@ -1124,7 +1131,7 @@ def deletemarkups(list1, dbPath , path):
|
|
| 1124 |
perimstodelete=[]
|
| 1125 |
|
| 1126 |
dbxTeam=tsadropboxretrieval.ADR_Access_DropboxTeam('user')
|
| 1127 |
-
print('pathhhhh',dbPath+path)
|
| 1128 |
md, res =dbxTeam.files_download(path= dbPath+path)
|
| 1129 |
data = res.content
|
| 1130 |
doc=fitz.open("pdf", data)
|
|
@@ -1133,7 +1140,7 @@ def deletemarkups(list1, dbPath , path):
|
|
| 1133 |
for page in doc:
|
| 1134 |
for annot in page.annots():
|
| 1135 |
list2.loc[len(list2)] =annot.info
|
| 1136 |
-
print(list1)
|
| 1137 |
deletedrows=pd.concat([list1,list2]).drop_duplicates(keep=False)
|
| 1138 |
|
| 1139 |
print(deletedrows,len(deletedrows))
|
|
@@ -1145,574 +1152,5 @@ def deletemarkups(list1, dbPath , path):
|
|
| 1145 |
else:
|
| 1146 |
flag=0
|
| 1147 |
return deletedrows
|
| 1148 |
-
|
| 1149 |
-
def deletefromlegend(deletedrows,SimilarAreaDictionarycopy,section, areaPermArr=[]):
|
| 1150 |
-
items=[]
|
| 1151 |
-
idx=0
|
| 1152 |
-
if section.startswith('1.0'):
|
| 1153 |
-
areaPermArr=ast.literal_eval(areaPermArr)
|
| 1154 |
-
myDict=eval(SimilarAreaDictionarycopy)
|
| 1155 |
-
SimilarAreaDictionarycopy=pd.DataFrame(myDict)
|
| 1156 |
-
strings=deletedrows['content']
|
| 1157 |
-
areastodelete = []
|
| 1158 |
-
perimstodelete=[]
|
| 1159 |
-
lengthstodelete=[]
|
| 1160 |
-
print('areaPermArr',areaPermArr)
|
| 1161 |
-
for item in strings:
|
| 1162 |
-
items.append(str(item).split('\n \n'))
|
| 1163 |
-
# print('itemsssssss',float(re.findall("\d+\.\d+", str(items[i][0]).split()[0])[0])) #take area and perim mn hna l sec 3.2 and +/- value margin
|
| 1164 |
-
|
| 1165 |
-
for i in range(len(items)):
|
| 1166 |
-
print('ITEMSS',str(items[i]).split())
|
| 1167 |
-
areastodelete.append(float(re.findall("\d+\.\d+", str(items[i][0]).split()[1])[0]))
|
| 1168 |
-
perimstodelete.append(float(re.findall("\d+\.\d+", str(items[i][1]).split()[1])[0]) )
|
| 1169 |
-
lengthstodelete.append(float(re.findall("\d+\.\d+", str(items[i][2]).split()[1])[0]) )
|
| 1170 |
-
|
| 1171 |
-
for i in range(len(areastodelete)):#item in areastodelete:
|
| 1172 |
-
areamin=round(areastodelete[i],1)- 0.3
|
| 1173 |
-
areamax=round(areastodelete[i],1)+ 0.3
|
| 1174 |
-
perimmin=round(perimstodelete[i],1)- 0.3
|
| 1175 |
-
perimmax=round(perimstodelete[i],1)+ 0.3
|
| 1176 |
-
if section.startswith('1.0'):
|
| 1177 |
-
for p in range(len(areaPermArr)):
|
| 1178 |
-
|
| 1179 |
-
if areastodelete[i] in areaPermArr[p]:
|
| 1180 |
-
print('AAA',areaPermArr[p])
|
| 1181 |
-
area= areaPermArr[p][0]
|
| 1182 |
-
width= areaPermArr[p][1]
|
| 1183 |
-
height= areaPermArr[p][2]
|
| 1184 |
-
# if section.startswith('1.0'):
|
| 1185 |
-
widthMin= width -10
|
| 1186 |
-
widthMax= width +10
|
| 1187 |
-
heightMin = height-10
|
| 1188 |
-
heightMax=height+10
|
| 1189 |
-
found=SimilarAreaDictionarycopy.loc[SimilarAreaDictionarycopy.index[((SimilarAreaDictionarycopy['Rounded'] >=areamin) & (SimilarAreaDictionarycopy['Rounded']<=areamax) & (SimilarAreaDictionarycopy['Perimeter'] >=perimmin) & (SimilarAreaDictionarycopy['Perimeter']<=perimmax) ) & ( ((SimilarAreaDictionarycopy['Width']>=widthMin) & (SimilarAreaDictionarycopy['Width']<=widthMax) & (SimilarAreaDictionarycopy['Height']>=heightMin) & (SimilarAreaDictionarycopy['Height']<=heightMax) ) | ((SimilarAreaDictionarycopy['Width']>=heightMin) & (SimilarAreaDictionarycopy['Width']<=heightMax) & (SimilarAreaDictionarycopy['Height']>=widthMin) & (SimilarAreaDictionarycopy['Height']<=widthMax) )) ]]
|
| 1190 |
-
elif section.startswith('3.2'):
|
| 1191 |
-
areamin=round(areastodelete[i],1)- 0.1
|
| 1192 |
-
areamax= round(areastodelete[i],1) + 0.1
|
| 1193 |
-
|
| 1194 |
-
found=SimilarAreaDictionarycopy.loc[SimilarAreaDictionarycopy.index[((SimilarAreaDictionarycopy['Area'] >=areamin) & (SimilarAreaDictionarycopy['Area']<=areamax) )]]
|
| 1195 |
-
|
| 1196 |
-
if len(found.index.values ) >0:
|
| 1197 |
-
occ=SimilarAreaDictionarycopy.loc[found.index.values[0],'Occurences']
|
| 1198 |
-
if occ== 1: #drop row
|
| 1199 |
-
print('occ=1')
|
| 1200 |
-
SimilarAreaDictionarycopy= SimilarAreaDictionarycopy.drop(found.index.values[0])
|
| 1201 |
-
|
| 1202 |
-
else: #occ minus 1 , total area - areavalue , total perim - perimvalue
|
| 1203 |
-
print('occ>1')
|
| 1204 |
-
if section.startswith('1.0'):
|
| 1205 |
-
idx=SimilarAreaDictionarycopy.index[((SimilarAreaDictionarycopy['Rounded'] >=areamin) & (SimilarAreaDictionarycopy['Rounded']<=areamax) & (SimilarAreaDictionarycopy['Perimeter'] >=perimmin) & (SimilarAreaDictionarycopy['Perimeter']<=perimmax) ) & ( ((SimilarAreaDictionarycopy['Width']>=widthMin) & (SimilarAreaDictionarycopy['Width']<=widthMax) & (SimilarAreaDictionarycopy['Height']>=heightMin) & (SimilarAreaDictionarycopy['Height']<=heightMax) ) | ((SimilarAreaDictionarycopy['Width']>=heightMin) & (SimilarAreaDictionarycopy['Width']<=heightMax) & (SimilarAreaDictionarycopy['Height']>=widthMin) & (SimilarAreaDictionarycopy['Height']<=widthMax) )) ]
|
| 1206 |
-
elif section.startswith('3.2'):
|
| 1207 |
-
perimmin=round(perimstodelete[i],1)- 50
|
| 1208 |
-
perimmax=round(perimstodelete[i],1)+ 50
|
| 1209 |
-
idx=SimilarAreaDictionarycopy.index[((SimilarAreaDictionarycopy['Area'] >=areamin) & (SimilarAreaDictionarycopy['Area']<=areamax) & (SimilarAreaDictionarycopy['Perimeter'] >=perimmin) & (SimilarAreaDictionarycopy['Perimeter']<=perimmax) )]
|
| 1210 |
-
SimilarAreaDictionarycopy.loc[idx,'Total Area'] = SimilarAreaDictionarycopy.loc[idx,'Total Area'] - areastodelete[i]
|
| 1211 |
-
SimilarAreaDictionarycopy.loc[idx,'Total Perimeter'] = SimilarAreaDictionarycopy.loc[idx,'Total Perimeter'] - perimstodelete[i]
|
| 1212 |
-
SimilarAreaDictionarycopy.loc[idx,'Total Length'] = SimilarAreaDictionarycopy.loc[idx,'Total Length'] - lengthstodelete[i]
|
| 1213 |
-
SimilarAreaDictionarycopy.loc[idx,'Occurences'] = int(SimilarAreaDictionarycopy.loc[idx,'Occurences']) - 1
|
| 1214 |
-
return SimilarAreaDictionarycopy
|
| 1215 |
-
#######################################################
|
| 1216 |
-
##Legend
|
| 1217 |
-
def authorizeLegend():
|
| 1218 |
-
SCOPES = [
|
| 1219 |
-
'https://www.googleapis.com/auth/spreadsheets',
|
| 1220 |
-
'https://www.googleapis.com/auth/drive',
|
| 1221 |
-
'https://www.googleapis.com/auth/drive.metadata'
|
| 1222 |
-
]
|
| 1223 |
-
credentials = service_account.Credentials.from_service_account_file('credentials.json', scopes=SCOPES)
|
| 1224 |
-
spreadsheet_service = build('sheets', 'v4', credentials=credentials)
|
| 1225 |
-
drive_service = build('drive', 'v3', credentials=credentials)
|
| 1226 |
-
gc = pygsheets.authorize(custom_credentials=credentials, client_secret='credentials.json')
|
| 1227 |
-
return spreadsheet_service,drive_service,gc
|
| 1228 |
-
#create/update legend
|
| 1229 |
-
def legendGoogleSheets(SimilarAreaDictionary,path ,pdfpath, spreadsheetId=0):
|
| 1230 |
-
|
| 1231 |
-
spreadsheet_service,drive_service,gc=authorizeLegend()
|
| 1232 |
-
########
|
| 1233 |
-
legendTitle= path
|
| 1234 |
-
titles=gc.spreadsheet_titles()
|
| 1235 |
-
|
| 1236 |
-
|
| 1237 |
-
|
| 1238 |
-
if legendTitle in titles:
|
| 1239 |
-
print('found sheet ', legendTitle)
|
| 1240 |
-
ws=gc.open(str(legendTitle))
|
| 1241 |
-
spreadsheetId=ws.id
|
| 1242 |
-
else:
|
| 1243 |
-
# ####### create new sheet
|
| 1244 |
-
print('creating new sheeet')
|
| 1245 |
-
|
| 1246 |
-
spreadsheet_details = {
|
| 1247 |
-
'properties': {
|
| 1248 |
-
'title': path
|
| 1249 |
-
}
|
| 1250 |
-
}
|
| 1251 |
-
sheet = spreadsheet_service.spreadsheets().create(body=spreadsheet_details,
|
| 1252 |
-
fields='spreadsheetId').execute()
|
| 1253 |
-
|
| 1254 |
-
spreadsheetId = sheet.get('spreadsheetId')
|
| 1255 |
-
permission1 = {
|
| 1256 |
-
'type': 'anyone',
|
| 1257 |
-
'role': 'writer',
|
| 1258 |
-
# 'emailAddress': 'marthe.adr@gmail.com'
|
| 1259 |
-
}
|
| 1260 |
-
# permission2 = {
|
| 1261 |
-
# 'type': 'user',
|
| 1262 |
-
# 'role': 'writer',
|
| 1263 |
-
# 'emailAddress': 'marthe.adr@gmail.com',
|
| 1264 |
-
# 'pendingOwner': True
|
| 1265 |
-
# }
|
| 1266 |
-
|
| 1267 |
-
|
| 1268 |
-
drive_service.permissions().create(fileId=spreadsheetId, body=permission1, supportsAllDrives=True ).execute()
|
| 1269 |
-
ws=gc.open_by_key(spreadsheetId)
|
| 1270 |
-
|
| 1271 |
-
sheetId = '0' # Please set sheet ID.
|
| 1272 |
-
worksheet = ws.worksheet(0)
|
| 1273 |
-
worksheet.title='Legend and data created'
|
| 1274 |
-
worksheet.clear()
|
| 1275 |
-
print('PDFPATHHH',pdfpath)
|
| 1276 |
-
ws.create_developer_metadata('path',pdfpath)
|
| 1277 |
-
splittedpdfpath=re.split(r'[`\-=~!@#$%^&*()_+\[\]{};\'\\:"|<,/<>?]', pdfpath)
|
| 1278 |
-
namepathArr=[legendTitle , spreadsheetId,ws.get_developer_metadata('path')[0].value]
|
| 1279 |
-
if splittedpdfpath[-2].startswith('2.2') or splittedpdfpath[-2].startswith('2.1') :
|
| 1280 |
-
worksheet.set_dataframe(start='A1',df=SimilarAreaDictionary)
|
| 1281 |
-
print(SimilarAreaDictionary)
|
| 1282 |
-
else:
|
| 1283 |
-
top_header_format = [
|
| 1284 |
-
{'mergeCells': { #areas
|
| 1285 |
-
'mergeType': 'MERGE_ROWS',
|
| 1286 |
-
'range': {
|
| 1287 |
-
'sheetId': '0',
|
| 1288 |
-
'startRowIndex': 1,
|
| 1289 |
-
'endRowIndex': 2,
|
| 1290 |
-
'startColumnIndex': 3,
|
| 1291 |
-
'endColumnIndex':5
|
| 1292 |
-
|
| 1293 |
-
|
| 1294 |
-
}
|
| 1295 |
-
}},
|
| 1296 |
-
|
| 1297 |
-
{'mergeCells': { #perimeters
|
| 1298 |
-
'mergeType': 'MERGE_ROWS',
|
| 1299 |
-
'range': {
|
| 1300 |
-
'sheetId': '0',
|
| 1301 |
-
'startRowIndex': 1,
|
| 1302 |
-
'endRowIndex': 2,
|
| 1303 |
-
'startColumnIndex': 5,
|
| 1304 |
-
'endColumnIndex':7
|
| 1305 |
-
}
|
| 1306 |
-
|
| 1307 |
-
}},
|
| 1308 |
-
{'mergeCells': { #lengths
|
| 1309 |
-
'mergeType': 'MERGE_ROWS',
|
| 1310 |
-
'range': {
|
| 1311 |
-
'sheetId': '0',
|
| 1312 |
-
'startRowIndex': 1,
|
| 1313 |
-
'endRowIndex': 2,
|
| 1314 |
-
'startColumnIndex': 7,
|
| 1315 |
-
'endColumnIndex':9
|
| 1316 |
-
}
|
| 1317 |
-
|
| 1318 |
-
}},
|
| 1319 |
-
|
| 1320 |
-
{'mergeCells': { # legend and data created
|
| 1321 |
-
'mergeType': 'MERGE_ROWS',
|
| 1322 |
-
'range': {
|
| 1323 |
-
'sheetId': '0',
|
| 1324 |
-
'startRowIndex': 0,
|
| 1325 |
-
'endRowIndex': 1,
|
| 1326 |
-
'startColumnIndex': 0,
|
| 1327 |
-
'endColumnIndex':10
|
| 1328 |
-
}
|
| 1329 |
-
|
| 1330 |
-
}}
|
| 1331 |
-
]
|
| 1332 |
-
|
| 1333 |
-
|
| 1334 |
-
spreadsheet_service.spreadsheets().batchUpdate( spreadsheetId=spreadsheetId , body={'requests': top_header_format} ).execute()
|
| 1335 |
-
worksheet.cell((1,1)).value='Legend and Data Created'
|
| 1336 |
-
worksheet.cell((2,1)).value='Guess'
|
| 1337 |
-
worksheet.cell((2,2)).value='Color'
|
| 1338 |
-
worksheet.cell((2,3)).value='Count'
|
| 1339 |
-
worksheet.cell((2,4)).value='Areas'
|
| 1340 |
-
worksheet.cell((2,6)).value='Perimeters'
|
| 1341 |
-
worksheet.cell((2,8)).value='Lengths'
|
| 1342 |
-
worksheet.cell((2,10)).value='Texts'
|
| 1343 |
-
second_row_data=['Nr','m2','Total','m','Total','m','Total']
|
| 1344 |
-
if splittedpdfpath[-2].startswith('1.0') or splittedpdfpath[-2].startswith('3.2'):
|
| 1345 |
-
worksheet.update_row(3,second_row_data,col_offset=2)
|
| 1346 |
-
worksheet.update_col(1,list(SimilarAreaDictionary['Guess']),row_offset=3)
|
| 1347 |
-
worksheet.update_col(3,list(SimilarAreaDictionary['Occurences']),row_offset=3)
|
| 1348 |
-
worksheet.update_col(4,list(SimilarAreaDictionary['Area']),row_offset=3)
|
| 1349 |
-
worksheet.update_col(5,list(SimilarAreaDictionary['Total Area']),row_offset=3)
|
| 1350 |
-
worksheet.update_col(6,list(SimilarAreaDictionary['Perimeter']),row_offset=3)
|
| 1351 |
-
worksheet.update_col(7,list(SimilarAreaDictionary['Total Perimeter']),row_offset=3)
|
| 1352 |
-
|
| 1353 |
-
worksheet.update_col(8,list(SimilarAreaDictionary['Length']),row_offset=3)
|
| 1354 |
-
worksheet.update_col(9,list(SimilarAreaDictionary['Total Length']),row_offset=3)
|
| 1355 |
-
worksheet.update_col(10,list(SimilarAreaDictionary['Texts']),row_offset=3)
|
| 1356 |
-
if splittedpdfpath[-2].startswith('1.0'):
|
| 1357 |
-
colorsUsed=[]
|
| 1358 |
-
for i in range(len(SimilarAreaDictionary)):
|
| 1359 |
-
colorsUsed.append([SimilarAreaDictionary['R'].iloc[i] ,SimilarAreaDictionary['G'].iloc[i] , SimilarAreaDictionary['B'].iloc[i]] )
|
| 1360 |
-
elif splittedpdfpath[-2].startswith('3.2'):
|
| 1361 |
-
colorsUsed=list(SimilarAreaDictionary['Color'])
|
| 1362 |
-
|
| 1363 |
-
#legend specs here
|
| 1364 |
-
rowsLen=len(SimilarAreaDictionary.values.tolist()) #kam row -- last row = rowsLen +1
|
| 1365 |
-
lastcell=worksheet.cell((rowsLen+2,1)) #row,col
|
| 1366 |
-
lastcellNotation=str(lastcell.address.label)
|
| 1367 |
-
# worksheet.set_data_validation('A3',lastcellNotation, condition_type='ONE_OF_LIST', condition_values=['Ground Beam','Pile Cap'], showCustomUi=True)
|
| 1368 |
-
|
| 1369 |
-
#get lengths of df
|
| 1370 |
-
columnsLen=len(SimilarAreaDictionary.columns.values.tolist()) #kam column -- last col = columnsLen+1 3shan base0
|
| 1371 |
-
lastUsedCol=columnsLen+1
|
| 1372 |
-
|
| 1373 |
-
worksheet.adjust_column_width(start=2,end=3)
|
| 1374 |
-
worksheet.adjust_column_width(start=10,end=10)
|
| 1375 |
-
# if splittedpdfpath[-2].startswith('1.0'):
|
| 1376 |
-
worksheet.adjust_column_width(start=4,end=9,pixel_size=60)
|
| 1377 |
-
startrow = 3
|
| 1378 |
-
# elif splittedpdfpath[-2].startswith('3.2'):
|
| 1379 |
-
# startrow=2
|
| 1380 |
-
|
| 1381 |
-
sheetId = '0' # Please set sheet ID.
|
| 1382 |
-
for i in range(len(colorsUsed)):
|
| 1383 |
-
|
| 1384 |
-
print(colorsUsed[i])
|
| 1385 |
-
r,g,b=colorsUsed[i]
|
| 1386 |
-
body = {
|
| 1387 |
-
"requests": [
|
| 1388 |
-
{
|
| 1389 |
-
"updateCells": {
|
| 1390 |
-
"range": {
|
| 1391 |
-
"sheetId": sheetId,
|
| 1392 |
-
"startRowIndex": i+startrow,
|
| 1393 |
-
# "endRowIndex":4 ,
|
| 1394 |
-
"startColumnIndex":1,
|
| 1395 |
-
|
| 1396 |
-
# "endColumnIndex": 0
|
| 1397 |
-
},
|
| 1398 |
-
|
| 1399 |
-
"rows": [
|
| 1400 |
-
{
|
| 1401 |
-
"values": [
|
| 1402 |
-
{
|
| 1403 |
-
"userEnteredFormat": {
|
| 1404 |
-
"backgroundColor": {
|
| 1405 |
-
|
| 1406 |
-
"red": r/255,
|
| 1407 |
-
"green": g/255,
|
| 1408 |
-
"blue": b/255,
|
| 1409 |
-
"alpha": 0.4,
|
| 1410 |
-
|
| 1411 |
-
}
|
| 1412 |
-
|
| 1413 |
-
}
|
| 1414 |
-
}
|
| 1415 |
-
]
|
| 1416 |
-
}
|
| 1417 |
-
],
|
| 1418 |
-
"fields": "userEnteredFormat.backgroundColor",
|
| 1419 |
-
|
| 1420 |
-
}
|
| 1421 |
-
|
| 1422 |
-
|
| 1423 |
-
|
| 1424 |
-
}
|
| 1425 |
-
]
|
| 1426 |
-
}
|
| 1427 |
-
res = spreadsheet_service.spreadsheets().batchUpdate(spreadsheetId=spreadsheetId, body=body).execute()
|
| 1428 |
-
# if splittedpdfpath[-2].startswith('1.0'):
|
| 1429 |
-
endColindex=10
|
| 1430 |
-
endrow=3
|
| 1431 |
-
body2={
|
| 1432 |
-
"requests": [
|
| 1433 |
-
{
|
| 1434 |
-
"updateBorders": {
|
| 1435 |
-
"range": {
|
| 1436 |
-
"sheetId": sheetId,
|
| 1437 |
-
"startRowIndex": 0,
|
| 1438 |
-
"endRowIndex": len(SimilarAreaDictionary)+endrow,
|
| 1439 |
-
"startColumnIndex": 0,
|
| 1440 |
-
"endColumnIndex": endColindex
|
| 1441 |
-
},
|
| 1442 |
-
"top": {
|
| 1443 |
-
"style": "SOLID",
|
| 1444 |
-
"width": 2,
|
| 1445 |
-
"color": {
|
| 1446 |
-
"red": 0.0,
|
| 1447 |
-
"green":0.0,
|
| 1448 |
-
"blue":0.0
|
| 1449 |
-
},
|
| 1450 |
-
},
|
| 1451 |
-
"bottom": {
|
| 1452 |
-
"style": "SOLID",
|
| 1453 |
-
"width": 2,
|
| 1454 |
-
"color": {
|
| 1455 |
-
"red": 0.0,
|
| 1456 |
-
"green":0.0,
|
| 1457 |
-
"blue":0.0
|
| 1458 |
-
},
|
| 1459 |
-
},
|
| 1460 |
-
"left":{
|
| 1461 |
-
"style": "SOLID",
|
| 1462 |
-
"width":2,
|
| 1463 |
-
"color": {
|
| 1464 |
-
"red": 0.0,
|
| 1465 |
-
"green":0.0,
|
| 1466 |
-
"blue":0.0
|
| 1467 |
-
},
|
| 1468 |
-
},
|
| 1469 |
-
"right":{
|
| 1470 |
-
"style": "SOLID",
|
| 1471 |
-
"width": 2,
|
| 1472 |
-
"color": {
|
| 1473 |
-
"red": 0.0,
|
| 1474 |
-
"green":0.0,
|
| 1475 |
-
"blue":0.0
|
| 1476 |
-
},
|
| 1477 |
-
},
|
| 1478 |
-
"innerHorizontal":{
|
| 1479 |
-
"style": "SOLID",
|
| 1480 |
-
"width":2,
|
| 1481 |
-
"color": {
|
| 1482 |
-
"red": 0.0,
|
| 1483 |
-
"green":0.0,
|
| 1484 |
-
"blue":0.0
|
| 1485 |
-
},
|
| 1486 |
-
},
|
| 1487 |
-
"innerVertical": {
|
| 1488 |
-
"style": "SOLID",
|
| 1489 |
-
"width": 2,
|
| 1490 |
-
"color": {
|
| 1491 |
-
"red": 0.0,
|
| 1492 |
-
"green":0.0,
|
| 1493 |
-
"blue":0.0
|
| 1494 |
-
},
|
| 1495 |
-
},
|
| 1496 |
-
}
|
| 1497 |
-
}
|
| 1498 |
-
]
|
| 1499 |
-
}
|
| 1500 |
-
spreadsheet_service.spreadsheets().batchUpdate(spreadsheetId=spreadsheetId, body=body2).execute()
|
| 1501 |
-
|
| 1502 |
-
model_cell =worksheet.cell('A1')
|
| 1503 |
-
model_cell.set_text_format('bold', True)
|
| 1504 |
-
model_cell.set_horizontal_alignment( pygsheets.custom_types.HorizontalAlignment.CENTER )
|
| 1505 |
-
model_cell.color = (213/255, 219/255 ,255/255)
|
| 1506 |
-
pygsheets.DataRange('A2','J2', worksheet=worksheet).apply_format(model_cell)
|
| 1507 |
-
spreadsheet_url = "https://docs.google.com/spreadsheets/d/%s" % spreadsheetId
|
| 1508 |
-
print(spreadsheet_url)
|
| 1509 |
-
drive_service.permissions().update(transferOwnership=True , fileId=spreadsheetId,permissionId='11OfoB4Z6wOVII8mYmbnCbbqTQs7rYA65')
|
| 1510 |
-
|
| 1511 |
-
|
| 1512 |
-
return gc,spreadsheet_service,spreadsheetId ,spreadsheet_url , namepathArr
|
| 1513 |
-
#######################
|
| 1514 |
-
|
| 1515 |
-
def mapnametoLegend(McTName):
|
| 1516 |
-
|
| 1517 |
-
sectionKey = McTName.pop()
|
| 1518 |
-
key=sectionKey[0]
|
| 1519 |
-
section=sectionKey[1]
|
| 1520 |
-
|
| 1521 |
-
spreadsheet_service,drive_service,gc=authorizeLegend()
|
| 1522 |
-
spreadsheet_key =str(key) # Please set the Spreadsheet ID.
|
| 1523 |
-
|
| 1524 |
-
ws = gc.open_by_key(spreadsheet_key)
|
| 1525 |
-
# guessednamesfinal=getguessnames(gc,ws)
|
| 1526 |
-
sheetnames=[]
|
| 1527 |
-
unit=''
|
| 1528 |
-
# ws.add_worksheet("Summary") # Please set the new sheet name.
|
| 1529 |
-
for i in ws._sheet_list:
|
| 1530 |
-
print(i)
|
| 1531 |
-
sheetnames.append(i.title)
|
| 1532 |
-
print(i.index)
|
| 1533 |
-
if 'XML Export Summary' in sheetnames:
|
| 1534 |
-
worksheetS = ws.worksheet_by_title('XML Export Summary')
|
| 1535 |
-
else:
|
| 1536 |
-
ws.add_worksheet("XML Export Summary") # Please set the new sheet name.
|
| 1537 |
-
worksheetw = ws.worksheet(0) #legend
|
| 1538 |
-
worksheetS = ws.worksheet_by_title('XML Export Summary')
|
| 1539 |
-
summaryId= ws[1].id
|
| 1540 |
-
print('summaryyyID',summaryId)
|
| 1541 |
-
print('summaryyyID2',worksheetS.id)
|
| 1542 |
-
worksheetS.clear()
|
| 1543 |
-
|
| 1544 |
-
countnames=0
|
| 1545 |
-
row0=['MC_T Name','Qty','Unit']
|
| 1546 |
-
worksheetS.update_row(1,row0)
|
| 1547 |
-
|
| 1548 |
-
|
| 1549 |
-
for i in range(len(McTName)):
|
| 1550 |
-
allgbnames=''
|
| 1551 |
-
item=''
|
| 1552 |
-
print(McTName[i][0])
|
| 1553 |
-
|
| 1554 |
-
# firstpart= re.split(r'[`\-=~!@#$%^&*()_+\[\]{};\'\\:"|<,./<>?]', McTName[i][0])
|
| 1555 |
-
print('kkk' ,McTName[i][2])
|
| 1556 |
-
if McTName[i][2].startswith('Area'):
|
| 1557 |
-
if section.startswith('1.0'):
|
| 1558 |
-
rowvalue=5# column 5
|
| 1559 |
-
elif section.startswith('3.2'):
|
| 1560 |
-
rowvalue=3
|
| 1561 |
-
ar=0
|
| 1562 |
-
unit='m2'
|
| 1563 |
-
if McTName[i][2].startswith('Perimeter'):
|
| 1564 |
-
if section.startswith('1.0'):
|
| 1565 |
-
rowvalue=7# column 7
|
| 1566 |
-
elif section.startswith('3.2'):
|
| 1567 |
-
rowvalue=3
|
| 1568 |
-
ar=0
|
| 1569 |
-
unit='m'
|
| 1570 |
-
if McTName[i][2].startswith('Length'):
|
| 1571 |
-
if section.startswith('1.0'):
|
| 1572 |
-
rowvalue=9# column 7
|
| 1573 |
-
elif section.startswith('3.2'):
|
| 1574 |
-
rowvalue=3
|
| 1575 |
-
ar=0
|
| 1576 |
-
unit='m'
|
| 1577 |
-
if McTName[i][2].startswith('Count'):
|
| 1578 |
-
if section.startswith('1.0'):
|
| 1579 |
-
rowvalue=3# column 7
|
| 1580 |
-
elif section.startswith('3.2'):
|
| 1581 |
-
rowvalue=3
|
| 1582 |
-
ar=0
|
| 1583 |
-
unit='Nr'
|
| 1584 |
-
|
| 1585 |
-
print('mcct',McTName[i][1])
|
| 1586 |
-
if isinstance(McTName[i][1], list):
|
| 1587 |
-
guessednames=worksheetw.get_col(1, returnas='matrix', include_tailing_empty=False)
|
| 1588 |
-
|
| 1589 |
-
for m in McTName[i][1]:
|
| 1590 |
-
if m:
|
| 1591 |
-
if m.startswith('text1'):
|
| 1592 |
-
name=m.removeprefix('text1')
|
| 1593 |
-
allgbnames+= name +' +'
|
| 1594 |
-
indices = [o for o, x in enumerate(guessednames) if x == name]
|
| 1595 |
-
print(indices)
|
| 1596 |
-
for j in range(len(indices)):
|
| 1597 |
-
# print('kjjjj',roww[j])
|
| 1598 |
-
ar+=float(worksheetw.cell((indices[j]+1 ,rowvalue)).value)
|
| 1599 |
-
else:
|
| 1600 |
-
item+=m + ' ,'
|
| 1601 |
-
print(item)
|
| 1602 |
-
n= McTName[i][0] + ' ( '+ allgbnames[:-2] +' , ' + item[:-1] + ' ) '
|
| 1603 |
-
else:
|
| 1604 |
-
if McTName[i][1].startswith('text1'):
|
| 1605 |
-
name=McTName[i][1].removeprefix('text1')
|
| 1606 |
-
allgbnames+= name
|
| 1607 |
-
|
| 1608 |
-
roww=worksheetw.find(name)
|
| 1609 |
-
print(roww)
|
| 1610 |
-
for j in range(len(roww)):
|
| 1611 |
-
print('kjjjj',roww[j])
|
| 1612 |
-
ar+=float(worksheetw.cell((roww[j].row ,rowvalue)).value)
|
| 1613 |
-
n= McTName[i][0] + ' ( '+ allgbnames + ' ) '
|
| 1614 |
-
|
| 1615 |
-
rowi=[str(n),ar,unit]
|
| 1616 |
-
worksheetS.update_row(i+2,rowi)
|
| 1617 |
-
# worksheetS.adjust_column_width(start=1,end=4)
|
| 1618 |
-
worksheetS.adjust_column_width(start=1,end=1, pixel_size=350)
|
| 1619 |
-
worksheetS.adjust_column_width(start=2,end=2, pixel_size=100)
|
| 1620 |
-
worksheetS.adjust_column_width(start=3,end=3)
|
| 1621 |
-
|
| 1622 |
-
xx=(worksheetS.cell( ( len(McTName) +1 ,3)) ).address.label
|
| 1623 |
-
model_cell1 =worksheetS.cell('A2')
|
| 1624 |
-
model_cell1.set_horizontal_alignment( pygsheets.custom_types.HorizontalAlignment.LEFT )
|
| 1625 |
-
pygsheets.DataRange('A2', str(xx), worksheet=worksheetS).apply_format(model_cell1)
|
| 1626 |
-
|
| 1627 |
-
|
| 1628 |
-
model_cell =worksheetS.cell('A1')
|
| 1629 |
-
model_cell.set_text_format('bold', True)
|
| 1630 |
-
model_cell.set_horizontal_alignment( pygsheets.custom_types.HorizontalAlignment.CENTER )
|
| 1631 |
-
pygsheets.DataRange('A1','C1', worksheet=worksheetS).apply_format(model_cell)
|
| 1632 |
|
| 1633 |
-
|
| 1634 |
-
"requests": [
|
| 1635 |
-
{
|
| 1636 |
-
"updateBorders": {
|
| 1637 |
-
"range": {
|
| 1638 |
-
"sheetId": str(summaryId),
|
| 1639 |
-
"startRowIndex": 0,
|
| 1640 |
-
"endRowIndex": len(McTName) +1 ,
|
| 1641 |
-
"startColumnIndex": 0,
|
| 1642 |
-
"endColumnIndex": 3
|
| 1643 |
-
},
|
| 1644 |
-
"top": {
|
| 1645 |
-
"style": "SOLID",
|
| 1646 |
-
"width": 2,
|
| 1647 |
-
"color": {
|
| 1648 |
-
"red": 0.0,
|
| 1649 |
-
"green":0.0,
|
| 1650 |
-
"blue":0.0
|
| 1651 |
-
},
|
| 1652 |
-
},
|
| 1653 |
-
"bottom": {
|
| 1654 |
-
"style": "SOLID",
|
| 1655 |
-
"width": 2,
|
| 1656 |
-
"color": {
|
| 1657 |
-
"red": 0.0,
|
| 1658 |
-
"green":0.0,
|
| 1659 |
-
"blue":0.0
|
| 1660 |
-
},
|
| 1661 |
-
},
|
| 1662 |
-
"left":{
|
| 1663 |
-
"style": "SOLID",
|
| 1664 |
-
"width":2,
|
| 1665 |
-
"color": {
|
| 1666 |
-
"red": 0.0,
|
| 1667 |
-
"green":0.0,
|
| 1668 |
-
"blue":0.0
|
| 1669 |
-
},
|
| 1670 |
-
},
|
| 1671 |
-
"right":{
|
| 1672 |
-
"style": "SOLID",
|
| 1673 |
-
"width": 2,
|
| 1674 |
-
"color": {
|
| 1675 |
-
"red": 0.0,
|
| 1676 |
-
"green":0.0,
|
| 1677 |
-
"blue":0.0
|
| 1678 |
-
},
|
| 1679 |
-
},
|
| 1680 |
-
"innerHorizontal":{
|
| 1681 |
-
"style": "SOLID",
|
| 1682 |
-
"width":2,
|
| 1683 |
-
"color": {
|
| 1684 |
-
"red": 0.0,
|
| 1685 |
-
"green":0.0,
|
| 1686 |
-
"blue":0.0
|
| 1687 |
-
},
|
| 1688 |
-
},
|
| 1689 |
-
"innerVertical": {
|
| 1690 |
-
"style": "SOLID",
|
| 1691 |
-
"width": 2,
|
| 1692 |
-
"color": {
|
| 1693 |
-
"red": 0.0,
|
| 1694 |
-
"green":0.0,
|
| 1695 |
-
"blue":0.0
|
| 1696 |
-
},
|
| 1697 |
-
},
|
| 1698 |
-
}
|
| 1699 |
-
}
|
| 1700 |
-
]
|
| 1701 |
-
}
|
| 1702 |
-
spreadsheet_service.spreadsheets().batchUpdate(spreadsheetId=spreadsheet_key, body=body2).execute()
|
| 1703 |
-
return summaryId #,guessednamesfinal
|
| 1704 |
-
|
| 1705 |
-
# print(x,xarea)
|
| 1706 |
-
|
| 1707 |
-
def getguessnames(gc,ws):
|
| 1708 |
-
guessednamesfinal=[]
|
| 1709 |
-
worksheetw = ws.worksheet(0)
|
| 1710 |
-
guessednames=worksheetw.get_col(1, returnas='matrix', include_tailing_empty=False)
|
| 1711 |
-
print(guessednames[2:])
|
| 1712 |
-
for item in guessednames[2:]:
|
| 1713 |
-
if item not in guessednamesfinal:
|
| 1714 |
-
guessednamesfinal.append(item)
|
| 1715 |
-
print(guessednamesfinal)
|
| 1716 |
-
return guessednamesfinal
|
| 1717 |
-
|
| 1718 |
-
################################################################
|
|
|
|
| 24 |
import tsadropboxretrieval
|
| 25 |
from collections import Counter
|
| 26 |
from unidecode import unidecode
|
| 27 |
+
import google_sheet_Legend
|
| 28 |
|
| 29 |
def textLists(img,dataDoc):
|
| 30 |
allTexts = texts_from_pdf(dataDoc)
|
|
|
|
| 198 |
thresh=20
|
| 199 |
point=0.2
|
| 200 |
maxLineGap=40
|
| 201 |
+
|
| 202 |
green1=cv2.bitwise_not(smalldashesOut)
|
| 203 |
smalldashesOut=cv2.cvtColor(smalldashesOut,cv2.COLOR_GRAY2BGR)
|
| 204 |
imgLines= cv2.HoughLinesP(green1,point,np.pi/180,thresh,minLineLength=25,maxLineGap =maxLineGap) #try 180
|
|
|
|
| 233 |
return green2
|
| 234 |
else:
|
| 235 |
#imgDark with no dashed lines or small dashes
|
| 236 |
+
|
| 237 |
imgDark1=getImgDark(noCircles)
|
| 238 |
+
|
| 239 |
img4,imgBW,max,min=DashedPreprocessing(imgOriginal,noCircles)
|
| 240 |
imgDarkNoDashedLines=removeDashedLines(img4,imgDark1,max,min) #do preprocessing on normal img , and draw on darkimg
|
| 241 |
imgBW0 = cv2.cvtColor(imgBW, cv2.COLOR_BGR2GRAY)
|
| 242 |
imgDarkNoDashedLines = cv2.cvtColor(imgDarkNoDashedLines, cv2.COLOR_GRAY2BGR)
|
| 243 |
imgDarkNoDashedLines,smalldashesOut0=removeSmallDashes(imgDarkNoDashedLines,imgBW0)
|
| 244 |
+
|
| 245 |
#imgOld no small dashes - for oring purposes
|
| 246 |
imgoldG = cv2.cvtColor(imgold, cv2.COLOR_GRAY2BGR)
|
| 247 |
imgoldnoDashes,_=removeSmallDashes(cv2.bitwise_not(imgoldG),imgBW0,1)
|
| 248 |
+
|
| 249 |
#to connect leader lines after removing dashed lines and circles
|
| 250 |
Nodashedlines=removeDashedLines(img4,imgBW,max,min)
|
| 251 |
imgCopy,smalldashesOut=removeSmallDashes(imgOriginal,Nodashedlines)
|
|
|
|
| 260 |
green2=cv2.medianBlur(green2,5)
|
| 261 |
# cv2_imshow(green2)
|
| 262 |
imgoldnoDashes=cv2.medianBlur(imgoldnoDashes,5)
|
| 263 |
+
|
| 264 |
return green2 , cv2.bitwise_not(imgoldnoDashes)
|
| 265 |
|
| 266 |
|
|
|
|
| 470 |
BlackmaskA=cv2.erode(BlackmaskA,kernel, iterations=1)
|
| 471 |
contoursA, hier1 = cv2.findContours(BlackmaskA, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
|
| 472 |
finalcntsA.append(contoursA)
|
| 473 |
+
if pc_coor:
|
| 474 |
+
textPoint=nearestTextPCCOOR(int(x+(width/2)), int(y+(height/2)) , pc_coor)
|
| 475 |
+
txt=''
|
| 476 |
+
if(textPoint!='none'):
|
| 477 |
+
for textTuple in listall:
|
| 478 |
+
if textPoint[0]==textTuple[0] and textPoint[1]==textTuple[1]:
|
| 479 |
+
txt=textTuple[2]
|
| 480 |
+
if "GB" in txt or "RC" in txt or "PC" in txt:
|
| 481 |
+
shapetxts.append(txt)
|
| 482 |
+
elif textPoint=='none':
|
| 483 |
+
shapetxts.append('none')
|
| 484 |
+
|
| 485 |
+
if 'GB' in shapetxts:
|
| 486 |
+
xcBlk, ycBlk , width, height = cv2.boundingRect(contoursP[0])
|
| 487 |
+
xx=cv2.bitwise_and(outlines,outlines,mask=BlackmaskP)
|
| 488 |
+
xx = cv2.threshold(xx, 250, 255, cv2.THRESH_BINARY)[1]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 489 |
cntsx,hierx= cv2.findContours(xx, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
|
| 490 |
if len(cntsx)>0:
|
| 491 |
+
hierx=hierx[0]
|
| 492 |
+
xx=cv2.bitwise_and(outlinesDotIN,outlinesDotIN,mask=xx)
|
| 493 |
cntsx,hierx= cv2.findContours(xx, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
|
| 494 |
if len(cntsx)>0:
|
| 495 |
+
xx=connectsmallDot(xx)
|
| 496 |
+
cntsx,hierx= cv2.findContours(xx, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
|
| 497 |
+
if len(cntsx)>0:
|
| 498 |
+
hierx=hierx[0]
|
| 499 |
+
for comp in zip(cntsx,hierx):
|
| 500 |
+
c=comp[0]
|
| 501 |
+
h=comp[1]
|
| 502 |
+
xc, yc , width, height = cv2.boundingRect(c)
|
| 503 |
+
perimeter=cv2.arcLength(c,True)
|
| 504 |
+
shape=[]
|
| 505 |
+
approx = cv2.approxPolyDP(c, 0.003* perimeter, True)
|
| 506 |
+
if h[2]<0 and h[3] <0:
|
| 507 |
+
perimeter1 = cv2.arcLength(approx, True)
|
| 508 |
+
perimeter=perimeter1/2
|
| 509 |
+
# cv2_imshow(xx)
|
| 510 |
+
openClosedFlag='open'
|
| 511 |
+
imgtransparent1=cv2.polylines(imgtransparent1, [approx], False, (0,255,0), thickness=4,lineType=8)
|
| 512 |
+
perimeters.append([xc, yc ,xcBlk, ycBlk ,perimeter ,openClosedFlag , approx])
|
| 513 |
+
else:
|
| 514 |
+
if h[2] >0:
|
| 515 |
+
openClosedFlag='closed'
|
| 516 |
|
| 517 |
return tuple(finalcntsP),tuple(finalcntsA), perimeters , shapetxts , imgtransparent1 ,ArrthreshCnt , texts, iddk
|
| 518 |
|
|
|
|
| 626 |
for othercolor in finalColorArray:
|
| 627 |
# othercolor2=hexRGB(othercolor)
|
| 628 |
othercolor2=[othercolor[0],othercolor[1],othercolor[2]]
|
| 629 |
+
|
| 630 |
if othercolor2!=color:
|
| 631 |
+
|
| 632 |
masked0=DetectColor(firstLevel,othercolor)[0]
|
| 633 |
pil_image0=Image.fromarray(masked0)
|
| 634 |
extrema0 = pil_image0.convert("L").getextrema()
|
|
|
|
| 874 |
if passed ==0:
|
| 875 |
if SimilarAreaDictionary['Color'].loc[i] == [rgbcolor[0],rgbcolor[1],rgbcolor[2]] and ( SimilarAreaDictionary['Rounded'].loc[i] <= areaPerimeterMax and SimilarAreaDictionary['Rounded'].loc[i] >= areaPerimeterMin) :
|
| 876 |
if (SimilarAreaDictionary['Width'].loc[i] <=widthMax and SimilarAreaDictionary['Width'].loc[i] >= widthMin) and (SimilarAreaDictionary['Height'].loc[i] <= heightMax and SimilarAreaDictionary['Height'].loc[i] >= heightMin ) or (SimilarAreaDictionary['Width'].loc[i] <=heightMax and SimilarAreaDictionary['Width'].loc[i] >= heightMin) and (SimilarAreaDictionary['Height'].loc[i] <= widthMax and SimilarAreaDictionary['Height'].loc[i] >= widthMin ) :
|
| 877 |
+
if len(alltxts)>0:
|
| 878 |
+
SimilarAreaDictionary['Guess'].loc[i].append(str(alltxts[contour]))
|
| 879 |
for t in texts:
|
| 880 |
if "GB" not in t or "RC" not in t or "PC" not in t:
|
| 881 |
if t not in SimilarAreaDictionary['Texts'].loc[i]:
|
|
|
|
| 902 |
annot11 = page.add_polyline_annot( points=shapee) # 'Polygon'
|
| 903 |
annot11.set_border(width=0.2, dashes=[3])
|
| 904 |
annot1.set_colors(stroke=color ,fill=None)
|
| 905 |
+
if len(alltxts)>0:
|
| 906 |
+
annot11.set_info(content='Perimeter='+str(round((p[4]-1)*ratioperim,3))+' m',subject='ADR Team',title=str(alltxts[contour]))
|
| 907 |
# annot.set_line_ends(fitz.PDF_ANNOT_LE_DIAMOND, fitz.PDF_ANNOT_LE_CIRCLE)
|
| 908 |
annot11.update()
|
| 909 |
pFlagDF=1
|
|
|
|
| 911 |
annot1 = page.add_polyline_annot( points=shape) # 'Polygon'
|
| 912 |
annot1.set_border(width=0.2 ,dashes=[3])
|
| 913 |
annot1.set_colors(stroke=color , fill=None)
|
| 914 |
+
if len(alltxts)>0:
|
| 915 |
+
annot1.set_info(content='Perimeter='+str(perimeterr)+' m',subject='ADR Team',title=str(alltxts[contour]))
|
| 916 |
SimilarAreaDictionary['Total Perimeter'].loc[i]+=perimeterr
|
| 917 |
SimilarAreaDictionary['Perimeter'].loc[i]=perimeterr
|
| 918 |
SimilarAreaDictionary['Total Length'].loc[i]+=lengthShape
|
|
|
|
| 924 |
annot.set_border(width=0.2)
|
| 925 |
annot.set_colors(stroke=color, fill= color )
|
| 926 |
annot.set_opacity(0.5)
|
| 927 |
+
if len(alltxts)>0:
|
| 928 |
+
annot.set_info(content='Area='+str(areaa)+' m2' +'\n \n Length='+str(lengthShape)+' m',subject='ADR Team',title=str(alltxts[contour]))
|
| 929 |
# annot.set_line_ends(fitz.PDF_ANNOT_LE_DIAMOND, fitz.PDF_ANNOT_LE_CIRCLE)
|
| 930 |
annot.update()
|
| 931 |
|
|
|
|
| 1014 |
if passed ==0:
|
| 1015 |
if ( SimilarAreaDictionary['Rounded'].loc[i] <= areaPerimeterMax and SimilarAreaDictionary['Rounded'].loc[i] >= areaPerimeterMin) :
|
| 1016 |
if (SimilarAreaDictionary['Width'].loc[i] <=widthMax and SimilarAreaDictionary['Width'].loc[i] >= widthMin) and (SimilarAreaDictionary['Height'].loc[i] <= heightMax and SimilarAreaDictionary['Height'].loc[i] >= heightMin ) or (SimilarAreaDictionary['Width'].loc[i] <=heightMax and SimilarAreaDictionary['Width'].loc[i] >= heightMin) and (SimilarAreaDictionary['Height'].loc[i] <= widthMax and SimilarAreaDictionary['Height'].loc[i] >= widthMin ) :
|
| 1017 |
+
if len(alltxts)>0:
|
| 1018 |
+
SimilarAreaDictionary['Guess'].loc[i].append(str(alltxts[contour]))
|
| 1019 |
for t in texts:
|
| 1020 |
if "GB" not in t or "RC" not in t or "PC" not in t:
|
| 1021 |
if t not in SimilarAreaDictionary['Texts'].loc[i]:
|
|
|
|
| 1042 |
annot11 = page.add_polyline_annot( points=shapee) # 'Polygon'
|
| 1043 |
annot11.set_border(width=0.2, dashes=[3])
|
| 1044 |
annot1.set_colors(stroke=color ,fill=None)
|
| 1045 |
+
if len(alltxts)>0:
|
| 1046 |
+
annot11.set_info(content='Perimeter='+str(round((p[4]-1)*ratioperim,3))+' m',subject='ADR Team',title=str(alltxts[contour]))
|
| 1047 |
# annot.set_line_ends(fitz.PDF_ANNOT_LE_DIAMOND, fitz.PDF_ANNOT_LE_CIRCLE)
|
| 1048 |
annot11.update()
|
| 1049 |
pFlagDF=1
|
|
|
|
| 1051 |
annot1 = page.add_polyline_annot( points=shape) # 'Polygon'
|
| 1052 |
annot1.set_border(width=0.2 ,dashes=[3])
|
| 1053 |
annot1.set_colors(stroke=color ,fill=None)
|
| 1054 |
+
if len(alltxts)>0:
|
| 1055 |
+
annot1.set_info(content='Perimeter='+str(perimeterr)+' m',subject='ADR Team',title=str(alltxts[contour]))
|
| 1056 |
SimilarAreaDictionary['Total Perimeter'].loc[i]+=perimeterr
|
| 1057 |
SimilarAreaDictionary['Perimeter'].loc[i]=perimeterr
|
| 1058 |
SimilarAreaDictionary['Total Length'].loc[i]+=lengthShape
|
|
|
|
| 1064 |
annot.set_border(width=0.2)
|
| 1065 |
annot.set_colors(stroke=color, fill= color )
|
| 1066 |
annot.set_opacity(0.5)
|
| 1067 |
+
if len(alltxts)>0:
|
| 1068 |
+
annot.set_info(content='Area='+str(areaa)+' m2' +'\n \n Length='+str(lengthShape)+' m',subject='ADR Team',title=str(alltxts[contour]))
|
| 1069 |
# annot.set_line_ends(fitz.PDF_ANNOT_LE_DIAMOND, fitz.PDF_ANNOT_LE_CIRCLE)
|
| 1070 |
annot.update()
|
| 1071 |
|
|
|
|
| 1112 |
for annot in page.annots():
|
| 1113 |
list1.loc[len(list1)] =annot.info
|
| 1114 |
|
| 1115 |
+
gc,spreadsheet_service,spreadsheetId, spreadsheet_url , namepathArr=google_sheet_Legend.legendGoogleSheets(SimilarAreaDictionary , path,pdfpath)
|
|
|
|
| 1116 |
return imgPerimeter1,image_new1,SimilarAreaDictionary, colorsUsed , spreadsheet_url , spreadsheetId , list1 , pdflink , areas_Perimeters , namepathArr
|
| 1117 |
|
| 1118 |
######################################################
|
|
|
|
| 1131 |
perimstodelete=[]
|
| 1132 |
|
| 1133 |
dbxTeam=tsadropboxretrieval.ADR_Access_DropboxTeam('user')
|
| 1134 |
+
# print('pathhhhh',dbPath+path)
|
| 1135 |
md, res =dbxTeam.files_download(path= dbPath+path)
|
| 1136 |
data = res.content
|
| 1137 |
doc=fitz.open("pdf", data)
|
|
|
|
| 1140 |
for page in doc:
|
| 1141 |
for annot in page.annots():
|
| 1142 |
list2.loc[len(list2)] =annot.info
|
| 1143 |
+
# print(list1)
|
| 1144 |
deletedrows=pd.concat([list1,list2]).drop_duplicates(keep=False)
|
| 1145 |
|
| 1146 |
print(deletedrows,len(deletedrows))
|
|
|
|
| 1152 |
else:
|
| 1153 |
flag=0
|
| 1154 |
return deletedrows
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1155 |
|
| 1156 |
+
#######################################################
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|