引言
西安疫情当道,在网上并没有找到可靠的疫情地理位置的查询,索性写一个,通过键入地址,进行查询当前位置疫情地区,利用地图展示出来,并标注方圆5公里位置,方便防疫以及谨慎出行。(目前仅支持西安地区)
功能结构
输入地理位置,地图展示周围疫情地点,并标注方圆5公里位置。
pyQt5 + request + 高德API + folium + Sqlite
- pyQt5 制作桌面应用
- request + 高德API,通过输入地址获取标准地址名称和经纬度信息
- 利用foliium加载经纬度信息,在地图上标注对应的地理位置
-
将中风险地区经纬度信息,存储在sqlite轻量库内,待使用。
小应用上图
RiskCitySearch
代码DEMO
- 部分1: 请求高德API获取经纬度信息,存储Sqlite
# coding=utf-8
import requests
import jsonpath
from RiskCheck.setting import GAODE_GET_LOCATION
## 请求高德API功能类
class RequestGaodeApi:
def __init__(self):
self.base_url = GAODE_GET_LOCATION
def request_gaode_get_lat_lon(self, address, output_format='JSON'):
params = {
'address': address,
'output': output_format,
}
info = requests.get(self.base_url, params=params).json()
try:
formatted_address = jsonpath.jsonpath(info, '$..formatted_address')
location = jsonpath.jsonpath(info, '$..location')
except Exception as e:
print(e)
if type(formatted_address) != bool and type(location) != bool:
ret = (
''.join(formatted_address),
[float(x) for x in ",".join(location).split(",")],
)
else:
ret = ()
return ret
## 数据保存sqlite库
def save_db(address: list):
request_gaodeAPI = RequestGaodeApi()
ret = [request_gaodeAPI.request_gaode_get_lat_lon(x) for x in address]
print(ret)
sql = 'insert into risk_city_location values(?,?,?)'
insert_info = [(x[0], x[1][0], x[1][1]) for x in ret if x]
conn_sqlite = ConnSQLite(db_path)
cur = conn_sqlite.cur
# print(cur)
try:
cur.executemany(sql, insert_info)
except Exception as e:
print(e)
finally:
conn_sqlite.conn.commit()
cur.close()
conn_sqlite.conn.close()
- 部分2:利用folium生成地图,并将经纬度信息在地图上打标记
import folium
from RiskCheck.setting import CIRCLE_KILOMETER
class GenMapDisplay:
def __init__(self, location: list, address):
self.m = folium.Map(location=location, zoom_start=13, width='100%', height='100%',
zoom_control='False',
tiles='http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}<ype=6',
attr='AutoNavi'
)
folium.Marker(location=location, popup=address, icon=folium.Icon('green')).add_to(self.m)
folium.Circle(location=location,radius=CIRCLE_KILOMETER,popup='方圆5公里内').add_to(self.m)
def gen_map(self, address_list: list):
[folium.Marker(location=[x[1], x[2]], popup=x[0], icon=folium.Icon('red')).add_to(self.m)
for x in address_list]
self.m.save('risk_city.html')
-
部分3:Qt Designer 设置版式
Qt Designer
a. Label 标签文字展示,填充框解释文字信息。
b. Line Edit 单行输入框,接入人工输入信息。
c. Push Button 点击按钮,动作触发按钮,可绑定自定义功能函数。
d. QWebEngineView 加载html文件,可自定义传入html文件。
e. 将ui文件,转化成python代码
# 通过pyuic5将Qt Designer设计的ui文件,转化成python代码
pyuic5 -o D:\PyQt5\riskCitySearchWindow.py D:\PyQt5\riskCitySearch.ui
- 部分4:启动窗口主程序
import sys, riskCitySearchWindow, os
from PyQt5.QtCore import QUrl, QFileInfo
from PyQt5.QtWidgets import QApplication, QDialog, QMainWindow, QMessageBox, QPushButton
from RiskCheck.common.connSQLite import ConnSQLite
from RiskCheck.common.utils import transform_list
from RiskCheck.getRiskCityLocation.requestGaodeApi import RequestGaodeApi
from RiskCheck.mapDisplay.genMapDisplay import GenMapDisplay
base_path = os.getcwd()
db_path = os.path.join(base_path, 'common/risk.db')
class MainWindow(QMainWindow):
def __init__(self):
super(QMainWindow, self).__init__()
self.ui = riskCitySearchWindow.Ui_MainWindow()
self.ui.setupUi(self)
conn_sqlite = ConnSQLite(db_path)
sql = 'select risk_address,risk_longitude,risk_latitude from risk_city_location'
self.risk_address_list = conn_sqlite.read_record_sqlite(sql)
def general_maps(self):
your_address = self.ui.lineEdit.text()
# 获取输入地址的location
request_gaode_api = RequestGaodeApi()
your_location = request_gaode_api.request_gaode_get_lat_lon(your_address)
if len(your_location) >= 2:
location = transform_list(your_location[1])
address = your_location[0]
# 生成地图
gen_map_display = GenMapDisplay(location, address)
gen_map_display.gen_map(self.risk_address_list)
self.ui.webEngineView.load(QUrl(QFileInfo('./risk_city.html').absoluteFilePath()))
self.ui.webEngineView.show()
else: ## 请求不到地址时,弹出提示框,并清理输入框内容
self.show_message()
self.clear_text()
def clear_text(self):
self.ui.lineEdit.clear()
self.ui.webEngineView.close()
def show_message(self):
QMessageBox.critical(self, "错误", "输入地址未识别,请重新输入")
详细代码见gitee
RiskCitySearch: 疫情地区查询 (gitee.com)
网友评论