Marthee commited on
Commit
371a5d5
·
verified ·
1 Parent(s): fb5d442

Upload 3 files

Browse files
Files changed (3) hide show
  1. Code_2_7.py +0 -0
  2. Legend_Detection.py +564 -0
  3. app.py +0 -0
Code_2_7.py CHANGED
The diff for this file is too large to render. See raw diff
 
Legend_Detection.py ADDED
@@ -0,0 +1,564 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ """## Imports"""
3
+ import sys
4
+ import math
5
+ import random
6
+ import string
7
+ import zlib
8
+ import base64
9
+ import datetime
10
+ import uuid
11
+ import re
12
+ from io import BytesIO
13
+ from ctypes import sizeof
14
+ from collections import Counter
15
+ from typing import NewType
16
+ import xml.etree.ElementTree as ET
17
+ from xml.etree.ElementTree import Element, SubElement, tostring, ElementTree
18
+ from xml.dom.minidom import parseString
19
+
20
+ import numpy as np
21
+ import cv2
22
+ from matplotlib import pyplot as plt
23
+ from matplotlib.patches import Polygon
24
+ from shapely.geometry import Point, Polygon as ShapelyPolygon
25
+ from shapely.ops import unary_union
26
+ from PIL import Image, ImageDraw, ImageFont, ImageColor
27
+
28
+ import fitz
29
+ import ezdxf
30
+ from ezdxf import units, bbox
31
+ from ezdxf.colors import aci2rgb
32
+ from ezdxf.math import OCS, Matrix44, Vec3, Vec2
33
+
34
+ import pandas as pd
35
+ import google_sheet_Legend
36
+ import tsadropboxretrieval
37
+
38
+ from PyPDF2 import PdfReader, PdfWriter
39
+ from PyPDF2.generic import (
40
+ NameObject,
41
+ TextStringObject,
42
+ DictionaryObject,
43
+ ArrayObject,
44
+ FloatObject,
45
+ NumberObject,
46
+ )
47
+
48
+ from math import sin, cos, radians, isclose
49
+
50
+
51
+ def aci_to_rgb(aci):
52
+ aci_rgb_map = {
53
+ 0: (0, 0, 0),
54
+ 1: (255, 0, 0),
55
+ 2: (255, 255, 0),
56
+ 3: (0, 255, 0),
57
+ 4: (0, 255, 255),
58
+ 5: (0, 0, 255),
59
+ 6: (255, 0, 255),
60
+ 7: (255, 255, 255),
61
+ 8: (65, 65, 65),
62
+ 9: (128, 128, 128),
63
+ 10: (255, 0, 0),
64
+ 11: (255, 170, 170),
65
+ 12: (189, 0, 0),
66
+ 13: (189, 126, 126),
67
+ 14: (129, 0, 0),
68
+ 15: (129, 86, 86),
69
+ 16: (104, 0, 0),
70
+ 17: (104, 69, 69),
71
+ 18: (79, 0, 0),
72
+ 19: (79, 53, 53),
73
+ 20: (255, 63, 0),
74
+ 21: (255, 191, 170),
75
+ 22: (189, 46, 0),
76
+ 23: (189, 141, 126),
77
+ 24: (129, 31, 0),
78
+ 25: (129, 96, 86),
79
+ 26: (104, 25, 0),
80
+ 27: (104, 78, 69),
81
+ 28: (79, 19, 0),
82
+ 29: (79, 59, 53),
83
+ 30: (255, 127, 0),
84
+ 31: (255, 212, 170),
85
+ 32: (189, 94, 0),
86
+ 33: (189, 157, 126),
87
+ 34: (129, 64, 0),
88
+ 35: (129, 107, 86),
89
+ 36: (104, 52, 0),
90
+ 37: (104, 86, 69),
91
+ 38: (79, 39, 0),
92
+ 39: (79, 66, 53),
93
+ 40: (255, 191, 0),
94
+ 41: (255, 234, 170),
95
+ 42: (189, 141, 0),
96
+ 43: (189, 173, 126),
97
+ 44: (129, 96, 0),
98
+ 45: (129, 118, 86),
99
+ 46: (104, 78, 0),
100
+ 47: (104, 95, 69),
101
+ 48: (79, 59, 0),
102
+ 49: (79, 73, 53),
103
+ 50: (255, 255, 0),
104
+ 51: (255, 255, 170),
105
+ 52: (189, 189, 0),
106
+ 53: (189, 189, 126),
107
+ 54: (129, 129, 0),
108
+ 55: (129, 129, 86),
109
+ 56: (104, 104, 0),
110
+ 57: (104, 104, 69),
111
+ 58: (79, 79, 0),
112
+ 59: (79, 79, 53),
113
+ 60: (191, 255, 0),
114
+ 61: (234, 255, 170),
115
+ 62: (141, 189, 0),
116
+ 63: (173, 189, 126),
117
+ 64: (96, 129, 0),
118
+ 65: (118, 129, 86),
119
+ 66: (78, 104, 0),
120
+ 67: (95, 104, 69),
121
+ 68: (59, 79, 0),
122
+ 69: (73, 79, 53),
123
+ 70: (127, 255, 0),
124
+ 71: (212, 255, 170),
125
+ 72: (94, 189, 0),
126
+ 73: (157, 189, 126),
127
+ 74: (64, 129, 0),
128
+ 75: (107, 129, 86),
129
+ 76: (52, 104, 0),
130
+ 77: (86, 104, 69),
131
+ 78: (39, 79, 0),
132
+ 79: (66, 79, 53),
133
+ 80: (63, 255, 0),
134
+ 81: (191, 255, 170),
135
+ 82: (46, 189, 0),
136
+ 83: (141, 189, 126),
137
+ 84: (31, 129, 0),
138
+ 85: (96, 129, 86),
139
+ 86: (25, 104, 0),
140
+ 87: (78, 104, 69),
141
+ 88: (19, 79, 0),
142
+ 89: (59, 79, 53),
143
+ 90: (0, 255, 0),
144
+ 91: (170, 255, 170),
145
+ 92: (0, 189, 0),
146
+ 93: (126, 189, 126),
147
+ 94: (0, 129, 0),
148
+ 95: (86, 129, 86),
149
+ 96: (0, 104, 0),
150
+ 97: (69, 104, 69),
151
+ 98: (0, 79, 0),
152
+ 99: (53, 79, 53),
153
+ 100: (0, 255, 63),
154
+ 101: (170, 255, 191),
155
+ 102: (0, 189, 46),
156
+ 103: (126, 189, 141),
157
+ 104: (0, 129, 31),
158
+ 105: (86, 129, 96),
159
+ 106: (0, 104, 25),
160
+ 107: (69, 104, 78),
161
+ 108: (0, 79, 19),
162
+ 109: (53, 79, 59),
163
+ 110: (0, 255, 127),
164
+ 111: (170, 255, 212),
165
+ 112: (0, 189, 94),
166
+ 113: (126, 189, 157),
167
+ 114: (0, 129, 64),
168
+ 115: (86, 129, 107),
169
+ 116: (0, 104, 52),
170
+ 117: (69, 104, 86),
171
+ 118: (0, 79, 39),
172
+ 119: (53, 79, 66),
173
+ 120: (0, 255, 191),
174
+ 121: (170, 255, 234),
175
+ 122: (0, 189, 141),
176
+ 123: (126, 189, 173),
177
+ 124: (0, 129, 96),
178
+ 125: (86, 129, 118),
179
+ 126: (0, 104, 78),
180
+ 127: (69, 104, 95),
181
+ 128: (0, 79, 59),
182
+ 129: (53, 79, 73),
183
+ 130: (0, 255, 255),
184
+ 131: (170, 255, 255),
185
+ 132: (0, 189, 189),
186
+ 133: (126, 189, 189),
187
+ 134: (0, 129, 129),
188
+ 135: (86, 129, 129),
189
+ 136: (0, 104, 104),
190
+ 137: (69, 104, 104),
191
+ 138: (0, 79, 79),
192
+ 139: (53, 79, 79),
193
+ 140: (0, 191, 255),
194
+ 141: (170, 234, 255),
195
+ 142: (0, 141, 189),
196
+ 143: (126, 173, 189),
197
+ 144: (0, 96, 129),
198
+ 145: (86, 118, 129),
199
+ 146: (0, 78, 104),
200
+ 147: (69, 95, 104),
201
+ 148: (0, 59, 79),
202
+ 149: (53, 73, 79),
203
+ 150: (0, 127, 255),
204
+ 151: (170, 212, 255),
205
+ 152: (0, 94, 189),
206
+ 153: (126, 157, 189),
207
+ 154: (0, 64, 129),
208
+ 155: (86, 107, 129),
209
+ 156: (0, 52, 104),
210
+ 157: (69, 86, 104),
211
+ 158: (0, 39, 79),
212
+ 159: (53, 66, 79),
213
+ 160: (0, 63, 255),
214
+ 161: (170, 191, 255),
215
+ 162: (0, 46, 189),
216
+ 163: (126, 141, 189),
217
+ 164: (0, 31, 129),
218
+ 165: (86, 96, 129),
219
+ 166: (0, 25, 104),
220
+ 167: (69, 78, 104),
221
+ 168: (0, 19, 79),
222
+ 169: (53, 59, 79),
223
+ 170: (0, 0, 255),
224
+ 171: (170, 170, 255),
225
+ 172: (0, 0, 189),
226
+ 173: (126, 126, 189),
227
+ 174: (0, 0, 129),
228
+ 175: (86, 86, 129),
229
+ 176: (0, 0, 104),
230
+ 177: (69, 69, 104),
231
+ 178: (0, 0, 79),
232
+ 179: (53, 53, 79),
233
+ 180: (63, 0, 255),
234
+ 181: (191, 170, 255),
235
+ 182: (46, 0, 189),
236
+ 183: (141, 126, 189),
237
+ 184: (31, 0, 129),
238
+ 185: (96, 86, 129),
239
+ 186: (25, 0, 104),
240
+ 187: (78, 69, 104),
241
+ 188: (19, 0, 79),
242
+ 189: (59, 53, 79),
243
+ 190: (127, 0, 255),
244
+ 191: (212, 170, 255),
245
+ 192: (94, 0, 189),
246
+ 193: (157, 126, 189),
247
+ 194: (64, 0, 129),
248
+ 195: (107, 86, 129),
249
+ 196: (52, 0, 104),
250
+ 197: (86, 69, 104),
251
+ 198: (39, 0, 79),
252
+ 199: (66, 53, 79),
253
+ 200: (191, 0, 255),
254
+ 201: (234, 170, 255),
255
+ 202: (141, 0, 189),
256
+ 203: (173, 126, 189),
257
+ 204: (96, 0, 129),
258
+ 205: (118, 86, 129),
259
+ 206: (78, 0, 104),
260
+ 207: (95, 69, 104),
261
+ 208: (59, 0, 79),
262
+ 209: (73, 53, 79),
263
+ 210: (255, 0, 255),
264
+ 211: (255, 170, 255),
265
+ 212: (189, 0, 189),
266
+ 213: (189, 126, 189),
267
+ 214: (129, 0, 129),
268
+ 215: (129, 86, 129),
269
+ 216: (104, 0, 104),
270
+ 217: (104, 69, 104),
271
+ 218: (79, 0, 79),
272
+ 219: (79, 53, 79),
273
+ 220: (255, 0, 191),
274
+ 221: (255, 170, 234),
275
+ 222: (189, 0, 141),
276
+ 223: (189, 126, 173),
277
+ 224: (129, 0, 96),
278
+ 225: (129, 86, 118),
279
+ 226: (104, 0, 78),
280
+ 227: (104, 69, 95),
281
+ 228: (79, 0, 59),
282
+ 229: (79, 53, 73),
283
+ 230: (255, 0, 127),
284
+ 231: (255, 170, 212),
285
+ 232: (189, 0, 94),
286
+ 233: (189, 126, 157),
287
+ 234: (129, 0, 64),
288
+ 235: (129, 86, 107),
289
+ 236: (104, 0, 52),
290
+ 237: (104, 69, 86),
291
+ 238: (79, 0, 39),
292
+ 239: (79, 53, 66),
293
+ 240: (255, 0, 63),
294
+ 241: (255, 170, 191),
295
+ 242: (189, 0, 46),
296
+ 243: (189, 126, 141),
297
+ 244: (129, 0, 31),
298
+ 245: (129, 86, 96),
299
+ 246: (104, 0, 25),
300
+ 247: (104, 69, 78),
301
+ 248: (79, 0, 19),
302
+ 249: (79, 53, 59),
303
+ 250: (51, 51, 51),
304
+ 251: (80, 80, 80),
305
+ 252: (105, 105, 105),
306
+ 253: (130, 130, 130),
307
+ 254: (190, 190, 190),
308
+ 255: (255, 255, 255)
309
+ }
310
+
311
+ # Default to white if index is invalid or not found
312
+ return aci_rgb_map.get(aci, (255, 255, 255))
313
+
314
+
315
+ def int_to_rgb(color_int):
316
+ """Convert an integer to an (R, G, B) tuple."""
317
+ r = (color_int >> 16) & 255
318
+ g = (color_int >> 8) & 255
319
+ b = color_int & 255
320
+ return (r, g, b)
321
+
322
+
323
+ def get_hatch_color(entity):
324
+ """Extract hatch color with detailed debugging."""
325
+ if not entity:
326
+ # print("No entity provided for color extraction.")
327
+ return (255, 255, 255),'default'
328
+
329
+
330
+ # Check for true color
331
+ if entity.dxf.hasattr('true_color'):
332
+ true_color = entity.dxf.true_color
333
+ rgb_color = int_to_rgb(true_color) # Convert integer to (R, G, B)
334
+ # print(f"True color detected (RGB): {rgb_color}")
335
+ if(rgb_color == (255, 255, 255)):
336
+ return rgb_color,'White true_color'
337
+ else:
338
+ return rgb_color,'true_color'
339
+
340
+ # Check for color index
341
+ color_index = entity.dxf.color
342
+ # print(f"Entity color index: {color_index}")
343
+ if 1 <= color_index <= 255:
344
+ rgb_color = aci_to_rgb(color_index) # Convert ACI to RGB
345
+ # print(f"Converted ACI to RGB: {rgb_color}")
346
+ return rgb_color,'aci'
347
+
348
+ # Handle ByLayer or ByBlock
349
+ if color_index == 0: # ByLayer
350
+ layer_name = entity.dxf.layer
351
+ layer = entity.doc.layers.get(layer_name)
352
+ # print(f"ByLayer detected for layer '{layer_name}'.")
353
+ if layer:
354
+ layer_color_index = layer.dxf.color
355
+ # print(layer_color_index)
356
+ rgb_color = aci_to_rgb(layer_color_index)
357
+ # print(f"Layer '{layer_name}' color index {layer_color_index} converted to RGB: {rgb_color}")
358
+ return rgb_color,'bylayer'
359
+ else:
360
+ # print(f"Layer '{layer_name}' not found. Defaulting to white.")
361
+ return (255, 255, 255),'default'
362
+
363
+ # Default
364
+ # print("Unhandled color case. Defaulting to white.")
365
+ return (255, 255, 255),'default'
366
+
367
+ def calculate_distance(pt1, pt2):
368
+ dx = pt2[0] - pt1[0]
369
+ dy = pt2[1] - pt1[1]
370
+ return math.hypot(dx, dy)
371
+
372
+ def Legend_Detection(datadoc,dxfile,SearchArray,pdf_content=0):
373
+
374
+
375
+ doc = ezdxf.readfile(dxfile)
376
+ doc.header['$MEASUREMENT'] = 1
377
+ msp = doc.modelspace()
378
+
379
+ text_with_positions = []
380
+
381
+
382
+ # if pdf_content:
383
+ # doc = fitz.open(stream=pdf_content, filetype="pdf")
384
+ # else:
385
+ # doc = fitz.open('pdf',datadoc)
386
+
387
+ if(SearchArray):
388
+ for i in range(len(SearchArray)):
389
+
390
+ if (SearchArray[i][0] and SearchArray[i][1] and SearchArray[i][2]):
391
+ print("First IF")
392
+ print("SearchArray[i][1] = ",SearchArray[i][0])
393
+ print("SearchArray[i][2] = ",SearchArray[i][1])
394
+ print("SearchArray[i][3] = ",SearchArray[i][2])
395
+ for text_entity in doc.modelspace().query('TEXT MTEXT'):
396
+ text = text_entity.text.strip() if hasattr(text_entity, 'text') else ""
397
+ # if (text.startswith("P") and len(text) == 3) or (text.startswith("I") and len(text) == 3): # Filter for "Wall"
398
+ if(text.startswith(SearchArray[i][0]) and len(text)==int(SearchArray[i][2])):
399
+ # print("text = ",text)
400
+ position = text_entity.dxf.insert # Extract text position
401
+ x, y = position.x, position.y
402
+
403
+ for text_entity in doc.modelspace().query('TEXT MTEXT'):
404
+ NBS = text_entity.text.strip() if hasattr(text_entity, 'text') else ""
405
+ # textNBS = None
406
+ if (NBS.startswith(SearchArray[i][1])):
407
+ positionNBS = text_entity.dxf.insert # Extract text position
408
+ xNBS, yNBS = positionNBS.x, positionNBS.y
409
+
410
+ if(x == xNBS or y == yNBS):
411
+ textNBS=NBS
412
+ # print("textNBS = ",textNBS)
413
+ break
414
+
415
+ else:
416
+ textNBS = None
417
+
418
+
419
+
420
+ nearest_hatch = None
421
+ min_distance = float('inf') # Initialize with a very large value
422
+ detected_color = (255, 255, 255) # Default to white
423
+
424
+ # Search for the nearest hatch
425
+ for hatch in doc.modelspace().query('HATCH'): # Query only hatches
426
+ if hatch.paths:
427
+ for path in hatch.paths:
428
+ if path.type == 1: # PolylinePath
429
+ vertices = [v[:2] for v in path.vertices]
430
+ # Calculate the centroid of the hatch
431
+ centroid_x = sum(v[0] for v in vertices) / len(vertices)
432
+ centroid_y = sum(v[1] for v in vertices) / len(vertices)
433
+ centroid = (centroid_x, centroid_y)
434
+
435
+ # Calculate the distance between the text and the hatch centroid
436
+ distance = calculate_distance((x, y), centroid)
437
+
438
+ # Update the nearest hatch if a closer one is found
439
+ if distance < min_distance:
440
+ min_distance = distance
441
+ nearest_hatch = hatch
442
+
443
+ # Get the color of this hatch
444
+ current_color,color_index = get_hatch_color(hatch)
445
+ if current_color != (255, 255, 255): # Valid color found
446
+ detected_color = current_color
447
+ break # Stop checking further paths for this hatch
448
+
449
+
450
+ # Append the detected result only once
451
+ text_with_positions.append([text, textNBS, (x, y), detected_color])
452
+
453
+
454
+ elif (SearchArray[i][0] and SearchArray[i][2]):
455
+ print("Second IF")
456
+ for text_entity in doc.modelspace().query('TEXT MTEXT'):
457
+ text = text_entity.text.strip() if hasattr(text_entity, 'text') else ""
458
+ # if (text.startswith("P") and len(text) == 3) or (text.startswith("I") and len(text) == 3): # Filter for "Wall"
459
+ if(text.startswith(SearchArray[i][0]) and len(text)==int(SearchArray[i][2])):
460
+ position = text_entity.dxf.insert # Extract text position
461
+ x, y = position.x, position.y
462
+ textNBS = None
463
+ nearest_hatch = None
464
+ min_distance = float('inf') # Initialize with a very large value
465
+ detected_color = (255, 255, 255) # Default to white
466
+
467
+ # Search for the nearest hatch
468
+ for hatch in doc.modelspace().query('HATCH'): # Query only hatches
469
+ if hatch.paths:
470
+ for path in hatch.paths:
471
+ if path.type == 1: # PolylinePath
472
+ vertices = [v[:2] for v in path.vertices]
473
+ # Calculate the centroid of the hatch
474
+ centroid_x = sum(v[0] for v in vertices) / len(vertices)
475
+ centroid_y = sum(v[1] for v in vertices) / len(vertices)
476
+ centroid = (centroid_x, centroid_y)
477
+
478
+ # Calculate the distance between the text and the hatch centroid
479
+ distance = calculate_distance((x, y), centroid)
480
+
481
+ # Update the nearest hatch if a closer one is found
482
+ if distance < min_distance:
483
+ min_distance = distance
484
+ nearest_hatch = hatch
485
+
486
+ # Get the color of this hatch
487
+ current_color,color_index = get_hatch_color(hatch)
488
+ if current_color != (255, 255, 255): # Valid color found
489
+ detected_color = current_color
490
+ break # Stop checking further paths for this hatch
491
+
492
+
493
+ # Append the detected result only once
494
+ text_with_positions.append([text, textNBS, (x, y), detected_color])
495
+ # print("text_with_positions=",text_with_positions)
496
+
497
+ elif(SearchArray[i][0]):
498
+ print("Third IF")
499
+ for text_entity in doc.modelspace().query('TEXT MTEXT'):
500
+ text = text_entity.text.strip() if hasattr(text_entity, 'text') else ""
501
+ # if (text.startswith("P") and len(text) == 3) or (text.startswith("I") and len(text) == 3): # Filter for "Wall"
502
+ if(text.startswith(SearchArray[i][0])):
503
+ position = text_entity.dxf.insert # Extract text position
504
+ x, y = position.x, position.y
505
+ textNBS = None
506
+ nearest_hatch = None
507
+ min_distance = float('inf') # Initialize with a very large value
508
+ detected_color = (255, 255, 255) # Default to white
509
+
510
+ # Search for the nearest hatch
511
+ for hatch in doc.modelspace().query('HATCH'): # Query only hatches
512
+ if hatch.paths:
513
+ for path in hatch.paths:
514
+ if path.type == 1: # PolylinePath
515
+ vertices = [v[:2] for v in path.vertices]
516
+ # Calculate the centroid of the hatch
517
+ centroid_x = sum(v[0] for v in vertices) / len(vertices)
518
+ centroid_y = sum(v[1] for v in vertices) / len(vertices)
519
+ centroid = (centroid_x, centroid_y)
520
+
521
+ # Calculate the distance between the text and the hatch centroid
522
+ distance = calculate_distance((x, y), centroid)
523
+
524
+ # Update the nearest hatch if a closer one is found
525
+ if distance < min_distance:
526
+ min_distance = distance
527
+ nearest_hatch = hatch
528
+
529
+ # Get the color of this hatch
530
+ current_color,color_index = get_hatch_color(hatch)
531
+ if current_color != (255, 255, 255): # Valid color found
532
+ detected_color = current_color
533
+ break # Stop checking further paths for this hatch
534
+
535
+
536
+ # Append the detected result only once
537
+ text_with_positions.append([text, textNBS, (x, y), detected_color])
538
+
539
+
540
+ # Group entries by the text value (first element)
541
+ print("Grouping")
542
+ grouped = {}
543
+ for entry in text_with_positions:
544
+ key = entry[0]
545
+ grouped.setdefault(key, []).append(entry)
546
+
547
+ # Filter the groups: if any entry in a group has a non-None Text Nbs, keep only one of those
548
+ filtered_results = []
549
+ for key, entries in grouped.items():
550
+ # Find the first entry with a valid textNBS (non-None)
551
+ complete = next((entry for entry in entries if entry[1] is not None), None)
552
+ if complete:
553
+ filtered_results.append(complete)
554
+ else:
555
+ # If none are complete, you can choose to keep just one entry
556
+ filtered_results.append(entries[0])
557
+
558
+ # Print the filtered results
559
+ for text, textNbs, position, detected_color in filtered_results:
560
+ print(f"Text: {text}, Text Nbs: {textNbs}, Position: {position}, Nearest Hatch Color: {detected_color}")
561
+
562
+
563
+ text_with_positions=filtered_results
564
+ return text_with_positions
app.py CHANGED
The diff for this file is too large to render. See raw diff