露天爆破设计完整流程
以下示例用 dimine_python_sdk.lib.blasting(纯 Python)从爆区多边形出发,完成
布孔 → 装药 → 起爆网络 → 纯计算分析 → 权威地表起爆时间,并装配、落盘为
Dimine 炮孔数据库 .dmo(26 列),同时导出便于 Excel 查看的炮孔汇总 CSV。
除最后一步 .dmo 落盘外,整个设计计算不需要 DIMINE_HOME、不需要启动 Dimine GUI。
前置条件
uv add pandas numpy # numpy 为设计核心依赖;pandas 仅用于可选查看(本文 CSV 用标准库,非必需)
- Python >= 3.12
- 环境变量
DIMINE_HOME指向含DmPyBindInterface.pyd的目录 —— 仅写.dmo需要, 未设置时脚本自动跳过落盘、只输出分析与 CSV - 输入:爆区多边形(示例内置;也可从 CSV 读取,见代码注释)
等时线/柱状图/动画(matplotlib)与 Excel 爆破设计说明书不在 SDK 内,属
open-pit-blasting-designskill;本文展示的是 SDK 数值流程本身。
完整示例
"""
露天爆破设计完整流程
输入: 爆区多边形(内置示例 60m×40m;可用 CSV 覆盖)
输出: 炮孔数据库 .dmo + 炮孔汇总 CSV + 控制台分析
用法:
python open_pit_blasting_design.py
"""
import csv
import os
from collections import defaultdict
from pathlib import Path
from dimine_python_sdk.lib.blasting import (
BlastRegion, HoleLayoutParams, ChargeParams, Explosive, NetworkParams,
DetonatorType, LayoutPattern, layout_holes, design_charge, build_network,
flyrock_range, throw_direction, blast_bounds, resolve_schedule, build_dmo,
FlyrockParams,
)
# ==============================================================================
# 输入与配置
# ==============================================================================
OUTPUT_DIR = Path("blast_design_output")
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
# 若装了 Dimine,让最后一步能落盘 .dmo:
# os.environ["DIMINE_HOME"] = r"E:\数采软件\x64\x64"
REGION_NAME = "M01"
POLYGON = [(0, 0), (60, 0), (60, 40), (0, 40)] # 爆区多边形顶点 (X, Y)
FRONT_AZIMUTH = 0.0 # 前排方向角 °(0=正北,自由面在 +Y 侧)
MOUTH_Z = 765.0 # 孔口标高 m
BENCH_DEPTH = 15.0 # 台阶高度 m
BURDEN = 4.0 # 最小抵抗线 W(m)
HOLE_SPACING, ROW_SPACING = 4.5, 3.5 # 孔距 / 排距 m
DIAMETER = 200.0 # 孔径 mm
DETONATOR = DetonatorType.NONEL # 雷管类型(导爆管/数码电子)
INIT_DELAY = 100.0 # 起爆点延时 ms
BURN_VELOCITY = 2000.0 # 导爆管燃速 m/s
EXPLOSIVES = [Explosive(name="乳化炸药", line_density=15.0, unit_price=5.5)] # kg/m
def main():
# ------------------------------------------------------------------
# ① 爆破区域:多边形 + 前排方向 + 孔口/孔底标高策略
# ------------------------------------------------------------------
region = BlastRegion(
name=REGION_NAME, polygon=POLYGON, front_azimuth=FRONT_AZIMUTH,
mouth={"mode": "z", "value": MOUTH_Z},
bottom={"mode": "depth", "value": BENCH_DEPTH},
)
# ------------------------------------------------------------------
# ② 布孔:孔网 / 安全距离 / 孔径 / 超深 → list[Hole]
# ------------------------------------------------------------------
layout = HoleLayoutParams(
pattern=LayoutPattern.SQUARE, # 方形 / 梅花形 / 三角形
hole_spacing=HOLE_SPACING, row_spacing=ROW_SPACING,
front_distance=4.0, back_distance=3.0, # 前排(自由面) / 后冲安全距离 m
left_distance=3.0, right_distance=3.0,
diameter=DIAMETER, inclination=-90.0, # 孔径 mm / 倾角°(负=向下)
front_overdrill=2.0, back_overdrill=1.0, # 前排 / 后排超深 m
detonator=DETONATOR, init_delay=INIT_DELAY,
)
holes = layout_holes(region, layout)
if not holes:
raise SystemExit("布孔结果为空:请检查爆区尺寸与安全距离")
front = sum(1 for h in holes if h.row == 0) # row==0 为前排
print(f"[1] 布孔完成: {len(holes)} 孔(前排 {front} 孔)")
print(f" {holes[0].number}: 孔深 {holes[0].depth}m, "
f"超深 {holes[0].overdrill}m, 台阶高 {holes[0].bench_height}m")
# ------------------------------------------------------------------
# ③ 装药:单耗 q × 负担面积 × 台阶高 → 每孔装药结构
# 装药长度 = 药量 ÷ 线装药密度;可换 design_charge_from_template 套模板
# ------------------------------------------------------------------
charges = design_charge(
holes, ChargeParams(template="间隔装药", in_hole_delay=350.0, deck_delay_step=30.0),
EXPLOSIVES, burden=BURDEN,
)
warn = [c for c in charges if c.warnings]
total_kg = sum(c.charge_weight for c in charges)
print(f"[2] 装药完成: 总药量 {total_kg:.1f} kg, 红警孔 {len(warn)} 个")
for c in warn[:5]:
print(f" {c.hole_number}: {c.warnings}") # 装药被截断 / 填塞不足等
c0 = charges[0]
print(f" {c0.hole_number}: 药量 {c0.charge_weight:.1f}kg, "
f"装药 {c0.charge_length:.1f}m, 填塞 {c0.stemming_length:.1f}m")
# ------------------------------------------------------------------
# ④ 起爆网络:V型/斜线型 → 连线树 + 设计地表起爆时间
# ------------------------------------------------------------------
net = build_network(
holes, NetworkParams(connection_type="V型", hole_delay=25.0,
row_delay_min=42.0, row_delay_max=65.0),
init_delay=layout.init_delay, charge_results=charges,
)
print(f"[3] 起爆网络: V型, 起爆孔 {net.initiating_hole}, 连线 {len(net.edges)} 条")
# ------------------------------------------------------------------
# ⑤ 纯计算分析:飞石 / 爆破范围 / 抛掷方向
# ------------------------------------------------------------------
fr = flyrock_range(FlyrockParams(W=BURDEN, n=1.0, Kf=1.0)) # GB 6722-2014
bb = blast_bounds(holes)
print(f"[4] 分析: 飞石影响范围 {fr['影响范围']} m; "
f"爆区 X {bb['X最小']:.1f}~{bb['X最大']:.1f}m, 炮孔 {bb['炮孔数']} 个; "
f"抛掷 {throw_direction(region)['vector']}")
# ------------------------------------------------------------------
# ⑥ 权威地表起爆时间(与 .dmo 落盘同口径)→ 装配 DMO → 落盘
# ------------------------------------------------------------------
surface = resolve_schedule(holes, charges, net, region,
burn_velocity=BURN_VELOCITY, detonator=DETONATOR)
net.delays = surface # 回写权威值
seg_kg = defaultdict(float)
for h, c in zip(holes, charges):
seg_kg[surface[h.number]] += c.charge_weight
print(f"[5] 权威地表起爆时间: 末段 {max(surface.values())} ms, "
f"单段最大药量 {max(seg_kg.values()):.1f} kg")
dmo = build_dmo(holes, charges, net, region,
burn_velocity=BURN_VELOCITY, detonator=DETONATOR)
# 输出① 炮孔汇总 CSV(纯标准库,UTF-8 BOM,Excel 可直接打开)
csv_path = OUTPUT_DIR / "炮孔汇总.csv"
with open(csv_path, "w", newline="", encoding="utf-8-sig") as f:
w = csv.writer(f)
w.writerow(["炮孔编号", "孔深(m)", "装药重量(kg)", "装药长度(m)",
"填塞长度(m)", "地表起爆时间(ms)", "单孔药量占比(%)"])
total = sum(c.charge_weight for c in charges) or 1.0
for h, c in zip(holes, charges):
w.writerow([h.number, round(h.depth, 2), round(c.charge_weight, 2),
round(c.charge_length, 2), round(c.stemming_length, 2),
surface[h.number], round(100 * c.charge_weight / total, 2)])
print(f" 汇总已写: {csv_path}")
# 输出② DMO 炮孔数据库(需 DIMINE_HOME;无原生运行环境时跳过)
dmo_path = OUTPUT_DIR / "炮孔数据库.dmo"
try:
dmo.save(str(dmo_path), burn_velocity=BURN_VELOCITY)
print(f"[6] 炮孔数据库已写: {dmo_path}")
except Exception as exc: # noqa: BLE001
print(f"[6] 跳过 .dmo 落盘(需 DIMINE_HOME 指向含 DmPyBindInterface.pyd 的目录): {exc}")
if __name__ == "__main__":
main()
用爆区多边形从 CSV 读取(顶点表带 X/Y 列即可):
import csv
with open("爆区.csv", newline="", encoding="utf-8-sig") as f:
POLYGON = [(float(r["X"]), float(r["Y"])) for r in csv.DictReader(f)]
装药也可改为「套装药模板」:先
ChargeTemplateDB().segments("间隔装药")取出模板, 再design_charge_from_template(holes, template, explosives, burden=4.0, params=...), 参数见 装药模板套用与适配。
运行输出示例
[1] 布孔完成: 130 孔(前排 13 孔)
A-01: 孔深 17.0m, 超深 2.0m, 台阶高 15.0m
[2] 装药完成: 总药量 14119.0 kg, 红警孔 0 个
A-01: 药量 108.0kg, 装药 7.2m, 填塞 5.8m
[3] 起爆网络: V型, 起爆孔 A-07, 连线 129 条
[4] 分析: 飞石影响范围 200.0 m; 爆区 X 3.0~57.0m, 炮孔 130 个; 抛掷 [0.0, 1.0]
[5] 权威地表起爆时间: 末段 657 ms, 单段最大药量 217.3 kg
汇总已写: blast_design_output/炮孔汇总.csv
[6] 炮孔数据库已写: blast_design_output/炮孔数据库.dmo # 无 DIMINE_HOME 时跳过
(以上为示例爆区运行结果节选,数值随输入变化。)
参数速查
| 参数 | 单位 | 示例值 | 说明 |
|---|---|---|---|
hole_spacing / row_spacing |
m | 4.5 / 3.5 | 孔间距 / 排间距(梅花/三角相邻排错半孔距) |
front_distance / back_distance |
m | 4 / 3 | 前排(自由面)/ 后冲安全距离 |
diameter / inclination |
mm / ° | 200 / -90 | 孔径 / 倾角(负=向下) |
front_overdrill / back_overdrill |
m | 2 / 1 | 前排 / 后排超深 |
specific_charge(单耗 q) |
kg/m³ | 0.4 | 与孔径/线密度匹配,否则装药被截断并红警 |
line_density(线装药密度) |
kg/m | 15 | 决定装药长度 |
| 孔间 / 排间延时 | ms | 25 / 42 | V 型累进基准 |
burn_velocity |
m/s | 2000 | 导爆管连线燃烧;数码电子不计 |
相关参考
- 指南:模块总览与数据模型
- 指南:爆破设计流程:布孔 → 装药 → 起爆网络 → 分析 → DMO
- 指南:全局配置库与参数来源(从 Dimine 全局配置读入上述参数)
- 指南:装药模板套用与适配
- 文件格式:DMO 炮孔数据库
- 其它示例:储量估算完整管线