merge: origin/sub_laptop_2 합류 — 9장 계수 표 합집합(양쪽 열쇠 모두 살림) · 9장 소요량 식 값 반영
This commit is contained in:
@@ -0,0 +1,639 @@
|
||||
"""건설품셈 공통 제8장 8-3(손료) · 8-4(운전경비) · 8-5(기계가격) 표 → resources/master_data/기계_건설품셈.json
|
||||
|
||||
본문 md(확정) 표를 읽어 기계 한 줄로 합침. 값은 md 에서만 · 계산·추정 없음.
|
||||
실행: python resources/master_data/scripts/build_기계_건설품셈.py [--dry]
|
||||
"""
|
||||
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
REPO = Path(__file__).resolve().parents[3]
|
||||
DIR = (
|
||||
REPO
|
||||
/ "resources/knowledge/original/원가계산/건설공사_표준품셈/본문/01_공통부문/제08장_건설기계"
|
||||
)
|
||||
OUT = REPO / "resources/master_data/기계_건설품셈.json"
|
||||
SRC = "건설품셈 공통 "
|
||||
NUM = re.compile(r"^-?\d+(?:,\d{3})*(?:\.\d+)?$")
|
||||
|
||||
# ---------------------------------------------------------------- md 읽기
|
||||
|
||||
|
||||
def cell_join(s, name=False):
|
||||
"""<br> 줄바꿈 이음. 숫자·연산자 사이는 붙이고 그 밖은 한 칸."""
|
||||
parts = s.split("<br>")
|
||||
out = parts[0].strip()
|
||||
for p in parts[1:]:
|
||||
p = p.strip()
|
||||
if not out or not p:
|
||||
out += p
|
||||
continue
|
||||
a, b = out[-1], p[0]
|
||||
if (a.isdigit() and b.isdigit()) or b in "×)" or a in "(×∼~" or (name and b == "("):
|
||||
out += p
|
||||
else:
|
||||
out += " " + p
|
||||
return out
|
||||
|
||||
|
||||
def read_md(path):
|
||||
"""표 목록 [{h3, h4, rows, notes}] — rows 는 구분줄 뺀 셀 목록."""
|
||||
L = path.read_text(encoding="utf8").split("\n")
|
||||
L = L[L.index("---", 1) + 1 :]
|
||||
tabs, h3, h4, i = [], "", "", 0
|
||||
while i < len(L):
|
||||
ln = L[i]
|
||||
if ln.startswith("### "):
|
||||
h3, h4 = ln[4:].strip(), ""
|
||||
elif ln.startswith("#### "):
|
||||
h4 = ln[5:].strip()
|
||||
elif ln.startswith("|"):
|
||||
rows = []
|
||||
while i < len(L) and L[i].startswith("|"):
|
||||
if not re.match(r"^\|[\s\-|:]+\|$", L[i]):
|
||||
rows.append([c.strip() for c in L[i].strip()[1:-1].split("|")])
|
||||
i += 1
|
||||
notes, comments = [], []
|
||||
while i < len(L) and not L[i].startswith(("#", "|")):
|
||||
t = L[i].strip()
|
||||
if t.startswith("<!--"):
|
||||
comments.append(t)
|
||||
elif t:
|
||||
notes.append(t.replace("\\*", "*"))
|
||||
i += 1
|
||||
tabs.append(
|
||||
{
|
||||
"h3": h3,
|
||||
"h4": h4,
|
||||
"rows": rows,
|
||||
"notes": notes,
|
||||
"comments": comments,
|
||||
"file": path.name,
|
||||
}
|
||||
)
|
||||
continue
|
||||
i += 1
|
||||
return tabs
|
||||
|
||||
|
||||
def num(s):
|
||||
"""쉼표 뺀 수 · '-' 와 빈칸은 None · 그 밖 글은 그대로."""
|
||||
s = s.strip()
|
||||
if s in ("", "-"):
|
||||
return None
|
||||
if NUM.match(s):
|
||||
t = s.replace(",", "")
|
||||
f = float(t)
|
||||
return int(f) if f == int(f) and "." not in t else float(t)
|
||||
return s
|
||||
|
||||
|
||||
def sec_no(h3):
|
||||
return h3.split()[0] # '8-3-1'
|
||||
|
||||
|
||||
def full_code(raw, prefix):
|
||||
raw = raw.strip()
|
||||
if re.fullmatch(r"\d{4}-\d{4}", raw):
|
||||
return raw, raw[:4]
|
||||
if re.fullmatch(r"-?\d{4}", raw) and prefix: # 원문에 「-0003」 꼴도 있음
|
||||
return f"{prefix}-{raw.lstrip('-')}", prefix
|
||||
return None, prefix
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- 8-3
|
||||
|
||||
|
||||
def unit_of(label):
|
||||
m = re.search(r"\(([^()]*)\)$", label)
|
||||
return m.group(1) if m else None
|
||||
|
||||
|
||||
def build_83(tabs, rows_out, tables_out, notes_out, anomalies):
|
||||
for t in tabs:
|
||||
h1 = t["rows"][0]
|
||||
c1 = [cell_join(c) for c in h1]
|
||||
code = re.match(r"\((\d{4})\)", t["h4"])
|
||||
code = code.group(1) if code else None
|
||||
key_note = f"{sec_no(t['h3'])} ({code})"
|
||||
if c1[0].replace(" ", "") == "공기압축기":
|
||||
tables_out.append(("관계", t, key_note))
|
||||
notes_out.setdefault(key_note, []).extend(t["notes"])
|
||||
continue
|
||||
has2 = len(t["rows"]) > 1 and t["rows"][1][0] == ""
|
||||
c2 = [cell_join(c) for c in t["rows"][1]] if has2 else None
|
||||
data = t["rows"][2:] if has2 else t["rows"][1:]
|
||||
H = [c.replace(" ", "") for c in c1]
|
||||
iN = next((i for i, h in enumerate(H) if h.startswith("내용")), None)
|
||||
iS = next(i for i, h in enumerate(H) if h.startswith("시간당"))
|
||||
sp_end = iN if iN is not None else iS
|
||||
spec = [] # (index, label)
|
||||
for i in range(1, sp_end):
|
||||
lab = (c2[i] if c2 and c2[i] else c1[i]).replace(" ", "")
|
||||
if c2 is None and lab == "규격" and i > 1 and c1[i - 1] and False:
|
||||
pass
|
||||
spec.append((i, lab))
|
||||
mid = [(i, H[i]) for i in range(sp_end, iS)]
|
||||
if c2:
|
||||
sons = [(i, c2[i].replace(" ", "")) for i in range(iS, len(c1))]
|
||||
else:
|
||||
sons = [(iS, "손료계수")]
|
||||
sons = [(i, "손료계수" if l == "계" else l) for i, l in sons]
|
||||
merged = {
|
||||
i
|
||||
for i in range(1, len(c1))
|
||||
if any(re.search(rf"병합: {i + 1}열 \d+~\d+행", c) for c in t["comments"])
|
||||
}
|
||||
prefix, inherit, group = None, {}, ""
|
||||
for r in data:
|
||||
r = r + [""] * (len(c1) - len(r))
|
||||
raw = r[0].strip()
|
||||
if re.fullmatch(r"\d{4}-", raw): # 「9020-」 접두 줄
|
||||
prefix = raw[:4]
|
||||
group = " ".join(cell_join(r[i], True) for i, _ in spec if r[i].strip())
|
||||
continue
|
||||
fc, prefix = full_code(raw, prefix)
|
||||
if not fc:
|
||||
anomalies.append(f"8-3 코드 해석 실패 {t['file']} {raw!r}")
|
||||
continue
|
||||
parts, appended = ([group] if group else []), False
|
||||
for i, lab in spec:
|
||||
if r[i].strip():
|
||||
inherit[i] = v = cell_join(r[i])
|
||||
else:
|
||||
v = inherit.get(i, "") if i in merged else ""
|
||||
if not v:
|
||||
continue
|
||||
u = unit_of(lab)
|
||||
base = re.sub(r"\(.*", "", lab) if "(" in lab else lab
|
||||
if len(spec) == 1:
|
||||
simple = u and lab.count("(") == 1
|
||||
appended = bool(simple and NUM.match(v.replace(",", "")))
|
||||
parts.append(v + u if appended else v)
|
||||
else:
|
||||
parts.append(f"{base} {v}{u if u and NUM.match(v.replace(',', '')) else ''}")
|
||||
unit_note = None
|
||||
if len(spec) == 1 and not appended and unit_of(spec[0][1]):
|
||||
unit_note = re.sub(r"^규격", "", spec[0][1])
|
||||
elif len(spec) > 1 and any(unit_of(lab) for _, lab in spec):
|
||||
unit_note = " · ".join(lab for _, lab in spec)
|
||||
vals, odd = {}, {}
|
||||
for i, lab in mid + sons:
|
||||
n = num(r[i])
|
||||
if isinstance(n, str) and re.fullmatch(
|
||||
r"\d[\d,]*", n
|
||||
): # 쉼표 자리가 어긋난 원문(3,0000)
|
||||
odd[f"{sec_no(t['h3'])} {lab}"] = n
|
||||
n = int(n.replace(",", ""))
|
||||
vals[lab] = n
|
||||
rows_out.setdefault(fc, {}).update(
|
||||
{
|
||||
"이름83": re.sub(r"\s*\('\d\d[^()]*\)$", "", t["h4"])
|
||||
.split(") ", 1)[-1]
|
||||
.strip(),
|
||||
"규격": " · ".join(parts),
|
||||
"규격단위": unit_note,
|
||||
"83": vals,
|
||||
"원문83": odd or None,
|
||||
"sec83": sec_no(t["h3"]),
|
||||
}
|
||||
)
|
||||
notes_out.setdefault(key_note, []).extend(t["notes"])
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- 8-4 (분류번호 줄 표)
|
||||
|
||||
|
||||
def parse_fuel(s):
|
||||
"""주연료 칸 → (값, 종류, 원문표시 필요)"""
|
||||
raw = cell_join(s)
|
||||
if raw in ("", "-"):
|
||||
return None, None, False
|
||||
m = re.fullmatch(r"(휘발유|중유|경유)\s*(\d+(?:\.\d+)?)", raw)
|
||||
if m:
|
||||
return num(m.group(2)), m.group(1), True
|
||||
if NUM.match(raw.replace(",", "")):
|
||||
return num(raw), "경유", False
|
||||
return raw, None, True
|
||||
|
||||
|
||||
def build_84(tabs, rows_out, notes_out, anomalies):
|
||||
for t in tabs:
|
||||
H = [cell_join(c).replace(" ", "") for c in t["rows"][0]]
|
||||
if H[0] != "분류번호":
|
||||
continue
|
||||
prefix, name = None, ""
|
||||
sec = sec_no(t["h3"])
|
||||
for r in t["rows"][1:]:
|
||||
fc, prefix = full_code(r[0], prefix)
|
||||
if not fc:
|
||||
anomalies.append(f"8-4 코드 해석 실패 {r[0]!r}")
|
||||
continue
|
||||
if r[1].strip():
|
||||
name = cell_join(r[1], True)
|
||||
fuel, kind, orig = parse_fuel(r[3])
|
||||
jam = r[4].strip().rstrip("%")
|
||||
op = num(r[5])
|
||||
rows_out.setdefault(fc, {}).update(
|
||||
{
|
||||
"이름84": name,
|
||||
"규격84": cell_join(r[2]),
|
||||
"84": {
|
||||
"주연료": fuel,
|
||||
"주연료종류": kind,
|
||||
"잡재료율": num(jam) if jam else None,
|
||||
"조종원": op,
|
||||
},
|
||||
"원문84": {
|
||||
k: v
|
||||
for k, v in (
|
||||
("주연료", cell_join(r[3]) if orig else None),
|
||||
("잡재료", cell_join(r[4]) if isinstance(num(jam), str) else None),
|
||||
)
|
||||
if v
|
||||
}
|
||||
or None,
|
||||
"sec84": sec,
|
||||
}
|
||||
)
|
||||
notes_out.setdefault(sec, []).extend(t["notes"])
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- 8-4-9 해상 (가로 표)
|
||||
|
||||
|
||||
def build_849(tabs, rows_out, notes_out, anomalies):
|
||||
for t in tabs:
|
||||
H = [cell_join(c).replace(" ", "") for c in t["rows"][0]]
|
||||
if H[0] != "명칭":
|
||||
continue
|
||||
m = re.match(r"\((\d{4})\)", t["h4"])
|
||||
grp = m.group(1)
|
||||
sec = sec_no(t["h3"])
|
||||
specs = [cell_join(c) for c in t["rows"][1][2:-1]]
|
||||
cols = sorted(k for k, v in rows_out.items() if k.startswith(grp + "-") and "83" in v)
|
||||
if len(cols) != len(specs):
|
||||
anomalies.append(f"8-4-9 {grp} 열 {len(specs)} ≠ 8-3 줄 {len(cols)}")
|
||||
continue
|
||||
# 규격 글의 수와 8-3 규격 수가 같은 순서인지 눈으로 볼 수 있게 남김
|
||||
for k, s in zip(cols, specs):
|
||||
a = re.findall(r"\d+(?:,\d{3})*(?:\.\d+)?", s)
|
||||
b = re.findall(r"\d+(?:,\d{3})*(?:\.\d+)?", rows_out[k]["규격"])
|
||||
if not (set(a) & set(b) or not a):
|
||||
anomalies.append(
|
||||
f"8-4-9 {grp} 열-줄 대응 의심 {k} 84={s!r} 83={rows_out[k]['규격']!r}"
|
||||
)
|
||||
for ci, k in enumerate(cols):
|
||||
v84 = {"주연료": None, "주연료종류": None, "잡재료율": None, "조종원": None}
|
||||
extra, orig = {}, {}
|
||||
for r in t["rows"][2:]:
|
||||
lab = cell_join(r[0]).replace(" ", "")
|
||||
cell = cell_join(r[2 + ci])
|
||||
if lab == "주연료":
|
||||
val = num(cell)
|
||||
v84["주연료"] = val
|
||||
v84["주연료종류"] = "경유" if isinstance(val, (int, float)) else None
|
||||
elif lab == "잡재료":
|
||||
val = num(cell)
|
||||
v84["잡재료율"] = val
|
||||
if isinstance(val, str):
|
||||
orig["잡재료"] = cell_join(cell)
|
||||
elif lab in ("준설선운전사", "건설기계운전사"):
|
||||
v84["조종원"] = num(cell)
|
||||
v84["조종원직종"] = "1054" if lab == "준설선운전사" else "1048"
|
||||
else:
|
||||
extra[lab] = num(cell)
|
||||
rows_out[k].update(
|
||||
{
|
||||
"이름84": rows_out[k]["이름83"],
|
||||
"84": v84,
|
||||
"extra84": extra,
|
||||
"원문84": orig or None,
|
||||
"sec84": sec,
|
||||
"직종고정": "조종원직종" in v84 and v84.get("조종원직종") is not None,
|
||||
}
|
||||
)
|
||||
notes_out.setdefault(f"{sec} ({grp})", []).extend(t["notes"])
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- 8-5
|
||||
|
||||
|
||||
def build_85(tabs, rows_out, anomalies):
|
||||
for t in tabs:
|
||||
H = [cell_join(c).replace(" ", "") for c in t["rows"][0]]
|
||||
if H[0] != "기종":
|
||||
continue
|
||||
prefix, name = None, ""
|
||||
for r in t["rows"][1:]:
|
||||
if r[0].strip():
|
||||
name = cell_join(r[0], True)
|
||||
fc, prefix = full_code(r[1], prefix)
|
||||
if not fc:
|
||||
anomalies.append(f"8-5 코드 해석 실패 {r[1]!r}")
|
||||
continue
|
||||
p = num(r[2])
|
||||
if not isinstance(p, int):
|
||||
anomalies.append(f"8-5 가격 이상 {fc} {r[2]!r}")
|
||||
rows_out.setdefault(fc, {}).update(
|
||||
{"이름85": name, "가격": p, "sec85": sec_no(t["h3"])}
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- 조종원 직종 (8-1-3 5 에 이름이 나온 기종만)
|
||||
|
||||
K1048 = [
|
||||
"불도저",
|
||||
"굴착기",
|
||||
"굴삭기",
|
||||
"로더",
|
||||
"지게차",
|
||||
"스크레이퍼",
|
||||
"모터그레이더",
|
||||
"롤러",
|
||||
"스테이빌라이저",
|
||||
"노상안정기",
|
||||
"배치플랜트",
|
||||
"피니셔",
|
||||
"스프레더",
|
||||
"아스팔트믹싱플랜트",
|
||||
"골재살포기",
|
||||
"슬러리실",
|
||||
"천공기",
|
||||
"사리채취기",
|
||||
"노면파쇄기",
|
||||
]
|
||||
K1049 = ["살수차", "화물트럭", "트랙터", "제설차", "노면청소차", "트럭탑재형크레인"]
|
||||
K1050 = ["양수기", "윈치", "발전기", "래머", "콤팩터", "벨트컨베이어", "콘크리트파쇄기"]
|
||||
|
||||
|
||||
JOB_NAME = {
|
||||
"1048": "건설기계운전사",
|
||||
"1049": "화물차운전사",
|
||||
"1050": "일반기계운전사",
|
||||
"1054": "준설선운전사",
|
||||
}
|
||||
|
||||
|
||||
def job_of(name):
|
||||
n = re.sub(r"\s", "", name)
|
||||
for k, code in ((K1048, "1048"), (K1049, "1049"), (K1050, "1050")):
|
||||
if any(w in n for w in k):
|
||||
return code
|
||||
return None
|
||||
|
||||
|
||||
def job_for_row(name, spec):
|
||||
n = re.sub(r"\s", "", name)
|
||||
m = re.match(r"\d+(?:\.\d+)?", spec.replace(",", ""))
|
||||
q = float(m.group(0)) if m else None
|
||||
if "덤프트럭" in n:
|
||||
return None if q is None else ("1048" if q >= 12 else "1049")
|
||||
if "공기압축기" in n and "이동식" in n:
|
||||
return "1048" if q is not None and q >= 2.83 else None
|
||||
return job_of(name)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- 실행
|
||||
|
||||
|
||||
def load():
|
||||
t83, t84, t85 = [], [], []
|
||||
for p in sorted(DIR.glob("8-03-0[1-9]*.md")) + sorted(DIR.glob("8-03-10*.md")):
|
||||
t83 += read_md(p)
|
||||
t84 = read_md(next(DIR.glob("8-04_*.md")))
|
||||
t85 = read_md(next(DIR.glob("8-05_*.md")))
|
||||
return t83, t84, t85
|
||||
|
||||
|
||||
UNIT = {
|
||||
"가격": "천원",
|
||||
"내용시간": "시간",
|
||||
"연간표준가동시간": "시간",
|
||||
"상각비율": "",
|
||||
"정비비율": "",
|
||||
"연간관리비율": "",
|
||||
"상각비계수": "10^-7/시간",
|
||||
"정비비계수": "10^-7/시간",
|
||||
"관리비계수": "10^-7/시간",
|
||||
"손료계수": "10^-7/시간",
|
||||
"주연료": "ℓ/hr",
|
||||
"주연료종류": "",
|
||||
"잡재료율": "주연료의 %",
|
||||
"조종원": "인/일",
|
||||
"조종원직종": "",
|
||||
}
|
||||
K83 = [
|
||||
"내용시간",
|
||||
"연간표준가동시간",
|
||||
"상각비율",
|
||||
"정비비율",
|
||||
"연간관리비율",
|
||||
"상각비계수",
|
||||
"정비비계수",
|
||||
"관리비계수",
|
||||
"손료계수",
|
||||
]
|
||||
FUEL_NOTE = SRC + "8-4 주①㉰"
|
||||
|
||||
|
||||
def note_lines(lines):
|
||||
out = []
|
||||
for ln in lines:
|
||||
ln = re.sub(r"^\[주\]\s*", "", ln)
|
||||
if ln:
|
||||
out.append(ln)
|
||||
return out
|
||||
|
||||
|
||||
def compose(rows):
|
||||
out = []
|
||||
for k in sorted(rows):
|
||||
v = rows[k]
|
||||
r83, r84 = v.get("83"), v.get("84")
|
||||
name = v.get("이름83") or v.get("이름84") or v.get("이름85")
|
||||
spec = v.get("규격") or v.get("규격84") or ""
|
||||
# 값이 null 인 칸의 출처 = 그 칸을 읽는 절(틀 검사가 출처 문자열을 요구) · 표에 줄이 있으면 그 표의 절
|
||||
s83, s84 = SRC + v.get("sec83", "8-3"), SRC + v.get("sec84", "8-4")
|
||||
val = {"가격": v.get("가격")}
|
||||
src = {"가격": SRC + v.get("sec85", "8-5")}
|
||||
for f in K83:
|
||||
val[f] = (r83 or {}).get(f)
|
||||
src[f] = s83
|
||||
for f in ("주연료", "주연료종류", "잡재료율", "조종원"):
|
||||
val[f] = (r84 or {}).get(f)
|
||||
src[f] = FUEL_NOTE if f == "주연료종류" and val[f] == "경유" else s84
|
||||
fixed = (r84 or {}).get("조종원직종")
|
||||
job = fixed or (job_for_row(name, spec) if val["조종원"] is not None else None)
|
||||
val["조종원직종"] = job
|
||||
src["조종원직종"] = SRC + "8-1-3 5" + (" · 건설노임 " + job if job else "")
|
||||
for lab, x in (v.get("extra84") or {}).items():
|
||||
val[lab] = x
|
||||
src[lab] = s84
|
||||
unit = dict(UNIT)
|
||||
for lab in v.get("extra84") or {}:
|
||||
unit[lab] = "인"
|
||||
row = {"열쇠": k, "이름": name, "규격": spec, "단위": unit, "값": val, "출처": src}
|
||||
memo = ["조종원직종 원문 이름: " + JOB_NAME[job]] if job else []
|
||||
if v.get("규격단위"):
|
||||
memo.append("규격 단위: " + v["규격단위"])
|
||||
if memo:
|
||||
row["비고"] = " · ".join(memo)
|
||||
org = dict(v.get("원문83") or {})
|
||||
org.update({f"{v['sec84']} {a}": b for a, b in (v.get("원문84") or {}).items()})
|
||||
if org:
|
||||
row["원문"] = org
|
||||
out.append(row)
|
||||
return out
|
||||
|
||||
|
||||
def dumps_row(r):
|
||||
j = lambda o: json.dumps(o, ensure_ascii=False)
|
||||
head = f'{{ "열쇠": {j(r["열쇠"])}, "이름": {j(r["이름"])}, "규격": {j(r["규격"])},'
|
||||
tail = [k for k in ("비고", "원문") if k in r]
|
||||
body = [f' "단위": {j(r["단위"])},', f' "값": {j(r["값"])},']
|
||||
body.append(f' "출처": {j(r["출처"])}' + ("," if tail else " }"))
|
||||
for n, k in enumerate(tail):
|
||||
body.append(f' "{k}": {j(r[k])}' + ("," if n < len(tail) - 1 else " }"))
|
||||
return " " + head + "\n" + "\n".join(body)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- 관계표 · 글 속 계산용 수
|
||||
|
||||
|
||||
def relation_table(t, key):
|
||||
R = t["rows"]
|
||||
grp = [cell_join(c) for c in R[0]]
|
||||
spec = [cell_join(c) for c in R[1]]
|
||||
hose = [cell_join(c) for c in R[2]]
|
||||
names, cur = [], ""
|
||||
for j in range(2, len(R[0])):
|
||||
if grp[j]:
|
||||
cur = grp[j]
|
||||
names.append(f"{cur} {spec[j]}".strip())
|
||||
lines = []
|
||||
for r in R[3:]:
|
||||
size = num(r[0])
|
||||
for j, nm in enumerate(names, start=2):
|
||||
c = cell_join(r[j]) if j < len(r) else ""
|
||||
if c in ("", "-"):
|
||||
continue
|
||||
m = re.fullmatch(r"(\d+)\((\d+)\)", c)
|
||||
row = {"공기압축기 규격": size, "부수물": nm}
|
||||
if hose[j].strip():
|
||||
row["사용에어호스경"] = num(hose[j])
|
||||
row["사용가능대수"] = int(m.group(1)) if m else num(c)
|
||||
if m:
|
||||
row["괄호값"] = int(m.group(2))
|
||||
lines.append(row)
|
||||
return {
|
||||
"열쇠": f"8-3-6 ({key[-5:-1]}) 공기압축기·부수물 관계",
|
||||
"이름": "공기압축기 규격별 부수물 사용가능 대수",
|
||||
"그룹": "계수",
|
||||
"기준": "",
|
||||
"출처": SRC + "8-3-6 (5210)",
|
||||
"조건": {"공기압축기 규격": "수", "부수물": "고르기", "사용에어호스경": "수"},
|
||||
"값칸": {"사용가능대수": "대", "괄호값": "대(수중 4m 이하)"},
|
||||
"줄": lines,
|
||||
"주": t["notes"],
|
||||
}
|
||||
|
||||
|
||||
def text_tables(notes):
|
||||
def tb(key, name, src, cond, vc, lines, note):
|
||||
return {
|
||||
"열쇠": key,
|
||||
"이름": name,
|
||||
"그룹": "계수",
|
||||
"기준": "",
|
||||
"출처": SRC + src,
|
||||
"조건": cond,
|
||||
"값칸": vc,
|
||||
"줄": lines,
|
||||
"주": note,
|
||||
}
|
||||
|
||||
n83 = notes["8-3-3 (2208)"]
|
||||
n84 = notes["8-4-8"]
|
||||
g = lambda L, s: next(x for x in L if x.startswith(s))
|
||||
return [
|
||||
tb(
|
||||
"8-3-3 (2208) 주③ 권상용 와이어",
|
||||
"타워크레인 권상용 와이어 소모",
|
||||
"8-3-3 (2208) 주③",
|
||||
{"구분": "고르기"},
|
||||
{"값": "", "단위": ""},
|
||||
[
|
||||
{"구분": "와이어 규격", "값": "18㎜×120m", "단위": "1set"},
|
||||
{"구분": "시간당 소모율", "값": 0.003, "단위": "1set 기준"},
|
||||
],
|
||||
[g(n83, "③")],
|
||||
),
|
||||
tb(
|
||||
"8-3-3 (2210) 주③ 동력",
|
||||
"건설용리프트 동력",
|
||||
"8-3-3 (2210) 주③",
|
||||
{"구분": "고르기"},
|
||||
{"값": "㎾", "대수": "대"},
|
||||
[{"구분": "동력", "값": 7.5, "대수": 2}],
|
||||
[g(notes["8-3-3 (2210)"], "③")],
|
||||
),
|
||||
tb(
|
||||
"8-4 주①㉮ 연료 소비량 산정 기준",
|
||||
"시간당 주연료 소비량 산정 기준",
|
||||
"8-4 주①㉮",
|
||||
{"구분": "고르기"},
|
||||
{"최소": "%", "최대": "%", "적용식": "식"},
|
||||
[
|
||||
{"구분": "엔진부하율", "최소": 70, "최대": 80},
|
||||
{"구분": "실작업시간", "적용식": "50/60", "원문": "실작업시간은 50/60"},
|
||||
],
|
||||
[g(n84, "㉮")],
|
||||
),
|
||||
tb(
|
||||
"8-4 주⑤ 잡재료 비율",
|
||||
"불도저·굴착기 부착기계 조합 시 잡재료 비율",
|
||||
"8-4 주⑤",
|
||||
{"구분": "고르기"},
|
||||
{"값": "주연료의 %"},
|
||||
[{"구분": "불도저 및 굴착기에 리퍼·브레이커·부착용집게 조합", "값": 16}],
|
||||
[g(n84, "⑤")],
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def main():
|
||||
t83, t84, t85 = load()
|
||||
rows, special, notes, anom = {}, [], {}, []
|
||||
build_83(t83, rows, special, notes, anom)
|
||||
build_84(t84, rows, notes, anom)
|
||||
build_849(t84, rows, notes, anom)
|
||||
build_85(t85, rows, anom)
|
||||
body = compose(rows)
|
||||
tables = [relation_table(t, key) for _, t, key in special] + text_tables(notes)
|
||||
jn = {k: note_lines(v) for k, v in notes.items() if note_lines(v)}
|
||||
j = lambda o, ind=None: json.dumps(o, ensure_ascii=False, indent=ind)
|
||||
parts = [
|
||||
'{\n "그룹": "기계",\n "원문": "건설품셈",\n "판": "2026",\n',
|
||||
' "주": ' + json.dumps(jn, ensure_ascii=False, indent=2).replace("\n", "\n ") + ",\n",
|
||||
' "줄": [\n' + ",\n".join(dumps_row(r) for r in body) + "\n ],\n",
|
||||
' "표": '
|
||||
+ json.dumps(tables, ensure_ascii=False, indent=2).replace("\n", "\n ")
|
||||
+ "\n}\n",
|
||||
]
|
||||
text = "".join(parts)
|
||||
json.loads(text)
|
||||
return text, rows, body, anom, tables, jn
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
text, rows, body, anom, tables, jn = main()
|
||||
for a in anom:
|
||||
print("이상:", a)
|
||||
print("기계", len(body), "표", len(tables), "주 묶음", len(jn), "줄수", text.count("\n"))
|
||||
if "--dry" not in sys.argv:
|
||||
with open(OUT, "w", encoding="utf8", newline="\n") as f:
|
||||
f.write(text)
|
||||
print("씀", OUT)
|
||||
@@ -0,0 +1,368 @@
|
||||
{
|
||||
"그룹": "계수",
|
||||
"원문": "산림품셈",
|
||||
"판": "2026-01-01",
|
||||
"표": [
|
||||
{
|
||||
"열쇠": "13-2-1 주 계산용 수",
|
||||
"이름": "채집 인력 주 속 수",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-2-1 주②④",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "선별기 보조원 보통인부(기계채집)", "적용": [2, 3], "단위": "인/대당", "적용원문": "2∼3인/대당" },
|
||||
{ "구분": "석재 세척 유해물질 초과 시 보통인부 할증", "적용": 0.2, "단위": "인" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-2-2 소할 할증",
|
||||
"이름": "막돌 채집 소할 할증",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-2-2",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "전석 소할 시 할석공 할증", "적용": 0.2, "단위": "인/㎥", "적용원문": "㎥당 할석공 0.2인을 할증한다" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-2-3 주 계산용 수",
|
||||
"이름": "큰돌 채집 주 속 계산용 수",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-2-3 주②③④⑦⑧⑨⑩",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "큰돌 직경 범위", "적용": [40, 100], "단위": "㎝", "적용원문": "직경 40㎝이상~100㎝이하" },
|
||||
{ "구분": "큰돌 뒷길이 범위", "적용": [60, 120], "단위": "㎝", "적용원문": "뒷길이 60~120㎝" },
|
||||
{ "구분": "돌 구입 운반 공극률", "적용": 23, "단위": "%" },
|
||||
{ "구분": "직경 60㎝ 이상 큰돌 최소화 기준", "적용": 60, "단위": "㎝" },
|
||||
{ "구분": "소운반 포함 거리", "적용": 20, "단위": "m" },
|
||||
{ "구분": "티스 소모율", "적용": 0.002 },
|
||||
{ "구분": "티스갯수", "적용": 6, "단위": "개" },
|
||||
{ "구분": "40㎝이상~60㎝미만 적용", "적용": 75, "단위": "%", "적용원문": "본품의 75%" },
|
||||
{ "구분": "60㎝이상~80㎝미만 적용", "적용": 100, "단위": "%", "적용원문": "본품의 100%" },
|
||||
{ "구분": "80㎝이상~100㎝이하 적용", "적용": 125, "단위": "%", "적용원문": "본품의 125%" },
|
||||
{ "구분": "공사 시 발생하는 큰 돌 적용", "적용": 50, "단위": "%", "적용원문": "본 품의 50%" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-2-4 주① 소할 할증",
|
||||
"이름": "야면석 채집 소할 할증",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-2-4 주①",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "전석 소할 시 할석공 할증", "적용": 0.2, "단위": "인/㎥", "적용원문": "㎥당 할석공 0.2인을 할증한다" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-4-2 주③ 적용 조건",
|
||||
"이름": "메쌓기(장비) 적용 조건",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-4-2 주③",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "경사도", "적용": "1:1", "적용원문": "1:1보다 급한 경우" },
|
||||
{ "구분": "높이(이하)", "적용": 3, "단위": "m" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-4-5 주③ 적용 조건",
|
||||
"이름": "찰쌓기(장비) 적용 조건",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-4-5 주③",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "경사도", "적용": "1:1", "적용원문": "1:1보다 급한 경우" },
|
||||
{ "구분": "높이(이하)", "적용": 3, "단위": "m" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-4-6 주③ 적용 조건",
|
||||
"이름": "밑돌 및 천단 돌쌓기 적용 조건",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-4-6 주③",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "높이(이하)", "적용": 3, "단위": "m" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-4-4 주 계산용 수",
|
||||
"이름": "찰쌓기 주 속 계산용 수",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-4-4 주④⑤⑥⑦⑨",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "줄눈메꿈 모르타르", "적용": 0.009, "단위": "㎥" },
|
||||
{ "구분": "물구멍 설치 면적당 1개소 이상", "적용": [2, 3], "단위": "㎡", "적용원문": "2~3㎡당 1개소 이상" },
|
||||
{ "구분": "물구멍 파이프 지름", "적용": [3, 6], "단위": "㎝", "적용원문": "3~6㎝" },
|
||||
{ "구분": "돌쌓기·돌붙이기 구분 경사도", "적용": "1:1" },
|
||||
{ "구분": "절토 뒤채움 조약돌 두께(상·하부 같이)", "적용": [30, 40], "단위": "㎝", "적용원문": "30∼40㎝" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-5-1 주 계산용 수",
|
||||
"이름": "돌붙임(인력) 주 속 수",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-5-1 주③④",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "줄눈메꿈 모르타르", "적용": 0.009, "단위": "㎥/㎡" },
|
||||
{ "구분": "돌붙임 틈메우기돌(고임돌량의 최대)", "적용": 15, "단위": "%" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-5-2 주③ 적용 조건",
|
||||
"이름": "돌붙임(장비) 적용 조건",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-5-2 주③",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "경사도", "적용": "1:1", "적용원문": "1:1보다 완만한 경우" },
|
||||
{ "구분": "높이(이하)", "적용": 5, "단위": "m" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-6-1 주 계산용 수",
|
||||
"이름": "큰돌 메쌓기 주 속 수",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-6-1 주⑤⑨",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "사용 돌 직경(이하, 임도)", "적용": 60, "단위": "㎝" },
|
||||
{ "구분": "소운반 포함 거리", "적용": 20, "단위": "m" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-6-2 주 계산용 수",
|
||||
"이름": "큰돌 찰쌓기 주 속 수",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-6-2 주⑤⑩⑫",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "사용 돌 직경(이하, 임도)", "적용": 60, "단위": "㎝" },
|
||||
{ "구분": "뒤채움콘크리트량 기준", "적용": 0.2, "단위": "㎥" },
|
||||
{ "구분": "뒤채움콘크리트량 현지여건 상한", "적용": 0.3, "단위": "㎥" },
|
||||
{ "구분": "소운반 포함 거리", "적용": 20, "단위": "m" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-6-3 주 계산용 수",
|
||||
"이름": "친환경 큰돌쌓기 주 속 수",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-6-3 주⑤⑩",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "뒤채움콘크리트량 기준", "적용": 0.2, "단위": "㎥" },
|
||||
{ "구분": "뒤채움콘크리트량 현지여건 상한", "적용": 0.3, "단위": "㎥" },
|
||||
{ "구분": "소운반 포함 거리", "적용": 20, "단위": "m" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-7-1 주⑤ 소운반",
|
||||
"이름": "큰돌 메붙이기 소운반",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-7-1 주⑤",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "소운반 포함 거리", "적용": 20, "단위": "m" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-7-2 주⑤ 소운반",
|
||||
"이름": "큰돌 찰붙이기 소운반",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-7-2 주⑤",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "소운반 포함 거리", "적용": 20, "단위": "m" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-8 막돌쌓기 주 계산용 수",
|
||||
"이름": "막돌쌓기 계산용 수",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-8 머리 글 · 주④⑤",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "막돌 직경길이(이상)", "적용": 20, "단위": "㎝" },
|
||||
{ "구분": "막돌 뒷길이", "적용": [25, 40], "단위": "㎝", "적용원문": "25~40㎝" },
|
||||
{ "구분": "높이(미만 불가 기준)", "적용": 2.0, "단위": "m", "적용원문": "2.0m 이상으로 할 수 없음" },
|
||||
{ "구분": "막돌 붙임 적용", "적용": 70, "단위": "%", "적용원문": "본 품의 70%" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-10-2 말뚝박기 계산용 수",
|
||||
"이름": "말뚝박기공 할증 · 감 계수",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-10-2 머리 글 · 1 주①②③④ · 2 주①②③⑤ · 3 주①②④⑤⑧",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "산지 비탈면 시공 할증", "적용": 30, "단위": "%" },
|
||||
{ "구분": "작은 말뚝 연토 지질 감", "적용": 20, "단위": "%" },
|
||||
{ "구분": "작은 말뚝 자갈층 할증", "적용": 30, "단위": "%" },
|
||||
{ "구분": "작은 말뚝 말뚝머리 자르기 보통인부 할증", "적용": 0.02, "단위": "인/본", "적용원문": "본당 보통인부 0.02인" },
|
||||
{ "구분": "작은 말뚝 9할박기 할증", "적용": 30, "단위": "%" },
|
||||
{ "구분": "작은 말뚝 말뚝빼기", "적용": 70, "단위": "%" },
|
||||
{ "구분": "기초말뚝 사항박기 가산", "적용": 15, "단위": "%" },
|
||||
{ "구분": "기초말뚝 말뚝빼기", "적용": 70, "단위": "%" },
|
||||
{ "구분": "기초말뚝 연토사질 감", "적용": 20, "단위": "%" },
|
||||
{ "구분": "기초말뚝 자갈질 가산", "적용": 30, "단위": "%" },
|
||||
{ "구분": "기초말뚝 철근 콘크리트 말뚝박기 감", "적용": 30, "단위": "%" },
|
||||
{ "구분": "윈치 보통 토사질 관입길이(박기)", "적용": [6, 8], "단위": "할", "적용원문": "6~8할" },
|
||||
{ "구분": "윈치 3~5할 박기 개수 가산", "적용": 20, "단위": "%" },
|
||||
{ "구분": "윈치 지질 가감(이내)", "적용": 30, "단위": "%" },
|
||||
{ "구분": "윈치 콘크리트 말뚝 시공개수 가산", "적용": 20, "단위": "%" },
|
||||
{ "구분": "윈치 원동기 전력 사용 시", "적용": 0.75, "단위": "KWH/HP/hr" },
|
||||
{ "구분": "윈치 계항 선타항 길이 품 가산", "적용": 50, "단위": "%" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-11-1 주 계산용 수",
|
||||
"이름": "원형 돌망태 주 속 수",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-11-1 주④⑤",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "필터매트(부직포) 설치 시 특별인부", "적용": 0.09, "단위": "인/㎡" },
|
||||
{ "구분": "필터매트(부직포) 설치 시 보통인부", "적용": 0.15, "단위": "인/㎡" },
|
||||
{ "구분": "돌망태 간격가수(1연당)", "적용": 0.05, "단위": "m" },
|
||||
{ "구분": "조약돌 크기(망태지름 대비, 미만)", "적용": "1/2" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-11-2 주 계산용 수",
|
||||
"이름": "타원형 돌망태 주 속 수",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-11-2 주④⑤",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "필터매트(부직포) 설치 시 특별인부", "적용": 0.09, "단위": "인/㎡" },
|
||||
{ "구분": "필터매트(부직포) 설치 시 보통인부", "적용": 0.15, "단위": "인/㎡" },
|
||||
{ "구분": "돌망태 간격가수(1연당)", "적용": 0.05, "단위": "m" },
|
||||
{ "구분": "조약돌 크기(망태지름 대비, 미만)", "적용": "1/2" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-11-3 주 계산용 수",
|
||||
"이름": "매트리스형 돌망태 주 속 수",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-11-3 주③④⑤",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "필터매트(부직포) 설치 시 특별인부", "적용": 0.09, "단위": "인/㎡" },
|
||||
{ "구분": "필터매트(부직포) 설치 시 보통인부", "적용": 0.15, "단위": "인/㎡" },
|
||||
{ "구분": "매트리스형 폭", "적용": 100, "단위": "㎝" },
|
||||
{ "구분": "매트리스형 높이", "적용": 30, "단위": "㎝" },
|
||||
{ "구분": "굴착기(0.7㎥)", "적용": 0.012, "단위": "hr/㎥" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-12-2 지오셀 기준",
|
||||
"이름": "지오셀 표준 사면",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-12-2 주③",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "표준 사면높이", "적용": 4, "단위": "m" },
|
||||
{ "구분": "표준 기울기", "적용": "1:2" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-13-1 구조 구분",
|
||||
"이름": "목재 구조 구분 기준",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-13-1 주③",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "보통구조 통나무 등 비율(이상)", "적용": 80, "단위": "%" },
|
||||
{ "구분": "중등구조 통나무 등 비율(이상)", "적용": 50, "단위": "%" },
|
||||
{ "구분": "상등구조 소각재 등 비율(이상)", "적용": 50, "단위": "%" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-14 식생토낭 주 계산용 수",
|
||||
"이름": "식생토낭 및 포트",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-14 주①④",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "토낭백 규격(가×세×높이)", "적용": "80×40×20", "단위": "㎝" },
|
||||
{ "구분": "토낭백 규격(가능)", "적용": "60×40×20", "단위": "㎝" },
|
||||
{ "구분": "식생포트 1개당 본수", "적용": 3, "단위": "본" },
|
||||
{ "구분": "식생포트 보통인부", "적용": 0.033, "단위": "인/본" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-15-2 횡목 직경",
|
||||
"이름": "목책 설치 횡목 직경",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-15-2 주③",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "횡목 직경 제한", "적용": [20, 30], "단위": "㎝", "적용원문": "20 ∼ 30cm" }
|
||||
],
|
||||
"주": []
|
||||
},
|
||||
{
|
||||
"열쇠": "13-16-1 매트 주 계산용 수",
|
||||
"이름": "필터매트 주 속 계산용 수",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 13-16-1 주⑤⑦",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글", "단위": "글" },
|
||||
"줄": [
|
||||
{ "구분": "수중 부설 수심(이하 기준)", "적용": 10, "단위": "m" },
|
||||
{ "구분": "공구손료 및 경장비(봉합기) 기계경비(인력품의)", "적용": 4, "단위": "%" }
|
||||
],
|
||||
"주": []
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
+3593
-358
File diff suppressed because it is too large
Load Diff
@@ -46,7 +46,7 @@
|
||||
"값칸": { "적용": "구분 따름", "적용원문": "글", "비고": "글" },
|
||||
"줄": [
|
||||
{ "구분": "K", "적용": 0.9 },
|
||||
{ "구분": "f", "적용원문": "1/1.30" },
|
||||
{ "구분": "f", "적용": "1/1.30", "적용원문": "1/1.30" },
|
||||
{ "구분": "E", "적용": [0.45, 0.55], "적용원문": "0.55∼0.45" },
|
||||
{ "구분": "㎝(sec)", "적용": 20, "적용원문": "20(135°)" }
|
||||
],
|
||||
@@ -90,7 +90,7 @@
|
||||
"값칸": { "적용": "구분 따름", "적용원문": "글", "비고": "글" },
|
||||
"줄": [
|
||||
{ "구분": "K", "적용": 0.55 },
|
||||
{ "구분": "f", "적용원문": "1/1.40" },
|
||||
{ "구분": "f", "적용": "1/1.40", "적용원문": "1/1.40" },
|
||||
{ "구분": "E", "적용": 0.35 },
|
||||
{ "구분": "㎝(sec)", "적용": 20, "적용원문": "20(135°)" }
|
||||
],
|
||||
@@ -143,7 +143,7 @@
|
||||
"값칸": { "적용": "구분 따름", "적용원문": "글", "비고": "글" },
|
||||
"줄": [
|
||||
{ "구분": "K", "적용": 0.55 },
|
||||
{ "구분": "f", "적용원문": "1/1.625" },
|
||||
{ "구분": "f", "적용": "1/1.625", "적용원문": "1/1.625" },
|
||||
{ "구분": "E", "적용": 0.35 },
|
||||
{ "구분": "㎝(sec)", "적용": 20, "적용원문": "20(135°)" }
|
||||
],
|
||||
@@ -386,11 +386,12 @@
|
||||
{ "구분": "거리(L)", "단위": "km", "적용": 0.1 },
|
||||
{ "구분": "운반속도(V)", "단위": "km/hr", "적용": 2.5 },
|
||||
{ "구분": "적재적하시간(t)", "단위": "min", "적용": 4.0 },
|
||||
{ "구분": "일일실작업시간(T)", "단위": "분", "적용원문": "480분-30분" },
|
||||
{ "구분": "일일실작업시간(T)", "단위": "분", "적용": "480분-30분", "적용원문": "480분-30분" },
|
||||
{ "구분": "1회 운반량(q)", "단위": "ℓ", "적용": 25 }
|
||||
],
|
||||
"주": [
|
||||
"표 안 비고(여섯 줄 병합): N=(V×T)/(120×L+V.t)= 회/일 Q = N×q = ℓ/일"
|
||||
"표 안 비고(여섯 줄 병합): N=(V×T)/(120×L+V.t)= 회/일 Q = N×q = ℓ/일",
|
||||
"표 안 빈 줄: 1일 운반횟수(N) · 회 · 적용 칸 비어 있음"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -473,21 +474,6 @@
|
||||
"집수정, 맨홀 등 배수구조물의 터파기에 적용한다."
|
||||
]
|
||||
},
|
||||
{
|
||||
"열쇠": "9-13 관보호공 보통인력 가산",
|
||||
"이름": "구조물터파기 관보호공·관부설 보통인력 의무 가산",
|
||||
"그룹": "계수",
|
||||
"기준": "",
|
||||
"출처": "산림품셈 9-13",
|
||||
"조건": { "구분": "고르기" },
|
||||
"값칸": { "가산율": "%" },
|
||||
"줄": [
|
||||
{ "구분": "관보호공 설치 · 관부설 공사", "가산율": 30 }
|
||||
],
|
||||
"주": [
|
||||
"※ 관보호공의 설치, 관부설 공사의 경우 돌 구름, 토사붕괴를 관리하기 위하여 보통인력 30%를 의무화하여 가산한다."
|
||||
]
|
||||
},
|
||||
{
|
||||
"열쇠": "9-13-2 육상토사(1~2m)",
|
||||
"이름": "구조물터파기 육상토사(1~2m)",
|
||||
@@ -801,7 +787,7 @@
|
||||
"값칸": { "적용": "구분 따름", "적용원문": "글", "비고": "글" },
|
||||
"줄": [
|
||||
{ "구분": "K(버킷계수)", "적용": 0.9 },
|
||||
{ "구분": "f(토량환산계수)", "적용원문": "1/1.30" },
|
||||
{ "구분": "f(토량환산계수)", "적용": "1/1.30", "적용원문": "1/1.30" },
|
||||
{ "구분": "E(작업효율)", "적용": 0.7 },
|
||||
{ "구분": "㎝(1회 사이클시간)", "적용": 20, "적용원문": "20(135°) sec" }
|
||||
],
|
||||
@@ -826,10 +812,10 @@
|
||||
{ "구분": "T(표토두께)", "단위": "m", "적용": 0.2 },
|
||||
{ "구분": "L(운반거리)", "단위": "m", "적용": 20 },
|
||||
{ "구분": "E(작업효율)", "적용": 0.4 },
|
||||
{ "구분": "q(삽날의 용량)", "적용원문": "q0×e(㎥)" },
|
||||
{ "구분": "q(삽날의 용량)", "적용": "q0×e(㎥)", "적용원문": "q0×e(㎥)" },
|
||||
{ "구분": "q0(거리를 고려하지 않은 삽날의 용량)", "단위": "㎥", "적용": 3.2 },
|
||||
{ "구분": "e(운반거리계수)", "적용": 0.96 },
|
||||
{ "구분": "f(토량환산계수)", "적용원문": "1/1.3" },
|
||||
{ "구분": "f(토량환산계수)", "적용": "1/1.3", "적용원문": "1/1.3" },
|
||||
{ "구분": "V1(전진속도)", "단위": "m/분", "적용": 40, "적용원문": "40m/분(1단)" },
|
||||
{ "구분": "V2(후진속도)", "단위": "m/분", "적용": 46, "적용원문": "46m/분(1단)" },
|
||||
{ "구분": "t(기어변속시간)", "단위": "분", "적용": 0.25 }
|
||||
@@ -852,10 +838,10 @@
|
||||
"값칸": { "적용": "줄 따름", "적용원문": "글" },
|
||||
"줄": [
|
||||
{ "구분": "L", "단위": "m", "적용": 20 },
|
||||
{ "구분": "E", "적용원문": "(0.55-0.1)" },
|
||||
{ "구분": "E", "적용": "(0.55-0.1)", "적용원문": "(0.55-0.1)" },
|
||||
{ "구분": "q0", "단위": "m", "적용": 3.2 },
|
||||
{ "구분": "e", "적용": 0.96 },
|
||||
{ "구분": "f", "적용원문": "1/1.3" },
|
||||
{ "구분": "f", "적용": "1/1.3", "적용원문": "1/1.3" },
|
||||
{ "구분": "V1", "단위": "m/분", "적용": 75, "적용원문": "75m/분(3단)" },
|
||||
{ "구분": "V2", "단위": "m/분", "적용": 98, "적용원문": "98m/분(3단)" },
|
||||
{ "구분": "t", "단위": "분", "적용": 0.25 }
|
||||
@@ -877,7 +863,7 @@
|
||||
"값칸": { "적용": "구분 따름", "적용원문": "글", "비고": "글" },
|
||||
"줄": [
|
||||
{ "적용장비": "굴착기(무한궤도, 0.7㎥)", "구분": "K", "적용": 0.9 },
|
||||
{ "적용장비": "굴착기(무한궤도, 0.7㎥)", "구분": "f", "적용원문": "1/1.3" },
|
||||
{ "적용장비": "굴착기(무한궤도, 0.7㎥)", "구분": "f", "적용": "1/1.3", "적용원문": "1/1.3" },
|
||||
{ "적용장비": "굴착기(무한궤도, 0.7㎥)", "구분": "E", "적용": 0.7 },
|
||||
{ "적용장비": "굴착기(무한궤도, 0.7㎥)", "구분": "㎝(sec)", "적용": 22, "적용원문": "22(180°)" }
|
||||
],
|
||||
@@ -1036,7 +1022,7 @@
|
||||
"값칸": { "적용": "구분 따름", "적용원문": "글", "비고": "글" },
|
||||
"줄": [
|
||||
{ "구분": "K(버킷계수)", "적용": 0.9 },
|
||||
{ "구분": "f(토량환산계수)", "적용원문": "1/1.25" },
|
||||
{ "구분": "f(토량환산계수)", "적용": "1/1.25", "적용원문": "1/1.25" },
|
||||
{ "구분": "E(작업효율)", "적용": 0.75 },
|
||||
{ "구분": "Cm(1회 사이클시간)", "적용": 18, "적용원문": "18(90°)sec" }
|
||||
],
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user