Files
keinasystem/document/03_データ仕様書.md
2026-02-15 10:56:50 +09:00

14 KiB
Raw Blame History

データ仕様書

📊 データ構造の全体像

このシステムで扱うデータは3種類

  1. 実圃場データ(吉田農地台帳.ods- 実際に作業する農地
  2. 共済マスタ(水稲共済細目用.ods- 申請書用の区画
  3. 中山間マスタ(中山間.ods- 申請書用の区画

紐付けの関係:

  • 実圃場 → 共済区画: M対1複数の実圃場が1つの共済区画に対応
  • 実圃場 → 中山間区画: M対1複数の実圃場が1つの中山間区画に対応
erDiagram
    実圃場 }o--|| 共済区画 : "紐づく(M:1)"
    実圃場 }o--|| 中山間区画 : "紐づく(M:1)"
    実圃場 ||--o{ 作付け計画 : "持つ(1:N)"
    
    実圃場 {
        int id PK
        string 名称
        string 住所
        float 面積_反
        string 地主
        int 細目_耕地番号 "共済紐付けキー"
        int 細目_分筆番号 "共済紐付けキー"
        int 中山間_ID "中山間紐付けキー"
    }
    
    共済区画 {
        int id PK
        string 地名_地番
        int 耕地番号
        int 分筆番号
        float 本地面積_m2
        string 漢字地名
    }
    
    中山間区画 {
        int id PK
        int ID
        string 大字
        string 字
        int 地番
        int 農地面積_m2
        int 交付金額
    }
    
    作付け計画 {
        int id PK
        int 実圃場_id FK
        int 年度
        string 作物
        string 品種
        date 播種日
        date 収穫日
    }

1. 実圃場データ(吉田農地台帳.ods

ファイル情報

  • 行数: 39行39筆の圃場
  • 列数: 7列

カラム定義

カラム名 データ型 必須 説明
名称 string 圃場の名称(自由記述) "口神 1反2畝"
住所 string 圃場の住所 "口神笹ヶ谷374-1)"
面積(反) float 面積(単位: 反※1反=1000m2=10a 1.20
地主 string 地主の氏名 "山崎 出祥"
細目_耕地番号 int 共済マスタとの紐付けキー1/2 2
細目_分筆番号 int 共済マスタとの紐付けキー2/2 1
中山間_ID int 中山間マスタとの紐付けキー 50

データサンプル

名称             住所                         面積(反)  細目_耕地番号  細目_分筆番号  中山間_ID
口神 1反2畝    口神笹ヶ谷374-1)     1.20          2            1            50
口神 北東        口神笹ヶ谷374-1)     0.40          2            2            50
口神 北中        口神笹ヶ谷374-1)     0.43          2            2            50

特記事項

  • 中山間_IDは一部NULL: 39筆中2筆が中山間の対象外NaN
  • 同じ共済区画に複数の実圃場: 例えば共済キー「2-2」には3つの実圃場が紐づく
  • 面積単位: DB内部では「反」と「m2」の両方を保持する変換: 1反=1000m2

2. 共済マスタ(水稲共済細目用.ods

ファイル情報

  • 行数: 31行31区画
  • 列数: 5列

カラム定義

カラム名 データ型 必須 説明
地名 地番 string 地名と地番(スペース区切り) "四万十町 ササガタニ 374-1"
耕地番号 int 共済区画の識別子1/2 2
分筆番号 int 共済区画の識別子2/2 1
本地面積 (m2) float 申請上の面積(単位: m2 25.4
漢字地名 string 漢字表記の地名 "四万十町 笹ヶ谷 374-1"

データサンプル

地名 地番                  耕地番号  分筆番号  本地面積(m2)  漢字地名
四万十町 ササガタニ 374-1      2        1        25.4      四万十町 笹ヶ谷 374-1
四万十町 ササガタニ 374-1      2        2        12.0      四万十町 笹ヶ谷 374-1

特記事項

  • 面積の不整合は許容: 役場データが古いため、実圃場の合計面積と一致しないことがある
    • 例: 共済キー「2-2」の面積は12.0m2だが、実圃場の合計は1.33反=1330m2
    • これは「そういうもの」として扱い、システム側で修正しない
  • 重複キーなし: (耕地番号, 分筆番号)の組み合わせは一意

3. 中山間マスタ(中山間.ods

ファイル情報

  • 行数: 71行71区画
  • 列数: 17列うち使用するのは一部

カラム定義(主要なもの)

カラム名 データ型 必須 説明
ID int 中山間区画の識別子 50
大字 string 大字名 "口神ノ川"
string 字名 "壱町切"
地番 int 地番 1694
農地面積 int 面積(単位: m2 2900
作付け品目 string (役場が記入、システムでは上書き) "ニラ"
交付金額 int 交付金額 37700

データサンプル

ID  大字      字      地番   農地面積  作付け品目  交付金額
50  口神ノ川  笹ヶ谷  374     2698     米         xxxxxx

特記事項

  • 使用する列は限定的: システムでは主に「ID」「大字」「字」「地番」「農地面積」を使用
  • 作付け品目は上書き: 役場が記入した「作付け品目」は参考情報で、システムで上書きする
  • 面積の不整合は許容: 共済マスタと同様、実圃場との差異は受け入れる

4. 作付け計画データ(システム内部)

テーブル定義

カラム名 データ型 必須 説明
id int 主キー(自動採番)
field_id int 実圃場ID外部キー
year int 年度2025など
crop string 作物(「米」「トウモロコシ」など)
variety string 品種(「にこまる」など)
planting_date date 播種日/定植日Phase 2
harvest_date date 収穫日Phase 2
notes text 備考

制約

  • ユニーク制約: (field_id, year) - 1つの圃場に対して1年度につき1つの作付け計画のみ
    • Phase 2で二毛作対応する場合は、この制約を見直す

5. 作物マスタ

作物リスト

  • トウモロコシ
  • エンドウ
  • 野菜
  • その他

品種の登録方法

すべての作物で統一されたUI:

  • プリセット品種から選択
  • その場で新しい品種を追加可能
  • 作物による操作の違いなし

プリセット品種の例

  • にこまる
  • たちはるか
  • たちはるか(特栽)

トウモロコシ

  • (ユーザーが追加)

エンドウ

  • 久留米豊

野菜

  • (ユーザーが追加)

その他

  • 完全休耕
  • 緑肥(ヘアリーベッチ)
  • 緑肥(レンゲ)
  • 景観作物(コスモス)
  • 景観作物(ヒマワリ)

実装上の注意

  • すべての作物で Variety テーブルに品種を登録
  • 「作付けしない」系を特別扱いしない
  • UIは完全に統一

6. データインポート仕様

初期セットアップ時

  1. 共済マスタのインポート

    • 水稲共済細目用.ods を読み込み
    • OfficialKyosaiField テーブルに保存
  2. 中山間マスタのインポート

    • 中山間.ods を読み込み
    • OfficialChusankanField テーブルに保存
  3. 実圃場データのインポート

    • 吉田農地台帳.ods を読み込み
    • Field テーブルに保存
    • 同時に共済・中山間マスタとの紐付けを確立:
      • 細目_耕地番号 + 細目_分筆番号OfficialKyosaiField.id を外部キーとして保存
      • 中山間_IDOfficialChusankanField.id を外部キーとして保存

紐付けロジック

# 共済マスタとの紐付け
kyosai_record = OfficialKyosaiField.objects.get(
    k_num=row['細目_耕地番号'],
    s_num=row['細目_分筆番号']
)
field.kyosai_field_ref = kyosai_record.id

# 中山間マスタとの紐付け
if pd.notna(row['中山間_ID']):
    chusankan_record = OfficialChusankanField.objects.get(
        c_id=int(row['中山間_ID'])
    )
    field.chusankan_field_ref = chusankan_record.id

7. 申請書PDF出力ロジック

水稲共済細目書

出力形式:

  • A4サイズ、縦向き
  • ヘッダー: 「水稲共済細目書(◯◯年度)」
  • 表形式(罫線あり)
  • フォントサイズ: 10pt
  • ページ番号(複数ページの場合)

表の列:

耕地番号 | 分筆番号 | 地名地番 | 漢字地名 | 本地面積(m2) | 作付品目 | 品種 | 備考
   1    |    1    | 四万十町... | 四万十町... |    2.2      |  米  |にこまる|
   2    |    1    | 四万十町... | 四万十町... |   25.4      |  米  |にこまる|
   2    |    2    | 四万十町... | 四万十町... |   12.0      |米,野菜|にこまる,トマト|複数圃場

集計ロジック:

def generate_kyosai_pdf(year):
    # 1. データ集約CSVと同じロジック
    output_rows = []
    for kyosai in OfficialKyosaiField.objects.all().order_by('k_num', 's_num'):
        fields = Field.objects.filter(kyosai_field_ref=kyosai.id)
        plans = Plan.objects.filter(field__in=fields, year=year)
        
        crops = list(set([p.crop.name for p in plans if p.crop]))
        varieties = list(set([p.variety.name for p in plans if p.variety]))
        
        row = {
            '耕地番号': kyosai.k_num,
            '分筆番号': kyosai.s_num,
            '地名地番': kyosai.address,
            '漢字地名': kyosai.kanji_name,
            '本地面積(m2)': kyosai.area,
            '作付品目': ','.join(crops) if crops else '未設定',
            '品種': ','.join(varieties) if varieties else '',
            '備考': f'{len(fields)}筆合算' if len(fields) > 1 else ''
        }
        output_rows.append(row)
    
    # 2. HTMLテンプレートで表を生成
    html = render_to_string('reports/kyosai_template.html', {
        'year': year,
        'rows': output_rows
    })
    
    # 3. HTML → PDF変換
    pdf = HTML(string=html).write_pdf()
    return pdf

HTMLテンプレート例reports/kyosai_template.html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <style>
        @page { size: A4; margin: 2cm; }
        body { font-family: "MS Gothic", monospace; font-size: 10pt; }
        h1 { text-align: center; font-size: 14pt; margin-bottom: 20px; }
        table { width: 100%; border-collapse: collapse; }
        th, td { border: 1px solid black; padding: 5px; text-align: center; }
        th { background-color: #f0f0f0; }
    </style>
</head>
<body>
    <h1>水稲共済細目書({{ year }}年度)</h1>
    <table>
        <thead>
            <tr>
                <th>耕地番号</th>
                <th>分筆番号</th>
                <th>地名地番</th>
                <th>漢字地名</th>
                <th>本地面積(m2)</th>
                <th>作付品目</th>
                <th>品種</th>
                <th>備考</th>
            </tr>
        </thead>
        <tbody>
            {% for row in rows %}
            <tr>
                <td>{{ row.耕地番号 }}</td>
                <td>{{ row.分筆番号 }}</td>
                <td>{{ row.地名地番 }}</td>
                <td>{{ row.漢字地名 }}</td>
                <td>{{ row.本地面積(m2) }}</td>
                <td>{{ row.作付品目 }}</td>
                <td>{{ row.品種 }}</td>
                <td>{{ row.備考 }}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
</body>
</html>

中山間交付金申請

出力形式:

  • A4サイズ、縦向き
  • ヘッダー: 「中山間地域等直接支払交付金(◯◯年度)」
  • 表形式(罫線あり)

表の列:

ID | 大字 | 字 | 地番 | 農地面積(m2) | 作付品目 | 品種 | 備考
50 | 口神ノ川 | 笹ヶ谷 | 374 | 2698 | 米,野菜 | にこまる,トマト | 7筆合算

集計ロジック:

  • 水稲共済と同様、中山間マスタをループして実圃場を集約 → HTMLテンプレート → PDF

8. データ移行・メンテナンス

年度更新

  • 圃場マスタ: 年度をまたいで共通(更新不要)
  • 作付け計画: 年度ごとに独立(前年度コピー機能で複製)

マスタデータの更新

  • 共済・中山間マスタ: 役場から新しいファイルをもらった場合、再インポート
    • 既存データは上書きせず、差分を確認してマージ
    • または、全削除→再インポートの2段階処理

バックアップ

  • 全テーブルをCSV/Excelでエクスポート可能にする
  • 最低5年分のデータを保持補助金監査対応

9. 面積単位の扱い

システム内部では以下のように統一:

表示単位 DB保存 変換式
反(たん) m2 1反 = 1000m2
アールa m2 1a = 100m2
ヘクタールha m2 1ha = 10000m2

実装方針:

  • DB内部は全て m2 で保存(整数型)
  • 表示時にユーザー設定に応じて変換(デフォルトは「反」)
  • 入力時は「反」で受け付け、内部で m2 に変換

10. データ整合性チェック

チェック項目

  1. 紐付けの存在確認

    • 実圃場の 細目_耕地番号/細目_分筆番号 が共済マスタに存在するか
    • 実圃場の 中山間_ID が中山間マスタに存在するか
  2. 面積の整合性(参考情報)

    • 1つの共済区画に紐づく実圃場の合計面積と、共済マスタの面積を比較
    • ⚠️ 不整合があっても警告のみ(修正はしない)
  3. 作付け未設定の検出

    • 指定年度で作付け計画が未設定の圃場をリストアップ

実装

  • インポート時にバリデーションを実行
  • 管理画面で「データ整合性レポート」を表示