@@ -41,8 +41,9 @@ def _setup_layers(self):
4141 ('DIMENSIONS' , 4 ), # Cyan
4242 ('TITLE_BLOCK' , 7 ), # White
4343 ('TRAVERSE' , 6 ), # Magenta
44- ('SPOT_HEIGHTS' , 3 ), # Green
44+ ('SPOT_HEIGHTS' , 7 ), # Black/White
4545 ("FOOTER" , 7 ), # Black/White
46+ ('BOUNDARY' , 1 ), # Red
4647 ]
4748
4849 for name , color in layers :
@@ -86,6 +87,21 @@ def setup_beacon_style(self, type_: str = "box", size: float = 1.0):
8687 path = hatch .paths .add_edge_path ()
8788 path .add_arc ((0 , 0 ), radius = radius , start_angle = 0 , end_angle = 360 )
8889
90+ def setup_topo_point_style (self , type_ : str = "cross" , size : float = 1 ):
91+ size = size * self .scale
92+
93+ # Point styles (using blocks)
94+ block = self .doc .blocks .new (name = 'TOPO_POINT' )
95+ if type_ == "cross" :
96+ # cross only
97+ block .add_line ((- size , - size ), (size , size ), dxfattribs = {"true_color" : ezdxf .colors .rgb2int ((205 , 105 , 40 ))}) # Green
98+ block .add_line ((- size , size ), (size , - size ), dxfattribs = {"true_color" : ezdxf .colors .rgb2int ((205 , 105 , 40 ))})
99+ else :
100+ block .add_line ((- size , - size ), (size , size ), dxfattribs = {"true_color" : ezdxf .colors .rgb2int ((205 , 105 , 40 ))})
101+ block .add_line ((- size , size ), (size , - size ), dxfattribs = {"true_color" : ezdxf .colors .rgb2int ((205 , 105 , 40 ))})
102+
103+ block .add_point ((0 , 0 ), dxfattribs = {"true_color" : ezdxf .colors .rgb2int ((205 , 105 , 40 ))}) # Green
104+
89105 def setup_graphical_scale_style (self , length : float = 1000 ):
90106 length = length * self .scale
91107 height = length * 0.05 # 5% of length
@@ -231,6 +247,15 @@ def add_parcel(self, parcel_id: str, points: list, label_scale: float = 1.0):
231247 align = TextEntityAlignment .MIDDLE_CENTER
232248 )
233249
250+ def add_boundary (self , points : list ):
251+ """Add a boundaty given its ID and list of (x, y) points"""
252+ # scale points
253+ points = [(x * self .scale , y * self .scale ) for x , y , * rest in points ]
254+
255+ self .msp .add_lwpolyline (points , close = True , dxfattribs = {
256+ 'layer' : 'BOUNDARY'
257+ })
258+
234259 def add_text (self , text : str , x : float , y : float , angle : float = 0.0 , height : float = 1.0 ):
235260 x = x * self .scale
236261 y = y * self .scale
@@ -284,7 +309,7 @@ def draw_title_block(self, text: str, x: float, y: float, width: float, title_he
284309 # add graphical scale below title
285310 graphical_ref = self .msp .add_blockref (
286311 'GRAPHICAL_SCALE' ,
287- (graphical_x , title_min_y - (3.5 * self . scale )),
312+ (graphical_x , title_min_y - (graphical_scale_length * 0.05 * 3 )),
288313 dxfattribs = {'layer' : 'TITLE_BLOCK' }
289314 )
290315
@@ -332,7 +357,6 @@ def draw_footer_box(self, text: str, min_x, min_y, max_x, max_y, font_size: floa
332357 footer_mtext .set_location ((min_x + (0.05 * (max_x - min_x )), max_y - (0.1 * (max_y - min_y ))))
333358 footer_mtext .dxf .char_height = font_size
334359
335-
336360 def draw_frame (self , min_x , min_y , max_x , max_y ):
337361 min_x = min_x * self .scale
338362 min_y = min_y * self .scale
@@ -349,6 +373,34 @@ def draw_frame(self, min_x, min_y, max_x, max_y):
349373 'layer' : 'FRAME' ,
350374 })
351375
376+ def draw_topo_point (self , x : float , y : float , z : float = 0 , label : str = None , text_height : float = 1.0 ):
377+ # Add a topo point with optional label
378+ x = x * self .scale
379+ y = y * self .scale
380+ z = z * self .scale
381+ text_height = text_height * self .scale
382+
383+ self .msp .add_blockref (
384+ 'TOPO_POINT' ,
385+ (x , y , z ),
386+ dxfattribs = {'layer' : 'SPOT_HEIGHTS' }
387+ )
388+
389+ # add label
390+ if label is not None :
391+ offset = 0.5 * self .scale
392+ self .msp .add_text (
393+ label ,
394+ dxfattribs = {
395+ 'layer' : 'SPOT_HEIGHTS' ,
396+ 'height' : text_height ,
397+ 'style' : 'SURVEY_TEXT' ,
398+ 'color' : 7 # Black/White
399+ }
400+ ).set_placement (
401+ (x + offset , y + offset , z + offset )
402+ )
403+
352404 def get_filename (self ):
353405 plan_name = self .plan_name .lower ()
354406 plan_name = re .sub (r"\s+" , "_" ,plan_name )
@@ -406,27 +458,27 @@ def save_dwg(self, dxf_filepath: str, filepath: str = None):
406458 odafc .convert (dxf_filepath , filepath )
407459
408460 def save (self , paper_size : str = "A4" , orientation : str = "portrait" ):
409- with tempfile .TemporaryDirectory () as tmpdir :
410- filename = self .get_filename ()
411- dxf_path = os .path .join (tmpdir , f"{ filename } .dxf" )
412- # dwg_path = os.path.join(tmpdir, f"{filename}.dwg")
413- pdf_path = os .path .join (tmpdir , f"{ filename } .pdf" )
414- zip_path = os .path .join (tmpdir , f"{ filename } .zip" )
415-
416- self .save_dxf (dxf_path )
417- # self.save_dwg(dxf_path, dwg_path)
418- self .save_pdf (pdf_path , paper_size = paper_size , orientation = orientation )
419-
420- # Create a ZIP file containing all three formats
421- with zipfile .ZipFile (zip_path , "w" ) as zipf :
422- zipf .write (dxf_path , os .path .basename (dxf_path ))
423- # zipf.write(dwg_path, os.path.basename(dwg_path))
424- zipf .write (pdf_path , os .path .basename (pdf_path ))
425-
426- url = upload_file (zip_path , folder = "survey_plans" , file_name = filename )
427- if url is None :
428- raise Exception ("Upload failed" )
429- return url
461+ # with tempfile.TemporaryDirectory() as tmpdir:
462+ filename = self .get_filename ()
463+ dxf_path = os .path .join ("" , f"{ filename } .dxf" )
464+ # dwg_path = os.path.join(tmpdir, f"{filename}.dwg")
465+ pdf_path = os .path .join ("" , f"{ filename } .pdf" )
466+ zip_path = os .path .join ("" , f"{ filename } .zip" )
467+
468+ self .save_dxf (dxf_path )
469+ # self.save_dwg(dxf_path, dwg_path)
470+ self .save_pdf (pdf_path , paper_size = paper_size , orientation = orientation )
471+
472+ # Create a ZIP file containing all three formats
473+ with zipfile .ZipFile (zip_path , "w" ) as zipf :
474+ zipf .write (dxf_path , os .path .basename (dxf_path ))
475+ # zipf.write(dwg_path, os.path.basename(dwg_path))
476+ zipf .write (pdf_path , os .path .basename (pdf_path ))
477+
478+ url = upload_file (zip_path , folder = "survey_plans" , file_name = filename )
479+ if url is None :
480+ raise Exception ("Upload failed" )
481+ return url
430482
431483 # def add_topo_point(self, x: float, y: float, z: float, label: str = None, text_height: float = 1.0):
432484 # self.msp.add_blockref(
0 commit comments