Marthee commited on
Commit
154e666
·
1 Parent(s): c56393f

Upload 5 files

Browse files
Files changed (5) hide show
  1. db.py +275 -0
  2. main.py +337 -0
  3. pilecaps_adr.py +1555 -0
  4. pixelconversion.py +102 -0
  5. tameem3_2.py +659 -0
db.py ADDED
@@ -0,0 +1,275 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """dropbox.ipynb
3
+
4
+ Automatically generated by Colaboratory.
5
+
6
+ Original file is located at
7
+ https://colab.research.google.com/drive/11JdwIfblSKRelJJa7rllER8HwbSl_0Nu
8
+ """
9
+
10
+
11
+ import dropbox
12
+ import dropbox.exceptions as AuthError
13
+ import cv2
14
+ import pandas as pd
15
+ import os
16
+ import fitz
17
+
18
+ """### Lists of project names, parts, sections --
19
+ *Will get from MC*
20
+ """
21
+
22
+ prjname1=['2340 United Living Low Rise Building','2341 Bouygues-Cotswold','2342 GF Tomlinson - Hardingstone Primary School']
23
+ prjname1parts=['Block O Pumphouse','Hawthorn','Ling','Red Oak']
24
+ prjname2parts=['Block B','Block G']
25
+
26
+ prjname1sec1=['1.0 Substructure','5.1 Sanitary','8.2 Roads, Paths, Pavings','8.4 Fencing, Railing, Walls','8.5 External Fixtures','8.6 External Drainage','8.7 External Services','8.8 Minor Buildings']
27
+ prjname1sec2=['1.0 Substructure','2.1 Frames','2.3 Roof','2.4 Stairs','2.5 External Walls','2.6 External Openings','2.7 Internal Walls','2.8 Internal Openings','3.1 Wall Finishes','3.2 Floor Finishes','3.3 Ceiling Finishes','4.0 Fittings, Furnishings and Equipments','7.0 Works to exisitng buildings','8.1 Site Preparation Works','8.2 Roads, Paths, Pavings','8.3 Soft Landscaping','8.5 External Fixtures','8.6 External Drainage','8.7 External Services','8.8 Minor Buildings']
28
+ prjname1sec3=['1.0 Substructure','2.3 Roof','2.4 Stairs','2.5 External Walls','2.6 External Openings','2.7 Internal Walls','3.1 Wall Finishes','3.2 Floor Finishes','3.3 Ceiling Finishes', '4.0 Fittings, Furnishings and Equipments','7.0 Works to existing buildings','8.1 Site Preparation Works','8.2 Roads, Paths, Pavings','8.3 Soft Landscaping','8.5 External Fixtures','8.6 External Drainage']
29
+ prjname1sec4=['1.0 Substructure','2.3 Roof','2.4 Stairs','2.5 External Walls','2.6 External Openings','2.7 Internal Walls','3.1 Wall Finishes','3.2 Floor Finishes','3.3 Ceiling Finishes', '4.0 Fittings, Furnishings and Equipments','7.0 Works to existing buildings','8.1 Site Preparation Works','8.2 Roads, Paths, Pavings','8.3 Soft Landscaping','8.5 External Fixtures','8.6 External Drainage']
30
+ prj1secs=[prjname1sec1,prjname1sec2,prjname1sec3,prjname1sec4]
31
+ prjname2parts=['Block B','Block G']
32
+ prjname2sec=['3.3 Ceiling Finishes']
33
+ prjname2sec2=['3.3 Ceiling Finishes']
34
+ prj2secs=[prjname2sec,prjname2sec2]
35
+ prjname3parts=['Community Center building','External Works','Primary School']
36
+ prjname3sec1=['1.0 Substructure','2.3 Roof','3.1 Wall Finishes','3.2 Floor Finishes','3.3 Ceiling Finishes','4.0 Fittings, Furnishings and Equipments','5.1 Sanitary']
37
+ prjname3sec2=['8.1 Site Preparation Works','8.4 Fencing, Railing, Walls','8.5 External Fixtures', ' 8.6 External Drainage']
38
+ prjname3sec3=['1.0 Substructure','2.3 Roof','2.4 Stairs','3.2 Floor Finishes','3.3 Ceiling Finishes','4.0 Fittings, Furnishings and Equipments','5.1 Sanitary']
39
+ prj3secs=[prjname3sec1,prjname3sec2,prjname3sec3]
40
+
41
+ """### Main Dropbox Functions :connect - list- download- upload"""
42
+
43
+ access_token='sl.BiJ1Bte91KheyVoQI95qEQs9fVRR9Chq7U6RBtu73oJPWSrCaMUiNhRjwRzcCHbK4OrQsUTh9hPCJDJ5Ht7KASbAp-RffAqzZLIFMu6ZAHoWNygK2dShvKwznFF4eHGgp4AqD2RG'
44
+ ###################################################################################################################
45
+ def dropbox_connect():
46
+ """Create a connection to Dropbox."""
47
+ print('connecy')
48
+ try:
49
+ # print('ayhaga')
50
+ dbx = dropbox.Dropbox(
51
+ app_key='67w6ibpa9d2b60x',
52
+ app_secret='d3ecz8g1604fu04',
53
+ oauth2_refresh_token = 'Oc-2umxnIFsAAAAAAAAAAXQlSUH2EutbUiUa-cZE-iVhe96p4qHLAE2J2ZZ8NqjW',
54
+
55
+ )
56
+ # dbx=dropbox.Dropbox(access_token)
57
+
58
+ except AuthError as e:
59
+ print('Error connecting to Dropbox with access token: ' + str(e))
60
+ return dbx
61
+
62
+
63
+ ################################################################################################################
64
+ def dropbox_list_files(path):
65
+ """Return a Pandas dataframe of files in a given Dropbox folder path in the Apps directory.
66
+ """
67
+
68
+ dbx = dropbox_connect()
69
+
70
+ try:
71
+ files = dbx.files_list_folder(path).entries
72
+ files_list = []
73
+ for file in files:
74
+ if isinstance(file, dropbox.files.FileMetadata):
75
+ metadata = {
76
+ 'name': file.name,
77
+ 'path_display': file.path_display,
78
+ 'client_modified': file.client_modified,
79
+ 'server_modified': file.server_modified
80
+ }
81
+ files_list.append(metadata)
82
+
83
+ df = pd.DataFrame.from_records(files_list)
84
+ return df.sort_values(by='server_modified', ascending=False)
85
+
86
+ except Exception as e:
87
+ print('Error getting list of files from Dropbox: ' + str(e))
88
+
89
+ #####################################################################################################################
90
+
91
+ def dropbox_download_file(dropbox_file_path, local_file_path):
92
+ """Download a file from Dropbox to the local machine."""
93
+
94
+ try:
95
+ dbx = dropbox_connect()
96
+
97
+ with open(local_file_path, 'wb') as f:
98
+ metadata, result = dbx.files_download(path=dropbox_file_path)
99
+ f.write(result.content)
100
+ except Exception as e:
101
+
102
+ print('Error downloading file from Dropbox: ' + str(e))
103
+
104
+
105
+
106
+ #########################################################################################################################
107
+ def dropbox_shareableLink(path):
108
+ dbx= dropbox_connect()
109
+ shared_link_metadata = dbx.sharing_create_shared_link_with_settings(path)
110
+ return shared_link_metadata.url
111
+
112
+ #########################################################################################################################
113
+
114
+ def dropbox_upload_file( doc, pdfname, pdfpath,flag=0):
115
+ try:
116
+ dbx = dropbox_connect()
117
+ path= pdfpath + pdfname
118
+ print('pathindb:',path)
119
+ if flag==0:
120
+ meta=dbx.files_upload(doc.write(),path,mode=dropbox.files.WriteMode("overwrite"))
121
+ elif flag==1:
122
+ perm = int( # permissions bit flags
123
+ fitz.PDF_PERM_ACCESSIBILITY # always use this
124
+ | fitz.PDF_PERM_PRINT # permit printing
125
+ )
126
+ encrypt = fitz.PDF_ENCRYPT_AES_256 # strongest algorithm
127
+ meta=dbx.files_upload( doc.write() ,path,mode=dropbox.files.WriteMode("overwrite"))
128
+ try:
129
+ shared_link_metadata = dbx.sharing_create_shared_link_with_settings(path)
130
+ except:
131
+ shared_link_metadata=dbx.sharing_create_shared_link(path)
132
+ print( shared_link_metadata.url)
133
+ return shared_link_metadata.url
134
+ except Exception as e:
135
+ print('Error uploading file to Dropbox: ' + str(e))
136
+
137
+
138
+ #########################################################################################################################
139
+ """### Create Dictionaries (relation between values)"""
140
+ def createDictionaries():
141
+ projectsdictionary={} # prj name: parts
142
+ sectionsdict={} #each prj part:sections
143
+ #allprj parts
144
+ parts=[prjname1parts,prjname2parts,prjname3parts]
145
+ #allprjsections
146
+ sections=[prj1secs,prj2secs,prj3secs]
147
+
148
+ for i in range(len(prjname1)):
149
+ projectsdictionary.update({prjname1[i]:parts[i]})
150
+ for j in range(len(parts[i]) ):
151
+ sectionsdict.update({parts[i][j]:sections[i][j]})
152
+ return projectsdictionary, sectionsdict , parts
153
+
154
+
155
+ """### Create prj from scratch or prj name with all subfolders in it"""
156
+ def create_folder(projectsdictionary={},sectionsdict={}):
157
+ dbx = dropbox_connect()
158
+ projectsdictionary, sectionsdict , parts= createDictionaries()
159
+ try:
160
+ df1,df2=dropbox_list_files('')
161
+ print(df1,df2)
162
+ if (len(df2)>0):
163
+ if list(df2['name'])==prjname1:
164
+ return projectsdictionary, sectionsdict , parts
165
+ elif list(df2['name'])!=prjname1:
166
+ if len(projectsdictionary)==0 and len(sectionsdict)==0:
167
+ print(len(projectsdictionary))
168
+
169
+ else:
170
+ names=[]
171
+ secondnames=[]
172
+ for item in projectsdictionary.items():
173
+ for secondItem in item[1]:
174
+ name='/'+item[0]
175
+ secondname='/'+secondItem
176
+ name+=secondname
177
+ names.append(name)
178
+ for item1 in sectionsdict.items():
179
+ for ii in item1[1]:
180
+ if secondItem== item1[0]:
181
+ final =name+'/'+ii
182
+ print(final)
183
+ dbx.files_create_folder(path=final)
184
+ except Exception as e:
185
+ print('eeeeeerorrrrrrrrrr',e)
186
+ return projectsdictionary, sectionsdict , parts
187
+
188
+ def dropbox_list_files(path):
189
+ """Return a Pandas dataframe of files in a given Dropbox folder path in the Apps directory.
190
+ """
191
+
192
+ dbx = dropbox_connect()
193
+
194
+ try:
195
+ files = dbx.files_list_folder(path).entries
196
+ files_list = []
197
+ folders_list=[]
198
+ for file in files:
199
+ if isinstance(file, dropbox.files.FileMetadata):
200
+
201
+ metadata = {
202
+ 'name': file.name,
203
+ 'path_display': file.path_display,
204
+ # 'client_modified': file.client_modified,
205
+ # 'server_modified': file.server_modified
206
+ }
207
+ files_list.append(metadata)
208
+ else:#folder
209
+ metadata = {
210
+ 'name': file.name,
211
+ 'path_display': file.path_display,
212
+ }
213
+ folders_list.append(metadata)
214
+ df = pd.DataFrame.from_records(files_list)
215
+ df2 = pd.DataFrame.from_records(folders_list)
216
+ return df , df2
217
+
218
+ except Exception as e:
219
+ print('Error getting list of files from Dropbox: ' + str(e))
220
+
221
+ def prjNameCheckandCreate(projectsdictionary, sectionsdict):
222
+ df1,df2=dropbox_list_files('')
223
+
224
+ if len(df2)!=0:
225
+ df2Values=list(df2['name'].values)
226
+ difference = list(set(prjname1) - set(df2Values))
227
+ if len(difference)==0:
228
+ print(df2Values)
229
+ else:
230
+ newdict={}
231
+ newsecdict={}
232
+ print('else')
233
+ for i in difference:
234
+ newdict.update({i:projectsdictionary.get(i)})
235
+ for key,value in newdict.items():
236
+ for ii in value:
237
+ newsecdict.update({ii:sectionsdict.get(ii)})
238
+ create_folder(projectsdictionary=newdict,sectionsdict=newsecdict)
239
+ return df2
240
+
241
+ def prjPartSectionCheckandCreate():
242
+ projectsdictionary, sectionsdict , parts=create_folder()
243
+ df2= prjNameCheckandCreate(projectsdictionary, sectionsdict )
244
+ for i in range(len(df2['path_display'].values)):
245
+ #look for the same path
246
+ df11,df21=dropbox_list_files(df2['path_display'].values[i])
247
+
248
+ if len(df21)!=0:
249
+ df2Values=list(df21['name'].values)
250
+ difference = list(set(parts[i]) - set(df2Values))
251
+ if len(difference)==0:
252
+ print('samee')
253
+ else:
254
+ for j in difference:
255
+ dbx = dropbox_connect()
256
+ dbx.files_create_folder_v2(df2['path_display'].values[i]+'/'+j) #nopart - create part folder
257
+ for k in sectionsdict.get(j):
258
+ dbx.files_create_folder(df2['path_display'].values[i]+'/'+j+'/'+k) #create sections folders
259
+ #check if section is missing and get prj name and part for path
260
+ for arr in df2Values:
261
+ df111,df211=dropbox_list_files(df2['path_display'].values[i]+'/'+arr)
262
+ if len(df211)!=0:
263
+ df211Values=list(df211['name'].values)
264
+ for key,value in sectionsdict.items():
265
+ if key== arr:
266
+ if value == df211Values:
267
+ print('s')
268
+ else:
269
+ difference1 = list(set(value) - set(df211Values))
270
+ dbx = dropbox_connect()
271
+ for d in difference1:
272
+ print(arr,d)
273
+ dbx.files_create_folder_v2(df2['path_display'].values[i]+'/'+arr+'/'+d) #no section - create section folder
274
+
275
+
main.py ADDED
@@ -0,0 +1,337 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import print_function
2
+ from flask import Flask, render_template,request,flash , json, url_for,g , redirect , jsonify
3
+ import os
4
+ import json
5
+ import fitz
6
+ from PIL import Image
7
+ import cv2
8
+ import numpy as np
9
+ import sys
10
+ import pilecaps_adr
11
+ import base64
12
+ from db import dropbox_connect
13
+ import db
14
+ import cv2
15
+ import pandas as pd
16
+ import ast
17
+ import time
18
+ from io import BytesIO
19
+ from flask import Flask, Response
20
+ from werkzeug.wsgi import wrap_file
21
+ import tameem3_2
22
+ import pypdfium2 as pdfium
23
+ import pixelconversion
24
+
25
+ app = Flask(__name__)
26
+
27
+ out_file = open("static/data/myfile.json", "w")
28
+
29
+ #retrieves project parts
30
+ @app.route('/getmethod/<jsdata>',methods=['GET','POST'])
31
+ def get_javascript_data(jsdata):
32
+ #get project from the first dropdown
33
+ print(jsdata)
34
+ matches=update_dropdown(jsdata) #list f of projects
35
+ print(matches)
36
+ return jsonify (list(matches))
37
+ #---------------------------------------------------------------
38
+
39
+ #get projects of 'project name'
40
+ def update_dropdown(section):
41
+ if section.startswith('1.0'):
42
+ plans_inrepo=os.listdir('dropbox_plans/1.0')
43
+ elif section.startswith('3.2'):
44
+ plans_inrepo=os.listdir('dropbox_plans/3.2')
45
+ elif section.startswith('2.2'):
46
+ plans_inrepo=os.listdir('dropbox_plans/2.2')
47
+ else:
48
+ return ''
49
+ #if 'foundation' in radio and project in plans_inrepo
50
+ matches=[]
51
+ if section==None:
52
+ print('no proj')
53
+ else:
54
+ for x in plans_inrepo:
55
+ matches.append(x)
56
+ print(matches)
57
+ return matches
58
+ #_________________________________________________________________________________________________________________________
59
+ #_________________________________________________________________________________________________________________________
60
+ #NOT IMP NOW
61
+ #retrieve all info of elements after clicking 'measure' button
62
+ @app.route("/",methods=["GET", "POST"])
63
+ def getInfotoMeasure():
64
+ # db.create_folder()
65
+ mylist=[1,2,3,4]
66
+ return render_template("proposed-GUI.html",mylist=mylist)
67
+ #_________________________________________________________________________________________________________________________
68
+ #_________________________________________________________________________________________________________________________
69
+ #Hex value to RGB value
70
+ def hexRGB(color):
71
+ color=color.lstrip('#')
72
+ color= tuple(int(color[i:i+2], 16) for i in (0, 2, 4)) #hex to rgb
73
+ color=list(color) #rgb to bgr
74
+ return color
75
+ #_________________________________________________________________________________________________________________________
76
+ #_________________________________________________________________________________________________________________________
77
+
78
+ #MAIN FUNCTION -- calls python code to measure the chosen plan from the interface
79
+ @app.route('/projecttomeasure/<jsdata>',methods=["GET","POST"])
80
+ def measureproject(jsdata):
81
+ colorarr=[]
82
+ result = json.loads(jsdata)
83
+ pdfpath='/'
84
+ ################################# -1.0- #################################
85
+ for word in result[5]:
86
+ pdfpath+=word +'/'
87
+ arr=[]
88
+
89
+ if result[5][2].startswith('1.0'): #section value - 1.0 substructure- pile caps
90
+ img = plan2img('dropbox_plans/1.0/'+str(result[0]) )
91
+
92
+ for item in result[2]:
93
+ item1 ='#'+item
94
+ c=hexRGB(item1)
95
+ colorarr.append(c)
96
+ imgPerimeter1,image_new1,SimilarAreaDictionary , colorsUsed,spreadsheet_url, spreadsheetId,list1, pdflink, areas_Perimeters, namepathArr =pilecaps_adr.drawAllContours(img,int(result[1]),colorarr, result[3], result[4],'area', result[0],pdfpath)
97
+ _, buffer = cv2.imencode('.png', image_new1)
98
+ arr=[base64.b64encode(buffer).decode('utf-8'),SimilarAreaDictionary.to_dict(),spreadsheet_url , spreadsheetId,colorsUsed,list1.to_dict(), pdflink, areas_Perimeters, namepathArr]
99
+ ################################# -3.2- #################################
100
+ elif result[5][2].startswith('3.2'): #section value - 3.2 floor finishes
101
+ outputimg, df_merged , dropboxpdflink , spreadsheetId, spreadsheet_url , list1 = tameem3_2.mainFunction(str(result[0]),result[3], result[4] , pdfpath) #pass arearatio,perimratio
102
+ _, buffer = cv2.imencode('.png', outputimg)
103
+ arr=[ base64.b64encode(buffer).decode('utf-8') , df_merged.to_dict() , dropboxpdflink , spreadsheetId, spreadsheet_url , list1.to_dict()]
104
+ ################################# -2.2- #################################
105
+ # elif result[5][2].startswith('2.2'): #section value - 2.2 rc slabs
106
+ #add here python code
107
+ #
108
+ #link (add this to ur code)
109
+ # pdflink= db.dropbox_upload_file(doc=doc,pdfname=path,pdfpath=pdfpath)
110
+
111
+ # gc,spreadsheet_service,spreadsheetId, spreadsheet_url , namepathArr= pilecaps_adr.legendGoogleSheets(df,plan ,pdfpath)
112
+
113
+
114
+ #output img
115
+ # _, buffer = cv2.imencode('.png', outputimg)
116
+
117
+ #let first result to be the img
118
+ #return results in arr=[base64.b64encode(buffer).decode('utf-8'),pdflink,spreadsheetId,spreadsheet_url] like the previous sections in the above lines
119
+ return jsonify(arr)
120
+ #_________________________________________________________________________________________________________________________
121
+ #_________________________________________________________________________________________________________________________
122
+
123
+ #pdf to img
124
+ def plan2img(path):
125
+
126
+ doc = fitz.open(path)
127
+ for page in doc:
128
+ pix = page.get_pixmap(dpi=200) # render page to an image
129
+ pl=Image.frombytes('RGB', [pix.width,pix.height],pix.samples)
130
+ img=np.array(pl)
131
+ print(img.shape)
132
+ img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
133
+ return img
134
+ #_________________________________________________________________________________________________________________________
135
+ #_________________________________________________________________________________________________________________________
136
+
137
+ #not used in 1.0
138
+ def convert2img(path):
139
+ pdf = pdfium.PdfDocument(path)
140
+ page = pdf.get_page(0)
141
+ pil_image = page.render().to_pil()
142
+ pl1=np.array(pil_image)
143
+ img = cv2.cvtColor(pl1, cv2.COLOR_RGB2BGR)
144
+ return img
145
+ #_________________________________________________________________________________________________________________________
146
+ #_________________________________________________________________________________________________________________________
147
+
148
+ #User-made MC-T NAME - in the second part of the interface
149
+ @app.route("/mctnametoGoogleSheet/<jsdata>",methods=["GET", "POST"])
150
+ def sendmctnametoLegend(jsdata):
151
+ result = json.loads(jsdata)
152
+ print(result)
153
+ summaryid,guessednamesfinal=pilecaps_adr.mapnametoLegend(result)
154
+ allreturns=[summaryid,guessednamesfinal]
155
+ return jsonify(allreturns)
156
+ #_________________________________________________________________________________________________________________________
157
+ #_________________________________________________________________________________________________________________________
158
+ #NOT USED (pixel conversion instead)
159
+ def calcRef(img):
160
+ blk = np.ones(img.shape, dtype="uint8") * [[[np.uint8(0), np.uint8(0), np.uint8(0)]]]
161
+
162
+ start_point = (50, 100)
163
+ end_point = (120, 200)
164
+ color = (255, 255, 255) # white BGR
165
+ thickness = -1 # Thickness of -1 will fill the entire shape
166
+
167
+ blk = cv2.rectangle(blk, start_point, end_point, color, thickness)
168
+
169
+ blk = cv2.cvtColor(blk, cv2.COLOR_BGR2GRAY)
170
+
171
+ contourzz, hierarchy = cv2.findContours(image=blk, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_NONE)
172
+ for i, cnt3 in enumerate(contourzz):
173
+ M = cv2.moments(cnt3)
174
+ if M['m00'] != 0.0:
175
+ x2 = int(M['m10']/M['m00'])
176
+ y2 = int(M['m01']/M['m00'])
177
+ area = cv2.contourArea(cnt3)
178
+ perimeter = cv2.arcLength(cnt3, True)
179
+ return area,perimeter , blk
180
+
181
+ #NOT USED (pixel conversion instead)
182
+ def modifyingcalcRefDynamic(img):
183
+ imgcopy = img.copy()
184
+
185
+ blk = np.ones(img.shape, dtype="uint8") * [[[np.uint8(0), np.uint8(0), np.uint8(0)]]]
186
+
187
+ x = 50
188
+ y = 100
189
+ xD = int(img.shape[1] * 0.10)
190
+ yD = int(img.shape[0] * 0.10)
191
+ start_point = (x, y)
192
+ end_point = (x+xD, y+yD)
193
+ blue = (255, 0, 0) # BGR
194
+ white = (255, 255, 255) # BGR
195
+ thickness = -1 # Thickness of -1 will fill the entire shape
196
+
197
+ imgcopy = cv2.rectangle(imgcopy, start_point, end_point, blue, thickness)
198
+ blk = cv2.rectangle(blk, start_point, end_point, white, thickness)
199
+
200
+ blk = cv2.cvtColor(blk, cv2.COLOR_BGR2GRAY)
201
+
202
+ contourzz, hierarchy = cv2.findContours(image=blk, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_NONE)
203
+ for i, cnt3 in enumerate(contourzz):
204
+ M = cv2.moments(cnt3)
205
+ if M['m00'] != 0.0:
206
+ x2 = int(M['m10']/M['m00'])
207
+ y2 = int(M['m01']/M['m00'])
208
+ area = cv2.contourArea(cnt3)
209
+ perimeter = cv2.arcLength(cnt3, True)
210
+ return area, perimeter, blk , imgcopy
211
+ #_________________________________________________________________________________________________________________________
212
+ #_________________________________________________________________________________________________________________________
213
+
214
+ #PIXEL CONVERSION METHOD -- SAVES DOC ON DROPBOX TO BE MEASURED BY USER
215
+ @app.route("/pixelimg/<jsdata>",methods=["GET", "POST"])
216
+ def getimg(jsdata):
217
+ db.create_folder()
218
+ print(jsdata)
219
+ jsdata=eval(jsdata)
220
+ if jsdata[2].startswith('1.0'):
221
+ doc = fitz.open('dropbox_plans/1.0/'+str(jsdata[3]) )
222
+ elif jsdata[2].startswith('3.2'):
223
+ doc = fitz.open('dropbox_plans/3.2/'+str(jsdata[3]) )
224
+ elif jsdata[2].startswith('2.2'):
225
+ doc = fitz.open('dropbox_plans/2.2/'+str(jsdata[3]) )
226
+ else:
227
+ return ''
228
+ for page in doc:
229
+
230
+ pix = page.get_pixmap() # render page to an image
231
+ pl=Image.frombytes('RGB', [pix.width,pix.height],pix.samples)
232
+ img=np.array(pl)
233
+ print(img.shape)
234
+ img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
235
+ if jsdata[2].startswith('1.0'):
236
+ doc=pixelconversion.openDrawPDF(path='dropbox_plans/1.0/'+str(jsdata[3]))
237
+ elif jsdata[2].startswith('3.2'):
238
+ doc=pixelconversion.openDrawPDF(path='dropbox_plans/3.2/'+str(jsdata[3]))
239
+ elif jsdata[2].startswith('2.2'):
240
+ doc=pixelconversion.openDrawPDF(path='dropbox_plans/2.2/'+str(jsdata[3]))
241
+ pdfpath='/'+jsdata[0]+'/'+jsdata[1]+'/'+jsdata[2]+'/'+'Scale Document' +'/'
242
+ dburl=db.dropbox_upload_file(doc=doc,pdfname=str(jsdata[3]) ,pdfpath=pdfpath,flag=1)
243
+ areaPixel,perimeterPixel= pixelconversion.getAreaPerimeter(pdfpath, str(jsdata[3]))
244
+
245
+ print(areaPixel,perimeterPixel)
246
+ outputs=[areaPixel,perimeterPixel , dburl]
247
+ return jsonify(outputs)
248
+
249
+ #_________________________________________________________________________________________________________________________
250
+ #_________________________________________________________________________________________________________________________
251
+ #DELETE MARKUPS (for comparison)
252
+ @app.route('/_submission',methods=["GET", "POST"])
253
+ def getnewlegend():
254
+ pdfpth=''
255
+ list1 = request.args.get('dict1')
256
+ path = request.args.get('path')
257
+ spreadsheetId =request.args.get('spreadsheetId')
258
+ pdfpathpath=request.args.get('pdfpathpath')
259
+ pdfname=request.args.get('pdfname')
260
+ for word in eval(pdfpathpath):
261
+ pdfpth+='/' +word
262
+ pdfpth+='/'
263
+ deletedrows1=pilecaps_adr.deletemarkups(list1=list1,pdfpath=pdfpth,path=path)
264
+ print(deletedrows1)
265
+ arr1=[deletedrows1.to_dict()]
266
+ return jsonify(arr1)
267
+ #---------------------------------------------------------------------------
268
+ #if user wishes to delete
269
+ @app.route('/deletemarkupsroute',methods=["GET", "POST"])
270
+ def dltmarkupslegend():
271
+ pdfpth=''
272
+ SimilarAreaDictionary = request.args.get('dict')
273
+ deletedrows = request.args.get('deletedrows')
274
+ path = request.args.get('path')
275
+ spreadsheetId =request.args.get('spreadsheetId')
276
+ areaPermArr=request.args.get('areaPermArr')
277
+ section=request.args.get('section')
278
+ pdfpathpath=request.args.get('pdfpathpath')
279
+ for word in eval(pdfpathpath):
280
+ pdfpth+='/' +word
281
+ pdfpth+='/'
282
+ myDict=eval(deletedrows)
283
+ deletedrows=pd.DataFrame(myDict)
284
+
285
+ if section.startswith('1.0'):
286
+ newlgnd=pilecaps_adr.deletefromlegend(deletedrows=deletedrows,SimilarAreaDictionarycopy=SimilarAreaDictionary, section=section,areaPermArr=areaPermArr)
287
+ else:
288
+ newlgnd=pilecaps_adr.deletefromlegend(deletedrows=deletedrows,SimilarAreaDictionarycopy=SimilarAreaDictionary, section=section)
289
+ try:
290
+ newlgnd1=pilecaps_adr.legendGoogleSheets(SimilarAreaDictionary=newlgnd,path=path,spreadsheetId=spreadsheetId ,pdfpath=pdfpth) #new legend
291
+ except:
292
+ print("An exception occurred")
293
+ time.sleep(10)
294
+ newlgnd1=pilecaps_adr.legendGoogleSheets(SimilarAreaDictionary=newlgnd,path=path,spreadsheetId=spreadsheetId,pdfpath=pdfpth)
295
+
296
+ return jsonify('donee')
297
+
298
+ #_________________________________________________________________________________________________________________________
299
+ #_________________________________________________________________________________________________________________________
300
+ #get pdf dropbox url after measurement is done
301
+ @app.route('/getdropboxurl/<jsdata>',methods=["GET", "POST"])
302
+ def calldropboxurl(jsdata):
303
+ pdfpth=''
304
+ for word in eval(jsdata):
305
+ pdfpth+='/' +word
306
+ print(pdfpth)
307
+ pdfurl=db.dropbox_shareableLink(pdfpth)
308
+ return jsonify(pdfurl)
309
+
310
+ #_________________________________________________________________________________________________________________________
311
+ #_________________________________________________________________________________________________________________________
312
+ #Google sheet links
313
+ @app.route('/getdrivelinks/<jsdata>',methods=["GET", "POST"])
314
+ def getlinkscreated(jsdata):
315
+ spreadsheet_service,drive_service,gc= pilecaps_adr.authorizeLegend()
316
+ ids=gc.spreadsheet_ids()
317
+ titles=gc.spreadsheet_titles()
318
+ allpaths=[]
319
+ # for title in titles:
320
+ for i in range(len(titles)):
321
+ ws=gc.open(titles[i])
322
+ allpaths.append([titles[i], ws.get_developer_metadata('path')[0].value , drive_service.files().get(fileId=ids[i],fields="createdTime, modifiedTime").execute() ,ids[i] ])
323
+
324
+ return jsonify(allpaths)
325
+
326
+ #_________________________________________________________________________________________________________________________
327
+ #_________________________________________________________________________________________________________________________
328
+
329
+ #_________________________________________________________________________________________________________________________
330
+ #_________________________________________________________________________________________________________________________
331
+
332
+ #_________________________________________________________________________________________________________________________
333
+ #_________________________________________________________________________________________________________________________
334
+ if __name__ == "__main__":
335
+ app.run(debug=True)
336
+
337
+
pilecaps_adr.py ADDED
@@ -0,0 +1,1555 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """Copy of XOR- ROI from plan-PileCaps-ADR.ipynb
3
+
4
+ Automatically generated by Colaboratory.
5
+
6
+ Original file is located at
7
+ https://colab.research.google.com/drive/16RHtRae7VU_fqHMAjOUL4ET5slEFo3pf
8
+ """
9
+
10
+ # pip install pdf-annotate
11
+
12
+ # pip install pdf-annotate
13
+
14
+ #pip install pdf2image
15
+
16
+ #!pip install -q gradio
17
+
18
+ #pip install pygsheets
19
+
20
+ # !apt-get install poppler-utils
21
+
22
+ import numpy as np
23
+ import cv2
24
+ #from google.colab.patches import cv2_imshow
25
+ from matplotlib import pyplot as plt
26
+ #from pdf2image import convert_from_path
27
+
28
+ import math
29
+
30
+ import pandas as pd
31
+ import random
32
+ # import imutils
33
+ # from imutils import contours
34
+ import colorsys
35
+ from PIL import Image , ImageDraw, ImageFont , ImageColor
36
+ import numpy as np
37
+ #import gradio as gr
38
+
39
+ # from __future__ import print_function
40
+ from googleapiclient.discovery import build
41
+ from google.oauth2 import service_account
42
+ import pygsheets
43
+ import re
44
+ import pandas
45
+ import fitz
46
+ import json
47
+ import db
48
+ import ast
49
+
50
+ def detectCircles(imgOriginal ):
51
+ im=imgOriginal.copy()
52
+ imgGry1 = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
53
+ kernel=np.ones((3,3),np.uint8)
54
+ er1=cv2.erode(imgGry1,kernel, iterations=2)
55
+
56
+ er1=cv2.dilate(er1,kernel, iterations=1)
57
+ gray_blurred = cv2.blur(er1, (3,3 ))
58
+ # Apply Hough transform on the blurred image.
59
+ # min distance between circles, Upper threshold for the internal Canny edge detector.
60
+ detected_circles = cv2.HoughCircles( gray_blurred, cv2.HOUGH_GRADIENT, 1, 50, param1= 550,
61
+ param2 =21, minRadius = 20, maxRadius = 40) #18 param2
62
+
63
+ # Draw circles that are detected.
64
+ if detected_circles is not None:
65
+ # Convert the circle parameters a, b and r to integers.
66
+ detected_circles = np.uint16(np.around(detected_circles))
67
+ detected_circles = np.round(detected_circles[0, :]).astype("int")
68
+ #DRAW CIRCLES
69
+ for (x, y, r) in detected_circles:
70
+ cv2.circle(im, (x, y), r, (255, 255, 255), 5)
71
+ im=cv2.medianBlur(im,1)
72
+ print('circles')
73
+ # cv2_imshow(im)
74
+ return im
75
+
76
+ def detectSmallCircles(img ):
77
+ #Remove tiny TOC points that interfere with shapes
78
+ im=img.copy()
79
+ imgGry1 = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
80
+ kernel=np.ones((3,3),np.uint8)
81
+ er1=cv2.erode(imgGry1,kernel, iterations=1)
82
+ # Apply Hough transform on the blurred image.
83
+ # min distance between circles, Upper threshold for the internal Canny edge detector.
84
+ detected_circles = cv2.HoughCircles( imgGry1, cv2.HOUGH_GRADIENT, 1, 60, param1 =550,
85
+ param2 =13, minRadius = 1, maxRadius = 10) #18 param2
86
+
87
+ # Draw circles that are detected.
88
+ if detected_circles is not None:
89
+ # Convert the circle parameters a, b and r to integers.
90
+ detected_circles = np.uint16(np.around(detected_circles))
91
+ detected_circles = np.round(detected_circles[0, :]).astype("int")
92
+ #DRAW CIRCLES
93
+ for (x, y, r) in detected_circles:
94
+ cv2.circle(im, (x, y), r+1, (255, 255, 255), -1)
95
+ # cv2_imshow(im)
96
+ return im
97
+ # c=detectCircles(img)
98
+
99
+ def DashedPreprocessing(imgOriginal,imgnoSmall):
100
+ h,w=imgOriginal.shape[0:2]
101
+ #remove the gray contours from the plan
102
+ imgBW=cv2.threshold(imgnoSmall, 180, 255, cv2.THRESH_BINARY)[1]
103
+
104
+ im_copy=imgBW.copy()
105
+ im_copy1=im_copy
106
+ kernel1 = np.ones((3,5),np.uint8)
107
+ kernel2 = np.ones((9,9),np.uint8)
108
+ kernel3= np.ones((3,3),np.uint8)
109
+ imgGray=cv2.cvtColor(imgBW,cv2.COLOR_BGR2GRAY)
110
+ imgBW1=cv2.threshold(imgGray, 200, 255, cv2.THRESH_BINARY_INV)[1]
111
+
112
+ img1=cv2.erode(imgBW1, kernel1, iterations=1)
113
+ img2=cv2.dilate(img1, kernel2, iterations=3)
114
+ img3 = cv2.bitwise_and(imgBW1,img2)
115
+ img3= cv2.bitwise_not(img3)
116
+ img4 = cv2.bitwise_and(imgBW1,imgBW1,mask=img3)
117
+ img4=cv2.blur(img4,(7,7))
118
+ if h > w :
119
+ max = h
120
+ min = w
121
+ else:
122
+ max = w
123
+ min = h
124
+ return img4, imgBW, max,min
125
+
126
+ def removeDashedLines(img4, imgBW ,max,min):
127
+
128
+ imgLines= cv2.HoughLinesP(img4,1,np.pi/310,30,minLineLength=(max-min)//1.8,maxLineGap = 120) #was w-h , gap=150 0.99
129
+ #1 120
130
+
131
+ for i in range(len(imgLines)):
132
+ for x1,y1,x2,y2 in imgLines[i]:
133
+ cv2.line(imgBW,(x1,y1),(x2,y2),(0,255,0),2)
134
+
135
+ im_copy=imgBW.copy()
136
+ green=im_copy[:,:,1]
137
+ # cv2_imshow(im_copy)
138
+ return green
139
+
140
+ def removeSmallDashes(imgOriginal,green):
141
+ smalldashes=green.copy()
142
+ smalldashes=cv2.bitwise_not(smalldashes)
143
+
144
+ kernel3= np.ones((3,3),np.uint8)
145
+
146
+ img1=cv2.dilate(smalldashes, kernel3, iterations=2)
147
+ img2=cv2.erode(img1, kernel3, iterations=2)
148
+
149
+ smalldashes=cv2.medianBlur(img2,5)
150
+ smalldashes=cv2.medianBlur(smalldashes,7)
151
+ # cv2_imshow(smalldashes)
152
+ smalldashesOut=green.copy()
153
+ smalldashesOut=cv2.cvtColor(smalldashesOut,cv2.COLOR_GRAY2BGR)
154
+ imgLines= cv2.HoughLinesP(smalldashes,1,np.pi/150,27,minLineLength=10,maxLineGap = 70) #was w-h , gap=150
155
+
156
+ imgCopy=imgOriginal.copy()
157
+ for i in range(len(imgLines)):
158
+ for x1,y1,x2,y2 in imgLines[i]:
159
+ cv2.line(smalldashesOut,(x1,y1),(x2,y2),(0,255,0),2)
160
+
161
+
162
+ smalldashesOut=smalldashesOut[:,:,1]
163
+ # cv2_imshow(smalldashesOut)
164
+ for i in range(len(imgLines)):
165
+ for x1,y1,x2,y2 in imgLines[i]:
166
+ cv2.line(imgCopy,(x1,y1),(x2,y2),(0,255,0),6)
167
+
168
+ imgCopy=imgCopy[:,:,1]
169
+ # cv2_imshow(imgCopy)
170
+ return imgCopy,smalldashesOut
171
+
172
+ def euclidian_distance(point1, point2):
173
+ return sum([(point1[x] - point2[x]) ** 2 for x in range(len(point1))]) ** 0.5
174
+
175
+ def removeDashedLinesSmall(img4, imgBW ,max,min):
176
+
177
+ imgBW=cv2.cvtColor(imgBW,cv2.COLOR_GRAY2BGR)
178
+
179
+ imgLines= cv2.HoughLinesP(img4,1,np.pi/100,20,minLineLength=(max-min)//2.2,maxLineGap = 70) #2.1
180
+
181
+ for i in range(len(imgLines)):
182
+ for x1,y1,x2,y2 in imgLines[i]:
183
+ dist=euclidian_distance((x1,y1), (x2,y2))
184
+ # if dist > 1300 and dist <1450:
185
+ if dist >= (max-min)//2.1 and dist < (max-min)//1.9: #1.4
186
+ cv2.line(imgBW,(x1,y1),(x2,y2),(0,255,0),3)
187
+
188
+ im_copy=imgBW.copy()
189
+ green=im_copy[:,:,1]
190
+ # cv2_imshow(im_copy)
191
+ return green
192
+
193
+ def ConnectBeamLines(smalldashesOut):
194
+ green1=cv2.bitwise_not(smalldashesOut)
195
+ green2=smalldashesOut.copy()
196
+ green2=cv2.cvtColor(green2,cv2.COLOR_GRAY2BGR)
197
+ imgLines= cv2.HoughLinesP(green1,0.05,np.pi/250,10,minLineLength=25,maxLineGap = 20) #was w-h , gap=150 #50
198
+ for i in range(len(imgLines)):
199
+ for x1,y1,x2,y2 in imgLines[i]:
200
+ cv2.line(green2,(x1,y1),(x2,y2),(0,0,0),1)
201
+
202
+ imgLines= cv2.HoughLinesP(green1,0.3,np.pi/360,10,minLineLength=25,maxLineGap = 20) #try 180
203
+
204
+
205
+ for i in range(len(imgLines)):
206
+ for x1,y1,x2,y2 in imgLines[i]:
207
+ cv2.line(green2,(x1,y1),(x2,y2),(0,0,0),1)
208
+ # cv2_imshow(green2)
209
+ return green2
210
+
211
+ def allpreSteps(imgOriginal):
212
+ noCircles=detectCircles(imgOriginal)
213
+ imgnoSmall=detectSmallCircles(noCircles )
214
+ img4,imgBW,max,min=DashedPreprocessing(imgOriginal,imgnoSmall)
215
+ green=removeDashedLines(img4,imgBW,max,min)
216
+ imgCopy,smalldashesOut=removeSmallDashes(imgOriginal,green)
217
+ noSmallDashes=removeDashedLinesSmall(img4, smalldashesOut ,max,min)
218
+ green2=ConnectBeamLines(noSmallDashes)
219
+ # cv2_imshow(green2)
220
+ return green2
221
+
222
+ def ChangeBrightness(img,k):
223
+ imgdarker = 255 * (img/255)**k # k>1 darker , k <1 lighter
224
+ # cv2_imshow(imgdarker)
225
+ imgdarker = imgdarker.astype('uint8')
226
+ return imgdarker
227
+
228
+ def preprocessold(img,number):
229
+
230
+ # imcopy=detectCircles(img)
231
+ blurG = cv2.GaussianBlur(ChangeBrightness(img,6),(3,3),0)
232
+
233
+ imgGry = cv2.cvtColor(blurG, cv2.COLOR_BGR2GRAY)
234
+
235
+ kernel=np.ones((3,3),np.uint8)
236
+
237
+ er1=cv2.dilate(imgGry,kernel, iterations=2) #thinning
238
+
239
+ er2=cv2.erode(er1,kernel, iterations=3) #thicken
240
+ er3=cv2.dilate(er2,kernel, iterations=4)
241
+
242
+ if number == 0:
243
+ ret3, thresh = cv2.threshold(er3, 200, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
244
+ else:
245
+ ret3, thresh = cv2.threshold(er3, 220, 255, cv2.THRESH_BINARY_INV) #`140 - 141
246
+ # cv2_imshow(thresh)
247
+ return thresh
248
+ # preprocessold(img,0)
249
+
250
+ def preprocess(imgOriginal,number,green2):
251
+ #first preprocessing ( old method - black img with white shapes)
252
+ img1=preprocessold(imgOriginal,number)
253
+ kernel0=np.ones((3,3),np.uint8)
254
+ img1=cv2.dilate(img1,kernel0, iterations=3)
255
+ green3=ChangeBrightness(green2,6)
256
+ anding=cv2.bitwise_and(green3,green3,mask=img1)
257
+ anding = cv2.cvtColor(anding , cv2.COLOR_BGR2GRAY)
258
+
259
+ return anding
260
+
261
+ """# ROI (levels)
262
+ ## Detect regions with specific color and mask them
263
+ """
264
+
265
+ def hexRGB(color):
266
+ color=color.lstrip('#')
267
+
268
+ color= tuple(int(color[i:i+2], 16) for i in (0, 2, 4)) #hex to rgb
269
+ color=np.array(color) #rgb to bgr
270
+ return color
271
+ def DetectColor(img,color=0):
272
+
273
+ imgCopy=img.copy()
274
+ imgCopy=cv2.cvtColor(imgCopy,cv2.COLOR_BGR2HSV)
275
+ tol=5 #tolerance
276
+ # color=hexRGB(color)
277
+ h,s,v = cv2.cvtColor(np.uint8([[[color[2],color[1],color[0]]]]),cv2.COLOR_BGR2HSV)[0][0]
278
+
279
+ lower =np.array( [h- tol, 100, 100 ], dtype='uint8')
280
+ upper = np.array( [h + tol, 255, 255],dtype='uint8')
281
+
282
+ mask = cv2.inRange(imgCopy, lower , upper)
283
+
284
+ detectedColors = cv2.bitwise_and(imgCopy,imgCopy, mask= mask) # Bitwise-AND mask and original image
285
+
286
+ kernel=np.ones((3,3),np.uint8)
287
+ mask=cv2.dilate(mask,kernel, iterations=5)
288
+ mask=cv2.erode(mask,kernel, iterations=4)
289
+
290
+ detectedColors=cv2.dilate(detectedColors,kernel, iterations=5)
291
+ detectedColors=cv2.erode(detectedColors,kernel, iterations=4)
292
+
293
+ detectedColors=cv2.cvtColor(detectedColors,cv2.COLOR_HSV2BGR)
294
+ detectedColors=cv2.medianBlur(detectedColors,7)
295
+ # cv2_imshow(detectedColors)
296
+
297
+ return mask, detectedColors, color
298
+
299
+
300
+ def detectAllColors(img,finalColorArray):
301
+ for i in range(len(finalColorArray)):
302
+ detectedColors= DetectColor(img,finalColorArray[i])[1]
303
+ if i == 0:
304
+ allcolorsImg=cv2.bitwise_or(detectedColors,detectedColors)
305
+ else:
306
+ allcolorsImg=cv2.bitwise_or(allcolorsImg,detectedColors)
307
+ allcolorsImg= cv2.medianBlur(allcolorsImg,7)
308
+
309
+ return allcolorsImg
310
+
311
+ def colorOrder(img,finalColorArray):
312
+ newimg=img.copy()
313
+ arraycolor=[]
314
+ allcolorsImg= detectAllColors(img,finalColorArray)
315
+ allcolorsImgG= cv2.cvtColor(allcolorsImg, cv2.COLOR_BGR2GRAY)
316
+
317
+ ColoredContour, Coloredhierarchy = cv2.findContours(allcolorsImgG, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
318
+ Coloredhierarchy=Coloredhierarchy[0]
319
+ for cnt in ColoredContour :
320
+ Blackmask = np.zeros(img.shape[:2], dtype="uint8")
321
+ cv2.drawContours(Blackmask,[cnt],0,(255,255,255),20)
322
+ coloredand=cv2.bitwise_and(allcolorsImg,allcolorsImg,mask=Blackmask)
323
+
324
+ for colors in finalColorArray:
325
+ getColor=DetectColor(coloredand,colors)[1]
326
+
327
+ pil_image=Image.fromarray(getColor)
328
+ extrema = pil_image.convert("L").getextrema()
329
+ if extrema != (0, 0): # if image is not black --> has a colored mask within
330
+ arraycolor.append(colors)
331
+ break
332
+
333
+ res = []
334
+ [res.append(x) for x in arraycolor if x not in res]
335
+
336
+ return res
337
+
338
+ def getinnerColor(BlackmaskDetected,img,detectedColors,finalColorArray,num1,num2,flag,eachcolor):
339
+
340
+ countBlackMasks=0
341
+ xored=detectedColors
342
+
343
+ invertedmask=detectedColors
344
+
345
+ imgc=img.copy()
346
+ imgNewCopy=img.copy()
347
+ Blackmask = np.zeros(img.shape[:2], dtype="uint8")
348
+ for eachcolor in finalColorArray:
349
+ masked=DetectColor(detectedColors,eachcolor)[0]
350
+ pil_image=Image.fromarray(masked)
351
+ extrema = pil_image.convert("L").getextrema()
352
+ if extrema != (0, 0): # if image is not black --> has a colored mask within
353
+ cc=detectedColors.copy()
354
+ # cc1=detectedColorsB.copy()
355
+ ColoredContour, Coloredhierarchy = cv2.findContours(masked, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
356
+
357
+ for cnt in ColoredContour:
358
+
359
+ area1 = cv2.contourArea(cnt)
360
+ if (area1 > 1000 ):
361
+
362
+ x, y , width, height = cv2.boundingRect(cnt)
363
+ # cv2.rectangle(cc, (x,y ), (x+width, y+height), (255,255,255), -1)
364
+ # cv2.rectangle(Blackmask, (x,y ), (x+width, y+height), 255, -1)
365
+ #to get rid of the edge of the inner reectangles
366
+ cv2.drawContours(cc,[cnt],0,(255,255,255), 3)
367
+ cv2.drawContours(Blackmask,[cnt] ,0, (255,255,255), 3)
368
+
369
+ cv2.drawContours(cc,[cnt],0,(255,255,255), -1) # (x-5,y-5 ), (x+width, y+height),
370
+ cv2.drawContours(Blackmask,[cnt] ,0, (255,255,255), -1) #,(x,y ), (x+width, y+height)
371
+
372
+ cv2.drawContours(BlackmaskDetected,[cnt] ,0, (0,0,0), -1) #,(x,y ), (x+width, y+height)
373
+
374
+ invertedmask = cv2.bitwise_and(imgc,imgc, mask= Blackmask)
375
+ xored=cc
376
+ # masked b abyad
377
+ detectedColors=xored
378
+
379
+ else: #black mask , no other levels are found # to check law count == number of colors in array yb2a no more levels and break
380
+ countBlackMasks+=1
381
+
382
+ return xored,invertedmask , BlackmaskDetected
383
+
384
+ def allLevelsofColor(BlackmaskDetected,img,levelonly, invertedmask,color,finalColorArray):
385
+
386
+ # cc=levelonly.copy()
387
+ firstLevel=levelonly
388
+ firstLevel1=levelonly
389
+ print('in')
390
+ Blackmask = np.zeros(img.shape[:2], dtype="uint8")
391
+
392
+ masked,maskedColor,rgbcolor=DetectColor(invertedmask,color)
393
+ # color=hexRGB(color)
394
+ color=[color[0],color[1],color[2]]
395
+
396
+ rgbcolor=[rgbcolor[0],rgbcolor[1],rgbcolor[2]]
397
+ print(rgbcolor,color)
398
+ pil_image=Image.fromarray(masked)
399
+ extrema = pil_image.convert("L").getextrema()
400
+ if extrema != (0, 0): # if image is not black --> has a colored mask within
401
+
402
+ if rgbcolor==color: #found level tany gowa b nfs el lon
403
+ print('kkkkkkkk')
404
+ ColoredContour, Coloredhierarchy = cv2.findContours(masked, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
405
+ Coloredhierarchy=Coloredhierarchy[0]
406
+ for component in zip(ColoredContour,Coloredhierarchy):
407
+ cnt=component[0]
408
+ hier=component[1]
409
+ area1 = cv2.contourArea(cnt)
410
+ if (area1 > 1000 ):
411
+ if hier[3]> -1:
412
+ cv2.drawContours(Blackmask,[cnt],0,(255,255,255), -1)
413
+ cv2.drawContours(Blackmask,[cnt],0,(0,0,0), 20)
414
+ cv2.drawContours(BlackmaskDetected,[cnt],0,(255,255,255), -1)
415
+
416
+ firstLevel=cv2.bitwise_and(invertedmask,invertedmask,mask=Blackmask)
417
+ ####remove black pixels and let them be all white
418
+ # get (i, j) positions of all RGB pixels that are black (i.e. [0, 0, 0])
419
+ black_pixels = np.where(
420
+ (firstLevel[:, :, 0] == 0) &
421
+ (firstLevel[:, :, 1] == 0) &
422
+ (firstLevel[:, :, 2] == 0)
423
+ )
424
+
425
+ # set those pixels to white
426
+ firstLevel[black_pixels] = [255, 255, 255]
427
+ firstLevel1=cv2.bitwise_and(levelonly,firstLevel)
428
+ # cv2_imshow(firstLevel1)
429
+
430
+ # cv2_imshow(firstLevel1)
431
+ for othercolor in finalColorArray:
432
+ # othercolor2=hexRGB(othercolor)
433
+ othercolor2=[othercolor[0],othercolor[1],othercolor[2]]
434
+ print(othercolor2,color)
435
+ if othercolor2!=color:
436
+ print('anothre')
437
+ masked0=DetectColor(firstLevel,othercolor)[0]
438
+ pil_image0=Image.fromarray(masked0)
439
+ extrema0 = pil_image0.convert("L").getextrema()
440
+ if extrema != (0, 0): # if image is not black --> has a colored mask within
441
+ ColoredContour0, Coloredhierarchy0 = cv2.findContours(masked0, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
442
+ for cnt in ColoredContour0:
443
+ area1 = cv2.contourArea(cnt)
444
+ if (area1 > 1000 ):
445
+ cv2.drawContours(firstLevel1,[cnt],0,(255,255,255), -1)
446
+ cv2.drawContours(firstLevel1,[cnt],0,(255,255,255), 10)
447
+ cv2.drawContours(BlackmaskDetected,[cnt],0,(0,0,0), -1)
448
+ # cv2.drawContours(Blackmask,[cnt],0,(255,255,255), -1)
449
+ # cv2.drawContours(Blackmask,[cnt],0,(255,255,255), 10)
450
+ # cv2_imshow(firstLevel1)
451
+ # cv2_imshow(Blackmask)
452
+ return firstLevel1, BlackmaskDetected
453
+
454
+ def getColoredContour(mask,img,finalColorArray,num1,num2,flag,eachcolor):
455
+ print('uuuuuuuuummmmmmmmmmmmm')
456
+
457
+ ColoredContour, Coloredhierarchy = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
458
+ Coloredhierarchy=Coloredhierarchy[0]
459
+
460
+ imgc= img.copy()
461
+
462
+ detectedColors=np.zeros(img.shape[:2], dtype="uint8")
463
+ Blackmask = np.zeros(img.shape[:2], dtype="uint8")
464
+
465
+ for component in zip( ColoredContour, Coloredhierarchy):
466
+ cnt=component[0]
467
+ hier=component[1]
468
+ area1 = cv2.contourArea(cnt)
469
+ if (area1 > 3000 ):
470
+ # cv2.drawContours(imgNewCopy, [cnt], 0,(255,255,255), 20) #(x+20,y+20 ), (x+width-20, y+height-20),
471
+ if hier[3] >-1:
472
+
473
+ x, y , width, height = cv2.boundingRect(cnt)
474
+ cv2.drawContours(Blackmask, [cnt], 0,(255,255,255), -1) #(x+20,y+20 ), (x+width-20, y+height-20),
475
+ cv2.drawContours(Blackmask, [cnt], 0,(0,0,0), 10) #(x+20,y+20 ), (x+width-20, y+height-20),
476
+
477
+ detectedColors = cv2.bitwise_and(imgc,imgc, mask= Blackmask)
478
+ pil_image=Image.fromarray(detectedColors)
479
+ extrema = pil_image.convert("L").getextrema()
480
+ if extrema == (0, 0) :#and extremaB==(0,0): # if image is not black --> has a colored mask within
481
+ break
482
+
483
+ levelOnly,invertedmask,BlackmaskDetected=getinnerColor(Blackmask,img,detectedColors,finalColorArray,num1,num2,flag,eachcolor) #mask inner levels b abyad
484
+ firstLevel1, BlackmaskDetected1= allLevelsofColor(BlackmaskDetected,img,levelOnly, invertedmask,eachcolor,finalColorArray)
485
+ # cv2.imshow('kk',firstLevel1)
486
+ print('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')
487
+ return firstLevel1,invertedmask, BlackmaskDetected1
488
+
489
+ """# contours"""
490
+
491
+ def findContoursFullImage(green2,img,number,finalColorArray,num1,num2,flag,color=[0,0,0]):
492
+ if number == 0:
493
+ thresh=preprocess(img,number,green2)
494
+
495
+ contourss, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
496
+ return contourss
497
+ else:
498
+ mask, detectedColors, rgbcolor =DetectColor(img,color)
499
+ print(rgbcolor)
500
+
501
+ pil_image=Image.fromarray(mask)
502
+
503
+ extrema = pil_image.convert("L").getextrema()
504
+ if extrema != (0, 0): # if image is not black --> has a colored mask within
505
+ coloredregions,invertedmask,BlackmaskDetected1=getColoredContour(mask,img,finalColorArray,num1,num2,flag,color)
506
+ thresh=preprocess(coloredregions,number,green2)
507
+ x=cv2.bitwise_and(thresh,thresh,mask=BlackmaskDetected1)
508
+ contourss, hierarchy = cv2.findContours(x, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
509
+ return contourss,rgbcolor ,invertedmask
510
+
511
+ else:
512
+ print('ELSEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE')
513
+ thresh=preprocess(img,number,green2)
514
+
515
+ contourss, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
516
+ hierarchy = hierarchy[0]
517
+ return contourss,color ,mask
518
+
519
+
520
+
521
+ def StraightenImage(contour,imgArea):
522
+ rect = cv2.minAreaRect(contour)
523
+
524
+ (center, (width, height), angleR) = cv2.minAreaRect(contour)
525
+
526
+ box = cv2.boxPoints(rect)
527
+ box = np.int0(box)
528
+
529
+ # get width and height of the detected rectangle
530
+ width = int(rect[1][0])
531
+ height = int(rect[1][1])
532
+
533
+ # src_pts = box.astype("float32")
534
+ # dst_pts = np.array([[0, height-1],
535
+ # [0, 0],
536
+ # [width-1, 0],
537
+ # [width-1, height-1]], dtype="float32")
538
+
539
+ # # the perspective transformation matrix
540
+ # M = cv2.getPerspectiveTransform(src_pts, dst_pts)
541
+
542
+ # # directly warp the rotated rectangle to get the straightened rectangle
543
+
544
+ # warped = cv2.warpPerspective(imgArea, M, (width, height))
545
+ ##############
546
+ return angleR,width,height
547
+
548
+ def getAreasPerimeter(green2,img,number,num1,num2,flag,finalColorArray,color=[0,0,0]):
549
+ appended=[]
550
+ if number==0:
551
+ contourss=findContoursFullImage(green2,img,number,finalColorArray,num1,num2,flag,color)
552
+ else:
553
+ contourss=findContoursFullImage(green2,img,number,finalColorArray,num1,num2,flag,color)[0]
554
+
555
+ for contour in contourss:
556
+
557
+ area1 = cv2.contourArea(contour)
558
+ perimeter1 = cv2.arcLength(contour, True)
559
+ x, y , width, height = cv2.boundingRect(contour)
560
+
561
+ angleR,widthR ,heightR= StraightenImage(contour,img)
562
+
563
+ if (angleR != 90.0 and angleR != -90.0 and angleR != 0.0 and angleR != -0.0 ): #inclined b ay degree
564
+ width=widthR
565
+ height=heightR
566
+ if (area1 > 4000 ): #check perimeter kman fl condition -- 2800
567
+ if num1!=0 and num2!=0:
568
+ #if flag=='area':
569
+ # addedMargin=area1+perimeter1*2
570
+ # areaa=round(addedMargin* (num1/(num2+perimeter1*2) ), 3) # true value of area of any shape/ area px value of same shape
571
+ areaa=round(area1*num1,3)
572
+ appended.append([areaa,width,height])
573
+
574
+ #else:
575
+ #perimeter=round(perimeter1*(num1/num2),3)
576
+ #appended.append([perimeter,width,height])
577
+
578
+ return appended
579
+
580
+
581
+ def FillDictionary(green2,SimilarAreaDictionary,img,number,num1,num2,flag,finalColorArray,rgbcolor=[0,0,0],color=[0,0,0]):
582
+ #fills dictionary with key areas and number of occurences
583
+ print('wttttt')
584
+ areas_Perimeters=sorted(getAreasPerimeter(green2,img,number,num1,num2,flag,finalColorArray,color) )
585
+
586
+ indices=[]
587
+ colorRanges=[[255,153,153],[51,255,51],[201,56,147],[255,0,0],[255,0,255],[0,102,204],[102,0,102],[153,0,76],[200,92,135],[52,161,99],[235,250,24],[40,30,170],[98,149,63],[100,30,179],[200,55,67],[150,80,200],[0,102,102],[250,28,191],[101,27,101],[230,150,76],[3,65,127],[114,39,39],[250,36,100],[180,30,40],[10,250,60],[140,30,253],[114,58,245],[47,255,255],[18,236,206],[225,105,29],[189,65,121],[206,204,48],[126,7,247],[3,168,251]]
588
+ print(colorRanges[0])
589
+ print(colorRanges[0][0],colorRanges[0][1], colorRanges[0][2])
590
+ colorsUsed=[]
591
+ for i in range(len(areas_Perimeters)):
592
+
593
+ # colorRGB=hexRGB(color)
594
+ item1 = areas_Perimeters[i][0]
595
+ width1 = areas_Perimeters[i][1]
596
+ height1 = areas_Perimeters[i][2]
597
+ widthMin= width1-10
598
+ widthMax= width1+10
599
+ heightMin=height1-10
600
+ heightMax= height1+10
601
+ areaPerimeterMin= round(item1,1) - 0.3
602
+ areaPerimeterMax= round(item1,1) + 0.3
603
+ # print (areaMin, areaMax)
604
+ if color != [0,0,0]: #colored images
605
+
606
+ mydata=[[rgbcolor[0],rgbcolor[1],rgbcolor[2] ],round(item1,1),width1,height1,1, 0,0,0,0,0,0,0,0,0]
607
+ # mydata=[round(item1,1),width1,height1,0, 1,0,[rgbcolor[0],rgbcolor[1],rgbcolor[2] ],colorRanges[0][2],colorRanges[0][1],colorRanges[0][0]]
608
+ # colorRanges.pop(0)
609
+ else:
610
+ # print('??')
611
+
612
+ mydata=[' ', round(item1,1),width1,height1,1, 0,0,0,0,0,0,0,0,0]
613
+
614
+ # if (( round(item1,1) in SimilarAreaDictionary['Rounded'].values) or (areaMin in SimilarAreaDictionary['Rounded'].values )or (areaMax in SimilarAreaDictionary['Rounded'].values )):
615
+
616
+ # myindex= SimilarAreaDictionary.index[( SimilarAreaDictionary['Rounded']== round(item1,1) ) ].tolist()
617
+ myindex= SimilarAreaDictionary.index[((SimilarAreaDictionary['Rounded'] >=areaPerimeterMin) &(SimilarAreaDictionary['Rounded']<=areaPerimeterMax) )].tolist()
618
+ # for i in myindex:
619
+ # SimilarAreaDictionary['Rounded'].loc[i]
620
+ if color!= [0,0,0]: #leveled image
621
+
622
+ checkifColorExists=0 # to check whether this row was found or not( area and color )
623
+ for i in myindex: # loop on indices that were found --> rows containing this area to check its color and add occ.
624
+ if SimilarAreaDictionary['Color'].loc[i]==[rgbcolor[0],rgbcolor[1],rgbcolor[2]] and ( SimilarAreaDictionary['Rounded'].loc[i] >= areaPerimeterMin and SimilarAreaDictionary['Rounded'].loc[i] <= areaPerimeterMax) :
625
+ 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 ) :
626
+ checkifColorExists=1 #found and incremented
627
+ SimilarAreaDictionary['Occurences'].loc[i]+=1
628
+ if checkifColorExists==0: #couldnt find the color , doesnt exist so add it
629
+ SimilarAreaDictionary.loc[len(SimilarAreaDictionary)] =mydata
630
+
631
+ else: #full image
632
+ # print('here')
633
+ #same code bs mgher color
634
+ checkifColorExists=0
635
+ for i in myindex: #(SimilarAreaDictionary['Rounded'].loc[i] == round(item1,1) ) or
636
+ if ( SimilarAreaDictionary['Rounded'].loc[i] <= areaPerimeterMax and SimilarAreaDictionary['Rounded'].loc[i] >= areaPerimeterMin) :
637
+ # print(SimilarAreaDictionary['Rounded'].loc[i] ,'in rng if', areaMin,areaMax)
638
+ 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 ) :
639
+ checkifColorExists=1 #found and incremented
640
+ SimilarAreaDictionary['Occurences'].loc[i]+=1
641
+ # SimilarAreaDictionary['R'].loc[i] =colorRanges[i][0]
642
+ # SimilarAreaDictionary['G'].loc[i] =colorRanges[i][1]
643
+ # SimilarAreaDictionary['B'].loc[i] = colorRanges[i][2]
644
+
645
+ # colorRanges.pop(0)
646
+
647
+ if checkifColorExists==0: #couldnt find the color , doesnt exist so add it
648
+ SimilarAreaDictionary.loc[len(SimilarAreaDictionary)] =mydata
649
+ # s= SimilarAreaDictionary
650
+ for i in range(len(SimilarAreaDictionary)):
651
+ SimilarAreaDictionary['R'].loc[i] =colorRanges[i][0]
652
+ SimilarAreaDictionary['G'].loc[i] =colorRanges[i][1]
653
+ SimilarAreaDictionary['B'].loc[i] = colorRanges[i][2]
654
+ colorsUsed.append(colorRanges[i])
655
+
656
+
657
+ return SimilarAreaDictionary, colorsUsed , areas_Perimeters
658
+ def drawAllContours(img,number,finalColorArray,ratioarea,ratioperim,flag , path,pdfpath):
659
+ green2=allpreSteps(img)
660
+ doc = fitz.open('dropbox_plans/1.0/'+path)
661
+ page = doc[0]
662
+ page.set_rotation(0)
663
+ pix=page.get_pixmap()
664
+ ratio = pix.width/ img.shape[1]
665
+
666
+ areasinImage=[]
667
+ totaldf=pd.DataFrame()
668
+ imgArea1= img.copy()
669
+ imgPerimeter1=img.copy()
670
+ imgtransparent1=img.copy()
671
+
672
+ Blackmask = np.zeros(img.shape[:2], dtype="uint8")
673
+
674
+ invertedmask=img
675
+ allpoints=[]
676
+
677
+ if number ==220:
678
+ # finalColorArray= colorOrder(img,finalColorArray)
679
+ # if flag== 'area':
680
+ # SimilarAreaDictionary= pd.DataFrame(columns=['Color','Rounded','Width','Height','Area','Occurences','Total Area' , 'R','G','B']) #
681
+ # else:
682
+ # SimilarAreaDictionary= pd.DataFrame(columns=['Color','Rounded','Width','Height','Perimeter','Occurences','Total Perimeter' ,'R','G','B'])
683
+ SimilarAreaDictionary= pd.DataFrame(columns=['Color','Rounded','Width','Height','Occurences','Area','Total Area','Perimeter','Total Perimeter','Length','Total Length','R','G','B'])
684
+ firstcolor=finalColorArray[0]
685
+ # print(lastcolor)
686
+ counter=0
687
+ maskDone=img.copy()
688
+ for eachcolor in finalColorArray:
689
+
690
+ print(eachcolor)
691
+ if eachcolor==firstcolor: # 3shan a3rf el array of colors et3adet kam mara - to support embedded levels
692
+ counter+=1
693
+
694
+ contourss,rgbcolor,invertedmask=findContoursFullImage(green2,maskDone,number,finalColorArray,ratioarea,ratioperim,flag,eachcolor)
695
+ SimilarAreaDictionary, colorsUsed , areas_Perimeters= FillDictionary(green2,SimilarAreaDictionary,maskDone,number,ratioarea,ratioperim,flag,finalColorArray,rgbcolor,eachcolor)
696
+
697
+ a = SimilarAreaDictionary.to_numpy()
698
+
699
+ # for component in zip(contourss,hierarchy):
700
+ # contour = component[0]
701
+ # currentHierarchy = component[1]
702
+ for contour in contourss:
703
+ shape=[]
704
+
705
+ # cv2_imshow(imgStraight)
706
+ area1 = cv2.contourArea(contour)
707
+ perimeter1 = cv2.arcLength(contour, True)
708
+ if (area1 > 4000 ): #check perimeter kman fl condition -- 2800
709
+ angleR,widthR ,heightR= StraightenImage(contour,imgArea1)
710
+ rect = cv2.minAreaRect(contour)
711
+
712
+ (center, (width, height), angleR) = cv2.minAreaRect(contour)
713
+
714
+ box = cv2.boxPoints(rect)
715
+ box = box.astype('int')
716
+ print(box)
717
+
718
+ x, y , width, height = cv2.boundingRect(contour)
719
+ # cv2.drawContours(imgArea1,contours=[box], contourIdx=0 , color=(0, 0, 255), thickness=10)
720
+ approx = cv2.approxPolyDP(contour, 0.005 * perimeter1, True)
721
+ for point in approx:
722
+ x1, y1 = point[0]
723
+
724
+ shape.append([int(x1*ratio),int(y1*ratio)])
725
+ # shape= np.fliplr(shape)
726
+
727
+ # cv2.circle(imgArea1, (x1, y1), 4, (0, 255, 0), -1)
728
+ allpoints.append(shape)
729
+ # print(x,y,width,height)
730
+ # print(allpoints)
731
+ print(shape)
732
+ if (angleR != 90.0 and angleR != -90.0 and angleR != 0.0 and angleR != -0.0 ): #inclined b ay degree
733
+ width=widthR
734
+ height=heightR
735
+ if width>height:
736
+ lengthShape = width
737
+ if height>width:
738
+ lengthShape = height
739
+ widthMin= width-10
740
+ widthMax= width+10
741
+ heightMin=height-10
742
+ heightMax= height+10
743
+ if ratioarea !=0 and ratioperim!=0:
744
+ widthh=round(width*ratioperim,3)
745
+ heightt=round(height*ratioperim,3)
746
+ # if flag=='area':
747
+ areaa=round(area1* ratioarea, 3) # true value of area of any shape/ area px value of same shape
748
+
749
+ # elif flag=='perimeter':
750
+ perimeterr=round(perimeter1* ratioperim, 3)
751
+ else:
752
+ areaa=area1
753
+ perimeterr=perimeter1
754
+
755
+ # if flag=='area':
756
+ areaPerimeterMin= round(areaa,1) - 0.3
757
+ areaPerimeterMax= round(areaa,1) + 0.3
758
+ # areaPerimeterMin= round(perimeterr,1) - 0.3
759
+ # areaPerimeterMax= round(perimeterr,1) + 0.3
760
+ masked=SimilarAreaDictionary.loc[SimilarAreaDictionary.index[((SimilarAreaDictionary['Rounded'] >=areaPerimeterMin) &(SimilarAreaDictionary['Rounded']<=areaPerimeterMax) )]]
761
+ # masked=SimilarAreaDictionary.loc[SimilarAreaDictionary['Rounded'] ==round(areaa,1)]
762
+ # if (round(areaa,1) in masked['Rounded'].values ) :
763
+ passed=0
764
+ for i, row in masked.iterrows():
765
+ if passed ==0:
766
+ if SimilarAreaDictionary['Color'].loc[i] == [rgbcolor[0],rgbcolor[1],rgbcolor[2]] and ( SimilarAreaDictionary['Rounded'].loc[i] <= areaPerimeterMax and SimilarAreaDictionary['Rounded'].loc[i] >= areaPerimeterMin) :
767
+ 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 ) :
768
+ SimilarAreaDictionary['Total Area'].loc[i]+=areaa
769
+ SimilarAreaDictionary['Area'].loc[i]=areaa
770
+
771
+ SimilarAreaDictionary['Total Perimeter'].loc[i]+=perimeterr
772
+ SimilarAreaDictionary['Perimeter'].loc[i]=perimeterr
773
+
774
+ SimilarAreaDictionary['Total Length'].loc[i]+=lengthShape
775
+ SimilarAreaDictionary['Length'].loc[i]=lengthShape
776
+ passed=1
777
+ # print(index)
778
+ # cv2.drawContours(imgArea1, [contour], 0, (int(rgbcolor[2]), int(rgbcolor[1]), int(rgbcolor[0])), -1)
779
+ cv2.drawContours(imgArea1, [contour], 0, ( int(SimilarAreaDictionary['B'].loc[i]), int(SimilarAreaDictionary['G'].loc[i]), int(SimilarAreaDictionary['R'].loc[i])), -1)
780
+ annot = page.add_polygon_annot( points=shape ) # 'Polygon'
781
+ annot.set_border(width=0.3, dashes=[2])
782
+ annot.set_colors( fill=( int(SimilarAreaDictionary['R'].loc[i])/255 , int(SimilarAreaDictionary['G'].loc[i])/255 , int(SimilarAreaDictionary['B'].loc[i])/255 ) )
783
+ # annot.set_colors( fill=(1,0,1) )
784
+ annot.set_opacity(0.5)
785
+ annot.set_info(content='Area='+str(areaa)+' m2' +'\n \nPerimeter='+str(perimeterr)+' m',subject='ADR Team')#,title='uuum')
786
+ # annot.set_line_ends(fitz.PDF_ANNOT_LE_DIAMOND, fitz.PDF_ANNOT_LE_CIRCLE)
787
+ annot.update()
788
+ cv2.putText(imgtransparent1,'Area= '+str(area1) , (x+50,y-10) ,cv2.FONT_HERSHEY_SIMPLEX, 0.6, (50, 50, 255), 2)
789
+ # cv2.putText(imgtransparent1,'Width= '+str(width) , (x+50,y-10) ,cv2.FONT_HERSHEY_SIMPLEX, 0.6, (50, 50, 255), 2)
790
+ # cv2.putText(imgtransparent1,'Length= '+str(height) , (x+50,y-20) ,cv2.FONT_HERSHEY_SIMPLEX, 0.6, (50, 50, 255), 2)
791
+ areasinImage.append(areaa)
792
+
793
+ cv2.putText(imgPerimeter1,'Perimeter'+str(perimeterr), (x+70,y-30) ,cv2.FONT_HERSHEY_SIMPLEX, 0.6, (50, 50, 255), 2)
794
+
795
+
796
+ for i,row in SimilarAreaDictionary.iterrows():
797
+ # print(row)
798
+ if row[5] not in areasinImage: # column of area
799
+ SimilarAreaDictionary = SimilarAreaDictionary.drop(SimilarAreaDictionary.loc[SimilarAreaDictionary.index==i].index)
800
+
801
+ print(SimilarAreaDictionary)
802
+ # display(totaldf)
803
+ #########################
804
+ else:
805
+
806
+ SimilarAreaDictionary= pd.DataFrame(columns=['Color','Rounded','Width','Height','Occurences','Area','Total Area','Perimeter','Total Perimeter','Length','Total Length','R','G','B'])
807
+ contourss=findContoursFullImage(green2,img,number,finalColorArray,ratioarea,ratioperim,flag)
808
+ SimilarAreaDictionary,colorsUsed , areas_Perimeters= FillDictionary(green2,SimilarAreaDictionary,img,number,ratioarea,ratioperim,flag,finalColorArray)
809
+ # print('filled')
810
+ for contour in contourss:
811
+ # shape=[]
812
+ area1 = cv2.contourArea(contour)
813
+ perimeter1 = cv2.arcLength(contour, True)
814
+ if (area1 >4000 ):
815
+ shape=[]
816
+ angleR,widthR ,heightR= StraightenImage(contour,imgArea1)
817
+ x, y , width, height = cv2.boundingRect(contour)
818
+
819
+ approx = cv2.approxPolyDP(contour, 0.005 * perimeter1, True)
820
+ for point in approx:
821
+ x1, y1 = point[0]
822
+ shape.append([int(x1*ratio),int(y1*ratio)])
823
+ allpoints.append(shape)
824
+ if (angleR != 90.0 and angleR != -90.0 and angleR != 0.0 and angleR != -0.0 ): #inclined b ay degree
825
+ width=widthR
826
+ height=heightR
827
+ if width>height:
828
+ lengthShape = width
829
+ if height>width:
830
+ lengthShape = height
831
+ widthMin= width-10 #5
832
+ widthMax= width+10
833
+ heightMin=height-10
834
+ heightMax= height+10
835
+
836
+
837
+ if ratioarea !=0 and ratioperim!=0:
838
+ # if flag=='area':
839
+ # addedMargin=area1+perimeter1*2
840
+ # areaa=round(addedMargin* (num1/(num2+perimeter1*2) ), 3) # true value of area of any shape/ area px value of same shape
841
+ # elif flag=='perimeter':
842
+ areaa=round(area1* ratioarea, 3) # true value of area of any shape/ area px value of same shape
843
+ perimeterr=round(perimeter1* ratioperim, 3)
844
+ else:
845
+ areaa=area1
846
+ perimeterr=perimeter1
847
+ # if flag=='area':
848
+ areaPerimeterMin= round(areaa,1) - 0.3
849
+ areaPerimeterMax= round(areaa,1) + 0.3
850
+ masked=SimilarAreaDictionary.loc[SimilarAreaDictionary.index[((SimilarAreaDictionary['Rounded'] >=areaPerimeterMin) & (SimilarAreaDictionary['Rounded']<=areaPerimeterMax) )]]
851
+ passed=0
852
+ # if (round(areaa,1) in masked['Rounded'].values ) :
853
+
854
+ for i, row in masked.iterrows():
855
+ if passed ==0:
856
+ # if SimilarAreaDictionary['Rounded'].loc[i] == round(areaa,1) :
857
+ if ( SimilarAreaDictionary['Rounded'].loc[i] <= areaPerimeterMax and SimilarAreaDictionary['Rounded'].loc[i] >= areaPerimeterMin) :
858
+ 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 ) :
859
+ SimilarAreaDictionary['Total Area'].loc[i]+=areaa
860
+ SimilarAreaDictionary['Area'].loc[i]=areaa
861
+
862
+ SimilarAreaDictionary['Total Perimeter'].loc[i]+=perimeterr
863
+ SimilarAreaDictionary['Perimeter'].loc[i]=perimeterr
864
+
865
+ SimilarAreaDictionary['Total Length'].loc[i]+=lengthShape
866
+ SimilarAreaDictionary['Length'].loc[i]=lengthShape
867
+ passed=1
868
+ cv2.drawContours(imgArea1, [contour], 0, ( int(SimilarAreaDictionary['B'].loc[i]), int(SimilarAreaDictionary['G'].loc[i]), int(SimilarAreaDictionary['R'].loc[i])), -1)
869
+
870
+ annot = page.add_polygon_annot( points=shape ) # 'Polygon'
871
+ annot.set_border(width=0.3, dashes=[2])
872
+ annot.set_colors( fill=( int(SimilarAreaDictionary['R'].loc[i])/255 , int(SimilarAreaDictionary['G'].loc[i])/255 , int(SimilarAreaDictionary['B'].loc[i])/255 ) )
873
+ # annot.set_colors( fill=(1,0,1) )
874
+ annot.set_opacity(0.5)
875
+ annot.set_info(content='Area='+str(areaa)+' m2' +'\n \nPerimeter='+str(perimeterr)+' m',subject='ADR Team')#,title='uuum')
876
+ # annot.set_line_ends(fitz.PDF_ANNOT_LE_DIAMOND, fitz.PDF_ANNOT_LE_CIRCLE)
877
+ annot.update()
878
+ cv2.putText(imgtransparent1,'area= '+str(area1) + ' m', (x+50,y-10) ,cv2.FONT_HERSHEY_SIMPLEX, 0.6, (50, 50, 255), 2)
879
+ # cv2.putText(imgtransparent1,'Width= '+str(width) , (x+50,y-10) ,cv2.FONT_HERSHEY_SIMPLEX, 0.6, (50, 50, 255), 2)
880
+ # cv2.putText(imgtransparent1,'Length= '+str(height) , (x+50,y-40) ,cv2.FONT_HERSHEY_SIMPLEX, 0.6, (50, 50, 255), 2)
881
+ cv2.drawContours(imgArea1, [contour], 0, (0, 0, 255),2)
882
+ cv2.drawContours(imgPerimeter1, [contour], 0, (0, 0, 255), 4)
883
+ cv2.putText(imgPerimeter1,'Perimeter='+str(perimeter1), (x+30,y-30) ,cv2.FONT_HERSHEY_SIMPLEX, 0.6, (50, 50, 255), 2)
884
+
885
+
886
+ alpha = 0.4 # Transparency factor.
887
+ image_new1 = cv2.addWeighted(imgArea1, alpha, imgtransparent1, 1 - alpha, 0)
888
+
889
+ # SimilarAreaDictionary.drop(['Rounded', 'Width','Height','R','G','B'], axis=1, inplace=True)
890
+
891
+ print(SimilarAreaDictionary)
892
+
893
+ # annotationsSave
894
+ # doc.save('k.pdf', deflate=True)
895
+ pdflink= db.dropbox_upload_file(doc=doc,pdfname=path,pdfpath=pdfpath)
896
+ # list1=pd.DataFrame(columns=['content', 'creationDate', 'id', 'modDate', 'name', 'subject', 'title'])
897
+ # doc1 = fitz.open('k.pdf')
898
+ # for page in doc1:
899
+ # for annot in page.annots():
900
+ # list1.loc[len(list1)] =annot.info
901
+ # print(list1)
902
+ dbx=db.dropbox_connect()
903
+ md, res =dbx.files_download(path= pdfpath+path)
904
+ data = res.content
905
+ doc=fitz.open("pdf", data)
906
+ # list1=pd.DataFrame(columns=['content', 'creationDate', 'id', 'modDate', 'name', 'subject', 'title'])
907
+ list1=pd.DataFrame(columns=['content', 'id', 'subject'])
908
+ for page in doc:
909
+ for annot in page.annots():
910
+ list1.loc[len(list1)] =annot.info
911
+
912
+ print(list1)
913
+ gc,spreadsheet_service,spreadsheetId, spreadsheet_url , namepathArr=legendGoogleSheets(SimilarAreaDictionary , path,pdfpath)
914
+ return imgPerimeter1,image_new1,SimilarAreaDictionary, colorsUsed , spreadsheet_url , spreadsheetId , list1 , pdflink , areas_Perimeters , namepathArr
915
+
916
+ ######################################################
917
+
918
+ def deletemarkups(list1, pdfpath , path):
919
+ '''list1 : original markup pdf
920
+ list2 : deleted markup pdf
921
+ deletedrows : deleted markups - difference betw both dfs
922
+
923
+ '''
924
+
925
+ myDict1=eval(list1)
926
+ list1=pd.DataFrame(myDict1)
927
+
928
+ areastodelete = []
929
+ perimstodelete=[]
930
+
931
+ dbx=db.dropbox_connect()
932
+
933
+ md, res =dbx.files_download(path= pdfpath+path)
934
+ data = res.content
935
+ doc=fitz.open("pdf", data)
936
+ list2=pd.DataFrame(columns=['content', 'id', 'subject'])
937
+ # list2=pd.DataFrame(columns=['content', 'creationDate', 'id', 'modDate', 'name', 'subject', 'title'])
938
+ for page in doc:
939
+ for annot in page.annots():
940
+ list2.loc[len(list2)] =annot.info
941
+ print(list1)
942
+ deletedrows=pd.concat([list1,list2]).drop_duplicates(keep=False)
943
+
944
+ print(deletedrows,len(deletedrows))
945
+ flag=0
946
+ if len(deletedrows)!=0:
947
+ flag=1
948
+ deletedrows=deletedrows[['content', 'id', 'subject']]
949
+ deletedrows = deletedrows.drop(deletedrows.index[deletedrows['content'].str.startswith('Scale')] )#, inplace=True)
950
+ else:
951
+ flag=0
952
+ return deletedrows
953
+
954
+
955
+
956
+ def deletefromlegend(deletedrows,SimilarAreaDictionarycopy,section, areaPermArr=[]):
957
+ items=[]
958
+ idx=0
959
+ if section.startswith('1.0'):
960
+ areaPermArr=ast.literal_eval(areaPermArr)
961
+ myDict=eval(SimilarAreaDictionarycopy)
962
+ SimilarAreaDictionarycopy=pd.DataFrame(myDict)
963
+ strings=deletedrows['content']
964
+
965
+ areastodelete = []
966
+ perimstodelete=[]
967
+
968
+ for item in strings:
969
+ items.append(str(item).split('\n \n'))
970
+ # 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
971
+ for i in range(len(items)):
972
+ areastodelete.append(float(re.findall("\d+\.\d+", str(items[i][0]).split()[0])[0]))
973
+ perimstodelete.append(float(re.findall("\d+\.\d+", str(items[i][1]).split()[0])[0]) )
974
+ print(areastodelete,perimstodelete)
975
+ for i in range(len(areastodelete)):#item in areastodelete:
976
+ areamin=round(areastodelete[i],1)- 0.3
977
+ areamax=round(areastodelete[i],1)+ 0.3
978
+ perimmin=round(perimstodelete[i],1)- 0.3
979
+ perimmax=round(perimstodelete[i],1)+ 0.3
980
+ if section.startswith('1.0'):
981
+ for p in range(len(areaPermArr)):
982
+ if areastodelete[i] in areaPermArr[p]:
983
+ area= areaPermArr[p][0]
984
+ width= areaPermArr[p][1]
985
+ height= areaPermArr[p][2]
986
+ if section.startswith('1.0'):
987
+ widthMin= width -10
988
+ widthMax= width +10
989
+ heightMin = height-10
990
+ heightMax=height+10
991
+ print(width, widthMin ,height, heightMin)
992
+ 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) )) ]]
993
+ elif section.startswith('3.2'):
994
+ areamin=round(areastodelete[i],1)- 0.1
995
+ areamax= round(areastodelete[i],1) + 0.1
996
+
997
+ found=SimilarAreaDictionarycopy.loc[SimilarAreaDictionarycopy.index[((SimilarAreaDictionarycopy['Area'] >=areamin) & (SimilarAreaDictionarycopy['Area']<=areamax) )]]
998
+
999
+ if len(found.index.values ) >0:
1000
+ occ=SimilarAreaDictionarycopy.loc[found.index.values[0],'Occurences']
1001
+ if occ== 1: #drop row
1002
+ print('occ=1')
1003
+ SimilarAreaDictionarycopy= SimilarAreaDictionarycopy.drop(found.index.values[0])
1004
+
1005
+ else: #occ minus 1 , total area - areavalue , total perim - perimvalue
1006
+ print('occ>1')
1007
+ if section.startswith('1.0'):
1008
+ 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) )) ]
1009
+ elif section.startswith('3.2'):
1010
+ perimmin=round(perimstodelete[i],1)- 50
1011
+ perimmax=round(perimstodelete[i],1)+ 50
1012
+ idx=SimilarAreaDictionarycopy.index[((SimilarAreaDictionarycopy['Area'] >=areamin) & (SimilarAreaDictionarycopy['Area']<=areamax) & (SimilarAreaDictionarycopy['Perimeter'] >=perimmin) & (SimilarAreaDictionarycopy['Perimeter']<=perimmax) )]
1013
+ SimilarAreaDictionarycopy.loc[idx,'Total Area'] = SimilarAreaDictionarycopy.loc[idx,'Total Area'] - areastodelete[i]
1014
+ SimilarAreaDictionarycopy.loc[idx,'Total Perimeter'] = SimilarAreaDictionarycopy.loc[idx,'Total Perimeter'] - perimstodelete[i]
1015
+ print('ppppppppppppppppppp',SimilarAreaDictionarycopy.loc[idx,'Occurences'])
1016
+ SimilarAreaDictionarycopy.loc[idx,'Occurences'] = int(SimilarAreaDictionarycopy.loc[idx,'Occurences']) - 1
1017
+ print(SimilarAreaDictionarycopy)
1018
+ return SimilarAreaDictionarycopy
1019
+ #######################################################
1020
+
1021
+ def getTitle(path):
1022
+ planName= path.split("/")[-1].split('.')
1023
+ LegendName='Legend of ' + str(planName[0]) + ' plan'
1024
+ return LegendName
1025
+
1026
+ def retrieveMCCol(gc):
1027
+ ws=gc.open_by_key('1A8VtqLFhe2NXPxIjfAilbxF9xV2eSzZ-yZ9GP8_5jSo')
1028
+ worksheet = ws.worksheet(0)
1029
+ mcT_Names=worksheet.get_col(1)
1030
+ newMcTNames=[]
1031
+ for i in mcT_Names:
1032
+ if i != '':
1033
+ newMcTNames.append(i)
1034
+ return newMcTNames
1035
+
1036
+
1037
+ def getdropdownValues(gc,spreadsheet_service,spreadsheetid):
1038
+ dropdownValues=[]
1039
+ ws=gc.open_by_key('1A8VtqLFhe2NXPxIjfAilbxF9xV2eSzZ-yZ9GP8_5jSo') ## spreadsheet containing mc-t names
1040
+
1041
+ worksheet = ws.worksheet(0)
1042
+ response = spreadsheet_service.spreadsheets().get(
1043
+ spreadsheetId=spreadsheetid, fields='*',
1044
+ ranges='A2:A60',includeGridData=True).execute()
1045
+ r=list(response['sheets'][0]['data'][0]['rowData'][0]['values'][0])
1046
+ print(r)
1047
+ if 'dataValidation' in r:
1048
+ print('yes')
1049
+ colvals= response['sheets'][0]['data'][0]['rowData'][0]['values'][0]['dataValidation']
1050
+ colvalsList=list(colvals.items())
1051
+ print(colvalsList[0][1])
1052
+ lengthVals=len(colvalsList[0][1]['values'])
1053
+ for i in range(lengthVals):
1054
+ dictVal=(colvalsList[0][1]['values'][i].values())
1055
+ # val=[*dictVal]
1056
+
1057
+ dropdownValues.append(*dictVal)
1058
+ print(dropdownValues)
1059
+ worksheet.update_col(index=1, values=dropdownValues)
1060
+ return dropdownValues
1061
+ def authorizeLegend():
1062
+ SCOPES = [
1063
+ 'https://www.googleapis.com/auth/spreadsheets',
1064
+ 'https://www.googleapis.com/auth/drive',
1065
+ 'https://www.googleapis.com/auth/drive.metadata'
1066
+ ]
1067
+ credentials = service_account.Credentials.from_service_account_file('credentials.json', scopes=SCOPES)
1068
+ spreadsheet_service = build('sheets', 'v4', credentials=credentials)
1069
+ drive_service = build('drive', 'v3', credentials=credentials)
1070
+ gc = pygsheets.authorize(custom_credentials=credentials, client_secret='credentials.json')
1071
+ return spreadsheet_service,drive_service,gc
1072
+
1073
+ def legendGoogleSheets(SimilarAreaDictionary,path ,pdfpath, spreadsheetId=0):
1074
+
1075
+ spreadsheet_service,drive_service,gc=authorizeLegend()
1076
+ ########
1077
+ legendTitle= path
1078
+ titles=gc.spreadsheet_titles()
1079
+
1080
+
1081
+
1082
+ if legendTitle in titles:
1083
+ print('found sheet ', legendTitle)
1084
+ ws=gc.open(str(legendTitle))
1085
+ spreadsheetId=ws.id
1086
+ else:
1087
+ # ####### create new sheet
1088
+ print('creating new sheeet')
1089
+
1090
+ spreadsheet_details = {
1091
+ 'properties': {
1092
+ 'title': path
1093
+ }
1094
+ }
1095
+ sheet = spreadsheet_service.spreadsheets().create(body=spreadsheet_details,
1096
+ fields='spreadsheetId').execute()
1097
+
1098
+ spreadsheetId = sheet.get('spreadsheetId')
1099
+ permission1 = {
1100
+ 'type': 'anyone',
1101
+ 'role': 'writer',
1102
+ # 'emailAddress': 'marthe.adr@gmail.com'
1103
+ }
1104
+ # permission2 = {
1105
+ # 'type': 'user',
1106
+ # 'role': 'writer',
1107
+ # 'emailAddress': 'marthe.adr@gmail.com',
1108
+ # 'pendingOwner': True
1109
+ # }
1110
+
1111
+
1112
+ drive_service.permissions().create(fileId=spreadsheetId, body=permission1, supportsAllDrives=True ).execute()
1113
+ ws=gc.open_by_key(spreadsheetId)
1114
+
1115
+ sheetId = '0' # Please set sheet ID.
1116
+ worksheet = ws.worksheet(0)
1117
+ worksheet.title='Legend and data created'
1118
+ worksheet.clear()
1119
+
1120
+ ws.create_developer_metadata('path',pdfpath)
1121
+ splittedpdfpath=re.split(r'[`\-=~!@#$%^&*()_+\[\]{};\'\\:"|<,/<>?]', pdfpath)
1122
+ namepathArr=[legendTitle , spreadsheetId,ws.get_developer_metadata('path')[0].value]
1123
+ if splittedpdfpath[-2].startswith('2.2'):
1124
+ df=[]
1125
+ worksheet.update( df.values.tolist()) #CHECKKKK
1126
+
1127
+
1128
+ else:
1129
+ top_header_format = [
1130
+ {'mergeCells': { #areas
1131
+ 'mergeType': 'MERGE_ROWS',
1132
+ 'range': {
1133
+ 'sheetId': '0',
1134
+ 'startRowIndex': 1,
1135
+ 'endRowIndex': 2,
1136
+ 'startColumnIndex': 3,
1137
+ 'endColumnIndex':5
1138
+
1139
+
1140
+ }
1141
+ }},
1142
+
1143
+ {'mergeCells': { #perimeters
1144
+ 'mergeType': 'MERGE_ROWS',
1145
+ 'range': {
1146
+ 'sheetId': '0',
1147
+ 'startRowIndex': 1,
1148
+ 'endRowIndex': 2,
1149
+ 'startColumnIndex': 5,
1150
+ 'endColumnIndex':7
1151
+ }
1152
+
1153
+ }},
1154
+ {'mergeCells': { #lengths
1155
+ 'mergeType': 'MERGE_ROWS',
1156
+ 'range': {
1157
+ 'sheetId': '0',
1158
+ 'startRowIndex': 1,
1159
+ 'endRowIndex': 2,
1160
+ 'startColumnIndex': 7,
1161
+ 'endColumnIndex':9
1162
+ }
1163
+
1164
+ }},
1165
+
1166
+ {'mergeCells': { # legend and data created
1167
+ 'mergeType': 'MERGE_ROWS',
1168
+ 'range': {
1169
+ 'sheetId': '0',
1170
+ 'startRowIndex': 0,
1171
+ 'endRowIndex': 1,
1172
+ 'startColumnIndex': 0,
1173
+ 'endColumnIndex':9
1174
+ }
1175
+
1176
+ }}
1177
+ ]
1178
+
1179
+
1180
+ spreadsheet_service.spreadsheets().batchUpdate( spreadsheetId=spreadsheetId , body={'requests': top_header_format} ).execute()
1181
+ worksheet.cell((1,1)).value='Legend and Data Created'
1182
+ worksheet.cell((2,1)).value='Guess'
1183
+ worksheet.cell((2,2)).value='Color'
1184
+ worksheet.cell((2,3)).value='Count'
1185
+ worksheet.cell((2,4)).value='Areas'
1186
+ worksheet.cell((2,6)).value='Perimeters'
1187
+ worksheet.cell((2,8)).value='Lengths'
1188
+ second_row_data=['Nr','m2','Total','m','Total','m','Total']
1189
+
1190
+ worksheet.update_row(3,second_row_data,col_offset=2)
1191
+
1192
+ worksheet.update_col(3,list(SimilarAreaDictionary['Occurences']),row_offset=3)
1193
+ worksheet.update_col(4,list(SimilarAreaDictionary['Area']),row_offset=3)
1194
+ worksheet.update_col(5,list(SimilarAreaDictionary['Total Area']),row_offset=3)
1195
+ worksheet.update_col(6,list(SimilarAreaDictionary['Perimeter']),row_offset=3)
1196
+ worksheet.update_col(7,list(SimilarAreaDictionary['Total Perimeter']),row_offset=3)
1197
+
1198
+ worksheet.update_col(8,list(SimilarAreaDictionary['Length']),row_offset=3)
1199
+ worksheet.update_col(9,list(SimilarAreaDictionary['Total Length']),row_offset=3)
1200
+ if splittedpdfpath[-2].startswith('1.0'):
1201
+ colorsUsed=[]
1202
+ for i in range(len(SimilarAreaDictionary)):
1203
+ colorsUsed.append([SimilarAreaDictionary['R'].iloc[i] ,SimilarAreaDictionary['G'].iloc[i] , SimilarAreaDictionary['B'].iloc[i]] )
1204
+ elif splittedpdfpath[-2].startswith('3.2'):
1205
+ colorsUsed=list(SimilarAreaDictionary['Color'])
1206
+ #legend specs here
1207
+ rowsLen=len(SimilarAreaDictionary.values.tolist()) #kam row -- last row = rowsLen +1
1208
+ lastcell=worksheet.cell((rowsLen+2,1)) #row,col
1209
+ lastcellNotation=str(lastcell.address.label)
1210
+ # worksheet.set_data_validation('A3',lastcellNotation, condition_type='ONE_OF_LIST', condition_values=['Ground Beam','Pile Cap'], showCustomUi=True)
1211
+
1212
+ #get lengths of df
1213
+ columnsLen=len(SimilarAreaDictionary.columns.values.tolist()) #kam column -- last col = columnsLen+1 3shan base0
1214
+ lastUsedCol=columnsLen+1
1215
+
1216
+ worksheet.adjust_column_width(start=2,end=3)
1217
+ # if splittedpdfpath[-2].startswith('1.0'):
1218
+ worksheet.adjust_column_width(start=4,end=9,pixel_size=60)
1219
+ startrow = 3
1220
+ # elif splittedpdfpath[-2].startswith('3.2'):
1221
+ # startrow=2
1222
+
1223
+ sheetId = '0' # Please set sheet ID.
1224
+ for i in range(len(colorsUsed)):
1225
+
1226
+ print(colorsUsed[i])
1227
+ r,g,b=colorsUsed[i]
1228
+ body = {
1229
+ "requests": [
1230
+ {
1231
+ "updateCells": {
1232
+ "range": {
1233
+ "sheetId": sheetId,
1234
+ "startRowIndex": i+startrow,
1235
+ # "endRowIndex":4 ,
1236
+ "startColumnIndex":1,
1237
+
1238
+ # "endColumnIndex": 0
1239
+ },
1240
+
1241
+ "rows": [
1242
+ {
1243
+ "values": [
1244
+ {
1245
+ "userEnteredFormat": {
1246
+ "backgroundColor": {
1247
+
1248
+ "red": r/255,
1249
+ "green": g/255,
1250
+ "blue": b/255,
1251
+ "alpha": 0.4,
1252
+
1253
+ }
1254
+
1255
+ }
1256
+ }
1257
+ ]
1258
+ }
1259
+ ],
1260
+ "fields": "userEnteredFormat.backgroundColor",
1261
+
1262
+ }
1263
+
1264
+
1265
+
1266
+ }
1267
+ ]
1268
+ }
1269
+ res = spreadsheet_service.spreadsheets().batchUpdate(spreadsheetId=spreadsheetId, body=body).execute()
1270
+ # if splittedpdfpath[-2].startswith('1.0'):
1271
+ endColindex=9
1272
+ endrow=3
1273
+ # elif splittedpdfpath[-2].startswith('3.2'):
1274
+ # endColindex=3
1275
+ # endrow=2
1276
+ body2={
1277
+ "requests": [
1278
+ {
1279
+ "updateBorders": {
1280
+ "range": {
1281
+ "sheetId": sheetId,
1282
+ "startRowIndex": 0,
1283
+ "endRowIndex": len(SimilarAreaDictionary)+endrow,
1284
+ "startColumnIndex": 0,
1285
+ "endColumnIndex": endColindex
1286
+ },
1287
+ "top": {
1288
+ "style": "SOLID",
1289
+ "width": 2,
1290
+ "color": {
1291
+ "red": 0.0,
1292
+ "green":0.0,
1293
+ "blue":0.0
1294
+ },
1295
+ },
1296
+ "bottom": {
1297
+ "style": "SOLID",
1298
+ "width": 2,
1299
+ "color": {
1300
+ "red": 0.0,
1301
+ "green":0.0,
1302
+ "blue":0.0
1303
+ },
1304
+ },
1305
+ "left":{
1306
+ "style": "SOLID",
1307
+ "width":2,
1308
+ "color": {
1309
+ "red": 0.0,
1310
+ "green":0.0,
1311
+ "blue":0.0
1312
+ },
1313
+ },
1314
+ "right":{
1315
+ "style": "SOLID",
1316
+ "width": 2,
1317
+ "color": {
1318
+ "red": 0.0,
1319
+ "green":0.0,
1320
+ "blue":0.0
1321
+ },
1322
+ },
1323
+ "innerHorizontal":{
1324
+ "style": "SOLID",
1325
+ "width":2,
1326
+ "color": {
1327
+ "red": 0.0,
1328
+ "green":0.0,
1329
+ "blue":0.0
1330
+ },
1331
+ },
1332
+ "innerVertical": {
1333
+ "style": "SOLID",
1334
+ "width": 2,
1335
+ "color": {
1336
+ "red": 0.0,
1337
+ "green":0.0,
1338
+ "blue":0.0
1339
+ },
1340
+ },
1341
+ }
1342
+ }
1343
+ ]
1344
+ }
1345
+ spreadsheet_service.spreadsheets().batchUpdate(spreadsheetId=spreadsheetId, body=body2).execute()
1346
+
1347
+ model_cell =worksheet.cell('A1')
1348
+ model_cell.set_text_format('bold', True)
1349
+ model_cell.set_horizontal_alignment( pygsheets.custom_types.HorizontalAlignment.CENTER )
1350
+ model_cell.color = (213/255, 219/255 ,255/255)
1351
+ pygsheets.DataRange('A2','I2', worksheet=worksheet).apply_format(model_cell)
1352
+ spreadsheet_url = "https://docs.google.com/spreadsheets/d/%s" % spreadsheetId
1353
+ print(spreadsheet_url)
1354
+ drive_service.permissions().update(transferOwnership=True , fileId=spreadsheetId,permissionId='11OfoB4Z6wOVII8mYmbnCbbqTQs7rYA65')
1355
+
1356
+
1357
+ return gc,spreadsheet_service,spreadsheetId ,spreadsheet_url , namepathArr
1358
+ #######################
1359
+
1360
+ def mapnametoLegend(McTName):
1361
+
1362
+ sectionKey = McTName.pop()
1363
+ key=sectionKey[0]
1364
+ section=sectionKey[1]
1365
+
1366
+ spreadsheet_service,drive_service,gc=authorizeLegend()
1367
+ spreadsheet_key =str(key) # Please set the Spreadsheet ID.
1368
+
1369
+ ws = gc.open_by_key(spreadsheet_key)
1370
+ guessednamesfinal=getguessnames(gc,ws)
1371
+ sheetnames=[]
1372
+ unit=''
1373
+ # ws.add_worksheet("Summary") # Please set the new sheet name.
1374
+ for i in ws._sheet_list:
1375
+ print(i)
1376
+ sheetnames.append(i.title)
1377
+ print(i.index)
1378
+ if 'XML Export Summary' in sheetnames:
1379
+ worksheetS = ws.worksheet_by_title('XML Export Summary')
1380
+ else:
1381
+ ws.add_worksheet("XML Export Summary") # Please set the new sheet name.
1382
+ worksheetw = ws.worksheet(0) #legend
1383
+ worksheetS = ws.worksheet_by_title('XML Export Summary')
1384
+ summaryId= ws[1].id
1385
+ worksheetS.clear()
1386
+ countnames=0
1387
+ row0=['MC_T Name','Qty','Unit']
1388
+ worksheetS.update_row(1,row0)
1389
+
1390
+ for i in range(len(McTName)):
1391
+ allgbnames=''
1392
+ item=''
1393
+ print(McTName[i][0])
1394
+
1395
+ # firstpart= re.split(r'[`\-=~!@#$%^&*()_+\[\]{};\'\\:"|<,./<>?]', McTName[i][0])
1396
+
1397
+ if McTName[i][2].startswith('Area'):
1398
+ if section.startswith('1.0'):
1399
+ rowvalue=5# column 5
1400
+ elif section.startswith('3.2'):
1401
+ rowvalue=3
1402
+ ar=0
1403
+ unit='m2'
1404
+ if McTName[i][2].startswith('Perimeter'):
1405
+ if section.startswith('1.0'):
1406
+ rowvalue=7# column 7
1407
+ elif section.startswith('3.2'):
1408
+ rowvalue=3
1409
+ ar=0
1410
+ unit='m'
1411
+ if McTName[i][2].startswith('Length'):
1412
+ if section.startswith('1.0'):
1413
+ rowvalue=9# column 7
1414
+ elif section.startswith('3.2'):
1415
+ rowvalue=3
1416
+ ar=0
1417
+ unit='m'
1418
+ if McTName[i][2].startswith('Count'):
1419
+ if section.startswith('1.0'):
1420
+ rowvalue=3# column 7
1421
+ elif section.startswith('3.2'):
1422
+ rowvalue=3
1423
+ ar=0
1424
+ unit='Nr'
1425
+
1426
+ print('mcct',McTName[i][1])
1427
+ if isinstance(McTName[i][1], list):
1428
+ for m in McTName[i][1]:
1429
+
1430
+ if m.startswith('gb') or m.startswith('p'):
1431
+ allgbnames+= m +' +'
1432
+
1433
+ roww=worksheetw.find(m)
1434
+ print(roww)
1435
+ for j in range(len(roww)):
1436
+ print('kjjjj',roww[j])
1437
+ ar+=float(worksheetw.cell((roww[j].row ,rowvalue)).value)
1438
+ else:
1439
+ item+=m + ' ,'
1440
+ print(item)
1441
+ n= McTName[i][0] + ' ( '+ allgbnames[:-2] +' , ' + item[:-1] + ' ) '
1442
+ else:
1443
+ if McTName[i][1].startswith('gb'):
1444
+ allgbnames+= McTName[i][1]
1445
+
1446
+ roww=worksheetw.find(McTName[i][1])
1447
+ print(roww)
1448
+ for j in range(len(roww)):
1449
+ print('kjjjj',roww[j])
1450
+ ar+=float(worksheetw.cell((roww[j].row ,rowvalue)).value)
1451
+ n= McTName[i][0] + ' ( '+ allgbnames + ' ) '
1452
+
1453
+ rowi=[str(n),ar,unit]
1454
+ worksheetS.update_row(i+2,rowi)
1455
+ # worksheetS.adjust_column_width(start=1,end=4)
1456
+ worksheetS.adjust_column_width(start=1,end=1, pixel_size=350)
1457
+ worksheetS.adjust_column_width(start=2,end=2, pixel_size=100)
1458
+ worksheetS.adjust_column_width(start=3,end=3)
1459
+
1460
+ xx=(worksheetS.cell( ( len(McTName) +1 ,3)) ).address.label
1461
+ model_cell1 =worksheetS.cell('A2')
1462
+ model_cell1.set_horizontal_alignment( pygsheets.custom_types.HorizontalAlignment.LEFT )
1463
+ pygsheets.DataRange('A2', str(xx), worksheet=worksheetS).apply_format(model_cell1)
1464
+
1465
+
1466
+ model_cell =worksheetS.cell('A1')
1467
+ model_cell.set_text_format('bold', True)
1468
+ model_cell.set_horizontal_alignment( pygsheets.custom_types.HorizontalAlignment.CENTER )
1469
+ pygsheets.DataRange('A1','C1', worksheet=worksheetS).apply_format(model_cell)
1470
+
1471
+ body2={
1472
+ "requests": [
1473
+ {
1474
+ "updateBorders": {
1475
+ "range": {
1476
+ "sheetId": str(summaryId),
1477
+ "startRowIndex": 0,
1478
+ "endRowIndex": len(McTName) +1 ,
1479
+ "startColumnIndex": 0,
1480
+ "endColumnIndex": 3
1481
+ },
1482
+ "top": {
1483
+ "style": "SOLID",
1484
+ "width": 2,
1485
+ "color": {
1486
+ "red": 0.0,
1487
+ "green":0.0,
1488
+ "blue":0.0
1489
+ },
1490
+ },
1491
+ "bottom": {
1492
+ "style": "SOLID",
1493
+ "width": 2,
1494
+ "color": {
1495
+ "red": 0.0,
1496
+ "green":0.0,
1497
+ "blue":0.0
1498
+ },
1499
+ },
1500
+ "left":{
1501
+ "style": "SOLID",
1502
+ "width":2,
1503
+ "color": {
1504
+ "red": 0.0,
1505
+ "green":0.0,
1506
+ "blue":0.0
1507
+ },
1508
+ },
1509
+ "right":{
1510
+ "style": "SOLID",
1511
+ "width": 2,
1512
+ "color": {
1513
+ "red": 0.0,
1514
+ "green":0.0,
1515
+ "blue":0.0
1516
+ },
1517
+ },
1518
+ "innerHorizontal":{
1519
+ "style": "SOLID",
1520
+ "width":2,
1521
+ "color": {
1522
+ "red": 0.0,
1523
+ "green":0.0,
1524
+ "blue":0.0
1525
+ },
1526
+ },
1527
+ "innerVertical": {
1528
+ "style": "SOLID",
1529
+ "width": 2,
1530
+ "color": {
1531
+ "red": 0.0,
1532
+ "green":0.0,
1533
+ "blue":0.0
1534
+ },
1535
+ },
1536
+ }
1537
+ }
1538
+ ]
1539
+ }
1540
+ spreadsheet_service.spreadsheets().batchUpdate(spreadsheetId=spreadsheet_key, body=body2).execute()
1541
+ return summaryId,guessednamesfinal
1542
+
1543
+ # print(x,xarea)
1544
+ def getguessnames(gc,ws):
1545
+ guessednamesfinal=[]
1546
+ worksheetw = ws.worksheet(0)
1547
+ guessednames=worksheetw.get_col(1, returnas='matrix', include_tailing_empty=False)
1548
+ print(guessednames[2:])
1549
+ for item in guessednames[2:]:
1550
+ if item not in guessednamesfinal:
1551
+ guessednamesfinal.append(item)
1552
+ print(guessednamesfinal)
1553
+ return guessednamesfinal
1554
+
1555
+ ################################################################
pixelconversion.py ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """pixelconversion.ipynb
3
+
4
+ Automatically generated by Colaboratory.
5
+
6
+ Original file is located at
7
+ https://colab.research.google.com/drive/1hfdgkYOw8w6DdJqsZx8txmw8INUGxesl
8
+ """
9
+
10
+
11
+ # pip install pymupdf -q
12
+
13
+ """### Imports"""
14
+
15
+ import fitz
16
+ from PIL import Image
17
+ import numpy as np
18
+ import cv2
19
+ import db
20
+
21
+ """### Open PDF and draw a rectangle on it using Fitz"""
22
+ def openDrawPDF(path):
23
+ doc = fitz.open(path)
24
+ page = doc[0]
25
+ pix = page.get_pixmap(dpi=200) # render page to an image
26
+
27
+ if page.rect.height > page.rect.width:
28
+ rect = fitz.Rect(10, 10, (10+page.rect.width-50),( 10+700))
29
+ rectText=fitz.Rect(300, 200, (10+page.rect.width-50),( 300+100))
30
+ rotate=90
31
+ else:
32
+ rect = fitz.Rect(10, 10,( 10+page.rect.height-50),(10+700))
33
+ rectText=fitz.Rect(300, 200,(10+page.rect.height-50) ,( 300+100))
34
+ rotate=0
35
+ annot = page.add_rect_annot(rect)
36
+ annot.set_colors( fill=(75/255,0,130/255) ,stroke=(75/255,0,130/255) )
37
+ annot.set_opacity(0.9)
38
+ annot.set_border(border=None, width=0)
39
+ annot.update()
40
+
41
+ text = """Scale Document"""
42
+ annot1=page.add_freetext_annot(rectText, text, fontsize=45, fontname='helv', border_color=(1,1,1), text_color=(1,1,1), rotate=rotate, align=1)
43
+ annot1.update()
44
+ perm = int( # permissions bit flags
45
+ fitz.PDF_PERM_ACCESSIBILITY #always use this
46
+ | fitz.PDF_PERM_PRINT # permits printing
47
+
48
+ )
49
+ encrypt = fitz.PDF_ENCRYPT_AES_256 # strongest algorithm
50
+ # Ndoc=doc.write(encryption=encrypt,permissions=perm)
51
+
52
+ return doc
53
+ """### Extract color"""
54
+
55
+ def DetectColor(img,color=0):
56
+
57
+ imgCopy=img.copy()
58
+ imgCopy=cv2.cvtColor(imgCopy,cv2.COLOR_BGR2HSV)
59
+ tol=5 #tolerance
60
+ # color=hexRGB(color)
61
+ h,s,v = cv2.cvtColor(np.uint8([[[color[2],color[1],color[0]]]]),cv2.COLOR_BGR2HSV)[0][0]
62
+
63
+ lower =np.array( [h- tol, 100, 100 ], dtype='uint8')
64
+ upper = np.array( [h + tol, 255, 255],dtype='uint8')
65
+
66
+ mask = cv2.inRange(imgCopy, lower , upper)
67
+
68
+ detectedColors = cv2.bitwise_and(imgCopy,imgCopy, mask= mask) # Bitwise-AND mask and original image
69
+
70
+ kernel=np.ones((3,3),np.uint8)
71
+ mask=cv2.dilate(mask,kernel, iterations=5)
72
+ mask=cv2.erode(mask,kernel, iterations=4)
73
+
74
+ detectedColors=cv2.dilate(detectedColors,kernel, iterations=5)
75
+ detectedColors=cv2.erode(detectedColors,kernel, iterations=4)
76
+
77
+ detectedColors=cv2.cvtColor(detectedColors,cv2.COLOR_HSV2BGR)
78
+ detectedColors=cv2.medianBlur(detectedColors,7)
79
+ # cv2_imshow(detectedColors)
80
+
81
+ return mask
82
+
83
+ """### For backend - calc area and perim"""
84
+
85
+ def getAreaPerimeter(pdfpath, plan):
86
+ dbx=db.dropbox_connect()
87
+ md, res =dbx.files_download(path= pdfpath+plan)
88
+ data = res.content
89
+ doc=fitz.open("pdf", data)
90
+ for page in doc:
91
+ pix = page.get_pixmap(dpi=200) # render page to an image
92
+ pl=Image.frombytes('RGB', [pix.width,pix.height],pix.samples)
93
+ img=np.array(pl)
94
+ print(img.shape)
95
+ img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
96
+ mask=DetectColor(img,color=(73,0,130)) #detect colored rect drawn on the pdf
97
+
98
+ contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
99
+ for contour in contours:
100
+ area = cv2.contourArea(contour)
101
+ perimeter = cv2.arcLength(contour, True)
102
+ return area,perimeter
tameem3_2.py ADDED
@@ -0,0 +1,659 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """3.2(Ready for new interface).ipynb
3
+
4
+ Automatically generated by Colaboratory.
5
+
6
+ Original file is located at
7
+ https://colab.research.google.com/drive/16maX93rvCuU14RBPDK60YxXqxv7aB4Jz
8
+
9
+ # Libraries
10
+ """
11
+
12
+ # from google.colab.patches import cv2_imshow
13
+ import cv2
14
+ import numpy as np
15
+ import pandas as pd
16
+
17
+ import statistics
18
+ from statistics import mode
19
+
20
+ from PIL import Image
21
+
22
+ # !pip install easydev
23
+ # !pip install colormap
24
+ # !pip install extcolors
25
+
26
+ import matplotlib.pyplot as plt
27
+ import matplotlib.patches as patches
28
+
29
+ import extcolors
30
+
31
+ from colormap import rgb2hex
32
+
33
+ # !pip install pypdfium2
34
+
35
+ import pypdfium2 as pdfium
36
+ import math
37
+ import fitz
38
+ import db
39
+ import pilecaps_adr
40
+ """# Reading Pdf file and returning image ready to use
41
+
42
+ """
43
+
44
+ def convert2img(path):
45
+ pdf = pdfium.PdfDocument(path)
46
+ page = pdf.get_page(0)
47
+ pil_image = page.render().to_pil()
48
+ pl1=np.array(pil_image)
49
+ img = cv2.cvtColor(pl1, cv2.COLOR_RGB2BGR)
50
+ return img
51
+
52
+ def readImgggg(img):
53
+ hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
54
+ return hsv
55
+
56
+ #change Background to red, this step before changing the gray shapes
57
+ #This function helps in improving colour extraction later in the code
58
+ def changeBackground(img):
59
+ imgCopy = img.copy()
60
+ hsv = cv2.cvtColor(imgCopy, cv2.COLOR_BGR2HSV)
61
+ white_range_low = np.array([0,0,250])
62
+ white_range_high = np.array([0,0,255])
63
+ mask2=cv2.inRange(hsv,white_range_low, white_range_high)
64
+ imgCopy[mask2>0]=(0,0,255)
65
+ return imgCopy
66
+
67
+ #If there any gray shapes it will be changed to blue
68
+ def changeGrayModify(img):
69
+ noGray = changeBackground(img)
70
+ hsv = cv2.cvtColor(noGray, cv2.COLOR_BGR2HSV)
71
+ gray_range_low = np.array([0,0,170])
72
+ gray_range_high = np.array([150,30,255])
73
+ mask=cv2.inRange(hsv,gray_range_low,gray_range_high)
74
+ noGray[mask>0]=(255,0,0)
75
+ return noGray
76
+
77
+ #We may use this function to return background to white after changing the gray shapes to blue
78
+ def returnWhite(img):
79
+ imgCopy = img.copy()
80
+ hsv = cv2.cvtColor(imgCopy, cv2.COLOR_BGR2HSV)
81
+ red_range_low = np.array([0,250,250])
82
+ red_range_high = np.array([0,255,255])
83
+ mask2=cv2.inRange(hsv,red_range_low, red_range_high)
84
+ imgCopy[mask2>0]=(255,255,255)
85
+ return imgCopy
86
+
87
+ """# Extracting colours for the next phase (preprocessing)"""
88
+
89
+ #This function will take the image with red background and extract all the colours in the plan
90
+ def extractClrs(medianF):
91
+ im = cv2.cvtColor(medianF, cv2.COLOR_BGR2RGB)
92
+ im = Image.fromarray(im)
93
+ colors_x = extcolors.extract_from_image(im,8,8)
94
+ listofTuples = []
95
+ for i in range(len(colors_x[0])):
96
+ listofTuples.append(colors_x[0][i][0])
97
+ rgb = []
98
+ for i in range(len(listofTuples)):
99
+ rgb.append([])
100
+ for i in range(len(listofTuples)):
101
+ for j in range(len(listofTuples[i])):
102
+ rgb[i].append(listofTuples[i][j])
103
+ rgb = np.uint8([[rgb]])
104
+ clr_hsv = []
105
+ for i in range(len(rgb)):
106
+ clr_hsv.append(cv2.cvtColor(rgb[i], cv2.COLOR_RGB2HSV))
107
+ return clr_hsv
108
+
109
+ #Used to delete any gray or white colours detected
110
+ def deleteZeroHue(clr_hsv):
111
+ clr_hsv_short = []
112
+ for i in range(len(clr_hsv[0][0])):
113
+ if clr_hsv[0][0][i][0] > 0:
114
+ clr_hsv_short.append(clr_hsv[0][0][i])
115
+ return clr_hsv_short
116
+
117
+ #Saving the region of the different colours in the plan
118
+ def dividingInput(clr_hsv_short):
119
+ hInput = []
120
+ sInput = []
121
+ vInput = []
122
+ for i in range(len(clr_hsv_short)):
123
+ hInput.append(clr_hsv_short[i][0])
124
+ sInput.append(clr_hsv_short[i][1])
125
+ vInput.append(clr_hsv_short[i][2])
126
+ return hInput, sInput, vInput
127
+
128
+ #Setting the range of upper and lower range of the Hue of different colours
129
+ #Will be used to separate each shape inside the plan in a different img due to their different colours
130
+ def setRange(n, hInput):
131
+ lower = []
132
+ upper = []
133
+ for i in range(len(hInput)):
134
+ if (hInput[i] - n > 0):
135
+ lower.append(np.uint(hInput[i] - n))
136
+ else:
137
+ lower.append(np.uint(hInput[i]))
138
+ upper.append(np.uint(hInput[i] + n))
139
+ return lower, upper
140
+
141
+ """# Reading the image's colours"""
142
+
143
+ #Saving all the hues, saturations, values of the plan
144
+ def getColoursImage(hsv, img):
145
+ hue = hsv[:,:,0]
146
+ saturation = hsv[:,:,1]
147
+ value = hsv[:,:,2]
148
+ h=[]
149
+ s=[]
150
+ v=[]
151
+
152
+ for i in range(img.shape[1]):
153
+ for j in range(img.shape[0]):
154
+ if hue[j][i] > 0 :
155
+ h.append(hue[j][i])
156
+ s.append(saturation[j][i])
157
+ v.append(value[j][i])
158
+ return h,s,v
159
+
160
+ #Putting different hues in different categories (each colour is a category)
161
+ def categorizeV4(hsv, lower, upper, img):
162
+ h, s, v = getColoursImage(hsv, img)
163
+ groups = []
164
+ for i in range(len(lower)):
165
+ groups.append([])
166
+ for i in range(len(h)):
167
+ for j in range(len(lower)):
168
+ if h[i] in range(lower[j],upper[j]):
169
+ groups[j].append([h[i], s[i], v[i]])
170
+ return groups
171
+
172
+ #Putting the hue, saturation, values in the categories
173
+ def getHuesV3(categorey):
174
+ hues = []
175
+ for i in range(len(categorey)):
176
+ hues.append([])
177
+ for i in range(len(categorey)):
178
+ for j in range(len(categorey[i])):
179
+ hues[i].append(categorey[i][j][0])
180
+ return hues
181
+
182
+ def getSaturationsV3(categorey):
183
+ saturations = []
184
+ for i in range(len(categorey)):
185
+ saturations.append([])
186
+ for i in range(len(categorey)):
187
+ for j in range(len(categorey[i])):
188
+ saturations[i].append(categorey[i][j][1])
189
+ return saturations
190
+
191
+ def getValuesV3(categorey):
192
+ values = []
193
+ for i in range(len(categorey)):
194
+ values.append([])
195
+ for i in range(len(categorey)):
196
+ for j in range(len(categorey[i])):
197
+ values[i].append(categorey[i][j][2])
198
+ return values
199
+
200
+ #Getting the maximum and minimum of each h,s,v of each category
201
+ def setBoundaries(hues, saturations, values):
202
+
203
+ hueMin = []
204
+ hueMax = []
205
+ satMin = []
206
+ satMax = []
207
+ valMin = []
208
+ valMax = []
209
+
210
+ for i in range(len(hues)):
211
+ hueMin.append(min(hues[i]))
212
+ hueMax.append(max(hues[i]))
213
+
214
+ for i in range(len(saturations)):
215
+ satMin.append(min(saturations[i]))
216
+ satMax.append(max(saturations[i]))
217
+
218
+ for i in range(len(values)):
219
+ valMin.append(min(values[i]))
220
+ valMax.append(max(values[i]))
221
+ return hueMin, hueMax, satMin, satMax, valMin, valMax
222
+
223
+ """# Colour Segmentation"""
224
+
225
+ #Producing List of images, each image contains a shape of different Colour (imgResult)
226
+ def segment(hueMin, hueMax, satMin, satMax, valMin, valMax):
227
+ lowerRange = []
228
+ upperRange = []
229
+ for i in range(len(hueMin)):
230
+ #lowerRange.append([hueMin[i], satMin[i] , valMin[i]])
231
+ lowerRange.append([hueMin[i], np.uint8(satMin[i] +15) , valMin[i]])
232
+ upperRange.append([hueMax[i], satMax[i], valMax[i]])
233
+ lower_range = np.array(lowerRange)
234
+ upper_range = np.array(upperRange)
235
+ return lower_range, upper_range
236
+
237
+
238
+ def masking(lower_range, upper_range, hsvMedian, img):
239
+ mask = []
240
+ imgResult = []
241
+ for i in range(len(lower_range)):
242
+ mask.append(cv2.inRange(hsvMedian, lower_range[i], upper_range[i]))
243
+ for j in range(len(lower_range)):
244
+ imgResult.append(cv2.bitwise_and(img, img, mask=mask[j]))
245
+ return imgResult
246
+
247
+ """# Preprocessing"""
248
+
249
+ # Returning a Clean Image ready to be used in measurement
250
+ def bluring(imgResult):
251
+ imgGray = []
252
+ imgBlur = []
253
+ for i in range(len(imgResult)):
254
+ imgGray.append(cv2.cvtColor(imgResult[i], cv2.COLOR_BGR2GRAY))
255
+ for i in range(len(imgGray)):
256
+ imgBlur.append(cv2.GaussianBlur(imgGray[i], (5,5),3))
257
+ return imgBlur
258
+
259
+ def preprocessing(imgBlur):
260
+ imTT = []
261
+ th2 = []
262
+ for i in range(len(imgBlur)):
263
+ imTT.append([])
264
+ for k in range(len(imgBlur)):
265
+ for i in range(imgBlur[k].shape[1]):
266
+ for j in range(imgBlur[k].shape[0]):
267
+ if imgBlur[k][j][i] > 5:
268
+ imTT[k].append(imgBlur[k][j][i])
269
+ modd = []
270
+ for i in range(len(imTT)):
271
+ modd.append(mode(imTT[i]))
272
+ for i in range(len(imgBlur)):
273
+ th2.append(cv2.threshold(imgBlur[i],modd[i]-70,255,cv2.THRESH_BINARY))
274
+ return th2
275
+
276
+ def is_contour_bad(c):
277
+ peri = cv2.arcLength(c, True)
278
+ approx = cv2.approxPolyDP(c, 0.02 * peri, True)
279
+ return cv2.contourArea(c) < 1200
280
+
281
+ def beforeCelaning(maskBad, th2):
282
+ imgb4Cleaned = []
283
+ for i in range(len(th2)):
284
+ imgb4Cleaned.append(th2[i][1].copy())
285
+ return imgb4Cleaned
286
+
287
+ def badMask(imgResult, img):
288
+ maskBad = []
289
+ for i in range(len(imgResult)):
290
+ maskBad.append(np.ones(img.shape[:2], dtype="uint8") * 255)
291
+ return maskBad
292
+
293
+ def applyBadContours(imgb4Cleaned, th2, maskBad):
294
+ imgCleaned = []
295
+ for j in range(len(th2)):
296
+ contours, hierarchy = cv2.findContours(image=th2[j][1], mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_SIMPLE)
297
+ for k, cnt in enumerate(contours):
298
+ if is_contour_bad(cnt):
299
+ cv2.drawContours(maskBad[j], [cnt], -1, 0, -1)
300
+ imgCleaned.append(cv2.bitwise_and(imgb4Cleaned[j], th2[j][1], mask=maskBad[j]))
301
+ return imgCleaned
302
+ def morph(imgCleaned):
303
+ dilations = []
304
+ kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
305
+ for i in range(len(imgCleaned)):
306
+ dilations.append(cv2.dilate(imgCleaned[i], kernel, iterations=2))
307
+ return dilations
308
+
309
+ """# (optional) If we want to get those rectangle colours in producing Legends"""
310
+
311
+ def extractNewRgb(imgResult):
312
+ im = cv2.cvtColor(imgResult, cv2.COLOR_BGR2RGB)
313
+ im = Image.fromarray(im)
314
+ colors_x = extcolors.extract_from_image(im,2,2)
315
+
316
+ listofTuples = []
317
+ for i in range(len(colors_x[0])):
318
+ listofTuples.append(colors_x[0][i][0])
319
+ rgb = []
320
+ for i in range(len(listofTuples)):
321
+ rgb.append([])
322
+ for i in range(len(listofTuples)):
323
+ for j in range(len(listofTuples[i])):
324
+ rgb[i].append(listofTuples[i][j])
325
+ return rgb
326
+
327
+ def intRgb(imgResult):
328
+ list_keda = []
329
+ for i in range(len(imgResult)):
330
+ list_keda.append(extractNewRgb(imgResult[i]))
331
+ newRgb = []
332
+ for i in range(len(list_keda)):
333
+ newRgb.append(list_keda[i][1])
334
+
335
+ list_int = []
336
+ for i in range(len(newRgb)):
337
+ list_int.append([])
338
+
339
+ for i in range(len(newRgb)):
340
+ for j in range(len(newRgb[i])):
341
+ list_int[i].append(int(newRgb[i][j]))
342
+ return list_int
343
+
344
+ def rgb2hexa(list_int):
345
+ x = []
346
+ for i in range(len(list_int)):
347
+ x.append(rgb2hex(list_int[i][0],list_int[i][1],list_int[i][2]))
348
+ return x
349
+
350
+ # (optional) If we want to get those rectangle colours in producing Legends
351
+
352
+ def extractNewRgb(imgResult):
353
+ im = cv2.cvtColor(imgResult, cv2.COLOR_BGR2RGB)
354
+ im = Image.fromarray(im)
355
+ colors_x = extcolors.extract_from_image(im,2,2)
356
+
357
+ listofTuples = []
358
+ for i in range(len(colors_x[0])):
359
+ listofTuples.append(colors_x[0][i][0])
360
+ rgb = []
361
+ for i in range(len(listofTuples)):
362
+ rgb.append([])
363
+ for i in range(len(listofTuples)):
364
+ for j in range(len(listofTuples[i])):
365
+ rgb[i].append(listofTuples[i][j])
366
+ return rgb
367
+
368
+ def intRgb(imgResult):
369
+ list_keda = []
370
+ for i in range(len(imgResult)):
371
+ list_keda.append(extractNewRgb(imgResult[i]))
372
+ newRgb = []
373
+ for i in range(len(list_keda)):
374
+ newRgb.append(list_keda[i][1])
375
+
376
+ list_int = []
377
+ for i in range(len(newRgb)):
378
+ list_int.append([])
379
+
380
+ for i in range(len(newRgb)):
381
+ for j in range(len(newRgb[i])):
382
+ list_int[i].append(int(newRgb[i][j]))
383
+ return list_int
384
+
385
+ def rgb2hexa(list_int):
386
+ x = []
387
+ for i in range(len(list_int)):
388
+ x.append(rgb2hex(list_int[i][0],list_int[i][1],list_int[i][2]))
389
+ return x
390
+
391
+
392
+ """# Measuring Area
393
+
394
+ """
395
+
396
+ # Produce List of shape's area in PPIXELS
397
+ def getArea(dilation):
398
+ contourzz, hierarchy = cv2.findContours(image=dilation, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_NONE)
399
+ areaa = 0
400
+
401
+ for i, cnt3 in enumerate(contourzz):
402
+ M = cv2.moments(cnt3)
403
+ if M['m00'] != 0.0:
404
+ x2 = int(M['m10']/M['m00'])
405
+ y2 = int(M['m01']/M['m00'])
406
+ area3 = cv2.contourArea(cnt3)
407
+ areaa = areaa+area3
408
+ return areaa
409
+
410
+ def measure(dilations):
411
+ areas = []
412
+ for i in range(len(dilations)):
413
+ areas.append(getArea(dilations[i]))
414
+ return areas
415
+
416
+ #Producing Image with drawing Contours and putting the number of areas as text on the shape
417
+ def getDrawing(page,ratio,dilation, img ,areaRatio,perimRatio):
418
+
419
+ contourzz, hierarchy = cv2.findContours(image=dilation, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_NONE)
420
+ areaa = 0
421
+ perimeter = 0
422
+ imgNew = img
423
+
424
+ for i, cnt3 in enumerate(contourzz):
425
+ shape=[]
426
+ M = cv2.moments(cnt3)
427
+ if M['m00'] != 0.0:
428
+ x2 = int(M['m10']/M['m00'])
429
+ y2 = int(M['m01']/M['m00'])
430
+ area3 = cv2.contourArea(cnt3)
431
+ areaRatio1= area3*areaRatio
432
+ areaa = areaa+area3
433
+ perimeter3 = cv2.arcLength(cnt3, True)
434
+ perimeterRatio1=perimeter3*perimRatio
435
+ perimeterr = perimeter+perimeter3
436
+ approx = cv2.approxPolyDP(cnt3, 0.005 * perimeter3, True)
437
+ for point in approx:
438
+ x1, y1 = point[0]
439
+ shape.append([int(x1*ratio),int(y1*ratio)])
440
+ #areaa = round(areaa * 15.25/13480.0, 3)
441
+
442
+
443
+ cv2.putText(imgNew, f'Area :{areaa}', (x2, y2), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
444
+ imgNew = cv2.drawContours(img, [cnt3], -1, (0,255,255), 3)
445
+ annot = page.add_polygon_annot( points=shape ) # 'Polygon'
446
+ annot.set_border(width=0.3, dashes=[2])
447
+ annot.set_colors( fill=( 0 , 1, 1 ) )
448
+ # annot.set_colors( fill=(1,0,1) )
449
+ annot.set_opacity(0.5)
450
+ annot.set_info(content='Area='+str(areaRatio1)+' m2' +'\n \nPerimeter='+str(perimeterRatio1)+' m',subject='ADR Team')#,title='uuum')
451
+ # annot.set_line_ends(fitz.PDF_ANNOT_LE_DIAMOND, fitz.PDF_ANNOT_LE_CIRCLE)
452
+ annot.update()
453
+ # doc.save('tameem.pdf', deflate=True)
454
+ return imgNew
455
+
456
+
457
+ def exDraw(plan, dilations, img, pdfpath,areaRatio,perimRatio):
458
+ ##
459
+ doc = fitz.open('dropbox_plans/3.2/'+plan)
460
+ page = doc[0]
461
+ page.set_rotation(0)
462
+ pix=page.get_pixmap()
463
+ ratio = pix.width/ img.shape[1]
464
+ ###
465
+ print(pdfpath)
466
+ newImg = img
467
+ for i in range(len(dilations)):
468
+ newImg = (getDrawing(page,ratio, dilations[i], img ,areaRatio,perimRatio))
469
+ # doc.save('tameem.pdf', deflate=True)
470
+ pdflink= db.dropbox_upload_file(doc=doc,pdfname=plan,pdfpath=pdfpath)
471
+
472
+ print(pdflink)
473
+ return newImg , pdflink
474
+ # Perimeter
475
+
476
+ def getPerimeter(dilation):
477
+ contourzz, hierarchy = cv2.findContours(image=dilation, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_NONE)
478
+ perimeter = 0
479
+ for i, cnt3 in enumerate(contourzz):
480
+ #imgResult4 = img.copy()
481
+ M = cv2.moments(cnt3)
482
+ if M['m00'] != 0.0:
483
+ x2 = int(M['m10']/M['m00'])
484
+ y2 = int(M['m01']/M['m00'])
485
+ perimeter3 = cv2.arcLength(cnt3, True)
486
+ perimeter = perimeter+perimeter3
487
+ return perimeter
488
+ def measureP(dilations):
489
+ perimeters = []
490
+ for i in range(len(dilations)):
491
+ perimeters.append(getPerimeter(dilations[i]))
492
+ return perimeters
493
+
494
+ # Number of Shapes
495
+
496
+
497
+ def getNumber(dilation):
498
+ contourzz, hierarchy = cv2.findContours(image=dilation, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_NONE)
499
+ n_shapes = 0
500
+ for i, cnt3 in enumerate(contourzz):
501
+ #imgResult4 = img.copy()
502
+ M = cv2.moments(cnt3)
503
+ if M['m00'] != 0.0:
504
+ x2 = int(M['m10']/M['m00'])
505
+ y2 = int(M['m01']/M['m00'])
506
+ n_shapes = n_shapes + 1
507
+ return n_shapes
508
+
509
+ def countShapes(dilations):
510
+ n_shapes = []
511
+ for i in range(len(dilations)):
512
+ n_shapes.append(getNumber(dilations[i]))
513
+ return n_shapes
514
+
515
+ # Length
516
+
517
+
518
+ def getLength(dilation):
519
+ contourzz, hierarchy = cv2.findContours(image=dilation, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_NONE)
520
+ perimeter = 0
521
+ for i, cnt3 in enumerate(contourzz):
522
+ #imgResult4 = img.copy()
523
+ M = cv2.moments(cnt3)
524
+ if M['m00'] != 0.0:
525
+ x2 = int(M['m10']/M['m00'])
526
+ y2 = int(M['m01']/M['m00'])
527
+ x, y, w, h = cv2.boundingRect(cnt3)
528
+ return w
529
+ def measureL(dilations):
530
+ Length = []
531
+ for i in range(len(dilations)):
532
+ Length.append(getLength(dilations[i]))
533
+ return Length
534
+
535
+ """# Converting Pixels to M2
536
+
537
+ """
538
+
539
+ #Producing Reference Object and calculating it's vale in PIXELS
540
+ def calcRef(img):
541
+ blk = np.ones(img.shape, dtype="uint8") * [[[np.uint8(0), np.uint8(0), np.uint8(0)]]]
542
+
543
+ start_point = (50, 100)
544
+ end_point = (120, 200)
545
+ color = (255, 255, 255) # white BGR
546
+ thickness = -1 # Thickness of -1 will fill the entire shape
547
+
548
+ blk = cv2.rectangle(blk, start_point, end_point, color, thickness)
549
+
550
+ blk = cv2.cvtColor(blk, cv2.COLOR_BGR2GRAY)
551
+
552
+ contourzz, hierarchy = cv2.findContours(image=blk, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_NONE)
553
+ for i, cnt3 in enumerate(contourzz):
554
+ M = cv2.moments(cnt3)
555
+ if M['m00'] != 0.0:
556
+ x2 = int(M['m10']/M['m00'])
557
+ y2 = int(M['m01']/M['m00'])
558
+ area = cv2.contourArea(cnt3)
559
+ return area
560
+
561
+ # Saving the Area of the Reference object in M2 that we get from the user
562
+ def getRealRef(area):
563
+ areaFromUser = area
564
+ return areaFromUser
565
+
566
+ # Calculating the M2 areas of each shape and saving them in a List
567
+ # areaGotFromUser --> User will pass it after measuring the produced shape in BB
568
+ # areaPixelRef --> will get it from calcRef() function
569
+ # areas --> will get it from the measure() function in the "Measuring Area Cells"
570
+ def m2R(PixelMetricRatio, areas):
571
+ mreal = []
572
+ for i in range(len(areas)):
573
+ mreal.append(areas[i] * PixelMetricRatio)
574
+ return mreal
575
+
576
+ """# Another approach (Getting the display screen dimensions from user)"""
577
+
578
+ def ppi_calculate(width, height, inch):
579
+ diagonal = math.sqrt((width**2 )+(height**2))
580
+ ppi = diagonal / inch
581
+ ppi2 = ppi * ppi
582
+ return ppi2
583
+ def convertToMeterSQ(ratio, areas):
584
+ areaM2 = []
585
+ for i in range(len(areas)):
586
+ areaM2.append(round(areas[i] * ratio, 3)) # true value of area of any shape/ area px value of same shape
587
+ return areaM2
588
+
589
+ """# Main Function That calls all of the above functions"""
590
+
591
+ def mainFunction(plan, areaRatio ,perimRatio, pdfpath):
592
+ plan1='dropbox_plans/3.2/'+str(plan)
593
+ img = convert2img(plan1)
594
+ img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
595
+ imgChange = changeGrayModify(img)
596
+ hsv = readImgggg(imgChange)
597
+ clr_hsv = extractClrs(imgChange)
598
+ clr_hsv_short = deleteZeroHue(clr_hsv)
599
+ hInput, sInput, vInput = dividingInput(clr_hsv_short)
600
+ lower, upper = setRange(5, hInput)
601
+ cat2 = categorizeV4(hsv, lower, upper, img)
602
+ hues = getHuesV3(cat2)
603
+ values = getValuesV3(cat2)
604
+ saturations = getSaturationsV3(cat2)
605
+ hueMin, hueMax, satMin, satMax, valMin, valMax = setBoundaries(hues, saturations, values)
606
+ lower_range, upper_range = segment(hueMin, hueMax, satMin, satMax, valMin, valMax)
607
+ imgResult = masking(lower_range, upper_range, hsv, img)
608
+ ##For the Legend newRgb and hexClrs, make the main function returns one of the following two variables
609
+ ## newRgb or hexClrs
610
+ newRgb = intRgb(imgResult)
611
+ hexClrs = rgb2hexa(newRgb)
612
+ imgBlur = bluring(imgResult)
613
+ th2 = preprocessing(imgBlur)
614
+ maskBad = badMask(imgResult, img)
615
+ imgb4Cleaned = beforeCelaning(maskBad,th2)
616
+ imgCleaned = applyBadContours(imgb4Cleaned, th2, maskBad)
617
+ dilations = morph(imgCleaned)
618
+ # newImg , pdflink = exDraw(plan, dilations, img , pdfpath)
619
+ areas = measure(imgCleaned)
620
+ perimeters = measureP(imgCleaned)
621
+ quantites = countShapes(imgCleaned)
622
+ length = measureL(imgCleaned)
623
+
624
+ # area_ref_pixel, perimeter_ref_pixel = calcRef(img)
625
+
626
+ # area_ref_real = getRealRef(areaRef)
627
+ # perimeter_ref_real = getRealRefL(perimeterRef)
628
+ realArea = m2R(areaRatio, areas)
629
+ realPerimeter = m2R(perimRatio, perimeters)
630
+
631
+ newImg , pdflink= exDraw(plan,dilations, img, pdfpath,areaRatio, perimRatio )
632
+ data = {
633
+ 'Color' : newRgb,
634
+ 'Occurences': quantites,
635
+ 'Area':realArea,
636
+ 'Total Area': realArea,
637
+ 'Perimeter':perimeters,
638
+ 'Total Perimeter': perimeters,
639
+ 'Length': length,
640
+ 'Total Length': length}
641
+ df = pd.DataFrame(data)
642
+ print(df)
643
+
644
+
645
+ gc,spreadsheet_service,spreadsheetId, spreadsheet_url , namepathArr= pilecaps_adr.legendGoogleSheets(df,plan ,pdfpath)
646
+
647
+ dbx=db.dropbox_connect()
648
+
649
+ md, res =dbx.files_download(path= pdfpath+plan)
650
+ data = res.content
651
+
652
+ doc=fitz.open("pdf", data)
653
+ # list1=pd.DataFrame(columns=['content', 'creationDate', 'id', 'modDate', 'name', 'subject', 'title'])
654
+ list1=pd.DataFrame(columns=['content', 'id', 'subject'])
655
+ for page in doc:
656
+ for annot in page.annots():
657
+ list1.loc[len(list1)] =annot.info
658
+ print(list1)
659
+ return newImg, df , pdflink , spreadsheetId, spreadsheet_url , list1