├── module ├── __init__.py ├── fileRW.py ├── thread.py ├── main.py └── main.ui ├── locationConvert.gif ├── README.md └── locationConvert.py /module/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /locationConvert.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MacwinWin/amap-location-to-lnglat/HEAD/locationConvert.gif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # amap-location-to-lnglat 2 | 使用高德地图api批量转换地址为经纬度 3 | - PyQt5 4 | - pandas 5 | - requests 6 | - qdarkstyle 7 | 8 | 1. 软件界面框架使用PyQt5,并使用QThread多线程,将界面线程与执行线程分离,保证在进行转换时界面不阻塞; 9 | 2. 转换过程调用高德地图api,需自行申请key,并替换[此处key值](https://github.com/MacwinWin/amap-location-to-lnglat/blob/29f1d4d0b52c6a98785ccb4357a3fc60c0b328ea/module/thread.py#L33); 10 | 3. 界面美化使用qdarkstyle 11 | 12 | 13 | -------------------------------------------------------------------------------- /module/fileRW.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | from PyQt5.QtWidgets import QFileDialog 5 | import os 6 | 7 | class fileClass(): 8 | 9 | def read_file(self): 10 | fileName_choose, filetype = QFileDialog.getOpenFileNames(None, 11 | '多选文件', 12 | '', 13 | 'All Files (*);;Excel 文件 (*.xlsx)') 14 | return fileName_choose 15 | 16 | def write_file(self): 17 | fileName_choose, filetype = QFileDialog.getSaveFileName(None, 18 | "文件保存", 19 | '', # 起始路径 20 | "All Files (*);;Excel 文件 (*.xlsx)") 21 | return fileName_choose 22 | 23 | def read_one_file(self): 24 | fileName_choose, filetype = QFileDialog.getOpenFileName(None, 25 | '单选文件', 26 | '', 27 | 'All Files (*);;Excel 文件 (*.xlsx)') 28 | return fileName_choose -------------------------------------------------------------------------------- /locationConvert.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | import traceback 4 | from PyQt5.QtWidgets import QMainWindow, QApplication, QMessageBox 5 | from PyQt5.QtGui import QIntValidator, QIcon 6 | from PyQt5 import QtCore 7 | from module import main, fileRW, convert 8 | from module.thread import Actions 9 | import qdarkstyle 10 | 11 | class MyFrom(QMainWindow): 12 | def __init__(self): 13 | super().__init__() 14 | self.ui = main.Ui_MainWindow() 15 | self.ui.setupUi(self) 16 | self.fileRW = fileRW.fileClass() 17 | self.ui.select_file.clicked.connect(self.getFileName) 18 | self.ui.start_convert.clicked.connect(self.convertLocation) 19 | self.ui.clear.clicked.connect(self.clearTextBrowser) 20 | self.ui.export_file.clicked.connect(self.exportFile) 21 | QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling) 22 | 23 | def convertLocation(self): 24 | self.city = self.ui.city_lineEdit.text() 25 | self.location = self.ui.location_lineEdit.text() 26 | self.main = Actions(self.ui, self.filePath, self.city, self.location) 27 | self.main.returnDF.connect(self.receiveDF) 28 | #self.main.show() 29 | #self.main.exec_() 30 | 31 | def receiveDF(self, df): 32 | self.df = df 33 | self.exportEnable() 34 | self.ui.export_file.setEnabled(True) 35 | 36 | def clearTextBrowser(self): 37 | self.filePath = [] 38 | self.ui.select_textBrowser.clear() 39 | self.ui.city_lineEdit.setEnabled(False) 40 | self.ui.location_lineEdit.setEnabled(False) 41 | self.ui.export_file.setEnabled(False) 42 | self.ui.convert_lable.clear() 43 | 44 | def getFileName(self): 45 | self.filePath = self.fileRW.read_one_file() 46 | #self.fileName = os.path.basename(self.filePath) 47 | self.ui.select_textBrowser.setText(os.path.basename(self.filePath)) 48 | self.ui.convert_lable.setText('') 49 | self.ui.export_lable.setText('') 50 | self.convertEnable() 51 | 52 | def convertEnable(self): 53 | if self.ui.select_textBrowser.toPlainText() != '': 54 | self.ui.city_lineEdit.setEnabled(True) 55 | self.ui.location_lineEdit.setEnabled(True) 56 | self.ui.start_convert.setEnabled(True) 57 | 58 | def exportEnable(self): 59 | if self.ui.convert_lable.text() == '转换完成!': 60 | self.ui.export_file.setEnabled(True) 61 | 62 | def exportFile(self): 63 | self.path = self.fileRW.write_file() 64 | try: 65 | self.df.to_excel(self.path, index = None, engine = 'xlsxwriter') 66 | self.ui.export_lable.setText('导出完成!') 67 | self.init() 68 | except: 69 | traceback.print_exc() 70 | 71 | def init(self): 72 | self.filePath = [] 73 | self.ui.select_textBrowser.clear() 74 | self.ui.city_lineEdit.setEnabled(False) 75 | self.ui.location_lineEdit.setEnabled(False) 76 | self.ui.start_convert.setEnabled(False) 77 | self.ui.export_file.setEnabled(False) 78 | 79 | if __name__ == '__main__': 80 | app = QApplication(sys.argv) 81 | app.setStyleSheet(qdarkstyle.load_stylesheet_pyqt5()) 82 | w = MyFrom() 83 | app.setWindowIcon(QIcon('logo.ico')) 84 | w.show() 85 | sys.exit(app.exec_()) -------------------------------------------------------------------------------- /module/thread.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import time 3 | import traceback 4 | 5 | from PyQt5.QtCore import Qt, QThread, pyqtSignal 6 | from PyQt5.QtWidgets import (QApplication, QDialog, 7 | QProgressBar, QPushButton) 8 | import pandas as pd 9 | import requests 10 | 11 | TIME_LIMIT = 100 12 | 13 | class convertClass(QThread): 14 | 15 | countChanged = pyqtSignal(int) 16 | returnDF = pyqtSignal(pd.DataFrame) 17 | close = pyqtSignal(int) 18 | def __init__(self, filePath, city, location): 19 | super(convertClass, self).__init__() 20 | self.url = "https://restapi.amap.com/v3/place/text" 21 | self.df = pd.read_excel(filePath) 22 | self.df['经纬度'] = '' 23 | self.city = city 24 | self.location = location 25 | 26 | def run(self): 27 | i = 0 28 | try: 29 | for index, row in self.df.iterrows(): 30 | city = row[self.city] 31 | item = row[self.location] 32 | data = { 33 | 'key': 'xxxxxxxxxxxxx', #在高德地图开发者平台申请的key,需要替换为自己的key 34 | 'keywords': item, 35 | 'city': city, 36 | 'types':'普通地名', 37 | 'citylimit':'true' 38 | } 39 | r = requests.get(self.url, params=data).json() 40 | try: 41 | i += 1 42 | lnglat = r['pois'][0]['location'] 43 | self.df.loc[index, '经纬度'] = lnglat 44 | except: 45 | traceback.print_exc() 46 | pass 47 | finally: 48 | count = i / self.df.shape[0] * 100 49 | self.countChanged.emit(int(count)) 50 | self.returnDF.emit(self.df) 51 | self.close.emit(1) 52 | except: 53 | traceback.print_exc() 54 | self.close.emit(0) 55 | #return self.df 56 | 57 | class Actions(QDialog): 58 | """ 59 | Simple dialog that consists of a Progress Bar and a Button. 60 | Clicking on the button results in the start of a timer and 61 | updates the progress bar. 62 | """ 63 | returnDF = pyqtSignal(pd.DataFrame) 64 | def __init__(self, ui, filePath, city, location): 65 | super().__init__() 66 | self.ui = ui 67 | self.filePath = filePath 68 | self.city = city 69 | self.location = location 70 | self.initUI() 71 | 72 | def initUI(self): 73 | # 阻塞父窗口 74 | self.setWindowModality(Qt.ApplicationModal) 75 | self.setWindowTitle('Progress Bar') 76 | self.progress = QProgressBar(self) 77 | self.progress.setGeometry(0, 0, 300, 25) 78 | self.progress.setMaximum(100) 79 | self.show() 80 | self.calc = convertClass(self.filePath, self.city, self.location) 81 | self.calc.countChanged.connect(self.onCountChanged) 82 | self.calc.returnDF.connect(self.returnDf) 83 | self.calc.close.connect(self.closeWindow) 84 | self.calc.start() 85 | 86 | def closeWindow(self, value): 87 | if value == 1: 88 | self.ui.convert_lable.setText('转换完成!') 89 | elif value == 0: 90 | self.ui.export_file.setEnabled(False) 91 | self.ui.convert_lable.setText('转换失败!') 92 | self.close() 93 | 94 | def returnDf(self, df): 95 | self.returnDF.emit(df) 96 | 97 | def onCountChanged(self, value): 98 | self.progress.setValue(value) 99 | 100 | if __name__ == "__main__": 101 | app = QApplication(sys.argv) 102 | window = Actions() 103 | sys.exit(app.exec_()) -------------------------------------------------------------------------------- /module/main.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file '.\main.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.11.3 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_MainWindow(object): 12 | def setupUi(self, MainWindow): 13 | MainWindow.setObjectName("MainWindow") 14 | MainWindow.resize(432, 241) 15 | self.centralwidget = QtWidgets.QWidget(MainWindow) 16 | self.centralwidget.setObjectName("centralwidget") 17 | self.gridLayout_3 = QtWidgets.QGridLayout(self.centralwidget) 18 | self.gridLayout_3.setObjectName("gridLayout_3") 19 | self.label_2 = QtWidgets.QLabel(self.centralwidget) 20 | self.label_2.setAlignment(QtCore.Qt.AlignCenter) 21 | self.label_2.setObjectName("label_2") 22 | self.gridLayout_3.addWidget(self.label_2, 2, 0, 1, 1) 23 | self.city_lineEdit = QtWidgets.QLineEdit(self.centralwidget) 24 | self.city_lineEdit.setEnabled(False) 25 | self.city_lineEdit.setMaximumSize(QtCore.QSize(100, 27)) 26 | font = QtGui.QFont() 27 | font.setFamily("微软雅黑") 28 | font.setPointSize(10) 29 | self.city_lineEdit.setFont(font) 30 | self.city_lineEdit.setText("") 31 | self.city_lineEdit.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) 32 | self.city_lineEdit.setObjectName("city_lineEdit") 33 | self.gridLayout_3.addWidget(self.city_lineEdit, 2, 1, 1, 1) 34 | self.select_file = QtWidgets.QPushButton(self.centralwidget) 35 | self.select_file.setMaximumSize(QtCore.QSize(83, 27)) 36 | font = QtGui.QFont() 37 | font.setFamily("微软雅黑") 38 | font.setPointSize(10) 39 | self.select_file.setFont(font) 40 | self.select_file.setObjectName("select_file") 41 | self.gridLayout_3.addWidget(self.select_file, 0, 0, 1, 1) 42 | self.location_lineEdit = QtWidgets.QLineEdit(self.centralwidget) 43 | self.location_lineEdit.setEnabled(False) 44 | self.location_lineEdit.setMaximumSize(QtCore.QSize(100, 27)) 45 | font = QtGui.QFont() 46 | font.setFamily("微软雅黑") 47 | font.setPointSize(10) 48 | self.location_lineEdit.setFont(font) 49 | self.location_lineEdit.setText("") 50 | self.location_lineEdit.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter) 51 | self.location_lineEdit.setObjectName("location_lineEdit") 52 | self.gridLayout_3.addWidget(self.location_lineEdit, 3, 1, 1, 1) 53 | self.convert_lable = QtWidgets.QLabel(self.centralwidget) 54 | self.convert_lable.setMaximumSize(QtCore.QSize(83, 27)) 55 | font = QtGui.QFont() 56 | font.setFamily("微软雅黑") 57 | font.setPointSize(10) 58 | self.convert_lable.setFont(font) 59 | self.convert_lable.setText("") 60 | self.convert_lable.setObjectName("convert_lable") 61 | self.gridLayout_3.addWidget(self.convert_lable, 3, 3, 1, 1) 62 | self.select_textBrowser = QtWidgets.QTextBrowser(self.centralwidget) 63 | self.select_textBrowser.setMaximumSize(QtCore.QSize(300, 16777215)) 64 | font = QtGui.QFont() 65 | font.setFamily("微软雅黑") 66 | font.setPointSize(10) 67 | self.select_textBrowser.setFont(font) 68 | self.select_textBrowser.setObjectName("select_textBrowser") 69 | self.gridLayout_3.addWidget(self.select_textBrowser, 1, 0, 1, 3) 70 | self.export_lable = QtWidgets.QLabel(self.centralwidget) 71 | self.export_lable.setMaximumSize(QtCore.QSize(83, 27)) 72 | font = QtGui.QFont() 73 | font.setFamily("微软雅黑") 74 | font.setPointSize(10) 75 | self.export_lable.setFont(font) 76 | self.export_lable.setText("") 77 | self.export_lable.setObjectName("export_lable") 78 | self.gridLayout_3.addWidget(self.export_lable, 4, 1, 1, 1) 79 | self.label = QtWidgets.QLabel(self.centralwidget) 80 | self.label.setAlignment(QtCore.Qt.AlignCenter) 81 | self.label.setObjectName("label") 82 | self.gridLayout_3.addWidget(self.label, 3, 0, 1, 1) 83 | self.export_file = QtWidgets.QPushButton(self.centralwidget) 84 | self.export_file.setEnabled(False) 85 | self.export_file.setMaximumSize(QtCore.QSize(86, 27)) 86 | font = QtGui.QFont() 87 | font.setFamily("微软雅黑") 88 | font.setPointSize(10) 89 | self.export_file.setFont(font) 90 | self.export_file.setObjectName("export_file") 91 | self.gridLayout_3.addWidget(self.export_file, 4, 0, 1, 1) 92 | self.start_convert = QtWidgets.QPushButton(self.centralwidget) 93 | self.start_convert.setEnabled(False) 94 | self.start_convert.setMaximumSize(QtCore.QSize(83, 27)) 95 | font = QtGui.QFont() 96 | font.setFamily("微软雅黑") 97 | font.setPointSize(10) 98 | self.start_convert.setFont(font) 99 | self.start_convert.setObjectName("start_convert") 100 | self.gridLayout_3.addWidget(self.start_convert, 3, 2, 1, 1) 101 | self.clear = QtWidgets.QPushButton(self.centralwidget) 102 | self.clear.setMaximumSize(QtCore.QSize(83, 27)) 103 | font = QtGui.QFont() 104 | font.setFamily("微软雅黑") 105 | font.setPointSize(10) 106 | self.clear.setFont(font) 107 | self.clear.setObjectName("clear") 108 | self.gridLayout_3.addWidget(self.clear, 0, 1, 1, 1) 109 | MainWindow.setCentralWidget(self.centralwidget) 110 | 111 | self.retranslateUi(MainWindow) 112 | QtCore.QMetaObject.connectSlotsByName(MainWindow) 113 | 114 | def retranslateUi(self, MainWindow): 115 | _translate = QtCore.QCoreApplication.translate 116 | MainWindow.setWindowTitle(_translate("MainWindow", "批量转换经纬度v1.1")) 117 | self.label_2.setText(_translate("MainWindow", "选择城市列:")) 118 | self.select_file.setText(_translate("MainWindow", "选择文件")) 119 | self.select_textBrowser.setHtml(_translate("MainWindow", "\n" 120 | "\n" 123 | "


")) 124 | self.label.setText(_translate("MainWindow", "选择地址列:")) 125 | self.export_file.setText(_translate("MainWindow", "导出文件")) 126 | self.start_convert.setText(_translate("MainWindow", "开始转换")) 127 | self.clear.setText(_translate("MainWindow", "清空")) 128 | 129 | -------------------------------------------------------------------------------- /module/main.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 432 10 | 241 11 | 12 | 13 | 14 | 批量转换经纬度v1.1 15 | 16 | 17 | 18 | 19 | 20 | 21 | 选择城市列: 22 | 23 | 24 | Qt::AlignCenter 25 | 26 | 27 | 28 | 29 | 30 | 31 | false 32 | 33 | 34 | 35 | 100 36 | 27 37 | 38 | 39 | 40 | 41 | 微软雅黑 42 | 10 43 | 44 | 45 | 46 | 47 | 48 | 49 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 83 58 | 27 59 | 60 | 61 | 62 | 63 | 微软雅黑 64 | 10 65 | 66 | 67 | 68 | 选择文件 69 | 70 | 71 | 72 | 73 | 74 | 75 | false 76 | 77 | 78 | 79 | 100 80 | 27 81 | 82 | 83 | 84 | 85 | 微软雅黑 86 | 10 87 | 88 | 89 | 90 | 91 | 92 | 93 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 83 102 | 27 103 | 104 | 105 | 106 | 107 | 微软雅黑 108 | 10 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 300 121 | 16777215 122 | 123 | 124 | 125 | 126 | 微软雅黑 127 | 10 128 | 129 | 130 | 131 | <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> 132 | <html><head><meta name="qrichtext" content="1" /><style type="text/css"> 133 | p, li { white-space: pre-wrap; } 134 | </style></head><body style=" font-family:'微软雅黑'; font-size:10pt; font-weight:400; font-style:normal;"> 135 | <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'SimSun'; font-size:9pt;"><br /></p></body></html> 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 83 144 | 27 145 | 146 | 147 | 148 | 149 | 微软雅黑 150 | 10 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 选择地址列: 162 | 163 | 164 | Qt::AlignCenter 165 | 166 | 167 | 168 | 169 | 170 | 171 | false 172 | 173 | 174 | 175 | 86 176 | 27 177 | 178 | 179 | 180 | 181 | 微软雅黑 182 | 10 183 | 184 | 185 | 186 | 导出文件 187 | 188 | 189 | 190 | 191 | 192 | 193 | false 194 | 195 | 196 | 197 | 83 198 | 27 199 | 200 | 201 | 202 | 203 | 微软雅黑 204 | 10 205 | 206 | 207 | 208 | 开始转换 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 83 217 | 27 218 | 219 | 220 | 221 | 222 | 微软雅黑 223 | 10 224 | 225 | 226 | 227 | 清空 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | select_file 236 | clear 237 | select_textBrowser 238 | city_lineEdit 239 | location_lineEdit 240 | start_convert 241 | export_file 242 | 243 | 244 | 245 | 246 | --------------------------------------------------------------------------------