内容
# 地籍信息管理系统
## 系统概述
本系统基于韩国 국토교통부 的 브이월드 Open API,提供 **土地利用计划查询 + 地籍图 DXF导出** 功能。
## 功能列表
| 工具 | 说明 |
|---|---|
| `get_land_use_plan` | 通过地号地址查询土地登记簿(地目、面积、所有权划分)+ 用途区域/地区/范围 + 个别公示地价 |
| `get_land_use_plan_by_pnu` | 通过 PNU(19位)查询上述信息 |
| `export_cadastral_dxf` | 通过地号地址导出地籍图(+周边地籍)为 DXF 文件 |
| `export_cadastral_dxf_by_pnu` | 通过 PNU(19位)导出上述地籍图 |
| `export_land_report_dxf` | 通过地号地址请求信息(表格)+ 土地利用计划 + 地籍图(XCLIP 裁剪)为一个页面 DXF 文件 |
| `export_land_report_dxf_by_pnu` | 通过 PNU(19位)导出上述信息 |
| `search_national_law` | 通过国家法律(法律/施行令/施行规则)名称搜索(不包括判例、法律术语等) |
| `get_national_law_text` | 通过国家法律 MST 查询条款 - 条款编号(jo)未指定时,返回目录;指定时,返回整个条款文本 |
所有功能仅供参考 - 不具有法律效力的「土地利用计划确认书」·地籍测量成果图。准确确认请咨询 [토지이음(eum.go.kr)](https://www.eum.go.kr) 或相关行政机关。
## 安装
```bash
npm install
npm run build
```
要使用 `export_land_report_dxf`(一个页面报告,XCLIP 裁剪),还需要安装 Python 3 + ezdxf:
```bash
pip install ezdxf
```
如果系统中安装了多个 Python 版本,可能会导致自动检测失败,此时需要在 `.env` 文件中指定正确的 Python 路径:
```bash
CADASTRAL_PYTHON=/path/to/python
```
## VWorld API 密钥申请
1. [vworld.kr](https://www.vworld.kr) 注册并登录
2. 在开放 API 认证密钥申请页面:
- **服务 URL**:填写部署本服务器的域名/IP 地址(例如:`http://localhost`,部署服务器时填写实际域名)
- **应用 API**:必须勾选以下项目
- `搜索 API` - 地址转换为 PNU
- `2D 数据 API` - 地籍地块边界坐标,个别公示地价(多边形属性)
- `国家重点 API` - 土地登记簿,用途区域/地区(`ned/data/*` 端点属于此类别)
- `WMS/WFS API` - 不必须,但建议一起勾选
3. 审批通常需要几分钟到几小时。
**重要**:`搜索 API` 即使没有域名值也可以工作,但 `2D 数据` 和 `国家重点` API 请求如果没有 `domain` 参数或与申请的服务 URL 不匹配,将会返回 `INCORRECT_KEY` 错误。因此,请确保 `VWORLD_DOMAIN` 与服务 URL 完全一致。
## 环境变量
复制 `.env.example` 为 `.env` 并填写:
| 变量 | 必需 | 说明 |
|---|---|---|
| `VWORLD_KEY` | 必需 | VWorld 开放 API 认证密钥 |
| `VWORLD_DOMAIN` | 几乎必需 | 与密钥申请时登记的服务 URL 完全一致。否则,2D 数据和国家重点 API 将因 `INCORRECT_KEY` 失败 |
| `DXF_OUTPUT_DIR` | 可选 | DXF 文件保存路径(默认:`./output`) |
| `CADASTRAL_PYTHON` | 可选 | `export_land_report_dxf` 使用的 Python 执行文件路径。若未指定,将自动检测 `python3`/`python`/`py` |
| `LAW_OC` | 可选 | 法制处开放 API 认证密钥。用于 `export_land_report_dxf` 自动查询地块所在地方自治团体조례中的容积率/绿化基准。无则使用国家法律上限代替 |
## 连接 MCP 客户端(例如 Claude Desktop)
`claude_desktop_config.json`:
```json
{
"mcpServers": {
"cadastral-mcp": {
"command": "node",
"args": ["绝对路径/cadastral-mcp/build/index.js"],
"env": {
"VWORLD_KEY": " 발급받은 키",
"VWORLD_DOMAIN": "키 신청 시 등록한 서비스 URL"
}
}
}
}
```
## 工具详情
### `get_land_use_plan` / `get_land_use_plan_by_pnu`
- 输入:`address`(或 `pnu`),`stdrYear`(可选,个别公示地价基准年,默认为今年)
- 输出示例:
```json
{
"PNU": "5211312000100770003",
"土地登记簿": { "地目": "田", "面积": "4470", "所有权划分": "个人" },
"用途区域/地区": ["自然灾害危险改善区", "畜牧业限制区", "生产绿地区"],
"个别公示地价": [{ "基准年": "2026", "每平方米公示地价": "191300" }]
}
```
### `export_cadastral_dxf` / `export_cadastral_dxf_by_pnu`
- 输入:`address`(或 `pnu`),`crs`(可选,默认为 `EPSG:5186`),`includeNeighbors`(可选,默认为 `true`),`bufferMeters`(可选,默认为 `50`)
- 目标地块边界上的缓冲区范围内的所有地块(包括公共道路)都会被一并查询和绘制。
- **如果用户未指定范围(`bufferMeters`),建议在调用前询问并确认。** (工具说明中也包含此指南,因此 MCP 客户端可以自动识别。)
- DXF 图层构成:
- `TARGET_PARCEL` / `TARGET_LABEL` - 目标地块边界(粗红线)+ 地号标签
- `NEIGHBOR_PARCELS` / `NEIGHBOR_LABEL` - 周边地块边界(细蓝线)+ 地号标签
- `SOURCE_NOTE` - 来源/免责声明(绿色)
### `export_land_report_dxf` / `export_land_report_dxf_by_pnu`
- 输入:`address`(或 `pnu`),`crs`/`includeNeighbors`/`bufferMeters`(默认与 `export_cadastral_dxf` 相同),`stdrYear`(可选)
- 一页布局(使用돋움字体,白色菱形图标 + 绿色标题 + 黄色双下划线标题),左右上角均为表格形式:
- **左侧**:请求信息表 - 基地位置·基地面积·地目·区域/地区 使用 VWorld 数据。 **最大容积率·最大建筑面积比率·绿化计划·停车计划分别显示国家法律上限和地块所在地方自治团体조례的值** (参见下面的“地方自治团体 조례 自动查询”)。前道路·接道长度因数据来源缺失而显示为 `-`
- **右上角**:土地利用计划 - 法定洞·地号·地目·面积·所有权划分·区域/地区·个别公示地价 7 行表格
- **右下角**:地籍图 - 使用 `CADASTRAL_MAP` 块绘制后,以面板边界为裁剪边界 **实际应用 AutoCAD XCLIP(SPATIAL_FILTER)** ,将超出框外的地块(道路等)真正剪裁掉
- XCLIP 使用 Python(ezdxf)子进程应用。 如果没有 Python/ezdxf,则会创建不带剪裁的 DXF 文件,并在响应中的 `地籍图_XCLIP 裁剪` 字段中显示失败原因。
## 地方自治团体 조례 自动查询(容积率/绿化/停车)
- 从法定洞名中提取市/县名称,使用法制处开放 API 搜索 "{市} 城市规划 조례"/"{市} 建筑 조례"/"{市} 停车场 조례",并在整个条款中找到对应条款(不推测条款编号与目录顺序是否匹配)。
- **停车标准通常在条款正文中没有明确指出,而是在 별표(HWP/PDF 附件)中,因此如果在条款中找到对 별표N 的引用,则搜索 별표 列表,下载实际文件,并使用 [`kordoc`](https://github.com/chrisryugj/kordoc) 将 HWP/HWPX/PDF 转换为 Markdown 后提取 "其他/其他设施" 行。**
- 如果조례 未找到或条款/별표 解析失败,则始终会显示 **国家法律上限** 作为单独的行。 在表格中,将显示 (法律)/(조례) 两行,如果조례 查询失败,则在조례 行中显示失败原因。
- 可以通过响应中的 `地方自治团体조례_查询` 字段确认每个项目的查询成功与否。
- 如果已经在使用 `korean-law-mcp`,由于是不同的进程,因此无法共享密钥,需要为 cadastral-mcp 单独设置 `LAW_OC`。
## 国家法律实时查询(容积率/建筑面积比率)- `lib/national-law.ts`
- 与조례一样,**每次请求都直接调用法制处 API** ,读取 국토계획법 시행령 第 84 条(建筑面积比率)和第 85 条(容积率)的原文 - 即使施行令修订,也能自动反映最新值,无需修改代码。
- 条款标题(例如“建筑面积比率”关键词)可能与其他条款混淆,因此通过条款编号(第 84 条/第 85 条)准确查找。 条款编号即使法律修订也很少更改,是一个稳定的引用。
- 容积率(第 85 条)与조례 不同,规定为 **范围** (具体数值为地方自治团体 조례 在此范围内确定),因此与조례 单个值提取不同,范围直接提取。
- 绿化(建筑法施行令第 27 条)实际上是一个“免除绿化措施对象”列表,而不是绿化面积百分比表 - 在国家法律层面上没有统一的绿化比率表,而是全部委托给地方自治团体建筑조례,因此仅确认绿地区是否免除,其他则使用静态指南文本(“根据面积和用途有不同的标准 - 需要确认조례”)。 这并不是过时的值,而是国家法律中没有此值的事实。
- 停车(停车场法施行令 별표1)未实现实时查询 - 별표 与条款不同,没有항/호/목 结构,而是来自 HWP 的固定宽度文本,因此难以稳定解析。 使用已验证的固定值(`lib/zoning-standards.ts`)继续。
## 国家法律自由查询 - `search_national_law` / `get_national_law_text`
- 公开用于 `export_land_report_dxf` 流水线内部使用的与法制处 API 客户端(`lib/national-law-api-client.ts`)的工具。
- 使用 `search_national_law(query)` 搜索法律名称以获取 MST(法律序列号),然后使用 `get_national_law_text(mst, jo?)` 查询条款。 如果未指定 `jo`,则仅返回条款目录(编号+标题)以减小响应大小。 如果指定 `jo`(例如 `"84"`,`"第84条"`,`"12之2"`),则返回整个条款文本。
- 不包括判例·审决例·法律术语·条约等 - 只实现了 `target=law`(法律)一种类型。 如果需要超出此范围的法律调查,请同时使用 `korean-law-mcp`(无需运行时依赖 - 参见下面的“与 korean-law-mcp 的关系”)。
## 与 korean-law-mcp 的关系
cadastral-mcp **引用** 了 [`korean-law-mcp`](https://github.com/chrisryugj/korean-law-mcp) 但 **完全没有运行时依赖** - 不在 `package.json` 中,也不需要 korean-law-mcp 在运行时启动。 cadastral-mcp **直接** 调用法制处开放 API(대한민국 정부가 공개한 표준 API - `target`/`OC`/`MST` 等参数规约由政府制定,而不是 korean-law-mcp 的创作)。
然而,法制处 API 如果没有 UA/Referer 头部则会拒绝,并对云 IP 使用 JavaScript 重定向伪装的反机器人页面。 这个绕过逻辑(`lib/law-antibot.ts`)是从 korean-law-mcp 借鉴的,在 MIT 许可下 - 在 `LICENSE` 文件中已注明出处。 本存储库处理的范围(地方自治团体 조례 + 国家法律条款,不包括判例·法律术语等)比 korean-law-mcp 窄得多,并且仅实现了 cadastral-mcp 的地籍图/土地利用计划流水线所需的部分。
## 数据来源
- 地籍边界·地号·公示地价:VWorld 2D 数据 API (`req/data`, layer `LP_PA_CBND_BUBUN` - 连续地籍图)。原始数据由 국토교통부/한국국토정보공사(LX)管理的连续地籍图(数値地籍)数据,VWorld 通过 REST API 提供服务。 不直接读取 shp 文件。
- 土地登记簿·用途区域/地区:VWorld 国家重点(NED)API (`ned/data/ladfrlList`, `ned/data/getLandUseAttr`)
- 个别公示地价:VWorld 国家重点(NED)API (`ned/data/getIndvdLandPriceAttr`)
## 已知限制
- 空洞(洞穴)形状的地块在逻辑上受支持,但未在实际使用案例中验证。
- DXF 仅供参考,不具有法律效力的地籍测量成果图。
- 由于 VWorld 数据更新周期(通常为每月),可能不是实时最新的。
- `export_land_report_dxf` 的 XCLIP 已在 `ezdxf.audit()` 结构验证(无错误,`has_extension_dict`/`has_clipping_path` 正常)以及实际 AutoCAD 中打开并正常运行(框外地块裁剪)得到确认。
- 如果系统中安装了多个 Python 版本,并且其中一个没有 ezdxf,则需要用 `CADASTRAL_PYTHON` 指定路径。
- 地方自治团体 조례 自动查询遵循 "{市} 城市规划 조례"/"{市} 建筑 조례"/"{市} 停车场 조례" 名称模式和 21 个用途区域表格格式(例如“生产绿地区:20%”)。 由于地方自治团体마다 조례 名称和表示方式不同,部分地区可能会匹配失败,仅显示国家法律上限行。
- 별표 HWP 解析(kordoc)由于文档格式多样,不保证 100% 成功。 如果失败,则仅显示章节编号和별표编号(不构造数值)。
- 国家法律容积率/建筑面积比率实时查询(`lib/national-law.ts`)基于 **条款编号** 稳定这一假设。 如果法律修订删除或移动此条款,实时查询将失败(→ 静默回退到固定值),但固定值本身不会自动反映法律修订。
- 国家法律停车标准(停车场法施行令 별표1)未实现实时查询 - 별표 与条款不同,没有항/호/목 结构,而是来自 HWP 的固定宽度文本,因此难以稳定解析。 使用已验证的固定值(`PARKING_STANDARD_CELL`)继续。
## 开发
```bash
npm run watch # TypeScript 监视构建
npm run typecheck # 仅类型检查
npm test # vitest
```
测试在不进行网络调用的情况下仅验证纯逻辑 - 地方自治团体 조례 解析(`local-ordinance.test.ts`,实际使用中发现的错误),国家法律上限固定值(`zoning-standards.test.ts`),国家法律实时查询解析(`national-law.test.ts`,范围表示提取·条款分支编号处理等)。 API 连接本身(VWorld/法制处/XCLIP)使用实际密钥手动验证。