INM による Lden コンターマップ 作成マニュアル 北海道立総合研究機構 環境・地質研究本部 環境科学研究センター 地球・大気環境グループ 2015 年 3 月 目次 1 INM による Lden コンターマップ作成マニュアルについて ......................................... 2 1-1 はじめに ......................................................................................................... 2 1-2 手順の流れ...................................................................................................... 2 1-3 実行に必要なソフトウェア ............................................................................. 2 1-4 本マニュアルの表記について ......................................................................... 3 2 飛行航跡データの収集 ............................................................................................. 4 2-1 ADS-B 信号受信システムの作成 ....................................................................... 4 2-2 航跡データの収集 ........................................................................................... 5 2-3 データ処理...................................................................................................... 6 2-4 飛行高度の気圧補正 ....................................................................................... 9 3 コース選択予測モデルの作成 ................................................................................ 10 4 INM によるシミュレーション手順 .......................................................................... 17 4-1 対象空港の条件設定 ..................................................................................... 17 4-2 離発着コースデータの作成 ........................................................................... 20 4-3 プロファイルデータの作成 ........................................................................... 26 4-4 機種・コース別運行本数の作成 .................................................................... 33 4-5 騒音評価方法の設定 ..................................................................................... 37 4-6 周辺地形の設定 ............................................................................................ 38 4-7 シミュレーションの実行 .............................................................................. 39 4-8 結果の表示・保存 ......................................................................................... 41 1 1INM による Lden コンターマップ作成マニュアルについて 1-1はじめに H25 年度より航空機騒音の評価指標が Lden へと移行し、今後環境基準類型の地域の指定範 囲の見直しや新規指定を検討するためには Lden コンターマップが必要です。INM はアメリカ 合衆国連邦航空宇宙庁が制作した航空機騒音シミュレーションソフトウェアで安価($3 00)で入手でき、航空機騒音の発生・減衰データが豊富に収録されています。本マニュア ルは、INM を用いて Lden コンターマップを作成するためのデータ入手と設定の手順を取りま とめたものであり、安価に Lden コンターマップを作成することができます。 1-2手順の流れ ADS-B 信号受信システム 想定運航スケジュール ベイズ統計を用い 飛行航跡データ 気象条件 コース選択予測モデル たパターン解析 機種・コース別平均運行数 気象データ シミュレーション設定 速度プロファイル 離着陸コース 高度プロファイル INMによるシミュレーション ⇒Ldenコンターマップ作成 1-3実行に必要なソフトウェア ・INM は FAA より購入できます。 HP アドレス: https://www.faa.gov/about/office_org/headquarters_offices/apl/research /models/inm_model/ ・本手順では大規模 GIS データを扱うための Python と関連するライブラリおよび PostgreSQL、地理空間情報を扱うための QGIS と関連するライブラリおよび PostGIS、統 2 計モデル解析のための R および OpenBUGS を使用しています。これらはすべてオープンソ ースソフトウェアであり、無料で入手可能です。 ・必要なソフトウェア INM, Python, Python ライブラリ(NumPy,Pandas,psycopg2,guiqwt), PsotgreSQL, PostGIS, QGIS, R, R ライブラリ(R2OpenBUGS) ベイズ推計ソフトウェア(OpenBUGS) ・INM の詳しい操作方法については、ソフトウェア付属のマニュアルを参照してください 1-4本マニュアルの表記について 本マニュアルでは枠で囲ってある部分は実際の作業を示しています。使用するソフトウ ェアは枠の最初の行に記載してあります。 3 2飛行航跡データの収集 2-1ADS-B 信号受信システムの作成 ① シングルボードコンピューター(RaspberryPi)を用意し、”Raspbian”をインストー ル、初期設定を行う。 参考 HP:http://qiita.com/makoto_kw/items/393e098f214f81449c9f ② R820T チップを搭載する USB ワンセグチューナーを用意する。 ③ RspberryPi に必要なソフトウェアをインストールする。 #/***RaspberryPi コンソール******/ #ライブラリのインストール $pi>sudo apt-get update $pi>sudo apt-get upgrade $pi>sudo apt-get install autoconf automake libtool $pi>sudo apt-get install git libusb-1.0.0-dev # rtl-sdr のインストール $pi>git clone git://git.osmocom.org/rtl-sdr.git $pi>cd rtl-sdr $pi>sutoreconf –i $pi>./configure $pi>make $pi>sudo make install $pi>sudo ldconfig $pi>sudo make install-udev-rules # rtl-sdr のインストール $pi>git clone git://github.com/MalcolmRobb/dump1090.git $pi>cd dump1090 $pi>make $pi>cd /usr/local/bin/ $pi>ln –s ~/dump1090/dump1090 4 ④ テキストエディタを用いて pi のホームディレクトリに dump1090.sh を作成。 #******RaspberryPi テキストエディタ******** #!bin/si echo –n “DateTime Set Y/M/D H:M:S ----- “ read ans sudo date –s “$ans” ./dump1090/dump1090 --net --quiet & telnet localhost 30003 | tee `date + %Y%m%d%H%M`.log 2-2航跡データの収集 ① USB ワンセグチューナーとアンテナを三脚に固定し設置。 設置例 ② Raspberry Pi に接続し、起動。 ③ ログインし、dump1090.sh を実行。 #/***RaspberryPi コンソール******/ $pi>sh dump1090.sh 5 2-3データ処理 ① Python コンソールを起動し、log ファイルを読み込む。 #/***Python コンソール******/ import numpy as np import pandas as pd df = pd.read_csv('????.log',header=None,skiprows=3) df.rename(columns={0:"MSG type",1:"Transtype",2:"SessionID",\ 3:"AircraftID",4:"HexIdent",5:"FlightID",\6:"date gen",\ 7:"time gen",8:"date log",9:"time log",10:"callsign",\ 11:"altitude",12:"grnd speed", 13:"track",14:"latitude",\ 15:"longitude",16:"vert rate", 17:"squawk",18:"alert",\ 19:"emergency",20:"SPI",21:"on ground"}, inplace=True) ② 不必要なレコードを削除。 #/***Python コンソール******/ df = df[df["Trans type"]!=2] df = df[df["Trans type"]!=5] df = df[df["Trans type"]!=6] df = df[df["Trans type"]!=7] df = df[df["Trans type"]!=8] df = df[df["Trans type"].notnull()] df = df[df.HexIdent!="000000"] df = df[df.altitude!=0] hex_alt_min = df.altitude.groupby(df.HexIdent).min() df = df[np.in1d(df.HexIdent,hex_alt_min.index[hex_alt_min<3000].values)] ③ 使用機材 ID と受信時刻から離着陸を分割し、コールサインを割り振る。 #/***Python コンソール******/ #コールサインを抽出する関数 def res_cs_date(sub_df): call_ser = pd.Series(sub_df.callsign.dropna().unique()) call_ser = call_ser[np.logical_not(call_ser.str.startswith('?'))] date_str = sub_df.timestamp.iloc[0].date().strftime("%y%m%d") return call_ser[0].strip() + "_" + date_str 6 #/***Python コンソール******/ #日付時刻フォーマットデータを作成 df["timestamp"] = pd.to_datetime(df['date log'] + " " +df['time log']) #HexIdent 毎に処理 hex_ser = df.HexIdent.unique() for h_hex in hex_ser: tmp_df = df.ix[df.HexIdent==h_hex] ts_df = tmp_df[tmp_df["Trans type"] == 3] peri_start_ts = ts_df[ts_df.timestamp.diff().gt(10*60*1E9)].timestamp peri_start_arr = pd.Series(ts_df.iloc[0].timestamp).append(peri_start_ts) peri_end_arr = peri_start_ts.append(pd.Series(ts_df.iloc[-1].timestamp + np.timedelta64(1E9))) for i in range(peri_start_arr.count()): sub_df = tmp_df[np.logical_and( tmp_df.timestamp >= peri_start_arr.iloc[i], tmp_df.timestamp < peri_end_arr.iloc[i])]\ if sub_df.altitude.min() < 1500: df.ix[np.logical_and(df.HexIdent == h_hex, np.logical_and(df.timestamp >= peri_start_arr.iloc[i], df.timestamp < peri_end_arr.iloc[i])), "cs_date"] = res_cs_date(sub_df) df = df[np.logical_not(df.cs_date.isnull())] 7 ④ 緯度・経度を保有するレコードの速度、機首方向を前後のレコードから補完する。 #/***Python コンソール******/ #cs_date 毎に処理 cs_date_ser = df.cs_date.unique() for h_cs in cs_date_ser: df.ix[df.cs_date==h_cs,"track"]\ =df.ix[df.cs_date==h_cs,"track"].fillna(method='ffill') df.ix[df.cs_date==h_cs,"track"]\ =df.ix[df.cs_date==h_cs,"track"].fillna(method='bfill') df.ix[df.cs_date==h_cs,"grnd speed"]\ =df.ix[df.cs_date==h_cs,"grnd speed"].fillna(method='ffill') df.ix[df.cs_date==h_cs,"grnd speed"]\ =df.ix[df.cs_date==h_cs,"grnd speed"].fillna(method='bfill') ⑤ PostGIS にインポートする。 #/***Python コンソール******/ import psycopg2 conn = psycopg2.connect("dbname=???? user=???? host=localhost") cur = conn.cursor() tmp_df = df[df.latitude.notnull()] cur.execute("CREATE TABLE segm_points(id SERIAL, cs_date VARCHAR,\ latitude DOUBLE PRECISION, longitude DOUBLE PRECISION,\ altitude DOUBLE PRECISION,heading DOUBLE PRECISION,\ speed DOUBLE PRECISION, T_log TIMESTAMP)") cur.executemany("INSERT INTO segm_points(\ cs_date,latitude,longitude,altitude,heading,speed,t_log\ ) VALUES(%s,%s,%s,%s,%s,%s,%s)",\ [x[1:] for x in tmp_df[\ ["cs_date","latitude","longitude","altitude",\ "track","grnd speed","timestamp"]].itertuples()]) cur.execute("ALTER TABLE segm_points \ ADD COLUMN the_geom geometry(POINT,4326)") cur.execute("UPDATE segm_points SET the_geom \ = ST_SetSRID(ST_MakePoint(longitude,latitude),4326)") conn.commit() 8 2-4飛行高度の気圧補正 ① 気象庁・過去の気象データ・ダウンロードページより、対象空港に近い官署の海面気圧 時別値を入手。 ② Python コンソールを起動し、気圧データを postgreSQL にインポートする。 #/***Python コンソール******/ import numpy as np import pandas as pd import psycopg2 conn = psycopg2.connect("dbname=adsb user=postgres host=localhost") cur = conn.cursor() ame_df = pd.read_csv("data.csv",encoding = 'SHIFT-JIS',skiprows=4) ame_df.columns = ['date','pressure','d_flg','no'] ame_df["datetime"] = pd.to_datetime(ame_df.date) cur.execute("CREATE TABLE ame_pres( id SERIAL, T_log TIMESTAMP, pressure DOUBLE PRECISION)") conn.commit() cur.executemany("INSERT INTO ame_pres(T_log, pressure) VALUES( %s, %s)", [x[1:] for x in ame_df[["datetime","pressure"]].itertuples()]) conn.commit() ③ 飛行高度の気圧補正を行う。 #/***Python コンソール******/ cur.execute("ALTER TABLE segm_points ADD COLUMN qnh_alt \ DOUBLE PRECISION") cur.execute("UPDATE segm_points a SET qnh_alt = \ (SELECT (b.pressure - 1013.25 )/ 1013.25 * 8434.515630756852 /0.3048 + \ a.altitude FROM ame_pres b WHERE date_trunc('hour',a.t_log) = b.t_log)") conn.commit() 9 3コース選択予測モデルの作成 ① 電子航空路誌(eAIP)から Standard Departure Chart 及び Instrument Approach Chart を入手する。 HP アドレス https://aisjapan.mlit.go.jp/Login.do 離陸コース 着陸コース RWY34,RWY16 LOC Z, LOC Y, RNAV ② Python コンソールを起動し、フライトリストを PostgreSQL にインポートする。 #/***Python コンソール******/ import numpy as np import pandas as pd #高度が最小値のレコードを抽出する関数 def f_head(df): return df.sort("altitude").head(1) #cs_date でグループ化して処理し、csv に出力 df = pd.read_picke(“adsb.df”) tmp_df = df[df.latitude.notnull()] apdp_df = tmp_df.groupby("cs_date").apply(f_head) apdp_df[["cs_date","HexIdent","timestamp"]].to_csv(\ "apdp_list.csv",index=False,date_format='%Y/%m/%d %H:%M:%S') 10 ③ フライト毎に飛行コースを判別する。 #/*******QGIS&Excel******/ Ⅰ.航跡データを QGIS に読み込む レイヤ→レイヤの追加 →PostGIS レイヤの追加 →segm_points を選択 Ⅱ.cs_date で分類して表示 レイヤのプロパティ→ →スタイルタブ →”分類された”を選択 カラム:”cs_date”を選択 Ⅲ.cs_date 別に飛行コースを判別 apdp_list.csv に couse 列を追加 QGIS 上で cs_date 別の航跡を 表示し、飛行コースを判別。 11 ④ 離発着時刻における気象データを入力する。 #/*******QGIS&Excel******/ apdp_list.csv に風速、風向、視程列を追 加 気象庁・過去のアメ ダスデータより、対 象空港に最も近い観 測地点の離発着時刻 のデータを入力 ⑤ 気象条件を説明変数、離発着方向を応答変数とした一般化線形モデルを作成する。 #旭川空港におけるモデル ・ILS が R34 方向にしか設置されていないため、視程距離が短い場合、風向に関係な く R34 に着陸する。そのため、ゼロインフレーションベルヌーイ分布を用いたモデ ルを作成した。 0. with prbability 𝑞𝑖 𝑌𝑖 ~ { 𝑏𝑒𝑟𝑛𝑜𝑢𝑙𝑙𝑖(𝑝𝑖 ) with probability (1 − 𝑞𝑖 ) 𝑝𝑖 = 𝑞𝑖 = ここで、𝑌𝑖 : R16 方向の生起 1 1 + exp(−(𝛼1 + 𝛽1 𝑤𝑠𝑖 )) 1 1 + exp(−(𝛼2 + 𝛽2 𝑣𝑖𝑠𝑖 )) ws𝑖 : R34 方向の風速成分 vis𝑖 : 視程距離 12 ⑥ ベイズ推計ソフトウェア OpenBUGS コードによりモデルを記述する。 #/*******Text Editor*******/ #BUGSmodel の作成 → model.txt に保存 model{ for( i in 1:N_dat){ Y[i] ~ dbern(p1[i]) p1[i] <- q1[i] * p2[i] p2[i] ~ dbern(q2[i]) logit(q1[i]) <- logit_q1[i] logit_q1[i] <- a1 + b1 * ws[i] logit(q2[i]) <- logit_q2[i] logit_q2[i] <- a2 + b2 * vis[i] } a1 ~ dnorm(0,0.00001) a2 ~ dnorm(0,0.00001) b1 ~ dnorm(0,0.00001) b2 ~ dnorm(0,0.00001) } ⑦ R を用いてデータの前処理を行う。 #/*******R コンソール******/ apdp.df <- read.csv("apdp_list.csv",fileEncoding="shift-jis") apdp.df[apdp.df$couse == "RWY34","op_dir"] = 0 apdp.df[apdp.df$couse == "RWY16",”op_dir"] = 1 apdp.df[apdp.df$couse == "LOCY","op_dir"] = 0 apdp.df[apdp.df$couse == "LOCZ",”op_dir"] = 0 apdp.df[apdp.df$couse == "RNAV",”op_dir"] = 1 apdp.df[apdp.df$w_direction == "北","w_dir_deg"] = 0. apdp.df[apdp.df$w_direction == "北北東","w_dir_deg"] = 22.5 * 1 apdp.df[apdp.df$w_direction == "北東","w_dir_deg"] = 22.5 * 2 apdp.df[apdp.df$w_direction == "東北東","w_dir_deg"] = 22.5 * 3 13 apdp.df[apdp.df$w_direction == "東","w_dir_deg"] = 22.5 * 4 apdp.df[apdp.df$w_direction == "東南東","w_dir_deg"] = 22.5*5 apdp.df[apdp.df$w_direction == "南東","w_dir_deg"] = 22.5*6 apdp.df[apdp.df$w_direction == "南南東","w_dir_deg"] = 22.5*7 apdp.df[apdp.df$w_direction == "南","w_dir_deg"] = 22.5*8 apdp.df[apdp.df$w_direction == "南南西","w_dir_deg"] = 22.5*9 apdp.df[apdp.df$w_direction == "南西","w_dir_deg"] = 22.5*10 apdp.df[apdp.df$w_direction == "西南西","w_dir_deg"] = 22.5*11 apdp.df[apdp.df$w_direction == "西","w_dir_deg"] = 22.5*12 apdp.df[apdp.df$w_direction == "西北西","w_dir_deg"] = 22.5*13 apdp.df[apdp.df$w_direction == "北西","w_dir_deg"] = 22.5*14 apdp.df[apdp.df$w_direction == "北北西","w_dir_deg"] = 22.5*15 apdp.df["w_cos"] = cos((apdp.df$w_dir_deg + 180 - 334.17)/180*pi) apdp.df["w_comp"] = apdp.df["w_cos"] * apdp.df["w_speed"] ⑧ OpenBUGS を用いて、パラメータ推定を行う。 #/*******R コンソール******/ library(R2OpenBUGS) Y <- apdp.df$op_dir vis <- apdp.df$visibility ws <- apdp.df$w_comp N_dat <- dim(apdp.df)[1] source <- list(“Y”,”vis”,”ws”,”N_dat”) parameters <- list(“a1”,”a2”,”b1”,”b2”) inits <- function(){ list(a1 = rnorm(1,0,0.001), a2 = rnorm(1,0,0.001), b1 = rnorm(1,0,0.001), b2 = rnorm(1,0,0.001)) } sim <- bugs( data=source, inits, parameters, model.file=”model.txt”, n.chains = 3, n.iter = 15000) 14 #結果の表示 sim Inference for Bugs model at "model.txt", Current: 3 chains, each with 15000 iterations (first 10000 discarded) Cumulative: n.sims = 15000 iterations saved mean sd 2.5% 25% 50% 75% 97.5% Rhat n.eff a1 -1.4 0.2 -1.8 -1.5 -1.4 -1.2 -1.0 1 430 a2 -1.3 0.7 -2.8 -1.6 -1.2 -0.8 -0.1 1 210 b1 0.9 0.1 0.7 0.8 0.9 0.9 1.2 1 160 b2 0.5 0.3 0.2 0.3 0.4 0.5 1.3 1 93 deviance 312.3 31.5 243.5 291.1 315.6 337.9 359.4 1 85 For each parameter, n.eff is a crude measure of effective sample size, and Rhat is the potential scale reduction factor (at convergence, Rhat=1). DIC info (using the rule, pD = var(deviance)/2) pD = 485.3 and DIC = 797.6 DIC is an estimate of expected predictive error (lower deviance is better). #旭川空港では、R34 の着陸コースが LOCY と LOCZ の 2 種類存在するが、出発地との 関係性がみられないため、航跡データの割合で単純分配する。 p_LOCY = sum(apdp.df$couse == "LOCY") /sum(apdp.df$couse %in% c("LOCY","LOCZ")) #0.56 15 ⑨ 得られたパラメータの値を使用して、コース選択予測モデルを作成する。 #コース選択予測モデル q(𝑣𝑖𝑠𝑖 ) = 1 − p(𝑤𝑠𝑖 ) = 1 1 + 𝑒𝑥𝑝(−(−1.3 + 0.5 ∗ 𝑣𝑖𝑠𝑖 )) 1 1 + 𝑒𝑥𝑝(−(−1.4 + 0.9 ∗ 𝑤𝑠𝑖 )) Pr(𝑅𝑊𝑌34|𝑤𝑠, 𝑣𝑖𝑠) = q(𝑣𝑖𝑠𝑖 ) + (1 − q(𝑣𝑖𝑠𝑖 )) ∗ (1 − p(𝑤𝑠𝑖 )) Pr(𝑅𝑊𝑌16|𝑤𝑠, 𝑣𝑖𝑠) = (1 − q(𝑣𝑖𝑠𝑖 )) ∗ p(𝑤𝑠𝑖 ) Pr(𝐿𝑂𝐶𝑌|𝑤𝑠, 𝑣𝑖𝑠) = (q(𝑣𝑖𝑠𝑖 ) + (1 − q(𝑣𝑖𝑠𝑖 )) ∗ (1 − p(𝑤𝑠𝑖 ))) ∗ 0.56 Pr(𝐿𝑂𝐶𝑍|𝑤𝑠, 𝑣𝑖𝑠) = (q(𝑣𝑖𝑠𝑖 ) + (1 − q(𝑣𝑖𝑠𝑖 )) ∗ (1 − p(𝑤𝑠𝑖 ))) ∗ 0.44 Pr(𝑅𝑁𝐴𝑉|𝑤𝑠, 𝑣𝑖𝑠) = (1 − q(𝑣𝑖𝑠𝑖 )) ∗ p(𝑤𝑠𝑖 ) 16 4INM によるシミュレーション手順 4-1対象空港の条件設定 ① AISJapan の公開している AIP より対象空港の情報を入手する。 #AISJapan ページ : https://aisjapan.mlit.go.jp/Login.do #旭川空港 RJEC Asahikawa(Civil) ARP coordinates : 434015N/1422651E Elevation : 690ft Demendions of RUNWAY : 2500x60(M) RUNWAY PYSICAL CHARACTERISTICS RUMWAY NR TRUE BRG THR coordinates THR elevation 16 154.17° 434051.04N/1422626.96E 660ft 34 334.17° 433938.12N/1422715.59 721ft ② INM の Study を作成し、中心緯度経度および高度を設定する。 #/*******INM******/ Ⅰ.File→NewStudy を選択し、 Study を作成。 Ⅱ.使用単位を Engrish System に 設定。 Ⅲ.原点と空港名を設定 Latitude =43+40/60+15/3600 = 43.6708333 Longitude =142+26/60+51/3600 = 142.447500 Elevation=690ft 空港名:AKJ 17 ③ シミュレーションを行う機種を登録。 #/*******INM******/ Ⅰ.Setup→Civil Airplane を選択し、シミュレーショ ンする機種を登録する。 ④ 滑走路端の位置情報を設定。 #/*******INM******/ Ⅰ.Tracks→Runway and Helipad Identifer を選択する。 Ⅱ.Edit→Add Record でレコードを 追加し、滑走路端の識別名を設定 End #1: 34 End #2: 16 Width:60m/0.3048=196.85ft Ⅲ.Edit→Commit Record で確定 Ⅳ.Tracks→Runway Ends and Helipads を選択する。 18 Ⅴ.Runway Ends 毎に位置情報を設定。 Runway:16 Cordinates:Lat/Long Lat:43+40/60+51.04/3600 = 43.68084444 Long:142+26/60+26.96/3600 = 142.440822 Elavation MSL(ft): 660 Ⅵ.Edit→Commit Record で確定。 Ⅶ.Runway:34 も同様に設定する。 ⑤ ケースの作成。 #/*******INM******/ Ⅰ.Setup→Cases を選択する。 Ⅱ.Edit→Add Record を選択し、 Case 名を入力。 Ⅲ.Edit→Commit Record で確定 ⑥ シナリオの作成。 #/*******INM******/ Ⅰ.Setup→Scenarios を選択する。 Ⅱ.Edit→Add Record を選択し、 Senario 名を入力、Case を登録。 Ⅲ.Edit→Commit Record で確定 19 4-2離発着コースデータの作成 ① Python コンソールを起動し、フライトリストを PostGIS にインポートする。 import numpy as np import pandas as pd import psycopg2 conn = psycopg2.connect("dbname=adsb user=postgres host=localhost") cur = conn.cursor() apdp_df = pd.read_csv("apdp_list.csv",encoding="shift-jis") cur.execute("CREATE TABLE apdp_list(id SERIAL, cs_date VARCHAR, couse VARCHAR)") conn.commit() cur.executemany("INSERT INTO apdp_list(cs_date,couse) VALUES (%s,%s)", [x[1:] for x in apdp_df[["cs_date","couse"]].itertuples()]) conn.commit() cur.execute("CREATE VIEW segm_view AS SELECT a.*,b.couse FROM segm_points a, apdp_list b WHERE a.cs_date = b.cs_date") conn.commit() 20 ② 滑走路端のポイントデータを作成。 #/*******QGIS&Excel******/ Ⅰ.Excel を用いて滑走路端の位置情報シート を作成し、CSV カンマ区切り形式で保存。 Ⅱ.滑走路端の位置情報を QGIS に読み込む。 レイヤ→レイヤの追加 →デリミティッドテキストレイヤの追加 インポート設定 ファイル名:RunwayEnds.csv ファイル形式:CSV ジオメトリ定義:ポイント座標 X フィールド:Long Y フィールド:Lat 空間参照システム選択 フィルター:4326 空間参照システム:WGS 84 21 ③ QGIS に対象とするコースの航跡データをロードする。 #/*******QGIS&Excel******/ Ⅰ.航跡データを QGIS に読み込む レイヤ→レイヤの追加 →PostGIS レイヤの追加 →segm_view を選択 Ⅱ.フィルタの設定 フィルタの設定をクリック→ →フィルタ式を入力 “couse” = 作成するコース名 AND qnh_alt <= 6000(着陸コース) <= 10000(離陸コース) →設定ウィンドウを閉じ、追加をクリック。 Ⅲ.表示の変更 レイヤのプロパティ→ →スタイルタブ →シンプルマーカー 塗りつぶし:#f5f500 境界線:透過 地物混合モード:乗算 22 ④ GIS 上で複数の航跡の中心を通るラインベクターを作成。 #/*******QGIS&Excel******/ Ⅰ.ラインベクターの新規作成 レイヤ→レイヤの作成 →新規シェープファイルレイヤ レイヤの設定 タイプ:ライン 座標参照システム:WGS 84 レイヤに名前を付けて保存 コース名_line.shp Ⅱ.ラインの作成 レイヤ→編集モード切替 編集→地物の追加 航跡データの中心を通るよう に、左クリックでノードを追加 し、ラインを作成してゆく。 滑走路端で右クリックし、入力 を終了(着陸コース) 。 id を設定する。 ※離陸コースの場合は、滑走路 端から入力を始める。 Ⅱ.編集を終了 レイヤ→編集モード切替 保存をクリック 23 ⑤ ノードの緯度経度を計算する。 #/*******QGIS&Excel******/ Ⅰ.ラインのノードを展開する ベクタ→ジオメトリツール →ノードを展開する 入力ベクタレイヤ:LOCZ_line 出力ファイル:LOCZ_point.shp Ⅱ.地物 id を追加する 属性テーブル→編集モード切替 →フィールド計算機 地物 id の追加 フィールド名:node_id フィールドタイプ:整数値 フィールド幅:10 式:$id Ⅲ.編集を終了 レイヤ→編集モード切替 保存をクリック Ⅳ.CSV にエクスポート 名前を付けて保存する →形式:カンマで区切られた値 パス:LOCY_node レイヤオプション: GEOMETRY=AS_XY 24 ⑥ INM に離着陸 Track を設定。 #/*******INM******/ Ⅰ.Tracks→Imput Graphics を選択。 Ⅱ.Track を入力 Edit→Add Track で Track 入力モードに入る。 右下 の緯度経 度情報を参 考に 大まかな 位置で左ク リックし、始点を作成 右クリックで緯度経度入力 ウィンドウを起動し、ノー ド毎に緯度経度を入力。 滑走 路端でダブル クリッ クし、Track 識別名を入力。 Edit→Delete Point で 始点を削除。 25 4-3プロファイルデータの作成 ① 航跡データのそれぞれのポイントについて、滑走路端までの航行距離を計算する。 #/***Python コンソール******/ import numpy as np import pandas as pd import psycopg2 conn = psycopg2.connect("dbname=adsb user=postgres host=localhost") cur = conn.cursor() #滑走路端の位置情報を postGIS にインポート R_end_df = pd.read_csv("RunwayEnds.csv",encoding="shift-jis") cur.execute("CREATE TABLE runway_ends( \ id SERIAL, name VARCHAR, lat DOUBLE PRECISION, \ long DOUBLE PRECISION, the_geom GEOMETRY(POINT,4326))") conn.commit() cur.executemany("INSERT INTO runway_ends(name,lat,long) VALUES(%s,%s,%s)", \ [(str(x[1]),)+x[2:] for x in R_end_df[["Runway","Lat","Long"]].itertuples()]) conn.commit() cur.execute("UPDATE runway_ends SET the_geom = ST_SetSRID( \ ST_MakePoint(long,lat), 4326)") conn.commit() #航跡のラインデータを作成する cur.execute("ALTER TABLE apdp_list ADD COLUMN the_geom \ GEOMETRY(LINESTRING,2454)") conn.commit() 26 #離陸コースの処理 cur.execute("SELECT cs_date FROM apdp_list WHERE couse = 'RWY34'") h_list = cur.fetchall() cur.executemany("WITH raw_line AS ( SELECT ST_Transform(ST_MakeLine(\ ARRAY(SELECT the_geom FROM segm_points WHERE cs_date = %s \ ORDER BY t_log)),2454) AS the_geom ) UPDATE apdp_list SET the_geom\ = ST_LineSubstring((SELECT the_geom FROM raw_line),\ ST_LineLocatePoint((SELECT the_geom FROM raw_line),\ (SELECT ST_Transform(the_geom,2454) FROM runway_ends \ WHERE name = '16')),1) WHERE cs_date = %s",[x+x for x in h_list]) conn.commit() cur.execute("SELECT cs_date FROM apdp_list WHERE couse = 'RWY16'") h_list = cur.fetchall() cur.executemany("WITH raw_line AS ( SELECT ST_Transform(ST_MakeLine(\ ARRAY(SELECT the_geom FROM segm_points WHERE cs_date = %s \ ORDER BY t_log)),2454) AS the_geom ) UPDATE apdp_list SET the_geom\ = ST_LineSubstring((SELECT the_geom FROM raw_line),\ ST_LineLocatePoint((SELECT the_geom FROM raw_line),\ (SELECT ST_Transform(the_geom,2454) FROM runway_ends \ WHERE name = '34')),1) WHERE cs_date = %s",[x+x for x in h_list]) conn.commit() #着陸コースの処理(RNAV) cur.execute("SELECT cs_date FROM apdp_list WHERE couse = 'RNAV'") h_list = cur.fetchall() cur.executemany("WITH raw_line AS ( SELECT ST_Transform(ST_MakeLine(¥ ARRAY(SELECT the_geom FROM segm_points WHERE cs_date = %s \ ORDER BY t_log)),2454) AS the_geom ) UPDATE apdp_list SET the_geom \ = ST_LineSubstring((SELECT the_geom FROM raw_line),0.0,\ ST_LineLocatePoint((SELECT the_geom FROM raw_line),\ (SELECT ST_Transform(the_geom,2454) FROM runway_ends \ WHERE name = '16'))) WHERE cs_date = %s",[x+x for x in h_list]) conn.commit() 27 #着陸コースの処理(LOCZ,LOCY) cur.execute("SELECT cs_date FROM apdp_list \ WHERE couse IN ('LOCZ','LOCY')") h_list = cur.fetchall() cur.executemany("WITH raw_line AS ( SELECT ST_Transform(ST_MakeLine(\ ARRAY(SELECT the_geom FROM segm_points WHERE cs_date = %s \ ORDER BY t_log)),2454) AS the_geom ) UPDATE apdp_list SET the_geom \ = ST_LineSubstring((SELECT the_geom FROM raw_line),0.0,\ ST_LineLocatePoint((SELECT the_geom FROM raw_line),\ (SELECT ST_Transform(the_geom,2454) FROM runway_ends \ WHERE name = '34'))) WHERE cs_date = %s",[x+x for x in h_list]) conn.commit() #滑走路端からの飛行距離の算出 cur.execute("ALTER TABLE segm_points \ ADD COLUMN dist_km DOUBLE PRECISION") conn.commit() cur.execute("SELECT cs_date FROM apdp_list \ WHERE couse IN ('LOCZ','LOCY','RNAV')") h_list = cur.fetchall() cur.executemany("WITH raw_line AS (\ SELECT the_geom,ST_Length(the_geom) AS len \ FROM apdp_list WHERE cs_date = %s) \ UPDATE segm_points SET dist_km = (\ 1-ST_LineLocatePoint((SELECT the_geom FROM raw_line),\ ST_Transform(the_geom,2454)))*(SELECT len FROM raw_line)/1000 \ WHERE cs_date = %s",[x+x for x in h_list]) conn.commit() cur.execute("SELECT cs_date FROM apdp_list \ WHERE couse IN ('RWY34','RWY16')") h_list = cur.fetchall() cur.executemany("WITH raw_line AS (\ SELECT the_geom,ST_Length(the_geom) AS len \ FROM apdp_list WHERE cs_date = %s) \ UPDATE segm_points SET dist_km28 = \ ST_LineLocatePoint((SELECT the_geom FROM raw_line),\ ST_Transform(the_geom,2454))*(SELECT len FROM raw_line)/1000 \ WHERE cs_date = %s",[x+x for x in h_list]) ② 着陸について、コース別に滑走路端までの航行距離と高度の散布図を表示し、平均的な 高度プロファイルを作成。 #/***Python コンソール******/ #データの読み込みと処理 import numpy as np import pandas as pd import psycopg2 conn = psycopg2.connect("dbname=adsb user=postgres host=localhost") cur = conn.cursor() cur.execute("SELECT cs_date,speed,qnh_alt,dist_km FROM segm_points \ WHERE cs_date IN (SELECT cs_date FROM apdp_list \ WHERE couse = 'LOCY') AND qnh_alt < 8000") df = pd.DataFrame(cur.fetchall()) df.columns = ["cs_date","speed","qnh_alt","dist_km"] Xa= (df.dist_km/0.3048).values Ya = (df.qnh_alt - 721).values #散布図の作成 import guidata from guiqwt.plot import CurveDialog from guiqwt.builder import make from guiqwt.tools import MultiLineTool app = guidata.qapplication() win = CurveDialog(edit=True, toolbar=True, wintitle="ScatterPlot",\ options=dict(title="Dist-Alt Scatter", ylabel="Altitude(ft)",\ xlabel="TrackDistance(1000ft)")) plot = win.get_plot() s_plt = make.curve(Xa,Ya,marker="+",linestyle="NoPen") plot.add_item(s_plt) win.add_tool(MultiLineTool) win.show() app.exec_() 29 Ⅱ.平均的な高度プロファイルを作成 Plyline ツールを用い て平均的なプロファイ ルを描画 FreeMarkers ツールを用 いて変曲点の高度・距離 を取得 CSV(カンマ区切り)で保存 ③ Procedural Profile のステップを作成。 #/***Python コンソール******/ #高度プロファイルデータの読み込み prof_df = pd.read_csv("locy_profile.csv",encoding="shift_jis") #DecendStep 高度の TrackDistance を補完 prof_df = prof_df.append(pd.DataFrame(\ [1000,1500,3000,6000],columns=["Altitude"])) prof_df.index = prof_df.Altitude prof_df.sort(inplace=True) prof_df = prof_df.interpolate(method='values') #平均速度を求める prof_df.index = prof_df.Distance for h_dist in prof_df.Distance: tmp_df = res_df[np.logical_and(\ res_df.dist_km > h_dist*0.3048 - 0.5,\ res_df.dist_km < h_dist*0.3048 + 0.5)] prof_df.ix[prof_df.Distance == h_dist,"speed"] = tmp_df.speed.mean() 30 #降下角度を求める diff_df = prof_df.diff() prof_df["deg"] =\ np.degrees(np.arctan2(diff_df.Altitude,diff_df.Distance*1000)) #csv に保存 prof_df.to_csv("locy_steps.csv") ④ プロファイルの登録。 #/*******INM******/ Ⅰ.Civil→Profile Identifers を選択 し、機種を選択。APP-STANDARD1 を表示 し、Aircraft Weight をメモしておく。 Ⅱ.Edit→Add Record を選択し、 Operation:APP を選択。Profile Group 名と Aircraft Weight を入力 して Commit する。 Ⅲ.Civil→Procedual Profiles を選択 し、機種と Profile を選択。 Ⅳ.Edit→Add Record を選択 し、APP-STANDARD1を参考に、高 度 6000ft から順に Step データを 入力。 31 Ⅳ.Civil→Profile Graph を選択 し、作成プロファイルを確認。 32 4-4機種・コース別運行本数の作成 ① 一週間単位の運航スケジュールを作成。 #/*******Excel******/ Ⅰ.運航スケジュールを作成し、CSV で保存。 発着地 週運航日数 発着地までの 飛行マイル 発着時間帯の区分 day 使用機材 7:00-19:00 evening 19:00-23:00 night 23:00-7:00 ② 気象条件を作成。 #/*******Excel******/ Ⅰ. Excel を用いて風向風速階級別頻度表を作成し、CSV で保存。 列:16 方位(北から右回り) 行:階級幅 1m/s の風速 Ⅱ. 視程距離の階級別頻度表を作成し、CSV で保存。 階級幅 1kmの視程距離 10km 以上は合算 33 ③ コース選択予測モデルを用いてコース選択確率を計算する。 #/***Python コンソール******/ import numpy as np import pandas as pd #視程の影響の計算 vis_freq_df = pd.read_csv("vis_freq.csv") vis_mean_ser = vis_freq_df.vis.str.split("-") vis_freq_df["mean"] = np.nan vis_freq_df.iloc[:10]["mean"] \ = [np.array(x).astype(np.float).mean() for x in vis_mean_ser[:10]] vis_freq_df["q34"] = 1 - 1/(1+np.exp(-(-1.3+0.5*vis_freq_df["mean"]))) vis_freq_df.ix[vis_freq_df.vis=="10<","q34"] = 0 q_vis = (vis_freq_df.freq * vis_freq_df.q34).sum() / vis_freq_df.freq.sum() #コース選択予測確率の計算 ws_freq_df = pd.read_csv("wind_freq.csv") ws_freq_df.rename(columns={'Unnamed: 0':'ws'},inplace=True) ws_freq1d_df = pd.DataFrame(ws_freq_df.iloc[:,1:].as_matrix().flatten(),columns=["freq"]) ws_mat = np.matrix(np.arange(0.5,12.5,1)).T cos_mat = np.matrix(np.cos(np.radians(22.5*np.arange(0,16,1) + 180334.17))) comp_mat = ws_mat * cos_mat ws_freq1d_df["comp"] = comp_mat.getA().flatten() ws_freq1d_df["gp"] = pd.cut( ws_freq1d_df.comp,\ np.arange(-12,13,1),labels=np.arange(-11.5,12.5,1)) ws_p_df = pd.DataFrame(ws_freq1d_df.freq.groupby(ws_freq1d_df.gp).sum(),\ columns=["freq"]) ws_p_df["comp"] = ws_p_df.index.values ws_p_df["p16"] = 1/(1+np.exp(-(-1.4+0.9*ws_p_df.comp))) p_ws = (ws_p_df.freq * ws_p_df.p16).sum() / ws_p_df.freq.sum() 34 #選択確率の dict を作成 couse_p_dict = { "RWY34": q_vis + (1-q_vis)*(1-p_ws), "RWY16": (1-q_vis)*p_ws, "LOCY": (q_vis + (1-q_vis)*(1-p_ws)) * 0.56, "LOCZ": (q_vis + (1-q_vis)*(1-p_ws)) * 0.44, "RNAV": (1-q_vis)*p_ws} ④ 機種・コース別の日平均運航本数を計算する。 #/***Python コンソール******/ #機材毎の離着陸本数を集計 sche_df = pd.read_csv("flight_schedule.csv",encoding="shift_jis") sche_df["P_Stage"] = pd.cut(sche_df[u"飛行距離(マイル)"],\ np.r_[np.arange(0,2000,500),np.arange(2500,7500,1000),\ [10000]],labels=np.arange(1,10,1)) app_gp = sche_df[u'週運航日数'].groupby(\ [sche_df[u'使用機材'],sche_df[u'到着時間帯']]).sum() locz_freq = app_gp.unstack()*couse_p_dict["LOCZ"]/7 locy_freq = app_gp.unstack()*couse_p_dict["LOCY"]/7 rnav_freq = app_gp.unstack()*couse_p_dict["RNAV"]/7 app_df = pd.concat(dict(¥ LOCZ=locz_freq,LOCY=locy_freq,RNAV=rnav_freq),axis=1) app_df.to_csv("app_num.csv",encoding="shift-jis") dep_gp = sche_df[u'週運航日数'].groupby(\ [sche_df[u'使用機材'],sche_df["P_Stage"],¥ sche_df[u'出発時間帯']]).sum() rwy34_freq = dep_gp.unstack(1).unstack()* couse_p_dict["RWY34"]/7 rwy16_freq = dep_gp.unstack(1).unstack()* couse_p_dict["RWY16"]/7 dep_df = pd.concat(dict(RWY34=rwy34_freq,RWY16=rwy16_freq),axis=1) #CSV に保存 dep_df.to_csv("dep_num.csv",encoding="shift-jis") 35 ⑤ オペレーションを入力。 #/*******INM******/ Ⅰ.Operations→Civil Flights を選択し、 計算する Case を選択。 Ⅱ.Edit→Add Record を選択し、 日平均運航本数データを基に、 Flight Operation データを入力 し、Edit→Commit Record で確定。 36 4-5騒音評価方法の設定 ① Noise Metrics に Lden を追加する。 #/*******INM******/ Ⅰ.Setup→Noise Metrics を 選 択 し 、 Edit→Add Record で新規 Metrics を作成。 Ⅱ.以下のパラメータを設定し、 Edit→Commit Record で確定。 Metric ID: LDEN Family: A-weighted Type: Exposure Day Multiplier: 1 Evning Multiplier: 3.16 Night Multiplier: 10 10 log(T): 49.37 ② 騒音評価地点の設定。 #/*******INM******/ Ⅰ.Setup→Population Points を選択。 Edit→Add Record で新規 Point を作成。 Ⅱ.地点名、緯度経度を入力し、Edit→ Commit Record で確定。 37 4-6周辺地形の設定 ① 数値標高モデルから、対象空港周辺の 3TX ファイルを作成。 ② INM に読み込む。 #/*******INM******/ Ⅰ.File→Import Data into Study →Terrain Files を選択。 Ⅱ.Terrian Format:3CD/3TX を 選択し、ファイルの保存されて いるディレクトリを指定。 38 4-7シミュレーションの実行 ① グリッドの設定。 #/*******INM******/ Ⅰ.Run→Grid Setup を選択し、Scinario を選択。 Ⅱ. Edit→Add Record で新規レコードを 追加。GridType:contor を選択し、範囲 を指定、Edit→Commit Record で確定。 Ⅲ. Edit→Add Record で新規レコードを 追加。GridType:contor を選択し、範囲 を指定、Edit→Commit Record で確定。 ② Run Option の設定。 #/*******INM******/ Ⅰ.Run→Run Options を選択。 Run Type: Single Metric Noise Metrics:LDEN 実行するシナリオ を選択 Do Terrain をチェック Terrain Format: 3CD/3TX Do Line-of-Sight Blokage をチェック Do Contor をチェック Do Population Points をチェッ Ⅱ.Edit→Commit Record で確定 39 ③ シミュレーションの実行。 #/*******INM******/ Ⅰ.Run→Run Start を選択。 Ⅱ.実行するシナリオを登録し、 Multisleded をチェックして実行。 Ⅲ.処理状況が表示される。 40 4-8結果の表示・保存 ① Output の設定。 #/*******INM******/ Ⅰ.Output→Output Setup を選択。 Edit→Add Record で新規 Output を作成。 Ⅱ.Output 名を入力。Metric に LDEN を選 択し、表示する Senario を選択。 Ⅱ.Edit→Commit Record で確定 ② コンター表示とシェープファイルへのエクスポート。 #/*******INM******/ Ⅰ.Output→OutputGraphics を選択し、表 示する Output を選択。 ⅡFile→Export as Shapefile を選択し、 Export Unit を設定して実行。 41 ③ 騒音評価地点の結果の表示。 #/*******INM******/ Ⅰ.Output→Noise at PoP Pints を選択し、 表示する Scinario を選択。 42
© Copyright 2024 ExpyDoc