投稿の動機について
愛知県内小規模消防本部に勤務する50代半ばの公務員です。
コロナ以降、当本部においても、救急需要が増加しています。
消防本部の管轄を超えて、救急隊の配置を最適化することについて考察しました。
この場を借りて発表したいと思います。
引用データと、その取扱い、使用するソフトについて
個人の資格で発表しますのでデータはすべて、オープンデータを利用しました。
救急隊が配置されていない、消防署出張所もありますが、
救急隊の配置を動的に変化する 施策を行っている本部もあること、
消防隊が現場に出動する活動もあるため、救急隊が配置されていない
署所もpointとして取り上げます。
- 国土技術政策総合研究所都市開発研究部提供「将来人口・世帯予測ツールV3」
- 国土数値情報ダウンロードサイト 消防署2012版
- 年齢別人口当たりの救急搬送率__資料からデータを抽出しました
- https://www.fdma.go.jp/singi_kento/kento/items/kento019_09_8.pdf
- 令和6年愛知県消防統計
- https://www.pref.aichi.jp/uploaded/attachment/555652.pdf
- PostGIS データの生成、クラスタリング
- Qgis OpenStreetMap データの可視化
- 1kmメッシュ
平成27年愛知県消防署出張所配置状況
算出方法の方針
1. 1kmメッシュ毎に人口予測を行い、救急搬送者予測数を計算する
2. 予測された救急搬送者を、範囲内にポイントとしてランダムプロットする
3. ポイントを内包、管轄する消防本部内の最近傍署所との直線距離を計算する
4. ポイントと最近傍の署所の直線距離を管区を考慮せずに計算する
5. ST_Clusterkmeansを使用し、クラスタリングを行う
6. クラスター毎に重心を計算する ST_Centroid
7. クラスター毎に、重心と内包するポイントを結ぶ直線距離を計算する
8. 既存署所数から数を減らしながら、最適な署所数を判断する
9. クラスター間の偏りを補正する
10. クラスターに対しサブクラスタリングをさらに行う
11. サブクラスターの重心からポイントまでの距離を計算し合計する
12. 3、4,11の距離を比較し、署所配置の見直しの効果を測定する
1 メッシュごとの人口予測と、救急搬送者数
「将来人口・世帯予測ツールV3」を使用し100mメッシュ毎の人口を予測する。
令和12年の人口予測を基に、データを作成します。管轄する市町村はこの時期に
救急需要のピークを迎えるため選択しました。
管轄する市町村は過疎地域であり、0.5未満は誤差として処理されるため、1kmメッシュ毎にまとめました。
「将来人口・世帯予測ツール」マニュアルの出力仕様を確認。
救急搬送者予測数 = 令和12年5歳階級別人口予測 × 5歳階級別救急搬送率
1kmメッシュ毎に令和12年救急搬送者予測ができました。
2救急搬送者予測をポイントとしてランダムプロットする
救急出場は、道路沿いと想定できるが、市道まで網羅するオープンデータが見つかりませんでした。
精度の低下が予測されるますが、消防本部管轄域と1㎞メッシュポリゴンの交差域にランダムポイントを発生させました。
ST_GeneratePointsは「ポイントを発生させるGeom」、「発生させるポイント数」
の2つの引数を持ちます。
SELECT id,
(ST_Dump(ST_GeneratePoints
(e.geom,
(select point_counter from kmesh_qqpoint_counter WHERE id = e.id )))).geom
FROM kmesh_qqpoint_counter as e;
309,306件の救急出場予測ポイントを得ました。ユニークなidを割り振りなおします。
3 管轄する消防本部内の最も近い署所とポイントの距離を計算しまとめる。
現在、救急出場予測ポイントは管轄消防本部の情報を持ちません。
ST_Withinを使用し、予測ポイントを含む消防本部idを選び抽出します。
select q.sid,
r.city_code,
r.p17_005,
q.geom
from qqhansou_point_geom as q
left join aichi_fd_polygon as r
on ST_Within(q.geom, r.geom) order by city_code;
協定を結ぶ消防本部を除き、管轄を超えて救急出場は行いません。
管轄する消防本部内で最も近い署所を選び、直線距離を計算します。
select
distinct on (u.sid)
u.sid,
m.id as dept_id,
u.geom,
m.name,
(ST_DistanceSphere(u.geom, m.geom)/1000) AS dist
from qqhansou_point_geom As u left join aichi_fire_dep As m
on u.city_code = m.city_code
order by u.sid,
u.geom <-> m.geom;
救急出場予測ポイントと既存の消防署所をcity_codeでleft_joinします。
<->演算子を使用し、直線距離が短いものから並び替えます。
distinct on で最短のものを選びます。
4 ポイントと最近傍の署所の直線距離を管区を考慮せずに計算する
select
distinct on (u.sid)
u.sid,
m.id as dept_id,
u.geom,
m.name,
(ST_DistanceSphere(u.geom, m.geom)/1000) AS dist
from qqhansou_point_geom As u left join aichi_fire_dep As m
on ST_DWithin(u.geom, m.geom, 0.3)
order by u.sid,
u.geom <-> m.geom
;
先のコードとほぼ同じですが、left join の条件を
ST_DWithin(u.geom, m.geom, 0.3)に変更してあります。
数値0.3は随時変更してください。
大きすぎると計算時間がかかり、小さすぎるとjoin出来ずNullとなります。
5 ST_Clusterkmeansを使用し、クラスタリングを行う。
SELECT
sid
,ST_ClusterKMeans(geom, 40 )OVER() AS cluster_id
, geom
FROM qqhansou_point_geom;
6. クラスター毎に重心を計算する ST_Cntroid
SELECT
cluster_id
,ST_Centroid(ST_Union(geom)) as cgeom
from cluster_KMeans
group by cluster_id;
7. クラスター毎に、重心と内包するポイントを結ぶ直線距離を計算する
select
distinct on (u.sid)
u.cluster_id, m.cgeom,
(ST_DistanceSphere(u.geom, m.cgeom)/1000) AS dist
from cluster_kMeans As u left join center_cluster as m
on ST_DWithin(u.geom, m.cgeom, 1.0)
order by u.sid,
u.geom <-> m.cgeom;
8. 既存署所数から数を減らしながら、最適な署所数を判断する。
5,6,7のコードをwithでまとめます。
WITH cluster_KMeans AS(
SELECT
sid
,ST_ClusterKMeans(geom, 40 )OVER() AS cluster_id
, geom
FROM qqhansou_point_geom
),
center_cluster As(
SELECT
cluster_id
,ST_Centroid(ST_Union(geom)) as cgeom
from cluster_KMeans
group by cluster_id
),
cluster_dist As(
select
distinct on (u.sid)
u.cluster_id, m.cgeom,
(ST_DistanceSphere(u.geom, m.cgeom)/1000) AS dist
from cluster_kMeans As u left join center_cluster as m
on ST_DWithin(u.geom, m.cgeom, 1.0)
order by u.sid, u.geom <-> m.cgeom
),
cluster_count As(
select
cluster_id,
sum(dist) as sum_dist,
count(cluster_id) as counter
from cluster_dist
group by cluster_id
)
select
c.cluster_id,
c.sum_dist,
c.counter,
m.cgeom
from cluster_count as c left join center_cluster as m
on c.cluster_id = m.cluster_id
;
クラスター数の決定には、エルボー法、シルエット法があります。
厳密な計算は難しいので、グラフを作成し、推定します。
クラスター数は40,50周辺で減少が緩やかになります。
今回はクラスター数を40と決めます。
9. クラスター間の偏りを補正する
クラスター数を40に定め、8のコードを実行します。
kmeans法はクラスター間の重心距離の総計が最短になるようにクラスタリングを行います。
救急件数272件から18468件、直線総距離1726㎞から47397㎞と大きな偏りがあります。
補正方法として、クラスターをさらにサブクラスターに別けます。
救急隊の基準出場件数を決めます。
愛知県消防年報(令和6年版)データを基にします。
一年間の出場件数419,704を救急隊数248で割り1,692これを基準にします。

表について説明します。
- cluster_idは40個に分けられたクラスターの番号です
- sum_distはクラスターの中心からポイントまでの直線距離の合計です
- counterはクラスター毎のポイント数すなわち救急予想出場件数です
- cgeomはクラスターの中心の位置情報を表します
- counter_stdはcounterを基準で割り切り上げたものです
本来はsum_distを基準にクラスターを分割したいのですが、この情報にあたるものがオープンデータに無いため、counter_stdで代用します。サブクラスター数は合計で202となります。
10. 分割されたクラスターをクラスター毎にcounter_std数で分割します。
SELECT
sid
, cluster_id
, ST_ClusterKMeans(geom,counter_std)over(PARTITION BY cluster_id) AS cluster_sub_id
, sum_dist
, counter
, dist_std
, count_std
, geom
FROM qqhansou_geom_cluster_std;
これは5のコードと似ています。相違点は、
ST_ClusterKMeansの分割数がcounter_stdになっているところ
over()のカッコ内PARTITION by cluster_idとなっているところです。
cluster_idとcluster_sub_idを組み合わせてjoin_idとします。
文字列に変換して||で結合しました。より良い方法がありましたら、教えてください。
11. サブクラスターの重心からポイントまでの距離を計算し合計する。
8のコードに準じて、重心を計算し、join_id毎に現場到着までの直線距離を計算します。
WITH center_subcluster As(
SELECT
join_id
,ST_Centroid(ST_Union(geom)) as cgeom
from subcluster202_qqhansou2
group by join_id
),
subcluster_dist As(
select
distinct on (u.sid)
u.join_id, m.cgeom,
(ST_DistanceSphere(u.geom, m.cgeom)/1000) AS sub_dist
from subcluster202_qqhansou2 As u left join center_subcluster as m
on ST_DWithin(u.geom, m.cgeom, 0.2)
order by u.sid, u.geom <-> m.cgeom
),
subcluster_count As(
select
join_id,
sum(sub_dist) as sum_sub_dist,
count(join_id) as sub_counter
from subcluster_dist
group by join_id
)
select
c.join_id,
cast(c.sum_sub_dist as numeric(5,1)),
c.sub_counter,
m.cgeom
from subcluster_count as c left join center_subcluster as m
on c.join_id = m.join_id
;
FROM qqhansou_geom_cluster_std;
ここでjoin_idにより202に分割されたクラスターをボロノイド図で示します。
ポイント近くの数字は、予測される出場件数となります。
12. 直線距離総計を比較し、効果を検証する
3 消防本部管轄内最近傍署所と救急出場予測点までの直線距離総計 455046.2km
4 管轄所を越え、最近傍署所から救急出場予測点までの直線距離総計 431481.2㎞
11 クラスターで分割した重心から救急出場予測点までの直線距離総計 400162.4㎞
3,4は既存の消防署所213箇所からの直線距離総計です。
11は202か所からの直線距離です。10パーセント以上の削減効果があります。
検討課題
・より精度の高い検証を行うためには、愛知県下、消防本部の現場到着までの距離情報の提供を受ける必要があります。現場到着までの直線距離は、現場到着までの時間の近似値とみなせます。これを平準化できます。
・ 救急出場発生の可能性が高い、自動車が通行可能な道路のデータを得て、バッファーを発生し予測される救急出場場所をバッファー内に発生させることがきれば、より精度の高い予測となります。
結語
・オープンデータのみを使用したため、精度は不十分かもしれませんが、市区町村の境界を考慮しない署所の配置は、十分な効果があり、検討に値するものです。


