railwise-ai 1.2.32 → 1.2.34
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.
- package/agent-pack/README.md +16 -0
- package/agent-pack/assets/agent/chief_manager.md +69 -0
- package/agent-pack/assets/agent/commercial_specialist.md +47 -0
- package/agent-pack/assets/agent/data_analyst.md +54 -0
- package/agent-pack/assets/agent/docs.md +38 -0
- package/agent-pack/assets/agent/duplicate-pr.md +25 -0
- package/agent-pack/assets/agent/qa_inspector.md +58 -0
- package/agent-pack/assets/agent/qa_reviewer.md +57 -0
- package/agent-pack/assets/agent/solution_architect.md +53 -0
- package/agent-pack/assets/agent/technical_writer.md +61 -0
- package/agent-pack/assets/agent/translator.md +34 -0
- package/agent-pack/assets/agent/triage.md +139 -0
- package/agent-pack/assets/command/ai-deps.md +24 -0
- package/agent-pack/assets/command/bid-intel.md +29 -0
- package/agent-pack/assets/command/bid-prepare.md +24 -0
- package/agent-pack/assets/command/commit.md +37 -0
- package/agent-pack/assets/command/daily-report.md +26 -0
- package/agent-pack/assets/command/data-check.md +22 -0
- package/agent-pack/assets/command/emergency-response.md +66 -0
- package/agent-pack/assets/command/issues.md +23 -0
- package/agent-pack/assets/command/learn.md +42 -0
- package/agent-pack/assets/command/monthly-report.md +35 -0
- package/agent-pack/assets/command/payment-reminder.md +27 -0
- package/agent-pack/assets/command/plan-draft.md +28 -0
- package/agent-pack/assets/command/review-response.md +23 -0
- package/agent-pack/assets/command/rmslop.md +15 -0
- package/agent-pack/assets/command/safety-check.md +20 -0
- package/agent-pack/assets/command/spellcheck.md +5 -0
- package/agent-pack/assets/command/trend-analysis.md +38 -0
- package/agent-pack/assets/command/weekly-report.md +28 -0
- package/agent-pack/assets/lib/os_api.ts +100 -0
- package/agent-pack/assets/skill/adjustment-report/SKILL.md +88 -0
- package/agent-pack/assets/skill/approval-flow-intelligence/SKILL.md +123 -0
- package/agent-pack/assets/skill/bidding-knowledge/SKILL.md +98 -0
- package/agent-pack/assets/skill/bun-file-io/SKILL.md +42 -0
- package/agent-pack/assets/skill/business-finance/SKILL.md +91 -0
- package/agent-pack/assets/skill/business-operations-analytics/SKILL.md +120 -0
- package/agent-pack/assets/skill/cad-bim-review/SKILL.md +84 -0
- package/agent-pack/assets/skill/canvas-design/SKILL.md +141 -0
- package/agent-pack/assets/skill/construction-monitoring/SKILL.md +89 -0
- package/agent-pack/assets/skill/customer-portal-brief/SKILL.md +121 -0
- package/agent-pack/assets/skill/data-analysis/SKILL.md +79 -0
- package/agent-pack/assets/skill/di-bao-monitoring/SKILL.md +680 -0
- package/agent-pack/assets/skill/di-bao-monitoring/agents/openai.yaml +4 -0
- package/agent-pack/assets/skill/di-bao-monitoring/assets/crossing-static-level-input-template.csv +2 -0
- package/agent-pack/assets/skill/di-bao-monitoring/assets/crossing-total-station-input-template.csv +2 -0
- package/agent-pack/assets/skill/di-bao-monitoring/assets/crossing-total-station-report-template.md +59 -0
- package/agent-pack/assets/skill/di-bao-monitoring/assets/daily-report-template.md +90 -0
- package/agent-pack/assets/skill/di-bao-monitoring/assets/data-input-template.csv +2 -0
- package/agent-pack/assets/skill/di-bao-monitoring/assets/initial-value-report-template.md +92 -0
- package/agent-pack/assets/skill/di-bao-monitoring/assets/monthly-report-template.md +103 -0
- package/agent-pack/assets/skill/di-bao-monitoring/assets/plan-template.md +673 -0
- package/agent-pack/assets/skill/di-bao-monitoring/assets/point-alias-map-template.json +25 -0
- package/agent-pack/assets/skill/di-bao-monitoring/assets/project-brief-template.md +59 -0
- package/agent-pack/assets/skill/di-bao-monitoring/assets/project-summary-template.md +154 -0
- package/agent-pack/assets/skill/di-bao-monitoring/assets/warning-notice-template.md +58 -0
- package/agent-pack/assets/skill/di-bao-monitoring/assets/weekly-report-template.md +49 -0
- package/agent-pack/assets/skill/di-bao-monitoring/assets//345/256/214/346/225/264/346/212/245/350/241/250/346/250/241/346/235/277.xlsx +0 -0
- package/agent-pack/assets/skill/di-bao-monitoring/assets//345/277/253/346/212/245/346/250/241/346/235/277.xlsx +0 -0
- package/agent-pack/assets/skill/di-bao-monitoring/references/crossing-static-level-report.md +115 -0
- package/agent-pack/assets/skill/di-bao-monitoring/references/crossing-total-station-report.md +206 -0
- package/agent-pack/assets/skill/di-bao-monitoring/references/data-processing.md +170 -0
- package/agent-pack/assets/skill/di-bao-monitoring/references/elevated-line.md +319 -0
- package/agent-pack/assets/skill/di-bao-monitoring/references/initial-and-summary-workflow.md +222 -0
- package/agent-pack/assets/skill/di-bao-monitoring/references/key-difficulties.md +216 -0
- package/agent-pack/assets/skill/di-bao-monitoring/references/monitoring-catalog.md +80 -0
- package/agent-pack/assets/skill/di-bao-monitoring/references/phase0-intake.md +169 -0
- package/agent-pack/assets/skill/di-bao-monitoring/references/phase1-drafting.md +185 -0
- package/agent-pack/assets/skill/di-bao-monitoring/references/phase2-internal-review.md +166 -0
- package/agent-pack/assets/skill/di-bao-monitoring/references/report-workflow.md +181 -0
- package/agent-pack/assets/skill/di-bao-monitoring/references/review-checklist.md +140 -0
- package/agent-pack/assets/skill/di-bao-monitoring/references/review-response-template.md +87 -0
- package/agent-pack/assets/skill/di-bao-monitoring/references/scoping-and-pricing.md +214 -0
- package/agent-pack/assets/skill/di-bao-monitoring/references/source-analysis.md +137 -0
- package/agent-pack/assets/skill/di-bao-monitoring/references/technical-standards.md +188 -0
- package/agent-pack/assets/skill/di-bao-monitoring/references/toc-template-A.md +142 -0
- package/agent-pack/assets/skill/di-bao-monitoring/references/toc-template-B.md +100 -0
- package/agent-pack/assets/skill/di-bao-monitoring/references/warning-workflow.md +63 -0
- package/agent-pack/assets/skill/di-bao-monitoring/scripts/build_crossing_total_station_xlsx.py +2438 -0
- package/agent-pack/assets/skill/di-bao-monitoring/scripts/evaluate_alarms.py +215 -0
- package/agent-pack/assets/skill/di-bao-monitoring/scripts/fetch_adjusted_total_station.py +946 -0
- package/agent-pack/assets/skill/di-bao-monitoring/scripts/fetch_shhh_static_level.py +556 -0
- package/agent-pack/assets/skill/di-bao-monitoring/scripts/run_crossing_4h_report.sh +141 -0
- package/agent-pack/assets/skill/di-bao-monitoring/scripts/summarize_crossing_total_station.py +303 -0
- package/agent-pack/assets/skill/docx-generation/SKILL.md +141 -0
- package/agent-pack/assets/skill/excel-operations/SKILL.md +121 -0
- package/agent-pack/assets/skill/frontend-design/SKILL.md +151 -0
- package/agent-pack/assets/skill/humanizer/SKILL.md +90 -0
- package/agent-pack/assets/skill/monitoring-design/SKILL.md +100 -0
- package/agent-pack/assets/skill/operational-monitoring/SKILL.md +135 -0
- package/agent-pack/assets/skill/operational-monitoring/assets/checklists/archive-self-check.md +54 -0
- package/agent-pack/assets/skill/operational-monitoring/assets/schemas/convergence-result-table.csv +5 -0
- package/agent-pack/assets/skill/operational-monitoring/assets/schemas/horizontal-result-table.csv +3 -0
- package/agent-pack/assets/skill/operational-monitoring/assets/schemas/settlement-result-table.csv +7 -0
- package/agent-pack/assets/skill/operational-monitoring/assets/scripts/init-archive-tree.sh +65 -0
- package/agent-pack/assets/skill/operational-monitoring/assets/templates/control-network-report.md +102 -0
- package/agent-pack/assets/skill/operational-monitoring/assets/templates/daily-log.md +47 -0
- package/agent-pack/assets/skill/operational-monitoring/assets/templates/i-angle-check.md +38 -0
- package/agent-pack/assets/skill/operational-monitoring/assets/templates/monitoring-scheme.md +234 -0
- package/agent-pack/assets/skill/operational-monitoring/assets/templates/period-report.md +95 -0
- package/agent-pack/assets/skill/operational-monitoring/assets/templates/point-acceptance-record.md +51 -0
- package/agent-pack/assets/skill/operational-monitoring/assets/templates/point-installation-record.md +38 -0
- package/agent-pack/assets/skill/operational-monitoring/assets/templates/summary-report.md +89 -0
- package/agent-pack/assets/skill/operational-monitoring/assets/templates/warning-bulletin.md +61 -0
- package/agent-pack/assets/skill/operational-monitoring/assets/templates/weekly-monthly-report.md +46 -0
- package/agent-pack/assets/skill/operational-monitoring/references/archive-and-delivery.md +146 -0
- package/agent-pack/assets/skill/operational-monitoring/references/baseline-network.md +131 -0
- package/agent-pack/assets/skill/operational-monitoring/references/convergence-monitoring.md +134 -0
- package/agent-pack/assets/skill/operational-monitoring/references/data-processing.md +178 -0
- package/agent-pack/assets/skill/operational-monitoring/references/horizontal-displacement.md +128 -0
- package/agent-pack/assets/skill/operational-monitoring/references/monitoring-points.md +132 -0
- package/agent-pack/assets/skill/operational-monitoring/references/monitoring-scheme.md +178 -0
- package/agent-pack/assets/skill/operational-monitoring/references/period-report.md +108 -0
- package/agent-pack/assets/skill/operational-monitoring/references/regulations-and-frequency.md +127 -0
- package/agent-pack/assets/skill/operational-monitoring/references/settlement-monitoring.md +116 -0
- package/agent-pack/assets/skill/operational-monitoring/references/summary-report.md +128 -0
- package/agent-pack/assets/skill/operational-monitoring/references/warning-and-disposal.md +118 -0
- package/agent-pack/assets/skill/ops-monitoring/SKILL.md +93 -0
- package/agent-pack/assets/skill/railwise-knowledge-curation/SKILL.md +92 -0
- package/agent-pack/assets/skill/report-dibao/SKILL.md +60 -0
- package/agent-pack/assets/skill/report-writing/SKILL.md +103 -0
- package/agent-pack/assets/skill/resource-dispatch-intelligence/SKILL.md +125 -0
- package/agent-pack/assets/skill/standard-reference/SKILL.md +101 -0
- package/agent-pack/assets/skill/weekly-work-intelligence/SKILL.md +123 -0
- package/agent-pack/assets/template/adjustment-trend.json +53 -0
- package/agent-pack/assets/template/bid-technical-proposal.json +42 -0
- package/agent-pack/assets/template/compliance-review.json +35 -0
- package/agent-pack/assets/template/daily-monitor-report.json +34 -0
- package/agent-pack/assets/template/field-data-qa.json +47 -0
- package/agent-pack/assets/template/monitoring-plan.json +28 -0
- package/agent-pack/assets/template/monthly-monitor-report.json +47 -0
- package/agent-pack/assets/template/project-ppt.json +47 -0
- package/agent-pack/assets/template/review-response.json +28 -0
- package/agent-pack/assets/template/schema.json +72 -0
- package/agent-pack/assets/template/weekly-monitor-report.json +33 -0
- package/agent-pack/assets/theme/mytheme.json +223 -0
- package/agent-pack/assets/tool/angle_convert.ts +151 -0
- package/agent-pack/assets/tool/axial_force.ts +186 -0
- package/agent-pack/assets/tool/chart_generator.ts +185 -0
- package/agent-pack/assets/tool/control_network.ts +413 -0
- package/agent-pack/assets/tool/coord_transform.ts +333 -0
- package/agent-pack/assets/tool/cpiii_adjustment.ts +446 -0
- package/agent-pack/assets/tool/cross_section.ts +356 -0
- package/agent-pack/assets/tool/deformation_rate.ts +234 -0
- package/agent-pack/assets/tool/distance_calculator.ts +239 -0
- package/agent-pack/assets/tool/excel_export.ts +494 -0
- package/agent-pack/assets/tool/format_parser.ts +181 -0
- package/agent-pack/assets/tool/github-pr-search.ts +57 -0
- package/agent-pack/assets/tool/github-pr-search.txt +10 -0
- package/agent-pack/assets/tool/github-triage.ts +113 -0
- package/agent-pack/assets/tool/github-triage.txt +6 -0
- package/agent-pack/assets/tool/inclinometer.ts +248 -0
- package/agent-pack/assets/tool/monitoring_csv.ts +120 -0
- package/agent-pack/assets/tool/os_contract_query.ts +63 -0
- package/agent-pack/assets/tool/os_dibao_project_files.ts +75 -0
- package/agent-pack/assets/tool/os_file_download_ref.ts +48 -0
- package/agent-pack/assets/tool/os_file_preview.ts +46 -0
- package/agent-pack/assets/tool/os_gbrain_think.ts +31 -0
- package/agent-pack/assets/tool/os_ppt_generate.ts +37 -0
- package/agent-pack/assets/tool/os_project_context.ts +24 -0
- package/agent-pack/assets/tool/os_report_publish.ts +28 -0
- package/agent-pack/assets/tool/os_wiki_ingest.ts +38 -0
- package/agent-pack/assets/tool/os_wiki_query.ts +26 -0
- package/agent-pack/assets/tool/pile_stakeout.ts +299 -0
- package/agent-pack/assets/tool/report_export.ts +279 -0
- package/agent-pack/assets/tool/shield_guidance.ts +311 -0
- package/agent-pack/assets/tool/standard_query.ts +391 -0
- package/agent-pack/assets/tool/survey_calculator.ts +415 -0
- package/agent-pack/assets/tool/water_level.ts +209 -0
- package/agent-pack/bin/install.js +183 -0
- package/agent-pack/package.json +695 -0
- package/package.json +14 -8
- package/postinstall.mjs +53 -22
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
/// <reference path="../env.d.ts" />
|
|
2
|
+
import { tool } from "nb-railwise/tool"
|
|
3
|
+
|
|
4
|
+
const LEVELING_LIMITS: Record<string, { k: number; unit: string; desc: string }> = {
|
|
5
|
+
"1st": { k: 4, unit: "mm", desc: "一等水准" },
|
|
6
|
+
"2nd": { k: 6, unit: "mm", desc: "二等水准(城市轨道交通监测基准网常用)" },
|
|
7
|
+
"3rd": { k: 12, unit: "mm", desc: "三等水准" },
|
|
8
|
+
"4th": { k: 20, unit: "mm", desc: "四等水准" },
|
|
9
|
+
"city-2nd": { k: 8, unit: "mm", desc: "城市二等水准" },
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const TRAVERSE_ANGULAR_LIMITS: Record<string, { k: number; desc: string }> = {
|
|
13
|
+
DJ1: { k: 5, desc: "DJ1 经纬仪" },
|
|
14
|
+
DJ2: { k: 10, desc: "DJ2 经纬仪(城市测量常用)" },
|
|
15
|
+
DJ6: { k: 20, desc: "DJ6 经纬仪" },
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const leveling_closure = tool({
|
|
19
|
+
description:
|
|
20
|
+
"计算水准测量的高程闭合差是否在规范限差内。当需要判断外业水准数据是否合格时,必须调用此工具,绝不能自己口算或估算。",
|
|
21
|
+
args: {
|
|
22
|
+
measuredError: tool.schema.number().describe("现场实际测算出的高程闭合差,单位为毫米(mm),允许负值"),
|
|
23
|
+
routeLengthKm: tool.schema.number().positive().describe("水准路线的总长度,单位为公里(km)"),
|
|
24
|
+
order: tool.schema
|
|
25
|
+
.enum(["1st", "2nd", "3rd", "4th", "city-2nd"])
|
|
26
|
+
.default("4th")
|
|
27
|
+
.describe("测量等级:1st=一等, 2nd=二等, 3rd=三等, 4th=四等, city-2nd=城市二等"),
|
|
28
|
+
},
|
|
29
|
+
async execute(args) {
|
|
30
|
+
const spec = LEVELING_LIMITS[args.order]!
|
|
31
|
+
const limit = spec.k * Math.sqrt(args.routeLengthKm)
|
|
32
|
+
const pass = Math.abs(args.measuredError) <= limit
|
|
33
|
+
|
|
34
|
+
return JSON.stringify({
|
|
35
|
+
measured_error_mm: args.measuredError,
|
|
36
|
+
allowed_limit_mm: Number(limit.toFixed(3)),
|
|
37
|
+
order_desc: spec.desc,
|
|
38
|
+
formula: `±${spec.k}√L = ±${spec.k}×√${args.routeLengthKm} = ±${limit.toFixed(3)} mm`,
|
|
39
|
+
is_passed: pass,
|
|
40
|
+
ratio_pct: Number(((Math.abs(args.measuredError) / limit) * 100).toFixed(1)),
|
|
41
|
+
message: pass
|
|
42
|
+
? `✅ 合格:实测闭合差 ${args.measuredError}mm,限差 ±${limit.toFixed(3)}mm,占限差比例 ${((Math.abs(args.measuredError) / limit) * 100).toFixed(1)}%`
|
|
43
|
+
: `❌ 超限:实测闭合差 ${args.measuredError}mm,限差 ±${limit.toFixed(3)}mm,超出限差 ${(Math.abs(args.measuredError) - limit).toFixed(3)}mm,必须返工重测!`,
|
|
44
|
+
})
|
|
45
|
+
},
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
export const traverse_closure = tool({
|
|
49
|
+
description: "计算附合导线或闭合导线的角度闭合差是否满足规范限差。调用前请确认仪器等级和测站数量。",
|
|
50
|
+
args: {
|
|
51
|
+
measuredAngularError: tool.schema.number().describe("实测角度闭合差,单位为角秒(″),允许负值"),
|
|
52
|
+
stationCount: tool.schema.int().positive().describe("导线测站总数(转折点数量,不含起始点)"),
|
|
53
|
+
instrument: tool.schema.enum(["DJ1", "DJ2", "DJ6"]).default("DJ2").describe("使用的经纬仪等级:DJ1/DJ2/DJ6"),
|
|
54
|
+
},
|
|
55
|
+
async execute(args) {
|
|
56
|
+
const spec = TRAVERSE_ANGULAR_LIMITS[args.instrument]!
|
|
57
|
+
const limit = spec.k * Math.sqrt(args.stationCount)
|
|
58
|
+
const pass = Math.abs(args.measuredAngularError) <= limit
|
|
59
|
+
|
|
60
|
+
return JSON.stringify({
|
|
61
|
+
measured_error_arcsec: args.measuredAngularError,
|
|
62
|
+
allowed_limit_arcsec: Number(limit.toFixed(1)),
|
|
63
|
+
instrument_desc: spec.desc,
|
|
64
|
+
formula: `±${spec.k}″√n = ±${spec.k}×√${args.stationCount} = ±${limit.toFixed(1)}″`,
|
|
65
|
+
is_passed: pass,
|
|
66
|
+
message: pass
|
|
67
|
+
? `✅ 合格:角度闭合差 ${args.measuredAngularError}″,限差 ±${limit.toFixed(1)}″`
|
|
68
|
+
: `❌ 超限:角度闭合差 ${args.measuredAngularError}″,限差 ±${limit.toFixed(1)}″,超出 ${(Math.abs(args.measuredAngularError) - limit).toFixed(1)}″,必须返工重测!`,
|
|
69
|
+
})
|
|
70
|
+
},
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
export const alert_level = tool({
|
|
74
|
+
description: "根据监测点当前累计变化量和控制指标,计算预警等级。自动判断属于蓝色提示/黄色预警/红色报警/正常。",
|
|
75
|
+
args: {
|
|
76
|
+
cumulativeValue: tool.schema.number().describe("当前累计变化量绝对值,单位 mm(取绝对值传入)"),
|
|
77
|
+
alertThreshold: tool.schema.number().positive().describe("规范规定的报警控制值(红线),单位 mm"),
|
|
78
|
+
pointId: tool.schema.string().describe("测点编号,如 JC-01"),
|
|
79
|
+
},
|
|
80
|
+
async execute(args) {
|
|
81
|
+
const ratio = args.cumulativeValue / args.alertThreshold
|
|
82
|
+
let level: string
|
|
83
|
+
let color: string
|
|
84
|
+
let action: string
|
|
85
|
+
|
|
86
|
+
if (ratio >= 1.0) {
|
|
87
|
+
level = "红色报警"
|
|
88
|
+
color = "🔴"
|
|
89
|
+
action = "立即启动应急预案,暂停施工,通知各方负责人到场处置"
|
|
90
|
+
} else if (ratio >= 0.85) {
|
|
91
|
+
level = "橙色预警"
|
|
92
|
+
color = "🟠"
|
|
93
|
+
action = "通知项目负责人和监理,加密监测频率至每日2次,加强人工巡视"
|
|
94
|
+
} else if (ratio >= 0.7) {
|
|
95
|
+
level = "黄色预警"
|
|
96
|
+
color = "🟡"
|
|
97
|
+
action = "加密监测频率,关注发展趋势,准备上报项目部"
|
|
98
|
+
} else {
|
|
99
|
+
level = "正常"
|
|
100
|
+
color = "🟢"
|
|
101
|
+
action = "按正常频率继续监测"
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return JSON.stringify({
|
|
105
|
+
point_id: args.pointId,
|
|
106
|
+
cumulative_value_mm: args.cumulativeValue,
|
|
107
|
+
alert_threshold_mm: args.alertThreshold,
|
|
108
|
+
ratio_pct: Number((ratio * 100).toFixed(1)),
|
|
109
|
+
level,
|
|
110
|
+
color,
|
|
111
|
+
action,
|
|
112
|
+
message: `${color} ${args.pointId}:累计变化量 ${args.cumulativeValue}mm,占控制值比例 ${(ratio * 100).toFixed(1)}%,${level}。建议措施:${action}`,
|
|
113
|
+
})
|
|
114
|
+
},
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
// ============================================================
|
|
118
|
+
// Matrix utilities for least squares adjustment
|
|
119
|
+
// ============================================================
|
|
120
|
+
|
|
121
|
+
type Matrix = number[][]
|
|
122
|
+
|
|
123
|
+
const mat = {
|
|
124
|
+
zeros: (r: number, c: number): Matrix => Array.from({ length: r }, () => Array(c).fill(0) as number[]),
|
|
125
|
+
|
|
126
|
+
transpose: (a: Matrix): Matrix => a[0]!.map((_, j) => a.map((row) => row[j]!)),
|
|
127
|
+
|
|
128
|
+
mul: (a: Matrix, b: Matrix): Matrix =>
|
|
129
|
+
a.map((row) => b[0]!.map((_, j) => row.reduce((sum, val, k) => sum + val * b[k]![j]!, 0))),
|
|
130
|
+
|
|
131
|
+
mulVec: (a: Matrix, v: number[]): number[] => a.map((row) => row.reduce((sum, val, k) => sum + val * v[k]!, 0)),
|
|
132
|
+
|
|
133
|
+
invert: (src: Matrix): Matrix | null => {
|
|
134
|
+
const n = src.length
|
|
135
|
+
const aug = src.map((row, i) => [...row, ...Array.from({ length: n }, (_, j) => (i === j ? 1 : 0))])
|
|
136
|
+
for (let col = 0; col < n; col++) {
|
|
137
|
+
let pivotRow = col
|
|
138
|
+
for (let row = col + 1; row < n; row++) {
|
|
139
|
+
if (Math.abs(aug[row]![col]!) > Math.abs(aug[pivotRow]![col]!)) pivotRow = row
|
|
140
|
+
}
|
|
141
|
+
if (Math.abs(aug[pivotRow]![col]!) < 1e-15) return null
|
|
142
|
+
;[aug[col], aug[pivotRow]] = [aug[pivotRow]!, aug[col]!]
|
|
143
|
+
const pivot = aug[col]![col]!
|
|
144
|
+
for (let j = col; j < 2 * n; j++) aug[col]![j]! /= pivot
|
|
145
|
+
for (let row = 0; row < n; row++) {
|
|
146
|
+
if (row === col) continue
|
|
147
|
+
const factor = aug[row]![col]!
|
|
148
|
+
for (let j = col; j < 2 * n; j++) aug[row]![j]! -= factor * aug[col]![j]!
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return aug.map((row) => row.slice(n))
|
|
152
|
+
},
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// ============================================================
|
|
156
|
+
// Leveling network least squares adjustment
|
|
157
|
+
// ============================================================
|
|
158
|
+
|
|
159
|
+
export const leveling_adjustment = tool({
|
|
160
|
+
description:
|
|
161
|
+
"水准网严密平差(最小二乘法)。输入已知基准点高程和观测的高差数据,返回平差后高程、残差、单位权中误差及各点精度评定。data_analyst 在处理完闭合差校核后,需要严密计算时必须调用此工具。",
|
|
162
|
+
args: {
|
|
163
|
+
benchmarks: tool.schema
|
|
164
|
+
.array(
|
|
165
|
+
tool.schema.object({
|
|
166
|
+
id: tool.schema.string().describe("基准点编号"),
|
|
167
|
+
height: tool.schema.number().describe("已知高程(m)"),
|
|
168
|
+
}),
|
|
169
|
+
)
|
|
170
|
+
.min(1)
|
|
171
|
+
.describe("已知高程的基准点列表(至少1个)"),
|
|
172
|
+
observations: tool.schema
|
|
173
|
+
.array(
|
|
174
|
+
tool.schema.object({
|
|
175
|
+
from: tool.schema.string().describe("后视点编号"),
|
|
176
|
+
to: tool.schema.string().describe("前视点编号"),
|
|
177
|
+
heightDiff: tool.schema.number().describe("观测高差(m),from→to方向为正"),
|
|
178
|
+
routeLength: tool.schema.number().positive().describe("该测段路线长度(km)"),
|
|
179
|
+
}),
|
|
180
|
+
)
|
|
181
|
+
.min(1)
|
|
182
|
+
.describe("所有观测高差数据"),
|
|
183
|
+
order: tool.schema
|
|
184
|
+
.enum(["1st", "2nd", "3rd", "4th", "city-2nd"])
|
|
185
|
+
.default("4th")
|
|
186
|
+
.describe("测量等级,用于精度评定对比"),
|
|
187
|
+
},
|
|
188
|
+
async execute(args) {
|
|
189
|
+
const knownMap = new Map(args.benchmarks.map((b) => [b.id, b.height]))
|
|
190
|
+
const unknownIds = [...new Set(args.observations.flatMap((o) => [o.from, o.to]).filter((id) => !knownMap.has(id)))]
|
|
191
|
+
const u = unknownIds.length
|
|
192
|
+
const n = args.observations.length
|
|
193
|
+
|
|
194
|
+
if (u === 0) return JSON.stringify({ error: "所有点均为已知点,无需平差。" })
|
|
195
|
+
if (n < u)
|
|
196
|
+
return JSON.stringify({
|
|
197
|
+
error: `观测数 ${n} 少于未知数 ${u},无法进行平差。需要至少 ${u} 个观测值。`,
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
const idxOf = (id: string) => unknownIds.indexOf(id)
|
|
201
|
+
|
|
202
|
+
// Build coefficient matrix A, weight matrix P, observation vector L
|
|
203
|
+
const A = mat.zeros(n, u)
|
|
204
|
+
const P = mat.zeros(n, n)
|
|
205
|
+
const L: number[] = []
|
|
206
|
+
|
|
207
|
+
for (let i = 0; i < n; i++) {
|
|
208
|
+
const obs = args.observations[i]!
|
|
209
|
+
const fromIdx = idxOf(obs.from)
|
|
210
|
+
const toIdx = idxOf(obs.to)
|
|
211
|
+
|
|
212
|
+
// A matrix: h_to - h_from = heightDiff
|
|
213
|
+
if (fromIdx >= 0) A[i]![fromIdx] = -1
|
|
214
|
+
if (toIdx >= 0) A[i]![toIdx] = 1
|
|
215
|
+
|
|
216
|
+
// Weight = 1/routeLength (proportional to inverse of distance)
|
|
217
|
+
P[i]![i] = 1 / obs.routeLength
|
|
218
|
+
|
|
219
|
+
// L = observed - computed from known values
|
|
220
|
+
const fromH = knownMap.get(obs.from) ?? 0
|
|
221
|
+
const toH = knownMap.get(obs.to) ?? 0
|
|
222
|
+
L.push(obs.heightDiff - (toH - fromH))
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Normal equation: N = A^T P A, b = A^T P L
|
|
226
|
+
const AT = mat.transpose(A)
|
|
227
|
+
const ATP = mat.mul(AT, P)
|
|
228
|
+
const N = mat.mul(ATP, A)
|
|
229
|
+
const b = mat.mulVec(ATP, L)
|
|
230
|
+
|
|
231
|
+
const Qxx = mat.invert(N)
|
|
232
|
+
if (!Qxx) return JSON.stringify({ error: "法方程系数矩阵奇异,无法求解。请检查网形是否连通。" })
|
|
233
|
+
|
|
234
|
+
// Solve: X = Qxx * b
|
|
235
|
+
const X = mat.mulVec(Qxx, b)
|
|
236
|
+
|
|
237
|
+
// Residuals: V = A*X - L
|
|
238
|
+
const AX = mat.mulVec(A, X)
|
|
239
|
+
const V = AX.map((v, i) => v - L[i]!)
|
|
240
|
+
|
|
241
|
+
// Unit weight RMSE: σ₀ = sqrt(V^T P V / (n - u))
|
|
242
|
+
const VTPV = V.reduce((sum, v, i) => sum + v * P[i]![i]! * v, 0)
|
|
243
|
+
const redundancy = n - u
|
|
244
|
+
const sigma0 = redundancy > 0 ? Math.sqrt(VTPV / redundancy) : 0
|
|
245
|
+
|
|
246
|
+
// Point height RMSE: σ_i = σ₀ * sqrt(Q_ii)
|
|
247
|
+
const adjusted = unknownIds.map((id, i) => {
|
|
248
|
+
const approxH = knownMap.get(id) ?? 0
|
|
249
|
+
const correction = X[i]!
|
|
250
|
+
const height = approxH + correction
|
|
251
|
+
const rmse = sigma0 * Math.sqrt(Math.abs(Qxx[i]![i]!))
|
|
252
|
+
return {
|
|
253
|
+
point_id: id,
|
|
254
|
+
adjusted_height_m: Number(height.toFixed(4)),
|
|
255
|
+
correction_mm: Number((correction * 1000).toFixed(3)),
|
|
256
|
+
rmse_mm: Number((rmse * 1000).toFixed(3)),
|
|
257
|
+
}
|
|
258
|
+
})
|
|
259
|
+
|
|
260
|
+
const residuals = args.observations.map((obs, i) => ({
|
|
261
|
+
from: obs.from,
|
|
262
|
+
to: obs.to,
|
|
263
|
+
observed_mm: Number((obs.heightDiff * 1000).toFixed(3)),
|
|
264
|
+
residual_mm: Number((V[i]! * 1000).toFixed(3)),
|
|
265
|
+
}))
|
|
266
|
+
|
|
267
|
+
const spec = LEVELING_LIMITS[args.order]!
|
|
268
|
+
const maxRmse = Math.max(...adjusted.map((a) => a.rmse_mm))
|
|
269
|
+
|
|
270
|
+
return JSON.stringify({
|
|
271
|
+
method: "最小二乘法严密平差",
|
|
272
|
+
known_points: args.benchmarks.length,
|
|
273
|
+
unknown_points: u,
|
|
274
|
+
observations: n,
|
|
275
|
+
redundancy,
|
|
276
|
+
unit_weight_rmse_mm: Number((sigma0 * 1000).toFixed(3)),
|
|
277
|
+
order_desc: spec.desc,
|
|
278
|
+
max_point_rmse_mm: maxRmse,
|
|
279
|
+
adjusted_heights: adjusted,
|
|
280
|
+
residuals,
|
|
281
|
+
assessment:
|
|
282
|
+
sigma0 * 1000 < spec.k
|
|
283
|
+
? `✅ 单位权中误差 ${(sigma0 * 1000).toFixed(3)}mm < ${spec.k}mm(${spec.desc}限差系数),精度合格`
|
|
284
|
+
: `⚠️ 单位权中误差 ${(sigma0 * 1000).toFixed(3)}mm ≥ ${spec.k}mm(${spec.desc}限差系数),建议检查观测质量`,
|
|
285
|
+
})
|
|
286
|
+
},
|
|
287
|
+
})
|
|
288
|
+
|
|
289
|
+
// ============================================================
|
|
290
|
+
// Traverse network coordinate adjustment
|
|
291
|
+
// ============================================================
|
|
292
|
+
|
|
293
|
+
const deg2rad = (d: number) => (d * Math.PI) / 180
|
|
294
|
+
|
|
295
|
+
export const traverse_adjustment = tool({
|
|
296
|
+
description:
|
|
297
|
+
"附合导线/闭合导线坐标平差计算。输入起始点坐标、起始方位角、各站观测角和边长,返回平差后坐标、闭合差分析及各点精度。data_analyst 在处理导线测量数据时必须调用此工具。",
|
|
298
|
+
args: {
|
|
299
|
+
startPoint: tool.schema
|
|
300
|
+
.object({
|
|
301
|
+
id: tool.schema.string().describe("起始点编号"),
|
|
302
|
+
x: tool.schema.number().describe("起始点X坐标(东方向/m)"),
|
|
303
|
+
y: tool.schema.number().describe("起始点Y坐标(北方向/m)"),
|
|
304
|
+
})
|
|
305
|
+
.describe("起始已知点"),
|
|
306
|
+
endPoint: tool.schema
|
|
307
|
+
.object({
|
|
308
|
+
id: tool.schema.string().describe("终止点编号"),
|
|
309
|
+
x: tool.schema.number().describe("终止点X坐标(东方向/m)"),
|
|
310
|
+
y: tool.schema.number().describe("终止点Y坐标(北方向/m)"),
|
|
311
|
+
})
|
|
312
|
+
.describe("终止已知点(附合导线需要;闭合导线与起始点相同)"),
|
|
313
|
+
startAzimuth: tool.schema.number().describe("起始边方位角(度,十进制)"),
|
|
314
|
+
endAzimuth: tool.schema.number().describe("终止边方位角(度,十进制);闭合导线传起始方位角"),
|
|
315
|
+
stations: tool.schema
|
|
316
|
+
.array(
|
|
317
|
+
tool.schema.object({
|
|
318
|
+
id: tool.schema.string().describe("转折点编号"),
|
|
319
|
+
angle: tool.schema.number().describe("观测的左角/转折角(度,十进制)"),
|
|
320
|
+
distance: tool.schema.number().positive().describe("该站到下一站的边长(m)"),
|
|
321
|
+
}),
|
|
322
|
+
)
|
|
323
|
+
.min(1)
|
|
324
|
+
.describe("各导线测站观测数据(按测量顺序排列)"),
|
|
325
|
+
instrument: tool.schema.enum(["DJ1", "DJ2", "DJ6"]).default("DJ2").describe("经纬仪等级"),
|
|
326
|
+
},
|
|
327
|
+
async execute(args) {
|
|
328
|
+
const n = args.stations.length
|
|
329
|
+
const angSpec = TRAVERSE_ANGULAR_LIMITS[args.instrument]!
|
|
330
|
+
|
|
331
|
+
// Step 1: Angular closure
|
|
332
|
+
const sumAngles = args.stations.reduce((s, st) => s + st.angle, 0)
|
|
333
|
+
const theoreticalSum = (((args.endAzimuth - args.startAzimuth + 180 * n) % 360) + 360) % 360
|
|
334
|
+
const angularClosure = sumAngles - theoreticalSum
|
|
335
|
+
const normalized =
|
|
336
|
+
angularClosure > 180 ? angularClosure - 360 : angularClosure < -180 ? angularClosure + 360 : angularClosure
|
|
337
|
+
const closureSec = normalized * 3600
|
|
338
|
+
const angLimit = angSpec.k * Math.sqrt(n)
|
|
339
|
+
|
|
340
|
+
if (Math.abs(closureSec) > angLimit)
|
|
341
|
+
return JSON.stringify({
|
|
342
|
+
error: `角度闭合差 ${closureSec.toFixed(1)}″ 超出限差 ±${angLimit.toFixed(1)}″(${angSpec.desc}),请先返工重测角度。`,
|
|
343
|
+
angular_closure_arcsec: Number(closureSec.toFixed(1)),
|
|
344
|
+
angular_limit_arcsec: Number(angLimit.toFixed(1)),
|
|
345
|
+
})
|
|
346
|
+
|
|
347
|
+
// Step 2: Distribute angular error equally
|
|
348
|
+
const corr = -normalized / n
|
|
349
|
+
const azimuths: number[] = []
|
|
350
|
+
let az = args.startAzimuth
|
|
351
|
+
for (const st of args.stations) {
|
|
352
|
+
az = (((az + st.angle + corr + 180) % 360) + 360) % 360
|
|
353
|
+
azimuths.push(az)
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Step 3: Compute provisional coordinates
|
|
357
|
+
const totalDist = args.stations.reduce((s, st) => s + st.distance, 0)
|
|
358
|
+
const dxArr = args.stations.map((st, i) => st.distance * Math.sin(deg2rad(azimuths[i]!)))
|
|
359
|
+
const dyArr = args.stations.map((st, i) => st.distance * Math.cos(deg2rad(azimuths[i]!)))
|
|
360
|
+
|
|
361
|
+
const sumDx = dxArr.reduce((a, b) => a + b, 0)
|
|
362
|
+
const sumDy = dyArr.reduce((a, b) => a + b, 0)
|
|
363
|
+
const fx = sumDx - (args.endPoint.x - args.startPoint.x)
|
|
364
|
+
const fy = sumDy - (args.endPoint.y - args.startPoint.y)
|
|
365
|
+
const closureDist = Math.sqrt(fx * fx + fy * fy)
|
|
366
|
+
const relClosure = totalDist > 0 ? totalDist / closureDist : Infinity
|
|
367
|
+
|
|
368
|
+
// Step 4: Distribute coordinate closure proportionally
|
|
369
|
+
const coords: Array<{ id: string; x: number; y: number }> = []
|
|
370
|
+
let cumDist = 0
|
|
371
|
+
|
|
372
|
+
for (let i = 0; i < n; i++) {
|
|
373
|
+
cumDist += args.stations[i]!.distance
|
|
374
|
+
const ratio = cumDist / totalDist
|
|
375
|
+
const cx = args.startPoint.x + dxArr.slice(0, i + 1).reduce((a, b) => a + b, 0) - fx * ratio
|
|
376
|
+
const cy = args.startPoint.y + dyArr.slice(0, i + 1).reduce((a, b) => a + b, 0) - fy * ratio
|
|
377
|
+
coords.push({ id: args.stations[i]!.id, x: Number(cx.toFixed(4)), y: Number(cy.toFixed(4)) })
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const pointRmse = closureDist / Math.sqrt(3 * n)
|
|
381
|
+
|
|
382
|
+
return JSON.stringify({
|
|
383
|
+
method: "附合导线简易平差(角度等权分配,坐标按边长比例分配)",
|
|
384
|
+
station_count: n,
|
|
385
|
+
total_distance_m: Number(totalDist.toFixed(3)),
|
|
386
|
+
angular_closure: {
|
|
387
|
+
measured_arcsec: Number(closureSec.toFixed(1)),
|
|
388
|
+
limit_arcsec: Number(angLimit.toFixed(1)),
|
|
389
|
+
correction_per_station_arcsec: Number((corr * 3600).toFixed(2)),
|
|
390
|
+
is_passed: true,
|
|
391
|
+
},
|
|
392
|
+
coordinate_closure: {
|
|
393
|
+
fx_m: Number(fx.toFixed(4)),
|
|
394
|
+
fy_m: Number(fy.toFixed(4)),
|
|
395
|
+
closure_distance_m: Number(closureDist.toFixed(4)),
|
|
396
|
+
relative_closure: `1/${Math.round(relClosure)}`,
|
|
397
|
+
assessment:
|
|
398
|
+
relClosure >= 10000
|
|
399
|
+
? "✅ 优秀(全长相对闭合差 < 1/10000)"
|
|
400
|
+
: relClosure >= 4000
|
|
401
|
+
? "✅ 良好(全长相对闭合差 < 1/4000)"
|
|
402
|
+
: relClosure >= 2000
|
|
403
|
+
? "⚠️ 一般(全长相对闭合差 < 1/2000),建议复查"
|
|
404
|
+
: "❌ 不合格,需返工重测",
|
|
405
|
+
},
|
|
406
|
+
adjusted_coordinates: coords,
|
|
407
|
+
azimuths_deg: azimuths.map((a, i) => ({
|
|
408
|
+
from: i === 0 ? args.startPoint.id : args.stations[i - 1]!.id,
|
|
409
|
+
to: args.stations[i]!.id,
|
|
410
|
+
azimuth: Number(a.toFixed(6)),
|
|
411
|
+
})),
|
|
412
|
+
point_rmse_mm: Number((pointRmse * 1000).toFixed(2)),
|
|
413
|
+
})
|
|
414
|
+
},
|
|
415
|
+
})
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/// <reference path="../env.d.ts" />
|
|
2
|
+
import { tool } from "nb-railwise/tool"
|
|
3
|
+
|
|
4
|
+
export const water_level_analysis = tool({
|
|
5
|
+
description:
|
|
6
|
+
"基坑地下水位监测数据分析。根据水位观测井的水位数据序列,计算水位变化量、变化速率,判断降水效果和回灌影响。基坑自动化监测中水位监控的核心工具。data_analyst 处理水位数据时必须调用此工具。",
|
|
7
|
+
args: {
|
|
8
|
+
wellId: tool.schema.string().describe("观测井编号,如 SW-01"),
|
|
9
|
+
wellType: tool.schema
|
|
10
|
+
.enum(["pumping", "observation", "recharge"])
|
|
11
|
+
.describe("井类型:pumping=降水井, observation=观测井, recharge=回灌井"),
|
|
12
|
+
groundElevation: tool.schema.number().describe("井口地面标高(m)"),
|
|
13
|
+
initialLevel: tool.schema.number().describe("初始水位标高(m)或初始埋深(m)"),
|
|
14
|
+
levelType: tool.schema
|
|
15
|
+
.enum(["elevation", "depth"])
|
|
16
|
+
.default("elevation")
|
|
17
|
+
.describe("水位值类型:elevation=绝对标高, depth=距地面埋深"),
|
|
18
|
+
records: tool.schema
|
|
19
|
+
.array(
|
|
20
|
+
tool.schema.object({
|
|
21
|
+
date: tool.schema.string().describe("观测日期 YYYY-MM-DD 或 YYYY-MM-DD HH:mm"),
|
|
22
|
+
level: tool.schema.number().describe("水位值(标高m或埋深m,与levelType一致)"),
|
|
23
|
+
}),
|
|
24
|
+
)
|
|
25
|
+
.min(1)
|
|
26
|
+
.describe("水位观测数据"),
|
|
27
|
+
targetLevel: tool.schema.number().optional().describe("目标降水水位标高(m)或目标埋深(m)"),
|
|
28
|
+
alertRise: tool.schema.number().positive().optional().describe("水位回升报警值(m),超过此值需预警"),
|
|
29
|
+
excavationBottom: tool.schema.number().optional().describe("基坑底标高(m),用于计算水头差"),
|
|
30
|
+
},
|
|
31
|
+
async execute(args) {
|
|
32
|
+
const toElevation = (v: number) => (args.levelType === "elevation" ? v : args.groundElevation - v)
|
|
33
|
+
|
|
34
|
+
const initElev = toElevation(args.initialLevel)
|
|
35
|
+
|
|
36
|
+
const analyzed = args.records.map((r, i) => {
|
|
37
|
+
const elev = toElevation(r.level)
|
|
38
|
+
const depth = args.groundElevation - elev
|
|
39
|
+
const change = elev - initElev
|
|
40
|
+
const headAboveExcavation = args.excavationBottom !== undefined ? elev - args.excavationBottom : null
|
|
41
|
+
|
|
42
|
+
let status = "🟢 正常"
|
|
43
|
+
if (args.alertRise && change > args.alertRise) {
|
|
44
|
+
status = "🔴 水位回升超限"
|
|
45
|
+
} else if (args.targetLevel !== undefined) {
|
|
46
|
+
const targetElev = toElevation(args.targetLevel)
|
|
47
|
+
if (elev > targetElev + 0.5) status = "🟡 未达目标"
|
|
48
|
+
else if (elev <= targetElev) status = "🟢 已达目标"
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
date: r.date,
|
|
53
|
+
elevation_m: Number(elev.toFixed(3)),
|
|
54
|
+
depth_m: Number(depth.toFixed(3)),
|
|
55
|
+
change_from_initial_m: Number(change.toFixed(3)),
|
|
56
|
+
head_above_excavation_m: headAboveExcavation !== null ? Number(headAboveExcavation.toFixed(3)) : null,
|
|
57
|
+
status,
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
const rates: Array<{ period: string; rate_m_per_day: number }> = []
|
|
62
|
+
for (let i = 1; i < analyzed.length; i++) {
|
|
63
|
+
const dt = (new Date(args.records[i]!.date).getTime() - new Date(args.records[i - 1]!.date).getTime()) / 86400000
|
|
64
|
+
if (dt > 0) {
|
|
65
|
+
rates.push({
|
|
66
|
+
period: `${args.records[i - 1]!.date} → ${args.records[i]!.date}`,
|
|
67
|
+
rate_m_per_day: Number(((analyzed[i]!.elevation_m - analyzed[i - 1]!.elevation_m) / dt).toFixed(4)),
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const latest = analyzed[analyzed.length - 1]!
|
|
73
|
+
const lowest = analyzed.reduce((min, a) => (a.elevation_m < min.elevation_m ? a : min), analyzed[0]!)
|
|
74
|
+
const highest = analyzed.reduce((max, a) => (a.elevation_m > max.elevation_m ? a : max), analyzed[0]!)
|
|
75
|
+
const amplitude = highest.elevation_m - lowest.elevation_m
|
|
76
|
+
|
|
77
|
+
let dewateringAssessment = ""
|
|
78
|
+
if (args.targetLevel !== undefined) {
|
|
79
|
+
const targetElev = toElevation(args.targetLevel)
|
|
80
|
+
if (latest.elevation_m <= targetElev) {
|
|
81
|
+
dewateringAssessment = "✅ 降水达标,水位已降至目标水位以下"
|
|
82
|
+
} else {
|
|
83
|
+
const gap = latest.elevation_m - targetElev
|
|
84
|
+
dewateringAssessment = `⚠️ 降水未达标,当前水位高于目标 ${gap.toFixed(3)}m,需加强降水`
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
let safetyAssessment = ""
|
|
89
|
+
if (args.excavationBottom !== undefined && latest.head_above_excavation_m !== null) {
|
|
90
|
+
if (latest.head_above_excavation_m > 0) {
|
|
91
|
+
safetyAssessment = `⚠️ 水位高于基坑底 ${latest.head_above_excavation_m.toFixed(3)}m,存在突涌风险`
|
|
92
|
+
} else {
|
|
93
|
+
safetyAssessment = `✅ 水位低于基坑底 ${Math.abs(latest.head_above_excavation_m).toFixed(3)}m`
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return JSON.stringify({
|
|
98
|
+
well_id: args.wellId,
|
|
99
|
+
well_type: args.wellType === "pumping" ? "降水井" : args.wellType === "observation" ? "观测井" : "回灌井",
|
|
100
|
+
ground_elevation_m: args.groundElevation,
|
|
101
|
+
initial_elevation_m: Number(initElev.toFixed(3)),
|
|
102
|
+
latest: {
|
|
103
|
+
date: latest.date,
|
|
104
|
+
elevation_m: latest.elevation_m,
|
|
105
|
+
depth_m: latest.depth_m,
|
|
106
|
+
change_m: latest.change_from_initial_m,
|
|
107
|
+
},
|
|
108
|
+
range: {
|
|
109
|
+
lowest_m: lowest.elevation_m,
|
|
110
|
+
highest_m: highest.elevation_m,
|
|
111
|
+
amplitude_m: Number(amplitude.toFixed(3)),
|
|
112
|
+
},
|
|
113
|
+
records: analyzed,
|
|
114
|
+
rates,
|
|
115
|
+
dewatering_assessment: dewateringAssessment || undefined,
|
|
116
|
+
safety_assessment: safetyAssessment || undefined,
|
|
117
|
+
message: `✅ ${args.wellId} 水位分析:当前标高 ${latest.elevation_m}m(埋深 ${latest.depth_m}m),较初始${latest.change_from_initial_m > 0 ? "上升" : "下降"} ${Math.abs(latest.change_from_initial_m).toFixed(3)}m`,
|
|
118
|
+
})
|
|
119
|
+
},
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
export const water_level_contour = tool({
|
|
123
|
+
description:
|
|
124
|
+
"多井水位等值线数据生成。根据多个观测井的坐标和水位数据,计算水位梯度和流向,为绘制等水位线图提供数据。用于基坑降水效果评估。",
|
|
125
|
+
args: {
|
|
126
|
+
wells: tool.schema
|
|
127
|
+
.array(
|
|
128
|
+
tool.schema.object({
|
|
129
|
+
id: tool.schema.string().describe("井编号"),
|
|
130
|
+
x: tool.schema.number().describe("X坐标(m)"),
|
|
131
|
+
y: tool.schema.number().describe("Y坐标(m)"),
|
|
132
|
+
elevation: tool.schema.number().describe("当前水位标高(m)"),
|
|
133
|
+
}),
|
|
134
|
+
)
|
|
135
|
+
.min(3)
|
|
136
|
+
.describe("各井位置和水位(至少3口井)"),
|
|
137
|
+
excavationCenter: tool.schema
|
|
138
|
+
.object({
|
|
139
|
+
x: tool.schema.number().describe("基坑中心X"),
|
|
140
|
+
y: tool.schema.number().describe("基坑中心Y"),
|
|
141
|
+
})
|
|
142
|
+
.optional()
|
|
143
|
+
.describe("基坑中心坐标,用于判断降水漏斗形态"),
|
|
144
|
+
},
|
|
145
|
+
async execute(args) {
|
|
146
|
+
const n = args.wells.length
|
|
147
|
+
const avgElev = args.wells.reduce((s, w) => s + w.elevation, 0) / n
|
|
148
|
+
const maxWell = args.wells.reduce((max, w) => (w.elevation > max.elevation ? w : max), args.wells[0]!)
|
|
149
|
+
const minWell = args.wells.reduce((min, w) => (w.elevation < min.elevation ? w : min), args.wells[0]!)
|
|
150
|
+
|
|
151
|
+
const gradients: Array<{
|
|
152
|
+
from: string
|
|
153
|
+
to: string
|
|
154
|
+
gradient: number
|
|
155
|
+
distance_m: number
|
|
156
|
+
direction_deg: number
|
|
157
|
+
}> = []
|
|
158
|
+
|
|
159
|
+
for (let i = 0; i < n; i++) {
|
|
160
|
+
for (let j = i + 1; j < n; j++) {
|
|
161
|
+
const a = args.wells[i]!
|
|
162
|
+
const b = args.wells[j]!
|
|
163
|
+
const dist = Math.sqrt((b.x - a.x) ** 2 + (b.y - a.y) ** 2)
|
|
164
|
+
if (dist < 0.1) continue
|
|
165
|
+
const grad = Math.abs(b.elevation - a.elevation) / dist
|
|
166
|
+
const dir = (Math.atan2(b.x - a.x, b.y - a.y) * 180) / Math.PI
|
|
167
|
+
gradients.push({
|
|
168
|
+
from: a.id,
|
|
169
|
+
to: b.id,
|
|
170
|
+
gradient: Number(grad.toFixed(6)),
|
|
171
|
+
distance_m: Number(dist.toFixed(2)),
|
|
172
|
+
direction_deg: Number(((dir + 360) % 360).toFixed(1)),
|
|
173
|
+
})
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const avgGradient = gradients.length > 0 ? gradients.reduce((s, g) => s + g.gradient, 0) / gradients.length : 0
|
|
178
|
+
|
|
179
|
+
let funnelAssessment = ""
|
|
180
|
+
if (args.excavationCenter) {
|
|
181
|
+
const cx = args.excavationCenter.x
|
|
182
|
+
const cy = args.excavationCenter.y
|
|
183
|
+
const sorted = args.wells
|
|
184
|
+
.map((w) => ({ id: w.id, elev: w.elevation, dist: Math.sqrt((w.x - cx) ** 2 + (w.y - cy) ** 2) }))
|
|
185
|
+
.sort((a, b) => a.dist - b.dist)
|
|
186
|
+
|
|
187
|
+
const innerAvg = sorted.slice(0, Math.ceil(n / 2)).reduce((s, w) => s + w.elev, 0) / Math.ceil(n / 2)
|
|
188
|
+
const outerAvg = sorted.slice(Math.ceil(n / 2)).reduce((s, w) => s + w.elev, 0) / (n - Math.ceil(n / 2))
|
|
189
|
+
|
|
190
|
+
if (innerAvg < outerAvg) {
|
|
191
|
+
funnelAssessment = `✅ 降水漏斗形态正常:内侧平均水位 ${innerAvg.toFixed(3)}m < 外侧 ${outerAvg.toFixed(3)}m`
|
|
192
|
+
} else {
|
|
193
|
+
funnelAssessment = `⚠️ 降水漏斗异常:内侧平均水位 ${innerAvg.toFixed(3)}m ≥ 外侧 ${outerAvg.toFixed(3)}m,降水效果不佳`
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return JSON.stringify({
|
|
198
|
+
well_count: n,
|
|
199
|
+
average_elevation_m: Number(avgElev.toFixed(3)),
|
|
200
|
+
max_well: { id: maxWell.id, elevation_m: maxWell.elevation },
|
|
201
|
+
min_well: { id: minWell.id, elevation_m: minWell.elevation },
|
|
202
|
+
level_difference_m: Number((maxWell.elevation - minWell.elevation).toFixed(3)),
|
|
203
|
+
average_gradient: Number(avgGradient.toFixed(6)),
|
|
204
|
+
gradients,
|
|
205
|
+
funnel_assessment: funnelAssessment || undefined,
|
|
206
|
+
message: `✅ ${n}口井水位分析:水位差 ${(maxWell.elevation - minWell.elevation).toFixed(3)}m,平均梯度 ${avgGradient.toFixed(6)}`,
|
|
207
|
+
})
|
|
208
|
+
},
|
|
209
|
+
})
|