BERATools 0.2.0__py3-none-any.whl → 0.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- beratools/__init__.py +1 -7
- beratools/core/algo_centerline.py +491 -351
- beratools/core/algo_common.py +497 -0
- beratools/core/algo_cost.py +192 -0
- beratools/core/{dijkstra_algorithm.py → algo_dijkstra.py} +503 -460
- beratools/core/algo_footprint_rel.py +577 -0
- beratools/core/algo_line_grouping.py +944 -0
- beratools/core/algo_merge_lines.py +214 -0
- beratools/core/algo_split_with_lines.py +304 -0
- beratools/core/algo_tiler.py +428 -0
- beratools/core/algo_vertex_optimization.py +469 -0
- beratools/core/constants.py +52 -86
- beratools/core/logger.py +76 -85
- beratools/core/tool_base.py +196 -133
- beratools/gui/__init__.py +11 -15
- beratools/gui/{beratools.json → assets/beratools.json} +2185 -2300
- beratools/gui/batch_processing_dlg.py +513 -463
- beratools/gui/bt_data.py +481 -487
- beratools/gui/bt_gui_main.py +710 -691
- beratools/gui/main.py +26 -0
- beratools/gui/map_window.py +162 -146
- beratools/gui/tool_widgets.py +725 -493
- beratools/tools/Beratools_r_script.r +1120 -1120
- beratools/tools/Ht_metrics.py +116 -116
- beratools/tools/__init__.py +7 -7
- beratools/tools/batch_processing.py +136 -132
- beratools/tools/canopy_threshold_relative.py +672 -670
- beratools/tools/canopycostraster.py +222 -222
- beratools/tools/centerline.py +136 -176
- beratools/tools/common.py +857 -885
- beratools/tools/fl_regen_csf.py +428 -428
- beratools/tools/forest_line_attributes.py +408 -408
- beratools/tools/line_footprint_absolute.py +213 -363
- beratools/tools/line_footprint_fixed.py +436 -282
- beratools/tools/line_footprint_functions.py +733 -720
- beratools/tools/line_footprint_relative.py +73 -64
- beratools/tools/line_grouping.py +45 -0
- beratools/tools/ln_relative_metrics.py +615 -615
- beratools/tools/r_cal_lpi_elai.r +24 -24
- beratools/tools/r_generate_pd_focalraster.r +100 -100
- beratools/tools/r_interface.py +79 -79
- beratools/tools/r_point_density.r +8 -8
- beratools/tools/rpy_chm2trees.py +86 -86
- beratools/tools/rpy_dsm_chm_by.py +81 -81
- beratools/tools/rpy_dtm_by.py +63 -63
- beratools/tools/rpy_find_cellsize.py +43 -43
- beratools/tools/rpy_gnd_csf.py +74 -74
- beratools/tools/rpy_hummock_hollow.py +85 -85
- beratools/tools/rpy_hummock_hollow_raster.py +71 -71
- beratools/tools/rpy_las_info.py +51 -51
- beratools/tools/rpy_laz2las.py +40 -40
- beratools/tools/rpy_lpi_elai_lascat.py +466 -466
- beratools/tools/rpy_normalized_lidar_by.py +56 -56
- beratools/tools/rpy_percent_above_dbh.py +80 -80
- beratools/tools/rpy_points2trees.py +88 -88
- beratools/tools/rpy_vegcoverage.py +94 -94
- beratools/tools/tiler.py +48 -206
- beratools/tools/tool_template.py +69 -54
- beratools/tools/vertex_optimization.py +61 -620
- beratools/tools/zonal_threshold.py +144 -144
- beratools-0.2.1.dist-info/METADATA +109 -0
- beratools-0.2.1.dist-info/RECORD +74 -0
- {beratools-0.2.0.dist-info → beratools-0.2.1.dist-info}/WHEEL +1 -1
- {beratools-0.2.0.dist-info → beratools-0.2.1.dist-info}/licenses/LICENSE +22 -22
- beratools/gui/cli.py +0 -18
- beratools/gui/gui.json +0 -8
- beratools/gui_tk/ASCII Banners.txt +0 -248
- beratools/gui_tk/__init__.py +0 -20
- beratools/gui_tk/beratools_main.py +0 -515
- beratools/gui_tk/bt_widgets.py +0 -442
- beratools/gui_tk/cli.py +0 -18
- beratools/gui_tk/img/BERALogo.png +0 -0
- beratools/gui_tk/img/closed.gif +0 -0
- beratools/gui_tk/img/closed.png +0 -0
- beratools/gui_tk/img/open.gif +0 -0
- beratools/gui_tk/img/open.png +0 -0
- beratools/gui_tk/img/tool.gif +0 -0
- beratools/gui_tk/img/tool.png +0 -0
- beratools/gui_tk/main.py +0 -14
- beratools/gui_tk/map_window.py +0 -144
- beratools/gui_tk/runner.py +0 -1481
- beratools/gui_tk/tooltip.py +0 -55
- beratools/third_party/pyqtlet2/__init__.py +0 -9
- beratools/third_party/pyqtlet2/leaflet/__init__.py +0 -26
- beratools/third_party/pyqtlet2/leaflet/control/__init__.py +0 -6
- beratools/third_party/pyqtlet2/leaflet/control/control.py +0 -59
- beratools/third_party/pyqtlet2/leaflet/control/draw.py +0 -52
- beratools/third_party/pyqtlet2/leaflet/control/layers.py +0 -20
- beratools/third_party/pyqtlet2/leaflet/core/Parser.py +0 -24
- beratools/third_party/pyqtlet2/leaflet/core/__init__.py +0 -2
- beratools/third_party/pyqtlet2/leaflet/core/evented.py +0 -180
- beratools/third_party/pyqtlet2/leaflet/layer/__init__.py +0 -5
- beratools/third_party/pyqtlet2/leaflet/layer/featuregroup.py +0 -34
- beratools/third_party/pyqtlet2/leaflet/layer/icon/__init__.py +0 -1
- beratools/third_party/pyqtlet2/leaflet/layer/icon/icon.py +0 -30
- beratools/third_party/pyqtlet2/leaflet/layer/imageoverlay.py +0 -18
- beratools/third_party/pyqtlet2/leaflet/layer/layer.py +0 -105
- beratools/third_party/pyqtlet2/leaflet/layer/layergroup.py +0 -45
- beratools/third_party/pyqtlet2/leaflet/layer/marker/__init__.py +0 -1
- beratools/third_party/pyqtlet2/leaflet/layer/marker/marker.py +0 -91
- beratools/third_party/pyqtlet2/leaflet/layer/tile/__init__.py +0 -2
- beratools/third_party/pyqtlet2/leaflet/layer/tile/gridlayer.py +0 -4
- beratools/third_party/pyqtlet2/leaflet/layer/tile/tilelayer.py +0 -16
- beratools/third_party/pyqtlet2/leaflet/layer/vector/__init__.py +0 -5
- beratools/third_party/pyqtlet2/leaflet/layer/vector/circle.py +0 -15
- beratools/third_party/pyqtlet2/leaflet/layer/vector/circlemarker.py +0 -18
- beratools/third_party/pyqtlet2/leaflet/layer/vector/path.py +0 -5
- beratools/third_party/pyqtlet2/leaflet/layer/vector/polygon.py +0 -14
- beratools/third_party/pyqtlet2/leaflet/layer/vector/polyline.py +0 -18
- beratools/third_party/pyqtlet2/leaflet/layer/vector/rectangle.py +0 -14
- beratools/third_party/pyqtlet2/leaflet/map/__init__.py +0 -1
- beratools/third_party/pyqtlet2/leaflet/map/map.py +0 -220
- beratools/third_party/pyqtlet2/mapwidget.py +0 -45
- beratools/third_party/pyqtlet2/web/custom.js +0 -43
- beratools/third_party/pyqtlet2/web/map.html +0 -23
- beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/layers-2x.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/layers.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/marker-icon-2x.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/marker-icon.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_193/images/marker-shadow.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_193/leaflet.css +0 -656
- beratools/third_party/pyqtlet2/web/modules/leaflet_193/leaflet.js +0 -6
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/.codeclimate.yml +0 -14
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/.editorconfig +0 -4
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/.gitattributes +0 -22
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/.travis.yml +0 -43
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/LICENSE +0 -20
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/layers-2x.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/layers.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/marker-icon-2x.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/marker-icon.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/marker-shadow.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/spritesheet-2x.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/spritesheet.png +0 -0
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/images/spritesheet.svg +0 -156
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/leaflet.draw.css +0 -10
- beratools/third_party/pyqtlet2/web/modules/leaflet_draw_414/leaflet.draw.js +0 -10
- beratools/third_party/pyqtlet2/web/modules/leaflet_rotatedMarker_020/LICENSE +0 -22
- beratools/third_party/pyqtlet2/web/modules/leaflet_rotatedMarker_020/leaflet.rotatedMarker.js +0 -57
- beratools/tools/forest_line_ecosite.py +0 -216
- beratools/tools/lapis_all.py +0 -103
- beratools/tools/least_cost_path_from_chm.py +0 -152
- beratools-0.2.0.dist-info/METADATA +0 -63
- beratools-0.2.0.dist-info/RECORD +0 -142
- /beratools/gui/{img → assets}/BERALogo.png +0 -0
- /beratools/gui/{img → assets}/closed.gif +0 -0
- /beratools/gui/{img → assets}/closed.png +0 -0
- /beratools/{gui_tk → gui/assets}/gui.json +0 -0
- /beratools/gui/{img → assets}/open.gif +0 -0
- /beratools/gui/{img → assets}/open.png +0 -0
- /beratools/gui/{img → assets}/tool.gif +0 -0
- /beratools/gui/{img → assets}/tool.png +0 -0
- {beratools-0.2.0.dist-info → beratools-0.2.1.dist-info}/entry_points.txt +0 -0
beratools/gui_tk/bt_widgets.py
DELETED
|
@@ -1,442 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import sys
|
|
3
|
-
from PyQt5.QtWidgets import (QApplication, QLineEdit, QFileDialog, QComboBox, QWidget,
|
|
4
|
-
QPushButton, QLabel, QSlider, QMessageBox,
|
|
5
|
-
QStyleOptionSlider, QStyle, QToolTip, QAbstractSlider,
|
|
6
|
-
QHBoxLayout, QVBoxLayout, QSpinBox, QDoubleSpinBox)
|
|
7
|
-
|
|
8
|
-
from PyQt5.QtCore import pyqtSignal, Qt, QPoint
|
|
9
|
-
from pathlib import Path
|
|
10
|
-
import json
|
|
11
|
-
import re
|
|
12
|
-
|
|
13
|
-
import inspect
|
|
14
|
-
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
|
15
|
-
parentdir = os.path.dirname(currentdir)
|
|
16
|
-
sys.path.insert(0, parentdir)
|
|
17
|
-
|
|
18
|
-
from beratools_main import BeraTools
|
|
19
|
-
from common import *
|
|
20
|
-
|
|
21
|
-
bt = BeraTools()
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
class ToolWidgets(QWidget):
|
|
25
|
-
signal_save_tool_params = pyqtSignal(object)
|
|
26
|
-
|
|
27
|
-
def __init__(self, tool_name, parent=None):
|
|
28
|
-
super(ToolWidgets, self).__init__(parent)
|
|
29
|
-
|
|
30
|
-
self.tool_name = tool_name
|
|
31
|
-
self.current_tool_api = ''
|
|
32
|
-
self.widget_list = []
|
|
33
|
-
self.setWindowTitle("Tool widgets")
|
|
34
|
-
|
|
35
|
-
self.create_widgets()
|
|
36
|
-
layout = QVBoxLayout()
|
|
37
|
-
|
|
38
|
-
for item in self.widget_list:
|
|
39
|
-
layout.addWidget(item)
|
|
40
|
-
|
|
41
|
-
self.save_button = QPushButton('Save Parameters')
|
|
42
|
-
self.save_button.clicked.connect(self.save_tool_parameters)
|
|
43
|
-
self.save_button.setFixedSize(200, 50)
|
|
44
|
-
layout.addSpacing(20)
|
|
45
|
-
layout.addWidget(self.save_button, alignment=Qt.AlignCenter)
|
|
46
|
-
layout.addStretch()
|
|
47
|
-
self.setLayout(layout)
|
|
48
|
-
|
|
49
|
-
def get_current_tool_parameters(self):
|
|
50
|
-
tool_params = bt.get_bera_tool_parameters(self.tool_name)
|
|
51
|
-
self.current_tool_api = tool_params['tool_api']
|
|
52
|
-
return tool_params
|
|
53
|
-
|
|
54
|
-
def create_widgets(self):
|
|
55
|
-
k = bt.get_bera_tool_info(self.tool_name)
|
|
56
|
-
print(k)
|
|
57
|
-
print('\n')
|
|
58
|
-
|
|
59
|
-
j = self.get_current_tool_parameters()
|
|
60
|
-
|
|
61
|
-
param_num = 0
|
|
62
|
-
for p in j['parameters']:
|
|
63
|
-
json_str = json.dumps(p, sort_keys=True, indent=2, separators=(',', ': '))
|
|
64
|
-
pt = p['parameter_type']
|
|
65
|
-
widget = None
|
|
66
|
-
|
|
67
|
-
if 'ExistingFileOrFloat' in pt:
|
|
68
|
-
widget = FileOrFloat(json_str, None)
|
|
69
|
-
param_num = param_num + 1
|
|
70
|
-
elif 'ExistingFile' in pt or 'NewFile' in pt or 'Directory' in pt:
|
|
71
|
-
widget = FileSelector(json_str, None)
|
|
72
|
-
param_num = param_num + 1
|
|
73
|
-
elif 'FileList' in pt:
|
|
74
|
-
widget = MultifileSelector(json_str, None)
|
|
75
|
-
param_num = param_num + 1
|
|
76
|
-
elif 'Boolean' in pt:
|
|
77
|
-
widget = BooleanInput(json_str)
|
|
78
|
-
param_num = param_num + 1
|
|
79
|
-
elif 'OptionList' in pt:
|
|
80
|
-
widget = OptionsInput(json_str)
|
|
81
|
-
param_num = param_num + 1
|
|
82
|
-
elif ('Float' in pt or 'Integer' in pt or
|
|
83
|
-
'Text' in pt or 'String' in pt or 'StringOrNumber' in pt or
|
|
84
|
-
'StringList' in pt or 'VectorAttributeField' in pt):
|
|
85
|
-
widget = DataInput(json_str)
|
|
86
|
-
param_num = param_num + 1
|
|
87
|
-
else:
|
|
88
|
-
msg_box = QMessageBox()
|
|
89
|
-
msg_box.setIcon(QMessageBox.Warning)
|
|
90
|
-
msg_box.setText("Unsupported parameter type: {}.".format(pt))
|
|
91
|
-
msg_box.exec()
|
|
92
|
-
|
|
93
|
-
param_value = None
|
|
94
|
-
if 'saved_value' in p.keys():
|
|
95
|
-
param_value = p['saved_value']
|
|
96
|
-
if param_value is None:
|
|
97
|
-
param_value = p['default_value']
|
|
98
|
-
if param_value is not None:
|
|
99
|
-
if type(widget) is OptionsInput:
|
|
100
|
-
widget.value = param_value
|
|
101
|
-
elif widget:
|
|
102
|
-
widget.value = param_value
|
|
103
|
-
else:
|
|
104
|
-
print('No default value found: {}'.format(p['name']))
|
|
105
|
-
|
|
106
|
-
# hide optional widgets
|
|
107
|
-
if widget:
|
|
108
|
-
if widget.optional and widget.label:
|
|
109
|
-
widget.label.setStyleSheet("QLabel { background-color : transparent; color : blue; }")
|
|
110
|
-
|
|
111
|
-
# if widget.optional and not bt.show_advanced:
|
|
112
|
-
# widget.hide()
|
|
113
|
-
|
|
114
|
-
self.widget_list.append(widget)
|
|
115
|
-
|
|
116
|
-
def update_widgets(self, values_dict):
|
|
117
|
-
for key, value in values_dict.items():
|
|
118
|
-
for item in self.widget_list:
|
|
119
|
-
if key == item.flag:
|
|
120
|
-
item.set_value(value)
|
|
121
|
-
|
|
122
|
-
def save_tool_parameters(self):
|
|
123
|
-
params = {}
|
|
124
|
-
for item in self.widget_list:
|
|
125
|
-
if item.flag:
|
|
126
|
-
params[item.flag] = item.get_value()
|
|
127
|
-
|
|
128
|
-
self.signal_save_tool_params.emit(params)
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
class FileSelector(QWidget):
|
|
132
|
-
def __init__(self, json_str, runner, master=None, parent=None):
|
|
133
|
-
super(FileSelector, self).__init__(parent)
|
|
134
|
-
|
|
135
|
-
# first make sure that the json data has the correct fields
|
|
136
|
-
j = json.loads(json_str)
|
|
137
|
-
self.name = j['name']
|
|
138
|
-
self.description = j['description']
|
|
139
|
-
self.flag = j['flag']
|
|
140
|
-
self.parameter_type = j['parameter_type']
|
|
141
|
-
self.file_type = ""
|
|
142
|
-
if "ExistingFile" in self.parameter_type:
|
|
143
|
-
self.file_type = j['parameter_type']['ExistingFile']
|
|
144
|
-
elif "NewFile" in self.parameter_type:
|
|
145
|
-
self.file_type = j['parameter_type']['NewFile']
|
|
146
|
-
self.optional = j['optional']
|
|
147
|
-
self.value = j['default_value']
|
|
148
|
-
|
|
149
|
-
self.runner = runner
|
|
150
|
-
|
|
151
|
-
self.layout = QHBoxLayout()
|
|
152
|
-
self.label = QLabel(self.name)
|
|
153
|
-
self.label.setMinimumWidth(BT_LABEL_MIN_WIDTH)
|
|
154
|
-
self.in_file = QLineEdit()
|
|
155
|
-
self.btn_select = QPushButton("...")
|
|
156
|
-
self.btn_select.clicked.connect(self.select_file)
|
|
157
|
-
self.layout.addWidget(self.label)
|
|
158
|
-
self.layout.addWidget(self.in_file)
|
|
159
|
-
self.layout.addWidget(self.btn_select)
|
|
160
|
-
|
|
161
|
-
self.setLayout(self.layout)
|
|
162
|
-
|
|
163
|
-
def select_file(self):
|
|
164
|
-
try:
|
|
165
|
-
dialog = QFileDialog(self)
|
|
166
|
-
dialog.setViewMode(QFileDialog.Detail)
|
|
167
|
-
dialog.setDirectory(str(Path(self.value).parent))
|
|
168
|
-
dialog.selectFile(Path(self.value).name)
|
|
169
|
-
result = None
|
|
170
|
-
file_names = None
|
|
171
|
-
|
|
172
|
-
if self.parameter_type == "Directory":
|
|
173
|
-
dialog.setFileMode(QFileDialog.FileMode.Directory)
|
|
174
|
-
elif "ExistingFile" in self.parameter_type or "NewFile" in self.parameter_type:
|
|
175
|
-
file_types = "All files '*.*')"
|
|
176
|
-
if 'RasterAndVector' in self.file_type:
|
|
177
|
-
file_types = """Shapefiles (*.shp);;
|
|
178
|
-
Raster files (*.dep *.tif *.tiff *.bil *.flt *.sdat *.rdc *.asc *grd)"""
|
|
179
|
-
elif 'Raster' in self.file_type:
|
|
180
|
-
file_types = """Tiff raster files (*.tif *.tiff);;
|
|
181
|
-
Other raster files (*.dep *.bil *.flt *.sdat *.rdc *.asc *.grd)"""
|
|
182
|
-
elif 'Lidar' in self.file_type:
|
|
183
|
-
file_types = "LiDAR files (*.las *.zlidar *.laz *.zip)"
|
|
184
|
-
elif 'Vector' in self.file_type:
|
|
185
|
-
file_types = "Shapefiles (*.shp)"
|
|
186
|
-
elif 'Text' in self.file_type:
|
|
187
|
-
file_types = "Text files (*.txt);; all files (*.*)"
|
|
188
|
-
elif 'Csv' in self.file_type:
|
|
189
|
-
file_types = "CSC files (*.csv);; all files (*.*)"
|
|
190
|
-
elif 'Dat' in self.file_type:
|
|
191
|
-
file_types = "Binary data files (*.dat);; all files (*.*)"
|
|
192
|
-
elif 'Html' in self.file_type:
|
|
193
|
-
file_types = "HTML files (*.html)"
|
|
194
|
-
elif 'json' in self.file_type or 'JSON' in self.file_type:
|
|
195
|
-
file_types = "JSON files (*.json)"
|
|
196
|
-
|
|
197
|
-
dialog.setNameFilter(file_types)
|
|
198
|
-
|
|
199
|
-
if "ExistingFile" in self.parameter_type:
|
|
200
|
-
dialog.setFileMode(QFileDialog.FileMode.ExistingFiles)
|
|
201
|
-
else:
|
|
202
|
-
dialog.setFileMode(QFileDialog.FileMode.AnyFile)
|
|
203
|
-
|
|
204
|
-
if dialog.exec_():
|
|
205
|
-
file_names = dialog.selectedFiles()
|
|
206
|
-
|
|
207
|
-
if not file_names:
|
|
208
|
-
return
|
|
209
|
-
|
|
210
|
-
if len(file_names) == 0:
|
|
211
|
-
print('No file(s) selected.')
|
|
212
|
-
|
|
213
|
-
if file_names[0] == '':
|
|
214
|
-
print('File name not valid.')
|
|
215
|
-
return
|
|
216
|
-
|
|
217
|
-
# append suffix when not
|
|
218
|
-
# TODO: more consideration for multiple formats
|
|
219
|
-
result = file_names[0]
|
|
220
|
-
file_path = Path(result)
|
|
221
|
-
if result != '':
|
|
222
|
-
break_loop = False
|
|
223
|
-
selected_filters = self.get_file_filter_list(dialog.selectedNameFilter())
|
|
224
|
-
|
|
225
|
-
if file_path.suffix not in selected_filters:
|
|
226
|
-
if selected_filters[0] != '.*':
|
|
227
|
-
file_path = file_path.with_suffix(selected_filters[0])
|
|
228
|
-
|
|
229
|
-
result = str(file_path)
|
|
230
|
-
self.set_value(result)
|
|
231
|
-
|
|
232
|
-
# update the working
|
|
233
|
-
# if not self.runner and str(result) != '':
|
|
234
|
-
# self.runner.working_dir = os.path.dirname(result)
|
|
235
|
-
except:
|
|
236
|
-
t = "file"
|
|
237
|
-
if self.parameter_type == "Directory":
|
|
238
|
-
t = "directory"
|
|
239
|
-
|
|
240
|
-
msg_box = QMessageBox()
|
|
241
|
-
msg_box.setIcon(QMessageBox.Warning)
|
|
242
|
-
msg_box.setText("Could not find {}".format(t))
|
|
243
|
-
msg_box.exec()
|
|
244
|
-
|
|
245
|
-
def get_file_filter_list(self, filter_str):
|
|
246
|
-
"""
|
|
247
|
-
Extract filters out of full filter string, split int list and replace first '*'
|
|
248
|
-
Result: ['.shp', '.*']
|
|
249
|
-
"""
|
|
250
|
-
filter_list = re.search('\((.+?)\)', filter_str).group(1).split(' ')
|
|
251
|
-
filter_list = [item.replace('*', '', 1) for item in filter_list if item != '']
|
|
252
|
-
return filter_list
|
|
253
|
-
|
|
254
|
-
def get_value(self):
|
|
255
|
-
return self.value
|
|
256
|
-
|
|
257
|
-
def set_value(self, value):
|
|
258
|
-
self.value = value
|
|
259
|
-
self.in_file.setText(Path(self.value).name)
|
|
260
|
-
self.in_file.setToolTip(value)
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
class FileOrFloat(QWidget):
|
|
264
|
-
def __init__(self, json_str, runner, master=None, parent=None):
|
|
265
|
-
super(FileOrFloat, self).__init__(parent)
|
|
266
|
-
pass
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
class MultifileSelector(QWidget):
|
|
270
|
-
def __init__(self, json_str, runner, master=None, parent=None):
|
|
271
|
-
super(MultifileSelector, self).__init__(parent)
|
|
272
|
-
pass
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
class BooleanInput(QWidget):
|
|
276
|
-
def __init__(self, json_str, master=None, parent=None):
|
|
277
|
-
super(BooleanInput, self).__init__(parent)
|
|
278
|
-
pass
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
class OptionsInput(QWidget):
|
|
282
|
-
def __init__(self, json_str, master=None, parent=None):
|
|
283
|
-
super(OptionsInput, self).__init__(parent)
|
|
284
|
-
|
|
285
|
-
# first make sure that the json data has the correct fields
|
|
286
|
-
j = json.loads(json_str)
|
|
287
|
-
self.name = j['name']
|
|
288
|
-
self.description = j['description']
|
|
289
|
-
self.flag = j['flag']
|
|
290
|
-
self.parameter_type = j['parameter_type']
|
|
291
|
-
self.optional = j['optional']
|
|
292
|
-
self.data_type = j['data_type']
|
|
293
|
-
self.default_value = str(j['default_value'])
|
|
294
|
-
self.value = self.default_value # initialize in event of no default and no selection
|
|
295
|
-
|
|
296
|
-
self.label = QLabel(self.name)
|
|
297
|
-
self.label.setMinimumWidth(BT_LABEL_MIN_WIDTH)
|
|
298
|
-
self.combobox = QComboBox()
|
|
299
|
-
self.combobox.currentIndexChanged.connect(self.selection_change)
|
|
300
|
-
|
|
301
|
-
i = 1
|
|
302
|
-
default_index = -1
|
|
303
|
-
self.option_list = j['parameter_type']['OptionList']
|
|
304
|
-
if self.option_list:
|
|
305
|
-
self.option_list = [str(item) for item in self.option_list] # convert to strings
|
|
306
|
-
values = ()
|
|
307
|
-
for v in self.option_list:
|
|
308
|
-
values += (v,)
|
|
309
|
-
if v == str(self.default_value):
|
|
310
|
-
default_index = i - 1
|
|
311
|
-
i = i + 1
|
|
312
|
-
|
|
313
|
-
self.combobox.addItems(self.option_list)
|
|
314
|
-
self.combobox.setCurrentIndex(default_index)
|
|
315
|
-
|
|
316
|
-
self.layout = QHBoxLayout()
|
|
317
|
-
self.layout.addWidget(self.label)
|
|
318
|
-
self.layout.addWidget(self.combobox)
|
|
319
|
-
self.setLayout(self.layout)
|
|
320
|
-
|
|
321
|
-
def selection_change(self, i):
|
|
322
|
-
self.value = self.option_list[i]
|
|
323
|
-
|
|
324
|
-
def set_value(self, value):
|
|
325
|
-
self.value = self.value
|
|
326
|
-
for v in self.option_list:
|
|
327
|
-
if value == v:
|
|
328
|
-
self.combobox.setCurrentIndex(self.option_list.index(v))
|
|
329
|
-
|
|
330
|
-
def get_value(self):
|
|
331
|
-
return self.value
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
class DataInput(QWidget):
|
|
335
|
-
def __init__(self, json_str, master=None, parent=None):
|
|
336
|
-
super(DataInput, self).__init__(parent)
|
|
337
|
-
|
|
338
|
-
# first make sure that the json data has the correct fields
|
|
339
|
-
j = json.loads(json_str)
|
|
340
|
-
self.name = j['name']
|
|
341
|
-
self.description = j['description']
|
|
342
|
-
self.flag = j['flag']
|
|
343
|
-
self.parameter_type = j['parameter_type']
|
|
344
|
-
self.optional = j['optional']
|
|
345
|
-
self.default_value = j['default_value']
|
|
346
|
-
self.data = j['default_value']
|
|
347
|
-
self.label = QLabel(self.name)
|
|
348
|
-
self.label.setMinimumWidth(BT_LABEL_MIN_WIDTH)
|
|
349
|
-
self.data_input = None
|
|
350
|
-
|
|
351
|
-
if "Integer" in self.parameter_type:
|
|
352
|
-
self.data_input = QSpinBox()
|
|
353
|
-
elif "Float" in self.parameter_type or "Double" in self.parameter_type:
|
|
354
|
-
self.data_input = QDoubleSpinBox()
|
|
355
|
-
|
|
356
|
-
if self.data_input:
|
|
357
|
-
self.data_input.setValue(self.data)
|
|
358
|
-
|
|
359
|
-
self.data_input.valueChanged.connect(self.update_value)
|
|
360
|
-
|
|
361
|
-
self.layout = QHBoxLayout()
|
|
362
|
-
self.layout.addWidget(self.label)
|
|
363
|
-
self.layout.addWidget(self.data_input)
|
|
364
|
-
self.setLayout(self.layout)
|
|
365
|
-
|
|
366
|
-
def update_value(self):
|
|
367
|
-
self.data = self.data_input.value
|
|
368
|
-
|
|
369
|
-
def get_value(self):
|
|
370
|
-
v = self.data
|
|
371
|
-
if v:
|
|
372
|
-
if "Integer" in self.parameter_type:
|
|
373
|
-
return self.flag, int(self.data())
|
|
374
|
-
elif "Float" in self.parameter_type:
|
|
375
|
-
return self.flag, float(self.data())
|
|
376
|
-
elif "Double" in self.parameter_type:
|
|
377
|
-
return self.flag, float(self.data())
|
|
378
|
-
else: # String or StringOrNumber types
|
|
379
|
-
return self.flag, self.value.get()
|
|
380
|
-
else:
|
|
381
|
-
if not self.optional:
|
|
382
|
-
msg_box = QMessageBox()
|
|
383
|
-
msg_box.setIcon(QMessageBox.Warning)
|
|
384
|
-
msg_box.setText("Unspecified non-optional parameter {}.".format(self.flag))
|
|
385
|
-
msg_box.exec()
|
|
386
|
-
|
|
387
|
-
return None
|
|
388
|
-
|
|
389
|
-
def set_value(self, value):
|
|
390
|
-
if self.data_input:
|
|
391
|
-
self.data_input.setValue(value)
|
|
392
|
-
self.update_value()
|
|
393
|
-
|
|
394
|
-
class DoubleSlider(QSlider):
|
|
395
|
-
|
|
396
|
-
# create our our signal that we can connect to if necessary
|
|
397
|
-
doubleValueChanged = pyqtSignal(float)
|
|
398
|
-
|
|
399
|
-
def __init__(self, decimals=3, *args, **kargs):
|
|
400
|
-
super(DoubleSlider, self).__init__(Qt.Horizontal)
|
|
401
|
-
self._multi = 10 ** decimals
|
|
402
|
-
|
|
403
|
-
self.opt = QStyleOptionSlider()
|
|
404
|
-
self.initStyleOption(self.opt)
|
|
405
|
-
|
|
406
|
-
self.valueChanged.connect(self.emitDoubleValueChanged)
|
|
407
|
-
|
|
408
|
-
def emitDoubleValueChanged(self):
|
|
409
|
-
value = float(super(DoubleSlider, self).value())/self._multi
|
|
410
|
-
self.doubleValueChanged.emit(value)
|
|
411
|
-
|
|
412
|
-
def value(self):
|
|
413
|
-
return float(super(DoubleSlider, self).value()) / self._multi
|
|
414
|
-
|
|
415
|
-
def setMinimum(self, value):
|
|
416
|
-
return super(DoubleSlider, self).setMinimum(value * self._multi)
|
|
417
|
-
|
|
418
|
-
def setMaximum(self, value):
|
|
419
|
-
return super(DoubleSlider, self).setMaximum(value * self._multi)
|
|
420
|
-
|
|
421
|
-
def setSingleStep(self, value):
|
|
422
|
-
return super(DoubleSlider, self).setSingleStep(value * self._multi)
|
|
423
|
-
|
|
424
|
-
def singleStep(self):
|
|
425
|
-
return float(super(DoubleSlider, self).singleStep()) / self._multi
|
|
426
|
-
|
|
427
|
-
def setValue(self, value):
|
|
428
|
-
super(DoubleSlider, self).setValue(int(value * self._multi))
|
|
429
|
-
|
|
430
|
-
def sliderChange(self, change):
|
|
431
|
-
if change == QAbstractSlider.SliderValueChange:
|
|
432
|
-
sr = self.style().subControlRect(QStyle.CC_Slider, self.opt, QStyle.SC_SliderHandle)
|
|
433
|
-
bottomRightCorner = sr.bottomLeft()
|
|
434
|
-
QToolTip.showText(self.mapToGlobal(QPoint(bottomRightCorner.x(), bottomRightCorner.y())),
|
|
435
|
-
str(self.value()), self)
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
if __name__ == '__main__':
|
|
439
|
-
app = QApplication(sys.argv)
|
|
440
|
-
dlg = ToolWidgets('Raster Line Attributes')
|
|
441
|
-
dlg.show()
|
|
442
|
-
sys.exit(app.exec_())
|
beratools/gui_tk/cli.py
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
|
|
3
|
-
"""Console script for BERA tools."""
|
|
4
|
-
import sys
|
|
5
|
-
import click
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
@click.command()
|
|
9
|
-
def main(args=None):
|
|
10
|
-
"""Console script for BERA tools."""
|
|
11
|
-
click.echo("Replace this message by putting your code into "
|
|
12
|
-
"BERA_tools.cli.main")
|
|
13
|
-
click.echo("See click documentation at http://click.pocoo.org/")
|
|
14
|
-
return 0
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if __name__ == "__main__":
|
|
18
|
-
sys.exit(main()) # pragma: no cover
|
|
Binary file
|
beratools/gui_tk/img/closed.gif
DELETED
|
Binary file
|
beratools/gui_tk/img/closed.png
DELETED
|
Binary file
|
beratools/gui_tk/img/open.gif
DELETED
|
Binary file
|
beratools/gui_tk/img/open.png
DELETED
|
Binary file
|
beratools/gui_tk/img/tool.gif
DELETED
|
Binary file
|
beratools/gui_tk/img/tool.png
DELETED
|
Binary file
|
beratools/gui_tk/main.py
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import sys
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
from inspect import getsourcefile
|
|
4
|
-
|
|
5
|
-
if __name__ == "__main__":
|
|
6
|
-
current_file = Path(getsourcefile(lambda: 0)).resolve()
|
|
7
|
-
btool_dir = current_file.parents[2]
|
|
8
|
-
sys.path.insert(0, btool_dir.as_posix())
|
|
9
|
-
|
|
10
|
-
from beratools.gui_tk.runner import main_runner
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
if __name__ == "__main__":
|
|
14
|
-
main_runner()
|
beratools/gui_tk/map_window.py
DELETED
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import sys
|
|
3
|
-
os.environ['QT_API'] = 'pyqt5'
|
|
4
|
-
from qtpy.QtWidgets import (QApplication, QVBoxLayout, QHBoxLayout, QWidget, QTreeWidget, QTreeWidgetItem,
|
|
5
|
-
QPushButton, QGroupBox, QDialog, QDialogButtonBox)
|
|
6
|
-
from qtpy.QtCore import (Qt, Signal)
|
|
7
|
-
from beratools.third_party.pyqtlet2 import L, MapWidget
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class MapWindow(QDialog):
|
|
11
|
-
def __init__(self, parent=None):
|
|
12
|
-
# Setting up the widgets and layout
|
|
13
|
-
super(MapWindow, self).__init__(parent)
|
|
14
|
-
self.setWindowTitle('Tiler map')
|
|
15
|
-
self.setGeometry(0, 0, 1200, 800)
|
|
16
|
-
|
|
17
|
-
# delete dialog when close
|
|
18
|
-
self.setAttribute(Qt.WA_DeleteOnClose)
|
|
19
|
-
|
|
20
|
-
# Add OK/cancel buttons
|
|
21
|
-
self.ok_btn_box = QDialogButtonBox(Qt.Vertical)
|
|
22
|
-
self.ok_btn_box.addButton("Run Tiler", QDialogButtonBox.AcceptRole)
|
|
23
|
-
self.ok_btn_box.addButton("Cancel", QDialogButtonBox.RejectRole)
|
|
24
|
-
self.ok_btn_box.addButton("Help", QDialogButtonBox.HelpRole)
|
|
25
|
-
|
|
26
|
-
self.ok_btn_box.buttons()[0].setFixedSize(120, 40)
|
|
27
|
-
self.ok_btn_box.buttons()[1].setFixedSize(120, 40)
|
|
28
|
-
self.ok_btn_box.buttons()[2].setFixedSize(120, 40)
|
|
29
|
-
|
|
30
|
-
self.ok_btn_box.accepted.connect(self.run)
|
|
31
|
-
self.ok_btn_box.rejected.connect(self.cancel)
|
|
32
|
-
self.ok_btn_box.helpRequested.connect(self.help)
|
|
33
|
-
|
|
34
|
-
self.info_layout = QVBoxLayout() # layout reserved for tiles info widgets
|
|
35
|
-
self.vbox_group = QVBoxLayout()
|
|
36
|
-
self.vbox_group.addLayout(self.info_layout)
|
|
37
|
-
self.vbox_group.addStretch()
|
|
38
|
-
self.vbox_group.addWidget(self.ok_btn_box, alignment=Qt.AlignCenter)
|
|
39
|
-
|
|
40
|
-
groupbox_info = QGroupBox('Tiles')
|
|
41
|
-
groupbox_info.setLayout(self.vbox_group)
|
|
42
|
-
|
|
43
|
-
central_widget = QWidget()
|
|
44
|
-
map_layout = QHBoxLayout(central_widget)
|
|
45
|
-
map_layout.addWidget(groupbox_info)
|
|
46
|
-
|
|
47
|
-
groupbox_map = QGroupBox('Map')
|
|
48
|
-
self.map_widget = MapWidget()
|
|
49
|
-
self.map_widget.setContentsMargins(10, 10, 10, 10)
|
|
50
|
-
self.vbox_map = QVBoxLayout()
|
|
51
|
-
self.vbox_map.addWidget(self.map_widget)
|
|
52
|
-
groupbox_map.setLayout(self.vbox_map)
|
|
53
|
-
map_layout.addWidget(groupbox_map, 10)
|
|
54
|
-
self.setLayout(map_layout)
|
|
55
|
-
|
|
56
|
-
# Working with the maps with pyqtlet
|
|
57
|
-
self.map = L.map(self.map_widget)
|
|
58
|
-
self.map.setView([0, 0], 10) # this is necessary
|
|
59
|
-
|
|
60
|
-
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png').addTo(self.map)
|
|
61
|
-
|
|
62
|
-
# add marker layer
|
|
63
|
-
# self.add_marker_layer()
|
|
64
|
-
self.show()
|
|
65
|
-
|
|
66
|
-
def add_polygons_to_map(self, layer_name, polygons, color):
|
|
67
|
-
style = {'fillOpacity': 0.1, 'color': color}
|
|
68
|
-
vars()[layer_name] = L.polygon(polygons, style)
|
|
69
|
-
self.map.addLayer(vars()[layer_name])
|
|
70
|
-
|
|
71
|
-
# this works too. addLayer has to be called first
|
|
72
|
-
# self.map.runJavaScript("var stylePoly = {fillColor:'red',color: 'blue',weight:2,fillOpacity:0.8};", 0)
|
|
73
|
-
# self.map.runJavaScript(f'{self.multipolygon.jsName}.setStyle(stylePoly);', 0)
|
|
74
|
-
def add_polylines_to_map(self, polylines, color):
|
|
75
|
-
style = {'color': color}
|
|
76
|
-
lines = L.polyline(polylines, style)
|
|
77
|
-
self.map.addLayer(lines)
|
|
78
|
-
|
|
79
|
-
def set_view(self, point, zoom):
|
|
80
|
-
self.map = self.map.setView(point, zoom)
|
|
81
|
-
|
|
82
|
-
# bounds is a pair of corner points, LL and UR
|
|
83
|
-
def fit_bounds(self, bounds):
|
|
84
|
-
# self.map.fitBounds(bounds)
|
|
85
|
-
self.map.runJavaScript(f'{self.map.jsName}.fitBounds(bounds);', 0)
|
|
86
|
-
|
|
87
|
-
def add_marker_layer(self):
|
|
88
|
-
self.marker = L.marker([12.934056, -77.610029])
|
|
89
|
-
self.marker.bindPopup('Maps are a treasure.')
|
|
90
|
-
self.map.addLayer(self.marker)
|
|
91
|
-
|
|
92
|
-
# Create a icon called markerIcon in the js runtime.
|
|
93
|
-
self.map.runJavaScript('var markerIcon '
|
|
94
|
-
'= L.icon({iconUrl: "https://leafletjs.com/examples/custom-icons/leaf-red.png"});', 0)
|
|
95
|
-
|
|
96
|
-
# Edit the existing python object by accessing it's jsName property
|
|
97
|
-
self.map.runJavaScript(f'{self.marker.jsName}.setIcon(markerIcon);', 0)
|
|
98
|
-
|
|
99
|
-
def accept(self):
|
|
100
|
-
print("Run the tiling.")
|
|
101
|
-
QDialog.accept(self)
|
|
102
|
-
|
|
103
|
-
def run(self):
|
|
104
|
-
self.accept()
|
|
105
|
-
|
|
106
|
-
def cancel(self):
|
|
107
|
-
print("Tiling canceled.")
|
|
108
|
-
self.reject()
|
|
109
|
-
|
|
110
|
-
def help(self):
|
|
111
|
-
print("Help requested.")
|
|
112
|
-
|
|
113
|
-
def set_tiles_info(self, tiles_info):
|
|
114
|
-
tree = QTreeWidget()
|
|
115
|
-
tree.setColumnCount(2)
|
|
116
|
-
tree.setHeaderLabels(["Item", "Value"])
|
|
117
|
-
item = QTreeWidgetItem(['Tiles'])
|
|
118
|
-
for key, value in tiles_info.items():
|
|
119
|
-
child = QTreeWidgetItem([key, str(value)])
|
|
120
|
-
item.addChild(child)
|
|
121
|
-
|
|
122
|
-
tree.insertTopLevelItem(0, item)
|
|
123
|
-
tree.expandAll()
|
|
124
|
-
|
|
125
|
-
# add to group widget
|
|
126
|
-
self.vbox_group.insertWidget(0, tree)
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
if __name__ == '__main__':
|
|
130
|
-
# supress web engine logging
|
|
131
|
-
os.environ["QTWEBENGINE_CHROMIUM_FLAGS"] = "--enable-logging --log-level=3"
|
|
132
|
-
|
|
133
|
-
app = QApplication(sys.argv)
|
|
134
|
-
widget = MapWindow()
|
|
135
|
-
|
|
136
|
-
# add polygons to map
|
|
137
|
-
polygon_coords_base = [[[17.285044, 78.286671], [16.606174, 80.748015], [17.886816, 83.518482]]]
|
|
138
|
-
widget.add_polygons_to_map(polygon_coords_base, 'blue')
|
|
139
|
-
|
|
140
|
-
polygon_coords = [[[17.385044, 78.486671], [16.506174, 80.648015], [17.686816, 83.218482]],
|
|
141
|
-
[[13.082680, 80.270718], [12.971599, 77.594563], [15.828126, 78.037279]]]
|
|
142
|
-
widget.add_polygons_to_map(polygon_coords, 'red')
|
|
143
|
-
|
|
144
|
-
sys.exit(app.exec_())
|