class VoGISProfilToolPlotDialog(QDialog): def __init__(self, interface, settings, profiles, intersections): QDialog.__init__(self, interface.mainWindow()) self.iface = interface #output debug Log Messages: mainly for debugging matplotlib self.debug = False self.settings = settings self.profiles = profiles self.intersections = intersections # Set up the user interface from Designer. self.ui = Ui_VoGISProfilToolPlot() self.ui.setupUi(self) if self.settings.onlyHektoMode is True: self.ui.IDC_frPlot.hide() self.ui.IDC_frToolbar.hide() self.adjustSize() self.ui.IDC_chkHekto.setCheckState(Qt.Checked) self.ui.IDC_chkHekto.setEnabled(False) #self.filePath = '' if QGis.QGIS_VERSION_INT < 10900: self.filePath = QSettings().value("vogisprofiltoolmain/savepath", "").toString() else: self.filePath = QSettings().value("vogisprofiltoolmain/savepath", "") #nimmt die Locale vom System, nicht von QGIS #kein Weg gefunden, um QGIS Locale: QSettings().value("locale/userLocale") #zu initialisieren, nur um Dezimaltrenne auszulesen #QgsMessageLog.logMessage('QGIS Locale:{0}'.format(QSettings().value("locale/userLocale").toString()), 'VoGis') #!!!nl_langinfo not available on Windows!!! #http://docs.python.org/2.7/library/locale.html#locale.nl_langinfo # ... This function is not available on all systems ... #decimalDelimiter = locale.nl_langinfo(locale.RADIXCHAR) decimalDelimiter = locale.localeconv()['decimal_point'] QgsMessageLog.logMessage('delimiter:{0}'.format(decimalDelimiter), 'VoGis') idx = self.ui.IDC_cbDecimalDelimiter.findText(decimalDelimiter, Qt.MatchExactly) QgsMessageLog.logMessage('idx:{0}'.format(idx), 'VoGis') self.ui.IDC_cbDecimalDelimiter.setCurrentIndex(idx) plt_extent = PlotExtent() for profile in self.profiles: plt_extent.union(profile.getExtent()) if self.debug: QgsMessageLog.logMessage(plt_extent.toString(), 'VoGis') plt_extent.expand() self.orig_plt_xtnt = PlotExtent(plt_extent.xmin, plt_extent.ymin, plt_extent.xmax, plt_extent.ymax) self.plt_widget = self.__createMatplotlibCanvas(plt_extent) layout = self.ui.IDC_frPlot.layout() #QgsMessageLog.logMessage('layout: {0}'.format(layout), 'VoGis') layout.addWidget(self.plt_widget) # check matplotlib version solves https://github.com/BergWerkGIS/VoGIS-Profil-Tool/issues/6 if matplotlib.__version__ < 1.5: plt_toolbar = matplotlib.backends.backend_qt4agg.NavigationToolbar2QTAgg( self.plt_widget, self.ui.IDC_frPlot) else: plt_toolbar = matplotlib.backends.backend_qt4agg.NavigationToolbar2QT( self.plt_widget, self.ui.IDC_frPlot) self.ui.IDC_frToolbar.layout().addWidget(plt_toolbar) #adjust actions #QgsMessageLog.logMessage('{0}'.format(dir(lstActions[0])), 'VoGis') # for a in plt_toolbar.actions(): # QgsMessageLog.logMessage('{0}'.format(a.text()), 'VoGis') # for t in plt_toolbar.toolitems: # QgsMessageLog.logMessage('{0}'.format(t), 'VoGis') #lstActions = plt_toolbar.actions() #https://hub.qgis.org/wiki/17/Icons_20 firstaction = None for a in plt_toolbar.actions(): atxt = a.text() if atxt == 'Home': firstaction = a a.setIcon( QIcon(":/plugins/vogisprofiltoolmain/icons/home.png")) elif atxt == 'Back': a.setIcon( QIcon(":/plugins/vogisprofiltoolmain/icons/zoomlast.png")) elif atxt == 'Forward': a.setIcon( QIcon(":/plugins/vogisprofiltoolmain/icons/zoomnext.png")) elif atxt == 'Pan': a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/pan.png")) elif atxt == 'Zoom': a.setIcon( QIcon( ":/plugins/vogisprofiltoolmain/icons/zoomselect.png")) elif atxt == 'Save': a.setIcon( QIcon(":/plugins/vogisprofiltoolmain/icons/save.png")) else: plt_toolbar.removeAction(a) #insert 1:1 zoom button self.one2one = QPushButton() self.one2one.setText('1:1') self.one2one.clicked.connect(self.__one2oneClicked) #plt_toolbar.addWidget(self.one2one) #insert QLineEdit to change the exaggeration #catch updating of figure, when exaggeration QLineEdit has been updated from draw_event of figure self.draw_event_fired = False #catch closing of dialog, when enter key has been used accept exaggeration edit field self.exaggeration_edited = False #insert edit field for exaggeration self.editExaggeration = QLineEdit() self.editExaggeration.setFixedWidth(60) self.editExaggeration.setMaximumWidth(60) plt_toolbar.insertWidget(firstaction, self.editExaggeration) self.editExaggeration.editingFinished.connect( self.__exaggeration_edited) #insert identify button -> deactivate all tools #HACK: picked event gets fired before click event self.plotpicked = False plt_toolbar.insertWidget(firstaction, self.one2one) self.identify = QPushButton() self.identify.setIcon( QIcon(":/plugins/vogisprofiltoolmain/icons/identify.png")) self.identify.clicked.connect(self.__identify) plt_toolbar.insertWidget(firstaction, self.identify) #insert identify label to show name of clicked dhm self.dhmLbl = QLabel() plt_toolbar.insertWidget(firstaction, self.dhmLbl) #insert measure tool self.measuring = False self.measure_tool = QPushButton() self.measure_tool.setIcon( QIcon(":/plugins/vogisprofiltoolmain/icons/measure.png")) self.measure_tool.clicked.connect(self.__measure) plt_toolbar.insertWidget(firstaction, self.measure_tool) #show measure results self.click1 = None self.click2 = None self.click1pnt = None self.click2pnt = None self.measure_lbl = QLabel() self.measure_lbl.setText(u' ') plt_toolbar.insertWidget(firstaction, self.measure_lbl) #for less thatn 10 colors: #alternative method: http://stackoverflow.com/a/14720445 colors = [ (1.0, 0.0, 0.0, 1.0), (0.0, 1.0, 0.0, 1.0), (0.0, 0.0, 1.0, 1.0), (1.0, 1.0, 0.5, 1.0), (1.0, 0.0, 1.0, 1.0), (0.0, 1.0, 1.0, 1.0), (0.415686275, 0.807843137, 0.890196078, 1.0), (0.121568627, 0.470588235, 0.705882353, 1.0), (0.698039216, 0.874509804, 0.541176471, 1.0), (0.2, 0.62745098, 0.17254902, 1.0), (0.984313725, 0.603921569, 0.6, 1.0), (0.890196078, 0.101960784, 0.109803922, 1.0), (0.992156863, 0.749019608, 0.435294118, 1.0), (1, 0.498039216, 0, 1.0), (0.792156863, 0.698039216, 0.839215686, 1.0), (0.415686275, 0.239215686, 0.603921569, 1.0), (1, 1, 0.521568627, 1.0), ] max_profile_length = 0 #idxCol = 0 for idx, p in enumerate(self.profiles): max_profile_length = max(p.getExtent().xmax, max_profile_length) #if idxCol > len(colors) - 1: # idxCol = 0 #x, plt_segments = p.getPlotSegments() #QgsMessageLog.logMessage('x: {0}'.format(x), 'VoGis') plt_segments = p.getPlotSegments() #QgsMessageLog.logMessage('plt_segments: {0}'.format(plt_segments), 'VoGis') lineColl = LineCollection( plt_segments, linewidths=2, linestyles='solid', #colors=colors[randrange(len(colors))], #colors=colors[idxCol], colors=colors[:len(settings.mapData.rasters.selectedRasters() )], picker=True, label='LBL') #lineColl.set_array(x) #lineColl.text.set_text('line label') self.subplot.add_collection(lineColl) #idxCol += 1 #LINE STYLES: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.plot for idx, intersection in enumerate(self.intersections): color_intersection = ['b', 'g', 'r', 'c', 'm', 'y', 'k'] x_1 = intersection.from_dist x_2 = intersection.to_dist z_1 = intersection.from_z[self.settings.intersection_dhm_idx] z_2 = intersection.to_z[self.settings.intersection_dhm_idx] self.subplot.plot((x_1, x_2), (z_1, z_2), color_intersection[idx] + '--', linewidth=4, zorder=1) #http://matplotlib.org/users/annotations_guide.html#using-complex-coordinate-with-annotation self.subplot.annotate(u'{0:.2f}'.format(z_1), (x_1, z_1), xytext=(0, 30), textcoords="offset points", bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="->"), ha='center', va='bottom', rotation=90) self.subplot.annotate(u'{0:.2f}'.format(z_2), (x_2, z_2), xytext=(0, 30), textcoords="offset points", bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="->"), ha='center', va='bottom', rotation=90) #horizontale Ausspiegeling self.subplot.plot((x_1, max_profile_length), (z_1, z_1), color_intersection[idx] + ':', linewidth=4, zorder=1) #save inital view in history plt_toolbar.push_current() #select pan tool plt_toolbar.pan() self.plt_toolbar = plt_toolbar #(matplotlib.pyplot).tight_layout(True) #plt.tight_layout() #self.fig.tight_layout() QApplication.restoreOverrideCursor() def accept(self): #QMessageBox.warning(self.iface.mainWindow(), "VoGIS-Profiltool", "ACCEPTED") QgsMessageLog.logMessage( 'accept: {0}'.format(self.exaggeration_edited), 'VoGis') if self.exaggeration_edited is True: self.exaggeration_edited = False return QDialog.accept(self) def reject(self): #QMessageBox.warning(self.iface.mainWindow(), "VoGIS-Profiltool", "REJECTED") QgsMessageLog.logMessage( 'reject: {0}'.format(self.exaggeration_edited), 'VoGis') if self.exaggeration_edited is True: self.exaggeration_edited = False return QDialog.reject(self) def exportShpPnt(self): self.__exportShp(True) def exportShpLine(self): self.__exportShp(False) def __exportShp(self, asPnt): u = Util(self.iface) if asPnt is True: caption = QApplication.translate('code', 'Punkt Shapefile exportieren', None, QApplication.UnicodeUTF8) else: caption = QApplication.translate('code', 'Linien Shapefile exportieren', None, QApplication.UnicodeUTF8) fileName, file_ext = u.getFileName(caption, [["shp", "shp"]], self.filePath) if fileName == '': return fInfo = QFileInfo(fileName) self.filePath = fInfo.path() QSettings().setValue("vogisprofiltoolmain/savepath", self.filePath) expShp = ExportShape( self.iface, (self.ui.IDC_chkHekto.checkState() == Qt.Checked), (self.ui.IDC_chkLineAttributes.checkState() == Qt.Checked), self.__getDelimiter(), self.__getDecimalDelimiter(), fileName, self.settings, self.profiles) if asPnt is False: expShp.exportLine() else: expShp.exportPoint() def exportCsvXls(self): u = Util(self.iface) caption = QApplication.translate('code', 'Excel- oder CSV-Datei exportieren', None, QApplication.UnicodeUTF8) file_format = [] file_format.append(["Microsoft Excel 2007/2010 XML", "xlsx"]) file_format.append(["Comma-Separated Values CSV", "csv"]) fileName, fileExt = u.getFileName(caption, file_format, self.filePath) QgsMessageLog.logMessage( u'fileName: {0} fileExt:{1}'.format(fileName, fileExt), 'VoGis') if fileName == '': return fInfo = QFileInfo(fileName) self.filePath = fInfo.path() QSettings().setValue("vogisprofiltoolmain/savepath", self.filePath) hekto = (self.ui.IDC_chkHekto.checkState() == Qt.Checked) attribs = (self.ui.IDC_chkLineAttributes.checkState() == Qt.Checked) delimiter = ';' decimalDelimiter = self.__getDecimalDelimiter() if fileExt == 'csv': txt = open(fileName, 'w') txt.write(self.profiles[0].writeHeader( self.settings.mapData.rasters.selectedRasters(), hekto, attribs, delimiter)) for p in self.profiles: #txt.write('=====Profil {0}======{1}'.format(p.id, os.linesep)) #txt.write('Segments:{0}{1}'.format(len(p.segments), os.linesep)) #for s in p.segments: # txt.write('Vertices:{0}{1}'.format(len(s.vertices), os.linesep)) txt.write( p.toString(hekto, attribs, delimiter, decimalDelimiter)) else: # BEGIN XLSX-Export exXls = ExportXls(self.iface, fileName, self.settings, self.profiles, hekto, attribs, decimalDelimiter) exXls.create() def exportTxt(self): delimiter = self.__getDelimiter() decimalDelimiter = self.__getDecimalDelimiter() if delimiter == decimalDelimiter: msg = QApplication.translate( 'code', 'Gleiches Dezimal- und Spaltentrennzeichen gewählt!', None, QApplication.UnicodeUTF8) QMessageBox.warning(self.iface.mainWindow(), 'VoGIS-Profiltool', msg) return u = Util(self.iface) caption = QApplication.translate('code', 'Textdatei exportieren', None, QApplication.UnicodeUTF8) fileName, file_ext = u.getFileName(caption, [["txt", "txt"]], self.filePath) if fileName == '': return fInfo = QFileInfo(fileName) self.filePath = fInfo.path() QSettings().setValue("vogisprofiltoolmain/savepath", self.filePath) hekto = (self.ui.IDC_chkHekto.checkState() == Qt.Checked) attribs = (self.ui.IDC_chkLineAttributes.checkState() == Qt.Checked) txt = open(fileName, 'w') txt.write(self.profiles[0].writeHeader( self.settings.mapData.rasters.selectedRasters(), hekto, attribs, delimiter)) for p in self.profiles: #txt.write('=====Profil {0}======{1}'.format(p.id, os.linesep)) #txt.write('Segments:{0}{1}'.format(len(p.segments), os.linesep)) #for s in p.segments: # txt.write('Vertices:{0}{1}'.format(len(s.vertices), os.linesep)) txt.write(p.toString(hekto, attribs, delimiter, decimalDelimiter)) txt.close() def exportAutoCadTxt(self): u = Util(self.iface) caption = QApplication.translate('code', 'AutoCad Textdatei exportieren', None, QApplication.UnicodeUTF8) fileName, file_ext = u.getFileName(caption, [["txt", "txt"]], self.filePath) if fileName == '': return fInfo = QFileInfo(fileName) self.filePath = fInfo.path() QSettings().setValue("vogisprofiltoolmain/savepath", self.filePath) txt = open(fileName, 'w') for p in self.profiles: txt.write(p.toACadTxt(' ', '.')) txt.close() def exportDxfPnt(self): self.__exportDxf(True) def exportDxfLine(self): self.__exportDxf(False) def __exportDxf(self, asPnt): u = Util(self.iface) caption = QApplication.translate('code', 'DXF exportieren', None, QApplication.UnicodeUTF8) fileName, file_ext = u.getFileName(caption, [["dxf", "dxf"]], self.filePath) if fileName == '': return fInfo = QFileInfo(fileName) self.filePath = fInfo.path() QSettings().setValue("vogisprofiltoolmain/savepath", self.filePath) exDxf = ExportDxf(self.iface, fileName, self.settings, self.profiles) if asPnt is True: exDxf.exportPoint() else: exDxf.exportLine() def __identify(self): #dirty hack: deselect all tools #selecting a tool twice deselects it self.plt_toolbar.pan() self.plt_toolbar.zoom() self.plt_toolbar.zoom() def __measure(self): self.measuring = True #dirty hack: deselect all tools #selecting a tool twice deselects it self.plt_toolbar.pan() self.plt_toolbar.zoom() self.plt_toolbar.zoom() def __figureDrawn(self, event): if self.debug: QgsMessageLog.logMessage( '__figureDrawn, draw_event_fired:{0} exaggeration_edited: {1}'. format(self.draw_event_fired, self.exaggeration_edited), 'VoGis') #draw event seems to get fired twice????? if self.draw_event_fired == True: return self.draw_event_fired = True axes = self.plt_widget.figure.get_axes()[0] xlim = axes.get_xlim() ylim = axes.get_ylim() if self.debug: QgsMessageLog.logMessage( '__figureDrawn: xlim:{0} ylim:{1}'.format(xlim, ylim), 'VoGis') dpi = self.plt_widget.figure.get_dpi() fig_width = self.plt_widget.figure.get_figwidth() * dpi fig_height = self.plt_widget.figure.get_figheight() * dpi #bbox = axes.get_window_extent().transformed(self.plt_widget.figure.dpi_scale_trans.inverted()) #fig_width, fig_height = bbox.width * dpi, bbox.height * dpi fig_width *= (TOP_MARGIN - BOTTOM_MARGIN) fig_height *= (RIGHT_MARGIN - LEFT_MARGIN) delta_x = xlim[1] - xlim[0] delta_y = ylim[1] - ylim[0] ratio = (delta_x / fig_width) / (delta_y / fig_height) ratio = floor(ratio * 10) / 10 if self.debug: QgsMessageLog.logMessage( '__figureDrawn: fig_width:{0} fig_height:{1} dpi:{2} delta_x:{3} delta_y:{4}, ratio:{5}' .format(fig_width, fig_height, dpi, delta_x, delta_y, ratio), 'VoGis') if self.debug: QgsMessageLog.logMessage( '__figureDrawn: axes.get_data_ratio:{0}'.format( axes.get_data_ratio()), 'VoGis') #self.editExaggeration.setText('{0:.1f}'.format(ratio)) self.editExaggeration.setText('{0:.1f}'.format(axes.get_aspect())) self.draw_event_fired = False def __exaggeration_edited(self, *args): if self.debug: QgsMessageLog.logMessage( '__exaggeration_edited, exaggeration_edited:{0} draw_event_fired: {1}' .format(self.exaggeration_edited, self.draw_event_fired), 'VoGis') #this event handler seems to get called twice???? if self.draw_event_fired == True: return if self.exaggeration_edited == True: return self.exaggeration_edited = True #QgsMessageLog.logMessage('__exaggeration_edited: {0}'.format(self.exaggeration_edited), 'VoGis') ut = Util(self.iface) txtExa = QApplication.translate('code', 'Überhöhung', None, QApplication.UnicodeUTF8) if ut.isFloat(self.editExaggeration.text(), txtExa) is False: return False #clear focus of lineedit, otherwise it gets called even when the user wants to close the dialog self.editExaggeration.clearFocus() exa = float(self.editExaggeration.text().replace(',', '.')) self.__adjustAxes(exa) def __one2oneClicked(self): if self.debug: QgsMessageLog.logMessage('1:1 clicked', 'VoGis') #QgsMessageLog.logMessage('axes:{0}'.format(self.plt_widget.figure.get_axes()), 'VoGis') self.__adjustAxes(1.0) def __adjustAxes(self, exaggeration): exaggeration = floor(exaggeration * 10) / 10 axes = self.plt_widget.figure.get_axes()[0] #axes.set_aspect(exaggeration) #axes.set_autoscalex_on(False) #axes.set_autoscaley_on(True) if self.debug: QgsMessageLog.logMessage( '__adjustAxes, get_aspect:{0}'.format(axes.get_aspect()), 'VoGis') QgsMessageLog.logMessage( '__adjustAxes, get_position:{0}'.format(axes.get_position()), 'VoGis') QgsMessageLog.logMessage( '__adjustAxes, xBound:{0} xlim:{1}'.format( axes.get_xbound(), axes.get_xlim()), 'VoGis') QgsMessageLog.logMessage( '__adjustAxes, yBound:{0} ylim:{1}'.format( axes.get_ybound(), axes.get_ylim()), 'VoGis') oldexa = axes.get_aspect() ratioexa = oldexa / exaggeration ylim = axes.get_ylim() deltaYold = ylim[1] - ylim[0] deltaYnew = deltaYold * ratioexa centerY = ylim[0] + (deltaYold / 2) axes.set_ylim(centerY - deltaYnew / 2, centerY + deltaYnew / 2) axes.set_aspect(exaggeration, 'datalim', 'C') self.plt_widget.draw() if self.debug: QgsMessageLog.logMessage( '__adjustAxes, get_aspect:{0}'.format(axes.get_aspect()), 'VoGis') QgsMessageLog.logMessage( '__adjustAxes, get_position:{0}'.format(axes.get_position()), 'VoGis') QgsMessageLog.logMessage( '__adjustAxes, xBound:{0} xlim:{1}'.format( axes.get_xbound(), axes.get_xlim()), 'VoGis') QgsMessageLog.logMessage( '__adjustAxes, yBound:{0} ylim:{1}'.format( axes.get_ybound(), axes.get_ylim()), 'VoGis') def __plotPicked(self, event): self.plotpicked = True if self.debug: QgsMessageLog.logMessage('__plotPicked', 'VoGis') #QgsMessageLog.logMessage('artist:{0}'.format(type(event.artist)), 'VoGis') self.dhmLbl.setText(' ? ') if isinstance(event.artist, Line2D): QgsMessageLog.logMessage('Line2D', 'VoGis') line = event.artist xdata = line.get_xdata() ydata = line.get_ydata() ind = event.ind QgsMessageLog.logMessage('{0}: {1} {2}'.format(ind, xdata, ydata), 'VoGis') QgsMessageLog.logMessage(help(line), 'VoGis') elif isinstance(event.artist, LineCollection): QgsMessageLog.logMessage('LineCollection', 'VoGis') r = self.settings.mapData.rasters.selectedRasters()[event.ind[0]] QgsMessageLog.logMessage('Raster: {0}'.format(r.name), 'VoGis') self.dhmLbl.setText(u' [' + r.name + '] ') else: QgsMessageLog.logMessage('no Line2D or LineCollection', 'VoGis') def __mouse_move(self, event): if self.measuring is False: return if self.click1 is None: return if event.xdata is None or event.ydata is None: return dx = event.xdata - self.click1.xdata dy = event.ydata - self.click1.ydata if self.debug: #QgsMessageLog.logMessage('mouse move name {0}'.format(event.name), 'VoGis') #QgsMessageLog.logMessage('mouse move xdata {0}'.format(event.xdata), 'VoGis') #QgsMessageLog.logMessage('mouse move ydata {0}'.format(event.ydata), 'VoGis') QgsMessageLog.logMessage('dx/dy {0}/{1}'.format(dx, dy), 'VoGis') self.measure_lbl.setText( u' x/y:{0:.1f}/{1:.1f} dx/dy:{2:.1f}/{3:.1f}'.format( self.click1.xdata, self.click1.ydata, dx, dy)) self.plt_toolbar.draw_rubberband('xy', self.click1.xpixel, self.click1.ypixel, event.x, event.y) def __buttonPressed(self, event): if self.debug: QgsMessageLog.logMessage('__buttonPressed', 'VoGis') if self.plotpicked is False: self.dhmLbl.setText(' ? ') #reset flag to show '?' next time a button gets pressed self.plotpicked = False if self.measuring is False: return if self.debug: QgsMessageLog.logMessage('{0}'.format(dir(event)), 'VoGis') QgsMessageLog.logMessage('{0}'.format(dir(event.xdata)), 'VoGis') QgsMessageLog.logMessage('{0}'.format(dir(event.ydata)), 'VoGis') QgsMessageLog.logMessage( 'x:{0} y:{1} xdata:{2} ydata:{3} click1:{4} click2:{5} click1pnt:{6} click2pnt:{7}' .format(event.x, event.y, event.xdata, event.ydata, self.click1, self.click2, self.click1pnt, self.click2pnt), 'VoGis') QgsMessageLog.logMessage( 'click1pnt: {0}'.format(dir(self.click1pnt)), 'VoGis') if event.xdata is None or event.ydata is None: return if self.click1 is None: self.click1 = ChartPoint(event.x, event.y, event.xdata, event.ydata) self.click2 = None #self.measure_lbl.setText(u'') self.measure_lbl.setText(u' x/y:{0:.1f}/{1:.1f} dx/dy:0/0'.format( event.xdata, event.ydata)) if not self.click1pnt is None: p = self.click1pnt.pop(0) p.remove() del p self.click1pnt = None if not self.click2pnt is None: p = self.click2pnt.pop(0) p.remove() del p self.click2pnt = None self.click1pnt = self.subplot.plot(event.xdata, event.ydata, 'ro') elif self.click2 is None: self.click2 = ChartPoint(event.x, event.y, event.xdata, event.ydata) #delta_x = abs(self.click2[0] - self.click1[0]) #delta_y = abs(self.click2[1] - self.click1[1]) #dist = ((delta_x ** 2) + (delta_y ** 2)) ** 0.5 #self.measure_lbl.setText(u' dist: {0:.1f} '.format(dist)) delta_x = self.click2.xdata - self.click1.xdata delta_y = self.click2.ydata - self.click1.ydata dist = sqrt(pow(delta_x, 2) + pow(delta_y, 2)) self.measure_lbl.setText( u' dx/dy:{0:.1f}/{1:.1f} d:{2:.1f}'.format( delta_x, delta_y, dist)) self.click1 = None self.measuring = False if not self.click2pnt is None: p = self.click2pnt.pop(0) p.remove() del p self.click2pnt = None self.click2pnt = self.subplot.plot(event.xdata, event.ydata, 'go') #refresh plot to show points, when identify tool active #if self.debug: QgsMessageLog.logMessage('__buttonPressed: active: {0}'.format(self.plt_toolbar._active), 'VoGis') #if self.plotpicked is True: if self.plt_toolbar._active is None: self.plt_widget.draw() def __createMatplotlibCanvas(self, plt_extent): fig = Figure( (1, 1), #tight_layout=True, linewidth=0.0, subplotpars=matplotlib.figure.SubplotParams(left=0, bottom=0, right=1, top=1, wspace=0, hspace=0)) #fig.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=None, hspace=None) #fig = Figure((24, 24), tight_layout=True) # try: # fig = Figure(tight_layout=True) # except: # #tight layout not available # fig = Figure() #fig = plt.figure() #fig.set_tight_layout(True) #font = {'family': 'arial', 'weight': 'normal', 'size': 12} #rc('font', **font) rect = fig.patch rect.set_facecolor((0.9, 0.9, 0.9)) # self.subplot = fig.add_axes( # #(0.08, 0.15, 0.92, 0.82), # (0.0, 0.0, 1.0, 1.0), # anchor='SW', # adjustable='box-forced' # ) #left bottom right top self.subplot = fig.add_axes( (LEFT_MARGIN, BOTTOM_MARGIN, RIGHT_MARGIN, TOP_MARGIN), adjustable='datalim', aspect=1) #self.subplot.plot.tight_layout(True) self.subplot.set_xbound(plt_extent.xmin, plt_extent.xmax) self.subplot.set_ybound(plt_extent.ymin, plt_extent.ymax) self.__setupAxes(self.subplot) #fig.tight_layout() canvas = FigureCanvasQTAgg(fig) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) canvas.setSizePolicy(sizePolicy) canvas.mpl_connect('pick_event', self.__plotPicked) canvas.mpl_connect('draw_event', self.__figureDrawn) canvas.mpl_connect('button_press_event', self.__buttonPressed) canvas.mpl_connect('motion_notify_event', self.__mouse_move) return canvas def __setupAxes(self, axe1): axe1.grid() axe1.ticklabel_format(style='plain', useOffset=False) axe1.tick_params(axis="both", which="major", direction="out", length=10, width=1, bottom=True, top=False, left=True, right=False) axe1.minorticks_on() axe1.tick_params(axis="both", which="minor", direction="out", length=5, width=1, bottom=True, top=False, left=True, right=False) def __getDecimalDelimiter(self): #delim = self.ui.IDC_cbDecimalDelimiter.itemData(self.ui.IDC_cbDecimalDelimiter.currentIndex()) delim = self.ui.IDC_cbDecimalDelimiter.currentText() #QgsMessageLog.logMessage('delim:' + str(delim), 'VoGis') return delim def __getDelimiter(self): #delim = self.ui.IDC_cbDelimiter.itemData(self.ui.IDC_cbDelimiter.currentIndex()) delim = self.ui.IDC_cbDelimiter.currentText() if delim == "tab": delim = '\t' return delim
def __init__(self, interface, settings, profiles, intersections): QDialog.__init__(self, interface.mainWindow()) self.iface = interface #output debug Log Messages: mainly for debugging matplotlib self.debug = False self.settings = settings self.profiles = profiles self.intersections = intersections # Set up the user interface from Designer. self.ui = Ui_VoGISProfilToolPlot() self.ui.setupUi(self) if self.settings.onlyHektoMode is True: self.ui.IDC_frPlot.hide() self.ui.IDC_frToolbar.hide() self.adjustSize() self.ui.IDC_chkHekto.setCheckState(Qt.Checked) self.ui.IDC_chkHekto.setEnabled(False) #self.filePath = '' if QGis.QGIS_VERSION_INT < 10900: self.filePath = QSettings().value("vogisprofiltoolmain/savepath", "").toString() else: self.filePath = QSettings().value("vogisprofiltoolmain/savepath", "") #nimmt die Locale vom System, nicht von QGIS #kein Weg gefunden, um QGIS Locale: QSettings().value("locale/userLocale") #zu initialisieren, nur um Dezimaltrenne auszulesen #QgsMessageLog.logMessage('QGIS Locale:{0}'.format(QSettings().value("locale/userLocale").toString()), 'VoGis') #!!!nl_langinfo not available on Windows!!! #http://docs.python.org/2.7/library/locale.html#locale.nl_langinfo # ... This function is not available on all systems ... #decimalDelimiter = locale.nl_langinfo(locale.RADIXCHAR) decimalDelimiter = locale.localeconv()['decimal_point'] QgsMessageLog.logMessage('delimiter:{0}'.format(decimalDelimiter), 'VoGis') idx = self.ui.IDC_cbDecimalDelimiter.findText(decimalDelimiter, Qt.MatchExactly) QgsMessageLog.logMessage('idx:{0}'.format(idx), 'VoGis') self.ui.IDC_cbDecimalDelimiter.setCurrentIndex(idx) plt_extent = PlotExtent() for profile in self.profiles: plt_extent.union(profile.getExtent()) if self.debug: QgsMessageLog.logMessage(plt_extent.toString(), 'VoGis') plt_extent.expand() self.orig_plt_xtnt = PlotExtent(plt_extent.xmin, plt_extent.ymin, plt_extent.xmax, plt_extent.ymax) self.plt_widget = self.__createMatplotlibCanvas(plt_extent) layout = self.ui.IDC_frPlot.layout() #QgsMessageLog.logMessage('layout: {0}'.format(layout), 'VoGis') layout.addWidget(self.plt_widget) # check matplotlib version solves https://github.com/BergWerkGIS/VoGIS-Profil-Tool/issues/6 if matplotlib.__version__ < 1.5: plt_toolbar = matplotlib.backends.backend_qt4agg.NavigationToolbar2QTAgg( self.plt_widget, self.ui.IDC_frPlot) else: plt_toolbar = matplotlib.backends.backend_qt4agg.NavigationToolbar2QT( self.plt_widget, self.ui.IDC_frPlot) self.ui.IDC_frToolbar.layout().addWidget(plt_toolbar) #adjust actions #QgsMessageLog.logMessage('{0}'.format(dir(lstActions[0])), 'VoGis') # for a in plt_toolbar.actions(): # QgsMessageLog.logMessage('{0}'.format(a.text()), 'VoGis') # for t in plt_toolbar.toolitems: # QgsMessageLog.logMessage('{0}'.format(t), 'VoGis') #lstActions = plt_toolbar.actions() #https://hub.qgis.org/wiki/17/Icons_20 firstaction = None for a in plt_toolbar.actions(): atxt = a.text() if atxt == 'Home': firstaction = a a.setIcon( QIcon(":/plugins/vogisprofiltoolmain/icons/home.png")) elif atxt == 'Back': a.setIcon( QIcon(":/plugins/vogisprofiltoolmain/icons/zoomlast.png")) elif atxt == 'Forward': a.setIcon( QIcon(":/plugins/vogisprofiltoolmain/icons/zoomnext.png")) elif atxt == 'Pan': a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/pan.png")) elif atxt == 'Zoom': a.setIcon( QIcon( ":/plugins/vogisprofiltoolmain/icons/zoomselect.png")) elif atxt == 'Save': a.setIcon( QIcon(":/plugins/vogisprofiltoolmain/icons/save.png")) else: plt_toolbar.removeAction(a) #insert 1:1 zoom button self.one2one = QPushButton() self.one2one.setText('1:1') self.one2one.clicked.connect(self.__one2oneClicked) #plt_toolbar.addWidget(self.one2one) #insert QLineEdit to change the exaggeration #catch updating of figure, when exaggeration QLineEdit has been updated from draw_event of figure self.draw_event_fired = False #catch closing of dialog, when enter key has been used accept exaggeration edit field self.exaggeration_edited = False #insert edit field for exaggeration self.editExaggeration = QLineEdit() self.editExaggeration.setFixedWidth(60) self.editExaggeration.setMaximumWidth(60) plt_toolbar.insertWidget(firstaction, self.editExaggeration) self.editExaggeration.editingFinished.connect( self.__exaggeration_edited) #insert identify button -> deactivate all tools #HACK: picked event gets fired before click event self.plotpicked = False plt_toolbar.insertWidget(firstaction, self.one2one) self.identify = QPushButton() self.identify.setIcon( QIcon(":/plugins/vogisprofiltoolmain/icons/identify.png")) self.identify.clicked.connect(self.__identify) plt_toolbar.insertWidget(firstaction, self.identify) #insert identify label to show name of clicked dhm self.dhmLbl = QLabel() plt_toolbar.insertWidget(firstaction, self.dhmLbl) #insert measure tool self.measuring = False self.measure_tool = QPushButton() self.measure_tool.setIcon( QIcon(":/plugins/vogisprofiltoolmain/icons/measure.png")) self.measure_tool.clicked.connect(self.__measure) plt_toolbar.insertWidget(firstaction, self.measure_tool) #show measure results self.click1 = None self.click2 = None self.click1pnt = None self.click2pnt = None self.measure_lbl = QLabel() self.measure_lbl.setText(u' ') plt_toolbar.insertWidget(firstaction, self.measure_lbl) #for less thatn 10 colors: #alternative method: http://stackoverflow.com/a/14720445 colors = [ (1.0, 0.0, 0.0, 1.0), (0.0, 1.0, 0.0, 1.0), (0.0, 0.0, 1.0, 1.0), (1.0, 1.0, 0.5, 1.0), (1.0, 0.0, 1.0, 1.0), (0.0, 1.0, 1.0, 1.0), (0.415686275, 0.807843137, 0.890196078, 1.0), (0.121568627, 0.470588235, 0.705882353, 1.0), (0.698039216, 0.874509804, 0.541176471, 1.0), (0.2, 0.62745098, 0.17254902, 1.0), (0.984313725, 0.603921569, 0.6, 1.0), (0.890196078, 0.101960784, 0.109803922, 1.0), (0.992156863, 0.749019608, 0.435294118, 1.0), (1, 0.498039216, 0, 1.0), (0.792156863, 0.698039216, 0.839215686, 1.0), (0.415686275, 0.239215686, 0.603921569, 1.0), (1, 1, 0.521568627, 1.0), ] max_profile_length = 0 #idxCol = 0 for idx, p in enumerate(self.profiles): max_profile_length = max(p.getExtent().xmax, max_profile_length) #if idxCol > len(colors) - 1: # idxCol = 0 #x, plt_segments = p.getPlotSegments() #QgsMessageLog.logMessage('x: {0}'.format(x), 'VoGis') plt_segments = p.getPlotSegments() #QgsMessageLog.logMessage('plt_segments: {0}'.format(plt_segments), 'VoGis') lineColl = LineCollection( plt_segments, linewidths=2, linestyles='solid', #colors=colors[randrange(len(colors))], #colors=colors[idxCol], colors=colors[:len(settings.mapData.rasters.selectedRasters() )], picker=True, label='LBL') #lineColl.set_array(x) #lineColl.text.set_text('line label') self.subplot.add_collection(lineColl) #idxCol += 1 #LINE STYLES: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.plot for idx, intersection in enumerate(self.intersections): color_intersection = ['b', 'g', 'r', 'c', 'm', 'y', 'k'] x_1 = intersection.from_dist x_2 = intersection.to_dist z_1 = intersection.from_z[self.settings.intersection_dhm_idx] z_2 = intersection.to_z[self.settings.intersection_dhm_idx] self.subplot.plot((x_1, x_2), (z_1, z_2), color_intersection[idx] + '--', linewidth=4, zorder=1) #http://matplotlib.org/users/annotations_guide.html#using-complex-coordinate-with-annotation self.subplot.annotate(u'{0:.2f}'.format(z_1), (x_1, z_1), xytext=(0, 30), textcoords="offset points", bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="->"), ha='center', va='bottom', rotation=90) self.subplot.annotate(u'{0:.2f}'.format(z_2), (x_2, z_2), xytext=(0, 30), textcoords="offset points", bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="->"), ha='center', va='bottom', rotation=90) #horizontale Ausspiegeling self.subplot.plot((x_1, max_profile_length), (z_1, z_1), color_intersection[idx] + ':', linewidth=4, zorder=1) #save inital view in history plt_toolbar.push_current() #select pan tool plt_toolbar.pan() self.plt_toolbar = plt_toolbar #(matplotlib.pyplot).tight_layout(True) #plt.tight_layout() #self.fig.tight_layout() QApplication.restoreOverrideCursor()
def __init__(self, interface, settings, profiles): QDialog.__init__(self, interface.mainWindow()) self.iface = interface #output debug Log Messages: mainly for debugging matplotlib self.debug = False self.settings = settings self.profiles = profiles # Set up the user interface from Designer. self.ui = Ui_VoGISProfilToolPlot() self.ui.setupUi(self) if self.settings.onlyHektoMode is True: self.ui.IDC_frPlot.hide() self.ui.IDC_frToolbar.hide() self.adjustSize() self.ui.IDC_chkHekto.setCheckState(Qt.Checked) self.ui.IDC_chkHekto.setEnabled(False) #self.filePath = '' if QGis.QGIS_VERSION_INT < 10900: self.filePath = QSettings().value("vogisprofiltoolmain/savepath", "").toString() else: self.filePath = QSettings().value("vogisprofiltoolmain/savepath", "") #nimmt die Locale vom System, nicht von QGIS #kein Weg gefunden, um QGIS Locale: QSettings().value("locale/userLocale") #zu initialisieren, nur um Dezimaltrenne auszulesen #QgsMessageLog.logMessage('QGIS Locale:{0}'.format(QSettings().value("locale/userLocale").toString()), 'VoGis') #!!!nl_langinfo not available on Windows!!! #http://docs.python.org/2.7/library/locale.html#locale.nl_langinfo # ... This function is not available on all systems ... #decimalDelimiter = locale.nl_langinfo(locale.RADIXCHAR) decimalDelimiter = locale.localeconv()['decimal_point'] QgsMessageLog.logMessage('delimiter:{0}'.format(decimalDelimiter), 'VoGis') idx = self.ui.IDC_cbDecimalDelimiter.findText(decimalDelimiter, Qt.MatchExactly) QgsMessageLog.logMessage('idx:{0}'.format(idx), 'VoGis') self.ui.IDC_cbDecimalDelimiter.setCurrentIndex(idx) pltExt = PlotExtent() for p in self.profiles: pltExt.union(p.getExtent()) #QgsMessageLog.logMessage(pltExt.toString(), 'VoGis') pltExt.expand() self.origPltExt = PlotExtent(pltExt.xmin, pltExt.ymin, pltExt.xmax, pltExt.ymax) self.pltWidget = self.__createMatplotlibCanvas(pltExt) layout = self.ui.IDC_frPlot.layout() #QgsMessageLog.logMessage('layout: {0}'.format(layout), 'VoGis') layout.addWidget(self.pltWidget) pltToolbar = matplotlib.backends.backend_qt4agg.NavigationToolbar2QTAgg(self.pltWidget, self.ui.IDC_frPlot) self.ui.IDC_frToolbar.layout().addWidget(pltToolbar) #adjust actions #QgsMessageLog.logMessage('{0}'.format(dir(lstActions[0])), 'VoGis') # for a in pltToolbar.actions(): # QgsMessageLog.logMessage('{0}'.format(a.text()), 'VoGis') # for t in pltToolbar.toolitems: # QgsMessageLog.logMessage('{0}'.format(t), 'VoGis') #lstActions = pltToolbar.actions() firstaction = None for a in pltToolbar.actions(): atxt = a.text() if atxt == 'Home': firstaction = a a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/home.png")) elif atxt == 'Back': a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/zoomlast.png")) elif atxt == 'Forward': a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/zoomnext.png")) elif atxt == 'Pan': a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/pan.png")) elif atxt == 'Zoom': a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/zoomselect.png")) elif atxt == 'Save': a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/save.png")) else: pltToolbar.removeAction(a) #insert 1:1 zoom button self.one2one = QPushButton() self.one2one.setText('1:1') self.one2one.clicked.connect(self.__one2oneClicked) #pltToolbar.addWidget(self.one2one) #insert QLineEdit to change the exaggeration #catch updating of figure, when exaggeration QLineEdit has been updated from draw_event of figure self.drawEventFired = False #catch closing of dialog, when enter key has been used accept exaggeration edit field self.exaggerationEdited = False self.editExaggeration = QLineEdit() self.editExaggeration.setFixedWidth(60) self.editExaggeration.setMaximumWidth(60) pltToolbar.insertWidget(firstaction, self.editExaggeration) self.editExaggeration.editingFinished.connect(self.__exaggerationEdited) #insert identify button -> deactivate all tools #HACK: picked event gets fired before click event self.plotpicked = False pltToolbar.insertWidget(firstaction, self.one2one) self.identify = QPushButton() self.identify.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/identify.png")) self.identify.clicked.connect(self.__identify) pltToolbar.insertWidget(firstaction, self.identify) #insert identify label to show name of clicked dhm self.dhmLbl = QLabel() pltToolbar.insertWidget(firstaction, self.dhmLbl) #measure in figure self.click1 = None self.click2 = None self.click1pnt = None self.click2pnt = None self.measureLbl = QLabel() self.measureLbl.setText(u' ') pltToolbar.insertWidget(firstaction, self.measureLbl) #for less thatn 10 colors: #alternative method: http://stackoverflow.com/a/14720445 colors = [(1.0, 0.0, 0.0, 1.0), (0.0, 1.0, 0.0, 1.0), (0.0, 0.0, 1.0, 1.0), (1.0, 1.0, 0.5, 1.0), (1.0, 0.0, 1.0, 1.0), (0.0, 1.0, 1.0, 1.0), (0.415686275, 0.807843137, 0.890196078, 1.0), (0.121568627, 0.470588235, 0.705882353, 1.0), (0.698039216, 0.874509804, 0.541176471, 1.0), (0.2, 0.62745098, 0.17254902, 1.0), (0.984313725, 0.603921569, 0.6, 1.0), (0.890196078, 0.101960784, 0.109803922, 1.0), (0.992156863, 0.749019608, 0.435294118, 1.0), (1, 0.498039216, 0, 1.0), (0.792156863, 0.698039216, 0.839215686, 1.0), (0.415686275, 0.239215686, 0.603921569, 1.0), (1, 1, 0.521568627, 1.0), ] #idxCol = 0 for idx, p in enumerate(self.profiles): #if idxCol > len(colors) - 1: # idxCol = 0 #x, pltSegs = p.getPlotSegments() #QgsMessageLog.logMessage('x: {0}'.format(x), 'VoGis') pltSegs = p.getPlotSegments() #QgsMessageLog.logMessage('pltSegs: {0}'.format(pltSegs), 'VoGis') lineColl = LineCollection(pltSegs, linewidths=2, linestyles='solid', #colors=colors[randrange(len(colors))], #colors=colors[idxCol], colors=colors[:len(settings.mapData.rasters.selectedRasters())], picker=True, label='LBL' ) #lineColl.set_array(x) #lineColl.text.set_text('line label') self.subplot.add_collection(lineColl) #idxCol += 1 #save inital view in history pltToolbar.push_current() #select pan tool pltToolbar.pan() self.pltToolbar = pltToolbar #(matplotlib.pyplot).tight_layout(True) #plt.tight_layout() #self.fig.tight_layout() QApplication.restoreOverrideCursor()
class VoGISProfilToolPlotDialog(QDialog): def __init__(self, interface, settings, profiles): QDialog.__init__(self, interface.mainWindow()) self.iface = interface #output debug Log Messages: mainly for debugging matplotlib self.debug = False self.settings = settings self.profiles = profiles # Set up the user interface from Designer. self.ui = Ui_VoGISProfilToolPlot() self.ui.setupUi(self) if self.settings.onlyHektoMode is True: self.ui.IDC_frPlot.hide() self.ui.IDC_frToolbar.hide() self.adjustSize() self.ui.IDC_chkHekto.setCheckState(Qt.Checked) self.ui.IDC_chkHekto.setEnabled(False) #self.filePath = '' if QGis.QGIS_VERSION_INT < 10900: self.filePath = QSettings().value("vogisprofiltoolmain/savepath", "").toString() else: self.filePath = QSettings().value("vogisprofiltoolmain/savepath", "") #nimmt die Locale vom System, nicht von QGIS #kein Weg gefunden, um QGIS Locale: QSettings().value("locale/userLocale") #zu initialisieren, nur um Dezimaltrenne auszulesen #QgsMessageLog.logMessage('QGIS Locale:{0}'.format(QSettings().value("locale/userLocale").toString()), 'VoGis') #!!!nl_langinfo not available on Windows!!! #http://docs.python.org/2.7/library/locale.html#locale.nl_langinfo # ... This function is not available on all systems ... #decimalDelimiter = locale.nl_langinfo(locale.RADIXCHAR) decimalDelimiter = locale.localeconv()['decimal_point'] QgsMessageLog.logMessage('delimiter:{0}'.format(decimalDelimiter), 'VoGis') idx = self.ui.IDC_cbDecimalDelimiter.findText(decimalDelimiter, Qt.MatchExactly) QgsMessageLog.logMessage('idx:{0}'.format(idx), 'VoGis') self.ui.IDC_cbDecimalDelimiter.setCurrentIndex(idx) pltExt = PlotExtent() for p in self.profiles: pltExt.union(p.getExtent()) #QgsMessageLog.logMessage(pltExt.toString(), 'VoGis') pltExt.expand() self.origPltExt = PlotExtent(pltExt.xmin, pltExt.ymin, pltExt.xmax, pltExt.ymax) self.pltWidget = self.__createMatplotlibCanvas(pltExt) layout = self.ui.IDC_frPlot.layout() #QgsMessageLog.logMessage('layout: {0}'.format(layout), 'VoGis') layout.addWidget(self.pltWidget) pltToolbar = matplotlib.backends.backend_qt4agg.NavigationToolbar2QTAgg(self.pltWidget, self.ui.IDC_frPlot) self.ui.IDC_frToolbar.layout().addWidget(pltToolbar) #adjust actions #QgsMessageLog.logMessage('{0}'.format(dir(lstActions[0])), 'VoGis') # for a in pltToolbar.actions(): # QgsMessageLog.logMessage('{0}'.format(a.text()), 'VoGis') # for t in pltToolbar.toolitems: # QgsMessageLog.logMessage('{0}'.format(t), 'VoGis') #lstActions = pltToolbar.actions() firstaction = None for a in pltToolbar.actions(): atxt = a.text() if atxt == 'Home': firstaction = a a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/home.png")) elif atxt == 'Back': a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/zoomlast.png")) elif atxt == 'Forward': a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/zoomnext.png")) elif atxt == 'Pan': a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/pan.png")) elif atxt == 'Zoom': a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/zoomselect.png")) elif atxt == 'Save': a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/save.png")) else: pltToolbar.removeAction(a) #insert 1:1 zoom button self.one2one = QPushButton() self.one2one.setText('1:1') self.one2one.clicked.connect(self.__one2oneClicked) #pltToolbar.addWidget(self.one2one) #insert QLineEdit to change the exaggeration #catch updating of figure, when exaggeration QLineEdit has been updated from draw_event of figure self.drawEventFired = False #catch closing of dialog, when enter key has been used accept exaggeration edit field self.exaggerationEdited = False self.editExaggeration = QLineEdit() self.editExaggeration.setFixedWidth(60) self.editExaggeration.setMaximumWidth(60) pltToolbar.insertWidget(firstaction, self.editExaggeration) self.editExaggeration.editingFinished.connect(self.__exaggerationEdited) #insert identify button -> deactivate all tools #HACK: picked event gets fired before click event self.plotpicked = False pltToolbar.insertWidget(firstaction, self.one2one) self.identify = QPushButton() self.identify.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/identify.png")) self.identify.clicked.connect(self.__identify) pltToolbar.insertWidget(firstaction, self.identify) #insert identify label to show name of clicked dhm self.dhmLbl = QLabel() pltToolbar.insertWidget(firstaction, self.dhmLbl) #measure in figure self.click1 = None self.click2 = None self.click1pnt = None self.click2pnt = None self.measureLbl = QLabel() self.measureLbl.setText(u' ') pltToolbar.insertWidget(firstaction, self.measureLbl) #for less thatn 10 colors: #alternative method: http://stackoverflow.com/a/14720445 colors = [(1.0, 0.0, 0.0, 1.0), (0.0, 1.0, 0.0, 1.0), (0.0, 0.0, 1.0, 1.0), (1.0, 1.0, 0.5, 1.0), (1.0, 0.0, 1.0, 1.0), (0.0, 1.0, 1.0, 1.0), (0.415686275, 0.807843137, 0.890196078, 1.0), (0.121568627, 0.470588235, 0.705882353, 1.0), (0.698039216, 0.874509804, 0.541176471, 1.0), (0.2, 0.62745098, 0.17254902, 1.0), (0.984313725, 0.603921569, 0.6, 1.0), (0.890196078, 0.101960784, 0.109803922, 1.0), (0.992156863, 0.749019608, 0.435294118, 1.0), (1, 0.498039216, 0, 1.0), (0.792156863, 0.698039216, 0.839215686, 1.0), (0.415686275, 0.239215686, 0.603921569, 1.0), (1, 1, 0.521568627, 1.0), ] #idxCol = 0 for idx, p in enumerate(self.profiles): #if idxCol > len(colors) - 1: # idxCol = 0 #x, pltSegs = p.getPlotSegments() #QgsMessageLog.logMessage('x: {0}'.format(x), 'VoGis') pltSegs = p.getPlotSegments() #QgsMessageLog.logMessage('pltSegs: {0}'.format(pltSegs), 'VoGis') lineColl = LineCollection(pltSegs, linewidths=2, linestyles='solid', #colors=colors[randrange(len(colors))], #colors=colors[idxCol], colors=colors[:len(settings.mapData.rasters.selectedRasters())], picker=True, label='LBL' ) #lineColl.set_array(x) #lineColl.text.set_text('line label') self.subplot.add_collection(lineColl) #idxCol += 1 #save inital view in history pltToolbar.push_current() #select pan tool pltToolbar.pan() self.pltToolbar = pltToolbar #(matplotlib.pyplot).tight_layout(True) #plt.tight_layout() #self.fig.tight_layout() QApplication.restoreOverrideCursor() def accept(self): #QMessageBox.warning(self.iface.mainWindow(), "VoGIS-Profiltool", "ACCEPTED") QgsMessageLog.logMessage('accept: {0}'.format(self.exaggerationEdited), 'VoGis') if self.exaggerationEdited is True: self.exaggerationEdited = False return QDialog.accept(self) def reject(self): #QMessageBox.warning(self.iface.mainWindow(), "VoGIS-Profiltool", "REJECTED") QgsMessageLog.logMessage('reject: {0}'.format(self.exaggerationEdited), 'VoGis') if self.exaggerationEdited is True: self.exaggerationEdited = False return QDialog.reject(self) def exportShpPnt(self): self.__exportShp(True) def exportShpLine(self): self.__exportShp(False) def __exportShp(self, asPnt): u = Util(self.iface) if asPnt is True: caption = QApplication.translate('code', 'Punkt Shapefile exportieren', None, QApplication.UnicodeUTF8) else: caption = QApplication.translate('code', 'Linien Shapefile exportieren', None, QApplication.UnicodeUTF8) fileName = u.getFileName(caption, [["shp", "shp"]], self.filePath) if fileName == '': return fInfo = QFileInfo(fileName) self.filePath = fInfo.path() QSettings().setValue("vogisprofiltoolmain/savepath", self.filePath) expShp = ExportShape(self.iface, (self.ui.IDC_chkHekto.checkState() == Qt.Checked), (self.ui.IDC_chkLineAttributes.checkState() == Qt.Checked), self.__getDelimiter(), self.__getDecimalDelimiter(), fileName, self.settings, self.profiles ) if asPnt is False: expShp.exportLine() else: expShp.exportPoint() def exportCsvXls(self): u = Util(self.iface) caption = QApplication.translate('code', 'CSV-datei exportieren', None, QApplication.UnicodeUTF8) fileName = u.getFileName(caption, [["csv", "csv"]], self.filePath) if fileName == '': return fInfo = QFileInfo(fileName) self.filePath = fInfo.path() QSettings().setValue("vogisprofiltoolmain/savepath", self.filePath) hekto = (self.ui.IDC_chkHekto.checkState() == Qt.Checked) attribs = (self.ui.IDC_chkLineAttributes.checkState() == Qt.Checked) delimiter = ';' decimalDelimiter = self.__getDecimalDelimiter() txt = open(fileName, 'w') txt.write(self.profiles[0].writeHeader(self.settings.mapData.rasters.selectedRasters(), hekto, attribs, delimiter)) for p in self.profiles: #txt.write('=====Profil {0}======{1}'.format(p.id, os.linesep)) #txt.write('Segments:{0}{1}'.format(len(p.segments), os.linesep)) #for s in p.segments: # txt.write('Vertices:{0}{1}'.format(len(s.vertices), os.linesep)) txt.write(p.toString(hekto, attribs, delimiter, decimalDelimiter )) def exportTxt(self): delimiter = self.__getDelimiter() decimalDelimiter = self.__getDecimalDelimiter() if delimiter == decimalDelimiter: msg = QApplication.translate('code', 'Gleiches Dezimal- und Spaltentrennzeichen gewählt!', None, QApplication.UnicodeUTF8) QMessageBox.warning(self.iface.mainWindow(), 'VoGIS-Profiltool', msg) return u = Util(self.iface) caption = QApplication.translate('code', 'Textdatei exportieren', None, QApplication.UnicodeUTF8) fileName = u.getFileName(caption, [["txt", "txt"]], self.filePath) if fileName == '': return fInfo = QFileInfo(fileName) self.filePath = fInfo.path() QSettings().setValue("vogisprofiltoolmain/savepath", self.filePath) hekto = (self.ui.IDC_chkHekto.checkState() == Qt.Checked) attribs = (self.ui.IDC_chkLineAttributes.checkState() == Qt.Checked) txt = open(fileName, 'w') txt.write(self.profiles[0].writeHeader(self.settings.mapData.rasters.selectedRasters(), hekto, attribs, delimiter)) for p in self.profiles: #txt.write('=====Profil {0}======{1}'.format(p.id, os.linesep)) #txt.write('Segments:{0}{1}'.format(len(p.segments), os.linesep)) #for s in p.segments: # txt.write('Vertices:{0}{1}'.format(len(s.vertices), os.linesep)) txt.write(p.toString(hekto, attribs, delimiter, decimalDelimiter )) txt.close() def exportAutoCadTxt(self): u = Util(self.iface) caption = QApplication.translate('code', 'AutoCad Textdatei exportieren', None, QApplication.UnicodeUTF8) fileName = u.getFileName(caption, [["txt", "txt"]], self.filePath) if fileName == '': return fInfo = QFileInfo(fileName) self.filePath = fInfo.path() QSettings().setValue("vogisprofiltoolmain/savepath", self.filePath) txt = open(fileName, 'w') for p in self.profiles: txt.write(p.toACadTxt(' ', '.')) txt.close() def exportDxfPnt(self): self.__exportDxf(True) def exportDxfLine(self): self.__exportDxf(False) def __exportDxf(self, asPnt): u = Util(self.iface) caption = QApplication.translate('code', 'DXF exportieren', None, QApplication.UnicodeUTF8) fileName = u.getFileName(caption, [["dxf", "dxf"]], self.filePath) if fileName == '': return fInfo = QFileInfo(fileName) self.filePath = fInfo.path() QSettings().setValue("vogisprofiltoolmain/savepath", self.filePath) exDxf = ExportDxf(self.iface, fileName, self.settings, self.profiles) if asPnt is True: exDxf.exportPoint() else: exDxf.exportLine() def __identify(self): #dirty hack: deselect all tools #selecting a tool twice deselects it self.pltToolbar.pan() self.pltToolbar.zoom() self.pltToolbar.zoom() def __figureDrawn(self, event): if self.debug: QgsMessageLog.logMessage('__figureDrawn, drawEventFired:{0} exaggerationEdited: {1}'.format(self.drawEventFired, self.exaggerationEdited), 'VoGis') #draw event seems to get fired twice????? if self.drawEventFired == True: return self.drawEventFired = True axes = self.pltWidget.figure.get_axes()[0] xlim = axes.get_xlim() ylim = axes.get_ylim() if self.debug: QgsMessageLog.logMessage('__figureDrawn: xlim:{0} ylim:{1}'.format(xlim, ylim), 'VoGis') dpi = self.pltWidget.figure.get_dpi() figWidth = self.pltWidget.figure.get_figwidth() * dpi figHeight = self.pltWidget.figure.get_figheight() * dpi #bbox = axes.get_window_extent().transformed(self.pltWidget.figure.dpi_scale_trans.inverted()) #figWidth, figHeight = bbox.width * dpi, bbox.height * dpi figWidth *= (TOP_MARGIN - BOTTOM_MARGIN) figHeight *= (RIGHT_MARGIN - LEFT_MARGIN) deltaX = xlim[1] - xlim[0] deltaY = ylim[1] - ylim[0] ratio = (deltaX / figWidth) / (deltaY / figHeight) ratio = floor(ratio * 10) / 10 if self.debug: QgsMessageLog.logMessage('__figureDrawn: figWidth:{0} figHeight:{1} dpi:{2} deltaX:{3} deltaY:{4}, ratio:{5}'.format(figWidth, figHeight, dpi, deltaX, deltaY, ratio), 'VoGis') if self.debug: QgsMessageLog.logMessage('__figureDrawn: axes.get_data_ratio:{0}'.format(axes.get_data_ratio()), 'VoGis') #self.editExaggeration.setText('{0:.1f}'.format(ratio)) self.editExaggeration.setText('{0:.1f}'.format(axes.get_aspect())) self.drawEventFired = False def __exaggerationEdited(self, *args): if self.debug: QgsMessageLog.logMessage('__exaggerationEdited, exaggerationEdited:{0} drawEventFired: {1}'.format(self.exaggerationEdited, self.drawEventFired), 'VoGis') #this event handler seems to get called twice???? if self.drawEventFired == True: return if self.exaggerationEdited == True: return self.exaggerationEdited = True #QgsMessageLog.logMessage('__exaggerationEdited: {0}'.format(self.exaggerationEdited), 'VoGis') ut = Util(self.iface) txtExa = QApplication.translate('code', 'Überhöhung', None, QApplication.UnicodeUTF8) if ut.isFloat(self.editExaggeration.text(), txtExa) is False: return False #clear focus of lineedit, otherwise it gets called even when the user wants to close the dialog self.editExaggeration.clearFocus() exa = float(self.editExaggeration.text().replace(',', '.')) self.__adjustAxes(exa) def __one2oneClicked(self): if self.debug: QgsMessageLog.logMessage('1:1 clicked', 'VoGis') #QgsMessageLog.logMessage('axes:{0}'.format(self.pltWidget.figure.get_axes()), 'VoGis') self.__adjustAxes(1.0) def __adjustAxes(self, exaggeration): exaggeration = floor(exaggeration * 10) / 10 axes = self.pltWidget.figure.get_axes()[0] #axes.set_aspect(exaggeration) #axes.set_autoscalex_on(False) #axes.set_autoscaley_on(True) if self.debug: QgsMessageLog.logMessage('__adjustAxes, get_aspect:{0}'.format(axes.get_aspect()), 'VoGis') QgsMessageLog.logMessage('__adjustAxes, get_position:{0}'.format(axes.get_position()), 'VoGis') QgsMessageLog.logMessage('__adjustAxes, xBound:{0} xlim:{1}'.format(axes.get_xbound(),axes.get_xlim()), 'VoGis') QgsMessageLog.logMessage('__adjustAxes, yBound:{0} ylim:{1}'.format(axes.get_ybound(),axes.get_ylim()), 'VoGis') oldexa = axes.get_aspect() ratioexa = oldexa / exaggeration ylim = axes.get_ylim() deltaYold = ylim[1] - ylim[0] deltaYnew = deltaYold * ratioexa centerY = ylim[0] + (deltaYold / 2) axes.set_ylim(centerY - deltaYnew/2,centerY + deltaYnew/2) axes.set_aspect(exaggeration, 'datalim', 'C') self.pltWidget.draw() if self.debug: QgsMessageLog.logMessage('__adjustAxes, get_aspect:{0}'.format(axes.get_aspect()), 'VoGis') QgsMessageLog.logMessage('__adjustAxes, get_position:{0}'.format(axes.get_position()), 'VoGis') QgsMessageLog.logMessage('__adjustAxes, xBound:{0} xlim:{1}'.format(axes.get_xbound(),axes.get_xlim()), 'VoGis') QgsMessageLog.logMessage('__adjustAxes, yBound:{0} ylim:{1}'.format(axes.get_ybound(),axes.get_ylim()), 'VoGis') # if self.debug: QgsMessageLog.logMessage('__adjustAxes, exaggeration: {0}'.format(exaggeration), 'VoGis') # dpi = self.pltWidget.figure.get_dpi() # figWidth = self.pltWidget.figure.get_figwidth() * dpi # figHeight = self.pltWidget.figure.get_figheight() * dpi # axes = self.pltWidget.figure.get_axes()[0] # if self.debug: QgsMessageLog.logMessage('__adjustAxes, imgextextent:{0}'.format(axes.get_aspect()), 'VoGis') # #bbox = axes.get_window_extent().transformed(self.pltWidget.figure.dpi_scale_trans.inverted()) # #figWidth, figHeight = bbox.width * dpi, bbox.height * dpi # figWidth *= (TOP_MARGIN - BOTTOM_MARGIN) # figHeight *= (RIGHT_MARGIN - LEFT_MARGIN) # if self.debug: QgsMessageLog.logMessage('__adjustAxes, dataExtent:{0}'.format(self.origPltExt.toString()), 'VoGis') # if self.debug: QgsMessageLog.logMessage('__adjustAxes, fig size:{0}/{1}'.format(figWidth, figHeight), 'VoGis') # mPerPixH = self.origPltExt.xmax / figWidth # deltaVnew = figHeight * mPerPixH / exaggeration # newYmax = self.origPltExt.ymin + deltaVnew # #QgsMessageLog.logMessage('mPerPixH:{0} deltaV:{1} deltaVnew:{2} newYmax:{3}'.format(mPerPixH, deltaV, deltaVnew, newYmax), 'VoGis') # #self.pltWidget.figure.get_axes()[0].set_xbound(self.origPltExt.xmin, self.origPltExt.xmax) # #self.pltWidget.figure.get_axes()[0].set_ybound(self.origPltExt.ymin, newYmax) # self.pltWidget.figure.get_axes()[0].set_xlim((self.origPltExt.xmin, self.origPltExt.xmax)) # self.pltWidget.figure.get_axes()[0].set_ylim((self.origPltExt.ymin, newYmax)) # self.pltWidget.figure.get_axes()[0].redraw_in_frame() # self.pltWidget.draw() def __plotPicked(self, event): self.plotpicked = True if self.debug: QgsMessageLog.logMessage('__plotPicked', 'VoGis') #QgsMessageLog.logMessage('artist:{0}'.format(type(event.artist)), 'VoGis') self.dhmLbl.setText(' ? ') if isinstance(event.artist, Line2D): QgsMessageLog.logMessage('Line2D', 'VoGis') line = event.artist xdata = line.get_xdata() ydata = line.get_ydata() ind = event.ind QgsMessageLog.logMessage('{0}: {1} {2}'.format(ind, xdata, ydata), 'VoGis') QgsMessageLog.logMessage(help(line), 'VoGis') elif isinstance(event.artist, LineCollection): QgsMessageLog.logMessage('LineCollection', 'VoGis') r = self.settings.mapData.rasters.selectedRasters()[event.ind[0]] QgsMessageLog.logMessage('Raster: {0}'.format(r.name), 'VoGis') #self.pltWidget.figure.suptitle(r.name) self.dhmLbl.setText(u' [' + r.name + '] ') #QgsMessageLog.logMessage('{0}'.format(event), 'VoGis') #QgsMessageLog.logMessage('{0}'.format(dir(event)), 'VoGis') #QgsMessageLog.logMessage('{0}'.format(event.artist), 'VoGis') #QgsMessageLog.logMessage('{0}'.format(dir(event.artist)), 'VoGis') #QgsMessageLog.logMessage('{0}'.format(event.canvas), 'VoGis') #QgsMessageLog.logMessage('{0}'.format(dir(event.canvas)), 'VoGis') #QgsMessageLog.logMessage('{0}'.format(event.guiEvent), 'VoGis') #QgsMessageLog.logMessage('{0}'.format(dir(event.guiEvent)), 'VoGis') #QgsMessageLog.logMessage('{0}'.format(event.ind), 'VoGis') #QgsMessageLog.logMessage('{0}'.format(dir(event.ind)), 'VoGis') #QgsMessageLog.logMessage('{0}'.format(event.mouseevent), 'VoGis') #QgsMessageLog.logMessage('{0}'.format(dir(event.mouseevent)), 'VoGis') #QgsMessageLog.logMessage('{0}'.format(event.name), 'VoGis') #QgsMessageLog.logMessage('{0}'.format(dir(event.name)), 'VoGis') #lColl = event.artist #QgsMessageLog.logMessage('{0}'.format(lColl.get_array()), 'VoGis') #QgsMessageLog.logMessage('{0}'.format(lColl.get_paths()[event.ind[0]]), 'VoGis') #segs = lColl.get_segments() #l = segs[ind] #QgsMessageLog.logMessage('{0}'.format(l.get_data(True)), 'VoGis') #QgsMessageLog.logMessage('{0}'.format(l.get_data()), 'VoGis') else: QgsMessageLog.logMessage('no Line2D or LineCollection', 'VoGis') def __buttonPressed(self, event): if self.debug: QgsMessageLog.logMessage('__buttonPressed', 'VoGis') if self.plotpicked is False: self.dhmLbl.setText(' ? ') if self.debug: QgsMessageLog.logMessage('{0}'.format(dir(event)), 'VoGis') QgsMessageLog.logMessage('{0}'.format(dir(event.xdata)), 'VoGis') QgsMessageLog.logMessage('{0}'.format(dir(event.ydata)), 'VoGis') QgsMessageLog.logMessage( 'x:{0} y:{1} xdata:{2} ydata:{3} click1:{4} click2:{5} click1pnt:{6} click2pnt:{7}'.format( event.x, event.y, event.xdata, event.ydata, self.click1, self.click2,self.click1pnt, self.click2pnt), 'VoGis') if event.xdata is None or event.ydata is None: return if self.click1 is None: self.click1 = [event.xdata, event.ydata] self.click2 = None #self.measureLbl.setText(u'') self.measureLbl.setText(u' x:{0:.1f} y:{1:.1f} '.format(event.xdata, event.ydata)) if not self.click1pnt is None: p = self.click1pnt.pop(0); p.remove() del p self.click1pnt = None if not self.click2pnt is None: p = self.click2pnt.pop(0); p.remove() del p self.click2pnt = None self.click1pnt = self.subplot.plot(event.xdata, event.ydata, 'ro') elif self.click2 is None: self.click2 = [event.xdata, event.ydata] #deltaX = abs(self.click2[0] - self.click1[0]) #deltaY = abs(self.click2[1] - self.click1[1]) #dist = ((deltaX ** 2) + (deltaY ** 2)) ** 0.5 #self.measureLbl.setText(u' dist: {0:.1f} '.format(dist)) deltaX = self.click2[0] - self.click1[0] deltaY = self.click2[1] - self.click1[1] dist = sqrt(pow(deltaX, 2) + pow(deltaY, 2)) self.measureLbl.setText(u' dx:{0:.1f} dy:{1:.1f} d:{2:.1f}'.format(deltaX, deltaY, dist)) self.click1 = None if not self.click2pnt is None: p = self.click2pnt.pop(0); p.remove() del p self.click2pnt = None self.click2pnt = self.subplot.plot(event.xdata, event.ydata, 'go') #refresh plot to show points, when identify tool active #if self.debug: QgsMessageLog.logMessage('__buttonPressed: active: {0}'.format(self.pltToolbar._active), 'VoGis') #if self.plotpicked is True: if self.pltToolbar._active is None: self.pltWidget.draw() self.plotpicked = False def __createMatplotlibCanvas(self, pltExt): fig = Figure((1, 1), #tight_layout=True, linewidth=0.0, subplotpars=matplotlib.figure.SubplotParams(left=0, bottom=0, right=1, top=1, wspace=0, hspace=0 ) ) #fig.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=None, hspace=None) #fig = Figure((24, 24), tight_layout=True) # try: # fig = Figure(tight_layout=True) # except: # #tight layout not available # fig = Figure() #fig = plt.figure() #fig.set_tight_layout(True) #font = {'family': 'arial', 'weight': 'normal', 'size': 12} #rc('font', **font) rect = fig.patch rect.set_facecolor((0.9, 0.9, 0.9)) # self.subplot = fig.add_axes( # #(0.08, 0.15, 0.92, 0.82), # (0.0, 0.0, 1.0, 1.0), # anchor='SW', # adjustable='box-forced' # ) #left bottom right top self.subplot = fig.add_axes( (LEFT_MARGIN, BOTTOM_MARGIN, RIGHT_MARGIN, TOP_MARGIN), adjustable='datalim', aspect=1 ) #self.subplot.plot.tight_layout(True) self.subplot.set_xbound(pltExt.xmin, pltExt.xmax) self.subplot.set_ybound(pltExt.ymin, pltExt.ymax) self.__setupAxes(self.subplot) #fig.tight_layout() canvas = FigureCanvasQTAgg(fig) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) canvas.setSizePolicy(sizePolicy) canvas.mpl_connect('pick_event', self.__plotPicked) canvas.mpl_connect('draw_event', self.__figureDrawn) canvas.mpl_connect('button_press_event', self.__buttonPressed) return canvas def __setupAxes(self, axe1): axe1.grid() axe1.ticklabel_format(style='plain', useOffset=False) axe1.tick_params(axis="both", which="major", direction="out", length=10, width=1, bottom=True, top=False, left=True, right=False ) axe1.minorticks_on() axe1.tick_params(axis="both", which="minor", direction="out", length=5, width=1, bottom=True, top=False, left=True, right=False ) def __getDecimalDelimiter(self): #delim = self.ui.IDC_cbDecimalDelimiter.itemData(self.ui.IDC_cbDecimalDelimiter.currentIndex()) delim = self.ui.IDC_cbDecimalDelimiter.currentText() #QgsMessageLog.logMessage('delim:' + str(delim), 'VoGis') return delim def __getDelimiter(self): #delim = self.ui.IDC_cbDelimiter.itemData(self.ui.IDC_cbDelimiter.currentIndex()) delim = self.ui.IDC_cbDelimiter.currentText() if delim == "tab": delim = '\t' return delim
def __init__(self, interface, settings, profiles, intersections): QDialog.__init__(self, interface.mainWindow()) self.iface = interface #output debug Log Messages: mainly for debugging matplotlib self.debug = False self.settings = settings self.profiles = profiles self.intersections = intersections # Set up the user interface from Designer. self.ui = Ui_VoGISProfilToolPlot() self.ui.setupUi(self) if self.settings.onlyHektoMode is True: self.ui.IDC_frPlot.hide() self.ui.IDC_frToolbar.hide() self.adjustSize() self.ui.IDC_chkHekto.setCheckState(Qt.Checked) self.ui.IDC_chkHekto.setEnabled(False) #self.filePath = '' if QGis.QGIS_VERSION_INT < 10900: self.filePath = QSettings().value("vogisprofiltoolmain/savepath", "").toString() else: self.filePath = QSettings().value("vogisprofiltoolmain/savepath", "") #nimmt die Locale vom System, nicht von QGIS #kein Weg gefunden, um QGIS Locale: QSettings().value("locale/userLocale") #zu initialisieren, nur um Dezimaltrenne auszulesen #QgsMessageLog.logMessage('QGIS Locale:{0}'.format(QSettings().value("locale/userLocale").toString()), 'VoGis') #!!!nl_langinfo not available on Windows!!! #http://docs.python.org/2.7/library/locale.html#locale.nl_langinfo # ... This function is not available on all systems ... #decimalDelimiter = locale.nl_langinfo(locale.RADIXCHAR) decimalDelimiter = locale.localeconv()['decimal_point'] QgsMessageLog.logMessage('delimiter:{0}'.format(decimalDelimiter), 'VoGis') idx = self.ui.IDC_cbDecimalDelimiter.findText(decimalDelimiter, Qt.MatchExactly) QgsMessageLog.logMessage('idx:{0}'.format(idx), 'VoGis') self.ui.IDC_cbDecimalDelimiter.setCurrentIndex(idx) plt_extent = PlotExtent() for profile in self.profiles: plt_extent.union(profile.getExtent()) if self.debug: QgsMessageLog.logMessage(plt_extent.toString(), 'VoGis') plt_extent.expand() self.orig_plt_xtnt = PlotExtent(plt_extent.xmin, plt_extent.ymin, plt_extent.xmax, plt_extent.ymax) self.plt_widget = self.__createMatplotlibCanvas(plt_extent) layout = self.ui.IDC_frPlot.layout() #QgsMessageLog.logMessage('layout: {0}'.format(layout), 'VoGis') layout.addWidget(self.plt_widget) # check matplotlib version solves https://github.com/BergWerkGIS/VoGIS-Profil-Tool/issues/6 if matplotlib.__version__ < 1.5 : plt_toolbar = matplotlib.backends.backend_qt4agg.NavigationToolbar2QTAgg(self.plt_widget, self.ui.IDC_frPlot) else : plt_toolbar = matplotlib.backends.backend_qt4agg.NavigationToolbar2QT(self.plt_widget, self.ui.IDC_frPlot) self.ui.IDC_frToolbar.layout().addWidget(plt_toolbar) #adjust actions #QgsMessageLog.logMessage('{0}'.format(dir(lstActions[0])), 'VoGis') # for a in plt_toolbar.actions(): # QgsMessageLog.logMessage('{0}'.format(a.text()), 'VoGis') # for t in plt_toolbar.toolitems: # QgsMessageLog.logMessage('{0}'.format(t), 'VoGis') #lstActions = plt_toolbar.actions() #https://hub.qgis.org/wiki/17/Icons_20 firstaction = None for a in plt_toolbar.actions(): atxt = a.text() if atxt == 'Home': firstaction = a a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/home.png")) elif atxt == 'Back': a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/zoomlast.png")) elif atxt == 'Forward': a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/zoomnext.png")) elif atxt == 'Pan': a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/pan.png")) elif atxt == 'Zoom': a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/zoomselect.png")) elif atxt == 'Save': a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/save.png")) else: plt_toolbar.removeAction(a) #insert 1:1 zoom button self.one2one = QPushButton() self.one2one.setText('1:1') self.one2one.clicked.connect(self.__one2oneClicked) #plt_toolbar.addWidget(self.one2one) #insert QLineEdit to change the exaggeration #catch updating of figure, when exaggeration QLineEdit has been updated from draw_event of figure self.draw_event_fired = False #catch closing of dialog, when enter key has been used accept exaggeration edit field self.exaggeration_edited = False #insert edit field for exaggeration self.editExaggeration = QLineEdit() self.editExaggeration.setFixedWidth(60) self.editExaggeration.setMaximumWidth(60) plt_toolbar.insertWidget(firstaction, self.editExaggeration) self.editExaggeration.editingFinished.connect(self.__exaggeration_edited) #insert identify button -> deactivate all tools #HACK: picked event gets fired before click event self.plotpicked = False plt_toolbar.insertWidget(firstaction, self.one2one) self.identify = QPushButton() self.identify.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/identify.png")) self.identify.clicked.connect(self.__identify) plt_toolbar.insertWidget(firstaction, self.identify) #insert identify label to show name of clicked dhm self.dhmLbl = QLabel() plt_toolbar.insertWidget(firstaction, self.dhmLbl) #insert measure tool self.measuring = False self.measure_tool = QPushButton() self.measure_tool.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/measure.png")) self.measure_tool.clicked.connect(self.__measure) plt_toolbar.insertWidget(firstaction, self.measure_tool) #show measure results self.click1 = None self.click2 = None self.click1pnt = None self.click2pnt = None self.measure_lbl = QLabel() self.measure_lbl.setText(u' ') plt_toolbar.insertWidget(firstaction, self.measure_lbl) #for less thatn 10 colors: #alternative method: http://stackoverflow.com/a/14720445 colors = [(1.0, 0.0, 0.0, 1.0), (0.0, 1.0, 0.0, 1.0), (0.0, 0.0, 1.0, 1.0), (1.0, 1.0, 0.5, 1.0), (1.0, 0.0, 1.0, 1.0), (0.0, 1.0, 1.0, 1.0), (0.415686275, 0.807843137, 0.890196078, 1.0), (0.121568627, 0.470588235, 0.705882353, 1.0), (0.698039216, 0.874509804, 0.541176471, 1.0), (0.2, 0.62745098, 0.17254902, 1.0), (0.984313725, 0.603921569, 0.6, 1.0), (0.890196078, 0.101960784, 0.109803922, 1.0), (0.992156863, 0.749019608, 0.435294118, 1.0), (1, 0.498039216, 0, 1.0), (0.792156863, 0.698039216, 0.839215686, 1.0), (0.415686275, 0.239215686, 0.603921569, 1.0), (1, 1, 0.521568627, 1.0), ] max_profile_length = 0 #idxCol = 0 for idx, p in enumerate(self.profiles): max_profile_length = max(p.getExtent().xmax, max_profile_length) #if idxCol > len(colors) - 1: # idxCol = 0 #x, plt_segments = p.getPlotSegments() #QgsMessageLog.logMessage('x: {0}'.format(x), 'VoGis') plt_segments = p.getPlotSegments() #QgsMessageLog.logMessage('plt_segments: {0}'.format(plt_segments), 'VoGis') lineColl = LineCollection(plt_segments, linewidths=2, linestyles='solid', #colors=colors[randrange(len(colors))], #colors=colors[idxCol], colors=colors[:len(settings.mapData.rasters.selectedRasters())], picker=True, label='LBL' ) #lineColl.set_array(x) #lineColl.text.set_text('line label') self.subplot.add_collection(lineColl) #idxCol += 1 #LINE STYLES: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.plot for idx, intersection in enumerate(self.intersections): color_intersection = ['b', 'g', 'r', 'c', 'm', 'y', 'k'] x_1 = intersection.from_dist x_2 = intersection.to_dist z_1 = intersection.from_z[self.settings.intersection_dhm_idx] z_2 = intersection.to_z[self.settings.intersection_dhm_idx] self.subplot.plot( (x_1, x_2), (z_1, z_2), color_intersection[idx] + '--', linewidth=4, zorder=1 ) #http://matplotlib.org/users/annotations_guide.html#using-complex-coordinate-with-annotation self.subplot.annotate(u'{0:.2f}'.format(z_1), (x_1, z_1), xytext=(0, 30), textcoords="offset points", bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="->"), ha='center', va='bottom', rotation=90) self.subplot.annotate(u'{0:.2f}'.format(z_2), (x_2, z_2), xytext=(0, 30), textcoords="offset points", bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="->"), ha='center', va='bottom', rotation=90) #horizontale Ausspiegeling self.subplot.plot( (x_1, max_profile_length), (z_1, z_1), color_intersection[idx] + ':', linewidth=4, zorder=1 ) #save inital view in history plt_toolbar.push_current() #select pan tool plt_toolbar.pan() self.plt_toolbar = plt_toolbar #(matplotlib.pyplot).tight_layout(True) #plt.tight_layout() #self.fig.tight_layout() QApplication.restoreOverrideCursor()
def __init__(self, interface, settings, profiles): QDialog.__init__(self, interface.mainWindow()) self.iface = interface #output debug Log Messages: mainly for debugging matplotlib self.debug = False self.settings = settings self.profiles = profiles # Set up the user interface from Designer. self.ui = Ui_VoGISProfilToolPlot() self.ui.setupUi(self) if self.settings.onlyHektoMode is True: self.ui.IDC_frPlot.hide() self.ui.IDC_frToolbar.hide() self.adjustSize() self.ui.IDC_chkHekto.setCheckState(Qt.Checked) self.ui.IDC_chkHekto.setEnabled(False) #self.filePath = '' if QGis.QGIS_VERSION_INT < 10900: self.filePath = QSettings().value("vogisprofiltoolmain/savepath", "").toString() else: self.filePath = QSettings().value("vogisprofiltoolmain/savepath", "") #nimmt die Locale vom System, nicht von QGIS #kein Weg gefunden, um QGIS Locale: QSettings().value("locale/userLocale") #zu initialisieren, nur um Dezimaltrenne auszulesen #QgsMessageLog.logMessage('QGIS Locale:{0}'.format(QSettings().value("locale/userLocale").toString()), 'VoGis') #!!!nl_langinfo not available on Windows!!! #http://docs.python.org/2.7/library/locale.html#locale.nl_langinfo # ... This function is not available on all systems ... #decimalDelimiter = locale.nl_langinfo(locale.RADIXCHAR) decimalDelimiter = locale.localeconv()['decimal_point'] QgsMessageLog.logMessage('delimiter:{0}'.format(decimalDelimiter), 'VoGis') idx = self.ui.IDC_cbDecimalDelimiter.findText(decimalDelimiter, Qt.MatchExactly) QgsMessageLog.logMessage('idx:{0}'.format(idx), 'VoGis') self.ui.IDC_cbDecimalDelimiter.setCurrentIndex(idx) pltExt = PlotExtent() for p in self.profiles: pltExt.union(p.getExtent()) #QgsMessageLog.logMessage(pltExt.toString(), 'VoGis') pltExt.expand() self.origPltExt = PlotExtent(pltExt.xmin, pltExt.ymin, pltExt.xmax, pltExt.ymax) self.pltWidget = self.__createMatplotlibCanvas(pltExt) layout = self.ui.IDC_frPlot.layout() #QgsMessageLog.logMessage('layout: {0}'.format(layout), 'VoGis') layout.addWidget(self.pltWidget) pltToolbar = matplotlib.backends.backend_qt4agg.NavigationToolbar2QTAgg( self.pltWidget, self.ui.IDC_frPlot) self.ui.IDC_frToolbar.layout().addWidget(pltToolbar) #adjust actions #QgsMessageLog.logMessage('{0}'.format(dir(lstActions[0])), 'VoGis') # for a in pltToolbar.actions(): # QgsMessageLog.logMessage('{0}'.format(a.text()), 'VoGis') # for t in pltToolbar.toolitems: # QgsMessageLog.logMessage('{0}'.format(t), 'VoGis') #lstActions = pltToolbar.actions() firstaction = None for a in pltToolbar.actions(): atxt = a.text() if atxt == 'Home': firstaction = a a.setIcon( QIcon(":/plugins/vogisprofiltoolmain/icons/home.png")) elif atxt == 'Back': a.setIcon( QIcon(":/plugins/vogisprofiltoolmain/icons/zoomlast.png")) elif atxt == 'Forward': a.setIcon( QIcon(":/plugins/vogisprofiltoolmain/icons/zoomnext.png")) elif atxt == 'Pan': a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/pan.png")) elif atxt == 'Zoom': a.setIcon( QIcon( ":/plugins/vogisprofiltoolmain/icons/zoomselect.png")) elif atxt == 'Save': a.setIcon( QIcon(":/plugins/vogisprofiltoolmain/icons/save.png")) else: pltToolbar.removeAction(a) #insert 1:1 zoom button self.one2one = QPushButton() self.one2one.setText('1:1') self.one2one.clicked.connect(self.__one2oneClicked) #pltToolbar.addWidget(self.one2one) #insert QLineEdit to change the exaggeration #catch updating of figure, when exaggeration QLineEdit has been updated from draw_event of figure self.drawEventFired = False #catch closing of dialog, when enter key has been used accept exaggeration edit field self.exaggerationEdited = False self.editExaggeration = QLineEdit() self.editExaggeration.setFixedWidth(60) self.editExaggeration.setMaximumWidth(60) pltToolbar.insertWidget(firstaction, self.editExaggeration) self.editExaggeration.editingFinished.connect( self.__exaggerationEdited) #insert identify button -> deactivate all tools #HACK: picked event gets fired before click event self.plotpicked = False pltToolbar.insertWidget(firstaction, self.one2one) self.identify = QPushButton() self.identify.setIcon( QIcon(":/plugins/vogisprofiltoolmain/icons/identify.png")) self.identify.clicked.connect(self.__identify) pltToolbar.insertWidget(firstaction, self.identify) #insert identify label to show name of clicked dhm self.dhmLbl = QLabel() pltToolbar.insertWidget(firstaction, self.dhmLbl) #measure in figure self.click1 = None self.click2 = None self.click1pnt = None self.click2pnt = None self.measureLbl = QLabel() self.measureLbl.setText(u' ') pltToolbar.insertWidget(firstaction, self.measureLbl) #for less thatn 10 colors: #alternative method: http://stackoverflow.com/a/14720445 colors = [ (1.0, 0.0, 0.0, 1.0), (0.0, 1.0, 0.0, 1.0), (0.0, 0.0, 1.0, 1.0), (1.0, 1.0, 0.5, 1.0), (1.0, 0.0, 1.0, 1.0), (0.0, 1.0, 1.0, 1.0), (0.415686275, 0.807843137, 0.890196078, 1.0), (0.121568627, 0.470588235, 0.705882353, 1.0), (0.698039216, 0.874509804, 0.541176471, 1.0), (0.2, 0.62745098, 0.17254902, 1.0), (0.984313725, 0.603921569, 0.6, 1.0), (0.890196078, 0.101960784, 0.109803922, 1.0), (0.992156863, 0.749019608, 0.435294118, 1.0), (1, 0.498039216, 0, 1.0), (0.792156863, 0.698039216, 0.839215686, 1.0), (0.415686275, 0.239215686, 0.603921569, 1.0), (1, 1, 0.521568627, 1.0), ] #idxCol = 0 for idx, p in enumerate(self.profiles): #if idxCol > len(colors) - 1: # idxCol = 0 #x, pltSegs = p.getPlotSegments() #QgsMessageLog.logMessage('x: {0}'.format(x), 'VoGis') pltSegs = p.getPlotSegments() #QgsMessageLog.logMessage('pltSegs: {0}'.format(pltSegs), 'VoGis') lineColl = LineCollection( pltSegs, linewidths=2, linestyles='solid', #colors=colors[randrange(len(colors))], #colors=colors[idxCol], colors=colors[:len(settings.mapData.rasters.selectedRasters() )], picker=True, label='LBL') #lineColl.set_array(x) #lineColl.text.set_text('line label') self.subplot.add_collection(lineColl) #idxCol += 1 #save inital view in history pltToolbar.push_current() #select pan tool pltToolbar.pan() self.pltToolbar = pltToolbar #(matplotlib.pyplot).tight_layout(True) #plt.tight_layout() #self.fig.tight_layout() QApplication.restoreOverrideCursor()
class VoGISProfilToolPlotDialog(QDialog): def __init__(self, interface, settings, profiles, intersections): QDialog.__init__(self, interface.mainWindow()) self.iface = interface # output debug Log Messages: mainly for debugging matplotlib self.debug = False self.settings = settings self.profiles = profiles self.intersections = intersections # Set up the user interface from Designer. self.ui = Ui_VoGISProfilToolPlot() self.ui.setupUi(self) if self.settings.onlyHektoMode is True: self.ui.IDC_frPlot.hide() self.ui.IDC_frToolbar.hide() self.adjustSize() self.ui.IDC_chkHekto.setCheckState(Qt.Checked) self.ui.IDC_chkHekto.setEnabled(False) # self.filePath = '' if QGis.QGIS_VERSION_INT < 10900: self.filePath = QSettings().value("vogisprofiltoolmain/savepath", "").toString() else: self.filePath = QSettings().value("vogisprofiltoolmain/savepath", "") # nimmt die Locale vom System, nicht von QGIS # kein Weg gefunden, um QGIS Locale: QSettings().value("locale/userLocale") # zu initialisieren, nur um Dezimaltrenne auszulesen # QgsMessageLog.logMessage('QGIS Locale:{0}'.format(QSettings().value("locale/userLocale").toString()), 'VoGis') #!!!nl_langinfo not available on Windows!!! # http://docs.python.org/2.7/library/locale.html#locale.nl_langinfo # ... This function is not available on all systems ... # decimalDelimiter = locale.nl_langinfo(locale.RADIXCHAR) decimalDelimiter = locale.localeconv()["decimal_point"] QgsMessageLog.logMessage("delimiter:{0}".format(decimalDelimiter), "VoGis") idx = self.ui.IDC_cbDecimalDelimiter.findText(decimalDelimiter, Qt.MatchExactly) QgsMessageLog.logMessage("idx:{0}".format(idx), "VoGis") self.ui.IDC_cbDecimalDelimiter.setCurrentIndex(idx) plt_extent = PlotExtent() for profile in self.profiles: plt_extent.union(profile.getExtent()) if self.debug: QgsMessageLog.logMessage(plt_extent.toString(), "VoGis") plt_extent.expand() self.orig_plt_xtnt = PlotExtent(plt_extent.xmin, plt_extent.ymin, plt_extent.xmax, plt_extent.ymax) self.plt_widget = self.__createMatplotlibCanvas(plt_extent) layout = self.ui.IDC_frPlot.layout() # QgsMessageLog.logMessage('layout: {0}'.format(layout), 'VoGis') layout.addWidget(self.plt_widget) plt_toolbar = matplotlib.backends.backend_qt4agg.NavigationToolbar2QTAgg(self.plt_widget, self.ui.IDC_frPlot) self.ui.IDC_frToolbar.layout().addWidget(plt_toolbar) # adjust actions # QgsMessageLog.logMessage('{0}'.format(dir(lstActions[0])), 'VoGis') # for a in plt_toolbar.actions(): # QgsMessageLog.logMessage('{0}'.format(a.text()), 'VoGis') # for t in plt_toolbar.toolitems: # QgsMessageLog.logMessage('{0}'.format(t), 'VoGis') # lstActions = plt_toolbar.actions() # https://hub.qgis.org/wiki/17/Icons_20 firstaction = None for a in plt_toolbar.actions(): atxt = a.text() if atxt == "Home": firstaction = a a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/home.png")) elif atxt == "Back": a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/zoomlast.png")) elif atxt == "Forward": a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/zoomnext.png")) elif atxt == "Pan": a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/pan.png")) elif atxt == "Zoom": a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/zoomselect.png")) elif atxt == "Save": a.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/save.png")) else: plt_toolbar.removeAction(a) # insert 1:1 zoom button self.one2one = QPushButton() self.one2one.setText("1:1") self.one2one.clicked.connect(self.__one2oneClicked) # plt_toolbar.addWidget(self.one2one) # insert QLineEdit to change the exaggeration # catch updating of figure, when exaggeration QLineEdit has been updated from draw_event of figure self.draw_event_fired = False # catch closing of dialog, when enter key has been used accept exaggeration edit field self.exaggeration_edited = False # insert edit field for exaggeration self.editExaggeration = QLineEdit() self.editExaggeration.setFixedWidth(60) self.editExaggeration.setMaximumWidth(60) plt_toolbar.insertWidget(firstaction, self.editExaggeration) self.editExaggeration.editingFinished.connect(self.__exaggeration_edited) # insert identify button -> deactivate all tools # HACK: picked event gets fired before click event self.plotpicked = False plt_toolbar.insertWidget(firstaction, self.one2one) self.identify = QPushButton() self.identify.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/identify.png")) self.identify.clicked.connect(self.__identify) plt_toolbar.insertWidget(firstaction, self.identify) # insert identify label to show name of clicked dhm self.dhmLbl = QLabel() plt_toolbar.insertWidget(firstaction, self.dhmLbl) # insert measure tool self.measuring = False self.measure_tool = QPushButton() self.measure_tool.setIcon(QIcon(":/plugins/vogisprofiltoolmain/icons/measure.png")) self.measure_tool.clicked.connect(self.__measure) plt_toolbar.insertWidget(firstaction, self.measure_tool) # show measure results self.click1 = None self.click2 = None self.click1pnt = None self.click2pnt = None self.measure_lbl = QLabel() self.measure_lbl.setText(u" ") plt_toolbar.insertWidget(firstaction, self.measure_lbl) # for less thatn 10 colors: # alternative method: http://stackoverflow.com/a/14720445 colors = [ (1.0, 0.0, 0.0, 1.0), (0.0, 1.0, 0.0, 1.0), (0.0, 0.0, 1.0, 1.0), (1.0, 1.0, 0.5, 1.0), (1.0, 0.0, 1.0, 1.0), (0.0, 1.0, 1.0, 1.0), (0.415686275, 0.807843137, 0.890196078, 1.0), (0.121568627, 0.470588235, 0.705882353, 1.0), (0.698039216, 0.874509804, 0.541176471, 1.0), (0.2, 0.62745098, 0.17254902, 1.0), (0.984313725, 0.603921569, 0.6, 1.0), (0.890196078, 0.101960784, 0.109803922, 1.0), (0.992156863, 0.749019608, 0.435294118, 1.0), (1, 0.498039216, 0, 1.0), (0.792156863, 0.698039216, 0.839215686, 1.0), (0.415686275, 0.239215686, 0.603921569, 1.0), (1, 1, 0.521568627, 1.0), ] max_profile_length = 0 # idxCol = 0 for idx, p in enumerate(self.profiles): max_profile_length = max(p.getExtent().xmax, max_profile_length) # if idxCol > len(colors) - 1: # idxCol = 0 # x, plt_segments = p.getPlotSegments() # QgsMessageLog.logMessage('x: {0}'.format(x), 'VoGis') plt_segments = p.getPlotSegments() # QgsMessageLog.logMessage('plt_segments: {0}'.format(plt_segments), 'VoGis') lineColl = LineCollection( plt_segments, linewidths=2, linestyles="solid", # colors=colors[randrange(len(colors))], # colors=colors[idxCol], colors=colors[: len(settings.mapData.rasters.selectedRasters())], picker=True, label="LBL", ) # lineColl.set_array(x) # lineColl.text.set_text('line label') self.subplot.add_collection(lineColl) # idxCol += 1 # LINE STYLES: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.plot for idx, intersection in enumerate(self.intersections): color_intersection = ["b", "g", "r", "c", "m", "y", "k"] x_1 = intersection.from_dist x_2 = intersection.to_dist z_1 = intersection.from_z[self.settings.intersection_dhm_idx] z_2 = intersection.to_z[self.settings.intersection_dhm_idx] self.subplot.plot((x_1, x_2), (z_1, z_2), color_intersection[idx] + "--", linewidth=4, zorder=1) # http://matplotlib.org/users/annotations_guide.html#using-complex-coordinate-with-annotation self.subplot.annotate( u"{0:.2f}".format(z_1), (x_1, z_1), xytext=(0, 30), textcoords="offset points", bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="->"), ha="center", va="bottom", rotation=90, ) self.subplot.annotate( u"{0:.2f}".format(z_2), (x_2, z_2), xytext=(0, 30), textcoords="offset points", bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="->"), ha="center", va="bottom", rotation=90, ) # horizontale Ausspiegeling self.subplot.plot( (x_1, max_profile_length), (z_1, z_1), color_intersection[idx] + ":", linewidth=4, zorder=1 ) # save inital view in history plt_toolbar.push_current() # select pan tool plt_toolbar.pan() self.plt_toolbar = plt_toolbar # (matplotlib.pyplot).tight_layout(True) # plt.tight_layout() # self.fig.tight_layout() QApplication.restoreOverrideCursor() def accept(self): # QMessageBox.warning(self.iface.mainWindow(), "VoGIS-Profiltool", "ACCEPTED") QgsMessageLog.logMessage("accept: {0}".format(self.exaggeration_edited), "VoGis") if self.exaggeration_edited is True: self.exaggeration_edited = False return QDialog.accept(self) def reject(self): # QMessageBox.warning(self.iface.mainWindow(), "VoGIS-Profiltool", "REJECTED") QgsMessageLog.logMessage("reject: {0}".format(self.exaggeration_edited), "VoGis") if self.exaggeration_edited is True: self.exaggeration_edited = False return QDialog.reject(self) def exportShpPnt(self): self.__exportShp(True) def exportShpLine(self): self.__exportShp(False) def __exportShp(self, asPnt): u = Util(self.iface) if asPnt is True: caption = QApplication.translate("code", "Punkt Shapefile exportieren", None, QApplication.UnicodeUTF8) else: caption = QApplication.translate("code", "Linien Shapefile exportieren", None, QApplication.UnicodeUTF8) fileName, file_ext = u.getFileName(caption, [["shp", "shp"]], self.filePath) if fileName == "": return fInfo = QFileInfo(fileName) self.filePath = fInfo.path() QSettings().setValue("vogisprofiltoolmain/savepath", self.filePath) expShp = ExportShape( self.iface, (self.ui.IDC_chkHekto.checkState() == Qt.Checked), (self.ui.IDC_chkLineAttributes.checkState() == Qt.Checked), self.__getDelimiter(), self.__getDecimalDelimiter(), fileName, self.settings, self.profiles, ) if asPnt is False: expShp.exportLine() else: expShp.exportPoint() def exportCsvXls(self): u = Util(self.iface) caption = QApplication.translate("code", "Excel- oder CSV-Datei exportieren", None, QApplication.UnicodeUTF8) file_format = [] file_format.append(["Microsoft Excel 2007/2010 XML", "xlsx"]) file_format.append(["Comma-Separated Values CSV", "csv"]) fileName, fileExt = u.getFileName(caption, file_format, self.filePath) QgsMessageLog.logMessage(u"fileName: {0} fileExt:{1}".format(fileName, fileExt), "VoGis") if fileName == "": return fInfo = QFileInfo(fileName) self.filePath = fInfo.path() QSettings().setValue("vogisprofiltoolmain/savepath", self.filePath) hekto = self.ui.IDC_chkHekto.checkState() == Qt.Checked attribs = self.ui.IDC_chkLineAttributes.checkState() == Qt.Checked delimiter = ";" decimalDelimiter = self.__getDecimalDelimiter() if fileExt == "csv": txt = open(fileName, "w") txt.write( self.profiles[0].writeHeader(self.settings.mapData.rasters.selectedRasters(), hekto, attribs, delimiter) ) for p in self.profiles: # txt.write('=====Profil {0}======{1}'.format(p.id, os.linesep)) # txt.write('Segments:{0}{1}'.format(len(p.segments), os.linesep)) # for s in p.segments: # txt.write('Vertices:{0}{1}'.format(len(s.vertices), os.linesep)) txt.write(p.toString(hekto, attribs, delimiter, decimalDelimiter)) else: # BEGIN XLSX-Export exXls = ExportXls(self.iface, fileName, self.settings, self.profiles, hekto, attribs, decimalDelimiter) exXls.create() def exportTxt(self): delimiter = self.__getDelimiter() decimalDelimiter = self.__getDecimalDelimiter() if delimiter == decimalDelimiter: msg = QApplication.translate( "code", "Gleiches Dezimal- und Spaltentrennzeichen gewählt!", None, QApplication.UnicodeUTF8 ) QMessageBox.warning(self.iface.mainWindow(), "VoGIS-Profiltool", msg) return u = Util(self.iface) caption = QApplication.translate("code", "Textdatei exportieren", None, QApplication.UnicodeUTF8) fileName, file_ext = u.getFileName(caption, [["txt", "txt"]], self.filePath) if fileName == "": return fInfo = QFileInfo(fileName) self.filePath = fInfo.path() QSettings().setValue("vogisprofiltoolmain/savepath", self.filePath) hekto = self.ui.IDC_chkHekto.checkState() == Qt.Checked attribs = self.ui.IDC_chkLineAttributes.checkState() == Qt.Checked txt = open(fileName, "w") txt.write( self.profiles[0].writeHeader(self.settings.mapData.rasters.selectedRasters(), hekto, attribs, delimiter) ) for p in self.profiles: # txt.write('=====Profil {0}======{1}'.format(p.id, os.linesep)) # txt.write('Segments:{0}{1}'.format(len(p.segments), os.linesep)) # for s in p.segments: # txt.write('Vertices:{0}{1}'.format(len(s.vertices), os.linesep)) txt.write(p.toString(hekto, attribs, delimiter, decimalDelimiter)) txt.close() def exportAutoCadTxt(self): u = Util(self.iface) caption = QApplication.translate("code", "AutoCad Textdatei exportieren", None, QApplication.UnicodeUTF8) fileName, file_ext = u.getFileName(caption, [["txt", "txt"]], self.filePath) if fileName == "": return fInfo = QFileInfo(fileName) self.filePath = fInfo.path() QSettings().setValue("vogisprofiltoolmain/savepath", self.filePath) txt = open(fileName, "w") for p in self.profiles: txt.write(p.toACadTxt(" ", ".")) txt.close() def exportDxfPnt(self): self.__exportDxf(True) def exportDxfLine(self): self.__exportDxf(False) def __exportDxf(self, asPnt): u = Util(self.iface) caption = QApplication.translate("code", "DXF exportieren", None, QApplication.UnicodeUTF8) fileName, file_ext = u.getFileName(caption, [["dxf", "dxf"]], self.filePath) if fileName == "": return fInfo = QFileInfo(fileName) self.filePath = fInfo.path() QSettings().setValue("vogisprofiltoolmain/savepath", self.filePath) exDxf = ExportDxf(self.iface, fileName, self.settings, self.profiles) if asPnt is True: exDxf.exportPoint() else: exDxf.exportLine() def __identify(self): # dirty hack: deselect all tools # selecting a tool twice deselects it self.plt_toolbar.pan() self.plt_toolbar.zoom() self.plt_toolbar.zoom() def __measure(self): self.measuring = True # dirty hack: deselect all tools # selecting a tool twice deselects it self.plt_toolbar.pan() self.plt_toolbar.zoom() self.plt_toolbar.zoom() def __figureDrawn(self, event): if self.debug: QgsMessageLog.logMessage( "__figureDrawn, draw_event_fired:{0} exaggeration_edited: {1}".format( self.draw_event_fired, self.exaggeration_edited ), "VoGis", ) # draw event seems to get fired twice????? if self.draw_event_fired == True: return self.draw_event_fired = True axes = self.plt_widget.figure.get_axes()[0] xlim = axes.get_xlim() ylim = axes.get_ylim() if self.debug: QgsMessageLog.logMessage("__figureDrawn: xlim:{0} ylim:{1}".format(xlim, ylim), "VoGis") dpi = self.plt_widget.figure.get_dpi() fig_width = self.plt_widget.figure.get_figwidth() * dpi fig_height = self.plt_widget.figure.get_figheight() * dpi # bbox = axes.get_window_extent().transformed(self.plt_widget.figure.dpi_scale_trans.inverted()) # fig_width, fig_height = bbox.width * dpi, bbox.height * dpi fig_width *= TOP_MARGIN - BOTTOM_MARGIN fig_height *= RIGHT_MARGIN - LEFT_MARGIN delta_x = xlim[1] - xlim[0] delta_y = ylim[1] - ylim[0] ratio = (delta_x / fig_width) / (delta_y / fig_height) ratio = floor(ratio * 10) / 10 if self.debug: QgsMessageLog.logMessage( "__figureDrawn: fig_width:{0} fig_height:{1} dpi:{2} delta_x:{3} delta_y:{4}, ratio:{5}".format( fig_width, fig_height, dpi, delta_x, delta_y, ratio ), "VoGis", ) if self.debug: QgsMessageLog.logMessage("__figureDrawn: axes.get_data_ratio:{0}".format(axes.get_data_ratio()), "VoGis") # self.editExaggeration.setText('{0:.1f}'.format(ratio)) self.editExaggeration.setText("{0:.1f}".format(axes.get_aspect())) self.draw_event_fired = False def __exaggeration_edited(self, *args): if self.debug: QgsMessageLog.logMessage( "__exaggeration_edited, exaggeration_edited:{0} draw_event_fired: {1}".format( self.exaggeration_edited, self.draw_event_fired ), "VoGis", ) # this event handler seems to get called twice???? if self.draw_event_fired == True: return if self.exaggeration_edited == True: return self.exaggeration_edited = True # QgsMessageLog.logMessage('__exaggeration_edited: {0}'.format(self.exaggeration_edited), 'VoGis') ut = Util(self.iface) txtExa = QApplication.translate("code", "Überhöhung", None, QApplication.UnicodeUTF8) if ut.isFloat(self.editExaggeration.text(), txtExa) is False: return False # clear focus of lineedit, otherwise it gets called even when the user wants to close the dialog self.editExaggeration.clearFocus() exa = float(self.editExaggeration.text().replace(",", ".")) self.__adjustAxes(exa) def __one2oneClicked(self): if self.debug: QgsMessageLog.logMessage("1:1 clicked", "VoGis") # QgsMessageLog.logMessage('axes:{0}'.format(self.plt_widget.figure.get_axes()), 'VoGis') self.__adjustAxes(1.0) def __adjustAxes(self, exaggeration): exaggeration = floor(exaggeration * 10) / 10 axes = self.plt_widget.figure.get_axes()[0] # axes.set_aspect(exaggeration) # axes.set_autoscalex_on(False) # axes.set_autoscaley_on(True) if self.debug: QgsMessageLog.logMessage("__adjustAxes, get_aspect:{0}".format(axes.get_aspect()), "VoGis") QgsMessageLog.logMessage("__adjustAxes, get_position:{0}".format(axes.get_position()), "VoGis") QgsMessageLog.logMessage( "__adjustAxes, xBound:{0} xlim:{1}".format(axes.get_xbound(), axes.get_xlim()), "VoGis" ) QgsMessageLog.logMessage( "__adjustAxes, yBound:{0} ylim:{1}".format(axes.get_ybound(), axes.get_ylim()), "VoGis" ) oldexa = axes.get_aspect() ratioexa = oldexa / exaggeration ylim = axes.get_ylim() deltaYold = ylim[1] - ylim[0] deltaYnew = deltaYold * ratioexa centerY = ylim[0] + (deltaYold / 2) axes.set_ylim(centerY - deltaYnew / 2, centerY + deltaYnew / 2) axes.set_aspect(exaggeration, "datalim", "C") self.plt_widget.draw() if self.debug: QgsMessageLog.logMessage("__adjustAxes, get_aspect:{0}".format(axes.get_aspect()), "VoGis") QgsMessageLog.logMessage("__adjustAxes, get_position:{0}".format(axes.get_position()), "VoGis") QgsMessageLog.logMessage( "__adjustAxes, xBound:{0} xlim:{1}".format(axes.get_xbound(), axes.get_xlim()), "VoGis" ) QgsMessageLog.logMessage( "__adjustAxes, yBound:{0} ylim:{1}".format(axes.get_ybound(), axes.get_ylim()), "VoGis" ) def __plotPicked(self, event): self.plotpicked = True if self.debug: QgsMessageLog.logMessage("__plotPicked", "VoGis") # QgsMessageLog.logMessage('artist:{0}'.format(type(event.artist)), 'VoGis') self.dhmLbl.setText(" ? ") if isinstance(event.artist, Line2D): QgsMessageLog.logMessage("Line2D", "VoGis") line = event.artist xdata = line.get_xdata() ydata = line.get_ydata() ind = event.ind QgsMessageLog.logMessage("{0}: {1} {2}".format(ind, xdata, ydata), "VoGis") QgsMessageLog.logMessage(help(line), "VoGis") elif isinstance(event.artist, LineCollection): QgsMessageLog.logMessage("LineCollection", "VoGis") r = self.settings.mapData.rasters.selectedRasters()[event.ind[0]] QgsMessageLog.logMessage("Raster: {0}".format(r.name), "VoGis") self.dhmLbl.setText(u" [" + r.name + "] ") else: QgsMessageLog.logMessage("no Line2D or LineCollection", "VoGis") def __mouse_move(self, event): if self.measuring is False: return if self.click1 is None: return if event.xdata is None or event.ydata is None: return dx = event.xdata - self.click1.xdata dy = event.ydata - self.click1.ydata if self.debug: # QgsMessageLog.logMessage('mouse move name {0}'.format(event.name), 'VoGis') # QgsMessageLog.logMessage('mouse move xdata {0}'.format(event.xdata), 'VoGis') # QgsMessageLog.logMessage('mouse move ydata {0}'.format(event.ydata), 'VoGis') QgsMessageLog.logMessage("dx/dy {0}/{1}".format(dx, dy), "VoGis") self.measure_lbl.setText( u" x/y:{0:.1f}/{1:.1f} dx/dy:{2:.1f}/{3:.1f}".format(self.click1.xdata, self.click1.ydata, dx, dy) ) self.plt_toolbar.draw_rubberband("xy", self.click1.xpixel, self.click1.ypixel, event.x, event.y) def __buttonPressed(self, event): if self.debug: QgsMessageLog.logMessage("__buttonPressed", "VoGis") if self.plotpicked is False: self.dhmLbl.setText(" ? ") # reset flag to show '?' next time a button gets pressed self.plotpicked = False if self.measuring is False: return if self.debug: QgsMessageLog.logMessage("{0}".format(dir(event)), "VoGis") QgsMessageLog.logMessage("{0}".format(dir(event.xdata)), "VoGis") QgsMessageLog.logMessage("{0}".format(dir(event.ydata)), "VoGis") QgsMessageLog.logMessage( "x:{0} y:{1} xdata:{2} ydata:{3} click1:{4} click2:{5} click1pnt:{6} click2pnt:{7}".format( event.x, event.y, event.xdata, event.ydata, self.click1, self.click2, self.click1pnt, self.click2pnt ), "VoGis", ) QgsMessageLog.logMessage("click1pnt: {0}".format(dir(self.click1pnt)), "VoGis") if event.xdata is None or event.ydata is None: return if self.click1 is None: self.click1 = ChartPoint(event.x, event.y, event.xdata, event.ydata) self.click2 = None # self.measure_lbl.setText(u'') self.measure_lbl.setText(u" x/y:{0:.1f}/{1:.1f} dx/dy:0/0".format(event.xdata, event.ydata)) if not self.click1pnt is None: p = self.click1pnt.pop(0) p.remove() del p self.click1pnt = None if not self.click2pnt is None: p = self.click2pnt.pop(0) p.remove() del p self.click2pnt = None self.click1pnt = self.subplot.plot(event.xdata, event.ydata, "ro") elif self.click2 is None: self.click2 = ChartPoint(event.x, event.y, event.xdata, event.ydata) # delta_x = abs(self.click2[0] - self.click1[0]) # delta_y = abs(self.click2[1] - self.click1[1]) # dist = ((delta_x ** 2) + (delta_y ** 2)) ** 0.5 # self.measure_lbl.setText(u' dist: {0:.1f} '.format(dist)) delta_x = self.click2.xdata - self.click1.xdata delta_y = self.click2.ydata - self.click1.ydata dist = sqrt(pow(delta_x, 2) + pow(delta_y, 2)) self.measure_lbl.setText(u" dx/dy:{0:.1f}/{1:.1f} d:{2:.1f}".format(delta_x, delta_y, dist)) self.click1 = None self.measuring = False if not self.click2pnt is None: p = self.click2pnt.pop(0) p.remove() del p self.click2pnt = None self.click2pnt = self.subplot.plot(event.xdata, event.ydata, "go") # refresh plot to show points, when identify tool active # if self.debug: QgsMessageLog.logMessage('__buttonPressed: active: {0}'.format(self.plt_toolbar._active), 'VoGis') # if self.plotpicked is True: if self.plt_toolbar._active is None: self.plt_widget.draw() def __createMatplotlibCanvas(self, plt_extent): fig = Figure( (1, 1), # tight_layout=True, linewidth=0.0, subplotpars=matplotlib.figure.SubplotParams(left=0, bottom=0, right=1, top=1, wspace=0, hspace=0), ) # fig.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=None, hspace=None) # fig = Figure((24, 24), tight_layout=True) # try: # fig = Figure(tight_layout=True) # except: # #tight layout not available # fig = Figure() # fig = plt.figure() # fig.set_tight_layout(True) # font = {'family': 'arial', 'weight': 'normal', 'size': 12} # rc('font', **font) rect = fig.patch rect.set_facecolor((0.9, 0.9, 0.9)) # self.subplot = fig.add_axes( # #(0.08, 0.15, 0.92, 0.82), # (0.0, 0.0, 1.0, 1.0), # anchor='SW', # adjustable='box-forced' # ) # left bottom right top self.subplot = fig.add_axes( (LEFT_MARGIN, BOTTOM_MARGIN, RIGHT_MARGIN, TOP_MARGIN), adjustable="datalim", aspect=1 ) # self.subplot.plot.tight_layout(True) self.subplot.set_xbound(plt_extent.xmin, plt_extent.xmax) self.subplot.set_ybound(plt_extent.ymin, plt_extent.ymax) self.__setupAxes(self.subplot) # fig.tight_layout() canvas = FigureCanvasQTAgg(fig) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) canvas.setSizePolicy(sizePolicy) canvas.mpl_connect("pick_event", self.__plotPicked) canvas.mpl_connect("draw_event", self.__figureDrawn) canvas.mpl_connect("button_press_event", self.__buttonPressed) canvas.mpl_connect("motion_notify_event", self.__mouse_move) return canvas def __setupAxes(self, axe1): axe1.grid() axe1.ticklabel_format(style="plain", useOffset=False) axe1.tick_params( axis="both", which="major", direction="out", length=10, width=1, bottom=True, top=False, left=True, right=False, ) axe1.minorticks_on() axe1.tick_params( axis="both", which="minor", direction="out", length=5, width=1, bottom=True, top=False, left=True, right=False, ) def __getDecimalDelimiter(self): # delim = self.ui.IDC_cbDecimalDelimiter.itemData(self.ui.IDC_cbDecimalDelimiter.currentIndex()) delim = self.ui.IDC_cbDecimalDelimiter.currentText() # QgsMessageLog.logMessage('delim:' + str(delim), 'VoGis') return delim def __getDelimiter(self): # delim = self.ui.IDC_cbDelimiter.itemData(self.ui.IDC_cbDelimiter.currentIndex()) delim = self.ui.IDC_cbDelimiter.currentText() if delim == "tab": delim = "\t" return delim