日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python结合ogr2ogr之地理数据格式转换-1

發(fā)布時間:2023/12/15 python 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python结合ogr2ogr之地理数据格式转换-1 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前面寫過一篇公眾號文章,當(dāng)時為了能將矢量CAD數(shù)據(jù)轉(zhuǎn)換成kml,找到了一個開源的.net庫netdxf,該庫支持dxf文件直接讀寫,方便快捷:

DXF轉(zhuǎn)KML-1http://mp.weixin.qq.com/s?__biz=MzIwMDc1NjA0NQ==&mid=2247483785&idx=1&sn=a2d64db37b1a0b1024ba386e84334198&chksm=96f91faba18e96bd63444cb155fee0bb2bcbb06614e1f31abd7b5eeb96673c7fd5e6bdc0d7fb&scene=21#wechat_redirect

DXF轉(zhuǎn)KML-2http://mp.weixin.qq.com/s?__biz=MzIwMDc1NjA0NQ==&mid=2247483789&idx=1&sn=3e0fc1d491508a5f7685d8763720fb0a&chksm=96f91fafa18e96b9c84e1aed05ad3e7aa23c72f758039353b1693e98544f0f4c5e34eafd8a7d&scene=21#wechat_redirect

當(dāng)時的思路是:使用該庫讀取dxf文件,處理讀取的部分?jǐn)?shù)據(jù):line,polyline,circle等,然后將讀取的坐標(biāo)進(jìn)行相應(yīng)的轉(zhuǎn)換后再序列化輸出kml,雖然省了讀的功夫,但是寫也比較麻煩,最主要的問題是:

  • 要素不全,只轉(zhuǎn)換了部分線型,但有時候給的圖偏偏不是這幾種線型,還得編輯一下再轉(zhuǎn)

  • 轉(zhuǎn)換的線型也只輸出了坐標(biāo)信息,其它信息統(tǒng)統(tǒng)舍去,雖然如圖層、顏色之類的信息可能也沒有用

  • 需要有一步就是先將dwg打開另存為dxf

可是地理數(shù)據(jù)種類很多,有時候又是shapefile文件呢?遇到的時候我先把它轉(zhuǎn)成dxf再轉(zhuǎn)換kml,這一波下來,和我直接使用arcgis轉(zhuǎn)換也沒啥區(qū)別了,當(dāng)時的初衷不是為了省事,不借助那么多平臺嗎?于是我又網(wǎng)上搜了一下,發(fā)現(xiàn)了一個很強(qiáng)大的工具ogr2ogr

ogr2ogr的安裝和使用http://mp.weixin.qq.com/s?__biz=MzIwMDc1NjA0NQ==&mid=2247483802&idx=1&sn=4cec448d32b45affa9b59970a6cefed5&chksm=96f91fb8a18e96ae3261d021a3ae019cf17395ef56cb8e2a621b02d6ae49f25f07234ac8863d&scene=21#wechat_redirect

該工具支持幾十種矢量和柵格數(shù)據(jù)之間的轉(zhuǎn)換,更可怕的是,它還能進(jìn)行坐標(biāo)轉(zhuǎn)換??墒撬枰胮ython調(diào)用,于是前面也學(xué)習(xí)了一下python的安裝和開發(fā)環(huán)境布置,然后就放下了。因為python從來沒學(xué)過,只知道它很吊很強(qiáng)大。因為最終我是要制作一個桌面版的exe的,所以我需要解決幾個問題:

1、窗體設(shè)計

2、文件讀取與轉(zhuǎn)換

3、打包成exe

python的窗體程序不像C#那么簡單,它不是自帶的,需要安裝別的模塊,有好多模塊提供了這個功能,最后我選擇了PyQt5,安裝方法就不贅述了,界面如下:

創(chuàng)建一個新窗體

這就和別的Form很像了,也是控件拖拽的方式,根據(jù)需要我設(shè)計了如下界面:

選擇一個要轉(zhuǎn)換的文件類型,瀏覽選擇對應(yīng)的文件,然后選擇一個輸出的文件類型,瀏覽選擇輸出文件,選擇對應(yīng)的坐標(biāo)系,坐標(biāo)系是根據(jù)EPSG來控制的,主要是因為ogr2ogr支持的就是這種模式,這意味著,它是可以在不同橢球之間進(jìn)行轉(zhuǎn)換的,詳細(xì)的我們用得到的EPSG對照表如下:

EPGS對照表-CGCS2000http://mp.weixin.qq.com/s?__biz=MzIwMDc1NjA0NQ==&mid=2247483807&idx=1&sn=546bf94b91adc62ff42287de622c6c12&chksm=96f91fbda18e96ab77f202fb0be74f13c82ddada64a227c1e4c15577279876c51947522c3c0e&scene=21#wechat_redirect

這個表當(dāng)時寫的時候是從EXCEL里拉出來的,有些錯誤,不過應(yīng)該能看得出來。

下面就要貽笑大方之家了,因為python真是小白

窗體和調(diào)用的分離

使用PyQt5生成了一個*.ui文件,因為我在vscode里開發(fā),在vscode里安裝的PyQt5,所以可以直接將*.ui轉(zhuǎn)成.py文件,但是設(shè)計的窗體難免不完美需要改,如果調(diào)用窗體的部分和窗體轉(zhuǎn)換的py是一個文件,下次改變的窗體重新生成py就會覆蓋調(diào)用部分的代碼,所以要調(diào)用和窗體代碼分離。

# -*- coding: utf-8 -*-# Form implementation generated from reading ui file 'g:\python\learting\shapefile\ogr.ui' # # Created by: PyQt5 UI code generator 5.15.6 # # 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 PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(509, 201)MainWindow.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.label = QtWidgets.QLabel(self.centralwidget)self.label.setGeometry(QtCore.QRect(30, 10, 54, 12))self.label.setObjectName("label")self.label_2 = QtWidgets.QLabel(self.centralwidget)self.label_2.setGeometry(QtCore.QRect(20, 40, 54, 12))self.label_2.setObjectName("label_2")self.textEdit = QtWidgets.QTextEdit(self.centralwidget)self.textEdit.setGeometry(QtCore.QRect(90, 10, 221, 21))self.textEdit.setObjectName("textEdit")self.textEdit_2 = QtWidgets.QTextEdit(self.centralwidget)self.textEdit_2.setGeometry(QtCore.QRect(90, 40, 221, 21))self.textEdit_2.setObjectName("textEdit_2")self.pushButton = QtWidgets.QPushButton(self.centralwidget)self.pushButton.setGeometry(QtCore.QRect(430, 10, 75, 23))self.pushButton.setObjectName("pushButton")self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)self.pushButton_2.setGeometry(QtCore.QRect(430, 40, 75, 23))self.pushButton_2.setObjectName("pushButton_2")self.comboBox = QtWidgets.QComboBox(self.centralwidget)self.comboBox.setGeometry(QtCore.QRect(310, 10, 111, 22))self.comboBox.setEditable(True)self.comboBox.setObjectName("comboBox")self.comboBox.addItem("")self.comboBox.addItem("")self.comboBox.addItem("")self.comboBox.addItem("")self.comboBox_2 = QtWidgets.QComboBox(self.centralwidget)self.comboBox_2.setGeometry(QtCore.QRect(310, 40, 111, 22))self.comboBox_2.setTabletTracking(False)self.comboBox_2.setEditable(True)self.comboBox_2.setObjectName("comboBox_2")self.comboBox_2.addItem("")self.comboBox_2.addItem("")self.comboBox_2.addItem("")self.comboBox_2.addItem("")self.label_3 = QtWidgets.QLabel(self.centralwidget)self.label_3.setGeometry(QtCore.QRect(20, 70, 91, 16))self.label_3.setObjectName("label_3")self.comboBox_3 = QtWidgets.QComboBox(self.centralwidget)self.comboBox_3.setGeometry(QtCore.QRect(140, 70, 361, 22))sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)sizePolicy.setHorizontalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.comboBox_3.sizePolicy().hasHeightForWidth())self.comboBox_3.setSizePolicy(sizePolicy)font = QtGui.QFont()font.setFamily("楷體")font.setPointSize(8)self.comboBox_3.setFont(font)self.comboBox_3.setObjectName("comboBox_3")self.comboBox_3.addItem("")self.comboBox_3.addItem("")self.comboBox_3.addItem("")self.label_4 = QtWidgets.QLabel(self.centralwidget)self.label_4.setGeometry(QtCore.QRect(20, 100, 91, 16))self.label_4.setObjectName("label_4")self.comboBox_4 = QtWidgets.QComboBox(self.centralwidget)self.comboBox_4.setGeometry(QtCore.QRect(140, 100, 361, 21))sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)sizePolicy.setHorizontalStretch(0)sizePolicy.setVerticalStretch(0)sizePolicy.setHeightForWidth(self.comboBox_4.sizePolicy().hasHeightForWidth())self.comboBox_4.setSizePolicy(sizePolicy)font = QtGui.QFont()font.setFamily("楷體")font.setPointSize(8)self.comboBox_4.setFont(font)self.comboBox_4.setCursor(QtGui.QCursor(QtCore.Qt.SizeVerCursor))self.comboBox_4.setFocusPolicy(QtCore.Qt.TabFocus)self.comboBox_4.setAcceptDrops(False)self.comboBox_4.setLayoutDirection(QtCore.Qt.LeftToRight)self.comboBox_4.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToMinimumContentsLength)self.comboBox_4.setObjectName("comboBox_4")self.comboBox_4.addItem("")self.comboBox_4.addItem("")self.comboBox_4.addItem("")self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)self.pushButton_3.setGeometry(QtCore.QRect(230, 130, 75, 23))self.pushButton_3.setObjectName("pushButton_3")self.pushButton_4 = QtWidgets.QPushButton(self.centralwidget)self.pushButton_4.setGeometry(QtCore.QRect(310, 130, 75, 23))self.pushButton_4.setObjectName("pushButton_4")self.pushButton_5 = QtWidgets.QPushButton(self.centralwidget)self.pushButton_5.setGeometry(QtCore.QRect(390, 130, 75, 23))self.pushButton_5.setObjectName("pushButton_5")MainWindow.setCentralWidget(self.centralwidget)self.menubar = QtWidgets.QMenuBar(MainWindow)self.menubar.setGeometry(QtCore.QRect(0, 0, 509, 23))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.translateMainWindow.setWindowTitle(_translate("MainWindow", "基礎(chǔ)地理數(shù)據(jù)格式轉(zhuǎn)換"))self.label.setText(_translate("MainWindow", "源文件:"))self.label_2.setText(_translate("MainWindow", "目標(biāo)文件:"))self.pushButton.setText(_translate("MainWindow", "瀏覽"))self.pushButton_2.setText(_translate("MainWindow", "瀏覽"))self.comboBox.setItemText(0, _translate("MainWindow", "所有文件(*.*)"))self.comboBox.setItemText(1, _translate("MainWindow", "CAD文件(*.dwg)"))self.comboBox.setItemText(2, _translate("MainWindow", "ESRI Shapefile文件(*.shp)"))self.comboBox.setItemText(3, _translate("MainWindow", "kml文件(*.kml)"))self.comboBox_2.setItemText(0, _translate("MainWindow", "所有文件(*.*)"))self.comboBox_2.setItemText(1, _translate("MainWindow", "CAD文件(*.dwg)"))self.comboBox_2.setItemText(2, _translate("MainWindow", "ESRI Shapefile文件(*.shp)"))self.comboBox_2.setItemText(3, _translate("MainWindow", "kml文件(*.kml)"))self.label_3.setText(_translate("MainWindow", "源文件坐標(biāo)系"))self.comboBox_3.setItemText(0, _translate("MainWindow", "EPSG:4490 China Geodetic Coordinate System 2000"))self.comboBox_3.setItemText(1, _translate("MainWindow", "EPSG:4527 CGCS2000 / 3-degree Gauss-Kruger zone 39"))self.comboBox_3.setItemText(2, _translate("MainWindow", "EPSG:4548 CGCS2000 / 3-degree Gauss-Kruger CM 117E"))self.label_4.setText(_translate("MainWindow", "<html><head/><body><p>目標(biāo)文件坐標(biāo)系</p></body></html>"))self.comboBox_4.setItemText(0, _translate("MainWindow", "EPSG:4490 China Geodetic Coordinate System 2000"))self.comboBox_4.setItemText(1, _translate("MainWindow", "EPSG:4527 CGCS2000 / 3-degree Gauss-Kruger zone 39"))self.comboBox_4.setItemText(2, _translate("MainWindow", "EPSG:4548 CGCS2000 / 3-degree Gauss-Kruger CM 117E"))self.pushButton_3.setText(_translate("MainWindow", "輸出"))self.pushButton_4.setText(_translate("MainWindow", "打開"))self.pushButton_5.setText(_translate("MainWindow", "退出"))

窗體調(diào)用

python是腳本語言,從頭開始一行一行的執(zhí)行,不像別的語言都有一個入口,那么怎么調(diào)用這個form呢?

class MyWin(QMainWindow, Ui_MainWindow):def __init__(self, parent=None):super(MyWin, self).__init__(parent)self.setupUi(self)self.IniUI()def IniUI(self): if __name__ == '__main__':app = QApplication(sys.argv)mw = MyWin()mw.show()sys.exit(app.exec_())

這段是網(wǎng)上抄的:if __name__ == '__main__':相當(dāng)于確定了程序執(zhí)行的入口,__name__

在當(dāng)前文件它的值就等于__main__,作為模塊導(dǎo)入到別的文件,它的值就等于模塊名,也意味著當(dāng)前文件是主文件了。def __init__(self, parent=None): 是構(gòu)造函數(shù),self.setupUi(self)應(yīng)該是窗體文件里對應(yīng)的初始化模塊,self.IniUI()就是我自己要做的處理了。

信號與槽

控件和代碼如何連接呢?比如我如何確定點擊一下按鈕,能響應(yīng)打開選擇文件的操作:牽扯到的概念叫:信號與槽

按鈕點擊相當(dāng)于發(fā)射信號,打開文件相當(dāng)于槽,然后使用connect連接起來,就能執(zhí)行了,當(dāng)然每個控件都可能不止發(fā)射一種信號,clicked只是pushbutton的一種信號,槽也可以對應(yīng)好幾個信號,信號可以連接好幾個槽??梢宰远x槽,當(dāng)然也有默認(rèn)的槽。

調(diào)用ogr2ogr

需要調(diào)用subprocess.Popen模塊,所以要導(dǎo)入subprocess,當(dāng)成命令行的方式調(diào)用。

from fileinput import filename from pickle import GLOBAL from re import I from matplotlib import type1fontfrom pytest import cmdline from Ui_ogr import Ui_MainWindow from PyQt5.QtWidgets import QMainWindow, QApplication,QFileDialog,QMessageBox import sys from PyQt5.QtCore import QCoreApplication import subprocess infile=""#輸入文件路徑 outfile=""#輸出文件路徑 infileType=""#輸入文件類型 outfileType=""#輸出文件類型 inEPSG=""#輸入EPSG outEPSG=""#輸出EPSG class MyWin(QMainWindow, Ui_MainWindow):def __init__(self, parent=None):super(MyWin, self).__init__(parent)self.setupUi(self)self.IniUI()def IniUI(self):# 添加“打開文件”按鈕的信號和槽。注意getFile函數(shù)不加小括號()self.pushButton.clicked.connect(self.GetinType)self.pushButton.clicked.connect(self.getFile)self.pushButton_2.clicked.connect(self.GetoutType)self.pushButton_2.clicked.connect(self.saveNewFile)# self.comboBox.activated.connect(self.GetinType)# self.comboBox_2.activated.connect(self.GetoutType)# self.comboBox_3.activated.connect(self.GetinEPSG)# self.comboBox_4.activated.connect(self.GetoutEPSG)self.pushButton_3.clicked.connect(self.GetinEPSG)self.pushButton_3.clicked.connect(self.GetoutEPSG)self.pushButton_3.clicked.connect(self.TransBegin)self.pushButton_5.clicked.connect(QCoreApplication.instance().quit)def getFile(self):global infileinfile,ft = QFileDialog.getOpenFileName(self,"選擇待轉(zhuǎn)換的原始文件", "", infileType) # 獲取文件self.textEdit.setText(infile)def saveNewFile(self):global outfileoutfile,tn = QFileDialog.getSaveFileName(self,"選擇存儲的目標(biāo)文件", "", outfileType) # 獲取文件self.textEdit_2.setText(outfile)def GetinType(self):global infileTypeinfileType=self.comboBox.currentText()def GetoutType(self):global outfileTypeoutfileType=self.comboBox_2.currentText()def GetinEPSG(self):global inEPSGinEPSG=self.comboBox_3.currentText()# self.textEdit.setText(inEPSG)def GetoutEPSG(self):global outEPSGoutEPSG=self.comboBox_4.currentText()def TransBegin(self):if infile=="":QMessageBox.information(self, "提醒", "沒有選擇要轉(zhuǎn)換的文件")if outfile=="":QMessageBox.information(self, "提醒", "沒有選擇存儲文件的路徑") s=outfileType.find('文件')type=outfileType[0:s]# print(type)scoor=inEPSG[0:9]tcoor=outEPSG[0:9]cmdLine = "ogr2ogr "+"-s_srs "+ scoor +" -t_srs "+ tcoor +" -f \"" + type + "\" \"" + outfile.replace('/', '\\') + "\"" + " \"" + infile.replace('/', '\\') + "\""# print(cmdLine)# print("\r")# 避免出現(xiàn) ERROR 1: PROJ: proj_create_from_database: Cannot find proj.db# os.environ['PROJ_LIB'] = r'D:\\Python39\\Lib\\site-packages\\osgeo\\data\\proj/'subprocess.Popen(cmdLine, shell=True)QMessageBox.information(self, "結(jié)果", "轉(zhuǎn)換完成!")if __name__ == '__main__':app = QApplication(sys.argv)mw = MyWin()mw.show()sys.exit(app.exec_())

簡單測試了下,shapefile轉(zhuǎn)kml可以,但是CAD文件提示驅(qū)動器問題,這個后面還有繼續(xù)思考。

如何打包:

安裝pyinstaller

使用命令 pyintstaller --onefile --windowed -*py

--onefile是打包成一個exe,否則的話會將需要依賴的庫獨立出來打包成一個文件夾,這個要看需要了。

--windowed是打包成窗體程序,不要閃小黑框了。

基本過程就是這樣了。

問題:

測試的數(shù)據(jù)種類有限,有的數(shù)據(jù)提示轉(zhuǎn)換成功但是沒有數(shù)據(jù),有的轉(zhuǎn)換不成功但是沒有明顯的提示告知錯誤原因,都是后面還要繼續(xù)摸索的地方。

總結(jié)

以上是生活随笔為你收集整理的python结合ogr2ogr之地理数据格式转换-1的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。