From ebb253defd3f0dec30208bbcb6d1adf227afd873 Mon Sep 17 00:00:00 2001 From: hscrown Date: Fri, 24 May 2024 19:34:01 +0900 Subject: [PATCH 1/8] fix bug weather.py --- FlaskApps/weather.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/FlaskApps/weather.py b/FlaskApps/weather.py index 5a97aa5..177e229 100644 --- a/FlaskApps/weather.py +++ b/FlaskApps/weather.py @@ -71,7 +71,7 @@ def get_weather(): temp = 14 rain_mapping = { - '0': "강수없음", + '0': "강수없음", '1': "비", '2': "비 또는 눈", '3': "눈", @@ -124,7 +124,7 @@ def get_weather(): park_lat, lib_lat, muse_lat = None, None, None park_long, lib_long, muse_long = None, None, None park_adres, lib_adres, muse_adres = None, None, None - if (sky in ['맑음', '흐림']) and (rain == ' ') and (15 <= float(temp) <= 29): + if (sky in ['맑음', '흐림']) and (rain == '강수없음') and (15 <= float(temp) <= 29): # 공원 정보 불러오기 및 추천 로직 park_url = 'http://openAPI.seoul.go.kr:8088/57524f76506d656e3732636a52457a/json/SearchParkInfoService/1/1000/' park_response = requests.get(park_url) @@ -144,7 +144,7 @@ def get_weather(): if distance < min_distance: min_distance = distance park_name, park_lat, park_long, park_adres = row['NAME'], row['LATITUDE'], row['LONGITUDE'], row['ADRES'] - elif rain != '비가 오고 있지 않습니다.': + elif rain != '강수없음': # 도서관 정보 불러오기 및 추천 로직 lib_url = 'http://openAPI.seoul.go.kr:8088/57524f76506d656e3732636a52457a/json/SeoulLibraryTimeInfo/1/1000/' lib_response = requests.get(lib_url) From f6c0e6a9b2b05d5ff44ab8a62b06f5a6b6ac2e69 Mon Sep 17 00:00:00 2001 From: hscrown Date: Mon, 27 May 2024 03:36:42 +0900 Subject: [PATCH 2/8] feat: intergrate flask weather.py with index.tsx --- FlaskApps/weather.py | 4 +- app/(tabs)/index.tsx | 118 ++++++++++++++++++++++++++++--------------- flask.config.ts | 2 +- 3 files changed, 79 insertions(+), 45 deletions(-) diff --git a/FlaskApps/weather.py b/FlaskApps/weather.py index 177e229..89fa1f3 100644 --- a/FlaskApps/weather.py +++ b/FlaskApps/weather.py @@ -21,8 +21,8 @@ def get_weather(): kor_loc = pd.DataFrame(dataset['train']) kor_loc = kor_loc.iloc[:,:15].dropna() - mylat = request.args.get('lat', type=str) - mylong = request.args.get('long', type=str) + mylat = request.args.get('latitude') + mylong = request.args.get('longitude') if not mylat: print("response error:not valid user lat") diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index 188a129..204b3ee 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -1,18 +1,21 @@ +import React, { useEffect, useState } from 'react'; import { Image, - ScrollView, StyleSheet, Text, TextInput, TouchableOpacity, View, } from 'react-native'; -import React, { useEffect, useState } from 'react'; -import { Stack } from 'expo-router'; -import { Ionicons, FontAwesome } from '@expo/vector-icons'; -import Colors from '@/constants/Colors'; +import { FontAwesome } from '@expo/vector-icons'; import { useHeaderHeight } from '@react-navigation/elements'; import { router } from "expo-router"; +import * as Location from 'expo-location'; +import axios from 'axios'; +import Colors from '@/constants/Colors'; +import FlaskConfig from '@/flask.config'; + + const handleWeather = () => { router.push("weathers"); @@ -20,20 +23,49 @@ const handleWeather = () => { const handleMaps = () => { router.push("maps"); -} +}; -const handlePlace =() => { +const handlePlace = () => { router.push("place"); -} +}; const handleBorough = () => { router.push("borough"); -} +}; const Page = () => { const headerHeight = useHeaderHeight(); const [category, setCategory] = useState('전체'); const [loading, setLoading] = useState(false); + const [location, setLocation] = useState(null); + const [errorMsg, setErrorMsg] = useState(null); + const [address, setAddress] = useState('Waiting...'); + + useEffect(() => { + (async () => { + let { status } = await Location.requestForegroundPermissionsAsync(); + if (status !== 'granted') { + setErrorMsg('Permission to access location was denied'); + return; + } + + let location = await Location.getCurrentPositionAsync({}); + setLocation(location); + + if (location) { + const { latitude, longitude } = location.coords; + try { + const response = await axios.get( + `http://${FlaskConfig.Private_IP_Address}:${FlaskConfig.weather}/weather?latitude=${latitude}&longitude=${longitude}` + ); + const { guName, dongName } = response.data; + setAddress(`서울시 ${guName} ${dongName}`); + } catch (error) { + setErrorMsg('Error fetching address'); + } + } + })(); + }, []); const onCatChanged = (category: string) => { setCategory(category); @@ -41,45 +73,47 @@ const Page = () => { return ( <> - + - - - - 구파발역.서울특별시 은평구 지하 101 - - - - - Lemon MuL - :Free to Go everywhere! - - 시작하기 - - - - - 서울시 탐색 - - - 리뷰 / 평가 - - - 날씨 기반 추천 서비스 - - - 사용자 맞춤 추천 서비스 - + + + + + {errorMsg ? errorMsg : address} + + + + + + Lemon MuL + :Free to Go everywhere! + + 시작하기 + + + + + 서울시 탐색 + + + 리뷰 / 평가 + + + 날씨 기반 추천 서비스 + + + 사용자 맞춤 추천 서비스 + + - ); }; diff --git a/flask.config.ts b/flask.config.ts index 239f42f..bd8964c 100644 --- a/flask.config.ts +++ b/flask.config.ts @@ -1,6 +1,6 @@ // fetch url value const PythonConfig = { - Private_IP_Address: '192.000.0.0', + Private_IP_Address: '192.168.35.247', weather: '5001', svd: '5002', gu: '5003', From df904beacac811dfa088198f96dd302c1d78b1d2 Mon Sep 17 00:00:00 2001 From: hscrown Date: Mon, 27 May 2024 03:57:31 +0900 Subject: [PATCH 3/8] feat:update weather.py & add weatherrec.py --- FlaskApps/weather.py | 91 ++++--------------------------------- FlaskApps/weatherrec.py | 99 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 83 deletions(-) create mode 100644 FlaskApps/weatherrec.py diff --git a/FlaskApps/weather.py b/FlaskApps/weather.py index 89fa1f3..2ec0eff 100644 --- a/FlaskApps/weather.py +++ b/FlaskApps/weather.py @@ -1,7 +1,6 @@ from flask import Flask, jsonify, request import requests import pandas as pd -import numpy as np from datetime import datetime from lxml import etree from haversine import haversine @@ -9,9 +8,8 @@ app = Flask(__name__) -@app.route('/weather',methods=['GET']) +@app.route('/weather', methods=['GET']) def get_weather(): - # 오늘 날짜와 시간 불러오기 what_date = datetime.now().strftime("%Y%m%d") what_time = datetime.now().strftime("%H%M") @@ -25,12 +23,11 @@ def get_weather(): mylong = request.args.get('longitude') if not mylat: - print("response error:not valid user lat") + print("response error: not valid user lat") mylat = '37.51490409227562' if not mylong: - print("response error:not valid user long") + print("response error: not valid user long") mylong = '126.84135103588255' - # 내 좌표 설정 my_loc = (float(mylat), float(mylong)) @@ -71,7 +68,7 @@ def get_weather(): temp = 14 rain_mapping = { - '0': "강수없음", + '0': "강수없음", '1': "비", '2': "비 또는 눈", '3': "눈", @@ -84,8 +81,6 @@ def get_weather(): # 초단기예보데이터 url2 = 'http://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getUltraSrtFcst' - - response2 = requests.get(url2, params=params) root2 = etree.fromstring(response2.content) @@ -104,7 +99,6 @@ def get_weather(): "ny": item.findtext("ny") } for item in items] - # 데이터프레임으로 만들기 df = pd.DataFrame(data) @@ -119,86 +113,17 @@ def get_weather(): except (KeyError, IndexError): sky = "흐림" - # 날씨 정보에 따른 장소 추천 로직 - park_name, lib_name, muse_name = None, None, None - park_lat, lib_lat, muse_lat = None, None, None - park_long, lib_long, muse_long = None, None, None - park_adres, lib_adres, muse_adres = None, None, None - if (sky in ['맑음', '흐림']) and (rain == '강수없음') and (15 <= float(temp) <= 29): - # 공원 정보 불러오기 및 추천 로직 - park_url = 'http://openAPI.seoul.go.kr:8088/57524f76506d656e3732636a52457a/json/SearchParkInfoService/1/1000/' - park_response = requests.get(park_url) - park_data = park_response.json()['SearchParkInfoService']['row'] - park = pd.DataFrame(park_data) - park.rename(columns={'P_PARK': "NAME", 'P_ADDR': "ADRES", 'XCNTS': 'LATITUDE', 'YDNTS': "LONGITUDE"}, inplace=True) - park['LATITUDE'].replace('', np.nan, inplace=True) - park['LONGITUDE'].replace('', np.nan, inplace=True) - park = park.dropna() - park['LATITUDE'] = park['LATITUDE'].astype(float) - park['LONGITUDE'] = park['LONGITUDE'].astype(float) - # 가장 가까운 위치 찾기 - min_distance = float('inf') - for index, row in park.iterrows(): - point = (row['LATITUDE'], row['LONGITUDE']) - distance = haversine(my_loc, point) - if distance < min_distance: - min_distance = distance - park_name, park_lat, park_long, park_adres = row['NAME'], row['LATITUDE'], row['LONGITUDE'], row['ADRES'] - elif rain != '강수없음': - # 도서관 정보 불러오기 및 추천 로직 - lib_url = 'http://openAPI.seoul.go.kr:8088/57524f76506d656e3732636a52457a/json/SeoulLibraryTimeInfo/1/1000/' - lib_response = requests.get(lib_url) - lib_data = lib_response.json()['SeoulLibraryTimeInfo']['row'] - lib = pd.DataFrame(lib_data) - lib_url2 = 'http://openAPI.seoul.go.kr:8088/57524f76506d656e3732636a52457a/json/SeoulLibraryTimeInfo/1001/2000/' - lib_response2 = requests.get(lib_url2) - lib_data2 = lib_response2.json()['SeoulLibraryTimeInfo']['row'] - lib2 = pd.DataFrame(lib_data2) - lib = pd.concat([lib,lib2]) - lib.rename(columns={'LBRRY_NAME': "NAME", 'ADRES': "ADRES", 'XCNTS': 'LATITUDE', 'YDNTS': "LONGITUDE"}, inplace=True) - lib['LATITUDE'] = lib['LATITUDE'].astype(float) - lib['LONGITUDE'] = lib['LONGITUDE'].astype(float) - # 가장 가까운 위치 찾기 - min_distance = float('inf') - for index, row in lib.iterrows(): - point = (row['LATITUDE'], row['LONGITUDE']) - distance = haversine(my_loc, point) - if distance < min_distance: - min_distance = distance - lib_name, lib_lat, lib_long, lib_adres = row['NAME'], row['LATITUDE'], row['LONGITUDE'], row['ADRES'] - else: - # 박물관 정보 불러오기 및 추천 로직 - muse_url = 'http://openAPI.seoul.go.kr:8088/57524f76506d656e3732636a52457a/json/SeoulMuseumInfo/1/1000/' - muse_response = requests.get(muse_url) - muse_data = muse_response.json()['SeoulMuseumInfo']['row'] - muse = pd.DataFrame(muse_data) - muse.rename(columns={'MUSEUM_NAME': "NAME", 'ADDR': "ADRES", 'XCNTS': 'LATITUDE', 'YDNTS': "LONGITUDE"}, inplace=True) - muse['LATITUDE'] = muse['LATITUDE'].astype(float) - muse['LONGITUDE'] = muse['LONGITUDE'].astype(float) - # 가장 가까운 위치 찾기 - min_distance = float('inf') - for index, row in muse.iterrows(): - point = (row['LATITUDE'], row['LONGITUDE']) - distance = haversine(my_loc, point) - if distance < min_distance: - min_distance = distance - muse_name, muse_lat, muse_long, muse_adres = row['NAME'], row['LATITUDE'], row['LONGITUDE'], row['ADRES'] - # 결과 출력 result = { "sky": sky, "rain": rain, "temp": temp, - "name": park_name or lib_name or muse_name, - "latitude": park_lat or lib_lat or muse_lat, - "longitude": park_long or lib_long or muse_long, - "address": park_adres or lib_adres or muse_adres, - "place_type": "공원" if park_name else "도서관" if lib_name else "박물관", - "guName" : guName, - "dongName": dongName + "guName": guName, + "dongName": dongName } response = jsonify(result) - response.headers.add('Content-Type', 'application/json; charset=ASCII') #인코딩 문제 해결 + response.headers.add('Content-Type', 'application/json; charset=ASCII') # 인코딩 문제 해결 return response + if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=5001) diff --git a/FlaskApps/weatherrec.py b/FlaskApps/weatherrec.py new file mode 100644 index 0000000..bd09ed9 --- /dev/null +++ b/FlaskApps/weatherrec.py @@ -0,0 +1,99 @@ +# weatherrec.py +from flask import Flask, jsonify, request +import requests +import pandas as pd +import numpy as np +from haversine import haversine + +app = Flask(__name__) + +@app.route('/weatherrec', methods=['GET']) +def get_place_recommendation(): + mylat = request.args.get('latitude') + mylong = request.args.get('longitude') + sky = request.args.get('sky') + rain = request.args.get('rain') + temp = request.args.get('temp') + + if not mylat or not mylong or not sky or not rain or not temp: + return jsonify({"error": "Missing required parameters"}), 400 + + # 내 좌표 설정 + my_loc = (float(mylat), float(mylong)) + + park_name, lib_name, muse_name = None, None, None + park_lat, lib_lat, muse_lat = None, None, None + park_long, lib_long, muse_long = None, None, None + park_adres, lib_adres, muse_adres = None, None, None + + if (sky in ['맑음', '흐림']) and (rain == '강수없음') and (15 <= float(temp) <= 29): + # 공원 정보 불러오기 및 추천 로직 + park_url = 'http://openAPI.seoul.go.kr:8088/57524f76506d656e3732636a52457a/json/SearchParkInfoService/1/1000/' + park_response = requests.get(park_url) + park_data = park_response.json()['SearchParkInfoService']['row'] + park = pd.DataFrame(park_data) + park.rename(columns={'P_PARK': "NAME", 'P_ADDR': "ADRES", 'XCNTS': 'LATITUDE', 'YDNTS': "LONGITUDE"}, inplace=True) + park['LATITUDE'].replace('', np.nan, inplace=True) + park['LONGITUDE'].replace('', np.nan, inplace=True) + park = park.dropna() + park['LATITUDE'] = park['LATITUDE'].astype(float) + park['LONGITUDE'] = park['LONGITUDE'].astype(float) + # 가장 가까운 위치 찾기 + min_distance = float('inf') + for index, row in park.iterrows(): + point = (row['LATITUDE'], row['LONGITUDE']) + distance = haversine(my_loc, point) + if distance < min_distance: + min_distance = distance + park_name, park_lat, park_long, park_adres = row['NAME'], row['LATITUDE'], row['LONGITUDE'], row['ADRES'] + elif rain != '강수없음': + # 도서관 정보 불러오기 및 추천 로직 + lib_url = 'http://openAPI.seoul.go.kr:8088/57524f76506d656e3732636a52457a/json/SeoulLibraryTimeInfo/1/1000/' + lib_response = requests.get(lib_url) + lib_data = lib_response.json()['SeoulLibraryTimeInfo']['row'] + lib = pd.DataFrame(lib_data) + lib_url2 = 'http://openAPI.seoul.go.kr:8088/57524f76506d656e3732636a52457a/json/SeoulLibraryTimeInfo/1001/2000/' + lib_response2 = requests.get(lib_url2) + lib_data2 = lib_response2.json()['SeoulLibraryTimeInfo']['row'] + lib2 = pd.DataFrame(lib_data2) + lib = pd.concat([lib,lib2]) + lib.rename(columns={'LBRRY_NAME': "NAME", 'ADRES': "ADRES", 'XCNTS': 'LATITUDE', 'YDNTS': "LONGITUDE"}, inplace=True) + lib['LATITUDE'] = lib['LATITUDE'].astype(float) + lib['LONGITUDE'] = lib['LONGITUDE'].astype(float) + # 가장 가까운 위치 찾기 + min_distance = float('inf') + for index, row in lib.iterrows(): + point = (row['LATITUDE'], row['LONGITUDE']) + distance = haversine(my_loc, point) + if distance < min_distance: + min_distance = distance + lib_name, lib_lat, lib_long, lib_adres = row['NAME'], row['LATITUDE'], row['LONGITUDE'], row['ADRES'] + else: + # 박물관 정보 불러오기 및 추천 로직 + muse_url = 'http://openAPI.seoul.go.kr:8088/57524f76506d656e3732636a52457a/json/SeoulMuseumInfo/1/1000/' + muse_response = requests.get(muse_url) + muse_data = muse_response.json()['SeoulMuseumInfo']['row'] + muse = pd.DataFrame(muse_data) + muse.rename(columns={'MUSEUM_NAME': "NAME", 'ADDR': "ADRES", 'XCNTS': 'LATITUDE', 'YDNTS': "LONGITUDE"}, inplace=True) + muse['LATITUDE'] = muse['LATITUDE'].astype(float) + muse['LONGITUDE'] = muse['LONGITUDE'].astype(float) + # 가장 가까운 위치 찾기 + min_distance = float('inf') + for index, row in muse.iterrows(): + point = (row['LATITUDE'], row['LONGITUDE']) + distance = haversine(my_loc, point) + if distance < min_distance: + min_distance = distance + muse_name, muse_lat, muse_long, muse_adres = row['NAME'], row['LATITUDE'], row['LONGITUDE'], row['ADRES'] + + result = { + "name": park_name or lib_name or muse_name, + "latitude": park_lat or lib_lat or muse_lat, + "longitude": park_long or lib_long or muse_long, + "address": park_adres or lib_adres or muse_adres, + "place_type": "공원" if park_name else "도서관" if lib_name else "박물관" + } + return jsonify(result) + +if __name__ == '__main__': + app.run(debug=True, host='0.0.0.0', port=5000) From 59c418851adfce6f4d4cc0300379f44a146eb44e Mon Sep 17 00:00:00 2001 From: hscrown Date: Mon, 27 May 2024 04:07:41 +0900 Subject: [PATCH 4/8] refactor weather.py & weatherrec.py --- .../__pycache__/weatherrec.cpython-312.pyc | Bin 0 -> 4734 bytes FlaskApps/weather.py | 7 +++++- FlaskApps/weatherrec.py | 23 ++---------------- 3 files changed, 8 insertions(+), 22 deletions(-) create mode 100644 FlaskApps/__pycache__/weatherrec.cpython-312.pyc diff --git a/FlaskApps/__pycache__/weatherrec.cpython-312.pyc b/FlaskApps/__pycache__/weatherrec.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..73e65e3b09179b4a47f07a6852f1afe3d55b9090 GIT binary patch literal 4734 zcmdT|TWk|o8lJJo_V|)Gi5;BS&OHQNAP#|C2+$=oA%v1FiW4qLN;-HZ!M7PRGY(0Z zS>*v$jut6Fs|q8iaHVQVMIWe^l~Sn>^ktP*_hAMj#XDssr0&CVS&5c6p7xyaB_Txt zR;<)LlF$F2|NqZ_zW*}EV}D;zU_!un@riHTQ;Z-#!bNUqvdr^Fz+6E{gha#0aE7A8 z8g;E5#sJlXbrIdL4n;`qMPyh%je4+0aC5&0Rg7neNs8qHH08k0msj~0BM{{?Ws zIXVhfA|~oYeU>+fxM% zmiKF>G$AK~uzFGlDX=_DYf(VyE>bTR@eqePf@=|GWkONTk60`e2O;it<5qS}8p;7j z;&2vAcw^2isHQl#%21&s@6{&Qf(0*Y;fgepCeln=$b#z_S@@OpR<;}{BG^bXJR@j* z#jYa0C?^e;(*5DRrg|D-fO*3zhOnoe^Jr;x2h_a@2{T^+9f4@f)(}U;q$<518Kf9!||Nd;@$sfOsS%CEM?N6V^ z6Hl*v0(6hy7ucf;FwGEWc|O|V^)gY4?mX7p$Wcrz+&IBBhS-kwruKGkOIu6x?(w$P zmZny+wWXEX)wZj-byq6^q%CcPH^?!x*GCbo|Lie>4fWFFjE`a`1AfZ8)4Q{&smZI9 zzEZ7dS?0Wg^>_AlE4t3Efo`9IAMG6M9USWFR*Xk~+ux(I9!$|68#~rH@FAp~U0nl; z?&JskgFZ!fstb@ok47>0nQ$yZbBZBAN5h1lQVd>fe=d1nav zVjLBVycD!m4SH1ppqTrHeBDERDi#HU)mjCkHss?!{rTy&g&2HAdoq9V>BZ}h@62Xa zw?BRI)wf{f(J2^BL?{Ih6MTS=k(6Q#GxS7;H4r4pQXHq4)IyK((^1M}RdnNFhTs*P zrOw4Dj^`BZ1jQ>DY)(ZJB^6^A!4rpA=vL2Cs(S-VWqL(JM-?qi(2Aa9nJ7&tdV+&) z6+FOGEND`Wh3{>O-p|l}g7-8i`pEQHnDHxGE;OxRED@j;jHe<|#TW&Tz*rW2;7o=y zMnLMaLRAmqQVe0Bh77K1A(z<6bY*;B! zIba%PXbxmhU6LRP3I(%HpH`d*Ybt zIPI=Zx@7l`758r0z5C8k%Doq8pwoXk+=-z-2ysi=S$Si})g9NoKO;Kh3_5ot-o3CZ zU0RlKULH&O7q`g`t&+Vh-u=K)o!qoonsRvKhtpO^Vmk;fUA1MwlHPyd?xt@>mg|;- zfAvZur=_u=JQ9*3QR&>29GRB(Ps>FeAj$2?Q(v2YHp4@nSrAjb*C(&m`i2WS8abh}T z``)E)*?w?+VzQmOcxb6-IVkyQ+097PBJ9-P{U5d1vrLN>A;r#nMa_wmU|K9s+uir< zyOIVlEw-miEAN%ICAWfUF_5-Z+_SYO%fYl5{Cn-T%V)pCzjiH$elqI|^|Obb6(W|B z*}muCZb3W-wi*ycA0@!O!?AU6p`&Aw=rp?p@aor)dKG<%u!B%A0HzoCz6e9c!qofh lNw9=}y>ReX`!g+yqCX Date: Mon, 27 May 2024 04:43:44 +0900 Subject: [PATCH 5/8] =?UTF-8?q?feat:=20index.tsx=EC=97=90=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=EC=9E=90=EC=9C=84=EC=B9=98=20=ED=91=9C=EC=8B=9C=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__pycache__/weatherrec.cpython-312.pyc | Bin 4734 -> 4818 bytes FlaskApps/weatherrec.py | 15 +++++++---- app/(tabs)/index.tsx | 25 +++++++++--------- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/FlaskApps/__pycache__/weatherrec.cpython-312.pyc b/FlaskApps/__pycache__/weatherrec.cpython-312.pyc index 73e65e3b09179b4a47f07a6852f1afe3d55b9090..45fc6ae1839b4a316cdcf61f3400ae8eb90827da 100644 GIT binary patch delta 1032 zcmcIgO=}ZT6rDGjNivyCKAI+JGM!A?NhP(U+C`K=YVm8~#!@1P)`fwgMXE!YTG8@G zT~w%T!G?>*Mg4+;LS0mf(t;b&MWKs+C@2AU7NH4P`UBKA(-@Sx?OWXU&f%Qn)yTL2yyzNcVDm2kHu*Vf3vqnl9YU2p2J}+6IyoHHGx^g_TzBq-H||Xh-J};^|w5 zDar`qpvp&xo!oBo?xT&+Rncr{9!%lTEWPtK!Z?iU2M8KMlQIq)^~A$fz5nzeyvypv zTwur_jNvd`hA^37s3}_8Po@eCkiVT|tS+_QXaI?kg@##F{U(AV(19c&Xtq$DW;LSl z!zO#9HI1l-j7H1XSmPut?efJ;A0Mk}WO&5Lei6(4bd3|S2v6)%AUw^eo|oP~aS=uM z6?=*kRX$5*Am|yLLL%f@iPRp4+`EShgkNlsBMZ|u)CMDNC5_i6Zo*Ag(#T&MYBrM! z%{7gJ6)RPAS1QFyrBqWXRw~6xrR;gCHAfI-;Jc$cB5EvVby{uIkSeLMY1T;KM2>2e zq1zd=l~5dRIyVjm$l^=3OIqJ>GkKL4M>pqg$14wKHs_zlE04!2&k4FeUKxK~o){}n z%(TO0uHxf~RQH+1Ps&IyXxu4y<;vK1IM{M6qZW9}uhBXO58Oop+Jz*X74qmhEDC9M z%TDb(1n-1Y{EL%c^(yO5hPPBbSDL?^jEo{$oM7u fU|v)6LwdpltTudQ@P?j*j=B@vX@u(ZGlc#PojmbT delta 1062 zcmcgrPe>F|9DZ+hW}Vq_W_8=u-PxI4-5pcQwIV_a4;6;lrNb5-(k<&{m^jIpQSu(1 zGy{p1N0_Ndx4;fUhwv5zcCdqgf&#qEOM&oOEFn);;O4c5i_w#pFt~9F)bqfN$|H_ z2(XD%dO_N&u-eSFV7wI}15LUmSU&SwjDGeRLoJ|VXVa93OjM%tG@T9Pt0dK44%J0J zDV*|hi2jvdn&+UUiyRxy7wK%E zjeb-fsr+|wgZwI^4+D4ng~wWT3GSv})fHu3>UPkTTdqtOOD7nX)9UE3b_r(bhIT0R zPF9zL=~X%X*q(1(+jI1}`|9j+_T19>*R8qb_S~D+9KEiuhmFK+W->Fi?+cKWL3sDn z=!yJ6I$xHdBf%yqpIB3p^hNM(*sx|BCL5+2Iql{j+PDAd8>k-YFsisUe_yAAI{V!; YZzN}+x9_%FONT=(N*jbB_Y8x70=-`LDF6Tf diff --git a/FlaskApps/weatherrec.py b/FlaskApps/weatherrec.py index ea7b1ee..26d2429 100644 --- a/FlaskApps/weatherrec.py +++ b/FlaskApps/weatherrec.py @@ -10,7 +10,12 @@ def get_place_recommendation(my_loc, sky, rain, temp): park_long, lib_long, muse_long = None, None, None park_adres, lib_adres, muse_adres = None, None, None - if (sky in ['맑음', '흐림']) and (rain == '강수없음') and (15 <= float(temp) <= 29): + # 날씨 정보에 따른 장소 추천 로직 + park_name, lib_name, muse_name = None, None, None + park_lat, lib_lat, muse_lat = None, None, None + park_long, lib_long, muse_long = None, None, None + park_adres, lib_adres, muse_adres = None, None, None + if (sky in ['맑음', '흐림']) and (rain == ' ') and (15 <= float(temp) <= 29): # 공원 정보 불러오기 및 추천 로직 park_url = 'http://openAPI.seoul.go.kr:8088/57524f76506d656e3732636a52457a/json/SearchParkInfoService/1/1000/' park_response = requests.get(park_url) @@ -24,13 +29,13 @@ def get_place_recommendation(my_loc, sky, rain, temp): park['LONGITUDE'] = park['LONGITUDE'].astype(float) # 가장 가까운 위치 찾기 min_distance = float('inf') - for index, row in park.iterrows(): + for row in park.iterrows(): point = (row['LATITUDE'], row['LONGITUDE']) distance = haversine(my_loc, point) if distance < min_distance: min_distance = distance park_name, park_lat, park_long, park_adres = row['NAME'], row['LATITUDE'], row['LONGITUDE'], row['ADRES'] - elif rain != '강수없음': + elif rain != '비가 오고 있지 않습니다.': # 도서관 정보 불러오기 및 추천 로직 lib_url = 'http://openAPI.seoul.go.kr:8088/57524f76506d656e3732636a52457a/json/SeoulLibraryTimeInfo/1/1000/' lib_response = requests.get(lib_url) @@ -46,7 +51,7 @@ def get_place_recommendation(my_loc, sky, rain, temp): lib['LONGITUDE'] = lib['LONGITUDE'].astype(float) # 가장 가까운 위치 찾기 min_distance = float('inf') - for index, row in lib.iterrows(): + for row in lib.iterrows(): point = (row['LATITUDE'], row['LONGITUDE']) distance = haversine(my_loc, point) if distance < min_distance: @@ -63,7 +68,7 @@ def get_place_recommendation(my_loc, sky, rain, temp): muse['LONGITUDE'] = muse['LONGITUDE'].astype(float) # 가장 가까운 위치 찾기 min_distance = float('inf') - for index, row in muse.iterrows(): + for row in muse.iterrows(): point = (row['LATITUDE'], row['LONGITUDE']) distance = haversine(my_loc, point) if distance < min_distance: diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index 204b3ee..3400458 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -11,11 +11,7 @@ import { FontAwesome } from '@expo/vector-icons'; import { useHeaderHeight } from '@react-navigation/elements'; import { router } from "expo-router"; import * as Location from 'expo-location'; -import axios from 'axios'; import Colors from '@/constants/Colors'; -import FlaskConfig from '@/flask.config'; - - const handleWeather = () => { router.push("weathers"); @@ -39,13 +35,15 @@ const Page = () => { const [loading, setLoading] = useState(false); const [location, setLocation] = useState(null); const [errorMsg, setErrorMsg] = useState(null); - const [address, setAddress] = useState('Waiting...'); + const [address, setAddress] = useState('사용자 위치 정보를 불러오고 있습니다...'); + const [latitude, setLatitude] = useState(null); + const [longitude, setLongitude] = useState(null); useEffect(() => { (async () => { let { status } = await Location.requestForegroundPermissionsAsync(); if (status !== 'granted') { - setErrorMsg('Permission to access location was denied'); + setErrorMsg('위치 접근 권한이 거부되었습니다.'); return; } @@ -54,14 +52,17 @@ const Page = () => { if (location) { const { latitude, longitude } = location.coords; + setLatitude(latitude); + setLongitude(longitude); + try { - const response = await axios.get( - `http://${FlaskConfig.Private_IP_Address}:${FlaskConfig.weather}/weather?latitude=${latitude}&longitude=${longitude}` - ); - const { guName, dongName } = response.data; - setAddress(`서울시 ${guName} ${dongName}`); + let reverseGeocode = await Location.reverseGeocodeAsync({ latitude, longitude }); + if (reverseGeocode.length > 0) { + let address = reverseGeocode[0]; + setAddress(`${address.city} ${address.street} ${address.streetNumber} (${address.postalCode})`); + } } catch (error) { - setErrorMsg('Error fetching address'); + setErrorMsg('주소를 가져오는 중 오류가 발생했습니다.'); } } })(); From a5563b70927551417da044394dae37484ec68879 Mon Sep 17 00:00:00 2001 From: hscrown Date: Mon, 27 May 2024 07:31:28 +0900 Subject: [PATCH 6/8] fix bug --- .../__pycache__/weatherrec.cpython-312.pyc | Bin 4818 -> 4990 bytes FlaskApps/weather.py | 2 +- FlaskApps/weatherrec.py | 34 ++++++++++-------- app/(tabs)/index.tsx | 1 - app/weathers/weatherCompleted.tsx | 29 +++++++++++---- 5 files changed, 44 insertions(+), 22 deletions(-) diff --git a/FlaskApps/__pycache__/weatherrec.cpython-312.pyc b/FlaskApps/__pycache__/weatherrec.cpython-312.pyc index 45fc6ae1839b4a316cdcf61f3400ae8eb90827da..e8fc4411f722b2b29bfa66d75717f63b3b19449e 100644 GIT binary patch delta 1563 zcmcgsZ%i9y7=PdEU3*7+6zCuNzZ52{Wo(%kNfulrV?h?Tkr7akQERW;aP1ZD+QINn zz5pqaNXZ*x$ygxK59s_r)I>jMvc)CN%*5+3TD$Sd59-!T1U@YL;C!zzh*{#k`6l=L zyWjIZ&+obS-doT7UCZ8N*%E-)+n;xy`DvE5!$Y%mfeyfFqS~0QR|f${j)PwMBJ@*# zsJIh;m}ky~E<^-zfRA9u5RHepAQwu6#7H7cs+jGi!&-x%jVL`k5o5y=!D-I#1t1ND z)3cBK%uBomVux@2>>$(=V}}6fBLI*svQ@HjdOOa<+Mwz)gj|_$VxzbuAXQ$$NOj3J z$tIc4V^4(B)sjs%;~Zu?_g{P9cu8?DvJW>Yld?`Ok=f~H5~K;fPa;Zjb4|tOj<~ zj#{){)_w(UmvKlA6oPKntZu>4s+67RGU+uscQ7u_BD;%u?wy!N@;s5}RrB=T9ZVJa zmh_gpq^h&TPRu2_&==5cvCflR=_kg=bRm#joE`S%(nvkzFCA?d6!?UW~;p9_!n|z#2o!)L#@~KQs_9vM7&~LCE z`p`k5UE|wkjdhW=ugKb0WbNBx%{`qp1DCPDo}^CjJ(XfkqC5aNQr25soG zx;!<&bCD5r-Eh`Os^#)pAtEND39$zCv$bfFeYKcd;Yv^}YwC-OCym(dkzDwzR z<>qTYw)HE0{Xe($qj+iF?C>l!%r#s(uns6@6iyvW9Zff)<+27eX>6j>o)yN6zA>(v z9qxsFbNepsS78@+VLeCI^=e?V43xPPSL2HDxfFTFSUw|7NtxEg%DLk!#z2b9(S{lQ zlzyr9%eEV%N@OtW8dBaGOX)Xpmn{UkUitzu7#qhnwZP`ibRj8a$nEw;Gxn{vau!?0 zF&kVAFV$yjpI6LHsiSLzmbKq;?pf?!>RNF&rs6ddYtyjCRId6oO zQ+?mXmEapnn9l~|%1}Z{O4%V?AFniVk zWbMC{+14~zKNKtQNPl1g9d(3K$8S3;<=D0RI3ifCu4&bg<5P2 z>eZU3w=Z6?_+16{3w;DOumr+MEFRL$u{f8EMh*+z*xjpMXQBfOTpGe(f$=sl-3Aq_ Rz`F{38`@J4RtR1A^*^F=n2i7c delta 1406 zcmcgsUu+X~9RK~=YkSx0_1f*Ww!3!i*0oUP{t#J=T85jOW)EF53JFdW8?HlHd!2VH zGV=Smneb2s$!LB-Fd={miJEC7Atv+52Yev$rDY^62Rx|{u*FRGrit-)$E+HB=9k>} z|G&@om;3#hyps@q5Ck`%C$f~C>Z=MN*jwGPYmfajm~_s;6!XaRji;c&y_-9c*Yx+) z{87fVZ66oqcKU7o|cDGfFIZWrn40d5R z7S6rMfb%wW7agm4n)YVtT>BIW2gwAC3c+Q#-6n)W#Lq;87PExHniRK@@0h6A)`*dn zRvfnS!VOylMV`uQH}m-RMog4EVxoQ-MUUAUHW|s}YiFb-aG6oOUy6Ujg#gJ4Pd;*V zbCjp)6f|z$(F0}jl_O%8kB7)SY?~heZ#}C$IxvfQ>^1kO{;ULXY}O9Q0T>oy4J;j~ z!`eaUU%TrxcOY~&V&W)n;ca^gZ+sgs< zI}(yr2XbgOC9FavqO@Oj;4aja1*s_UbM1Bm#>gw&FFVSe^v>45J^lE`LTuyG^~X1_ z#Wt=~Ha?@;g~g4-lnVOr0wA?e5#%-{0S7h}nFp zT=>V4VhlcWFgtoMb7XudGioqHBP07YAMK?1DIp*5lTajg_<}8!AQPTCNeRcEXN$D( zk+N1W1WVHL`bzN%|`-fVIQ` z$$5LoVeg<6U+!KR{yuS=xz&9)ovlq|@1?WkhS%^l2QKcd?j`$v0}k#Kth`FDh>El3 zA6VrEh|BlT*W7wBT}_ig(|_WLzlS9J&%OOCZyGjzKzbim*ayMbRnI4$Yll{Yy%k|i z>bNH*>r!%6+F47zRF_^}8Ldmh74CuPUqWZlrLk2pSz*>#&k}!z|NOO;*KZ%M9aZb$ zQf&@b_`B?fq~_m47DV^|&G!boNqe87y~$!zrnE&7gOp3_pv-X2LDCH@6j99kp* diff --git a/FlaskApps/weather.py b/FlaskApps/weather.py index 4782344..2b63224 100644 --- a/FlaskApps/weather.py +++ b/FlaskApps/weather.py @@ -78,7 +78,7 @@ def get_weather(): '6': "빗방울 또는 눈날림", '7': "눈날림" } - rain = rain_mapping.get(rain, "기상 정보 없음") + rain = rain_mapping.get(rain, "강수없음") # 초단기예보데이터 url2 = 'http://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/getUltraSrtFcst' diff --git a/FlaskApps/weatherrec.py b/FlaskApps/weatherrec.py index 26d2429..804fa33 100644 --- a/FlaskApps/weatherrec.py +++ b/FlaskApps/weatherrec.py @@ -3,6 +3,8 @@ import pandas as pd import numpy as np from haversine import haversine +from datasets import load_dataset + def get_place_recommendation(my_loc, sky, rain, temp): park_name, lib_name, muse_name = None, None, None @@ -15,7 +17,7 @@ def get_place_recommendation(my_loc, sky, rain, temp): park_lat, lib_lat, muse_lat = None, None, None park_long, lib_long, muse_long = None, None, None park_adres, lib_adres, muse_adres = None, None, None - if (sky in ['맑음', '흐림']) and (rain == ' ') and (15 <= float(temp) <= 29): + if (sky in ['맑음', '흐림']) and (rain == '강수없음') and (15 <= float(temp) <= 29): # 공원 정보 불러오기 및 추천 로직 park_url = 'http://openAPI.seoul.go.kr:8088/57524f76506d656e3732636a52457a/json/SearchParkInfoService/1/1000/' park_response = requests.get(park_url) @@ -29,13 +31,13 @@ def get_place_recommendation(my_loc, sky, rain, temp): park['LONGITUDE'] = park['LONGITUDE'].astype(float) # 가장 가까운 위치 찾기 min_distance = float('inf') - for row in park.iterrows(): + for index, row in park.iterrows(): point = (row['LATITUDE'], row['LONGITUDE']) distance = haversine(my_loc, point) if distance < min_distance: min_distance = distance park_name, park_lat, park_long, park_adres = row['NAME'], row['LATITUDE'], row['LONGITUDE'], row['ADRES'] - elif rain != '비가 오고 있지 않습니다.': + elif rain != '강수없음': # 도서관 정보 불러오기 및 추천 로직 lib_url = 'http://openAPI.seoul.go.kr:8088/57524f76506d656e3732636a52457a/json/SeoulLibraryTimeInfo/1/1000/' lib_response = requests.get(lib_url) @@ -51,7 +53,7 @@ def get_place_recommendation(my_loc, sky, rain, temp): lib['LONGITUDE'] = lib['LONGITUDE'].astype(float) # 가장 가까운 위치 찾기 min_distance = float('inf') - for row in lib.iterrows(): + for index, row in lib.iterrows(): point = (row['LATITUDE'], row['LONGITUDE']) distance = haversine(my_loc, point) if distance < min_distance: @@ -59,21 +61,25 @@ def get_place_recommendation(my_loc, sky, rain, temp): lib_name, lib_lat, lib_long, lib_adres = row['NAME'], row['LATITUDE'], row['LONGITUDE'], row['ADRES'] else: # 박물관 정보 불러오기 및 추천 로직 - muse_url = 'http://openAPI.seoul.go.kr:8088/57524f76506d656e3732636a52457a/json/SeoulMuseumInfo/1/1000/' - muse_response = requests.get(muse_url) - muse_data = muse_response.json()['SeoulMuseumInfo']['row'] - muse = pd.DataFrame(muse_data) - muse.rename(columns={'MUSEUM_NAME': "NAME", 'ADDR': "ADRES", 'XCNTS': 'LATITUDE', 'YDNTS': "LONGITUDE"}, inplace=True) + muse = load_dataset("hscrown/seoul_museums") + muse = pd.DataFrame(muse['train']) + muse.rename(columns={'시설명': "NAME", '주소': "ADRES", '위도': 'LATITUDE', '경도': "LONGITUDE"}, inplace=True) + muse['LATITUDE'].replace('', np.nan, inplace=True) + muse['LONGITUDE'].replace('', np.nan, inplace=True) muse['LATITUDE'] = muse['LATITUDE'].astype(float) muse['LONGITUDE'] = muse['LONGITUDE'].astype(float) + # 가장 가까운 위치 찾기 min_distance = float('inf') - for row in muse.iterrows(): + for index, row in muse.iterrows(): point = (row['LATITUDE'], row['LONGITUDE']) - distance = haversine(my_loc, point) - if distance < min_distance: - min_distance = distance - muse_name, muse_lat, muse_long, muse_adres = row['NAME'], row['LATITUDE'], row['LONGITUDE'], row['ADRES'] + try: + distance = haversine(my_loc, point) + if distance < min_distance: + min_distance = distance + muse_name, muse_lat, muse_long, muse_adres = row['NAME'], row['LATITUDE'], row['LONGITUDE'], row['ADRES'] + except ValueError: + continue # 에러가 발생하면 해당 행을 건너뛰도록 설정 result = { "name": park_name or lib_name or muse_name, diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index 3400458..a7e2aea 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -187,7 +187,6 @@ const styles = StyleSheet.create({ alignItems: "center", marginBottom: 15, elevation: 3, - }, blueButton: { backgroundColor: "#5ea3ff", diff --git a/app/weathers/weatherCompleted.tsx b/app/weathers/weatherCompleted.tsx index 3136eab..3f0a607 100644 --- a/app/weathers/weatherCompleted.tsx +++ b/app/weathers/weatherCompleted.tsx @@ -1,5 +1,6 @@ import React, { useState, useEffect } from 'react'; -import { StyleSheet, Text, View, Image, TouchableOpacity } from 'react-native'; +import { StyleSheet, Text, View, Image, TouchableOpacity, Alert } from 'react-native'; +import * as Location from 'expo-location'; import Colors from '@/constants/Colors'; import { router } from 'expo-router'; import BackButton from '@/components/BackButton'; @@ -7,18 +8,34 @@ import FlaskConfig from '@/flask.config'; const WeatherDashboard = () => { const [weatherData, setWeatherData] = useState({}); - const lat = 37.5665; - const long = 126.978; + const [location, setLocation] = useState(null); + const [errorMsg, setErrorMsg] = useState(null); useEffect(() => { - console.log('Component mounted, starting to fetch weather data...'); - loadWeatherPlaces(lat, long); + (async () => { + let { status } = await Location.requestForegroundPermissionsAsync(); + if (status !== 'granted') { + setErrorMsg('Permission to access location was denied'); + return; + } + + let location = await Location.getCurrentPositionAsync({}); + setLocation(location); + })(); }, []); + useEffect(() => { + if (location) { + const { latitude, longitude } = location.coords; + loadWeatherPlaces(latitude, longitude); + } + }, [location]); + const loadWeatherPlaces = (lat, long) => { console.log( `Fetching weather data for latitude: ${lat}, longitude: ${long}` ); + fetch( `http://${FlaskConfig.Private_IP_Address}:${FlaskConfig.weather}/weather?latitude=${lat}&longitude=${long}` ) @@ -61,7 +78,7 @@ const WeatherDashboard = () => { /> {weatherData.name} - 오늘은 날씨가 {weatherData.sky}! + 오늘 날씨는 {weatherData.sky}! 이곳은 어떨까요? Date: Tue, 4 Jun 2024 20:36:41 +0900 Subject: [PATCH 7/8] add google map secret key --- app.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app.json b/app.json index 97ffa14..f01597f 100644 --- a/app.json +++ b/app.json @@ -18,7 +18,7 @@ "ios": { "supportsTablet": true, "config": { - "googleMapsApiKey": "AIzaSyCNv0u_zbqsH3_xPIIJSJw4_cMkW8_6mlk" + "googleMapsApiKey": "GOOGLE_MAP_KEY" } }, "android": { @@ -28,7 +28,7 @@ }, "config": { "googleMaps": { - "apiKey": "AIzaSyCNv0u_zbqsH3_xPIIJSJw4_cMkW8_6mlk" + "apiKey": "GOOGLE_MAP_KEY" } } }, From 6db4df41d6395035d1db4983cc000d19a92a857e Mon Sep 17 00:00:00 2001 From: hscrown Date: Tue, 4 Jun 2024 20:42:49 +0900 Subject: [PATCH 8/8] add seoul api key to maps --- app/maps/fullMarkerMap.tsx | 2 +- app/maps/library.tsx | 6 +++--- app/maps/park.tsx | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/maps/fullMarkerMap.tsx b/app/maps/fullMarkerMap.tsx index 788de18..61628ec 100644 --- a/app/maps/fullMarkerMap.tsx +++ b/app/maps/fullMarkerMap.tsx @@ -68,7 +68,7 @@ const Page: React.FC = () => { }, []); const fetchParks = async () => { - const seoul_key = '57524f76506d656e3732636a52457a'; + const seoul_key = 'SEOUL_API_KEY'; const url = `http://openAPI.seoul.go.kr:8088/${seoul_key}/json/SearchParkInfoService/1/1000/`; try { const response = await axios.get(url); diff --git a/app/maps/library.tsx b/app/maps/library.tsx index dbe2bb6..b6ac299 100644 --- a/app/maps/library.tsx +++ b/app/maps/library.tsx @@ -53,10 +53,10 @@ const HomeScreen: React.FC = () => { }, []); const fetchLibraries = async () => { - const api_key = '57524f76506d656e3732636a52457a'; + const seoul_key = 'SEOUL_API_KEY'; const urls = [ - `http://openAPI.seoul.go.kr:8088/${api_key}/json/SeoulLibraryTimeInfo/1/1000/`, - `http://openAPI.seoul.go.kr:8088/${api_key}/json/SeoulLibraryTimeInfo/1001/2000/` + `http://openAPI.seoul.go.kr:8088/${seoul_key}/json/SeoulLibraryTimeInfo/1/1000/`, + `http://openAPI.seoul.go.kr:8088/${seoul_key}/json/SeoulLibraryTimeInfo/1001/2000/` ]; try { diff --git a/app/maps/park.tsx b/app/maps/park.tsx index 41a5b28..f690115 100644 --- a/app/maps/park.tsx +++ b/app/maps/park.tsx @@ -56,7 +56,7 @@ const ParkScreen: React.FC = () => { }, []); const fetchParks = async () => { - const seoul_key = '57524f76506d656e3732636a52457a'; + const seoul_key = 'SEOUL_API_KEY'; const url = `http://openAPI.seoul.go.kr:8088/${seoul_key}/json/SearchParkInfoService/1/1000/`; try {