Skip to content

api

应用层:DMF 文件 API

核心类 DmfFile: - 打开/保存 DMF 文件 - 以属性方式访问图层和实体信息 - 支持插入实体(点、线、多段线、Shell、文本)

DmfFile 内部维护 DMF 的完整 Python 内存模型: 只有在 load() 解析文件和 save() 落盘时才接触底层 DmPyBindInterface。

Usage

with DmfFile("model.dmf") as dmf: print(dmf.layers) # 所有图层(实体为 types.py 共享类型) layer = dmf[0] # 按索引 layer = dmf["地形"] # 按名称 layer.insert_point(np.array([1, 2, 3]), name="测点") dmf.save("output.dmf")

DmfFile

DMF 文件管理器,Python 侧完整内存模型

Source code in dimine_python_sdk\lib\file\api.py
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
class DmfFile:
    """DMF 文件管理器,Python 侧完整内存模型"""

    def __init__(self, file_path: Optional[str] = None):
        self.file_path: Optional[str] = None
        self._layers: List[DmfLayer] = []

        if file_path is not None:
            self.load(file_path)

    # ------------------------------------------------------------------
    # 生命周期
    # ------------------------------------------------------------------

    def load(self, file_path: str) -> None:
        """加载 DMF 文件到 Python 内存模型"""
        path = Path(file_path)
        if not path.exists():
            raise DmfLoadError(f"文件不存在: {file_path}")

        db = create_local_database()
        if not database_load(db, str(file_path)):
            raise DmfLoadError(f"加载失败: {file_path}")

        self._layers = parse_dmf_file(db)

        self.file_path = file_path

    def save(self, file_path: Optional[str] = None) -> None:
        """将 Python 内存模型保存为 DMF 文件"""
        save_path = file_path or self.file_path
        if not save_path:
            raise DmfSaveError("未指定保存路径")

        db = create_local_database()
        build_dmf_from_model(db, self._layers)
        if not database_save(db, str(save_path)):
            raise DmfSaveError(f"保存失败: {save_path}")

    def close(self) -> None:
        """释放资源"""
        self._layers.clear()
        self.file_path = None

    # ------------------------------------------------------------------
    # 内部辅助
    # ------------------------------------------------------------------

    def _resolve_layer(self, index_or_name: Union[int, str]) -> tuple[int, DmfLayer]:
        """解析图层索引/名称,返回 (idx, DmfLayer)"""
        if isinstance(index_or_name, int):
            idx = index_or_name
            if 0 <= idx < len(self._layers):
                return idx, self._layers[idx]
            raise IndexError(f"图层索引 {index_or_name} 超出范围")

        for i, layer in enumerate(self._layers):
            if layer.name == index_or_name:
                return i, layer
        raise KeyError(f"未找到图层: {index_or_name}")

    # ------------------------------------------------------------------
    # 属性
    # ------------------------------------------------------------------

    @property
    def name(self) -> str:
        """文件名(不含扩展名)"""
        return Path(self.file_path).stem if self.file_path else ""

    @property
    def layer_count(self) -> int:
        return len(self._layers)

    @property
    def layer_names(self) -> List[str]:
        return [layer.name for layer in self._layers]

    @property
    def layers(self) -> List[DmfLayer]:
        """所有图层(直接返回内存模型)"""
        return self._layers

    @property
    def info(self) -> Dict[str, Any]:
        total = sum(layer.entity_count for layer in self._layers)
        return {
            "file": self.file_path or "",
            "name": self.name,
            "layers": self.layer_count,
            "total_entities": total,
            "layer_names": self.layer_names,
        }

    # ------------------------------------------------------------------
    # 图层操作
    # ------------------------------------------------------------------

    def get_layer(self, index_or_name: Union[int, str]) -> DmfLayer:
        """获取图层(直接返回内存模型)"""
        _, layer = self._resolve_layer(index_or_name)
        return layer

    def add_layer(self, name: str) -> DmfLayer:
        """添加新图层(仅更新内存模型)"""
        if not name.strip():
            raise ValueError("图层名称不能为空")

        idx = len(self._layers)
        new_layer = DmfLayer(
            id=str(idx),
            name=name.strip(),
            entities=[],
        )
        self._layers.append(new_layer)
        return new_layer

    # ------------------------------------------------------------------
    # 实体插入 —— 仅修改内存模型
    # ------------------------------------------------------------------

    def insert_point(
        self,
        layer: Union[int, str],
        position: np.ndarray,
        *,
        name: str = "",
    ) -> None:
        """向指定图层插入点实体"""
        _, lyr = self._resolve_layer(layer)
        lyr.insert_point(position, name=name)

    def insert_line(
        self,
        layer: Union[int, str],
        start: np.ndarray,
        end: np.ndarray,
        *,
        name: str = "",
    ) -> None:
        """向指定图层插入直线"""
        _, lyr = self._resolve_layer(layer)
        lyr.insert_line(start, end, name=name)

    def insert_polyline(
        self,
        layer: Union[int, str],
        points: np.ndarray,
        *,
        name: str = "",
    ) -> None:
        """向指定图层插入多段线"""
        _, lyr = self._resolve_layer(layer)
        lyr.insert_polyline(points, name=name)

    def insert_shell(
        self,
        layer: Union[int, str],
        points: np.ndarray,
        faces: np.ndarray,
        *,
        name: str = "",
    ) -> None:
        """向指定图层插入三维实体(Shell)"""
        _, lyr = self._resolve_layer(layer)
        lyr.insert_shell(points, faces, name=name)

    def insert_text(
        self,
        layer: Union[int, str],
        position: np.ndarray,
        text: str,
        *,
        name: str = "",
    ) -> None:
        """向指定图层插入文本标注"""
        _, lyr = self._resolve_layer(layer)
        lyr.insert_text(position, text, name=name)

    # ------------------------------------------------------------------
    # Pythonic 访问
    # ------------------------------------------------------------------

    def __getitem__(self, index_or_name: Union[int, str]) -> DmfLayer:
        return self.get_layer(index_or_name)

    def __len__(self) -> int:
        return self.layer_count

    def __iter__(self):
        return iter(self._layers)

    def __contains__(self, name: str) -> bool:
        return name in self.layer_names

    def __repr__(self) -> str:
        return (
            f"DmfFile('{self.file_path or ''}', "
            f"layers={self.layer_count}, "
            f"entities={sum(layer.entity_count for layer in self._layers)})"
        )

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.close()

layers property

所有图层(直接返回内存模型)

name property

文件名(不含扩展名)

add_layer(name)

添加新图层(仅更新内存模型)

Source code in dimine_python_sdk\lib\file\api.py
152
153
154
155
156
157
158
159
160
161
162
163
164
def add_layer(self, name: str) -> DmfLayer:
    """添加新图层(仅更新内存模型)"""
    if not name.strip():
        raise ValueError("图层名称不能为空")

    idx = len(self._layers)
    new_layer = DmfLayer(
        id=str(idx),
        name=name.strip(),
        entities=[],
    )
    self._layers.append(new_layer)
    return new_layer

close()

释放资源

Source code in dimine_python_sdk\lib\file\api.py
88
89
90
91
def close(self) -> None:
    """释放资源"""
    self._layers.clear()
    self.file_path = None

get_layer(index_or_name)

获取图层(直接返回内存模型)

Source code in dimine_python_sdk\lib\file\api.py
147
148
149
150
def get_layer(self, index_or_name: Union[int, str]) -> DmfLayer:
    """获取图层(直接返回内存模型)"""
    _, layer = self._resolve_layer(index_or_name)
    return layer

insert_line(layer, start, end, *, name='')

向指定图层插入直线

Source code in dimine_python_sdk\lib\file\api.py
181
182
183
184
185
186
187
188
189
190
191
def insert_line(
    self,
    layer: Union[int, str],
    start: np.ndarray,
    end: np.ndarray,
    *,
    name: str = "",
) -> None:
    """向指定图层插入直线"""
    _, lyr = self._resolve_layer(layer)
    lyr.insert_line(start, end, name=name)

insert_point(layer, position, *, name='')

向指定图层插入点实体

Source code in dimine_python_sdk\lib\file\api.py
170
171
172
173
174
175
176
177
178
179
def insert_point(
    self,
    layer: Union[int, str],
    position: np.ndarray,
    *,
    name: str = "",
) -> None:
    """向指定图层插入点实体"""
    _, lyr = self._resolve_layer(layer)
    lyr.insert_point(position, name=name)

insert_polyline(layer, points, *, name='')

向指定图层插入多段线

Source code in dimine_python_sdk\lib\file\api.py
193
194
195
196
197
198
199
200
201
202
def insert_polyline(
    self,
    layer: Union[int, str],
    points: np.ndarray,
    *,
    name: str = "",
) -> None:
    """向指定图层插入多段线"""
    _, lyr = self._resolve_layer(layer)
    lyr.insert_polyline(points, name=name)

insert_shell(layer, points, faces, *, name='')

向指定图层插入三维实体(Shell)

Source code in dimine_python_sdk\lib\file\api.py
204
205
206
207
208
209
210
211
212
213
214
def insert_shell(
    self,
    layer: Union[int, str],
    points: np.ndarray,
    faces: np.ndarray,
    *,
    name: str = "",
) -> None:
    """向指定图层插入三维实体(Shell)"""
    _, lyr = self._resolve_layer(layer)
    lyr.insert_shell(points, faces, name=name)

insert_text(layer, position, text, *, name='')

向指定图层插入文本标注

Source code in dimine_python_sdk\lib\file\api.py
216
217
218
219
220
221
222
223
224
225
226
def insert_text(
    self,
    layer: Union[int, str],
    position: np.ndarray,
    text: str,
    *,
    name: str = "",
) -> None:
    """向指定图层插入文本标注"""
    _, lyr = self._resolve_layer(layer)
    lyr.insert_text(position, text, name=name)

load(file_path)

加载 DMF 文件到 Python 内存模型

Source code in dimine_python_sdk\lib\file\api.py
63
64
65
66
67
68
69
70
71
72
73
74
75
def load(self, file_path: str) -> None:
    """加载 DMF 文件到 Python 内存模型"""
    path = Path(file_path)
    if not path.exists():
        raise DmfLoadError(f"文件不存在: {file_path}")

    db = create_local_database()
    if not database_load(db, str(file_path)):
        raise DmfLoadError(f"加载失败: {file_path}")

    self._layers = parse_dmf_file(db)

    self.file_path = file_path

save(file_path=None)

将 Python 内存模型保存为 DMF 文件

Source code in dimine_python_sdk\lib\file\api.py
77
78
79
80
81
82
83
84
85
86
def save(self, file_path: Optional[str] = None) -> None:
    """将 Python 内存模型保存为 DMF 文件"""
    save_path = file_path or self.file_path
    if not save_path:
        raise DmfSaveError("未指定保存路径")

    db = create_local_database()
    build_dmf_from_model(db, self._layers)
    if not database_save(db, str(save_path)):
        raise DmfSaveError(f"保存失败: {save_path}")

dmf_conn(file_path=None)

DMF 文件连接上下文管理器

Source code in dimine_python_sdk\lib\file\api.py
258
259
260
261
262
263
264
265
@contextmanager
def dmf_conn(file_path: Optional[str] = None) -> Generator[DmfFile, None, None]:
    """DMF 文件连接上下文管理器"""
    dmf = DmfFile(file_path)
    try:
        yield dmf
    finally:
        dmf.close()