3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

国土交通データプラットフォームAdvent Calendar 2023

Day 15

どこから対応する?~全国道路施設点検データベース・道路交通センサス①~

Last updated at Posted at 2023-12-14

本記事は国土交通データプラットフォームアドベントカレンダー15日目の記事です。

はじめに

みなさん こんにちは

突然ですが全国道路施設点検データベース~ 損傷マップ ~をご覧になったことはありますでしょうか?

道路橋やトンネルなどの道路施設の点検結果について「健全性」「措置状況」のどちらかで絞り込みして該当する施設を地図上に表示することができます。

road-structures-map.mlit.go.jp_Map.aspx(iPad Pro) (2) (1).png

road-structures-map.mlit.go.jp_Map.aspx(iPad Pro) (1) (1).png

ですが「措置状況」が「措置未着手」かつ「健全性」が「Ⅳ(緊急措置)」または「Ⅲ(早期措置)」の施設を全て表示したいといったことは残念ながらできません。。。

そこで国交DPFのAPIの出番です。上記のようなAND/ORの条件を組み合わせてデータを取得することができますよ!

早速Pythonでやってみましょう。

ライブラリの読み込み

まず必要なライブラリを読み込みます。

import json

import folium
import pandas as pd
import requests

データを取得する関数の作成

次に国土交通データプラットフォームにリクエストを送信する関数を定義します。
リクエストボディに設定するGraphQLを引数で受け取り、結果を辞書型で返します。
(13日目で使用したものと同じですね!)

def send_request(query: str) -> dict:
    """_summary_

    Args:
        query (str): QraphQL query string

    Returns:
        dict: MLIT DPF API response
    """
    END_POINT: str = "https://www.mlit-data.jp/api/v1/"
    API_KEY: str = "enter your api key"

    response: requests.models.Response = requests.post(
        END_POINT,
        headers={
            "Content-type": "application/json",
            "apikey": API_KEY,
        },
        json={"query": query},
    )
    result: dict = json.loads(response.content)["data"]
    return result

リクエストボディの定義

検索APIのクエリ内容を定義します。
データカタログに「全国道路施設点検データベース」のIDを指定し、措置状況RSDB:tenken.syuzen.sochi_joukyouが「1:措置未着手」、健全性RSDB:tenken.kiroku.hantei_kubunが「3:早期措置」または「4:緊急措置」の施設を取得します。また今回は東京都のデータを取得するようにDPF:prefecture_code13のデータのみとしています。

graphql_query: str = """
{
  search(
    term: "",
    phraseMatch: true,
    first: 0,
    size: 10000,
    attributeFilter: {
      AND: [
        {
          attributeName: "DPF:catalog_id",
          is: "rsdb"
        },
        {
          attributeName: "DPF:prefecture_code",
          is: "13"
        },
        {
          attributeName: "RSDB:tenken.syuzen.sochi_joukyou",
          is: "1"
        },
        {
          OR:[
            {
              attributeName: "RSDB:tenken.kiroku.hantei_kubun",
              is: "3"
            },
            {
              attributeName: "RSDB:tenken.kiroku.hantei_kubun",
              is: "4"
            },
          ]
        }
      ]
    }
  ) {
    totalNumber
    searchResults {
      title
      lat
      lon
      metadata
    }
  }
}
"""

全国道路施設点検データベースデータの取得

準備ができたのでリクエストを送信します。
結果はJSONで返ってくるためDataFrameに変換します。

data: dict = send_request(query=graphql_query)
df: pd.DataFrame = pd.json_normalize(data["search"]["searchResults"])

不要な項目が多く、列名も長いので必要な項目に列名も変えます。

selected_columns: list = [
    "title",
    "lat",
    "lon",
    "metadata.RSDB:shisetsu_id",
    "metadata.DPF:object_category",
    "metadata.RSDB:shisetsu_kubun",
    "metadata.RSDB:tenken.nendo",
    "metadata.RSDB:tenken.kiroku.hantei_kubun",
    "metadata.RSDB:tenken.syuzen.sochi_joukyou",
]
renamed_data = df[selected_columns].rename(
    columns={
        "metadata.RSDB:shisetsu_id": "id",
        "metadata.DPF:object_category": "object_category",
        "metadata.RSDB:shisetsu_kubun": "shisetsu_kubun",
        "metadata.RSDB:tenken.nendo": "nendo",
        "metadata.RSDB:tenken.kiroku.hantei_kubun": "hantei_kubun",
        "metadata.RSDB:tenken.syuzen.sochi_joukyou": "sochi_joukyou",
    }
)
renamed_data.head()
title lat lon id object_category shisetsu_kubun nendo hantei_kubun sochi_joukyou
0 亀戸駅前歩道橋 35.6966 139.825 35.69658,139.82548 横断歩道橋 5 2022 4 1
1 栄町横断歩道橋 35.7479 139.475 35.74792,139.47456 横断歩道橋 5 2022 4 1
2 湯の浜橋 34.747 139.354 34.74699,139.35408 道路橋 1 2018 4 1
3 和泉橋 35.6971 139.775 35.69710,139.77548 道路橋 1 2020 4 1
4 西国分寺人道橋 35.7009 139.466 35.70086,139.46581 道路橋 1 2014 4 1

すっきりしました!

地図表示

では地図に表示してみましょう。

m = folium.Map(tiles="http://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png", attr="地理院タイル")
for i, row in renamed_data.iterrows():
    folium.CircleMarker(
        location=[row["lat"], row["lon"]], fill=True, radius=5, color="black", fill_opacity=1, fill_color="white"
    ).add_to(m)
m

folium (1).png

できました!

まとめ

本家の全国道路施設点検データベース 損傷マップでは確認が難しい複雑な条件でのデータの可視化について国交DPFのAPIを活用することで実現することができました。

今回取得した条件でも施設数が840件あり、どこから着手すべきかこれだけだと判断が難しいです。

そこで次回は道路交通センサスと組み合わせて交通量が多い施設を特定したいと思います。
それではまた明日!

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?