Skip to content

Commit fb9468b

Browse files
committed
wip
1 parent 59369b0 commit fb9468b

18 files changed

Lines changed: 295 additions & 27 deletions

app.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import os
22
from dotenv import load_dotenv
3+
4+
from topographic import TopographicPlan
5+
36
load_dotenv() # reads .env into environment
47

58
from cadastral import CadastralPlan
@@ -24,6 +27,16 @@ def generate_cadastral_plan():
2427
url = plan.save()
2528
return jsonify({"message": "Cadastral plan generated", "filename": plan.name, "url": url}), 200
2629

30+
@app.route("/topographic/plan", methods=["POST"])
31+
def generate_topographic_plan():
32+
data = request.get_json()
33+
34+
plan = TopographicPlan(**data)
35+
plan.draw()
36+
37+
url = plan.save()
38+
return jsonify({"message": "Topographic plan generated", "filename": plan.name, "url": url}), 200
39+
2740
# @app.route("/route/plan", methods=["POST"])
2841
# def generate_route_plan():
2942
# data = request.get_json()
243 KB
Binary file not shown.

cadastral.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ def __init__(self, **kwargs):
1515

1616
self._frame_x_percent = 0.35
1717
self._frame_y_percent = 0.8
18+
self._bounding_box = self.get_bounding_box()
1819
self._frame_coords = self._setup_frame_coords()
1920
if not self._frame_coords:
2021
raise ValueError("Cannot determine frame coordinates without valid coordinates.")
@@ -28,7 +29,7 @@ def _setup_drawer(self) -> SurveyDXFManager:
2829
return drawer
2930

3031
def _setup_frame_coords(self):
31-
min_x, min_y, max_x, max_y = self.get_bounding_box()
32+
min_x, min_y, max_x, max_y = self._bounding_box
3233
if min_x is None or min_y is None or max_x is None or max_y is None:
3334
return None
3435

@@ -121,7 +122,7 @@ def add_leg_labels(self, leg, orientation: str):
121122

122123
def draw_frames(self):
123124
"""Draw outer and offset frames."""
124-
min_x, min_y, max_x, max_y = self.get_bounding_box()
125+
min_x, min_y, max_x, max_y = self._bounding_box
125126
width, height = max_x - min_x, max_y - min_y
126127

127128
margin_x, margin_y = max(width, height) * self._frame_x_percent, max(height, width) * self._frame_y_percent
@@ -135,7 +136,7 @@ def draw_frames(self):
135136

136137
def draw_title_block(self):
137138
"""Add title block to the frame."""
138-
min_x, min_y, max_x, max_y = self.get_bounding_box()
139+
min_x, min_y, max_x, max_y = self._bounding_box
139140
width, height = max_x - min_x, max_y - min_y
140141

141142
margin_x, margin_y = max(width, height) * self._frame_x_percent, max(height, width) * self._frame_y_percent

dxf.py

Lines changed: 76 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -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(
696 KB
Binary file not shown.
752 KB
Binary file not shown.
752 KB
Binary file not shown.
528 KB
Binary file not shown.
552 KB
Binary file not shown.
773 KB
Binary file not shown.

0 commit comments

Comments
 (0)