Marthee commited on
Commit
2de0c03
·
verified ·
1 Parent(s): 7e538e1

Update deploying_3_3.py

Browse files
Files changed (1) hide show
  1. deploying_3_3.py +253 -29
deploying_3_3.py CHANGED
@@ -563,7 +563,17 @@ def get_hatch_color(entity):
563
 
564
  """### Hatched areas"""
565
  def get_hatched_areas(datadoc,filename,FinalRatio,rotationangle):
566
-
 
 
 
 
 
 
 
 
 
 
567
  text_with_positions = []
568
  text_color_mapping = {}
569
  color_palette = [
@@ -585,14 +595,181 @@ def get_hatched_areas(datadoc,filename,FinalRatio,rotationangle):
585
  (74, 43, 98), (188, 13, 123), (129, 58, 91), (255, 128, 100),
586
  (171, 122, 145), (255, 98, 98), (222, 48, 77)
587
  ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
588
 
589
- doc = ezdxf.readfile(filename)
590
- doc.header['$MEASUREMENT'] = 1
591
- msp = doc.modelspace()
592
- trial=0
593
- hatched_areas = []
594
- threshold=0.01
595
- unique_shapes = []
596
 
597
  for entity in doc.modelspace().query('TEXT MTEXT'):
598
  if hasattr(entity, 'text'): # Ensure the entity has text content
@@ -847,7 +1024,7 @@ def get_hatched_areas(datadoc,filename,FinalRatio,rotationangle):
847
  hatched_areas.append([vertices, area1, perimeter, rgb_color])
848
 
849
  sorted_data = sorted(hatched_areas, key=lambda x: x[1])
850
- return sorted_data
851
 
852
  """### Rotate polygon"""
853
 
@@ -944,9 +1121,9 @@ def Create_DF(dxfpath,datadoc,hatched_areas,pdf_content=0):
944
  return SimilarAreaDictionary
945
  """### Draw on Image and PDF"""
946
 
947
- def adjustannotations(OutputPdfStage1):
948
  input_pdf_path = OutputPdfStage1
949
- output_pdf_path = "AnnotationAdjusted.pdf"
950
 
951
  # Load the input PDF
952
  pdf_bytes_io = BytesIO(OutputPdfStage1)
@@ -961,41 +1138,86 @@ def adjustannotations(OutputPdfStage1):
961
  metadata = reader.metadata
962
  writer.add_metadata(metadata)
963
 
964
- # Iterate over pages
965
  for page_index, page in enumerate(writer.pages):
966
  if "/Annots" in page:
967
  annotations = page["/Annots"]
968
  for annot_index, annot in enumerate(annotations):
969
  obj = annot.get_object()
970
 
971
- print("obj", obj)
972
  # print(obj.get("/IT"))
973
 
974
- if obj.get("/Subtype") == "/Polygon":
975
- print("AWL ANNOT IF")
976
  # Check the /IT value to differentiate annotations
977
- if "/Contents" in obj and "sq m" in obj["/Contents"]:
978
- print("Tany IF")
 
979
  obj.update({
980
  NameObject("/Measure"): DictionaryObject({
981
  NameObject("/Type"): NameObject("/Measure"),
982
- NameObject("/Area"): DictionaryObject({
983
  NameObject("/G"): FloatObject(1),
984
- NameObject("/U"): TextStringObject("sq m"), # Unit of measurement for area
985
  }),
986
-
987
- NameObject("/X"): FloatObject(1), # Horizontal scale (e.g., 1 unit = 1 meter)
988
- NameObject("/Y"): FloatObject(1), # Vertical scale
989
 
990
  }),
991
- NameObject("/IT"): NameObject("/Area_Annotation"), # Use more distinctive name
992
- NameObject("/Subj"): TextStringObject("Area Measurement"), # Intent explicitly for Area
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
993
  })
994
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
995
 
996
- print("After Update:", obj)
997
-
998
- # # Save the modified PDF
999
 
1000
  output_pdf_io = BytesIO()
1001
  writer.write(output_pdf_io)
@@ -1046,7 +1268,7 @@ def mainFunctionDrawImgPdf(datadoc,dxfpath, dxfratio,pdfpath=0,pdfname=0,pdf_con
1046
  rotationangle = 270
1047
 
1048
 
1049
- hatched_areas = get_hatched_areas(datadoc,dxfpath,FinalRatio,rotationangle)
1050
  allshapes=[]
1051
  # Iterate through each polygon in metric units
1052
  NewColors = []
@@ -1254,7 +1476,9 @@ def mainFunctionDrawImgPdf(datadoc,dxfpath, dxfratio,pdfpath=0,pdfname=0,pdf_con
1254
  SimilarAreaDictionary = grouped_df
1255
  # doc.save(OutputPdfStage1)
1256
  modified_pdf_data = doc.tobytes()
1257
- OutputPdfStage2=adjustannotations(modified_pdf_data)
 
 
1258
 
1259
  # with open("Adjusted_PDF.pdf", "wb") as f:
1260
  # f.write(OutputPdfStage2)
 
563
 
564
  """### Hatched areas"""
565
  def get_hatched_areas(datadoc,filename,FinalRatio,rotationangle):
566
+
567
+ doc = ezdxf.readfile(filename)
568
+ doc.header['$MEASUREMENT'] = 1
569
+ msp = doc.modelspace()
570
+ trial=0
571
+ hatched_areas = []
572
+ threshold=0.001
573
+ TextFound = 0
574
+ j=0
575
+ unique_shapes = []
576
+
577
  text_with_positions = []
578
  text_color_mapping = {}
579
  color_palette = [
 
595
  (74, 43, 98), (188, 13, 123), (129, 58, 91), (255, 128, 100),
596
  (171, 122, 145), (255, 98, 98), (222, 48, 77)
597
  ]
598
+
599
+ import re
600
+
601
+ text_with_positions = []
602
+
603
+ if(SearchArray):
604
+ for i in range(len(SearchArray)):
605
+
606
+ if (SearchArray[i][0] and SearchArray[i][1] and SearchArray[i][2]):
607
+ for text_entity in doc.modelspace().query('TEXT MTEXT'):
608
+ text = text_entity.text.strip() if hasattr(text_entity, 'text') else ""
609
+ # if (text.startswith("P") and len(text) == 3) or (text.startswith("I") and len(text) == 3): # Filter for "Wall"
610
+ if(text.startswith(SearchArray[i][0]) and len(text)==int(SearchArray[i][2])):
611
+ position = text_entity.dxf.insert # Extract text position
612
+ x, y = position.x, position.y
613
+
614
+ for text_entity in doc.modelspace().query('TEXT MTEXT'):
615
+ NBS = text_entity.text.strip() if hasattr(text_entity, 'text') else ""
616
+ if (NBS.startswith(SearchArray[i][1])):
617
+ positionNBS = text_entity.dxf.insert # Extract text position
618
+ xNBS, yNBS = positionNBS.x, positionNBS.y
619
+
620
+ if(x == xNBS or y == yNBS):
621
+ textNBS=NBS
622
+ break
623
+
624
+ else:
625
+ textNBS = None
626
+
627
+
628
+
629
+ nearest_hatch = None
630
+ min_distance = float('inf') # Initialize with a very large value
631
+ detected_color = (255, 255, 255) # Default to white
632
+
633
+ # Search for the nearest hatch
634
+ for hatch in doc.modelspace().query('HATCH'): # Query only hatches
635
+ if hatch.paths:
636
+ for path in hatch.paths:
637
+ if path.type == 1: # PolylinePath
638
+ vertices = [v[:2] for v in path.vertices]
639
+ # Calculate the centroid of the hatch
640
+ centroid_x = sum(v[0] for v in vertices) / len(vertices)
641
+ centroid_y = sum(v[1] for v in vertices) / len(vertices)
642
+ centroid = (centroid_x, centroid_y)
643
+
644
+ # Calculate the distance between the text and the hatch centroid
645
+ distance = calculate_distance((x, y), centroid)
646
+
647
+ # Update the nearest hatch if a closer one is found
648
+ if distance < min_distance:
649
+ min_distance = distance
650
+ nearest_hatch = hatch
651
+
652
+ # Get the color of this hatch
653
+ current_color = get_hatch_color(hatch)
654
+ if current_color != (255, 255, 255): # Valid color found
655
+ detected_color = current_color
656
+ break # Stop checking further paths for this hatch
657
+
658
+
659
+ # Append the detected result only once
660
+ Legendarray.append([text, textNBS, (x, y), detected_color])
661
+ print("text_with_positions=",text_with_positions)
662
+
663
+ elif (SearchArray[i][0] and SearchArray[i][2]):
664
+ for text_entity in doc.modelspace().query('TEXT MTEXT'):
665
+ text = text_entity.text.strip() if hasattr(text_entity, 'text') else ""
666
+ # if (text.startswith("P") and len(text) == 3) or (text.startswith("I") and len(text) == 3): # Filter for "Wall"
667
+ if(text.startswith(SearchArray[i][0]) and len(text)==int(SearchArray[i][2])):
668
+ position = text_entity.dxf.insert # Extract text position
669
+ x, y = position.x, position.y
670
+ textNBS = None
671
+ nearest_hatch = None
672
+ min_distance = float('inf') # Initialize with a very large value
673
+ detected_color = (255, 255, 255) # Default to white
674
+
675
+ # Search for the nearest hatch
676
+ for hatch in doc.modelspace().query('HATCH'): # Query only hatches
677
+ if hatch.paths:
678
+ for path in hatch.paths:
679
+ if path.type == 1: # PolylinePath
680
+ vertices = [v[:2] for v in path.vertices]
681
+ # Calculate the centroid of the hatch
682
+ centroid_x = sum(v[0] for v in vertices) / len(vertices)
683
+ centroid_y = sum(v[1] for v in vertices) / len(vertices)
684
+ centroid = (centroid_x, centroid_y)
685
+
686
+ # Calculate the distance between the text and the hatch centroid
687
+ distance = calculate_distance((x, y), centroid)
688
+
689
+ # Update the nearest hatch if a closer one is found
690
+ if distance < min_distance:
691
+ min_distance = distance
692
+ nearest_hatch = hatch
693
+
694
+ # Get the color of this hatch
695
+ current_color = get_hatch_color(hatch)
696
+ if current_color != (255, 255, 255): # Valid color found
697
+ detected_color = current_color
698
+ break # Stop checking further paths for this hatch
699
+
700
+
701
+ # Append the detected result only once
702
+ Legendarray.append([text, textNBS, (x, y), detected_color])
703
+ print("text_with_positions=",text_with_positions)
704
+
705
+ elif(SearchArray[i][0]):
706
+ for text_entity in doc.modelspace().query('TEXT MTEXT'):
707
+ text = text_entity.text.strip() if hasattr(text_entity, 'text') else ""
708
+ # if (text.startswith("P") and len(text) == 3) or (text.startswith("I") and len(text) == 3): # Filter for "Wall"
709
+ if(text.startswith(SearchArray[i][0])):
710
+ position = text_entity.dxf.insert # Extract text position
711
+ x, y = position.x, position.y
712
+ textNBS = None
713
+ nearest_hatch = None
714
+ min_distance = float('inf') # Initialize with a very large value
715
+ detected_color = (255, 255, 255) # Default to white
716
+
717
+ # Search for the nearest hatch
718
+ for hatch in doc.modelspace().query('HATCH'): # Query only hatches
719
+ if hatch.paths:
720
+ for path in hatch.paths:
721
+ if path.type == 1: # PolylinePath
722
+ vertices = [v[:2] for v in path.vertices]
723
+ # Calculate the centroid of the hatch
724
+ centroid_x = sum(v[0] for v in vertices) / len(vertices)
725
+ centroid_y = sum(v[1] for v in vertices) / len(vertices)
726
+ centroid = (centroid_x, centroid_y)
727
+
728
+ # Calculate the distance between the text and the hatch centroid
729
+ distance = calculate_distance((x, y), centroid)
730
+
731
+ # Update the nearest hatch if a closer one is found
732
+ if distance < min_distance:
733
+ min_distance = distance
734
+ nearest_hatch = hatch
735
+
736
+ # Get the color of this hatch
737
+ current_color = get_hatch_color(hatch)
738
+ if current_color != (255, 255, 255): # Valid color found
739
+ detected_color = current_color
740
+ break # Stop checking further paths for this hatch
741
+
742
+
743
+ # Append the detected result only once
744
+ Legendarray.append([text, textNBS, (x, y), detected_color])
745
+ print("text_with_positions=",Legendarray)
746
+
747
+
748
+
749
+
750
+
751
+
752
+
753
+
754
+ grouped = {}
755
+ for entry in Legendarray:
756
+ key = entry[0]
757
+ grouped.setdefault(key, []).append(entry)
758
+
759
+ # Filter the groups: if any entry in a group has a non-None Text Nbs, keep only one of those
760
+ filtered_results = []
761
+ for key, entries in grouped.items():
762
+ # Find the first entry with a valid textNBS (non-None)
763
+ complete = next((entry for entry in entries if entry[1] is not None), None)
764
+ if complete:
765
+ filtered_results.append(complete)
766
+ else:
767
+ # If none are complete, you can choose to keep just one entry
768
+ filtered_results.append(entries[0])
769
+
770
+ text_with_positions=filtered_results
771
 
772
+
 
 
 
 
 
 
773
 
774
  for entity in doc.modelspace().query('TEXT MTEXT'):
775
  if hasattr(entity, 'text'): # Ensure the entity has text content
 
1024
  hatched_areas.append([vertices, area1, perimeter, rgb_color])
1025
 
1026
  sorted_data = sorted(hatched_areas, key=lambda x: x[1])
1027
+ return sorted_data,Legendarray
1028
 
1029
  """### Rotate polygon"""
1030
 
 
1121
  return SimilarAreaDictionary
1122
  """### Draw on Image and PDF"""
1123
 
1124
+ def adjustannotations(OutputPdfStage1,text_with_positions):
1125
  input_pdf_path = OutputPdfStage1
1126
+ output_pdf_path = "Final-WallsAdjusted.pdf"
1127
 
1128
  # Load the input PDF
1129
  pdf_bytes_io = BytesIO(OutputPdfStage1)
 
1138
  metadata = reader.metadata
1139
  writer.add_metadata(metadata)
1140
 
 
1141
  for page_index, page in enumerate(writer.pages):
1142
  if "/Annots" in page:
1143
  annotations = page["/Annots"]
1144
  for annot_index, annot in enumerate(annotations):
1145
  obj = annot.get_object()
1146
 
1147
+ # print("obj", obj)
1148
  # print(obj.get("/IT"))
1149
 
1150
+ if obj.get("/Subtype") == "/Line":
1151
+ # print("AWL ANNOT IF")
1152
  # Check the /IT value to differentiate annotations
1153
+ # if "/Contents" in obj and "m" in obj["/Contents"]:
1154
+ if "/Subj" in obj and "Perimeter Measurement" in obj["/Subj"]:
1155
+ # print("Tany IF")
1156
  obj.update({
1157
  NameObject("/Measure"): DictionaryObject({
1158
  NameObject("/Type"): NameObject("/Measure"),
1159
+ NameObject("/L"): DictionaryObject({
1160
  NameObject("/G"): FloatObject(1),
1161
+ NameObject("/U"): TextStringObject("m"), # Unit of measurement for area
1162
  }),
 
 
 
1163
 
1164
  }),
1165
+ NameObject("/IT"): NameObject("/LineDimension"), # Use more distinctive name
1166
+ NameObject("/Subj"): TextStringObject("Length Measurement"), # Intent explicitly for Area
1167
+ })
1168
+ # print(obj)
1169
+
1170
+ if obj.get("/Subtype") in ["/Line", "/PolyLine"] and "/C" in obj:
1171
+ # Normalize and match the color
1172
+ annot_color = normalize_color(obj["/C"])
1173
+ matched_entry = next(
1174
+ ((text, NBS) for text,NBS, _, color in text_with_positions if color_close_enough(annot_color, color)),
1175
+ (None, None)
1176
+ )
1177
+ # print("matched_entry = ",matched_entry)
1178
+ matched_text, matched_nbs = matched_entry
1179
+
1180
+ combined_text = ""
1181
+ if matched_text and matched_nbs:
1182
+ combined_text = f"{matched_text} - {matched_nbs}"
1183
+ elif matched_text:
1184
+ combined_text = matched_text
1185
+ elif matched_nbs:
1186
+ combined_text = matched_nbs
1187
+
1188
+ obj.update({
1189
+ NameObject("/T"): TextStringObject(combined_text), # Custom text for "Comment" column
1190
  })
1191
 
1192
+ elif (obj.get("/Subtype") == "/Polygon" and "/C" in obj):
1193
+ # Normalize and match the color
1194
+ annot_color = normalize_color(obj["/C"])
1195
+ # print("annot_color = ",annot_color)
1196
+ # print("LASTarray = ",text_with_positions)
1197
+ # matched_entry = next(
1198
+ # ((text, NBS) for text,NBS, _, color in text_with_positions if annot_color == color),
1199
+ # (None, None)
1200
+ # )
1201
+ matched_entry = next(
1202
+ ((text, NBS) for text,NBS, _, color in text_with_positions if color_close_enough(annot_color, color)),
1203
+ (None, None)
1204
+ )
1205
+ # print("matched_entry = ",matched_entry)
1206
+ matched_text, matched_nbs = matched_entry
1207
+
1208
+ combined_text = ""
1209
+ if matched_text and matched_nbs:
1210
+ combined_text = f"{matched_text} - {matched_nbs}"
1211
+ elif matched_text:
1212
+ combined_text = matched_text
1213
+ elif matched_nbs:
1214
+ combined_text = matched_nbs
1215
+
1216
+ obj.update({
1217
+ NameObject("/T"): TextStringObject(combined_text), # Custom text for "Comment" column
1218
+ })
1219
+
1220
 
 
 
 
1221
 
1222
  output_pdf_io = BytesIO()
1223
  writer.write(output_pdf_io)
 
1268
  rotationangle = 270
1269
 
1270
 
1271
+ hatched_areas,Legendarray = get_hatched_areas(datadoc,dxfpath,FinalRatio,rotationangle)
1272
  allshapes=[]
1273
  # Iterate through each polygon in metric units
1274
  NewColors = []
 
1476
  SimilarAreaDictionary = grouped_df
1477
  # doc.save(OutputPdfStage1)
1478
  modified_pdf_data = doc.tobytes()
1479
+ # OutputPdfStage2=adjustannotations(modified_pdf_data)
1480
+ OutputPdfStage2=adjustannotations(modified_pdf_data,text_with_positions)
1481
+
1482
 
1483
  # with open("Adjusted_PDF.pdf", "wb") as f:
1484
  # f.write(OutputPdfStage2)