[[20220111111811]] 『2地点間が最短距離となる組み合わせの求め方』(pon) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『2地点間が最短距離となる組み合わせの求め方』(pon)

お世話になります。

例としてですが、
生徒の住所録データ(緯度経度情報有)と、避難場所データ(緯度経度情報有)があった場合、
A君にとって最短距離である避難場所は○○公園、
B君にとって最短距離となる避難場所は○○体育館、というように、
最も近い避難場所を求める方法をご教授頂きたいです。

実際のデータでは、住所録に相当するデータは1,500行程、避難場所データは15,000行程あります。

宜しくお願い致します。

< 使用 Excel:Excel2016、使用 OS:Windows10 >


データ例を示しなさい
(ah) 2022/01/11(火) 11:39

普通は各自治体内の避難場所に行くでしょうからマクロで

生徒の市町村を取得
それに該当する避難所を取り出す
単純に三平方で距離を出す
最小値を出した避難所を表示

って所でしょう
(ゆうっと) 2022/01/11(火) 12:59


ご返答ありがとうございます。
データとしては下記のようになっております。
住所録のF列に避難場所名を表示したいと思っています。
マクロ迄お教え頂けますと大変助かります。
宜しくお願い致します。

【住所録】1,500行程
  A   B  C         D       E
1 番号 名前 住所        緯度(10進法) 経度(10進法)
2  1  太郎 ○○県○○市〇-〇 39.-----    139.-----
3  2  次郎 △△県△△市△-△ 40.-----    140.-----
4  3  三郎 □□県□□市□-□ 41.-----    141.-----

【避難場所】15,000行程
  A   B     C         D       E
1 番号 名前    住所        緯度(10進法) 経度(10進法)
2  1  ○○公民館 ○○県○○市〇-〇 39.-----    139.-----
3  2  △△体育館 △△県△△市△-△ 40.-----    140.-----
4  3  □□大広場 □□県□□市□-□ 41.-----    141.-----
(pon) 2022/01/11(火) 14:03


 2点間の距離を緯度経度座標から求めるのはそれなりに大変です。
 求める精度によっては簡便な式も使えますが。

 こういうWeb上のサービスを活用してはどうでしょう
https://vldb.gsi.go.jp/sokuchi/surveycalc/main.html

 2.距離と方位角の計算 というのが使えると思います。
 ファイルで一括計算もできるので、
 1. Excelで入力用ファイルを作成
 2. Web上のサービスで距離計算
 3. 出力ファイルを読み込んで、最短距離を抽出

 1500☓15000行の入力ファイルをちゃんと処理してくれるかどうかはわかりませんが

 または、QGISみたいなオープンソースのGISソフトを使う方法もあります
 QGISは普段使ってないので、ぱっとできるかどうかはわかってませんが
(´・ω・`) 2022/01/11(火) 14:46

 上で紹介のサイトで、緯度経度座標を平面直角座標に変換してから
 普通に算術計算で距離を算出するというのがいいかもしれません
 注意点は系番号を適切に選択する必要があることです
(´・ω・`) 2022/01/11(火) 14:59

 単純な疑問ですが、直線距離でいいんですか?
(´・ω・`) 2022/01/11(火) 15:16

(´・ω・`)様

ご返答ありがとうございます。
お教え頂いたサイトを確認致しました。
2.距離と方位角の計算 では、
1対多 の計算が出力されるようで、多対多 での最適な組合せは取得できないようです。

経路距離であればベストですが、こだわりがあるわけではありません。
まずは最寄りの避難場所を取得したいというのが第一です。
(pon) 2022/01/11(火) 15:49


 >1対多 の計算が出力されるようで
 1行に出発地と目的地を書き込むので、1対1です。

 >多対多 での最適な組合せは取得できないようです
 そうです
 それがなにか?

 必要な計算の組み合わせを全部入力ファイルにいれればいいですよね
 自分の目的に完全に適応するサービスがないとできないとか考えないで工夫しましょう
(´・ω・`) 2022/01/11(火) 16:15

独り言です。
むかし、市内地図をブロックに分け、
二つの地点間の最短距離を出す、という
のをマクロで行おうとしたことがあり
ます。
隣り合うブロック間はブロックの真ん中と
真ん中を結ぶ直線上を移動、としました。

しかし、出た答えを実際の地図に当てはめる
と、隣り合うブロックでも実際は間に崖(下手
するとブロックの中にも崖)があったり、一方
通行で進めない方向だったりといろいろ不具合
があり断念しました。
(OK) 2022/01/11(火) 16:21


 距離自体の精度は不要なので、ざっくり一番近い場所だけわかればいいとして
 緯度経度から距離を求める場合に、一番問題なのは 
 緯度1度と経度1度の距離が違うことです。

 例えば、真東に経度1度の場所と真北に緯度1度の場所では、 
 真東に経度1度の場所のほうが近い

 対象地域近辺の緯度で、経度1度あたりの距離と緯度1度あたりの距離を
 ざっと計算してから三平方の定理つかったら、
 最短距離の場所の概算としてはそこそこいけるんじゃないでしょうか

 道路上の経路に沿った距離を出すのはもっともっと大変ですよね
(´・ω・`) 2022/01/11(火) 16:27

 連投失礼ます。最後にします。

 C# とか VB.Net とか使うなら、標準で距離計算の関数があるんですが
https://docs.microsoft.com/ja-jp/dotnet/api/system.device.location.geocoordinate.getdistanceto

 上記の関数では、Haversineの式が使われているようなので、
 自分で計算式を組むことも可能です。
https://ja.wikipedia.org/wiki/%E5%A4%A7%E5%86%86%E8%B7%9D%E9%9B%A2
https://en.wikipedia.org/wiki/Haversine_formula
(´・ω・`) 2022/01/11(火) 16:45

 地道に距離を測り最短を求めれば

 Option Explicit
 Sub Test()
    Dim lat1 As Double      '出発点緯度
    Dim lon1 As Double      '出発点経度
    Dim lat2 As Double      '到達点緯度
    Dim lon2 As Double      '到達点経度
    Dim i As Long, j As Long

    For i = 2 To 1500
        lat1 = Worksheets("住所録").Cells(i, "D").Value             '緯度
        lon1 = Worksheets("住所録").Cells(i, "E").Value             '経度
        For j = 2 To 15000
            lat2 = Worksheets("避難場所").Cells(j, "D").Value       '緯度
            lon2 = Worksheets("避難場所").Cells(j, "E").Value       '経度
            MsgBox Worksheets("住所録").Cells(i, "B").Value & " ⇔ " & _
            Worksheets("避難場所").Cells(j, "B").Value & vbCrLf & _
            "距離:" & Round(DAVIDLATLON(lat1, lon1, lat2, lon2), 4) & " ?q"
Exit Sub
        Next
    Next
 End Sub
 Function DAVIDLATLON(lat1, lon1, lat2, lon2)
    DAVIDLATLON = ArcCos(Cos(Application.WorksheetFunction.Radians(90 - lat1)) * _
                        Cos(Application.WorksheetFunction.Radians(90 - lat2)) + _
                        Sin(Application.WorksheetFunction.Radians(90 - lat1)) * _
                        Sin(Application.WorksheetFunction.Radians(90 - lat2)) * _
                        Cos(Application.WorksheetFunction.Radians(lon1 - lon2))) * 6371
 End Function
 Function ArcCos(RadAngle)
    ArcCos = Atn(-RadAngle / Sqr(-RadAngle * RadAngle + 1)) + 2 * Atn(1)
 End Function

 参考URL https://komoriss.com/calculate-distance-between-two-points-from-latitude-and-longitude/

(ピンク) 2022/01/11(火) 16:52


 OKさんの回答にもありすますが、実際は崖や川や池や鉄道や私有地など通れない所がありますので、直線距離ではあまり実用的ではないと思います。特に避難場所のような命にかかわるようことには。

 やるとするなら、グーグルマップでルート検索してその経路距離を取得するという方法がいいのではないでしょうか。例えば、下記が参考になるかと。

 【エクセルVBA】googleマップを操作して距離をまとめて調べる! | しよろぐ
https://showhey-channel.com/vba_map/

(hatena) 2022/01/11(火) 17:09


質問者の言葉
>経路距離であればベストですが、こだわりがあるわけではありません。
>まずは最寄りの避難場所を取得したいというのが第一です。
(mno) 2022/01/11(火) 17:13

ピンク 様

ご返答ありがとうございます。頂いた内容を参考にさせて頂きます。
(pon) 2022/01/11(火) 17:30


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.