목차
개발환경
개발완료보고서
요구사항 세부내역
일정표
파일 첨부
실행화면
코드 전문
개발환경
- 운영체제: Window 10 64 bit
- 개발언어: Python 3.11
- 개발 툴: Pycharm
- DBSM: SQLite
- 추가 패키지: PyQt, Pandas
개발완료보고서
요구사항분석서
일정표
파일 첨부
https://github.com/guaba98/seoul_trip_program
목업 이미지
실행사진
정보 입력 / 정보가 유효하지 않을 때 경고표시
db에 담기는 부분
메인 화면
음식 구별 리스트 선택창 / 각 구별 음식점 리스트 / 음식점 선택했을 때 상세정보와 지도 보여주기
선택한 구별 숙박시설 리스트 / 선택한 숙박시설 지도 위치
서울 관광명소 리스트 / 선택한 관광명소 지도 위치
서울관련 데이터 자료 확인 / 누르면 그래프에 대한 상세 정보 확인 가능
지도 선택하면 나오는 화면 / 명소는 사진으로 보여줍니다.
구 검색시 자동완성 기능
실행영상
코드 전문
main.py
더보기
import io
import random
import sqlite3
import folium
import sys
import pandas as pd
from selenium import webdriver
from selenium.webdriver.common.by import By
from seoul_main_page import *
from widget_for_food import *
from widget_for_sleep import *
from widget_for_tour import *
from widget_for_graph import *
from graph_data import *
from map_file import *
gu_list = ['종로구', '중구', '용산구', '성동구', '광진구', '동대문구', '중랑구', '성북구', '강북구', '도봉구',
'노원구', '은평구', '서대문구', '마포구', '양천구', '강서구', '구로구', '금천구', '영등포구', '동작구',
'관악구', '서초구', '강남구', '송파구', '강동구']
class WindowClass(QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.map_obj = FoliumMap() # 맵 객체 생성
self.setupUi(self) # ui 관련
self.var_init() # 변수 설정부분
self.Ui_init() # ui 설정부분
self.insert_values_in_gridlayout() # 그리드 레이아웃에 구 넣기
self.function_init() # 기능들 (시그널 연결 부분)
def show_map_as_search(self, user_idx):
"""검색한 값에 따라 자료들이 출력됨"""
self.user_index = user_idx
# 레이아웃에 있는 객체를 지움
if self.whole_map.count():
self.whole_map.takeAt(0)
# 유저가 검색한 내용을 가져옴
user_text = self.map_lineEdit.text()
print("유저가 선택한 동은", user_text)
# 사용자가 검색을 하지 않은 경우
if user_text == "":
if user_idx == 0:
self.map_obj.mapping_food_all_show() # 서울의 모든 음식점을 보여줌
elif user_idx == 1:
self.map_obj.mapping_lodges_all_show() # 서울의 모든 숙박업소를 보여줌
else:
self.map_obj.mapping_tour_all_show() # 서울의 모든 명소를 보여줌
# 사용자가 구 검색을 한 경우
else:
if user_idx == 0:
self.map_obj.mapping_food_guname_show(user_text) # 구 이름에 따라 음식점을 보여줌
elif user_idx == 1:
self.map_obj.mapping_lodges_guname_show(user_text) # 구 이름에 따라 숙박업소들을 보여줌
else:
self.map_obj.mapping_tour_guname_show(user_text) # 구 이름에 따라 명소들을 보여줌
# 레이아웃에 맵 객체를 리턴받아서 로드해 줌
self.whole_map.addWidget(self.map_obj.load_map())
del self.map_obj # map 클래스 객체를 지우고
self.map_obj = FoliumMap() # 다시 생성
print("객체 지움") # 확인용
def what_do_you_want_to_know(self, choice):
"""선택한 부분에 따라 페이지를 넘기고, 로드해 줌"""
self.stackedWidget.setCurrentWidget(self.main_page_2)
self.gu_btn_clicked(choice) # 음식, 숙박업소
# 구 버튼 클릭이벤트
def gu_btn_clicked(self, choice):
"""유저가 선택한 버튼에 따라 라벨의 내용을 변경해 줌"""
if choice == 'food':
self.frame_20.setStyleSheet('background-color:#FFEFB5;border-radius:20px;')
text = '가고싶은 서울의 장소를 선택하세요!\n인기있는 음식점들만 소개해 드립니다.'
self.main_2_title_lab.setText(text)
for idx, btn in enumerate(self.gu_btn_list):
btn.clicked.connect(lambda event, idx=idx: self.gu_btn_for_food(self.gu_btn_list[idx]))
elif choice == 'sleep':
self.frame_20.setStyleSheet('background-color:#B0DAFF;border-radius:20px;')
text = '가고싶은 서울의 장소를 선택하세요!\n최고의 숙박시설을 소개해 드립니다.'
self.main_2_title_lab.setText(text)
for idx, btn in enumerate(self.gu_btn_list):
btn.clicked.connect(lambda event, idx=idx: self.gu_btn_for_sleep(self.gu_btn_list[idx]))
def gu_btn_for_food(self, btn):
"""구 버튼을 클릭하면 스크롤 영역에 음식점 리스트를 넣어줌"""
region = btn.text()
food_text = f"{region}의 유명한 음식점을 안내해드려요!"
self.main_3_title_lab.setText(food_text)
self.main_4_title_lab.setText(food_text)
datas = self.cur.execute(f'select * from food_list where gu_name = "{region}";')
self.stackedWidget.setCurrentWidget(self.main_page_3)
self.clear_scroll_area()
self.set_data_of_food_in_scrollarea(datas)
self.scrollArea.ensureVisible(0, 0)
def gu_btn_for_sleep(self, btn):
"""구 버튼을 클릭하면 스크롤 영역에 숙박업소 리스트를 넣어줌"""
region = btn.text()
sleep_text = f'{region}의 최고의 숙박시설을 안내해드려요!'
self.main_3_title_lab.setText(sleep_text)
self.main_4_title_lab.setText(sleep_text)
datas = self.cur.execute(
f'select 사업장명, 영업상태명, 도로명주소, x_pos, y_pos, img_path from seoul_lodges where 지번주소 like "%{region}%";')
self.stackedWidget.setCurrentWidget(self.main_page_3)
self.clear_scroll_area()
self.set_data_of_sleep_in_scrollarea(datas)
self.scrollArea.ensureVisible(0, 0)
def tour_btn_click(self):
"""스크롤 영역에 명소리스트를 넣어줌"""
self.frame_20.setStyleSheet('background-color:#caffbf; border-radius:20px;')
self.back_3_btn_clicked = True
tour_text = '서울시의 유명한 명소를 소개해드려요!'
self.main_3_title_lab.setText(tour_text)
self.main_4_title_lab.setText(tour_text)
self.stackedWidget.setCurrentWidget(self.main_page_3)
self.clear_scroll_area()
self.set_data_of_tour_in_scrollarea()
self.scrollArea.ensureVisible(0, 0)
# 스크롤 위젯에 데이터 심기
def set_data_of_food_in_scrollarea(self, datas):
"""스크롤 영역에 음식점 데이터 심기"""
layout = self.scrollAreaWidgetContents.layout()
for data in datas:
name = data[2]
rate = data[3]
address = data[4]
x_pos = data[5]
y_pos = data[6]
main_dishes = data[-3]
price = data[-2]
img_path = data[-1]
layout.addWidget(SeoulForFood(name, rate, address, main_dishes, price, x_pos, y_pos, img_path, self))
def set_data_of_sleep_in_scrollarea(self, datas):
"""스크롤 영역에 숙박업소 리스트 심기"""
layout = self.scrollAreaWidgetContents.layout()
for data in datas:
name = data[0]
status = data[1]
address = data[2]
x_pos = data[3]
y_pos = data[4]
image_path = data[-1]
layout.addWidget(SeoulForSleep(name, status, address, x_pos, y_pos, image_path, self))
def set_data_of_tour_in_scrollarea(self):
"""스크롤 영역에 명소 리스트 심기"""
layout = self.scrollAreaWidgetContents.layout()
datas = self.cur.execute('select 상호명, 신주소, 운영요일, 운영시간, 휴무일, x_pos, y_pos, img_path from seoul_tourist;')
for data in datas:
name = data[0]
address = data[1]
working_day = data[2]
working_time = data[3]
holiday = data[4]
x_pos = data[-3]
y_pos = data[-2]
image_path = data[-1]
layout.addWidget(
SeoulForTour(name, address, working_day, working_time, holiday, x_pos, y_pos, image_path, self))
def clear_scroll_area(self):
"""스크롤 영역 위젯 비워주기"""
while self.scrollAreaWidgetContents.layout().count():
item = self.scrollAreaWidgetContents.layout().takeAt(0)
widget = item.widget()
self.scrollAreaWidgetContents.layout().removeWidget(widget)
def insert_values_in_gridlayout(self):
"""그리드 영역에 버튼 생성해서 넣어주기"""
self.gu_btn_list = list()
cnt = 0
for i in range(1, 6):
for j in range(1, 6):
button = QPushButton(gu_list[cnt]) # 버튼 생성 및 이름 넣어줌
button.setFixedSize(100, 100) # 버튼의 크기 고정
button.setStyleSheet('''
border-radius:15px;
border: 3px solid white;
''')
self.gridLayout.addWidget(button, i, j)
self.gu_btn_list.append(button)
cnt += 1
# 날씨관련
def wheather_crawling(self):
"""날씨를 크롤링해와서 메인 화면에 지정함"""
options = webdriver.ChromeOptions()
options.add_argument("headless")
self.driver = webdriver.Chrome(options=options)
self.driver.get("https://weather.naver.com/today/09140104?cpName=KMA")
temperature = self.driver.find_element(By.CSS_SELECTOR,
'#now > div > div.weather_area > div.weather_now > div > strong')
wheather = self.driver.find_element(By.CSS_SELECTOR,
'#now > div > div.weather_area > div.weather_now > p > span.weather')
self.temp_label.setText(f"{temperature.text[-5:]} ")
self.temp_label_2.setText(f'{wheather.text}')
self.set_wheather_icon(wheather.text)
self.driver.close()
# 날씨 셋업
def set_wheather_icon(self, wheather):
"""날씨 아이콘을 설정함"""
wheather_icon_path = {
'맑음': '../img/wheather_icon/shiny',
'구름많음': '../img/wheather_icon/cloud',
'흐림': '../img/wheather_icon/overcast',
'비': '../img/wheather_icon/rainy'
}
idx = wheather_icon_path.get(wheather)
self.wheather_icon.setPixmap(QPixmap(idx))
def activate_DB(self):
"""db 활성화함"""
self.conn = sqlite3.connect('../database/seoul_db.db')
self.cur = self.conn.cursor()
def back_3_btn_click_event(self):
"""버튼을 클릭했을 때 조건에 따라 페이지로 이동함"""
if not self.back_3_btn_clicked:
self.stackedWidget.setCurrentWidget(self.main_page_2)
else:
self.back_3_btn_clicked = False
self.stackedWidget.setCurrentWidget(self.main_page_1)
def input_personal_information(self):
"""개인정보 넣는 부분"""
self.check_name() # 이름 확인
if self.check_name() and self.check_len_phone_number(self.lineEdit_2.text()): #이름, 폰 길이가 True반영시
self.stackedWidget.setCurrentWidget(self.main_page_1) #페이지 이동
self.main_sub_title.setText(f"{self.lineEdit.text()}님, \n서울 여행을 준비하세요.")
self.user_id += 1
personal_info = (self.user_id, self.lineEdit.text(), self.lineEdit_2.text(), self.dateEdit.text())
self.cur.execute("insert into user_info values (?, ?, ?, ?);", personal_info) #데이터 넣어주기
self.conn.commit()
else:
pass # 창이 넘어가지 않음
def check_name(self):
"""이름 확인하는 부분"""
name = self.lineEdit.text()
if len(name) == 0:
self.user_name_label.setText('이름을 입력해주세요.')
self.user_name_label.setStyleSheet('color:red;')
return False
elif len(name) > 6:
self.user_name_label.setText('이름이 너무 깁니다.')
self.user_name_label.setStyleSheet('color:red;')
return False
else:
self.user_name_label.setText(f'{name}님 안녕하세요.')
self.user_name_label.setStyleSheet('color:blue;')
print('트루탐')
return True
def check_letter_in_number(self, number):
"""연락처 확인하는 부분"""
# number = self.lineEdit_2.text()
# check_number = self.check_len_phone_number(number)
for num in number:
num = ord(num)
if 47 < num < 58:
return True
pass
else:
self.user_number_label('숫자만 입력하실 수 잇습니다.')
self.user_number_label.setStyleSheet('color:red;')
return False
return True
def check_len_phone_number(self, number):
"""핸드폰 번호 길이 체크하는 부분"""
if len(number) == 11:
if self.check_letter_in_number(number):
return True
else:
self.user_number_label.setText('형식에 맞게 핸드폰 번호를 입력해주세요.')
self.user_number_label.setStyleSheet('color:red;')
return False
def set_graph_widget(self):
"""그래프 관련 작업 코드"""
layout = self.map_frame.layout()
row = 0
column = 0
for name, img_path, desc in zip(self.graph_name_list, self.graph_imgpath_list, self.graph_desc_list):
layout.addWidget(SeoulforGraph(name, img_path, desc, self), row, column)
column += 1
if column == 2:
row += 1
column = 0
def load_whole_map(self):
"""지도 이미지 기본 로드"""
self.stackedWidget.setCurrentWidget(self.main_page_5)
self.show_map_as_search(2)
print(self.user_index)
# 기능 이니트
def function_init(self):
# 날씨 크롤링
self.wheather_crawling()
# 버튼에 따라 다른 조건으로 이동
self.food_btn.clicked.connect(lambda: self.what_do_you_want_to_know('food'))
self.sleep_btn.clicked.connect(lambda: self.what_do_you_want_to_know('sleep'))
self.tour_btn.clicked.connect(self.tour_btn_click)
# 라벨 클릭하면 오픈 페이지로 이동
self.label.mousePressEvent = lambda event: self.stackedWidget.setCurrentWidget(self.login_page)
# 버튼 클릭하면 특정 페이지로 이동
self.back_2_btn.clicked.connect(lambda x: self.stackedWidget.setCurrentWidget(self.main_page_1))
self.back_3_btn.clicked.connect(self.back_3_btn_click_event)
self.back_4_btn.clicked.connect(lambda x: self.stackedWidget.setCurrentWidget(self.main_page_3))
self.back_5_btn.clicked.connect(lambda x: self.stackedWidget.setCurrentWidget(self.main_page_1))
self.back_btn_6.clicked.connect(lambda x: self.stackedWidget.setCurrentWidget(self.main_page_1))
self.back_btn_7.clicked.connect(lambda x: self.stackedWidget.setCurrentWidget(self.main_page_6))
# self.all_show_btn.clicked.connect(lambda x: self.stackedWidget.setCurrentWidget(self.main_page_5))
self.all_show_btn.clicked.connect(self.load_whole_map) # 전체 지도를 보여줌
self.map_back_btn.clicked.connect(lambda x, y=self.user_index: self.show_map_as_search(y))
self.admit_btn.clicked.connect(self.input_personal_information)
# db 활성화
self.activate_DB()
# 자동완성 기능 추가
completer = QCompleter(gu_list)
self.map_lineEdit.setCompleter(completer)
# 지도버튼 시그널 연결
map_btn_list = [self.map_food_btn, self.map_lodge_btn, self.map_place_btn]
for idx, btn in enumerate(map_btn_list):
btn.clicked.connect(lambda x, y=idx: self.show_map_as_search(y))
# 그래프 페이지 시그널 연결
self.set_graph_widget()
# 하단 버튼 시그널 연결
menu_btn_frame = [self.menu_btns_frame_1, self.menu_btns_frame_2, self.menu_btns_frame_3,
self.menu_btns_frame_4, self.menu_btns_frame_5] # 메뉴 버튼 담긴 프레임
menu_btns = [frame.findChildren(QPushButton) for frame in menu_btn_frame] # 해당 프레임에 있는 버튼들 가져오기
# 버튼에 따라 이동해야 할 페이지
button_mapping = {
'menu_home_btn': self.main_page_1,
'menu_map_btn': self.main_page_5,
'menu_menu_btn': self.main_page_6,
# 여기에 4번째 버튼 연결할 것 있으면 추가
}
# 버튼에 따라 다른 페이지로 이동(위 button_mapping 딕셔너리 참고)
for btn_list in menu_btns:
for btn in btn_list:
for object_name, widget in button_mapping.items():
if object_name in btn.objectName():
# map_btn일 때 음식 지도 로드하기
btn.clicked.connect(lambda checked, widget=widget: self.stackedWidget.setCurrentWidget(widget))
break
# def show_whole_map(self):
# """전체 지도를 보여줍니다"""
# self.stackedWidget.setCurrentWidget(self.main_page_5)
# print(self.whole_map)
# self.map_obj.mapping_tour_all_show() # 모든 관광명소를 지도에 마커+클러스터로 표시함
# self.verticalLayout_17.addWidget(self.map_obj.load_map())
# def back_3_btn_click_event(self):
# if not self.back_3_btn_clicked:
# self.stackedWidget.setCurrentWidget(self.main_page_2)
# else:
# self.back_3_btn_clicked = False
# self.stackedWidget.setCurrentWidget(self.main_page_1)
def Ui_init(self):
"""스타일시트 관련"""
# 스크롤에어리어 레이아웃 넣기
self.setWindowFlags(
Qt.WindowType.FramelessWindowHint) # Qt.WindowType.WindowStaysOnTopHint 프레임 지우기 / 윈도우가 다른 창 위에 항상 최상위로 유지되도록 함
self.setAttribute(Qt.WA_TranslucentBackground, True) # 배경 투명하게 함
v_layout = QVBoxLayout(self)
self.scrollAreaWidgetContents.setLayout(v_layout)
# 오픈 페이지 랜덤 지정
self.stackedWidget.setCurrentWidget(self.open_page)
random_num = random.randint(1, 4)
# 라벨에 이미지 넣어주기
self.label.setPixmap(QPixmap(f'../img/qt_img/background_{random_num}.png'))
self.back_2_btn.setIcon(QIcon('../img/qt_img/back.png'))
self.back_3_btn.setIcon(QIcon('../img/qt_img/back.png'))
self.back_4_btn.setIcon(QIcon('../img/qt_img/back.png'))
self.back_5_btn.setIcon(QIcon('../img/qt_img/back.png'))
# 커서 지정
self.setCursor(QCursor(QPixmap('../img/qt_img/mouse.png').scaled(80, 100)))
# self.label_1.setFont(QFont('Arial', 10))
# 폰트 지정
# self.main_sub_title.setFont(QFont('Pretendard', 28))
# Qmovie 설정
movie = QMovie('../img/qt_img/seoul.gif')
self.seoul_gif_label.setMovie(movie)
movie.start()
# 웹엔진뷰
self.webview = QWebEngineView()
webview_layout = QVBoxLayout(self)
self.map_widget.setLayout(webview_layout)
# 그래프 레이아웃 설정
graph_layout = QGridLayout(self)
self.map_frame.setLayout(graph_layout)
# self.map_lineEdit.returnPressed.connect(lambda x, y=0: self.show_map_as_search(y))
# btn.clicked.connect(lambda x, y=idx: self.show_map_as_search(y))
# init 안에
# self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)
# 메소드
# def mousePressEvent(self, event):
"""화면 이동"""
# if event.button() == Qt.LeftButton:
# self.m_flag = True
# self.m_Position = event.globalPos() - self.pos()
# event.accept()
# self.setCursor(QCursor(Qt.OpenHandCursor))
#
# def mouseMoveEvent(self, QMouseEvent):
# if Qt.LeftButton and self.m_flag:
# self.move(QMouseEvent.globalPos() - self.m_Position)
# QMouseEvent.accept()
#
# def mouseReleaseEvent(self, QMouseEvent):
# self.m_flag = False
# self.setCursor(QCursor(Qt.ArrowCursor))
def var_init(self):
"""관광버튼 눌렀는지 확인하기"""
self.user_id = 0
self.user_index = 2
self.back_3_btn_clicked = False
# 그래프 이미지 넣어주기
self.graph_imgpath_list = GraphData().imgpath_list
self.graph_name_list = GraphData().graph_name_list
self.graph_desc_list = GraphData().graph_desc_list
if __name__ == '__main__':
app = QApplication(sys.argv)
fontDB = QFontDatabase()
fontDB.addApplicationFont('../font/Pretendard-Medium.ttf') # 폰트 지정
app.setFont(QFont('Pretendard Medium'))
myWindow = WindowClass()
myWindow.show()
try:
sys.exit(app.exec_())
except SystemExit:
print('Closing Window...')
map_file.py
더보기
# --- import modules
import io
import sqlite3
import sys
import os
import webbrowser
import folium
import pandas as pd
from PyQt5.QtWebEngineWidgets import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from folium import plugins
from folium.plugins import *
class FoliumMap:
def __init__(self):
super().__init__()
# --- 판다스 옵션
pd.set_option("display.max_columns", None)
pd.set_option("display.max_rows", None)
# --- 레이아웃 & 버튼 & 웹엔진뷰
self.web = QWebEngineView()
self.con = sqlite3.connect('../database/seoul_db.db')
self.cur = self.con.cursor()
# --- self.seoul_map 지도 설정
self.latitude = 37.564214 # 위도
self.longitude = 127.001699 # 경도
self.zoom_level = 11
self.titles = "http://mt0.google.com/vt/lyrs=m&hl=ko&x={x}&y={y}&z={z}"
self.attr = "Google"
# self.coordinate = (35.19475778198943, 126.8399771747554)
# --- folium 맵 설정: 서울 전체 맵
self.seoul_map = folium.Map(
tiles=self.titles, # --- 배경지도 tiles에 대한 속성 (기본값: https://www.openstreetmap.org)
attr=self.attr,
zoom_start=self.zoom_level, # --- 화면 보여줄 거리 / 값이 적을수록 가까이 보여줌
location=[self.latitude, self.longitude], # --- 현재 화면에 보여줄 좌표 값
control_scale=True, # --- contol_scale: True 시 맵 좌측 하단에 배율을 보여줌
# zoom_control = False, # --- zoom_control: False 시 줌 컨트롤러가 사라집니다. (단, 마우스 휠 줌은 가능)
# scrollWheelZoom = False, # --- scrollWheelZoom: False 시 스크롤을 사용할 수 없음
# dragging = False # --- dragging: False 시 마우스 드래그를 사용할 수 없음
)
self.marker_cluster = MarkerCluster().add_to(self.seoul_map)
self.mini_map = MiniMap().add_to(self.seoul_map)
# --- 메소드 작성 부분
"""
▼ 메소드 설명:
self.mapping_tour_all_show() -> 모든 관광명소를 지도에 마커+클러스트로 표시합니다.
self.mapping_tour_guname_show() -> 특정 관광명소를 지도에 마커+클러스트로 표시합니다.
self.mapping_lodges_all_show() -> 모든 숙박업소를 지도에 마커+클러스트로 표시합니다.
self.mapping_lodges_guname_show() -> 특정 숙박업소를 지도에 마커+클러스트로 표시합니다.
self.mapping_food_all_show() -> 모든 음식점을 지도에 마커+클러스트로 표시합니다.
self.mapping_food_guname_show(guname: str) -> 특정 음식점을 지도에 마커+클러스트로 표시합니다.
"""
def mapping_tour_all_show(self):
"""DB의 관광명소 목록을 맵에 마커 + 클러스트로 적용시킵니다"""
tour_query = pd.read_sql("SELECT 상호명, 신주소, 전화번호, 웹사이트, x_pos, y_pos, img_path FROM seoul_tourist", self.con)
for index, row in tour_query.iterrows():
x_pos = row['x_pos']
y_pos = row['y_pos']
name = row['상호명']
info = row['신주소'], row['전화번호']
link = f"<a href={row['웹사이트']}>웹사이트 접속</a>"
img = row['img_path']
roadview = f'<a href="https://www.google.com/maps?layer=c&cbll={str(x_pos)},{str(y_pos)}">구글 거리뷰로 보기</a>'
icon = folium.features.CustomIcon(img, icon_size=(50, 50)) #사진으로 보여주기
# icon = folium.Icon(color="purple", icon="glyphicon glyphicon-tag", icon_color="white")
popup = folium.Popup(f"<img src='{img}'>" + "<br>" + name + f"({str(link)})" + "<br><br>" + str(info) + "<br><br>" + roadview, min_width=500, max_width=500)
folium.Marker([x_pos, y_pos], tooltip=name, popup=popup, icon=icon).add_to(self.marker_cluster)
def mapping_tour_guname_show(self, guname: str):
"""DB의 관광명소 목록을 맵에 마커 + 클러스트로 적용시킵니다"""
tour_query = pd.read_sql(f"SELECT 상호명, 신주소, 전화번호, 웹사이트, x_pos, y_pos, img_path FROM seoul_tourist WHERE 신주소 LIKE '%{guname}%'", self.con)
for index, row in tour_query.iterrows():
x_pos = row['x_pos']
y_pos = row['y_pos']
name = row['상호명']
info = row['신주소'], row['전화번호']
link = f"<a href={row['웹사이트']}>웹사이트 접속</a>"
img = row['img_path']
roadview = f'<a href="https://www.google.com/maps?layer=c&cbll={str(x_pos)},{str(y_pos)}">구글 거리뷰로 보기</a>'
icon = folium.features.CustomIcon(img, icon_size=(50, 50))
# icon = folium.Icon(color="purple", icon="glyphicon glyphicon-tag", icon_color="white")
popup = folium.Popup(f"<img src='{img}'>" + "<br>" + name + f"({str(link)})" + "<br><br>" + str(info) + "<br><br>" + roadview, min_width=500, max_width=500)
folium.Marker([x_pos, y_pos], tooltip=name, popup=popup, icon=icon).add_to(self.marker_cluster)
def mapping_lodges_all_show(self):
"""DB의 숙박지 목록을 맵에 마커 + 클러스트로 적용시킵니다"""
lodge_query = pd.read_sql("SELECT 사업장명, 도로명주소, 전화번호, x_pos, y_pos, img_path FROM seoul_lodges", self.con)
for index, row in lodge_query.iterrows():
x_pos = row['x_pos']
y_pos = row['y_pos']
name = row['사업장명']
info = row['도로명주소'], row['전화번호']
img = row['img_path']
roadview = f'<a href="https://www.google.com/maps?layer=c&cbll={str(x_pos)},{str(y_pos)}">구글 거리뷰로 보기</a>'
icon = folium.Icon(color="blue", icon="glyphicon glyphicon-tag", icon_color="white")
popup = folium.Popup(f"<img src='{img}'>" + "<br><br>" + name + "<br><br>" + str(info) + "<br><br>" + roadview, min_width=400, max_width=400)
# icon = plugins.BeautifyIcon(
# icon='utensils',
# border_color='darkblue',
# text_color='darkblue',
# icon_shape='triangle',
# )
folium.Marker([x_pos, y_pos], tooltip=name, popup=popup, icon=icon).add_to(self.marker_cluster)
def mapping_lodges_guname_show(self, guname: str):
"""DB의 숙박지 목록을 구별로 맵에 마커 + 클러스트로 적용시킵니다"""
lodge_query = pd.read_sql(f"SELECT 사업장명, 도로명주소, 전화번호, x_pos, y_pos, img_path FROM seoul_lodges WHERE 도로명주소 LIKE '%{guname}%'", self.con)
for index, row in lodge_query.iterrows():
x_pos = row['x_pos']
y_pos = row['y_pos']
name = row['사업장명']
info = row['도로명주소'], row['전화번호']
img = row['img_path']
roadview = f'<a href="https://www.google.com/maps?layer=c&cbll={str(x_pos)},{str(y_pos)}">구글 거리뷰로 보기</a>'
popup = folium.Popup(f"<img src='{img}'>" + "<br><br>" + name + "<br><br>" + str(info) + "<br><br>" + roadview, min_width=400, max_width=400)
icon = folium.Icon(color="blue", icon="glyphicon glyphicon-tag", icon_color="white")
folium.Marker([x_pos, y_pos], tooltip=name, popup=popup, icon=icon).add_to(self.marker_cluster)
def mapping_food_all_show(self):
"""DB의 음식점 목록을 맵에 마커 + 클러스트로 적용시킵니다"""
food_query = pd.read_sql("SELECT name, address, x_pos, y_pos, img_path FROM food_list", self.con)
for index, row in food_query.iterrows():
x_pos = row['x_pos']
y_pos = row['y_pos']
name = row['name']
info = row['address']
img = row['img_path']
roadview = f'<a href="https://www.google.com/maps?layer=c&cbll={str(x_pos)},{str(y_pos)}">구글 거리뷰로 보기</a>'
popup = folium.Popup(f"<img src='{img}'>" + "<br><br>" + name + "<br><br>" + str(info) + "<br><br>" + roadview, min_width=400, max_width=400)
icon = folium.Icon(color="red", icon="glyphicon glyphicon-tag", icon_color="white")
folium.Marker([x_pos, y_pos], tooltip=name, popup=popup, icon=icon).add_to(self.marker_cluster)
def mapping_food_guname_show(self, guname: str):
"""DB의 음식점 목록을 구별로 마커 + 클러스트로 적용시킵니다"""
food_query = pd.read_sql(f"SELECT gu_name, name, rate, address, x_pos, y_pos, img_path FROM food_list WHERE gu_name = '{guname}'", self.con)
for index, row in food_query.iterrows():
x_pos = row['x_pos']
y_pos = row['y_pos']
name = row['name']
info = row['address']
img = row['img_path']
roadview = f'<a href="https://www.google.com/maps?layer=c&cbll={str(x_pos)},{str(y_pos)}">구글 거리뷰로 보기</a>'
popup = folium.Popup(f"<img src='{img}'>" + "<br><br>" + name + "<br><br>" + str(info) + "<br><br>" + roadview, min_width=400, max_width=400)
icon = folium.Icon(color="red", icon="glyphicon glyphicon-tag", icon_color="white")
folium.Marker([x_pos, y_pos], tooltip=name, popup=popup, icon=icon).add_to(self.marker_cluster)
def load_map(self):
"""self.seoul_map을 index.html 파일로 저장하고, PyQt 레이아웃에 QWebEngineView를 추가합니다"""
self.seoul_map.save('index.html', close_file=False)
self.web.setUrl(QUrl("file:///index.html"))
return self.web
def load_map_2(self):
"""미사용"""
with open('index.html', 'r', encoding="utf-8") as f:
html = f.read()
self.web.setUrl(QUrl(html))
def button_clicked_event(self):
"""구글 스트릿 뷰 상태에서 뒤로가기 버튼을 클릭하면 원래 화면으로 이동합니다"""
print('탑니까..')
self.web.page().triggerAction(QWebEnginePage.WebAction.Back)
widget_for_food.py
더보기
import sys
import folium
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from seoul_widget import *
class SeoulForFood(QWidget, Ui_Form):
def __init__(self, name, rate, address, main_dishes, price, x_pos, y_pos, img_path, parent=None):
super().__init__(parent)
self.setupUi(self)
self.name = name
self.rate = rate
self.address = address
self.main_dishes = main_dishes
self.price = price
self.x_pos = x_pos
self.y_pos = y_pos
self.img_path = img_path
# Replace with the actual image path
self.circular_image = self.circleImage(self.img_path)
# self.imageLabel.setPixmap(circular_image)
self.seoul_main = parent
self.name_lab.setText(f"이 름 : {self.name} 평 점 : {self.rate}")
self.type_lab.setText(f"메인 메뉴 : {self.main_dishes} 가 격 대 : {self.price}")
self.location_lab.setText(f"주 소 : {self.address}")
# self.img_label.setPixmap(QPixmap(f"{self.img_path}"))
self.img_label.setPixmap(self.circular_image)
def circleImage(self, imagePath):
source = QtGui.QPixmap(imagePath)
size = min(source.width(), source.height())
target = QtGui.QPixmap(size, size)
target.fill(QtCore.Qt.transparent)
qp = QtGui.QPainter(target)
qp.setRenderHints(qp.Antialiasing)
path = QtGui.QPainterPath()
path.addEllipse(0, 0, size, size)
qp.setClipPath(path)
sourceRect = QtCore.QRect(0, 0, size, size)
sourceRect.moveCenter(source.rect().center())
qp.drawPixmap(target.rect(), source, sourceRect)
qp.end()
return target
def mousePressEvent(self, event):
self.seoul_main.stackedWidget.setCurrentWidget(self.seoul_main.main_page_4)
self.seoul_main.name_lab.setText(f"이 름 : {self.name} 평 점 : {self.rate}")
self.seoul_main.type_lab.setText(f"메인 메뉴 : {self.main_dishes} 가 격 대 : {self.price}")
self.seoul_main.location_lab.setText(f"주 소 : {self.address}")
self.seoul_main.img_label.setPixmap(self.circular_image)
self.create_map()
def create_map(self):
map = folium.Map(location=[self.x_pos, self.y_pos], zoom_start=17, scrollWheelZoom=False,
zoom_control=False, dragging=False)
folium.Marker([self.x_pos, self.y_pos], tooltip=self.name, icon=folium.Icon(color="green")).add_to(
map)
map.save('map.html')
self.loadPage()
def loadPage(self):
layout = self.seoul_main.map_widget.layout()
layout.addWidget(self.seoul_main.webview)
with open('map.html', 'r', encoding='UTF8') as f:
html = f.read()
self.seoul_main.webview.setHtml(html)
if __name__ == '__main__':
app = QApplication(sys.argv)
myWindow = SeoulForFood()
myWindow.show()
app.exec()
widget_for_sleep.py
더보기
import sys
import folium
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from seoul_widget import *
class SeoulForSleep(QWidget, Ui_Form):
def __init__(self, name, status, address, x_pos, y_pos, image_path,parent=None):
super().__init__(parent)
self.setupUi(self)
self.name = name
self.status = status
self.address = address
self.x_pos = x_pos
self.y_pos = y_pos
self.image_path = image_path
self.seoul_main = parent
self.circular_img = self.circleImage(image_path)
self.name_lab.setText(f"이 름 : {self.name}")
self.type_lab.setText(f"상 태 : {self.status}")
self.location_lab.setText(f"주 소 : {self.address}")
self.img_label.setPixmap(self.circular_img)
def mousePressEvent(self, event):
self.seoul_main.stackedWidget.setCurrentWidget(self.seoul_main.main_page_4)
self.seoul_main.name_lab.setText(f"이 름 : {self.name}")
self.seoul_main.type_lab.setText(f"상 태 : {self.status}")
self.seoul_main.location_lab.setText(f"주 소 : {self.address}")
# self.seoul_main.img_label.setPixmap(QPixmap(f"{self.image_path}"))
self.seoul_main.img_label.setPixmap(self.circular_img)
self.create_map()
def circleImage(self, imagePath):
source = QtGui.QPixmap(imagePath)
size = min(source.width(), source.height())
target = QtGui.QPixmap(size, size)
target.fill(QtCore.Qt.transparent)
qp = QtGui.QPainter(target)
qp.setRenderHints(qp.Antialiasing)
path = QtGui.QPainterPath()
path.addEllipse(0, 0, size, size)
qp.setClipPath(path)
sourceRect = QtCore.QRect(0, 0, size, size)
sourceRect.moveCenter(source.rect().center())
qp.drawPixmap(target.rect(), source, sourceRect)
qp.end()
return target
def create_map(self):
map = folium.Map(location=[self.x_pos, self.y_pos], zoom_start=17, scrollWheelZoom=False,
zoom_control=False, dragging=False)
folium.Marker([self.x_pos, self.y_pos], tooltip=self.name, icon=folium.Icon(color="green")).add_to(
map)
map.save('map.html')
self.loadPage()
def loadPage(self):
layout = self.seoul_main.map_widget.layout()
layout.addWidget(self.seoul_main.webview)
with open('map.html', 'r', encoding='UTF8') as f:
html = f.read()
self.seoul_main.webview.setHtml(html)
if __name__ == '__main__':
app = QApplication(sys.argv)
myWindow = SeoulForSleep()
myWindow.show()
app.exec()
widget_for_tour.py
더보기
import sys
import folium
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from seoul_widget import *
class SeoulForTour(QWidget, Ui_Form):
def __init__(self, name, address, working_day, working_time, holiday, x_pos, y_pos, image_path, parent=None):
super().__init__(parent)
self.setupUi(self)
self.seoul_main = parent
self.name = name
self.address = address
self.working_day = working_day
self.working_time = working_time
self.holiday = holiday
self.x_pos = x_pos
self.y_pos = y_pos
self.image_path = image_path
self.circlular_image = self.circleImage(self.image_path)
self.name_lab.setText(f"이 름 : {self.name}")
self.type_lab.setText(f"운영요일 : {self.working_day}\n운영시간 : {self.working_time}\n휴무일 :{self.holiday}")
self.location_lab.setText(f"주 소 : {self.address}")
# self.img_label.setPixmap(QPixmap(f"{self.image_path}"))
self.img_label.setPixmap(self.circlular_image)
def circleImage(self, imagePath):
source = QtGui.QPixmap(imagePath)
size = min(source.width(), source.height())
target = QtGui.QPixmap(size, size)
target.fill(QtCore.Qt.transparent)
qp = QtGui.QPainter(target)
qp.setRenderHints(qp.Antialiasing)
path = QtGui.QPainterPath()
path.addEllipse(0, 0, size, size)
qp.setClipPath(path)
sourceRect = QtCore.QRect(0, 0, size, size)
sourceRect.moveCenter(source.rect().center())
qp.drawPixmap(target.rect(), source, sourceRect)
qp.end()
return target
def mousePressEvent(self, event):
self.seoul_main.stackedWidget.setCurrentWidget(self.seoul_main.main_page_4)
self.seoul_main.name_lab.setText(f"이 름 : {self.name}")
self.seoul_main.type_lab.setText(f"운영요일 : {self.working_day}\n운영시간 : {self.working_time}\n휴무일 :{self.holiday}")
self.seoul_main.location_lab.setText(f"주 소 : {self.address}")
self.seoul_main.img_label.setPixmap(self.circlular_image)
self.create_map()
def create_map(self):
map = folium.Map(location=[self.x_pos, self.y_pos], zoom_start=17, scrollWheelZoom=False,
zoom_control=False, dragging=False)
folium.Marker([self.x_pos, self.y_pos], tooltip=self.name, icon=folium.Icon(color="green")).add_to(
map)
map.save('map.html')
self.loadPage()
def loadPage(self):
layout = self.seoul_main.map_widget.layout()
layout.addWidget(self.seoul_main.webview)
with open('map.html', 'r', encoding='UTF8') as f:
html = f.read()
self.seoul_main.webview.setHtml(html)
if __name__ == '__main__':
app = QApplication(sys.argv)
myWindow = SeoulForTour()
myWindow.show()
app.exec()
widget_for_graph.py
더보기
import sys
import folium
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from map_widget import *
class SeoulforGraph(QWidget, Ui_Form):
def __init__(self, name, img_path, desc, parent=None):
super().__init__(parent)
self.setupUi(self)
self.graph_name = name
self.img_path = img_path
self.desc = desc
self.seoul_main = parent
self.map_lab.setPixmap(QPixmap(f"{self.img_path}"))
self.map_info.setText(f"{self.graph_name}")
def mousePressEvent(self, event):
self.seoul_main.stackedWidget.setCurrentWidget(self.seoul_main.main_page_7)
self.seoul_main.graph_img_lab.setPixmap(QPixmap(f"{self.img_path}"))
self.seoul_main.graph_info_lab.setText(f"{self.desc}")
self.seoul_main.grahp_title_lab.setText(f'{self.graph_name}')
if __name__ == '__main__':
app = QApplication(sys.argv)
myWindow = SeoulforGraph()
myWindow.show()
app.exec()
'공부_백업용 > 프로젝트 모음' 카테고리의 다른 글
[팀프로젝트] (23.7.24 ~ 7.29) 업무 협업툴 만들기 (0) | 2023.08.19 |
---|---|
[팀프로젝트] (23.7.10 ~ 7.16) 채팅 프로그램 만들기 개발완료보고서 (2) | 2023.08.19 |
[개인프로젝트] (23.6.13 ~ 6.23) 메가커피 키오스크 만들기 개발완료보고서 (5) | 2023.08.18 |
[개인프로젝트] (23.6.28 ~ 7.1) 영화추천기 개발완료 보고서 (0) | 2023.07.01 |
[프로젝트] 개인프로젝트 - 키오스크 제작: 요구분석서 작성하기 (0) | 2023.06.12 |