274 lines
10 KiB
Python
274 lines
10 KiB
Python
"""
|
|
Title: Controller
|
|
Developer:
|
|
Sang Inn Woo, Ph.D. @ Incheon National University
|
|
Starting Date: 2022-11-10
|
|
"""
|
|
import psycopg2 as pg2
|
|
import numpy as np
|
|
import settle_prediction_steps_main
|
|
import matplotlib.pyplot as plt
|
|
|
|
import sys
|
|
import pdb
|
|
|
|
'''
|
|
apptb_surset01
|
|
cons_code: names of monitoring points
|
|
|
|
apptb_surset02
|
|
cons_code: names of monitoring points
|
|
amount_cum_sub: accumulated settlement
|
|
fill_height: height of surcharge fill
|
|
nod: number of date
|
|
'''
|
|
|
|
def settlement_prediction(business_code, cons_code):
|
|
|
|
# connect the database
|
|
#connection = pg2.connect("host=localhost dbname=postgres user=postgres password=lab36981 port=5432") # SW local
|
|
#connection = pg2.connect("host=localhost dbname=sgis user=postgres password=postgres port=5434") # ICTWay local
|
|
|
|
# connect the database
|
|
try:
|
|
# 디비엔텍 DB서버
|
|
connection = pg2.connect("host=10.dbnt.co.kr dbname=sgis_new user=smartgeoinfo password=Smartgeoinfo1! port=55432")
|
|
print(f"[OK] DB 접속 성공: {connection.get_dsn_parameters()['host']}")
|
|
except pg2.OperationalError as e:
|
|
print(f"[Error] DB 접속 실패: {e}")
|
|
sys.exit(1)
|
|
|
|
# set cursor
|
|
cursor = connection.cursor()
|
|
|
|
# select monitoring data for the monitoring point
|
|
postgres_select_query = """SELECT amount_cum_sub, fill_height, nod FROM apptb_surset02 WHERE business_code='""" + business_code \
|
|
+ """' and cons_code='""" + cons_code + """' ORDER BY nod ASC"""
|
|
'''
|
|
변경사항
|
|
(amount_cum_sub * -1) --> amount_cum_sub
|
|
침하예측은 부호의 영향을 크게 받습니다.
|
|
현재 개발이 침하량 양수를 기준으로 되어 있어, 양수를 넘겨 줘야 합니다.
|
|
여기서는 일단 데이터 그대로 받습니다.
|
|
'''
|
|
|
|
cursor.execute(postgres_select_query)
|
|
monitoring_record = cursor.fetchall()
|
|
|
|
# initialize time, surcharge, and settlement lists
|
|
time = []
|
|
surcharge = []
|
|
settlement = []
|
|
|
|
# fill lists
|
|
for row in monitoring_record:
|
|
# DB 값이 NULL(None)이면 건너뜀 (에러 방지)
|
|
if row[0] is None or row[1] is None or row[2] is None:
|
|
continue
|
|
|
|
settlement.append(float(row[0]))
|
|
surcharge.append(float(row[1]))
|
|
time.append(float(row[2]))
|
|
|
|
# convert lists to np arrays
|
|
settlement = np.array(settlement)
|
|
surcharge = np.array(surcharge)
|
|
time = np.array(time)
|
|
|
|
# adjust the sign
|
|
sgn = 1
|
|
if np.average(settlement) < 0:
|
|
sgn = -1
|
|
settlement = sgn * settlement
|
|
'''
|
|
변경사항
|
|
침하 예측은 부호의 영향을 크게 받습니다.
|
|
만일 평균 침하량의 부호가 음수라면,
|
|
침하량이 음수로 기입되어있다고 보고,
|
|
양수로 변환시킵니다.
|
|
'''
|
|
|
|
|
|
# run the settlement prediction and get results
|
|
results = (settle_prediction_steps_main.
|
|
run_settle_prediction(point_name=cons_code, np_time=time,
|
|
np_surcharge=surcharge, np_settlement=settlement,
|
|
final_step_predict_percent=90,
|
|
additional_predict_percent=300,
|
|
asaoka_interval=3))
|
|
|
|
# prediction method code
|
|
# 1: original hyperbolic method (쌍곡선법)
|
|
# 2: nonlinear hyperbolic method (비선형 쌍곡선법)
|
|
# 3: weighted nonlinear hyperbolic method (가중 비선형 쌍곡선법)
|
|
# 4: Asaoka method (아사오카법)
|
|
# 5: Step loading (단계성토 고려법)
|
|
|
|
'''
|
|
time_hyper, sp_hyper_original,
|
|
time_hyper, sp_hyper_nonlinear,
|
|
time_hyper, sp_hyper_weight_nonlinear,
|
|
time_asaoka, sp_asaoka,
|
|
time[step_start_index[0]:], -sp_step[step_start_index[0]:],
|
|
'''
|
|
|
|
for i in range(5):
|
|
|
|
# if there are prediction data for the given data point, delete it first
|
|
postgres_delete_query = """DELETE FROM apptb_pred02_no""" + str(i + 1) \
|
|
+ """ WHERE business_code='""" + business_code \
|
|
+ """' and cons_code='""" + cons_code + """'"""
|
|
cursor.execute(postgres_delete_query)
|
|
connection.commit()
|
|
|
|
# get time and settlement arrays
|
|
time = results[2 * i]
|
|
predicted_settlement = results[2 * i + 1]
|
|
|
|
# for each prediction time
|
|
for j in range(len(time)):
|
|
|
|
# construct insert query
|
|
postgres_insert_query \
|
|
= """INSERT INTO apptb_pred02_no""" + str(i + 1) + """ """ \
|
|
+ """(business_code, cons_code, prediction_progress_days, predicted_settlement, prediction_method) """ \
|
|
+ """VALUES (%s, %s, %s, %s, %s)"""
|
|
|
|
# set data to insert
|
|
#record_to_insert = (business_code, cons_code, time[j], -predicted_settlement[j], i + 1)
|
|
record_to_insert = (business_code, cons_code, float(time[j]), float(-predicted_settlement[j]), i + 1)
|
|
|
|
'''
|
|
변경사항
|
|
predicted_settlement[j] --> -predicted_settlement[j]
|
|
여기서 침하예측값의 부호를 음수로 설정해서 DB에 저장합니다.
|
|
'''
|
|
|
|
# execute the insert query
|
|
cursor.execute(postgres_insert_query, record_to_insert)
|
|
|
|
# commit changes
|
|
connection.commit()
|
|
|
|
|
|
def read_database_and_plot(business_code, cons_code):
|
|
|
|
# connect the database
|
|
connection = pg2.connect("host=localhost dbname=postgres user=postgres password=lab36981 port=5432") #SW local
|
|
#connection = pg2.connect("host=192.168.0.72 dbname=sgis user=sgis password=sgis port=5432") # ICTWay internal
|
|
|
|
# set cursor
|
|
cursor = connection.cursor()
|
|
|
|
# select monitoring data for the monitoring point
|
|
postgres_select_query = ("""SELECT amount_cum_sub, fill_height, nod FROM apptb_surset02 WHERE business_code='"""
|
|
+ business_code + """' and cons_code='""" + cons_code + """' ORDER BY nod ASC""")
|
|
|
|
cursor.execute(postgres_select_query)
|
|
monitoring_record = cursor.fetchall()
|
|
|
|
# initialize time, surcharge, and settlement lists
|
|
time_monitored = []
|
|
surcharge_monitored = []
|
|
settlement_monitored = []
|
|
|
|
# fill lists
|
|
for row in monitoring_record:
|
|
settlement_monitored.append(float(row[0]))
|
|
surcharge_monitored.append(float(row[1]))
|
|
time_monitored.append(float(row[2]))
|
|
|
|
# convert lists to np arrays
|
|
settlement_monitored = np.array(settlement_monitored)
|
|
surcharge_monitored = np.array(surcharge_monitored)
|
|
time_monitored = np.array(time_monitored)
|
|
|
|
# prediction method code
|
|
# 1: original hyperbolic method
|
|
# 2: nonlinear hyperbolic method
|
|
# 3: weighted nonlinear hyperbolic method
|
|
# 4: Asaoka method
|
|
# 5: Step loading
|
|
|
|
time_predicted_series = []
|
|
settlement_predicted_series = []
|
|
|
|
for i in range(5):
|
|
|
|
# temporarily set the prediction method as 0
|
|
postgres_select_query = """SELECT prediction_progress_days, predicted_settlement """ \
|
|
+ """FROM apptb_pred02_no""" + str(i + 1) \
|
|
+ """ WHERE business_code='""" + business_code \
|
|
+ """' and cons_code='""" + cons_code \
|
|
+ """' ORDER BY prediction_progress_days ASC"""
|
|
|
|
# select predicted data for the monitoring point
|
|
cursor.execute(postgres_select_query)
|
|
prediction_record = cursor.fetchall()
|
|
|
|
# initialize time, surcharge, and settlement lists
|
|
time_predicted = []
|
|
settlement_predicted = []
|
|
|
|
# fill lists
|
|
for row in prediction_record:
|
|
time_predicted.append(float(row[0]))
|
|
settlement_predicted.append(float(row[1]))
|
|
|
|
# add lists to series
|
|
time_predicted_series.append(np.array(time_predicted))
|
|
settlement_predicted_series.append(np.array(settlement_predicted))
|
|
|
|
# 그래프 크기, 서브 그래프 개수 및 비율 설정
|
|
fig, axes = plt.subplots(2, 1, figsize=(8, 6), gridspec_kw={'height_ratios': [1, 3]})
|
|
|
|
# 성토고 그래프 표시
|
|
axes[0].plot(time_monitored, surcharge_monitored, color='black', label='surcharge height')
|
|
|
|
# 성토고 그래프 설정
|
|
axes[0].set_ylabel("Surcharge height (m)", fontsize=10)
|
|
axes[0].set_xlim(left=0)
|
|
axes[0].set_xlim(right=np.max(time_predicted))
|
|
axes[0].grid(color="gray", alpha=.5, linestyle='--')
|
|
axes[0].tick_params(direction='in')
|
|
|
|
# 계측 및 예측 침하량 표시
|
|
axes[1].scatter(time_monitored, -settlement_monitored, s=30,
|
|
facecolors='white', edgecolors='grey', label='measured data')
|
|
|
|
axes[1].plot(time_predicted_series[0], settlement_predicted_series[0],
|
|
linestyle='--', color='red', label='Original Hyperbolic')
|
|
axes[1].plot(time_predicted_series[1], settlement_predicted_series[1],
|
|
linestyle='--', color='blue', label='Nonlinear Hyperbolic')
|
|
axes[1].plot(time_predicted_series[2], settlement_predicted_series[2],
|
|
linestyle='--', color='black', label='Weighted Nonlinear Hyperbolic')
|
|
axes[1].plot(time_predicted_series[3], settlement_predicted_series[3],
|
|
linestyle='--', color='olive', label='Asaoka')
|
|
axes[1].plot(time_predicted_series[4], settlement_predicted_series[4],
|
|
linestyle='--', color='navy', label='Step Loading Hyperbolic')
|
|
|
|
axes[0].set_ylabel("Settlement (cm)", fontsize=10)
|
|
axes[1].legend()
|
|
axes[1].set_ylim(top=0)
|
|
axes[1].set_xlim(left=0)
|
|
axes[1].set_xlim(right=np.max(time_predicted))
|
|
|
|
plt.show()
|
|
|
|
|
|
# script to call: python3 controller.py [business_code] [cons_code]
|
|
# for example: python3 controller.py 221222SA0003 CONS001
|
|
if __name__ == '__main__':
|
|
|
|
# Example site 1: 231229SA0001, CONS017
|
|
# Example site 2: 231229SA0006, CONS061
|
|
|
|
args = sys.argv[1:]
|
|
business_code = args[0]
|
|
cons_code = args[1]
|
|
|
|
settlement_prediction(business_code = business_code, cons_code = cons_code)
|
|
print("The settlement prediction is over.")
|
|
|
|
#read_database_and_plot(business_code=business_code, cons_code=cons_code)
|
|
#print("Visualization is over.") |