需求

    测绘时候经常用到rtk,可以测量一点的经纬度和高程,做控制点测量的时候,每个点需要测量多次,然后取平均值作为该点的最终值。

    现在公司里有两套仪器,导出的格式略有不同,我们需要提取 点的编号、经度、纬度、高程 这4个数据,然后把同一个点的多次测量结果求平均值;另外需要GUI界面,降低操作难度;其次,有时候需要同时使用多台仪器测量,所以要能一次输入导出的多个文件,输出一个最终处理结果;最后,处理结果要求可以选择csv、xlsx、dat三种格式,有时候要xlsx格式上报,有时候需要dat格式导入cass,有时候需要csv格式便于查看。

思路

  1. 判断输入的数据是哪套仪器导出的
  2. 提取 点编号、经度、纬度、高程 
  3. 间距小于0.1的点视为同一位置的多次测量结果,要对这些点求均值,测量的次数不固定,可能有任意多个
  4. 输出结果到一个文件
  5. 写个界面包装下

结果

Python 自定义函数 求平均值 python编程求平均值_数据

处理完毕

Python 自定义函数 求平均值 python编程求平均值_cass或cad里提取点坐标及高程的插件_02

处理结果

01

数据实例

Python 自定义函数 求平均值 python编程求平均值_Python 自定义函数 求平均值_03

rtk仪器1导出的结果

Python 自定义函数 求平均值 python编程求平均值_字符串_04

rtk仪器2导出的结果

02

开始写代码

import sysimport ctlsui import timeimport osimport xlwtfrom PyQt5.QtWidgets import (QMainWindow, QTextEdit,                             QAction, QFileDialog, QApplication,QMessageBox,QWidget)#dat:6,7   y,x,hclass ctl(QWidget):    def __init__(self,ui):        super(ctl,self).__init__()        self.ui = ui        self.xt = ''        self.zjg = ''    def warn(self,str_):        QMessageBox.information(self,                         #使用infomation信息框                                    "警告",                                    str_,                                    QMessageBox.Yes)    def showDialog(self):        #self.ui.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)          # 弹出文件选择框。第一个字符串参数是getOpenFileName()方法的标题。第二个字符串参数指定了对话框的工作目录。        # 默认的,文件过滤器设置成All files (*)。        fname = QFileDialog.getOpenFileNames(None, '打开文件', '','*.csv;;*')        # 选中文件后,读出文件的内容,并设置成文本编辑框组件的显示文本        if fname[0]:            paths = fname[0]            if isinstance(paths, list):                paths = '\n'.join(paths)            if self.ui.text.toPlainText():                self.ui.text.setPlainText(self.ui.text.toPlainText()+'\n'+paths)            else:                self.ui.text.setPlainText(paths)    #C:\Users\Administrator\Documents\Fiddler2    def write_excel(self,result,path=time.strftime("%Y%m%d_像控点.xls", time.localtime())):        path = path +'/'+time.strftime("%Y%m%d_像控点.xls", time.localtime())        workbook = xlwt.Workbook(encoding = 'ascii')        worksheet = workbook.add_sheet('像控点')        for i in range(len(result)):            for k in range(len(result[i])):                worksheet.write(i, k, result[i][k])        workbook.save(path)        return path    def write_csv(self,type_,result,path=time.strftime("%Y%m%d_像控点.csv", time.localtime())):        path = path +'/'+time.strftime("%Y%m%d_像控点.csv", time.localtime())        if type_ == 'dat':            path =path.replace('csv','dat')            result = result[1:]        with open(path,'w+',encoding='ascii')as f:            for item in result:                #print(item)                f.write("{},,{},{},{}\n".format(item[0],item[1],item[2],item[3]))        return path    def read_fle(self,path):        try:            #输入文件path,全部整理成一个样子            #-->#点号,x,y,h            with open(path, 'r',encoding='ansi') as f:                datas =  f.readlines()            result = []            if 'Version : 1' in datas[0]:                #大黄                for item in [k.split(',') for k in datas[2:]]:                    result.append((item[0],float(item[2]),float(item[1]),float(item[3])))            else:                #小蓝                 for item in [k.split(',') for k in datas[1:]]:                    result.append((item[0],float(item[13]),float(item[12]),float(item[14])))            return result        except:            self.warn('文件打开失败')                    def join_data(self,data):        #数据聚类、求平均        #输出结果数据[点,x,y,h]        #同一点要求:a-b<1        result = []        for item in data:            tmp = []            for k in data:#遍历其他                if abs(item[1]-k[1])<=1 and abs(item[2]-k[2])<=1:                    #xy的差值小于1                    if str(k) not in tmp:                        tmp.append(str(k))            if str(tmp) not in result:                result.append(str(tmp))        #average        new_result =[]        for items in list(result):            items = list(eval(items))            tmp = [items[0][0]]            x = 0            y = 0            h = 0            # print(items)            for item in items:                item = eval(item)                x +=item[1]                y +=item[2]                h += item[3]            x = x/len(items)            y /=len(items)            h /= len(items)            new_result.append([eval(items[0])[0],x,y,h])        #print(new_result)        return new_result    def cal(self):        try:            if self.ui.text.toPlainText():                #read files                self.result = [['点名','东坐标','北坐标','高程']]                for path in self.ui.text.toPlainText().split('\n'):                    if path:                        data=self.read_fle(path)                        self.result +=self.join_data(data)                print('done')                #print(self.result)                path ='C:/Users/Administrator/Documents/像控点处理'                if not os.path.exists(path):                    os.makedirs(path)                #write                excel_path = ''                csv_path = ''                dat_path = ''                if self.ui.excel.isChecked():                    excel_path = self.write_excel(self.result,path)                if self.ui.csv.isChecked():                    csv_path = self.write_csv('csv',self.result,path)                if self.ui.dat.isChecked():                    dat_path = self.write_csv('dat',self.result,path)                                if excel_path or csv_path or dat_path:                    QMessageBox.information(self,                         #使用infomation信息框                                            "处理完毕",                                            '处理完毕,已保存到'+path,                                            QMessageBox.Yes)                    if csv_path:                        os.startfile(csv_path)                    elif excel_path:                        os.startfile(excel_path)                    else:                        os.startfile(path)                else:                    QMessageBox.information(self,                         #使用infomation信息框                                            "处理完毕",                                            '未选择保存文件类型',                                            QMessageBox.Yes)            else:                self.warn('请输入数据')        except Exception as e:            print(e)            with open('log.txt','a+',encoding = 'utf-8')as f:                f.write(e)            QMessageBox.information(self,                         #使用infomation信息框                                                "未知错误",                                                '错误已保存到log.txt',                                                QMessageBox.Yes)if __name__ == '__main__':           app = QApplication(sys.argv)        MainWindow = QMainWindow()        ui = ctlsui.Ui_mainWindow()        ui.setupUi(MainWindow)        MainWindow.show()        ctl = ctl(ui)        ui.open.clicked.connect(lambda :ctl.showDialog())        ui.start.clicked.connect(lambda :ctl.cal())        sys.exit(app.exec_())

ui代码  ctlsui.py

# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'ctls.ui'## Created by: PyQt5 UI code generator 5.15.0## WARNING: Any manual changes made to this file will be lost when pyuic5 is# run again.  Do not edit this file unless you know what you are doing.from re import findallfrom PyQt5 import QtCore, QtGui, QtWidgetsclass textEdit(QtWidgets.QPlainTextEdit):    def __int__(self):        super().__init__()        self.setAcceptDrops(True) #允许接收拖曳过来的内容    def dragEnterEvent(self, e):        if e.mimeData().hasText():            e.accept()        else:            e.ignore()    def dropEvent(self, e):        if self.toPlainText():            self.setPlainText(self.toPlainText()+'\n'+e.mimeData().text().replace('file:///', ''))        else:            self.setPlainText(e.mimeData().text().replace('file:///', ''))class Ui_mainWindow(object):    def setupUi(self, mainWindow):        mainWindow.setObjectName("mainWindow")        mainWindow.resize(425, 265)        self.centralwidget = QtWidgets.QWidget(mainWindow)        self.centralwidget.setObjectName("centralwidget")        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)        self.gridLayout.setObjectName("gridLayout")        self.text = textEdit()        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)        sizePolicy.setHorizontalStretch(0)        sizePolicy.setVerticalStretch(0)        sizePolicy.setHeightForWidth(self.text.sizePolicy().hasHeightForWidth())        self.text.setSizePolicy(sizePolicy)        self.text.setObjectName("text")        self.gridLayout.addWidget(self.text, 0, 0, 1, 1)        self.verticalLayout = QtWidgets.QVBoxLayout()        self.verticalLayout.setObjectName("verticalLayout")        self.open = QtWidgets.QPushButton(self.centralwidget)        font = QtGui.QFont()        font.setBold(True)        font.setWeight(75)        self.open.setFont(font)        self.open.setObjectName("open")        self.verticalLayout.addWidget(self.open)        self.excel = QtWidgets.QCheckBox(self.centralwidget)        self.excel.setObjectName("excel")        self.verticalLayout.addWidget(self.excel)        self.csv = QtWidgets.QCheckBox(self.centralwidget)        self.csv.setChecked(True)        self.csv.setObjectName("csv")        self.verticalLayout.addWidget(self.csv)        self.dat = QtWidgets.QCheckBox(self.centralwidget)        self.dat.setObjectName("dat")        self.dat.setChecked(True)        self.verticalLayout.addWidget(self.dat)        self.gridLayout.addLayout(self.verticalLayout, 0, 1, 1, 1)        self.start = QtWidgets.QPushButton(self.centralwidget)        self.start.setLayoutDirection(QtCore.Qt.LeftToRight)        self.start.setObjectName("start")        self.gridLayout.addWidget(self.start, 1, 0, 1, 2)        mainWindow.setCentralWidget(self.centralwidget)        self.menubar = QtWidgets.QMenuBar(mainWindow)        self.menubar.setGeometry(QtCore.QRect(0, 0, 425, 22))        self.menubar.setObjectName("menubar")        mainWindow.setMenuBar(self.menubar)        self.statusbar = QtWidgets.QStatusBar(mainWindow)        self.statusbar.setObjectName("statusbar")        mainWindow.setStatusBar(self.statusbar)        self.retranslateUi(mainWindow)        QtCore.QMetaObject.connectSlotsByName(mainWindow)    def retranslateUi(self, mainWindow):        _translate = QtCore.QCoreApplication.translate        mainWindow.setWindowTitle(_translate("mainWindow", "控制点数据批量处理"))        self.text.setPlaceholderText(_translate("mainWindow", "请拖入或右侧打开文件"))        self.open.setText(_translate("mainWindow", "..."))        self.excel.setText(_translate("mainWindow", "导出至excel"))        self.csv.setText(_translate("mainWindow", "导出至csv"))        self.dat.setText(_translate("mainWindow", "导出至dat"))        self.start.setText(_translate("mainWindow", "开始处理"))

03

运行

Python 自定义函数 求平均值 python编程求平均值_c++求平均值_05

只要将仪器导出的文件拖入或者点击右侧按钮打开文件,就可以开始处理任意数量的文件,右侧还可以选择处理结果的格式,默认为csv和dat格式,点击开始处理,处理完毕后会自动打开文件便于查看。一般按下开始处理按钮,数据就处理完了,比以往要快很多。