library(tidyverse)
library(sf)
library(tmap)
library(tmaptools)
library(units)国土数値情報とRを活用した交通空白地の抽出と人口分析
本ドキュメントは、クリエイティブ・コモンズ・ライセンス表示4.0国際(CC BY 4.0)ライセンスのもとで提供されています。 クリエイティブ・コモンズ・ライセンスについては、下記のサイトを参照してください。 クリエイティブ・コモンズ・ライセンス表示4.0国際
本ドキュメントは下記の著作物をもとに改変して作成しています: 国土交通省 政策統括官付 地理空間情報課(協力:総合政策局 地域交通課)「国土数値情報とQGISを活用した交通空白地の抽出と人口分析」(2025年4月) https://nlftp.mlit.go.jp/ksj/manual/QGIS_manual_01.htm (CC BY 4.0)
はじめに
この記事では、主に都市計画や交通政策を担当する自治体職員や公共交通事業者の方々を対象に、公共交通分野におけるデータに基づいた政策立案や事業評価を行うための基礎的な分析手法として、国土数値情報とRを活用した交通空白地の抽出と人口分析について解説します。
- 駅・バス停留所からの徒歩圏を基準としたエリアの作成
- 駅とバス停留所からの徒歩圏を基準として、公共交通便利地域・不便地域・空白地域の3つのエリアを作成します。
- 面積案分計算による公共交通空白地域内の人口算出
- メッシュ別将来推計人口データを公共交通空白地域で切り抜き、面積比率をもとに各メッシュの人口を算出します。 -将来推計人口データを活用して、公共交通空白地域内の将来人口推移を分析します。
これらの手法により、公共交通の利便性を客観的に評価でき、効果的な公共交通政策の立案や地域の交通課題への具体的な対策立案に活用できます。
- この記事は、Rの基本操作ができることを前提として書かれています。
「交通空白」の考え方
国土交通省では、全国各地でタクシー、乗合タクシー、日本版ライドシェアや公共ライドシェア等を地域住民や来訪者が使えない「交通空白」の解消に向けて早急に対応していくため、令和6年7月に「交通空白」解消本部を設置し、「地域の足」「観光の足」の確保を進めています。
「交通空白」の解消に向け、まずは全国各地の「交通空白」の状況を把握する必要があり、各自治体においては、地域の実情を考慮して個別の判断基準を設けつつ、利用者の声や協議会での議論を踏まえて、「交通空白」を判断することが必要となります。
国土交通省では、「交通空白」の考え方として、“何らかの対応が必要とされる、誰もがアクセスできる移動の足がない又は利用しづらいなど地域交通に係るお困りごとを抱える地域(必ずしも、地理的、空間的な交通空白地に限らない)”としており、各自治体における「交通空白」の判断にあたっては、画一的な指標による判断のみならず、対象となる利用者の属性、移動の支障となる地形条件等を考慮した判断が求められます。
この記事では、分析の一例として、交通空白地に一定の定義を設定して解説をしますが、上記のとおり、実際には各自治体が地域の実情を考慮して「交通空白」を個別に判断する必要があるということを留意してください。
また、自治体等が「交通空白」の解消を進めるための支援ツールの一つとして、地域公共交通計画の立案等にあたってのモビリティデータの活用方法等を紹介した「アップデートガイダンス Ver1.0」を作成しています(令和7年3月公表)。
「アップデートガイダンス Ver1.0」では、これから地域公共交通計画の作成や改訂に取り組む地方公共団体の職員等が、計画の意義やアップデートの進め方を理解して実践できるようにするため、モビリティデータを活用した計画作成(現状診断やKPI設定等)のポイントを解説しています。この記事とあわせてご活用ください。
(参考:地域公共交通計画の「アップデートガイダンスVer1.0」手順書より抜粋)

この記事における「交通空白」の設定
駅・バス停留所からの徒歩圏を基準としたエリア区分
この記事では、駅・バス停留所からの徒歩圏を基準にエリア区分を行い、当該エリアの人口を算出します。 この記事においては最寄駅・バス停留所からの徒歩圏をそれぞれ半径1,000 m圏内・半径500 m圏内と設定し、表のようにエリア区分を設定しました。
公共交通便利地域は、最寄駅から1,000 m圏内のエリア、公共交通不便地域は、最寄駅から1000 m圏外のエリアのうち、最寄バス停留所からは500 m圏内のエリア、公共交通空白地域は、最寄駅からも最寄バス停留所からも徒歩圏外のエリアです。また、公共交通空白地域については、将来推計人口データを用いて人口が存在するエリアのみを対象とします。

公共交通のサービス圏を視覚的に把握することで、人口分布や施設立地などの地域特性と組み合わせた分析が可能となります。 これにより、交通不便地域の特定や路線の再編、新規路線の検討など、地域の実情に即した効果的な政策立案や事業評価を行うことができます。また、将来の人口動態予測と組み合わせることで、中長期的な視点での公共交通サービスの在り方を検討することも可能です。
この記事では、例として、千葉県市原市を対象地域として分析をおこないます。 なお、千葉県市原市では、実際に交通空白地対策として、公共交通不便地域・公共交通空白地域の特定と、その解消に向けた施策が以前より取り組まれています(市原市における交通空白地域対策について〜地域住民との協働による取り組み〜(千葉県市原市 企画部交通政策課))。

250 mメッシュ別将来推計人口データについて
メッシュ別将来推計人口とは
メッシュ別将来推計人口データは、日本全国の領域を一定サイズのメッシュに区切り、各メッシュごとの人口を推計したデータセットです。

メッシュ単位データにより行政区域に縛られない空間での人口分析が可能で、地域ごとの詳細な人口動態を把握することができます。 特に、2025年2月に新規公開された250mメッシュは、従来の500 mメッシュの4分の1のサイズであり、より細かな単位で区切られているため、精緻な分析が可能になりました。
データには総人口だけでなく年齢階級別(0~14歳、15~64歳、65歳以上)の人口も含まれ、高齢化率や生産年齢人口の推移分析も可能です。
データのダウンロードと追加
国土数値情報ダウンロードサイトの250 mメッシュ別将来推計人口データにアクセスします。
ダウンロードしたい地域やファイル形式でデータを絞り込むと条件に合うデータセットが下部に表示されるので、[ダウンロード]をクリックするとデータをダウンロードすることができます。この記事では、千葉県とGeoJSON形式でデータを絞り込みました。

データのダウンロード時にアンケートが表示されたら、回答もしくは[スキップする]をクリックするとデータのダウンロードが開始されます。

同様の手順で、行政区域データ、バス停留所データ、鉄道データをダウンロードします。データに複数年版がある場合は、最新のものを選択してください。
ダウンロードしたZIPファイルを解凍し、解凍したデータのにあるGeoJSONファイルを、データフォルダに追加します。 鉄道データについては、駅名を属性に持つ「N02-24_Station.geojson」を追加してください。
以降では、ワーキングディレクトリに「data」という名前のデータフォルダがあるものとします。
GeoJSONファイルを、sf::read_sf関数を使って読み込みます。 分かりやすい変数名を設定しましょう。
region <- read_sf("data/N03-20250101_12.geojson")
population <- read_sf("data/250m_mesh_2024_12.geojson")
station <- read_sf("data/N02-24_Station.geojson")
bus_stop <- read_sf("data/P11-22_12.geojson")地図に表示してみます。
ksj_credit <- "国土数値情報を加工して作成"
tm_shape(region) + tm_polygons() +
tm_shape(population) + tm_polygons(col = "green") +
tm_shape(station) + tm_lines(col = "red", lwd = 5) +
tm_shape(bus_stop) + tm_dots(fill = "blue") +
tm_credits(ksj_credit, fontfamily = "BIZ UDPGothic")
データの加工
「250 mメッシュ人口データ」の読み込みに時間がかかったはずです。 これは、千葉県全体で44,082のメッシュが存在し、データ量が膨大なためです。 そのため、次のステップでは対象地域のデータに絞り込みます。
将来推計人口データの抽出
データのダウンロードページを確認すると、250 mメッシュ人口データは「SHICODE」という属性名で行政区域コードを属性情報として持っていることがわかります。 行政区域コードとは、市区町村を分類するための5桁のコードのことです。 データのダウンロードページからコードリストをダウンロードすることでコードを確認することができます。
市原市の行政区域コードは「12219」なので、「SHICODE」が「12219」の地物で絞り込むことで市原市のみのデータを抽出することができます。

Rでは、filter関数1を使って、データを絞り込むことができます。
population <- population |>
filter(SHICODE == "12219")これにより、市原市のメッシュデータのみが抽出されました。
行政区域データの抽出
同様に、行政区域データについても抽出作業を行います。 行政区域データのダウンロードページを確認すると、「N03_007」という属性が行政区域コードであることがわかります。

filter関数の引数に、N03_007 == "12219"を指定して実行すると、行政区域コードで対象の市区町村を絞り込むことができます。
region <- region |>
filter(N03_007 == "12219")市原市の行政区域データに、市原市のメッシュデータを重ねて表示してみましょう。
tm_shape(region) + tm_polygons() +
tm_shape(population) + tm_polygons(col = "green") +
tm_credits(ksj_credit, fontfamily = "BIZ UDPGothic")
駅・バス停留所データの抽出
将来推計人口データと行政区域データは属性情報で絞り込みが可能でしたが、鉄道データやバス停留所データには行政区域コードなどの属性情報がないため、「属性による抽出」での抽出ができません。
そのため、レイヤどうしの空間的な位置関係からデータを絞り込みます。 空間的な位置関係とは、「あるポリゴン内に含まれるポイント」や「ラインに接するポリゴン」のように、地物間の「含まれる」「接する」といった関係性を指します。
Rでは、sf::st_filter関数を使って、空間的なデータを絞り込むことができます。
station <- station |> st_filter(region)
bus_stop <- bus_stop |> st_filter(region)駅とバス停を重ねて地図にしてみます。
tm_shape(region) + tm_polygons() +
tm_shape(population) + tm_polygons(col = "green") +
tm_shape(station) + tm_lines(col = "red", lwd = 5) +
tm_shape(bus_stop) + tm_dots(fill = "blue") +
tm_credits(ksj_credit, fontfamily = "BIZ UDPGothic")
駅のポイントデータを作成
これまでの手順で、必要なデータを市原市域のみに絞り込むことができました。 しかし、stationデータのジオメトリ・タイプを確認してみると、それがラインデータ(LINESTRING)であることがわかります。 また、自治体によっては同一駅が複数のラインデータで構成されていることもあります。
st_geometry_type(station) [1] LINESTRING LINESTRING LINESTRING LINESTRING LINESTRING LINESTRING
[7] LINESTRING LINESTRING LINESTRING LINESTRING LINESTRING LINESTRING
[13] LINESTRING LINESTRING LINESTRING LINESTRING LINESTRING LINESTRING
[19] LINESTRING LINESTRING LINESTRING
18 Levels: GEOMETRY POINT LINESTRING POLYGON MULTIPOINT ... TRIANGLE
これは、元データがラインデータ形式であることと、ターミナル駅のように複数路線が乗り入れる駅では、同一名称であっても路線ごとに個別のデータが存在することが要因です。このままでは駅ごとの分析が難しいため、各駅を1つのポイントデータとして表現できるようにします。
gsi_tile <- "https://cyberjapandata.gsi.go.jp/xyz/pale/{z}/{x}/{y}.png"
ksj_gsi_credit <- "国土数値情報および地理院タイルを加工して作成"
station |>
filter(N02_005 == "五井") |>
tm_shape(bbox = bb(URLencode("五井駅"), width = 0.02, height = 0.01)) +
tm_lines(col = "red", lwd = 5) +
tm_basemap(gsi_tile) +
tm_credits(ksj_gsi_credit, fontfamily = "BIZ UDPGothic")
詳しい操作手順は「国土数値情報 地価公示データとRを活用した都市の地価分析」の記事で解説していますので、この記事では各駅をポイントデータとして抽出した結果のみをご紹介します。
station <- station |>
group_by(N02_005) |> summarise() |> st_centroid()
tm_shape(region) + tm_polygons() +
tm_shape(population) + tm_polygons(col = "green") +
tm_shape(bus_stop) + tm_dots(fill = "blue") +
tm_shape(station) + tm_dots(fill = "red") +
tm_credits(ksj_credit, fontfamily = "BIZ UDPGothic")
公共交通便利地域等のエリアの作成
データの投影変換
これまでの手順により、データの絞り込みと各駅のポイントデータの作成が完了しました。 これから駅やバス停留所の徒歩圏に基づくエリア区分を行いますが、正確な距離計算のためには、データの座標系を緯度経度からメートル単位の座標系に変換する必要があります。
ここでは、すべてのデータを、平面直角座標系IX系(EPSG:6677)に変換します。
region <- region |> st_transform(6677)
population <- population |> st_transform(6677)
station <- station |> st_transform(6677)
bus_stop <- bus_stop |> st_transform(6677)駅・バス停留所の徒歩圏バッファの作成
バッファとは、ポイントやライン、ポリゴンの周囲に一定の距離で領域を発生させる空間解析手法です。 今回は、駅とバス停留所の位置(ポイント)から指定した距離(駅は1,000 m、バス停留所は500 m)の円形の領域を作成します。
Rではsf::st_buffer関数でバッファを作成することができます。 また、sf::st_union関数を使って、重なり合うバッファ領域を1つの領域に統合しています。
station_buffer <- station |> st_buffer(1000) |> st_union()
bus_stop_buffer <- bus_stop |> st_buffer(500) |> st_union()
tm_shape(region) + tm_polygons() +
tm_shape(bus_stop_buffer) + tm_polygons(fill = "lightblue") +
tm_shape(station_buffer) + tm_polygons(fill = "pink") +
tm_shape(bus_stop) + tm_dots(fill = "blue") +
tm_shape(station) + tm_dots(fill = "red") +
tm_credits(ksj_credit, fontfamily = "BIZ UDPGothic")
公共交通便利地域の作成
この記事では、最寄駅の徒歩圏内のエリアを「公共交通便利地域」と定義しています。 これに伴い、「駅1,000 mバッファ」の名称を変更します。
high_access_area <- station_buffer公共交通不便地域の作成
この記事では、公共交通不便地域を「最寄駅の徒歩圏外」かつ「最寄バス停留所の徒歩圏内」と定義しています。 具体的には、「バス停留所500 mバッファ」の範囲から「公共交通便利地域(駅1,000 mバッファ)」を除いたエリアとなります。
このような2つの領域の重なり合わないエリアを算出するには「差分」機能を使用します。 Rでは、sf::st_difference関数で算出できます。
low_access_area <- st_difference(bus_stop_buffer, station_buffer)
tm_shape(region) + tm_polygons() +
tm_shape(low_access_area) +
tm_polygons(fill = "lightblue") +
tm_credits(ksj_credit, fontfamily = "BIZ UDPGothic")
公共交通空白地域の作成
この記事では、公共交通空白地域を「駅とバス停留所の両方から徒歩圏外にあるエリア」と定義しています。 人口推移を算出するため、公共交通空白地域から無人のエリアを除外します。 無人のエリアは、 250 mメッシュ人口データから公共交通便利地域と公共交通不便地域を除外することで抽出できます。
後の分析に用いるため、はじめにメッシュ人口データの面積を計算します。 Rでは、sf::st_area関数でポリゴンの面積を計算することができます。
population <- population |>
mutate(area = st_area(geometry)) 次に、公共交通空白地域を抽出します。
「250 mメッシュ人口データ」から「公共交通便利地域」と「公共交通不便地域」を差し引くことで、公共交通空白地域を特定します。 具体的には「250 mメッシュ人口メッシュ」から公共交通便利地域を差し引いたエリアを作成し、そのエリアから公共交通不便地域を除外することで、公共交通空白地域を抽出できます。
no_access_pop <- population |>
st_difference(high_access_area) |>
st_difference(low_access_area)
tm_shape(region) + tm_polygons() +
tm_shape(no_access_pop) + tm_polygons(fill = "orange")
最後に、エリア間の比較を容易にするため、250 mメッシュ人口メッシュと、公共交通便利地域と公共交通不便地域それぞれとの「交差」を計算します。 Rでは、sf::st_intersection関数で、交差を計算することができます。
high_access_pop <- st_intersection(population, high_access_area)
low_access_pop <- st_intersection(population, low_access_area)
tm_shape(region) + tm_polygons(fill = NULL) +
tm_shape(high_access_pop) + tm_polygons(fill = "lightblue") +
tm_shape(low_access_pop) + tm_polygons(fill = "lightgreen") +
tm_shape(no_access_pop) + tm_polygons(fill = "orange") +
tm_shape(bus_stop) + tm_dots() +
tm_shape(station) + tm_dots(fill = "red") +
tm_basemap(gsi_tile, zoom = 12) +
tm_credits(ksj_gsi_credit) +
tm_layout(
text.fontfamily = "BIZ UDPGothic",
legend.position = c("left", "bottom")) +
tm_add_legend(
labels = c("バス停留所", "駅"),
fill = c("black", "red"),
type = "dots") +
tm_add_legend(
labels = c("公共交通便利地域", "公共交通不便地域", "公共交通空白地域"),
fill = c("lightblue", "lightgreen", "orange"),
type = "polygons") 
結果を確認してみると、公共交通便利地域は市の中央部および北部の主要道路沿いに広がっており、公共交通不便地域は鉄道沿線から離れたエリアや幹線道路沿いに分布しています。 また、公共交通空白地域は、水田が広がる人口の少ないエリアや山間部に位置していることがわかります。
公共交通空白地域の人口推移の分析
最後に、公共交通空白地域の各メッシュで面積按分して、人口推移を分析します。 面積按分とは、あるエリアの面積比率に応じて数値を配分する手法です。 例えば、1平方キロメートルのメッシュに100人が居住している場合、そのメッシュの半分が公共交通空白地域に該当すれば、50人が公共交通空白地域に居住していると推計します。
面積按分は、次の計算式で行います。
\[ 面積按分後の人口 = メッシュ内人口 \times \frac{公共交通空白地域のメッシュの面積}{メッシュの元の面積} \]
この計算を対象メッシュに対して行うことで、公共交通空白地域における将来推計人口を算出することができます。
面積按分して算出した人口をもとに、2025年から2065年まで20年ごとの変化を比較します。 ここでは、2025年時点で按分後の人口が多い市原市北部を拡大して表示しています。
no_access_density <-
no_access_pop |>
mutate(
blank_area = st_area(geometry),
blank_ratio = units::drop_units(blank_area / area)
) |>
select(blank_area, blank_ratio, PTN_2025, PTN_2045, PTN_2065 ,geometry) |>
pivot_longer(starts_with("PTN_")) |>
mutate(projected_density = units::drop_units(value * blank_ratio / blank_area * 10000))
bbox <- st_bbox(
c(xmin = 140.05, ymin = 35.42, xmax = 140.22, ymax = 35.57), crs = st_crs(6668)
)
tm_shape(bbox = bbox) +
tm_shape(region) + tm_polygons(fill = NULL) +
tm_shape(no_access_density) +
tm_polygons(
lwd = 0.5, fill = "projected_density",
fill.scale = tm_scale_intervals(values = "brewer.reds"),
fill.legend = tm_legend_hide()
) +
tm_facets("name") +
tm_shape(bus_stop) + tm_dots(fill = "red", size = 0.15) +
tm_shape(station) + tm_dots(fill = "blue") +
tm_credits(ksj_credit, fontfamily = "BIZ UDPGothic")
このエリアでは、2025年から2065年にかけて人口が横ばいあるいは減少傾向を示す地域が多く見られます。 一方で、2065年時点においても人口密度が比較的高い(青色のメッシュが集中する)エリアが一部存在しており、こうした地域では、公共交通の整備について検討する必要性があると考えられます。
以上のことから、将来的には人口減少が進む地域が広範囲に及ぶことを踏まえ、需要に応じた公共交通サービス水準の再検討や、新たな交通手段の導入など、柔軟な交通政策の検討が重要であると示唆されます。
おわりに
この記事では、Rと国土数値情報で公開されているデータを活用して、地域公共交通サービスの利便性によるエリア区分を行い、公共交通空白地域における人口推移を面積按分によって算出する方法を解説しました。 公共交通行政におけるEBPMの促進に是非ご活用ください。
この記事の執筆に使用したパッケージとそのバージョンは以下の通りです。
| package | loadedversion | source |
|---|---|---|
| sf | 1.1-0 | CRAN (R 4.5.2) |
| tidyverse | 2.0.0 | CRAN (R 4.5.0) |
| tmap | 4.2 | CRAN (R 4.5.0) |
| tmaptools | 3.3 | CRAN (R 4.5.0) |
| units | 1.0-1 | CRAN (R 4.5.2) |
dplyr::filter関数と同じ感覚で使える、sfオブフェクト用の関数sf::filter.sfが定義されています。sfオブジェクトに対してfilter関数を使うと、自動的にsf::filter.sf関数が適用されます。↩︎