Skip to content

Commit b8ee501

Browse files
committed
wip
1 parent 7c00532 commit b8ee501

7 files changed

Lines changed: 110 additions & 72 deletions

File tree

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ WORKDIR /app
3232
COPY requirements.txt requirements.txt
3333

3434
# Install Python dependencies
35-
RUN pip install --no-cache-dir -r requirements.txt
35+
RUN pip install -r requirements.txt
3636

3737
# Copy app files
3838
COPY . .

cadastral.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
from dxf import SurveyDXFManager
22
from models.plan import PlanProps, PlanType
3-
from utils import polygon_orientation, line_normals, line_direction, html_to_mtext
4-
from pydantic import PrivateAttr
3+
from utils import polygon_orientation, line_normals, line_direction, html_to_mtext, format_number
54

65
import math
76

@@ -113,19 +112,25 @@ def add_leg_labels(self, leg, orientation: str):
113112
text_angle += 180
114113

115114
# Add labels
116-
self._drawer.add_label(f"{leg.distance:.2f} m", mid_x, mid_y,
115+
self._drawer.add_label(f"{leg.distance:.2f}m", mid_x, mid_y,
117116
angle=text_angle, height=self.label_size)
118117
ld = line_direction(angle_deg)
119118
if ld == "left → right":
120-
self._drawer.add_label(f"{leg.bearing.degrees}°", first_x, first_y,
119+
# self._drawer.add_label_mtext(f"{format_number(leg.bearing.degrees, "hundredth")}° {format_number(leg.bearing.minutes, "tenth")}'", mid_x, mid_y,
120+
# angle=text_angle, height=self.label_size)
121+
self._drawer.add_label(f"{format_number(leg.bearing.degrees, "hundredth")}°", first_x, first_y,
121122
angle=text_angle, height=self.label_size)
122-
self._drawer.add_label(f"{leg.bearing.minutes}'", last_x, last_y,
123+
self._drawer.add_label(f"{format_number(leg.bearing.minutes, "tenth")}'", last_x, last_y,
123124
angle=text_angle, height=self.label_size)
124125
else:
125-
self._drawer.add_label(f"{leg.bearing.degrees}°", last_x, last_y,
126+
127+
self._drawer.add_label(f"{format_number(leg.bearing.degrees, "hundredth")}°", last_x, last_y,
126128
angle=text_angle, height=self.label_size)
127-
self._drawer.add_label(f"{leg.bearing.minutes}'", first_x, first_y,
129+
self._drawer.add_label(f"{format_number(leg.bearing.minutes, "tenth")}'", first_x, first_y,
128130
angle=text_angle, height=self.label_size)
131+
# print(
132+
# ''
133+
# )
129134

130135
def draw_frames(self):
131136
"""Draw outer and offset frames."""
@@ -173,7 +178,7 @@ def draw_footer_boxes(self):
173178
y_max = self._frame_coords[3]
174179

175180
box_width = (x_max - x_min) / len(self.footers)
176-
box_height = (y_max - y_min) * 0.25
181+
box_height = (y_max - y_min) * 0.2
177182

178183
for i, footer in enumerate(self.footers):
179184
x1 = x_min + i * box_width
@@ -203,7 +208,7 @@ def draw_north_arrow(self):
203208
# for northing label
204209
northing_label_y = self._frame_coords[1]
205210
if len(self.footers) > 0:
206-
northing_label_y = northing_label_y + ((self._frame_coords[3] - self._frame_coords[1]) * 0.25)
211+
northing_label_y = northing_label_y + ((self._frame_coords[3] - self._frame_coords[1]) * 0.2)
207212

208213
self._drawer.add_north_arrow_label((coord.easting, northing_label_y),
209214
(coord.easting, northing_label_y + height), f"{coord.northing}mN",

dxf.py

Lines changed: 60 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def __init__(self, plan_name: str = "Survey Plan", scale: float = 1.0, dxf_versi
3232
self.doc.header["$AUNITS"] = 1 # Degrees/minutes/seconds
3333
self.doc.header["$AUPREC"] = 3 # 0d00'00"
3434
self.doc.header["$ANGBASE"] = 90.0 # set 0° direction to North
35+
print(dxf_version)
3536

3637
def setup_layers(self):
3738
self.doc.layers.add(name="LABELS", color=colors.BLACK)
@@ -228,6 +229,18 @@ def add_greenspace(self, points: List[Tuple[float, float]], coords):
228229
hatch.set_pattern_fill('ANSI31', scale=0.5)
229230
hatch.paths.add_polyline_path(coords, is_closed=True)
230231

232+
def add_label_mtext(self, text: str, x: float, y: float, angle: float = 0.0, height: float = 1.0):
233+
x = x * self.scale
234+
y = y * self.scale
235+
height = height * self.scale
236+
237+
text = self.msp.add_mtext(text=text, dxfattribs={'style': 'SURVEY_TEXT'})
238+
text.dxf.attachment_point = ezdxf.enums.MTextEntityAlignment.MIDDLE_CENTER
239+
text.dxf.char_height = height
240+
text.set_location((x, y))
241+
text.set_rotation(angle)
242+
243+
231244
def add_label(self, text: str, x: float, y: float, angle: float = 0.0, height: float = 1.0):
232245
x = x * self.scale
233246
y = y * self.scale
@@ -258,7 +271,7 @@ def add_text(self, text: str, x: float, y: float, height: float = 1.0, rotation:
258271
dxfattribs={
259272
'layer': 'TEXT',
260273
'height': height,
261-
'style': 'STANDARD',
274+
'style': 'SURVEY_TEXT',
262275
"rotation": rotation,
263276
}
264277
).set_placement(
@@ -289,7 +302,7 @@ def draw_north_arrow(self, x: float, y: float, height: float = 100.0):
289302
'color': 5,
290303
}
291304
).set_placement(
292-
( -height * 0.3, height - (height * 0.25)),
305+
( -height * 0.3, height - (height * 0.2)),
293306
align=TextEntityAlignment.MIDDLE_CENTER
294307
)
295308

@@ -300,7 +313,7 @@ def draw_north_arrow(self, x: float, y: float, height: float = 100.0):
300313
'color': 5,
301314
}
302315
).set_placement(
303-
(height * 0.2, height - (height * 0.25)),
316+
(height * 0.2, height - (height * 0.2)),
304317
align=TextEntityAlignment.MIDDLE_CENTER
305318
)
306319

@@ -560,7 +573,7 @@ def draw_topo_point(self, x: float, y: float, z: float = 0, label: str = None, t
560573
dxfattribs={
561574
'layer': 'SPOT_HEIGHTS',
562575
'height': text_height,
563-
'style': 'Standard',
576+
'style': 'SURVEY_TEXT',
564577
'color': 7 # Black/White
565578
}
566579
).set_placement(
@@ -594,7 +607,7 @@ def add_grid_mesh_label(self, x: float, y: float, z: float, label: str, text_hei
594607
self.msp.add_text(label, dxfattribs={
595608
"layer": "GRID_MESH",
596609
"height": text_height,
597-
"style": "Standard",
610+
"style": "SURVEY_TEXT",
598611
"rotation": rotation
599612
}).set_placement((x, y, z),)
600613

@@ -618,7 +631,7 @@ def add_grid_mesh_corner_coords(self, x: float, y: float, z: float, label: str,
618631
self.msp.add_text(label, dxfattribs={
619632
"layer": "GRID_MESH",
620633
"height": text_height,
621-
"style": "Standard",
634+
"style": "SURVEY_TEXT",
622635
"rotation": rotation
623636
}).set_placement((x, y, z),)
624637

@@ -734,51 +747,51 @@ def save_dwg(self, dxf_filepath: str, filepath: str = None):
734747
filepath = f"{self.get_filename()}.dwg"
735748
odafc.convert(dxf_filepath, filepath)
736749

750+
def save(self, paper_size: str = "A4", orientation: str = "portrait"):
751+
# with tempfile.TemporaryDirectory() as tmpdir:
752+
filename = self.get_filename()
753+
dxf_path = os.path.join("", f"{filename}.dxf")
754+
dwg_path = os.path.join("", f"{filename}.dwg")
755+
pdf_path = os.path.join("", f"{filename}.pdf")
756+
zip_path = os.path.join("", f"{filename}.zip")
757+
758+
self.save_dxf(dxf_path)
759+
self.save_dwg(dxf_path, dwg_path)
760+
self.save_pdf(pdf_path, paper_size=paper_size, orientation=orientation)
761+
762+
# Create a ZIP file containing all three formats
763+
with zipfile.ZipFile(zip_path, "w") as zipf:
764+
zipf.write(dxf_path, os.path.basename(dxf_path))
765+
zipf.write(dwg_path, os.path.basename(dwg_path))
766+
zipf.write(pdf_path, os.path.basename(pdf_path))
767+
768+
# url = upload_file(zip_path, folder="survey_plans", file_name=filename)
769+
# if url is None:
770+
# raise Exception("Upload failed")
771+
return "url"
772+
737773
# def save(self, paper_size: str = "A4", orientation: str = "portrait"):
738-
# # with tempfile.TemporaryDirectory() as tmpdir:
739-
# filename = self.get_filename()
740-
# dxf_path = os.path.join("", f"{filename}.dxf")
741-
# dwg_path = os.path.join("", f"{filename}.dwg")
742-
# pdf_path = os.path.join("", f"{filename}.pdf")
743-
# zip_path = os.path.join("", f"{filename}.zip")
774+
# with tempfile.TemporaryDirectory() as tmpdir:
775+
# filename = self.get_filename()
776+
# dxf_path = os.path.join(tmpdir, f"{filename}.dxf")
777+
# dwg_path = os.path.join(tmpdir, f"{filename}.dwg")
778+
# pdf_path = os.path.join(tmpdir, f"{filename}.pdf")
779+
# zip_path = os.path.join(tmpdir, f"{filename}.zip")
744780
#
745-
# self.save_dxf(dxf_path)
746-
# self.save_dwg(dxf_path, dwg_path)
747-
# self.save_pdf(pdf_path, paper_size=paper_size, orientation=orientation)
781+
# self.save_dxf(dxf_path)
782+
# self.save_dwg(dxf_path, dwg_path)
783+
# self.save_pdf(pdf_path, paper_size=paper_size, orientation=orientation)
748784
#
749-
# # Create a ZIP file containing all three formats
750-
# with zipfile.ZipFile(zip_path, "w") as zipf:
751-
# zipf.write(dxf_path, os.path.basename(dxf_path))
752-
# zipf.write(dwg_path, os.path.basename(dwg_path))
753-
# zipf.write(pdf_path, os.path.basename(pdf_path))
785+
# # Create a ZIP file containing all three formats
786+
# with zipfile.ZipFile(zip_path, "w") as zipf:
787+
# zipf.write(dxf_path, os.path.basename(dxf_path))
788+
# zipf.write(dwg_path, os.path.basename(dwg_path))
789+
# zipf.write(pdf_path, os.path.basename(pdf_path))
754790
#
755-
# # url = upload_file(zip_path, folder="survey_plans", file_name=filename)
756-
# # if url is None:
757-
# # raise Exception("Upload failed")
758-
# return "url"
759-
760-
def save(self, paper_size: str = "A4", orientation: str = "portrait"):
761-
with tempfile.TemporaryDirectory() as tmpdir:
762-
filename = self.get_filename()
763-
dxf_path = os.path.join(tmpdir, f"{filename}.dxf")
764-
dwg_path = os.path.join(tmpdir, f"{filename}.dwg")
765-
pdf_path = os.path.join(tmpdir, f"{filename}.pdf")
766-
zip_path = os.path.join(tmpdir, f"{filename}.zip")
767-
768-
self.save_dxf(dxf_path)
769-
self.save_dwg(dxf_path, dwg_path)
770-
self.save_pdf(pdf_path, paper_size=paper_size, orientation=orientation)
771-
772-
# Create a ZIP file containing all three formats
773-
with zipfile.ZipFile(zip_path, "w") as zipf:
774-
zipf.write(dxf_path, os.path.basename(dxf_path))
775-
zipf.write(dwg_path, os.path.basename(dwg_path))
776-
zipf.write(pdf_path, os.path.basename(pdf_path))
777-
778-
url = upload_file(zip_path, folder="survey_plans", file_name=filename)
779-
if url is None:
780-
raise Exception("Upload failed")
781-
return url
791+
# url = upload_file(zip_path, folder="survey_plans", file_name=filename)
792+
# if url is None:
793+
# raise Exception("Upload failed")
794+
# return url
782795

783796

784797

layout.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from shapely.geometry import Polygon, Point, LineString, MultiPolygon
33
from shapely.ops import split, unary_union
44
from shapely.affinity import rotate, translate
5-
from utils import polygon_orientation, line_normals, line_direction, html_to_mtext
5+
from utils import polygon_orientation, line_normals, line_direction, html_to_mtext, format_number
66
from typing import List, Tuple, Dict, Optional
77
from pydantic import BaseModel
88
from dxf import SurveyDXFManager
@@ -687,14 +687,14 @@ def _add_leg_labels(self, leg, orientation: str):
687687
angle=text_angle, height=self.label_size)
688688
ld = line_direction(angle_deg)
689689
if ld == "left → right":
690-
self._drawer.add_label(f"{leg.bearing.degrees}°", first_x, first_y,
690+
self._drawer.add_label(f"{format_number(leg.bearing.degrees, "hundredth")}°", first_x, first_y,
691691
angle=text_angle, height=self.label_size)
692-
self._drawer.add_label(f"{leg.bearing.minutes}'", last_x, last_y,
692+
self._drawer.add_label(f"{format_number(leg.bearing.minutes, "tenth")}'", last_x, last_y,
693693
angle=text_angle, height=self.label_size)
694694
else:
695-
self._drawer.add_label(f"{leg.bearing.degrees}°", last_x, last_y,
695+
self._drawer.add_label(f"{format_number(leg.bearing.degrees, "hundredth")}°", last_x, last_y,
696696
angle=text_angle, height=self.label_size)
697-
self._drawer.add_label(f"{leg.bearing.minutes}'", first_x, first_y,
697+
self._drawer.add_label(f"{format_number(leg.bearing.minutes, "tenth")}'", first_x, first_y,
698698
angle=text_angle, height=self.label_size)
699699

700700
def _draw_boundary(self):
@@ -924,7 +924,7 @@ def draw_footer_boxes(self):
924924
y_max = self._frame_coords[3]
925925

926926
box_width = (x_max - x_min) / len(self.footers)
927-
box_height = (y_max - y_min) * 0.25
927+
box_height = (y_max - y_min) * 0.2
928928

929929
for i, footer in enumerate(self.footers):
930930
x1 = x_min + i * box_width
@@ -969,7 +969,7 @@ def draw_north_arrow(self):
969969
# for northing label
970970
northing_label_y = self._frame_coords[1]
971971
if len(self.footers) > 0:
972-
northing_label_y = northing_label_y + ((self._frame_coords[3] - self._frame_coords[1]) * 0.25)
972+
northing_label_y = northing_label_y + ((self._frame_coords[3] - self._frame_coords[1]) * 0.2)
973973

974974
self._drawer.add_north_arrow_label((coord.easting, northing_label_y),
975975
(coord.easting, northing_label_y + height), f"{coord.northing}mN",

route.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def draw_footer_boxes(self):
114114
y_max = self._frame_coords[3]
115115

116116
box_width = (x_max - x_min) / len(self.footers)
117-
box_height = (y_max - y_min) * 0.25
117+
box_height = (y_max - y_min) * 0.2
118118

119119
for i, footer in enumerate(self.footers):
120120
x1 = x_min + i * box_width

topographic.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from pydantic import PrivateAttr
66
from dxf import SurveyDXFManager
77
from models.plan import PlanProps, PlanType
8-
from utils import polygon_orientation, line_normals, line_direction, html_to_mtext
8+
from utils import polygon_orientation, line_normals, line_direction, html_to_mtext, format_number
99
from scipy.interpolate import griddata, LinearNDInterpolator
1010
from scipy.ndimage import gaussian_filter
1111
from scipy.spatial import Delaunay
@@ -160,14 +160,14 @@ def add_leg_labels(self, leg, orientation: str):
160160
angle=text_angle, height=self.label_size)
161161
ld = line_direction(angle_deg)
162162
if ld == "left → right":
163-
self._drawer.add_label(f"{leg.bearing.degrees}°", first_x, first_y,
163+
self._drawer.add_label(f"{format_number(leg.bearing.degrees, "hundredth")}°", first_x, first_y,
164164
angle=text_angle, height=self.label_size)
165-
self._drawer.add_label(f"{leg.bearing.minutes}'", last_x, last_y,
165+
self._drawer.add_label(f"{format_number(leg.bearing.minutes, "tenth")}'", last_x, last_y,
166166
angle=text_angle, height=self.label_size)
167167
else:
168-
self._drawer.add_label(f"{leg.bearing.degrees}°", last_x, last_y,
168+
self._drawer.add_label(f"{format_number(leg.bearing.degrees, "hundredth")}°", last_x, last_y,
169169
angle=text_angle, height=self.label_size)
170-
self._drawer.add_label(f"{leg.bearing.minutes}'", first_x, first_y,
170+
self._drawer.add_label(f"{format_number(leg.bearing.minutes, "tenth")}'", first_x, first_y,
171171
angle=text_angle, height=self.label_size)
172172

173173
def draw_frames(self):
@@ -217,7 +217,7 @@ def draw_footer_boxes(self):
217217
y_max = self._frame_coords[3]
218218

219219
box_width = (x_max - x_min) / len(self.footers)
220-
box_height = (y_max - y_min) * 0.25
220+
box_height = (y_max - y_min) * 0.2
221221

222222
for i, footer in enumerate(self.footers):
223223
x1 = x_min + i * box_width
@@ -534,7 +534,7 @@ def draw_north_arrow(self):
534534
# for northing label
535535
northing_label_y = self._frame_coords[1]
536536
if len(self.footers) > 0:
537-
northing_label_y = northing_label_y + ((self._frame_coords[3] - self._frame_coords[1]) * 0.25)
537+
northing_label_y = northing_label_y + ((self._frame_coords[3] - self._frame_coords[1]) * 0.2)
538538

539539

540540
self._drawer.add_north_arrow_label((coord.easting, northing_label_y), (coord.easting, northing_label_y + height), f"{coord.northing}mN", self.label_size)

utils.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,26 @@ def line_direction(angle) -> str:
2727
else:
2828
return "right → left"
2929

30+
31+
def format_number(num, mode="tenth"):
32+
if mode == "tenth":
33+
# Add one zero if number < 10
34+
if num < 10:
35+
return f"0{num}"
36+
return str(num)
37+
38+
elif mode == "hundredth":
39+
# Add one zero if number < 100
40+
# Add two zeros if number < 10
41+
if num < 10:
42+
return f"00{num}"
43+
elif num < 100:
44+
return f"0{num}"
45+
return str(num)
46+
47+
else:
48+
raise ValueError("mode must be either 'tenth' or 'hundredth'")
49+
3050
def html_to_mtext(html_text: str):
3151
if not html_text:
3252
return ""

0 commit comments

Comments
 (0)