
+++ README.md
... | ... | @@ -0,0 +1,1 @@ |
1 | +# Daegu-Jeju-DIP |
+++ action.py
... | ... | @@ -0,0 +1,201 @@ |
1 | + | |
2 | +from flask_restx import Resource, Api, Namespace, fields,reqparse | |
3 | +from fog_model.fog_predict import fog_classfication | |
4 | +from fog_model.fog_model import darkchannel | |
5 | +from flask import request,jsonify | |
6 | +from flask import Flask, render_template, request | |
7 | +from werkzeug.utils import secure_filename | |
8 | +import os | |
9 | +from haversine import haversine | |
10 | +from database.database import DB | |
11 | +import torch | |
12 | +from PIL import Image | |
13 | +from pothole_model.pothole import pothole | |
14 | +from datetime import datetime | |
15 | +import jwt | |
16 | + | |
17 | + | |
18 | +paths = os.getcwd() | |
19 | + | |
20 | +Action = Namespace( | |
21 | + name="Action", | |
22 | + description="노드 분석을 위해 사용하는 api.", | |
23 | +) | |
24 | + | |
25 | +def find_node(gps_address_y,gps_address_x): | |
26 | + db=DB() | |
27 | + nn_end = None | |
28 | + end_delta = float("inf") | |
29 | + value=0.0001 | |
30 | + near_nodes=[] | |
31 | + while near_nodes==[]: | |
32 | + value=value*10 | |
33 | + near_nodes=db.db_get_near_node(gps_address_y,gps_address_x,value) | |
34 | + | |
35 | + for n in near_nodes: | |
36 | + e_dist = haversine((gps_address_x,gps_address_y), n) | |
37 | + if e_dist < end_delta : | |
38 | + nn_end = n | |
39 | + end_delta = e_dist | |
40 | + return nn_end | |
41 | + | |
42 | + | |
43 | + | |
44 | +@Action.route('/image_summit') | |
45 | +class fileUpload(Resource): | |
46 | + @Action.doc(responses={200: 'Success'}) | |
47 | + @Action.doc(responses={500: 'Register Failed'}) | |
48 | + def post(self): | |
49 | + if request.method == 'POST': | |
50 | + current_time = datetime.now() | |
51 | + timestamp = current_time.strftime("%Y%m%d%H%M%S") | |
52 | +# 시간을 원하는 형식으로 포맷팅하기 (예: 년-월-일 시:분:초) | |
53 | + formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S") | |
54 | + # 포맷팅된 현재 시간 출력 | |
55 | + token = request.headers.get('Authorization') | |
56 | + print(token) | |
57 | + #print(token) | |
58 | + if not token: | |
59 | + return jsonify({'result': 'fail', 'msg': '토큰이 없습니다.'}) | |
60 | + | |
61 | + else: | |
62 | + # Decode the token to verify it | |
63 | + decoded_token = jwt.decode(token, "secret", algorithms=['HS256']) | |
64 | + print(decoded_token) | |
65 | + user_id = decoded_token['id'] | |
66 | + print("현재 시간,저장요청:", formatted_time) | |
67 | + f = request.files['file'] | |
68 | + save_path = f"images/{timestamp}/{user_id}" | |
69 | + os.makedirs(save_path, exist_ok=True) | |
70 | + new_filename = f"{save_path}/{user_id}_{timestamp}.jpg" | |
71 | + print(f) | |
72 | + f.save(new_filename) | |
73 | + print("저장완료", formatted_time) | |
74 | + | |
75 | + return { | |
76 | + 'save': 'done' # str으로 반환하여 return | |
77 | + }, 200 | |
78 | + | |
79 | + | |
80 | + | |
81 | +@Action.route('/image_anal') | |
82 | +class fileUpload(Resource): | |
83 | + @Action.doc(responses={200: 'Success'}) | |
84 | + @Action.doc(responses={500: 'Register Failed'}) | |
85 | + def post(self): | |
86 | + if request.method == 'POST': | |
87 | + current_time = datetime.now() | |
88 | + formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S") | |
89 | + print("현재 시간:", formatted_time) | |
90 | + | |
91 | + | |
92 | + fc = fog_classfication() | |
93 | + dir = os.getcwd() | |
94 | + filename = request.json['filename'] | |
95 | + file_type = request.json['file_type'] | |
96 | + gps_address_x = float(request.json['gps_x']) | |
97 | + gps_address_y = float(request.json['gps_y']) | |
98 | + total_path = dir+ "\\"+ filename + file_type | |
99 | + model_fc= fc.predict(total_path) | |
100 | + | |
101 | + #model_yolo= torch.hub.load(paths +'/yolov5/', 'custom', path=paths+'/yolov5/best.pt', source='local') | |
102 | + #im = Image.open(total_path) | |
103 | + #results = model_yolo(im) | |
104 | + #li_detect=list(results.pandas().xyxy[0]['name']) | |
105 | + if model_fc == "normal": | |
106 | + #if 'vest' in li_detect and 'cone' in li_detect: | |
107 | + nn_end = find_node(gps_address_y,gps_address_x) | |
108 | + return { | |
109 | + 'node': nn_end, | |
110 | + 'fog' : 'normal', | |
111 | + 'construction' : 'construction' | |
112 | + }, 200 | |
113 | + ''' | |
114 | + #else: | |
115 | + return { | |
116 | + 'node': None, | |
117 | + 'fog' : 'normal', | |
118 | + 'construction' : 'normal' | |
119 | + }, 200 | |
120 | + ''' | |
121 | + else: | |
122 | + # if 'vest' in li_detect and 'cone' in li_detect: | |
123 | + nn_end = find_node(gps_address_y,gps_address_x) | |
124 | + db=DB() | |
125 | + current_time = datetime.now() | |
126 | + formatted_time = current_time.strftime("%Y-%m-%d %H:%M:%S") | |
127 | + db.db_add_report(filename,gps_address_x,gps_address_y) | |
128 | + print("현재 시간:", formatted_time) | |
129 | + return { | |
130 | + 'node': nn_end, | |
131 | + 'fog' : 'fog', | |
132 | + 'construction' : 'construction' | |
133 | + }, 200 | |
134 | + | |
135 | + ''' | |
136 | + #else: | |
137 | + nn_end = find_node(gps_address_y,gps_address_x) | |
138 | + return { | |
139 | + 'node': nn_end, | |
140 | + 'fog' : 'fog', | |
141 | + 'construction' : 'normal' | |
142 | + }, 200 | |
143 | +''' | |
144 | + | |
145 | +@Action.route('/pothole_report') | |
146 | +class fileUpload(Resource): | |
147 | + @Action.doc(responses={200: 'Success'}) | |
148 | + @Action.doc(responses={500: 'Register Failed'}) | |
149 | + def post(self): | |
150 | + if request.method == 'POST': | |
151 | + pc = pothole() | |
152 | + dir = os.getcwd() | |
153 | + report_id = request.json['report_id'] | |
154 | + pothole_id = request.json['pothole_id'] | |
155 | + pothole_x = float(request.json['pothole_x']) | |
156 | + pothole_y = float(request.json['pothole_y']) | |
157 | + pc.report(report_id,pothole_id,pothole_x,pothole_y) | |
158 | + return { | |
159 | + 'report': 'done' # str으로 반환하여 return | |
160 | + }, 200 | |
161 | + | |
162 | +@Action.route('/gps_update') | |
163 | +class fileUpload(Resource): | |
164 | + def post(self): | |
165 | + db = DB() | |
166 | + data = request.get_json() | |
167 | + timestamp = data['timestamp'] | |
168 | + trip_id = data['trip_id'] | |
169 | + location_x = float(data['location_x']) | |
170 | + location_y = float(data['location_y']) | |
171 | + token = request.headers.get('Authorization') | |
172 | + print(token) | |
173 | + #print(token) | |
174 | + if not token: | |
175 | + return jsonify({'result': 'fail', 'msg': '토큰이 없습니다.'}) | |
176 | + | |
177 | + else: | |
178 | + # Decode the token to verify it | |
179 | + decoded_token = jwt.decode(token, "secret", algorithms=['HS256']) | |
180 | + print(decoded_token) | |
181 | + user_id = decoded_token['id'] | |
182 | + | |
183 | + # GPS 데이터베이스에 삽입 | |
184 | + db.insert_gps_data(trip_id, location_x, location_y, user_id, timestamp) | |
185 | + return jsonify({'result': 'success'}) | |
186 | + | |
187 | + | |
188 | + | |
189 | +@Action.route('/pothole_display') | |
190 | +class fileUpload(Resource): | |
191 | + @Action.doc(responses={200: 'Success'}) | |
192 | + @Action.doc(responses={500: 'Register Failed'}) | |
193 | + def get(self): | |
194 | + if request.method == 'GET': | |
195 | + pc = pothole() | |
196 | + dir = os.getcwd() | |
197 | + #timestamp = request.json['timestamp'] | |
198 | + value=pc.display() | |
199 | + return { | |
200 | + 'pothole': list(value) # str으로 반환하여 return | |
201 | + }, 200 |
+++ app.py
... | ... | @@ -0,0 +1,32 @@ |
1 | +from flask import Flask, request, abort, jsonify | |
2 | +from flask_restx import Api | |
3 | +from auth import Auth | |
4 | +from trip import Trip | |
5 | +from action import Action | |
6 | +from flask_caching import Cache | |
7 | +import json | |
8 | + | |
9 | +app = Flask(__name__) | |
10 | +cache = Cache(app, config={'CACHE_TYPE': 'simple'}) | |
11 | + | |
12 | +print("Api Start") | |
13 | +api = Api(app, | |
14 | + version='0.1', | |
15 | + title="trafficagent", | |
16 | + description="API Server", | |
17 | + terms_url="/", | |
18 | + contact="dhlim@takensoft.co.kr", | |
19 | + license="MIT") | |
20 | + | |
21 | +print("Api Started") | |
22 | +api.add_namespace(Trip, '/trip') | |
23 | +print("Api Add Trip") | |
24 | + | |
25 | +api.add_namespace(Auth, '/auth') | |
26 | +print("Api Add Auth") | |
27 | + | |
28 | +api.add_namespace(Action, '/action') | |
29 | + | |
30 | +if __name__ == "__main__": | |
31 | + app.run(debug=True, host='192.168.0.195', port=15857) | |
32 | + print("Flask Start") |
+++ auth.py
... | ... | @@ -0,0 +1,121 @@ |
1 | +import hashlib | |
2 | +from flask import request,jsonify,render_template,redirect,url_for | |
3 | +from flask_restx import Resource, Api, Namespace, fields | |
4 | +from database.database import DB | |
5 | +import datetime | |
6 | +import jwt | |
7 | + | |
8 | + | |
9 | + | |
10 | + | |
11 | + | |
12 | +users = {} | |
13 | + | |
14 | +Auth = Namespace( | |
15 | + name="Auth", | |
16 | + description="사용자 인증을 위한 API", | |
17 | +) | |
18 | + | |
19 | + | |
20 | +user_fields = Auth.model('User', { # Model 객체 생성 | |
21 | + 'id': fields.String(description='a User Name', required=True, example="id") | |
22 | +}) | |
23 | + | |
24 | + | |
25 | +user_fields_auth = Auth.inherit('User Auth', user_fields, { | |
26 | + 'password': fields.String(description='Password', required=True) | |
27 | + | |
28 | +}) | |
29 | + | |
30 | +user_fields_register = Auth.inherit('User reigster', user_fields, { | |
31 | + 'password': fields.String(description='Password', required=True),'email': fields.String(description='email', required=True),'user_sex': fields.String(description='sex', required=True),'phone': fields.String(description='phone', required=True) | |
32 | + | |
33 | +}) | |
34 | + | |
35 | + | |
36 | + | |
37 | +@Auth.route('/id') | |
38 | +class AuthCheck(Resource): | |
39 | + @Auth.doc(responses={200: 'Success'}) | |
40 | + @Auth.doc(responses={500: 'Register Failed'}) | |
41 | + def post(self): | |
42 | + db=DB() | |
43 | + id = request.json['id'] | |
44 | + value=db.db_check_id(id) | |
45 | + if value != None: | |
46 | + return { | |
47 | + "message": "중복 아이디가 있습니다" | |
48 | + }, 500 | |
49 | + else: | |
50 | + return { | |
51 | + 'message': '사용가능한 아이디입니다' # str으로 반환하여 return | |
52 | + }, 200 | |
53 | + | |
54 | + | |
55 | + | |
56 | + | |
57 | +@Auth.route('/register') | |
58 | +class AuthRegister(Resource): | |
59 | + @Auth.expect(user_fields_register) | |
60 | + @Auth.doc(responses={200: 'Success'}) | |
61 | + @Auth.doc(responses={500: 'Register Failed'}) | |
62 | + def post(self): | |
63 | + db=DB() | |
64 | + id_ = request.json['id'] | |
65 | + password = request.json['password'] | |
66 | + user_email = request.json['email'] | |
67 | + sex = request.json['sex'] | |
68 | + phone = request.json['phone'] | |
69 | + pw_has = hashlib.sha256(password.encode('utf-8')).hexdigest() | |
70 | + db_check_duplicate = db.db_check_id(id_) | |
71 | + if db_check_duplicate != None: | |
72 | + return { | |
73 | + "message" : "Register Failed : duplicate ID" | |
74 | + }, 500 | |
75 | + db_login_success_flag=db.db_login(id_,password) | |
76 | + if db_login_success_flag != None: | |
77 | + return { | |
78 | + "message": "Register Failed" | |
79 | + }, 500 | |
80 | + else: | |
81 | + db.db_add_id(id,pw_has,user_email,sex,phone) | |
82 | + return { | |
83 | + 'Authorization': id # str으로 반환하여 return | |
84 | + }, 200 | |
85 | + | |
86 | +@Auth.route('/login') | |
87 | +class AuthLogin(Resource): | |
88 | + @Auth.expect(user_fields_auth) | |
89 | + @Auth.doc(responses={200: 'Success'}) | |
90 | + @Auth.doc(responses={404: 'User Not Found'}) | |
91 | + @Auth.doc(responses={500: 'Auth Failed'}) | |
92 | + def post(self): | |
93 | + db=DB() | |
94 | + id = request.json['id'] | |
95 | + password = request.json['password'] | |
96 | + #CRITICAL ... WHY? WHY? | |
97 | + # ... hashing should be handled at client, not server... | |
98 | + pw_hash = hashlib.sha256(password.encode('utf-8')).hexdigest() | |
99 | + result = db.db_login(id,pw_hash) | |
100 | + if result is not None: | |
101 | + payload = { | |
102 | + 'id' : id, | |
103 | + 'exp' : datetime.datetime.utcnow() + datetime.timedelta(days=14) | |
104 | + } | |
105 | + token = jwt.encode(payload, "secret", algorithm='HS256') | |
106 | + return jsonify({'result': 'success', 'token': token}) | |
107 | + else: | |
108 | + return jsonify({'result': 'fail', 'msg': '아이디/비밀번호가 일치하지 않습니다.'}) | |
109 | + | |
110 | + | |
111 | +@Auth.route('/secession') | |
112 | +class AuthSecession(Resource): | |
113 | + def post(self): | |
114 | + db=DB() | |
115 | + id = request.json['token'] | |
116 | + payload = jwt.decode(id, "secret", algorithms=['HS256']) | |
117 | + db.db_delete_id(payload['id']) | |
118 | + return {'secession':'success'} | |
119 | + | |
120 | + | |
121 | + |
+++ blocked_ips.json
... | ... | @@ -0,0 +1,1 @@ |
1 | +["52.228.154.224", "118.235.81.10", "159.65.177.197", "85.204.85.178", "80.76.49.131", "172.245.131.82", "87.121.69.27", "178.128.175.240", "192.168.0.54", "146.70.199.147", "167.94.146.58", "94.156.64.121", "45.148.10.174", "165.229.169.32", "45.156.130.6", "185.59.223.68", "178.215.236.52", "209.141.32.195", "78.108.177.50", "27.0.238.68", "78.108.177.51", "27.0.238.70", "185.196.11.45", "51.159.103.12", "119.246.60.130", "151.235.201.120", "172.168.41.58", "45.88.91.41", "94.156.8.84", "172.212.61.226", "192.210.187.71", "87.236.176.109", "170.64.208.135", "103.252.136.86", "178.62.69.98", "141.98.11.15", "185.244.36.236", "134.122.117.248", "138.199.60.19", "206.168.34.180", "68.69.184.110"](파일 끝에 줄바꿈 문자 없음) |
+++ database/database.py
... | ... | @@ -0,0 +1,215 @@ |
1 | +import psycopg2 # driver 임포트 | |
2 | +import time | |
3 | +from datetime import datetime, timedelta | |
4 | + | |
5 | + | |
6 | +class DB(): | |
7 | + def __init__(self): | |
8 | + self.conn=psycopg2.connect( | |
9 | + host='210.180.118.83', | |
10 | + dbname='TRAFFICAGNET', | |
11 | + user='takensoft', | |
12 | + password='tts96314728!@', | |
13 | + port='5432', | |
14 | + options=f'-c search_path=trafficagent' | |
15 | + ) # db에 접속 | |
16 | + self.conn.autocommit=True | |
17 | + self.schema = 'trafficagent' | |
18 | + ''' | |
19 | + def __init__(self): | |
20 | + self.conn=psycopg2.connect( | |
21 | + host='165.229.169.113', | |
22 | + dbname='traffic_agent', | |
23 | + user='takensoft', | |
24 | + password='ts44301236!@', | |
25 | + port='5432', | |
26 | + options="-c search_path=traffic_agent_v1") # db에 접속 | |
27 | + self.conn.autocommit=True | |
28 | + ''' | |
29 | + | |
30 | + | |
31 | + | |
32 | + def db_check_id(self,id): | |
33 | + cur = self.conn.cursor() # 커서를 생성한다 | |
34 | + | |
35 | + cur.execute(f''' | |
36 | + SELECT user_id | |
37 | + FROM "{self.schema}".user_id | |
38 | + Where user_id = '{id}'; | |
39 | + ''') | |
40 | + result=cur.fetchone() | |
41 | + cur.close() | |
42 | + | |
43 | + return result | |
44 | + | |
45 | + def db_login(self,id,pw): | |
46 | + cur = self.conn.cursor() # 커서를 생성한다 | |
47 | + | |
48 | + cur.execute(f''' | |
49 | + SELECT user_id, user_pw, user_email, user_sex, user_phone, user_time_stamp | |
50 | + FROM "{self.schema}".user_id | |
51 | + Where user_id = '{id}' and user_pw='{pw}'; | |
52 | + ''') | |
53 | + result=cur.fetchone() | |
54 | + | |
55 | + | |
56 | + cur.close() | |
57 | + | |
58 | + return result | |
59 | + | |
60 | + def db_add_id(self,user_id,user_pw,user_email,user_sex,user_phone) : | |
61 | + cur = self.conn.cursor() # 커서를 생성한다 | |
62 | + recievingtime=datetime.now() | |
63 | + d = recievingtime.isoformat(sep=' ', timespec='milliseconds') | |
64 | + # d=recievingtime.strftime("%Y-%m-%d %H:%M:%S.%f") | |
65 | + cur.execute(f''' | |
66 | + insert into "{self.schema}".user_id (user_id,user_pw,user_email,user_sex,user_phone,user_time_stamp) | |
67 | + values ('{user_id}','{user_pw}','{user_email}','{user_sex}','{user_phone}','{d}') | |
68 | + ''') | |
69 | + | |
70 | + def db_add_action(self,user_id,user_pw,user_email,user_sex,user_phone) : | |
71 | + cur = self.conn.cursor() # 커서를 생성한다 | |
72 | + recievingtime=datetime.now() | |
73 | + d = recievingtime.isoformat(sep=' ', timespec='milliseconds') | |
74 | + # d=recievingtime.strftime("%Y-%m-%d %H:%M:%S.%f") | |
75 | + cur.execute(f''' | |
76 | + insert into "{self.schema}".user_id (user_id,user_pw,user_email,user_sex,user_phone,user_time_stamp) | |
77 | + values ('{user_id}','{user_pw}','{user_email}','{user_sex}','{user_phone}','{d}') | |
78 | + ''') | |
79 | + | |
80 | + | |
81 | + cur.close() | |
82 | + def db_delete_id(self,user_id) : | |
83 | + cur = self.conn.cursor() # 커서를 생성한다 | |
84 | + cur.execute(f''' | |
85 | + delete | |
86 | + from "{self.schema}".user_id ui | |
87 | + where user_id = '{user_id}' | |
88 | + ''') | |
89 | + cur.close() | |
90 | + | |
91 | + def db_get_node(self): | |
92 | + cur = self.conn.cursor() # 커서를 생성한다 | |
93 | + | |
94 | + cur.execute(''' | |
95 | + select "index",source_x ,source_y,target_x,target_y," dist " | |
96 | + from "{self.schema}".node n | |
97 | + where flcass != 'pedstrian' | |
98 | + ''') | |
99 | + result=cur.fetchall() | |
100 | + | |
101 | + return result | |
102 | + | |
103 | + def db_get_dest(self,dest1): | |
104 | + cur = self.conn.cursor() # 커서를 생성한다 | |
105 | + | |
106 | + cur.execute(f''' | |
107 | + select j.q,li.q ,li.location_cen_x_4623,li.location_cen_y_4623,li.location_exit_x_4623 ,li.location_exit_y_4623 | |
108 | + from "{self.schema}".jibun j, "{self.schema}".location_info li | |
109 | + where j.build_num =li.build_code and (j.q='{dest1}' or li.q='{dest1}' or li.build_name_city like '{dest1}') | |
110 | + ''') | |
111 | + result=cur.fetchone() | |
112 | + | |
113 | + return (float(result[4]),float(result[5])) | |
114 | + | |
115 | + def db_get_near_node(self,dest_x,dest_y,value): | |
116 | + cur = self.conn.cursor() # 커서를 생성한다 | |
117 | + | |
118 | + cur.execute(f''' | |
119 | + select source_x, source_y | |
120 | + from "{self.schema}".node n | |
121 | + where {dest_x} > source_y - {value} and {dest_x} <= source_y + {value} | |
122 | + and {dest_y} > source_x - {value} and {dest_y} <= source_x + {value} | |
123 | + | |
124 | + ''') | |
125 | + result=cur.fetchall() | |
126 | + return result | |
127 | + | |
128 | + def db_get_address(self,dest1): | |
129 | + cur = self.conn.cursor() # 커서를 생성한다 | |
130 | + | |
131 | + cur.execute(f''' | |
132 | + select j.q,li.q ,li.location_cen_x_4623,li.location_cen_y_4623,li.location_exit_x_4623 ,li.location_exit_y_4623 | |
133 | + from "{self.schema}".jibun j, "{self.schema}".location_info li | |
134 | + where j.build_num =li.build_code and (j.q='{dest1}' or li.q='{dest1}' or li.build_name_city like '{dest1}') | |
135 | + ''') | |
136 | + result=cur.fetchone() | |
137 | + print( (float(result[2]),float(result[3]))) | |
138 | + | |
139 | + return (float(result[2]),float(result[3])) | |
140 | + | |
141 | + def db_add_report(self,report_id,report_x,report_y) : | |
142 | + cur = self.conn.cursor() # 커서를 생성한다 | |
143 | + now=time.localtime() | |
144 | + d=time.strftime('%Y-%m-%d %X', now) | |
145 | + cur.execute(f''' | |
146 | + insert into "{self.schema}".report (report_id,report_x,report_y,timestamp) | |
147 | + values ('{report_id}','{report_x}','{report_y}','{d}') | |
148 | + ''') | |
149 | + | |
150 | + def db_get_near_point(self,dest_x,dest_y): | |
151 | + cur = self.conn.cursor() # 커서를 생성한다 | |
152 | + now=datetime.now() | |
153 | + d_plus=now +timedelta(hours=1) | |
154 | + d_plus=str("'"+d_plus.strftime('%Y-%m-%d %X')+"'") | |
155 | + d_minus=now -timedelta(hours=1) | |
156 | + d_minus=str("'"+d_minus.strftime('%Y-%m-%d %X')+"'") | |
157 | + cur.execute(f''' | |
158 | + select report_x, report_y | |
159 | + from "{self.schema}".report | |
160 | + where {dest_y} > report_y - 0.000498 and {dest_y} <= report_y + 0.000498 | |
161 | + and {dest_x} > report_x - 0.000498 and {dest_x} <= report_x + 0.000498 | |
162 | + and timestamp between {d_minus} and {d_plus}; | |
163 | + | |
164 | + | |
165 | + ''') | |
166 | + result=cur.fetchall() | |
167 | + return result | |
168 | + | |
169 | + | |
170 | + def db_add_pothole(self,pothole_id,pothole_location_x,pothole_location_y) : | |
171 | + cur = self.conn.cursor() # 커서를 생성한다 | |
172 | + now=datetime.now() | |
173 | + d=now.strftime('%Y-%m-%d %X') | |
174 | + cur.execute(f''' | |
175 | + insert into "{self.schema}".pothole (pothole_id,pothole_location_x,pothole_location_y,timestamp) | |
176 | + values ('{pothole_id}','{pothole_location_x}','{pothole_location_y}','{d}') | |
177 | + ''') | |
178 | + | |
179 | + def db_delete_pothole(self,dest_x,dest_y) : | |
180 | + cur = self.conn.cursor() # 커서를 생성한다 | |
181 | + now=datetime.now() | |
182 | + d_plus=now +timedelta(hours=1) | |
183 | + d_plus=str("'"+d_plus.strftime('%Y-%m-%d %X')+"'") | |
184 | + d_minus=now -timedelta(hours=1) | |
185 | + d_minus=str("'"+d_minus.strftime('%Y-%m-%d %X')+"'") | |
186 | + cur.execute(f''' | |
187 | + delete from "{self.schema}".pothole | |
188 | + where {dest_y} > pothole_location_y - 0.000498 and {dest_y} <= pothole_location_y + 0.000498 | |
189 | + and {dest_x} > pothole_location_x - 0.000498 and {dest_x} <= pothole_location_x + 0.000498 | |
190 | + and timestamp between {d_minus} and {d_plus}; | |
191 | + ''') | |
192 | + | |
193 | + def db_display_pothole(self) : | |
194 | + cur = self.conn.cursor() # 커서를 생성한다 | |
195 | + cur.execute(f''' | |
196 | + select report_x,report_y from "{self.schema}".report | |
197 | + ''') | |
198 | + result=cur.fetchall() | |
199 | + return result | |
200 | + | |
201 | + def insert_gps_data(self, trip_id, location_x, location_y,user_id, timestamp): | |
202 | + cur = self.conn.cursor() | |
203 | + | |
204 | + print(trip_id, location_x, location_y, user_id) | |
205 | + trip_id = trip_id['current'] | |
206 | + cur.execute(f''' | |
207 | + INSERT INTO "{self.schema}".gps_data (timestamp, trip_id, location_x, location_y,user_id) | |
208 | + VALUES (%s, %s, %s, %s,%s); | |
209 | + ''', (timestamp, trip_id, location_x, location_y,user_id)) | |
210 | + | |
211 | + cur.close() | |
212 | + return True | |
213 | + | |
214 | + | |
215 | + |
+++ gcity.py
... | ... | @@ -0,0 +1,153 @@ |
1 | +import networkx as nx | |
2 | +import math | |
3 | +from itertools import tee | |
4 | +from numpy import Inf, Infinity, inf | |
5 | +from database.database import DB | |
6 | +import pandas as pd | |
7 | +from haversine import haversine | |
8 | +import time | |
9 | +import pandas as pd | |
10 | +import os | |
11 | + | |
12 | +paths= os.getcwd() | |
13 | + | |
14 | +def dist(a, b): | |
15 | + (x1, y1) = a | |
16 | + (x2, y2) = b | |
17 | + return ((x1 - x2) ** 2 + (y1 - y2) ** 2) ** 0.5 | |
18 | + | |
19 | +def swith_xy(tuples): | |
20 | + x,y=tuples | |
21 | + return (y,x) | |
22 | + | |
23 | +def pairwise( iterable ): | |
24 | + """Returns an iterable access binary tuple | |
25 | + s -> (s0,s1), (s1,s2), (s2, s3), ...""" | |
26 | + a, b = tee( iterable ) | |
27 | + next(b, None) | |
28 | + return zip(a, b) | |
29 | + | |
30 | + | |
31 | + | |
32 | +class path_finder(): | |
33 | + def __init__(self): | |
34 | + start_time=time.time() | |
35 | + self.db=DB() | |
36 | + self.G=nx.read_gpickle(paths + '\\navigation_model\\OSM_gpickle.gpickle') | |
37 | + | |
38 | + print("done") | |
39 | + print(time.time()-start_time) | |
40 | + | |
41 | + | |
42 | + | |
43 | + def get_trip(self,dest1,dest2): | |
44 | + | |
45 | + start_time=time.time() | |
46 | + dest1=swith_xy(self.db.db_get_dest(dest1)) | |
47 | + dest2=swith_xy(self.db.db_get_dest(dest2)) | |
48 | + value=0.0001 | |
49 | + | |
50 | + start_near_nodes=[] | |
51 | + while start_near_nodes == []: | |
52 | + value=value*10 | |
53 | + start_near_nodes=self.db.db_get_near_node(dest1[1],dest1[0],value) | |
54 | + else: | |
55 | + start_near_nodes=self.db.db_get_near_node(dest1[1],dest1[0],value) | |
56 | + | |
57 | + nn_start = None | |
58 | + nn_end = None | |
59 | + start_delta = float("inf") | |
60 | + end_delta = float("inf") | |
61 | + | |
62 | + | |
63 | + | |
64 | + for n in start_near_nodes: | |
65 | + s_dist = haversine(dest1, n) | |
66 | + if s_dist < start_delta : | |
67 | + nn_start = n | |
68 | + start_delta = s_dist | |
69 | + value=0.0001 | |
70 | + end_near_nodes=[] | |
71 | + while end_near_nodes==[]: | |
72 | + value=value*10 | |
73 | + self.db.db_get_near_node(dest2[1],dest2[0],value) | |
74 | + end_near_nodes=self.db.db_get_near_node(dest2[1],dest2[0],value) | |
75 | + | |
76 | + for n in end_near_nodes: | |
77 | + e_dist = haversine(dest2, n) | |
78 | + if e_dist < end_delta : | |
79 | + nn_end = n | |
80 | + end_delta = e_dist | |
81 | + | |
82 | + path = list(nx.astar_path(self.G,nn_start,nn_end,heuristic=dist,weight='length')) | |
83 | + return path | |
84 | + | |
85 | + def get_dest(self, dest1): | |
86 | + dest1=swith_xy(self.db.db_get_address(dest1)) | |
87 | + return dest1 | |
88 | + | |
89 | +db=DB() | |
90 | +df = pd.read_csv('D:\\takensoft\\project2\\경산 길찾기\\경산시_체크.csv',encoding='euc-kr') | |
91 | +li_start=[] | |
92 | +li_dest1=[] | |
93 | +for i in range(len(df)): | |
94 | + try: | |
95 | + print(i) | |
96 | + dest1=df['start'][i] | |
97 | + li_dest1.append(dest1) | |
98 | + dest1=swith_xy(db.db_get_dest(dest1)) | |
99 | + value=0.0001 | |
100 | + start_near_nodes=[] | |
101 | + while start_near_nodes == []: | |
102 | + value=value*10 | |
103 | + start_near_nodes=db.db_get_near_node(dest1[1],dest1[0],value) | |
104 | + nn_start = None | |
105 | + start_delta = float("inf") | |
106 | + for n in start_near_nodes: | |
107 | + s_dist = haversine(dest1, n) | |
108 | + if s_dist < start_delta : | |
109 | + nn_start = n | |
110 | + start_delta = s_dist | |
111 | + li_start.append(nn_start) | |
112 | + except: | |
113 | + continue | |
114 | + | |
115 | +df_check=pd.DataFrame({'start':li_dest1,'시작지점':li_start}) | |
116 | + | |
117 | +df_check.to_csv('test.csv',encoding='euc-kr') | |
118 | + | |
119 | + | |
120 | +''' | |
121 | +df=pd.read_csv('D:\\takensoft\\project2\\경산 길찾기\\경산시.csv',encoding='euc-kr') | |
122 | + | |
123 | +p=path_finder() | |
124 | +li_path=[] | |
125 | +for i in range(len(df)): | |
126 | + try: | |
127 | + if i%100 ==0: | |
128 | + print(i) | |
129 | + df2=pd.DataFrame(li_path) | |
130 | + df2.to_csv(f'D:\\takensoft\\project2\\경산 길찾기\\길찾기 결과{i}.csv',encoding='euc-kr') | |
131 | + li_path=[] | |
132 | + start=df['start'][i] | |
133 | + end=df['end'][i] | |
134 | + li_path.append(p.get_trip(start,end)) | |
135 | + except: | |
136 | + continue | |
137 | +li_start_x = [] | |
138 | +li_start_y = [] | |
139 | +li_end_x = [] | |
140 | +li_end_y = [] | |
141 | + | |
142 | +db=DB() | |
143 | +#df.to_csv('D:\\takensoft\\project2\\경산 길찾기\\길찾기 결과.csv',encoding='euc-kr') | |
144 | + | |
145 | +df=pd.read_csv('D:\\takensoft\\project2\\경산 길찾기\\경산시.csv',encoding='euc-kr') | |
146 | +for i in range(len(df)): | |
147 | + li_start_x.append(db.db_get_dest(df['start'][i])[0]) | |
148 | + li_start_y.append(db.db_get_dest(df['start'][i])[1]) | |
149 | + li_end_x.append(db.db_get_dest(df['end'][i])[0]) | |
150 | + li_end_y.append([db.db_get_dest(df['end'][i])[1]]) | |
151 | +df2 = pd.DataFrame({'start_point_x':li_start_x,'start_point_y':li_start_y,'end_point_x':li_end_x,'end_point_y':li_end_y}) | |
152 | +df2.to_csv('D:\\takensoft\\project2\\경산 길찾기\\출발지도착지좌표.csv',encoding='euc-kr') | |
153 | +'''(파일 끝에 줄바꿈 문자 없음) |
+++ logger/logger.py
... | ... | @@ -0,0 +1,13 @@ |
1 | +from datetime import datetime | |
2 | +import os | |
3 | + | |
4 | +if not os.path.exists("logs"): | |
5 | + os.makedirs("logs") | |
6 | + os.makedirs("logs/gunicorn") | |
7 | + | |
8 | +bind = "192.168.0.195:15857" | |
9 | +workers = 2 | |
10 | +reload = True | |
11 | +accesslog = f"./logs/gunicorn/access_{datetime.now().strftime('%Y-%m-%d_%H')}.log" | |
12 | +errorlog = f"./logs/gunicorn/error_{datetime.now().strftime('%Y-%m-%d_%H')}.log" | |
13 | +loglevel = "info" |
+++ requirements.txt
... | ... | @@ -0,0 +1,41 @@ |
1 | +aniso8601==9.0.1 | |
2 | +attrs==23.2.0 | |
3 | +blinker==1.8.2 | |
4 | +cachelib==0.9.0 | |
5 | +click==8.1.7 | |
6 | +Flask==3.0.3 | |
7 | +Flask-Caching==2.3.0 | |
8 | +flask-restx==1.3.0 | |
9 | +haversine==2.8.1 | |
10 | +imageio==2.34.1 | |
11 | +importlib_resources==6.4.0 | |
12 | +itsdangerous==2.2.0 | |
13 | +Jinja2==3.1.4 | |
14 | +joblib==1.4.2 | |
15 | +jsonschema==4.22.0 | |
16 | +jsonschema-specifications==2023.12.1 | |
17 | +lazy_loader==0.4 | |
18 | +MarkupSafe==2.1.5 | |
19 | +networkx==3.3 | |
20 | +numpy==1.23.3 | |
21 | +opencv-python==4.10.0.82 | |
22 | +packaging==24.1 | |
23 | +pandas==2.2.2 | |
24 | +pillow==10.3.0 | |
25 | +psycopg2-binary==2.9.9 | |
26 | +PyJWT==2.8.0 | |
27 | +python-dateutil==2.9.0.post0 | |
28 | +pytz==2024.1 | |
29 | +referencing==0.35.1 | |
30 | +rpds-py==0.18.1 | |
31 | +scikit-image==0.23.2 | |
32 | +scikit-learn==1.5.0 | |
33 | +scipy==1.13.1 | |
34 | +six==1.16.0 | |
35 | +threadpoolctl==3.5.0 | |
36 | +tifffile==2024.5.22 | |
37 | +torch==1.12.1 | |
38 | +typing_extensions==4.12.2 | |
39 | +tzdata==2024.1 | |
40 | +Werkzeug==3.0.3 | |
41 | + |
+++ trip.py
... | ... | @@ -0,0 +1,78 @@ |
1 | +from flask import request | |
2 | +from flask_restx import Resource, Api, Namespace, fields | |
3 | +from navigation_model.model_trip import path_finder | |
4 | +import time | |
5 | +import numpy as np | |
6 | +import networkx | |
7 | + | |
8 | +todos = {} | |
9 | +count = 1 | |
10 | + | |
11 | +not_in_list=[] | |
12 | + | |
13 | + | |
14 | +#trip = path_finder() | |
15 | + | |
16 | + | |
17 | + | |
18 | +Trip = Namespace( | |
19 | + name="trip", | |
20 | + description="경로 노드를 받기위한 사용하는 API.", | |
21 | +) | |
22 | + | |
23 | +trip_fields = Trip.model('Trip', { # Model 객체 생성 | |
24 | + 'path_start': fields.String(description='a Todo', required=True),'path_end' : fields.String(description='a Todo', required=True) | |
25 | +}) | |
26 | + | |
27 | + | |
28 | + | |
29 | +@Trip.route('/trip') | |
30 | +class TripPost(Resource): | |
31 | + @Trip.expect(trip_fields) | |
32 | + @Trip.response(201, 'Success', trip_fields) | |
33 | + def post(self): | |
34 | + """경로를 받습니다""" | |
35 | + start_time=time.time() | |
36 | + start = request.json['path_start'] | |
37 | + end = request.json['path_end'] | |
38 | + | |
39 | + return { | |
40 | + 'nodes' : trip.get_trip(start,end), | |
41 | + 'start_point' : trip.get_dest(start), | |
42 | + 'end_point' : trip.get_dest(end) | |
43 | + | |
44 | + | |
45 | + }, 201 | |
46 | +@Trip.route('/trip2') | |
47 | +class TripPost(Resource): | |
48 | + @Trip.expect(trip_fields) | |
49 | + @Trip.response(201, 'Success', trip_fields) | |
50 | + def post(self): | |
51 | + """경로를 받습니다""" | |
52 | + start_time=time.time() | |
53 | + start_x = request.json['dest1_x'] | |
54 | + start_y = request.json['dest1_y'] | |
55 | + end = request.json['path_end'] | |
56 | + return { | |
57 | + 'nodes' : trip.get_trip_2(start_x,start_y,end,not_in_list), | |
58 | + 'start_point' : (start_x,start_y), | |
59 | + 'end_point' : trip.get_dest(end) | |
60 | + | |
61 | + | |
62 | + }, 201 | |
63 | + | |
64 | + | |
65 | +@Trip.route('/remove') | |
66 | +class removenodePost(Resource): | |
67 | + def post(self): | |
68 | + """경로를 받습니다""" | |
69 | + gps_x = request.json['gps_x'] | |
70 | + gps_y = request.json['gps_y'] | |
71 | + trip.G.remove_node((float(gps_x),float(gps_y))) | |
72 | + not_in_list.append((float(gps_x),float(gps_y))) | |
73 | + | |
74 | + return { | |
75 | + "done" : "done" | |
76 | + }, 201 | |
77 | + | |
78 | + |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?