compass-lib 0.0.1__py3-none-any.whl → 0.0.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- compass_lib/__init__.py +115 -3
- compass_lib/commands/__init__.py +2 -1
- compass_lib/commands/convert.py +225 -32
- compass_lib/commands/encrypt.py +115 -0
- compass_lib/commands/geojson.py +118 -0
- compass_lib/commands/main.py +4 -2
- compass_lib/constants.py +84 -0
- compass_lib/enums.py +309 -65
- compass_lib/errors.py +86 -0
- compass_lib/geo_utils.py +47 -0
- compass_lib/geojson.py +1024 -0
- compass_lib/interface.py +332 -0
- compass_lib/io.py +246 -0
- compass_lib/models.py +251 -0
- compass_lib/plot/__init__.py +28 -0
- compass_lib/plot/models.py +265 -0
- compass_lib/plot/parser.py +610 -0
- compass_lib/project/__init__.py +36 -0
- compass_lib/project/format.py +158 -0
- compass_lib/project/models.py +494 -0
- compass_lib/project/parser.py +638 -0
- compass_lib/survey/__init__.py +24 -0
- compass_lib/survey/format.py +284 -0
- compass_lib/survey/models.py +160 -0
- compass_lib/survey/parser.py +842 -0
- compass_lib/validation.py +74 -0
- compass_lib-0.0.3.dist-info/METADATA +60 -0
- compass_lib-0.0.3.dist-info/RECORD +31 -0
- {compass_lib-0.0.1.dist-info → compass_lib-0.0.3.dist-info}/WHEEL +1 -3
- compass_lib-0.0.3.dist-info/entry_points.txt +8 -0
- compass_lib/parser.py +0 -282
- compass_lib/section.py +0 -18
- compass_lib/shot.py +0 -21
- compass_lib-0.0.1.dist-info/METADATA +0 -268
- compass_lib-0.0.1.dist-info/RECORD +0 -14
- compass_lib-0.0.1.dist-info/entry_points.txt +0 -5
- compass_lib-0.0.1.dist-info/top_level.txt +0 -1
- {compass_lib-0.0.1.dist-info → compass_lib-0.0.3.dist-info/licenses}/LICENSE +0 -0
compass_lib/interface.py
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""Unified interface for Compass file I/O.
|
|
3
|
+
|
|
4
|
+
This module provides the primary entry point for reading and writing
|
|
5
|
+
Compass files. It follows the openspeleo_lib pattern:
|
|
6
|
+
|
|
7
|
+
1. Parsers produce dictionaries (like loading JSON from disk)
|
|
8
|
+
2. Dictionaries feed directly to Pydantic models via `model_validate()`
|
|
9
|
+
3. Models serialize to dictionaries via `model_dump()`
|
|
10
|
+
4. Formatters convert dictionaries to file content
|
|
11
|
+
|
|
12
|
+
This keeps parsing/formatting logic completely separate from Pydantic models.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from typing import Any
|
|
17
|
+
from typing import Protocol
|
|
18
|
+
|
|
19
|
+
from compass_lib.constants import COMPASS_ENCODING
|
|
20
|
+
from compass_lib.constants import JSON_ENCODING
|
|
21
|
+
from compass_lib.project.format import format_mak_file
|
|
22
|
+
from compass_lib.project.models import CompassMakFile
|
|
23
|
+
from compass_lib.project.parser import CompassProjectParser
|
|
24
|
+
from compass_lib.survey.format import format_dat_file
|
|
25
|
+
from compass_lib.survey.models import CompassDatFile
|
|
26
|
+
from compass_lib.survey.parser import CompassSurveyParser
|
|
27
|
+
|
|
28
|
+
# Re-export for backwards compatibility
|
|
29
|
+
DEFAULT_ENCODING = COMPASS_ENCODING
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ProgressCallback(Protocol):
|
|
33
|
+
"""Protocol for progress callbacks."""
|
|
34
|
+
|
|
35
|
+
def __call__(
|
|
36
|
+
self,
|
|
37
|
+
message: str | None = None,
|
|
38
|
+
completed: int | None = None,
|
|
39
|
+
total: int | None = None,
|
|
40
|
+
) -> None:
|
|
41
|
+
"""Report progress."""
|
|
42
|
+
...
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class CancellationToken:
|
|
46
|
+
"""Token for checking if an operation should be cancelled."""
|
|
47
|
+
|
|
48
|
+
def __init__(self) -> None:
|
|
49
|
+
self._cancelled = False
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def cancelled(self) -> bool:
|
|
53
|
+
"""Check if cancellation was requested."""
|
|
54
|
+
return self._cancelled
|
|
55
|
+
|
|
56
|
+
def cancel(self) -> None:
|
|
57
|
+
"""Request cancellation."""
|
|
58
|
+
self._cancelled = True
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class CompassInterface:
|
|
62
|
+
"""Unified interface for Compass file I/O.
|
|
63
|
+
|
|
64
|
+
This class provides all file I/O operations for Compass files,
|
|
65
|
+
following the pattern:
|
|
66
|
+
- Reading: File → Parser → Dictionary → model_validate() → Model
|
|
67
|
+
- Writing: Model → model_dump() → Dictionary → Formatter → File
|
|
68
|
+
|
|
69
|
+
Example:
|
|
70
|
+
# Load a complete project
|
|
71
|
+
project = CompassInterface.load_project(Path("cave.mak"))
|
|
72
|
+
|
|
73
|
+
# Access nested data
|
|
74
|
+
for file_dir in project.file_directives:
|
|
75
|
+
if file_dir.data:
|
|
76
|
+
for trip in file_dir.data.trips:
|
|
77
|
+
print(trip.header.survey_name)
|
|
78
|
+
|
|
79
|
+
# Save to JSON
|
|
80
|
+
CompassInterface.save_json(project, Path("cave.json"))
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
# -------------------------------------------------------------------------
|
|
84
|
+
# Loading Methods (File → Model)
|
|
85
|
+
# -------------------------------------------------------------------------
|
|
86
|
+
|
|
87
|
+
@classmethod
|
|
88
|
+
def load_project(
|
|
89
|
+
cls,
|
|
90
|
+
mak_path: Path,
|
|
91
|
+
*,
|
|
92
|
+
encoding: str = DEFAULT_ENCODING,
|
|
93
|
+
on_progress: ProgressCallback | None = None,
|
|
94
|
+
cancellation: CancellationToken | None = None,
|
|
95
|
+
) -> CompassMakFile:
|
|
96
|
+
"""Load a complete Compass project (MAK + all DAT files).
|
|
97
|
+
|
|
98
|
+
This is the main entry point for loading Compass projects. It:
|
|
99
|
+
1. Parses the MAK file to dictionary
|
|
100
|
+
2. Parses each referenced DAT file to dictionary
|
|
101
|
+
3. Nests DAT dictionaries into file directives
|
|
102
|
+
4. Validates entire structure with single model_validate() call
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
mak_path: Path to the .MAK file
|
|
106
|
+
encoding: Character encoding (default: Windows-1252)
|
|
107
|
+
on_progress: Optional progress callback
|
|
108
|
+
cancellation: Optional cancellation token
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
CompassMakFile with all DAT data loaded
|
|
112
|
+
|
|
113
|
+
Raises:
|
|
114
|
+
InterruptedError: If cancellation was requested
|
|
115
|
+
FileNotFoundError: If MAK file doesn't exist
|
|
116
|
+
"""
|
|
117
|
+
if on_progress:
|
|
118
|
+
on_progress(message=f"Reading {mak_path}")
|
|
119
|
+
|
|
120
|
+
# Parse MAK file to dictionary
|
|
121
|
+
mak_parser = CompassProjectParser()
|
|
122
|
+
with mak_path.open(encoding=encoding, errors="replace") as f:
|
|
123
|
+
mak_content = f.read()
|
|
124
|
+
mak_data = mak_parser.parse_string_to_dict(mak_content, str(mak_path))
|
|
125
|
+
|
|
126
|
+
if cancellation and cancellation.cancelled:
|
|
127
|
+
raise InterruptedError("Operation cancelled")
|
|
128
|
+
|
|
129
|
+
# Calculate total size for progress
|
|
130
|
+
mak_dir = mak_path.parent
|
|
131
|
+
total_size = 0
|
|
132
|
+
dat_files: list[tuple[dict[str, Any], Path]] = []
|
|
133
|
+
|
|
134
|
+
for directive in mak_data.get("directives", []):
|
|
135
|
+
if directive.get("type") == "file":
|
|
136
|
+
dat_path = mak_dir / directive["file"]
|
|
137
|
+
if dat_path.exists():
|
|
138
|
+
total_size += dat_path.stat().st_size
|
|
139
|
+
dat_files.append((directive, dat_path))
|
|
140
|
+
|
|
141
|
+
# Parse each DAT file and attach to directive dictionary
|
|
142
|
+
completed = 0
|
|
143
|
+
dat_parser = CompassSurveyParser()
|
|
144
|
+
|
|
145
|
+
for directive, dat_path in dat_files:
|
|
146
|
+
if cancellation and cancellation.cancelled:
|
|
147
|
+
raise InterruptedError("Operation cancelled")
|
|
148
|
+
|
|
149
|
+
if on_progress:
|
|
150
|
+
on_progress(
|
|
151
|
+
message=f"Reading {dat_path.name}",
|
|
152
|
+
completed=completed,
|
|
153
|
+
total=total_size,
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
# Parse DAT file to dictionary and attach
|
|
157
|
+
with dat_path.open(encoding=encoding, errors="replace") as f:
|
|
158
|
+
dat_content = f.read()
|
|
159
|
+
dat_data = dat_parser.parse_string_to_dict(dat_content, str(dat_path))
|
|
160
|
+
directive["data"] = dat_data
|
|
161
|
+
|
|
162
|
+
completed += dat_path.stat().st_size
|
|
163
|
+
if on_progress:
|
|
164
|
+
on_progress(completed=completed, total=total_size)
|
|
165
|
+
|
|
166
|
+
# Single model_validate() call for entire structure
|
|
167
|
+
return CompassMakFile.model_validate(mak_data)
|
|
168
|
+
|
|
169
|
+
@classmethod
|
|
170
|
+
def load_dat(
|
|
171
|
+
cls,
|
|
172
|
+
path: Path,
|
|
173
|
+
*,
|
|
174
|
+
encoding: str = DEFAULT_ENCODING,
|
|
175
|
+
) -> CompassDatFile:
|
|
176
|
+
"""Load a single DAT file.
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
path: Path to the .DAT file
|
|
180
|
+
encoding: Character encoding
|
|
181
|
+
|
|
182
|
+
Returns:
|
|
183
|
+
CompassDatFile with all trips
|
|
184
|
+
"""
|
|
185
|
+
parser = CompassSurveyParser()
|
|
186
|
+
with path.open(encoding=encoding, errors="replace") as f:
|
|
187
|
+
content = f.read()
|
|
188
|
+
data = parser.parse_string_to_dict(content, str(path))
|
|
189
|
+
|
|
190
|
+
# Single model_validate() call
|
|
191
|
+
return CompassDatFile.model_validate(data)
|
|
192
|
+
|
|
193
|
+
@classmethod
|
|
194
|
+
def load_mak(
|
|
195
|
+
cls,
|
|
196
|
+
path: Path,
|
|
197
|
+
*,
|
|
198
|
+
encoding: str = DEFAULT_ENCODING,
|
|
199
|
+
) -> CompassMakFile:
|
|
200
|
+
"""Load a MAK file without loading DAT files.
|
|
201
|
+
|
|
202
|
+
Args:
|
|
203
|
+
path: Path to the .MAK file
|
|
204
|
+
encoding: Character encoding
|
|
205
|
+
|
|
206
|
+
Returns:
|
|
207
|
+
CompassMakFile with directives only (no DAT data)
|
|
208
|
+
"""
|
|
209
|
+
parser = CompassProjectParser()
|
|
210
|
+
with path.open(encoding=encoding, errors="replace") as f:
|
|
211
|
+
content = f.read()
|
|
212
|
+
data = parser.parse_string_to_dict(content, str(path))
|
|
213
|
+
|
|
214
|
+
# Single model_validate() call
|
|
215
|
+
return CompassMakFile.model_validate(data)
|
|
216
|
+
|
|
217
|
+
# -------------------------------------------------------------------------
|
|
218
|
+
# Saving Methods (Model → File)
|
|
219
|
+
# -------------------------------------------------------------------------
|
|
220
|
+
|
|
221
|
+
@classmethod
|
|
222
|
+
def save_project(
|
|
223
|
+
cls,
|
|
224
|
+
project: CompassMakFile,
|
|
225
|
+
mak_path: Path,
|
|
226
|
+
*,
|
|
227
|
+
encoding: str = DEFAULT_ENCODING,
|
|
228
|
+
save_dat_files: bool = True,
|
|
229
|
+
) -> None:
|
|
230
|
+
"""Save a complete Compass project (MAK + all DAT files).
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
project: The project to save
|
|
234
|
+
mak_path: Path to write the .MAK file
|
|
235
|
+
encoding: Character encoding (default: Windows-1252)
|
|
236
|
+
save_dat_files: Whether to also save DAT files (default: True)
|
|
237
|
+
"""
|
|
238
|
+
# Save MAK file
|
|
239
|
+
cls.save_mak(project, mak_path, encoding=encoding)
|
|
240
|
+
|
|
241
|
+
# Optionally save DAT files
|
|
242
|
+
if save_dat_files:
|
|
243
|
+
mak_dir = mak_path.parent
|
|
244
|
+
for file_dir in project.file_directives:
|
|
245
|
+
if file_dir.data:
|
|
246
|
+
dat_path = mak_dir / file_dir.file
|
|
247
|
+
cls.save_dat(file_dir.data, dat_path, encoding=encoding)
|
|
248
|
+
|
|
249
|
+
@classmethod
|
|
250
|
+
def save_mak(
|
|
251
|
+
cls,
|
|
252
|
+
project: CompassMakFile,
|
|
253
|
+
path: Path,
|
|
254
|
+
*,
|
|
255
|
+
encoding: str = DEFAULT_ENCODING,
|
|
256
|
+
) -> None:
|
|
257
|
+
"""Save a MAK file.
|
|
258
|
+
|
|
259
|
+
Args:
|
|
260
|
+
project: The project to save
|
|
261
|
+
path: Path to write to
|
|
262
|
+
encoding: Character encoding
|
|
263
|
+
"""
|
|
264
|
+
content = format_mak_file(project.directives)
|
|
265
|
+
with path.open(mode="w", encoding=encoding, newline="") as f:
|
|
266
|
+
f.write(content or "")
|
|
267
|
+
|
|
268
|
+
@classmethod
|
|
269
|
+
def save_dat(
|
|
270
|
+
cls,
|
|
271
|
+
dat_file: CompassDatFile,
|
|
272
|
+
path: Path,
|
|
273
|
+
*,
|
|
274
|
+
encoding: str = DEFAULT_ENCODING,
|
|
275
|
+
) -> None:
|
|
276
|
+
"""Save a DAT file.
|
|
277
|
+
|
|
278
|
+
Args:
|
|
279
|
+
dat_file: The DAT file to save
|
|
280
|
+
path: Path to write to
|
|
281
|
+
encoding: Character encoding
|
|
282
|
+
"""
|
|
283
|
+
content = format_dat_file(dat_file.trips)
|
|
284
|
+
with path.open(mode="w", encoding=encoding, newline="") as f:
|
|
285
|
+
f.write(content or "")
|
|
286
|
+
|
|
287
|
+
# -------------------------------------------------------------------------
|
|
288
|
+
# JSON Methods
|
|
289
|
+
# -------------------------------------------------------------------------
|
|
290
|
+
|
|
291
|
+
@classmethod
|
|
292
|
+
def save_json(
|
|
293
|
+
cls,
|
|
294
|
+
model: CompassMakFile | CompassDatFile,
|
|
295
|
+
path: Path,
|
|
296
|
+
) -> None:
|
|
297
|
+
"""Save a model as JSON.
|
|
298
|
+
|
|
299
|
+
Uses Pydantic's built-in serialization.
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
model: Project or DAT file to serialize
|
|
303
|
+
path: Path to write JSON file
|
|
304
|
+
"""
|
|
305
|
+
json_str = model.model_dump_json(indent=2, by_alias=True)
|
|
306
|
+
path.write_text(json_str, encoding=JSON_ENCODING)
|
|
307
|
+
|
|
308
|
+
@classmethod
|
|
309
|
+
def load_project_json(cls, path: Path) -> CompassMakFile:
|
|
310
|
+
"""Load a project from JSON.
|
|
311
|
+
|
|
312
|
+
Args:
|
|
313
|
+
path: Path to JSON file
|
|
314
|
+
|
|
315
|
+
Returns:
|
|
316
|
+
Deserialized project
|
|
317
|
+
"""
|
|
318
|
+
json_str = path.read_text(encoding=JSON_ENCODING)
|
|
319
|
+
return CompassMakFile.model_validate_json(json_str)
|
|
320
|
+
|
|
321
|
+
@classmethod
|
|
322
|
+
def load_dat_json(cls, path: Path) -> CompassDatFile:
|
|
323
|
+
"""Load a DAT file from JSON.
|
|
324
|
+
|
|
325
|
+
Args:
|
|
326
|
+
path: Path to JSON file
|
|
327
|
+
|
|
328
|
+
Returns:
|
|
329
|
+
Deserialized DAT file
|
|
330
|
+
"""
|
|
331
|
+
json_str = path.read_text(encoding=JSON_ENCODING)
|
|
332
|
+
return CompassDatFile.model_validate_json(json_str)
|
compass_lib/io.py
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""File I/O operations for Compass files.
|
|
3
|
+
|
|
4
|
+
This module provides backwards-compatible wrappers around CompassInterface.
|
|
5
|
+
|
|
6
|
+
For new code, prefer using CompassInterface directly:
|
|
7
|
+
|
|
8
|
+
from compass_lib.interface import CompassInterface
|
|
9
|
+
|
|
10
|
+
project = CompassInterface.load_project(Path("cave.mak"))
|
|
11
|
+
CompassInterface.save_json(project, Path("cave.json"))
|
|
12
|
+
|
|
13
|
+
The functions in this module are thin wrappers maintained for API stability.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
from compass_lib.interface import DEFAULT_ENCODING
|
|
19
|
+
from compass_lib.interface import CancellationToken
|
|
20
|
+
from compass_lib.interface import CompassInterface
|
|
21
|
+
from compass_lib.interface import ProgressCallback
|
|
22
|
+
from compass_lib.project.models import CompassMakFile
|
|
23
|
+
from compass_lib.project.models import CompassProjectDirective
|
|
24
|
+
from compass_lib.survey.models import CompassDatFile
|
|
25
|
+
from compass_lib.survey.models import CompassTrip
|
|
26
|
+
|
|
27
|
+
# Re-export for API compatibility
|
|
28
|
+
__all__ = [
|
|
29
|
+
"DEFAULT_ENCODING",
|
|
30
|
+
"CancellationToken",
|
|
31
|
+
"ProgressCallback",
|
|
32
|
+
"load_dat_json",
|
|
33
|
+
"load_project",
|
|
34
|
+
"load_project_json",
|
|
35
|
+
"read_dat_file",
|
|
36
|
+
"read_mak_and_dat_files",
|
|
37
|
+
"read_mak_file",
|
|
38
|
+
"save_dat_json",
|
|
39
|
+
"save_project",
|
|
40
|
+
"save_project_json",
|
|
41
|
+
"write_dat_file",
|
|
42
|
+
"write_mak_file",
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# --- Reading Functions ---
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def read_dat_file(
|
|
50
|
+
path: Path,
|
|
51
|
+
*,
|
|
52
|
+
encoding: str = DEFAULT_ENCODING,
|
|
53
|
+
) -> list[CompassTrip]:
|
|
54
|
+
"""Read a Compass .DAT survey file.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
path: Path to the .DAT file
|
|
58
|
+
encoding: Character encoding (default: Windows-1252)
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
List of parsed trips
|
|
62
|
+
"""
|
|
63
|
+
dat_file = CompassInterface.load_dat(path, encoding=encoding)
|
|
64
|
+
return dat_file.trips
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def read_mak_file(
|
|
68
|
+
path: Path,
|
|
69
|
+
*,
|
|
70
|
+
encoding: str = DEFAULT_ENCODING,
|
|
71
|
+
) -> list[CompassProjectDirective]:
|
|
72
|
+
"""Read a Compass .MAK project file (directives only).
|
|
73
|
+
|
|
74
|
+
This function reads only the MAK file and does not load referenced
|
|
75
|
+
DAT files. Use `load_project()` to load the complete project with
|
|
76
|
+
all DAT file data.
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
path: Path to the .MAK file
|
|
80
|
+
encoding: Character encoding (default: Windows-1252)
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
List of parsed directives
|
|
84
|
+
"""
|
|
85
|
+
mak_file = CompassInterface.load_mak(path, encoding=encoding)
|
|
86
|
+
return mak_file.directives
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def load_project(
|
|
90
|
+
mak_path: Path,
|
|
91
|
+
*,
|
|
92
|
+
encoding: str = DEFAULT_ENCODING,
|
|
93
|
+
on_progress: ProgressCallback | None = None,
|
|
94
|
+
cancellation: CancellationToken | None = None,
|
|
95
|
+
) -> CompassMakFile:
|
|
96
|
+
"""Load a complete Compass project (MAK + all DAT files).
|
|
97
|
+
|
|
98
|
+
This is the main entry point for loading Compass projects.
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
mak_path: Path to the .MAK file
|
|
102
|
+
encoding: Character encoding (default: Windows-1252)
|
|
103
|
+
on_progress: Optional progress callback
|
|
104
|
+
cancellation: Optional cancellation token
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
CompassMakFile with all DAT data loaded
|
|
108
|
+
|
|
109
|
+
Raises:
|
|
110
|
+
InterruptedError: If cancellation was requested
|
|
111
|
+
FileNotFoundError: If MAK file doesn't exist
|
|
112
|
+
"""
|
|
113
|
+
return CompassInterface.load_project(
|
|
114
|
+
mak_path,
|
|
115
|
+
encoding=encoding,
|
|
116
|
+
on_progress=on_progress,
|
|
117
|
+
cancellation=cancellation,
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def read_mak_and_dat_files(
|
|
122
|
+
mak_path: Path,
|
|
123
|
+
*,
|
|
124
|
+
encoding: str = DEFAULT_ENCODING,
|
|
125
|
+
on_progress: ProgressCallback | None = None,
|
|
126
|
+
cancellation: CancellationToken | None = None,
|
|
127
|
+
) -> list[CompassProjectDirective]:
|
|
128
|
+
"""Read a Compass .MAK project file and all linked .DAT files.
|
|
129
|
+
|
|
130
|
+
Note: This function returns a list of directives for backwards compatibility.
|
|
131
|
+
For new code, use `load_project()` which returns a `CompassMakFile` object.
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
mak_path: Path to the .MAK file
|
|
135
|
+
encoding: Character encoding (default: Windows-1252)
|
|
136
|
+
on_progress: Optional progress callback
|
|
137
|
+
cancellation: Optional cancellation token
|
|
138
|
+
|
|
139
|
+
Returns:
|
|
140
|
+
List of parsed directives with attached DAT file data
|
|
141
|
+
|
|
142
|
+
Raises:
|
|
143
|
+
InterruptedError: If cancellation was requested
|
|
144
|
+
"""
|
|
145
|
+
mak_file = load_project(
|
|
146
|
+
mak_path,
|
|
147
|
+
encoding=encoding,
|
|
148
|
+
on_progress=on_progress,
|
|
149
|
+
cancellation=cancellation,
|
|
150
|
+
)
|
|
151
|
+
return mak_file.directives
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
# --- Writing Functions ---
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def write_dat_file(
|
|
158
|
+
path: Path,
|
|
159
|
+
trips: list[CompassTrip],
|
|
160
|
+
*,
|
|
161
|
+
encoding: str = DEFAULT_ENCODING,
|
|
162
|
+
) -> None:
|
|
163
|
+
"""Write a Compass .DAT survey file.
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
path: Path to write to
|
|
167
|
+
trips: List of trips to write
|
|
168
|
+
encoding: Character encoding (default: Windows-1252)
|
|
169
|
+
"""
|
|
170
|
+
dat_file = CompassDatFile(trips=trips)
|
|
171
|
+
CompassInterface.save_dat(dat_file, path, encoding=encoding)
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def write_mak_file(
|
|
175
|
+
path: Path,
|
|
176
|
+
directives: list[CompassProjectDirective],
|
|
177
|
+
*,
|
|
178
|
+
encoding: str = DEFAULT_ENCODING,
|
|
179
|
+
) -> None:
|
|
180
|
+
"""Write a Compass .MAK project file.
|
|
181
|
+
|
|
182
|
+
Args:
|
|
183
|
+
path: Path to write to
|
|
184
|
+
directives: List of directives to write
|
|
185
|
+
encoding: Character encoding (default: Windows-1252)
|
|
186
|
+
"""
|
|
187
|
+
project = CompassMakFile(directives=directives)
|
|
188
|
+
CompassInterface.save_mak(project, path, encoding=encoding)
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def save_project(
|
|
192
|
+
mak_path: Path,
|
|
193
|
+
project: CompassMakFile,
|
|
194
|
+
*,
|
|
195
|
+
encoding: str = DEFAULT_ENCODING,
|
|
196
|
+
save_dat_files: bool = True,
|
|
197
|
+
) -> None:
|
|
198
|
+
"""Save a complete Compass project (MAK + all DAT files).
|
|
199
|
+
|
|
200
|
+
Args:
|
|
201
|
+
mak_path: Path to write the .MAK file
|
|
202
|
+
project: The project to save
|
|
203
|
+
encoding: Character encoding (default: Windows-1252)
|
|
204
|
+
save_dat_files: Whether to also save DAT files (default: True)
|
|
205
|
+
"""
|
|
206
|
+
CompassInterface.save_project(
|
|
207
|
+
project,
|
|
208
|
+
mak_path,
|
|
209
|
+
encoding=encoding,
|
|
210
|
+
save_dat_files=save_dat_files,
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
# --- JSON I/O Functions ---
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
def save_project_json(path: Path, project: CompassMakFile) -> None:
|
|
218
|
+
"""Save a project as JSON.
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
path: Path to write JSON file
|
|
222
|
+
project: Project to serialize
|
|
223
|
+
"""
|
|
224
|
+
CompassInterface.save_json(project, path)
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
def load_project_json(path: Path) -> CompassMakFile:
|
|
228
|
+
"""Load a project from JSON.
|
|
229
|
+
|
|
230
|
+
Args:
|
|
231
|
+
path: Path to JSON file
|
|
232
|
+
|
|
233
|
+
Returns:
|
|
234
|
+
Deserialized project
|
|
235
|
+
"""
|
|
236
|
+
return CompassInterface.load_project_json(path)
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def save_dat_json(path: Path, dat_file: CompassDatFile) -> None:
|
|
240
|
+
"""Save a DAT file as JSON."""
|
|
241
|
+
CompassInterface.save_json(dat_file, path)
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def load_dat_json(path: Path) -> CompassDatFile:
|
|
245
|
+
"""Load a DAT file from JSON."""
|
|
246
|
+
return CompassInterface.load_dat_json(path)
|