class MapsterModule( BaseModule ): module_name = "Wyszukiwarka archiwalnych map Mapster" def __init__(self, parent): super().__init__(parent) self.point_tool = QgsMapToolEmitPoint( iface.mapCanvas() ) action = self.parent.add_action( ':/plugins/gissupport_plugin/mapster/mapster.svg', self.module_name, self.setMapsterTool, parent=iface.mainWindow(), checkable=True, add_to_topmenu=True ) self.point_tool.setAction( action ) self.point_tool.canvasClicked.connect( self.canvasClicked ) self.wgs84 = QgsCoordinateReferenceSystem( 'EPSG:4326' ) def setMapsterTool( self ): iface.mapCanvas().setMapTool( self.point_tool ) def canvasClicked( self, point, button ): project = QgsProject.instance() transformer = QgsCoordinateTransform( project.crs(), self.wgs84, project ) point = transformer.transform( point ) url = 'http://igrek.amzp.pl/result.php?cmd=pt&lat={}&lon={}&hideempty=on'.format( point.y(), point.x() ) QDesktopServices.openUrl(QUrl(url))
def setupUi(self, _): """ Add to the UI the following elements: 1) the selection editor 2) the tabs with the dynamic forms 3) the map 4) the toolbar with the map tools """ super(MainWindow, self).setupUi(self) self.selection_editor = SelectionDialog(self) self.actionUndo.setDisabled(True) # setup dynamic forms self.tabs = ( Tab("declustering", self.declusteringFormLayout, DECLUSTERER_METHODS, [self.declusterButton, self.declusteringPurgeButton]), Tab("completeness", self.completenessFormLayout, COMPLETENESS_METHODS, [self.completenessButton, self.completenessPurgeButton]), Tab("recurrence_model", self.recurrenceModelFormLayout, OCCURRENCE_METHODS, [self.recurrenceModelButton]), Tab("max_magnitude", self.maxMagnitudeFormLayout, MAX_MAGNITUDE_METHODS, [self.maxMagnitudeButton]), Tab("smoothed_seismicity", self.smoothedSeismicityFormLayout, SMOOTHED_SEISMICITY_METHODS, [self.smoothedSeismicityButton]), Tab("histogram", self.catalogueAnalysisFormLayout, CATALOGUE_ANALYSIS_METHODS, [self.catalogueAnalysisButton])) for tab in self.tabs: tab.setup_form(self.on_algorithm_select) self.stackedFormWidget.currentChanged.connect(self.change_tab) # setup Map self.mapWidget.setCanvasColor(Qt.white) self.mapWidget.enableAntiAliasing(True) self.mapWidget.show() #self.message_bar = QgsMessageBar(self.centralWidget) #self.outputVerticalLayout.insertWidget(0, self.message_bar) # setup toolbar group = QtGui.QActionGroup(self) group.addAction(self.actionZoomIn) group.addAction(self.actionZoomOut) group.addAction(self.actionPan) group.addAction(self.actionIdentify) # create the map tools toolPan = QgsMapToolPan(self.mapWidget) toolPan.setAction(self.actionPan) # false = in toolZoomIn = QgsMapToolZoom(self.mapWidget, False) toolZoomIn.setAction(self.actionZoomIn) # true = out toolZoomOut = QgsMapToolZoom(self.mapWidget, True) toolZoomOut.setAction(self.actionZoomOut) toolIdentify = QgsMapToolEmitPoint(self.mapWidget) toolIdentify.setAction(self.actionIdentify) toolIdentify.canvasClicked.connect( lambda point, button: self.catalogue_map.show_tip(point)) self.actionZoomIn.triggered.connect( lambda: self.mapWidget.setMapTool(toolZoomIn)) self.actionZoomOut.triggered.connect( lambda: self.mapWidget.setMapTool(toolZoomOut)) self.actionPan.triggered.connect( lambda: self.mapWidget.setMapTool(toolPan)) self.actionIdentify.triggered.connect( lambda: self.mapWidget.setMapTool(toolIdentify)) self.mapWidget.setMapTool(toolPan) self.stackedFormWidget.setCurrentIndex(0)
class EarthMineQGIS(QObject): """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface super(EarthMineQGIS, self).__init__() self.movingfeature = None self.iface = iface self.viewer = None self.canvas = self.iface.mapCanvas() self.settings = QSettings() # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value("locale/userLocale")[0:2] locale_path = os.path.join(self.plugin_dir, "i18n", "EarthMineQGIS_{}.qm".format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > "4.3.3": QCoreApplication.installTranslator(self.translator) self.pointtool = QgsMapToolEmitPoint(self.canvas) self.pointtool.canvasClicked.connect(self.set_viewer_location) self.settingsdialog = SettingsDialog(self.iface.mainWindow()) self.actions = [] self.menu = self.tr(u"&Earthmine") self.toolbar = self.iface.addToolBar(u"EarthMineQGIS") self.toolbar.setObjectName(u"EarthMineQGIS") self.legend = self.iface.legendInterface() emcolor = QColor(1, 150, 51) self.tempband = QgsRubberBand(self.canvas, QGis.Line) self.tempband.setWidth(5) self.tempband.setColor(emcolor) self.tempbandpoints = QgsRubberBand(self.canvas, QGis.Point) self.tempbandpoints.setWidth(7) self.tempbandpoints.setColor(emcolor) self.movingband = QgsRubberBand(self.canvas, QGis.Point) self.movingband.setWidth(5) self.movingband.setColor(emcolor) self.layersignals = [] self.marker = None def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ":/icons/settings" self.add_action( icon_path, text=self.tr(u"Show Settings"), callback=self.show_settings, parent=self.iface.mainWindow() ) icon_path = ":/icons/viewer" self.add_action( icon_path, text=self.tr(u"Earthmine Viewer"), callback=self.open_viewer, parent=self.iface.mainWindow() ) self.marker = PostionMarker(self.canvas) self.marker.hide() self.viewer = Viewer(callbackobject=self) self.viewer.trackingChanged.connect(self.marker.setTracking) self.viewer.setLocationTriggered.connect(partial(self.canvas.setMapTool, self.pointtool)) self.viewer.updateFeatures.connect(self.update_earthmine_features) self.viewer.layerChanged.connect(self.iface.setActiveLayer) self.viewer.clearLine.connect(self.clear_bands) self.viewer.closed.connect(self.remove_items) self.iface.currentLayerChanged.connect(self.viewer.update_current_layer) cursor = QCursor(QPixmap(":/icons/location")) self.pointtool.setCursor(cursor) self.pointtool.setAction(self.viewer.setlocationaction) def remove_items(self): self.marker.setTracking(False) self.disconnect_projectsignals() self.iface.actionPan().trigger() def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" self.canvas.scene().removeItem(self.marker) del self.marker self.disconnect_projectsignals() for action in self.actions: self.iface.removePluginMenu(self.tr(u"&Earthmine"), action) self.iface.removeToolBarIcon(action) del self.toolbar self.iface.removeDockWidget(self.viewer) self.viewer.deleteLater() def disconnect_projectsignals(self): safe_disconnect(QgsMapLayerRegistry.instance().layerWasAdded, self.connect_layer_signals) safe_disconnect(QgsMapLayerRegistry.instance().layersRemoved, self.layers_removed) safe_disconnect(self.canvas.layersChanged, self.layers_changed) safe_disconnect(self.iface.projectRead, self.connect_signals) safe_disconnect(self.canvas.selectionChanged, self.selection_changed) safe_disconnect(self.canvas.selectionChanged, self.viewer.selection_changed) def clear_bands(self): self.tempband.reset(QGis.Line) self.tempbandpoints.reset(QGis.Point) def visible_layers(self): """ Return the visible layers shown in the map canvas :return: """ return (layer for layer, visible in self.layers_with_states() if visible) def layers_with_states(self): for layer in maplayers(): if not layer.type() == QgsMapLayer.VectorLayer: continue if not layer.geometryType() in [QGis.Point, QGis.Line]: continue yield layer, self.legend.isLayerVisible(layer) def _layer_feature_added(self, featureid): layer = self.sender() if not layer: return self.layer_feature_added(layer, featureid) def layer_feature_added(self, layer, featureid): if not self.viewer: return feature = layer.getFeatures(QgsFeatureRequest(featureid)).next() renderer = layer.rendererV2() transform = self.coordinatetransform(layer) featuredata = to_feature_data(layer.id(), feature, renderer, transform) geomtype = layer.geometryType() layerdata = dict(id=layer.id(), geomtype=QGis.vectorGeometryType(geomtype)) self.viewer.load_features(layerdata, featuredata) def _layer_feature_delete(self, featureid): layer = self.sender() if not layer: return self.layer_feature_delete(layer, featureid) def layer_feature_delete(self, layer, featureid): if not self.viewer: return self.viewer.remove_feature(layer.id(), featureid) def _layer_geometry_changed(self, featureid, geometry): layer = self.sender() if not layer: return self.layer_geometry_changed(layer, featureid, geometry) def layer_geometry_changed(self, layer, featureid, geometry): if not self.viewer: return geomtype = layer.geometryType() if geomtype == QGis.Point: geom = geometry.asPoint() transform = self.coordinatetransform(layer) point = transform.transform(geom, QgsCoordinateTransform.ReverseTransform) location = dict(lat=point.y(), lng=point.x()) self.viewer.edit_feature(layer.id(), featureid, [location]) elif geomtype == QGis.Line: self.layer_feature_delete(layer, featureid) self.layer_feature_added(layer, featureid) def connect_layer_signals(self, layer): if not layer.type() == QgsMapLayer.VectorLayer: return layer.featureAdded.connect(self._layer_feature_added) layer.featureDeleted.connect(self._layer_feature_delete) layer.editingStarted.connect(self.layer_editstate_changed) layer.editingStopped.connect(self.layer_editstate_changed) # HACK The new style doesn't work here # http://hub.qgis.org/issues/6573 signal = SIGNAL("geometryChanged(QgsFeatureId, QgsGeometry&)") self.connect(layer, signal, self._layer_geometry_changed) self.load_layer_features(layers=[layer]) def layer_editstate_changed(self): layer = self.sender() if layer == self.iface.activeLayer(): self.viewer.layer_changed(layer) def disconnect_signals(self): self.disconnect_projectsignals() for layer in maplayers(): if not layer.type() == QgsMapLayer.VectorLayer: return safe_disconnect(layer.featureAdded, self._layer_feature_added) safe_disconnect(layer.featureDeleted, self._layer_feature_delete) safe_disconnect(layer.editingStarted, self.layer_editstate_changed) safe_disconnect(layer.editingStopped, self.layer_editstate_changed) # HACK The new style doesn't work here # http://hub.qgis.org/issues/6573 signal = SIGNAL("geometryChanged(QgsFeatureId, QgsGeometry&)") self.disconnect(layer, signal, self._layer_geometry_changed) def connect_signals(self): for layer in maplayers(): self.connect_layer_signals(layer) self.center_on_canvas() def set_viewer_location(self, point, mousebutton): transform = self.coordinatetransform() point = transform.transform(point, QgsCoordinateTransform.ReverseTransform) self.viewer.set_location(point) def distancearea(self): area = QgsDistanceArea() dest = self.canvas.mapRenderer().destinationCrs() area.setSourceCrs(dest) return area, dest.mapUnits() def coordinatetransform(self, layer=None): """ Return the transform for WGS84 -> QGIS projection. """ source = QgsCoordinateReferenceSystem() source.createFromWkt( 'GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]' ) if not layer: dest = self.canvas.mapRenderer().destinationCrs() else: dest = layer.crs() transform = QgsCoordinateTransform(source, dest) return transform def earthmine_settings(self): settings = {} with settinggroup(self.settings, "plugins/Earthmine"): for key in ["serviceUrl", "baseDataUrl", "apiKey", "secretKey", "viewerUrl"]: if not self.settings.contains(key): raise EarthmineSettingsError("{} not set".format(key)) value = self.settings.value(key, type=str) if value is None: raise EarthmineSettingsError("{} not set".format(key)) settings[key] = value return settings @pyqtSlot() def ready(self): """ Called when the viewer is ready to be started. At this point the viewer hasn't been loaded so no other methods apart from startViewer will be handled. """ settings = self.earthmine_settings() self.viewer.startViewer(settings) @pyqtSlot() def viewerReady(self): """ Called once the viewer is loaded and ready to get location events. """ self.disconnect_signals() self.connect_signals() self.iface.projectRead.connect(self.connect_signals) self.canvas.layersChanged.connect(self.layers_changed) self.canvas.selectionChanged.connect(self.selection_changed) self.canvas.selectionChanged.connect(self.viewer.selection_changed) QgsMapLayerRegistry.instance().layersRemoved.connect(self.layers_removed) QgsMapLayerRegistry.instance().layerWasAdded.connect(self.connect_layer_signals) self.center_on_canvas() self.viewer.activelayercombo.setLayer(self.iface.activeLayer()) def center_on_canvas(self): point = self.canvas.extent().center() transform = self.coordinatetransform() point = transform.transform(point, QgsCoordinateTransform.ReverseTransform) self.viewer.set_location(point) self.viewer.infoaction.toggle() def selection_changed(self, layer): ids = [feature.id() for feature in layer.selectedFeatures()] if not ids: self.viewer.clear_selection(layer.id()) else: self.viewer.set_selection(layer.id(), ids) def layers_changed(self): layerstates = self.layers_with_states() for layer, visible in layerstates: layerid = layer.id() viewerloaded = self.viewer.layer_loaded(layerid) QgsMessageLog.instance().logMessage(layerid, "Earthmine") QgsMessageLog.instance().logMessage("Viewer State:" + str(viewerloaded), "Earthmine") QgsMessageLog.instance().logMessage("QGIS State:" + str(visible), "Earthmine") if (viewerloaded and visible) or (not viewerloaded and not visible): QgsMessageLog.instance().logMessage("Ignoring as states match", "Earthmine") continue if viewerloaded and not visible: QgsMessageLog.instance().logMessage( "Clearing layer because viewer loaded and disabled in QGIS", "Earthmine" ) self.viewer.clear_layer_features(layerid) continue if not viewerloaded and visible: QgsMessageLog.instance().logMessage("Loading layer", "Earthmine") self.load_layer_features(layers=[layer]) continue def layers_removed(self, layers): for layerid in layers: self.viewer.clear_layer_features(layerid) @pyqtSlot(str, float, float) def viewChanged(self, event, yaw, angle): self.marker.setAngle(angle) self.marker.setYaw(yaw) @pyqtSlot(str, str) def getInfo(self, layerid, featureid): featureid = int(featureid) activelayer = self.iface.activeLayer() if not activelayer: return activetool = self.viewer.active_tool() if not activetool in ["Info", "Select"]: return # Only show information for the active layer if not layerid == activelayer.id(): return layer = layer_by_id(layerid) if activetool == "Select": layer.setSelectedFeatures([featureid]) elif activetool == "Info": rq = QgsFeatureRequest(featureid) feature = layer.getFeatures(rq).next() dlg = get_feature_form(layer, feature) if dlg.dialog().exec_(): self.canvas.refresh() @pyqtSlot(str, str, float, float, bool) def featureMoved(self, layerid, featureid, lat, lng, end): layer = layer_by_id(layerid) transform = self.coordinatetransform(layer) point = transform.transform(lng, lat) if not end: self.movingband.show() self.movingband.setToGeometry(QgsGeometry.fromPoint(point), layer) self.movingband.updatePosition() self.movingband.update() else: self.movingband.hide() feature = feature_by_id(layer, featureid) startpoint = feature.geometry().asPoint() dx = point.x() - startpoint.x() dy = point.y() - startpoint.y() layer.beginEditCommand("Feature Moved") # Block signals for this move as the geometry changed signal will re add the geometry on use. layer.blockSignals(True) layer.translateFeature(feature.id(), dx, dy) layer.blockSignals(False) self.canvas.refresh() layer.endEditCommand() @pyqtSlot(str, str) def onError(self, message, stacktrace=None): self.iface.messageBar().pushMessage("Earthmine", message, QgsMessageBar.WARNING) QgsMessageLog.logMessage(stacktrace, "Earthmine") @pyqtSlot(float, float, float) def addPoint(self, lat, lng, z): layer = self.viewer.active_layer if not layer.isEditable(): self.iface.messageBar().pushMessage( "Earthmine", "Selected layer isn't editable. Please enable edit mode to add features", duration=3, level=QgsMessageBar.WARNING, ) return transform = self.coordinatetransform(layer) point = transform.transform(lng, lat) geom = QgsGeometry.fromPoint(point) self.add_feature(layer, geom, z) def add_feature(self, layer, geom, z=None): feature = QgsFeature(layer.pendingFields()) if z and self.viewer.copyZvalue: try: feature["Z"] = z except KeyError: QgsMessageLog.log("No Z found on layer {}".format(layer.name())) pass feature.setGeometry(geom) dlg = get_feature_form(layer, feature, isadd=True) if dlg.dialog().exec_(): self.canvas.refresh() @pyqtSlot(str, bool, str) def drawLine(self, points, end, stats): points = json.loads(points) stats = json.loads(stats) QgsMessageLog.logMessage(str(stats), "Earthmine") self.tempband.reset(QGis.Line) self.tempbandpoints.reset(QGis.Point) color = QColor(self.viewer.current_action_color) self.tempband.setColor(color) self.tempbandpoints.setColor(color) layer = self.viewer.active_layer transform = self.coordinatetransform(layer) earthminepoints = [] for point in points: newpoint = transform.transform(point["lng"], point["lat"]) self.tempband.addPoint(newpoint) self.tempbandpoints.addPoint(newpoint) empoint = EarthminePoint(newpoint, point) earthminepoints.append(empoint) if end and not self.viewer.mode == "Vertical": geom = self.tempband.asGeometry() self.add_feature(layer, geom) self.clear_bands() self.viewer.geom = EarthmineLine(earthminepoints, stats) self.tempband.show() self.tempbandpoints.show() @pyqtSlot(str, str, str, float) def locationChanged(self, lat, lng, yaw, angle): transform = self.coordinatetransform() point = transform.transform(float(lng), float(lat)) self.marker.setCenter(point) yaw = float(yaw) self.marker.setAngle(angle) self.marker.setYaw(yaw) self.marker.setTracking(self.viewer.tracking) if self.marker.tracking: rect = QgsRectangle(point, point) extentlimt = QgsRectangle(self.canvas.extent()) extentlimt.scale(0.95) if not extentlimt.contains(point): self.canvas.setExtent(rect) self.canvas.refresh() # Clear old features self.viewer.clear_features() self.load_layer_features(point) def update_earthmine_features(self, viewfeatures): self.viewer.clear_features() if viewfeatures: self.load_layer_features() def load_layer_features(self, point=None, layers=None): # TODO Move this logic into the viewer and let it track it's position if point is None and self.marker.map_pos is None: return if point is None: point = self.marker.map_pos area, units = self.distancearea() rect = search_area(units, area, point) if layers is None: layers = self.visible_layers() for layer in layers: transform = self.coordinatetransform(layer) # Transform the rect source = self.canvas.mapRenderer().destinationCrs() dest = layer.crs() recttransform = QgsCoordinateTransform(source, dest) rect = recttransform.transformBoundingBox(rect) features = list(get_features_in_area(layer, rect, transform, self.canvas.mapSettings())) geomtype = layer.geometryType() layerdata = dict(id=layer.id(), geomtype=QGis.vectorGeometryType(geomtype)) self.viewer.load_features(layerdata, features) # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate("EarthMineQGIS", message) def add_action( self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None, ): """Add a toolbar icon to the InaSAFE toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to s, "Earhtmine"how in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToMenu(self.menu, action) self.actions.append(action) return action def open_viewer(self): """Run method that performs all the real work""" try: settings = self.earthmine_settings() except EarthmineSettingsError as ex: self.onError(ex.message) self.show_settings() return url = settings["viewerUrl"] if not url.startswith("http"): url = url.replace("\\\\", "\\") url = QUrl.fromLocalFile(url) else: url = QUrl(url) if not self.viewer.isVisible(): self.iface.addDockWidget(Qt.RightDockWidgetArea, self.viewer) self.viewer.loadviewer(url) def show_settings(self): self.settingsdialog.show()
class EarthMineQGIS(QObject): """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface super(EarthMineQGIS, self).__init__() self.movingfeature = None self.iface = iface self.viewer = None self.canvas = self.iface.mapCanvas() self.settings = QSettings() # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'EarthMineQGIS_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) self.pointtool = QgsMapToolEmitPoint(self.canvas) self.pointtool.canvasClicked.connect(self.set_viewer_location) self.settingsdialog = SettingsDialog(self.iface.mainWindow()) self.actions = [] self.menu = self.tr(u'&Earthmine') self.toolbar = self.iface.addToolBar(u'EarthMineQGIS') self.toolbar.setObjectName(u'EarthMineQGIS') self.legend = self.iface.legendInterface() emcolor = QColor(1, 150, 51) self.tempband = QgsRubberBand(self.canvas, QGis.Line) self.tempband.setWidth(5) self.tempband.setColor(emcolor) self.tempbandpoints = QgsRubberBand(self.canvas, QGis.Point) self.tempbandpoints.setWidth(7) self.tempbandpoints.setColor(emcolor) self.movingband = QgsRubberBand(self.canvas, QGis.Point) self.movingband.setWidth(5) self.movingband.setColor(emcolor) self.layersignals = [] self.marker = None def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/icons/settings' self.add_action(icon_path, text=self.tr(u'Show Settings'), callback=self.show_settings, parent=self.iface.mainWindow()) icon_path = ':/icons/viewer' self.add_action(icon_path, text=self.tr(u'Earthmine Viewer'), callback=self.open_viewer, parent=self.iface.mainWindow()) self.marker = PostionMarker(self.canvas) self.marker.hide() self.viewer = Viewer(callbackobject=self) self.viewer.trackingChanged.connect(self.marker.setTracking) self.viewer.setLocationTriggered.connect( partial(self.canvas.setMapTool, self.pointtool)) self.viewer.updateFeatures.connect(self.update_earthmine_features) self.viewer.layerChanged.connect(self.iface.setActiveLayer) self.viewer.clearLine.connect(self.clear_bands) self.viewer.closed.connect(self.remove_items) self.iface.currentLayerChanged.connect( self.viewer.update_current_layer) cursor = QCursor(QPixmap(":/icons/location")) self.pointtool.setCursor(cursor) self.pointtool.setAction(self.viewer.setlocationaction) def remove_items(self): self.marker.setTracking(False) self.disconnect_projectsignals() self.iface.actionPan().trigger() def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" self.canvas.scene().removeItem(self.marker) del self.marker self.disconnect_projectsignals() for action in self.actions: self.iface.removePluginMenu(self.tr(u'&Earthmine'), action) self.iface.removeToolBarIcon(action) del self.toolbar self.iface.removeDockWidget(self.viewer) self.viewer.deleteLater() def disconnect_projectsignals(self): safe_disconnect(QgsMapLayerRegistry.instance().layerWasAdded, self.connect_layer_signals) safe_disconnect(QgsMapLayerRegistry.instance().layersRemoved, self.layers_removed) safe_disconnect(self.canvas.layersChanged, self.layers_changed) safe_disconnect(self.iface.projectRead, self.connect_signals) safe_disconnect(self.canvas.selectionChanged, self.selection_changed) safe_disconnect(self.canvas.selectionChanged, self.viewer.selection_changed) def clear_bands(self): self.tempband.reset(QGis.Line) self.tempbandpoints.reset(QGis.Point) def visible_layers(self): """ Return the visible layers shown in the map canvas :return: """ return (layer for layer, visible in self.layers_with_states() if visible) def layers_with_states(self): for layer in maplayers(): if not layer.type() == QgsMapLayer.VectorLayer: continue if not layer.geometryType() in [QGis.Point, QGis.Line]: continue yield layer, self.legend.isLayerVisible(layer) def _layer_feature_added(self, featureid): layer = self.sender() if not layer: return self.layer_feature_added(layer, featureid) def layer_feature_added(self, layer, featureid): if not self.viewer: return feature = layer.getFeatures(QgsFeatureRequest(featureid)).next() renderer = layer.rendererV2() transform = self.coordinatetransform(layer) featuredata = to_feature_data(layer.id(), feature, renderer, transform) geomtype = layer.geometryType() layerdata = dict(id=layer.id(), geomtype=QGis.vectorGeometryType(geomtype)) self.viewer.load_features(layerdata, featuredata) def _layer_feature_delete(self, featureid): layer = self.sender() if not layer: return self.layer_feature_delete(layer, featureid) def layer_feature_delete(self, layer, featureid): if not self.viewer: return self.viewer.remove_feature(layer.id(), featureid) def _layer_geometry_changed(self, featureid, geometry): layer = self.sender() if not layer: return self.layer_geometry_changed(layer, featureid, geometry) def layer_geometry_changed(self, layer, featureid, geometry): if not self.viewer: return geomtype = layer.geometryType() if geomtype == QGis.Point: geom = geometry.asPoint() transform = self.coordinatetransform(layer) point = transform.transform( geom, QgsCoordinateTransform.ReverseTransform) location = dict(lat=point.y(), lng=point.x()) self.viewer.edit_feature(layer.id(), featureid, [location]) elif geomtype == QGis.Line: self.layer_feature_delete(layer, featureid) self.layer_feature_added(layer, featureid) def connect_layer_signals(self, layer): if not layer.type() == QgsMapLayer.VectorLayer: return layer.featureAdded.connect(self._layer_feature_added) layer.featureDeleted.connect(self._layer_feature_delete) layer.editingStarted.connect(self.layer_editstate_changed) layer.editingStopped.connect(self.layer_editstate_changed) # HACK The new style doesn't work here # http://hub.qgis.org/issues/6573 signal = SIGNAL("geometryChanged(QgsFeatureId, QgsGeometry&)") self.connect(layer, signal, self._layer_geometry_changed) self.load_layer_features(layers=[layer]) def layer_editstate_changed(self): layer = self.sender() if layer == self.iface.activeLayer(): self.viewer.layer_changed(layer) def disconnect_signals(self): self.disconnect_projectsignals() for layer in maplayers(): if not layer.type() == QgsMapLayer.VectorLayer: return safe_disconnect(layer.featureAdded, self._layer_feature_added) safe_disconnect(layer.featureDeleted, self._layer_feature_delete) safe_disconnect(layer.editingStarted, self.layer_editstate_changed) safe_disconnect(layer.editingStopped, self.layer_editstate_changed) # HACK The new style doesn't work here # http://hub.qgis.org/issues/6573 signal = SIGNAL("geometryChanged(QgsFeatureId, QgsGeometry&)") self.disconnect(layer, signal, self._layer_geometry_changed) def connect_signals(self): for layer in maplayers(): self.connect_layer_signals(layer) self.center_on_canvas() def set_viewer_location(self, point, mousebutton): transform = self.coordinatetransform() point = transform.transform(point, QgsCoordinateTransform.ReverseTransform) self.viewer.set_location(point) def distancearea(self): area = QgsDistanceArea() dest = self.canvas.mapRenderer().destinationCrs() area.setSourceCrs(dest) return area, dest.mapUnits() def coordinatetransform(self, layer=None): """ Return the transform for WGS84 -> QGIS projection. """ source = QgsCoordinateReferenceSystem() source.createFromWkt( 'GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]' ) if not layer: dest = self.canvas.mapRenderer().destinationCrs() else: dest = layer.crs() transform = QgsCoordinateTransform(source, dest) return transform def earthmine_settings(self): settings = {} with settinggroup(self.settings, "plugins/Earthmine"): for key in [ 'serviceUrl', 'baseDataUrl', "apiKey", 'secretKey', 'viewerUrl' ]: if not self.settings.contains(key): raise EarthmineSettingsError("{} not set".format(key)) value = self.settings.value(key, type=str) if value is None: raise EarthmineSettingsError("{} not set".format(key)) settings[key] = value return settings @pyqtSlot() def ready(self): """ Called when the viewer is ready to be started. At this point the viewer hasn't been loaded so no other methods apart from startViewer will be handled. """ settings = self.earthmine_settings() self.viewer.startViewer(settings) @pyqtSlot() def viewerReady(self): """ Called once the viewer is loaded and ready to get location events. """ self.disconnect_signals() self.connect_signals() self.iface.projectRead.connect(self.connect_signals) self.canvas.layersChanged.connect(self.layers_changed) self.canvas.selectionChanged.connect(self.selection_changed) self.canvas.selectionChanged.connect(self.viewer.selection_changed) QgsMapLayerRegistry.instance().layersRemoved.connect( self.layers_removed) QgsMapLayerRegistry.instance().layerWasAdded.connect( self.connect_layer_signals) self.center_on_canvas() self.viewer.activelayercombo.setLayer(self.iface.activeLayer()) def center_on_canvas(self): point = self.canvas.extent().center() transform = self.coordinatetransform() point = transform.transform(point, QgsCoordinateTransform.ReverseTransform) self.viewer.set_location(point) self.viewer.infoaction.toggle() def selection_changed(self, layer): ids = [feature.id() for feature in layer.selectedFeatures()] if not ids: self.viewer.clear_selection(layer.id()) else: self.viewer.set_selection(layer.id(), ids) def layers_changed(self): layerstates = self.layers_with_states() for layer, visible in layerstates: layerid = layer.id() viewerloaded = self.viewer.layer_loaded(layerid) QgsMessageLog.instance().logMessage(layerid, "Earthmine") QgsMessageLog.instance().logMessage( "Viewer State:" + str(viewerloaded), "Earthmine") QgsMessageLog.instance().logMessage("QGIS State:" + str(visible), "Earthmine") if (viewerloaded and visible) or (not viewerloaded and not visible): QgsMessageLog.instance().logMessage("Ignoring as states match", "Earthmine") continue if viewerloaded and not visible: QgsMessageLog.instance().logMessage( "Clearing layer because viewer loaded and disabled in QGIS", "Earthmine") self.viewer.clear_layer_features(layerid) continue if not viewerloaded and visible: QgsMessageLog.instance().logMessage("Loading layer", "Earthmine") self.load_layer_features(layers=[layer]) continue def layers_removed(self, layers): for layerid in layers: self.viewer.clear_layer_features(layerid) @pyqtSlot(str, float, float) def viewChanged(self, event, yaw, angle): self.marker.setAngle(angle) self.marker.setYaw(yaw) @pyqtSlot(str, str) def getInfo(self, layerid, featureid): featureid = int(featureid) activelayer = self.iface.activeLayer() if not activelayer: return activetool = self.viewer.active_tool() if not activetool in ["Info", "Select"]: return # Only show information for the active layer if not layerid == activelayer.id(): return layer = layer_by_id(layerid) if activetool == "Select": layer.setSelectedFeatures([featureid]) elif activetool == "Info": rq = QgsFeatureRequest(featureid) feature = layer.getFeatures(rq).next() dlg = get_feature_form(layer, feature) if dlg.dialog().exec_(): self.canvas.refresh() @pyqtSlot(str, str, float, float, bool) def featureMoved(self, layerid, featureid, lat, lng, end): layer = layer_by_id(layerid) transform = self.coordinatetransform(layer) point = transform.transform(lng, lat) if not end: self.movingband.show() self.movingband.setToGeometry(QgsGeometry.fromPoint(point), layer) self.movingband.updatePosition() self.movingband.update() else: self.movingband.hide() feature = feature_by_id(layer, featureid) startpoint = feature.geometry().asPoint() dx = point.x() - startpoint.x() dy = point.y() - startpoint.y() layer.beginEditCommand("Feature Moved") # Block signals for this move as the geometry changed signal will re add the geometry on use. layer.blockSignals(True) layer.translateFeature(feature.id(), dx, dy) layer.blockSignals(False) self.canvas.refresh() layer.endEditCommand() @pyqtSlot(str, str) def onError(self, message, stacktrace=None): self.iface.messageBar().pushMessage("Earthmine", message, QgsMessageBar.WARNING) QgsMessageLog.logMessage(stacktrace, "Earthmine") @pyqtSlot(float, float, float) def addPoint(self, lat, lng, z): layer = self.viewer.active_layer if not layer.isEditable(): self.iface.messageBar().pushMessage( "Earthmine", "Selected layer isn't editable. Please enable edit mode to add features", duration=3, level=QgsMessageBar.WARNING) return transform = self.coordinatetransform(layer) point = transform.transform(lng, lat) geom = QgsGeometry.fromPoint(point) self.add_feature(layer, geom, z) def add_feature(self, layer, geom, z=None): feature = QgsFeature(layer.pendingFields()) if z and self.viewer.copyZvalue: try: feature['Z'] = z except KeyError: QgsMessageLog.log("No Z found on layer {}".format( layer.name())) pass feature.setGeometry(geom) dlg = get_feature_form(layer, feature, isadd=True) if dlg.dialog().exec_(): self.canvas.refresh() @pyqtSlot(str, bool, str) def drawLine(self, points, end, stats): points = json.loads(points) stats = json.loads(stats) QgsMessageLog.logMessage(str(stats), "Earthmine") self.tempband.reset(QGis.Line) self.tempbandpoints.reset(QGis.Point) color = QColor(self.viewer.current_action_color) self.tempband.setColor(color) self.tempbandpoints.setColor(color) layer = self.viewer.active_layer transform = self.coordinatetransform(layer) earthminepoints = [] for point in points: newpoint = transform.transform(point['lng'], point['lat']) self.tempband.addPoint(newpoint) self.tempbandpoints.addPoint(newpoint) empoint = EarthminePoint(newpoint, point) earthminepoints.append(empoint) if end and not self.viewer.mode == "Vertical": geom = self.tempband.asGeometry() self.add_feature(layer, geom) self.clear_bands() self.viewer.geom = EarthmineLine(earthminepoints, stats) self.tempband.show() self.tempbandpoints.show() @pyqtSlot(str, str, str, float) def locationChanged(self, lat, lng, yaw, angle): transform = self.coordinatetransform() point = transform.transform(float(lng), float(lat)) self.marker.setCenter(point) yaw = float(yaw) self.marker.setAngle(angle) self.marker.setYaw(yaw) self.marker.setTracking(self.viewer.tracking) if self.marker.tracking: rect = QgsRectangle(point, point) extentlimt = QgsRectangle(self.canvas.extent()) extentlimt.scale(0.95) if not extentlimt.contains(point): self.canvas.setExtent(rect) self.canvas.refresh() # Clear old features self.viewer.clear_features() self.load_layer_features(point) def update_earthmine_features(self, viewfeatures): self.viewer.clear_features() if viewfeatures: self.load_layer_features() def load_layer_features(self, point=None, layers=None): # TODO Move this logic into the viewer and let it track it's position if point is None and self.marker.map_pos is None: return if point is None: point = self.marker.map_pos area, units = self.distancearea() rect = search_area(units, area, point) if layers is None: layers = self.visible_layers() for layer in layers: transform = self.coordinatetransform(layer) # Transform the rect source = self.canvas.mapRenderer().destinationCrs() dest = layer.crs() recttransform = QgsCoordinateTransform(source, dest) rect = recttransform.transformBoundingBox(rect) features = list( get_features_in_area(layer, rect, transform, self.canvas.mapSettings())) geomtype = layer.geometryType() layerdata = dict(id=layer.id(), geomtype=QGis.vectorGeometryType(geomtype)) self.viewer.load_features(layerdata, features) # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('EarthMineQGIS', message) def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the InaSAFE toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to s, "Earhtmine"how in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToMenu(self.menu, action) self.actions.append(action) return action def open_viewer(self): """Run method that performs all the real work""" try: settings = self.earthmine_settings() except EarthmineSettingsError as ex: self.onError(ex.message) self.show_settings() return url = settings["viewerUrl"] if not url.startswith("http"): url = url.replace("\\\\", "\\") url = QUrl.fromLocalFile(url) else: url = QUrl(url) if not self.viewer.isVisible(): self.iface.addDockWidget(Qt.RightDockWidgetArea, self.viewer) self.viewer.loadviewer(url) def show_settings(self): self.settingsdialog.show()
class TSTools(QObject): def __init__(self, iface): super(TSTools, self).__init__() # Save reference to the QGIS interface self.iface = iface self.canvas = self.iface.mapCanvas() # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value("locale/userLocale")[0:2] localePath = os.path.join(self.plugin_dir, 'i18n', 'tstools_{}.qm'.format(locale)) if os.path.exists(localePath): self.translator = QTranslator() self.translator.load(localePath) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Location info - define these elsewhere #TODO self.location = os.getcwd() # Toolbar self.init_toolbar() # Map tool on/off self.tool_enabled = True print 'DEBUG {f}: found {i} TS data models'.format( f=__file__, i=len(tsm.ts_drivers)) def init_toolbar(self): """ Creates and populates the toolbar for plugin """ # MapTool button self.action = QAction(QIcon(':/plugins/tstools/tstools_click.png'), 'Time Series Tools', self.iface.mainWindow()) self.action.triggered.connect(self.set_tool) self.iface.addToolBarIcon(self.action) # Configuration menu button self.action_cfg = QAction(QIcon(':/plugins/tstools/tstools_config.png'), 'Configure', self.iface.mainWindow()) self.action_cfg.triggered.connect(self.handle_config) self.iface.addToolBarIcon(self.action_cfg) # Map tool self.tool_ts = QgsMapToolEmitPoint(self.canvas) self.tool_ts.setAction(self.action) self.tool_ts.canvasClicked.connect(self.plot_request) @pyqtSlot() def set_tool(self): """ Sets the time series tool as current map tool """ self.tool_enabled = True self.canvas.setMapTool(self.tool_ts) @pyqtSlot() def unset_tool(self): """ Unsets the time series tool as current map tool """ self.tool_enabled = False self.canvas.setMapTool(None) def handle_config(self): """ Handles configuration menu for initializing the time series """ print 'DEBUG %s : show/hide config' % __file__ # Init the dialog self.config = Config(self, self.location) # Connect signals self.config.accepted.connect(self.config_accepted) self.config.canceled.connect(self.config_closed) # Execute & show dialog self.config.exec_() def config_accepted(self): """ Handles 'OK' button from Config dialog and tries to add time series """ # Try new values location = str(self.config.location) model_index = int(self.config.model_index) custom_options = self.config.custom_options # Set data model for controller from user pick try: self.controller.get_time_series( tsm.ts_drivers[model_index], location, custom_options) # Accept values self.location = location # Close config self.config_closed() # Send message self.iface.messageBar().pushMessage('Info', 'Loaded time series', level=QgsMessageBar.INFO, duration=3) except: # Send error message self.iface.messageBar().pushMessage('Error', 'Failed to find time series.', level=QgsMessageBar.CRITICAL, duration=3) raise def config_closed(self): """ Close and disconnect the configuration dialog """ self.config.accepted.disconnect() self.config.canceled.disconnect() self.config.close() def init_controls(self): """ Initialize and add signals to the left side control widget """ print 'DEBUG %s : init_controls' % __file__ # Create widget self.ctrl = ControlPanel(self.iface) # Create dock & add control widget self.ctrl_dock = QDockWidget('TS Tools Controls', self.iface.mainWindow()) self.ctrl_dock.setObjectName('TS Tools Controls') self.ctrl_dock.setWidget(self.ctrl) # Add to iface self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.ctrl_dock) def init_plots(self): """ Initialize and add signals to plots within bottom dock """ # Create time series plot self.ts_plot = TSPlot(self.iface) # TODO more plots, tabs self.doy_plot = DOYPlot(self.iface) # Create dock and add self.plot_dock = QDockWidget('Plots', self.iface.mainWindow()) self.plot_dock.setObjectName('Plots') # Create tab container self.plot_tabs = QTabWidget(self.plot_dock) self.plot_tabs.addTab(self.ts_plot, self.ts_plot.__str__()) self.plot_tabs.addTab(self.doy_plot, self.doy_plot.__str__()) # Add to dock widget self.plot_dock.setWidget(self.plot_tabs) # Add to iface self.iface.addDockWidget(Qt.BottomDockWidgetArea, self.plot_dock) def initGui(self): """ Required method for Qt to load components. Load controls, plot, and init the signal controller """ self.init_controls() self.init_plots() self.controller = Controller(self.iface, self.ctrl, self.ts_plot, self.doy_plot, parent=self) self.controller.enable_tool.connect(self.set_tool) self.controller.disable_tool.connect(self.unset_tool) self.plot_tabs.currentChanged.connect(self.controller.changed_tab) def plot_request(self, pos, button=None): """ Request handler for QgsMapToolEmitPoint. Gets position and sends signal to controller to grab data & plot """ if self.tool_enabled is False: print 'NO PLOT FOR YOU' return # Check if user has a layer added if self.canvas.layerCount() == 0 or pos is None: self.iface.messageBar().pushMessage('Error', 'Please add a layer before clicking...', level=QgsMessageBar.WARNING, duration=3) # Check currently selected layer #TODO remove? layer = self.canvas.currentLayer() if (layer is None or not layer.isValid() or layer.type() != QgsMapLayer.RasterLayer or layer not in setting.image_layers): self.iface.messageBar().pushMessage('Info', 'Please select a layer from time series before clicking', level=QgsMessageBar.WARNING, duration=2) return # Check if position needs to be reprojected to layer CRS layer_crs = layer.crs() map_crs = self.canvas.mapRenderer().destinationCrs() if not map_crs == layer_crs: if self.canvas.hasCrsTransformEnabled(): crs_transform = QgsCoordinateTransform(map_crs, layer_crs) try: pos = crs_transform.transform(pos) except: self.iface.messageBar().pushMessage('Error', 'Could not convert map CRS to layer CRS', level=QgsMessageBar.WARNING, duration=5) return else: self.iface.messageBar().pushMessage('Error', 'Could not convert map CRS to layer CRS', level=QgsMessageBar.WARNING, duration=5) return # Fetch data if inside raster if layer and layer.extent().contains(pos): # Fetch data self.controller.fetch_data(pos) if setting.canvas['show_click']: self.controller.show_click(pos) else: self.iface.messageBar().pushMessage('Warning', 'Please select a point within the time series image', level=QgsMessageBar.WARNING, duration=5) def unload(self): """ Shutdown and disconnect """ # Remove toolbar icons self.iface.removeToolBarIcon(self.action) self.iface.removeToolBarIcon(self.action_cfg) # Remove panels self.iface.removeDockWidget(self.plot_dock) self.iface.removeDockWidget(self.ctrl_dock) # Disconnect signals self.controller.disconnect()
class WaysCalc: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( self.plugin_dir, 'i18n', 'WaysCalc_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = self.tr(u'&WaysCalc') # TODO: We are going to let the user set this up in a future iteration # self.toolbar = self.iface.addToolBar(u'WaysCalc') # self.toolbar.setObjectName(u'WaysCalc') #print "** INITIALIZING WaysCalc" self.pluginIsActive = False self.dockwidget_inters_ways = None self.dockwidget_inters_allways = None # self.settings = None self.IW = None #IntersectionWays self.IAW = None #IntersectionAllWays # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('WaysCalc', message) def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" # выпадающая кнопка для пересекающихся маршрутов self.toolButton = QToolButton() self.toolButton.setMenu(QMenu()) # setPopupMode: DelayedPopup, MenuButtonPopup, InstantPopup self.toolButton.setPopupMode(QToolButton.InstantPopup) self.toolButton.setAutoRaise(True) self.toolButton_action = self.iface.addToolBarWidget(self.toolButton) self.action_intersection = QAction( QIcon(":/plugins/_Ways_calc/icon.png"), u'Поиск пересечений для линейного объекта', self.iface.mainWindow()) self.action_initLayerWays = QAction( u"Выбор слоя для поиска пересечений", self.iface.mainWindow()) self.action_allintersection = QAction( QIcon(":/plugins/_Ways_calc/icon.png"), u'Поиск пересечений всех линейных объектов', self.iface.mainWindow()) self.iface.addPluginToMenu(u"WaysCalc", self.action_intersection) self.iface.addPluginToMenu(u"WaysCalc", self.action_initLayerWays) self.iface.addPluginToMenu(u"WaysCalc", self.action_allintersection) # self.iface.addToolBarIcon(self.action_intersection) m = self.toolButton.menu() m.addAction(self.action_intersection) m.addAction(self.action_initLayerWays) m.addSeparator() m.addAction(self.action_allintersection) self.toolButton.setDefaultAction(self.action_intersection) self.action_intersection.triggered.connect(self.run_intersection) # пересекающиеся маршруты self.action_allintersection.triggered.connect(self.run_allintersection) # пересекающиеся все маршруты self.action_initLayerWays.triggered.connect(self.run_initLayerWays) # выбор слоя сравнения self.pointEmitterIntersection = QgsMapToolEmitPoint(self.iface.mapCanvas()) self.pointEmitterIntersection.setAction(self.action_intersection) self.pointEmitterIntersection.canvasClicked.connect(self.pointEmitterIntersectioncanvasClicked) self.iface.mapCanvas().currentLayerChanged.connect(self.onCurrentLayerChanged) #-------------------------------------------------------------------------- def onClosePlugin(self): """Cleanup necessary items here when plugin dockwidget is closed""" # disconnects try: self.dockwidget_inters_ways.closingPlugin.disconnect(self.onClosePlugin) except: pass try: self.dockwidget_inters_allways.closingPlugin.disconnect(self.onClosePlugin) except: pass self.pluginIsActive = False def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" self.iface.removePluginMenu(u"WaysCalc", self.action_intersection) self.iface.removePluginMenu(u"WaysCalc", self.action_allintersection) self.iface.removePluginMenu(u"WaysCalc", self.action_initLayerWays) self.iface.removeToolBarIcon(self.action_intersection) self.iface.removeToolBarIcon(self.action_intersection) self.iface.removeToolBarIcon(self.toolButton_action) self.action_intersection.triggered.disconnect(self.run_intersection) # пересекающиеся маршруты self.action_allintersection.triggered.disconnect(self.run_allintersection) # пересекающиеся все маршруты self.action_initLayerWays.triggered.disconnect(self.run_initLayerWays) # выбор слоя сравнения self.pointEmitterIntersection.canvasClicked.connect(self.pointEmitterIntersectioncanvasClicked) self.iface.mapCanvas().currentLayerChanged.disconnect(self.onCurrentLayerChanged) if self.IW is not None: self.IW.onUnLoadModule() def init_dock_inters_ways(self, dock): """Run method that loads and starts the plugin""" # if not self.pluginIsActive: self.pluginIsActive = True if self.dockwidget_inters_ways == None: self.dockwidget_inters_ways = WaysCalcDockWidget() self.dockwidget_inters_ways.closingPlugin.connect(self.onClosePlugin) self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockwidget_inters_ways) self.dockwidget_inters_ways.hide() self.dockwidget_inters_ways.setWindowTitle(u'WaysCalc: Поиск пересечений для линейного объекта') def init_dock_inters_allways(self, dock): """Run method that loads and starts the plugin""" # if not self.pluginIsActive: self.pluginIsActive = True if self.dockwidget_inters_allways == None: self.dockwidget_inters_allways = WaysCalcDockWidget() self.dockwidget_inters_allways.closingPlugin.connect(self.onClosePlugin) self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockwidget_inters_allways) self.dockwidget_inters_allways.hide() self.dockwidget_inters_allways.setWindowTitle(u'WaysCalc: Поиск пересечений всех линейных объектов') def onCurrentLayerChanged(self): self.iface.mapCanvas().unsetMapTool(self.pointEmitterIntersection) #-------------------------------------------------------------------------- # def loadSettings(self): # with open(os.path.join(self.plugin_dir, "settings.json"), "r") as read_file: # self.settings = json.load(read_file) #--------INTERSECTION WAYS------------------------------------------------- def run_initLayerWays(self): if self.IW is None: self.init_IW() self.IW.initLayerWays() def run_intersection(self): self.toolButton.setDefaultAction(self.action_intersection) self.init_dock_inters_ways(self.dockwidget_inters_ways) if self.IW is None: self.init_IW() if self.IW.checkLayers(): self.iface.mapCanvas().setMapTool(self.pointEmitterIntersection) def pointEmitterIntersectioncanvasClicked(self, point, button): self.IW.insersection_take_way(point) def init_IW(self): self.IW = IntersectionWays(self.iface, self.dockwidget_inters_ways) #-------- END INTERSECTION WAYS--------------------------------------------- def init_IAW(self): self.IAW = IntersectionAllWays(self.iface, self.dockwidget_inters_allways) def run_allintersection(self): self.init_dock_inters_allways(self.dockwidget_inters_allways) if self.IAW is None: self.init_IAW() self.IAW.showClickedFeaturesList()