測量:「python」のフィールドで

画像



楽しい時間を!

ちょっとした歴史:プログラミングの勉強中に、私は自分にとって本当の問題を探していました。 見つけた。 私は仕事でおなじみの測量士として、土地の体積を考慮しました。 非常に長く退屈です...



ボリュームの測地計算:

住宅、ハイテク施設、道路、鉄道の建設、および建築材料の量を決定し、土工の量を計算するには、測量士の助けが必要です。 領域全体をいわゆる「 ジオグリッド 」に分割して領域を「撮影」し、デバイスから受信したポイントをautoCADでアンロードし、領域全体の体積を計算します。 以下はジオグリッドの例です。



画像



各ポイントには、バルト海を基準にした独自の座標(x、y、zの高さ)があります。 順番に、前の画像に示されているように4つのポイントが取得され、これらのポイントの座標に基づいて土地の体積が計算されるため、グリッドで取得された図形のすべての体積が計算され、その結果、領域全体の体積が得られます。



この作業は非常に骨の折れる作業であり、すでに書いたので、経験と引き換えに実際のプロジェクトを引き受けたかったのです。 したがって、私はすべてが長い間私の前にあったという選択肢すら考えていませんでした。



数日間、私は隣人を見つけるためのアルゴリズムに混乱しましたが、結果は期待したほどではありませんでした。グリッドは理論のように滑らかではないという事実と、測量士がフィールドを歩き回ってマークを付ける曲線のために、アルゴリズムは思いどおりに機能しましたAutoCADは、ポイントが作成された時点で非常に簡単に並べ替えられることに気付きました。 さらに、AutoCADに少し関与して、ポイントをXMLファイルにエクスポートする興味深い順序に気付き、各ポイントにIDを割り当てる可能性を見つけました。今、各ポイントに左隅から右端まで名前を割り当て、上記のすべてのポイントを理解しました(これは500x700メートルの領域を持つ領土のボリュームを考慮するために2日よりも高速です)。 以下に、名前の付いたポイントが順番に並んだ完成したファイルの例を示します。



画像



理論上、ボリュームはピタゴラスに従って考慮されますが、数字は完全に異なり、実践が示すように、正方形と長方形は非常にまれです。 したがって、計算ではHeronの式に頼りました。 つまり、私が書いたソフトウェアの原理は次のとおりです。XMLファイルを読み取り、ポイントを収集し、4つの正方形の配列を持つ配列、ボリュームを計算するために必要なすべての形状を取得し、ボリュームを計算する前に、数字の側面(ベクトル)と長方形と正方形の角を確認します(特に私たちの測量士の場合、そのようなものがあり、それを使用する場合はピタゴラスを使用します)、台形、平行六面体などの数字を未知の4つの正方形として取り、ヘロンの式に従ってそれらを数えます そのボリュームを取得し、図の総面積に基づいて、私の下の2つの三角形の4点(私の同僚の検査員が私に説明したように)とplyusuyaエリアの最高の方、高さ、(高さを考慮して)、空間におけるそれらの領域を考えるolnika。



さらに、これらすべてのボリュームと0.2秒間で数日間の結果を取得し、データが収束するまで3つのプロジェクトをチェックしました。プログラムはさらに正確にボリュームを取得します。 私たちはそれをテストし続けます。 さて、先日、このコードをユーザーフレンドリーなインターフェイスにねじ込むことにしました。PyQt4は、グラフィックスを初めて作成した経験です。以下では、GUIにのみ適用されるコードを公開します。



from PyQt4 import QtGui import sys import cvgLeicaXmlReader import cvgMath class myWindow(QtGui.QMainWindow): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.setWindowTitle('CVG2014') self.setFixedSize(350, 350) self.setWindowIcon(QtGui.QIcon('static/Icon.png')) self.setStyleSheet("QMainWindow {background-image: url(static/background.png);}") self.directory = '' self.file = '' self.labelFilename = QtGui.QLabel('Select .XML file with points', self) self.labelFilename.setFixedWidth(300) self.labelFilename.setFixedHeight(25) self.labelFilename.move(10, 5) self.labelFilename.setStyleSheet("QLabel { background-color: white; \ border: 1px solid grey; \ color: grey;}") self.SB_WidthOfXAxis = QtGui.QSpinBox(self) self.SB_WidthOfXAxis.move(10, 35) self.SB_WidthOfXAxis.setFixedWidth(50) self.SB_WidthOfXAxis.setMaximum(9999) self.labelPointsWidth = QtGui.QLabel('Length of points on X axis', self) self.labelPointsWidth.setFixedWidth(250) self.labelPointsWidth.setFixedHeight(25) self.labelPointsWidth.move(65, 47.5) self.SB_HeightAboveSeaLevel = QtGui.QDoubleSpinBox(self) self.SB_HeightAboveSeaLevel.move(10, 75) self.SB_HeightAboveSeaLevel.setFixedWidth(50) self.SB_HeightAboveSeaLevel.setRange(-9999.99, 9999.99) self.labelPointsSeaLevel = QtGui.QLabel('Height above sea level', self) self.labelPointsSeaLevel.setFixedWidth(250) self.labelPointsSeaLevel.setFixedHeight(25) self.labelPointsSeaLevel.move(65, 87) self.buttonOpenFile = QtGui.QPushButton('...', self) self.buttonOpenFile.setFixedWidth(30) self.buttonOpenFile.setFixedHeight(27) self.buttonOpenFile.move(311, 4) self.buttonOpenFile.clicked.connect(self.getXmlFile) self.buttonGetVolume = QtGui.QPushButton('RUN', self) self.buttonGetVolume.setFixedWidth(52) self.buttonGetVolume.setFixedHeight(35) self.buttonGetVolume.move(9, 115) self.buttonGetVolume.clicked.connect(self.getVolume) self.showVolume = QtGui.QLabel('Get Vol', self) self.showVolume.setFixedWidth(140) self.showVolume.setFixedHeight(32) self.showVolume.move(72, 117) self.showVolume.setStyleSheet("QLabel { background-color: white; \ border: 1px solid grey; \ color: grey;}") def getVolume(self): xml_file = self.getFileName() points = cvgLeicaXmlReader.getPointsFromXmlFile(xml_file) if(xml_file and points): # length_of_points = len(points) QUANTITY_POINTS_AT_X_AXIS = self.SB_WidthOfXAxis.value() STATIC_HEIGHT = self.SB_HeightAboveSeaLevel.value() rows = cvgLeicaXmlReader.getRowsFromPoints(points, QUANTITY_POINTS_AT_X_AXIS) quads = cvgLeicaXmlReader.getAllQuads(rows) volumes = [] if (STATIC_HEIGHT or QUANTITY_POINTS_AT_X_AXIS) != 0: for quadrangle in quads: Quadrangle_type = cvgMath.getTypeQuadrangle(quadrangle) v = cvgMath.getVolumeQuadrangle(quadrangle, Quadrangle_type, STATIC_HEIGHT) volumes.append(v) else: volumes = 0 volumes = 0 if STATIC_HEIGHT == 0 else (round(sum(volumes), 3)) result = '-'+str(volumes) if STATIC_HEIGHT < 0 else str(volumes) result = '0' if result == '-0' else result self.showVolume.setStyleSheet("QLabel { background-color: white; \ border: 1px solid grey; \ color: grey;}") self.showVolume.setText(result) else: self.showVolume.setText('Select the correct file!') self.showVolume.setStyleSheet("QLabel { background-color: white; \ border: 1px solid grey; \ color: red; \ font-weight: bold}") def getFileName(self): return self.file def getXmlFile(self): sender = self.sender() path = QtGui.QFileDialog.getOpenFileName(sender, 'Open Xml file with points', self.directory, 'XML *.xml') fileName = path[path.rfind('/')+1:] self.directory = path[:path.rfind('/')] if(len(path) > 54): start = len(path)-54 pathSlice = path[start:] pathSlice = pathSlice[pathSlice.find('/'):] pathSlice = '..'+pathSlice else: pathSlice = path self.labelFilename.setText(pathSlice) print(len(path)) self.file = path if __name__ == '__main__': app = QtGui.QApplication(sys.argv) win = myWindow() win.show() app.exec_()
      
      







他のモジュールに興味がある人は、 githubで見つけることができます

また、Windows用のexeでコンパイルされたコードで.rarアーカイブをダウンロードしました。



画像



私たちに必要なもの:ポイントを持つXMLファイルを開き(たとえば、2つのファイルがギグにあります(テスト用に2つの正しいファイルと1つの打たれた))、フィールド幅に沿ったポイントの数を示し、下は海面に対する相対的な高さを示し、待機しますRUNボタン、開始ボタンの右側のフィールドにボリュームを取得します。



正直に言うと、このツールを実稼働で使用できるかどうかはわかりません。 しかし、私は自分の欲望を満たしました。 ご清聴ありがとうございました。



65ドット(幅13ドット)のファイル

78ドットファイル(13ドット幅)

XMLファイルリーダー

数学計算モジュール

ビジュアルデザインモジュール

エグゼでコンパイルされたコードでアーカイブ



All Articles