質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

3659閲覧

緯度経度を使用してある地点からある地点までの2点間距離を算出したいのですが、うまく計算ができません。どのようにしたらよいでしょうか?

yoda25

総合スコア14

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2020/05/06 10:33

表題のように2点間距離を算出したく、ネットで計算式を参考にしながら、プログラムを作成しております。ある1点は、直接打ち込んで緯度経度の座標を書き込み、もう1点は、csvファイルをテーブルとして読み込み、そこにある座標を使用したいと考えております。下記がテーブルファイルの一部抜粋です
イメージ説明
こちらにある座標データ(テーブルのlat,lon)を使用して、ある固定値との距離を算出し、その計算結果を最後の列に追加したいと考えております。下記のようなコードを書いたところ、リストが対応できないようなエラーメッセージが返ってきました。

python

1import os 2import numpy as np 3import math 4from math import * 5import pandas as pd 6 7os.chdir('C:/01_py-module/03_TL') 8#座標を入力 9lat = float(input('latを入力してください')) 10lon = float(input('lonを入力してください')) 11height = float(input('heightを入力してください')) 12#input_llh = input(lat, lon, height) 13#電子基準点リスト 14gcp_list = pd.read_csv("denshi_list.csv", encoding = 'shift_jis',header=0) 15gcp_list.head 16 17#2点間の距離計算 18# 楕円体 19ELLIPSOID_GRS80 = 1 # GRS80 20ELLIPSOID_WGS84 = 2 # WGS84 21 22# 楕円体ごとの長軸半径と扁平率 23GEODETIC_DATUM = { 24 ELLIPSOID_GRS80: [ 25 6378137.0, # [GRS80]長軸半径 26 1 / 298.257222101, # [GRS80]扁平率 27 ], 28 ELLIPSOID_WGS84: [ 29 6378137.0, # [WGS84]長軸半径 30 1 / 298.257223563, # [WGS84]扁平率 31 ], 32} 33 34# 反復計算の上限回数 35ITERATION_LIMIT = 1000 36 37''' 38Vincenty法(逆解法) 392地点の座標(緯度経度)から、距離と方位角を計算する 40:param lat1: 始点の緯度 41:param lon1: 始点の経度 42:param lat2: 終点の緯度 43:param lon2: 終点の経度 44:param ellipsoid: 楕円体 45:return: 距離と方位角 46''' 47def vincenty_inverse(lat1, lon1, lat2, lon2, ellipsoid=None): 48 49 # 差異が無ければ0.0を返す 50 if isclose(lat1, lat2) and isclose(lon1, lon2): 51 return { 52 'distance': 0.0, 53 'azimuth1': 0.0, 54 'azimuth2': 0.0, 55 } 56 57 # 計算時に必要な長軸半径(a)と扁平率(ƒ)を定数から取得し、短軸半径(b)を算出する 58 # 楕円体が未指定の場合はGRS80の値を用いる 59 a, ƒ = GEODETIC_DATUM.get(ellipsoid, GEODETIC_DATUM.get(ELLIPSOID_GRS80)) 60 b = (1 - ƒ) * a 61 62 φ1 = radians(lat1) 63 φ2 = radians(lat2) 64 λ1 = radians(lon1) 65 λ2 = radians(lon2) 66 67 # 更成緯度(補助球上の緯度) 68 U1 = atan((1 - ƒ) * tan(φ1)) 69 U2 = atan((1 - ƒ) * tan(φ2)) 70 71 sinU1 = sin(U1) 72 sinU2 = sin(U2) 73 cosU1 = cos(U1) 74 cosU2 = cos(U2) 75 76 # 2点間の経度差 77 L = λ2 - λ1 78 79 # λをLで初期化 80 λ = L 81 82 # 以下の計算をλが収束するまで反復する 83 # 地点によっては収束しないことがあり得るため、反復回数に上限を設ける 84 for i in range(ITERATION_LIMIT): 85 sinλ = sin(λ) 86 cosλ = cos(λ) 87 sinσ = sqrt((cosU2 * sinλ) ** 2 + (cosU1 * sinU2 - sinU1 * cosU2 * cosλ) ** 2) 88 cosσ = sinU1 * sinU2 + cosU1 * cosU2 * cosλ 89 σ = atan2(sinσ, cosσ) 90 sinα = cosU1 * cosU2 * sinλ / sinσ 91 cos2α = 1 - sinα ** 2 92 cos2σm = cosσ - 2 * sinU1 * sinU2 / cos2α 93 C = ƒ / 16 * cos2α * (4 + ƒ * (4 - 3 * cos2α)) 94 λʹ = λ 95 λ = L + (1 - C) * ƒ * sinα * (σ + C * sinσ * (cos2σm + C * cosσ * (-1 + 2 * cos2σm ** 2))) 96 97 # 偏差が.000000000001以下ならbreak 98 if abs(λ - λʹ) <= 1e-12: 99 break 100 else: 101 # 計算が収束しなかった場合はNoneを返す 102 return None 103 104 # λが所望の精度まで収束したら以下の計算を行う 105 u2 = cos2α * (a ** 2 - b ** 2) / (b ** 2) 106 A = 1 + u2 / 16384 * (4096 + u2 * (-768 + u2 * (320 - 175 * u2))) 107 B = u2 / 1024 * (256 + u2 * (-128 + u2 * (74 - 47 * u2))) 108 Δσ = B * sinσ * (cos2σm + B / 4 * (cosσ * (-1 + 2 * cos2σm ** 2) - B / 6 * cos2σm * (-3 + 4 * sinσ ** 2) * (-3 + 4 * cos2σm ** 2))) 109 110 # 2点間の楕円体上の距離 111 s = b * A * (σ - Δσ) 112 113 # 各点における方位角 114 α1 = atan2(cosU2 * sinλ, cosU1 * sinU2 - sinU1 * cosU2 * cosλ) 115 α2 = atan2(cosU1 * sinλ, -sinU1 * cosU2 + cosU1 * sinU2 * cosλ) + pi 116 117 if α1 < 0: 118 α1 = α1 + pi * 2 119 120 return { 121 'distance': s, # 距離 122 'azimuth1': degrees(α1), # 方位角(始点→終点) 123 'azimuth2': degrees(α2), # 方位角(終点→始点) 124 } 125 126lat1 = lat 127gcp_list['lat_0'] = lat 128gcp_list['lon_0'] = lon 129lat1 = gcp_list.lat_0.values.tolist() 130lon1 = gcp_list.lon_0.values.tolist() 131lat2 = gcp_list.lat.values.tolist() 132lon2 = gcp_list.lon.values.tolist() 133 134gcp_list['dis'] = vincenty_inverse(lat1, lon1, lat2, lon2, 2) 135 136

エラーメッセージとしては、下記になります

Traceback (most recent call last): File "distance_of_denshi.py", line 134, in <module> gcp_list['dis'] = vincenty_inverse(lat1, lon1, lat2, lon2, 2) File "distance_of_denshi.py", line 50, in vincenty_inverse if isclose(lat1, lat2) and isclose(lon1, lon2): TypeError: must be real number, not list

どのようにすれば、リストに計算ができるのでしょうか?
ご存じの方いらっしゃいましたらご教授頂けますと幸いです

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

どのようにすれば、リストに計算ができるのでしょうか?

とありますが、vincenty_inverse()がリストを扱えるようにするのではなく、vincenty_inverse()lat1, lon1, lat2, lon2から取り出した値を引数として渡せば良いでしょう。
forループなどでリストの全要素について処理すれば良いかと思います。

投稿2020/05/06 10:45

meg_

総合スコア10580

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yoda25

2020/05/06 12:10

教えていただきありがとうございました for文で足していったら、無事処理できました
guest

0

投稿2020/05/06 10:42

Orlofsky

総合スコア16415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yoda25

2020/05/06 12:12

ありがとうございます numpyでやる方法もありましたか、次はこのパターンでも作ってみたいと思います
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問