-
Notifications
You must be signed in to change notification settings - Fork 3
/
LiDARForestryHeight_dialog.py
235 lines (194 loc) · 9.46 KB
/
LiDARForestryHeight_dialog.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# -*- coding: utf-8 -*-
"""
/***************************************************************************
LiDARForestryHeight
A QGIS plugin. LiDAR Forestry Height
generates a DEM with the forest height,
calculated from a classified LiDAR point
cloud using LasPy Library
Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
-------------------
begin : 2018-09-24
copyright : (C) 2019 by PANOimagen S.L.
email : [email protected]
git sha : $Format:%H$
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
"""
from __future__ import unicode_literals
import os
from qgis.PyQt import uic
from qgis.PyQt import QtWidgets
import logging
logger = logging.getLogger("lfh")
logger.setLevel(logging.DEBUG)
from qgis.core import Qgis, QgsRasterLayer, QgsProject
from qgis.gui import QgisInterface, QgsMessageBar
from .lfh_errors import LasPyNotFoundError
try:
from . import plugin_process
LASPY_INSTALLED = True
except LasPyNotFoundError as e:
LASPY_INSTALLED = False
from. import files_paths_funs as dir_fns
FORM_CLASS, _ = uic.loadUiType(os.path.join(
os.path.dirname(__file__), 'LiDARForestryHeight_dialog_base.ui'))
class LiDARForestryHeightDialog(QtWidgets.QDialog, FORM_CLASS):
def __init__(self, parent=None):
"""Constructor."""
super(LiDARForestryHeightDialog, self).__init__(parent)
# Set up the user interface from Designer.
# After setupUI you can access any designer object by doing
# self.<objectname>, and you can use autoconnect slots - see
# http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
# #widgets-and-dialogs-with-auto-connect
self.setupUi(self)
self._initUi()
self.iface = QgisInterface
self.buttonBox.accepted.connect(self.accept)
self.buttonBox.accepted.connect(self.preparingProcess)
self.buttonBox.rejected.connect(self.reject)
self.addResultsCheckBox.setChecked(True)
self.createAndLoadIntermCheckBox.setChecked(False)
self.outputFolderToolButton.clicked.connect(self.setOutPath)
self.inputToolButton.clicked.connect(self.inputLiDAR)
def _initUi(self):
from . import version_number
version = version_number.get_version_from_metadata()
self.versionLabel.setText(u'Version: {}'.format(version))
if LASPY_INSTALLED:
text = u'LasPy Library avaible'
color = u'color: black'
else:
text = (u'LasPy Library is not installed. Visit' +
u' plugin homepage or LasPy documentation')
color = u'color: red'
self.lasPyInstalledLabel.setText(text)
self.lasPyInstalledLabel.setStyleSheet(color)
interpolate_methods = ['nearest', 'linear', 'cubic']
self.interpolatingMethodComboBox.addItems(interpolate_methods)
self.updateUi()
def updateUi(self):
""" Enable/disable UI options if LasPy Library is/isn't installed
"""
self.pluginGroupBox.setEnabled(LASPY_INSTALLED)
self.inputGroupBox.setEnabled(LASPY_INSTALLED)
self.resultsParamsGroupBox.setEnabled(LASPY_INSTALLED)
def inputLiDAR(self):
fileNames = QtWidgets.QFileDialog.getOpenFileNames(self,
u"Select the input LiDAR classified file/s",
self.inputLineEdit.text(),
("LiDAR files (*.laz *.LAZ* *.las *.LAS);;" +
" All files (*)"))
if fileNames:
# quoted = ['"{}"'.format(fn) for fn in fileNames]
self.inputLineEdit.setText(", ".join(fileNames[0]))
if not self.outputFolderLineEdit.text():
try:
outPath = os.path.join(
os.path.split(os.path.abspath(fileNames[0][0]))[0],
u'lidar_forestry_height_output')
self.outputFolderLineEdit.setText(outPath)
except IndexError:
pass
def setOutPath(self):
"""Function to select the output folder and update the LineEdit
"""
outPath = QtWidgets.QFileDialog.getExistingDirectory(self,
u"Select the output folder",
self.outputFolderToolButton.text())
if outPath:
self.outputFolderLineEdit.setText(os.path.join(
outPath, u'lidar_forestry_height_output'))
def preparingProcess(self):
if not LASPY_INSTALLED:
self.showQMessage(u"Error: LasPy Library is not installed!" +
u"\nPlease, solve it. More information" +
u" at plugin homepage.")
return
filenames = self.inputLineEdit.text()
if not filenames:
self.showQMessage(u"Error: Not input file selected!\nPlease," +
u" select one.")
outPath = self.outputFolderLineEdit.text()
if not outPath:
self.showQMessage(u"Error: Not output folder selected!\n" +
u"Please, select one.")
if filenames and outPath:
for f in filenames.split(","):
full_filename = f.strip()
_, filename = os.path.split(full_filename)
if outPath:
self.settingProcessParams(full_filename, outPath)
def settingProcessParams(self, full_filename, outPath):
self.pixel_size = self.pixelSizeDoubleSpinBox.value()
self.inter_method = self.interpolatingMethodComboBox.currentText()
self.load_result = self.addResultsCheckBox.isChecked()
self.partials_create_load = self.createAndLoadIntermCheckBox.isChecked()
_, filename = os.path.split(full_filename)
base_name, ext = os.path.splitext(filename)
start_index = 1
out_path = os.path.join(
outPath, (base_name + '_r' + str(start_index)))
if os.path.exists(out_path):
import glob
key_for_glob = os.path.join(outPath, (base_name + '_r*' ))
dirs_list = glob.glob(key_for_glob)
indexes = []
for directory in dirs_list:
try:
fn_index = int(directory[-3:])
except ValueError:
try:
fn_index = int(directory[-2:])
except ValueError:
fn_index = int(directory[-1])
indexes.append(fn_index)
max_index = max(indexes)
next_index = max_index + 1
out_path = os.path.join(outPath,
(base_name + '_r' + str(next_index)))
self.dir_fns = dir_fns.DirAndPaths(filename, out_path)
self.showMessage(u'Starting processing LiDAR data {}'.format(base_name),
Qgis.MessageLevel(0))
try:
self.process = plugin_process.Process(full_filename,
out_path,
self.pixel_size,
self.inter_method,
self.partials_create_load)
except (ValueError, OSError) as message:
self.showQMessage(str(message))
self.showMessage('LiDAR Forestry Height stopped process',
Qgis.MessageLevel(1))
return
if self.partials_create_load:
self.load_raster_layer(self.process.dirs.out_paths['dtm'])
self.load_raster_layer(self.process.dirs.out_paths['dsm'])
if self.load_result:
self.load_raster_layer(self.process.dirs.out_paths['height'])
def load_raster_layer(self, raster_full_path):
"""Add the result to canvas.
"""
raster_filename, _ = os.path.splitext(os.path.split(raster_full_path)[-1])
rlayer = QgsRasterLayer(raster_full_path,
raster_filename)
QgsProject.instance().addMapLayer(rlayer)
def showMessage(self, message, msg_level):
"""This function shows a QGIS message bar when is called with the
message and the message Level -i.e.:INFO-
"""
QgsMessageBar().pushMessage(
message, level=msg_level)
def showQMessage(self, message, msg_level = "Error message"):
"""This function shows a Qt message dialog when is called with the
message and the message Level-
"""
QtWidgets.QMessageBox.warning(self, msg_level, message)