diff --git a/get_nib/__init__.py b/get_nib/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7b0b10760ab1343d3a50b6f9202766737888a2aa --- /dev/null +++ b/get_nib/__init__.py @@ -0,0 +1,36 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + getnib + A QGIS plugin + Hent alle of-prosket i utsnitt + Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/ + ------------------- + begin : 2021-12-22 + copyright : (C) 2021 by ban, NIBIO + email : ban@nibio.no + git sha : $Format:%H$ + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + This script initializes the plugin, making it known to QGIS. +""" + + +# noinspection PyPep8Naming +def classFactory(iface): # pylint: disable=invalid-name + """Load getnib class from file getnib. + + :param iface: A QGIS interface instance. + :type iface: QgsInterface + """ + # + from .get_nib import getnib + return getnib(iface) diff --git a/get_nib/get_nib.py b/get_nib/get_nib.py new file mode 100644 index 0000000000000000000000000000000000000000..d5371389a2ff48016093971a68b4087c8ffd7d43 --- /dev/null +++ b/get_nib/get_nib.py @@ -0,0 +1,423 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + getnib + A QGIS plugin + + Plugin "NIB-ortofoto-prosjekt" + Hent alle of-prosjekt i et utsnitt fra Norge i bilder (WMS) + Utsnittet kan være bounding boksen til + - et kartlag i Layers panel + - en fil man laster opp + - aktuelt map canvas + +Ressures brukt: + - Plugin Builder for å få riktig oppsett og nødvendige filer + - https://www.qgistutorials.com/en/docs/3/building_a_python_plugin.html + NB! husk å lage og å kopiere over compile.bat (trengs for å kompilere resources.py slik at f.eks. eget icon skal bli synlig) + Se også https://gis.stackexchange.com/questions/136861/getting-layer-by-name-in-pyqgis + - https://docs.qgis.org/testing/en/docs/pyqgis_developer_cookbook/cheat_sheet.html# + - https://docs.qgis.org/3.16/en/docs/pyqgis_developer_cookbook/plugins/index.html + - https://norgeibilder.no/dok/webtjenester.pdf for å få tilgang til Metadata og se påkrevd format på input-verdier + - installert QGIS plugin "Releod plugin" for å oppdatere endringer gjort i plugin-en + - OSGeo4W-installasjon av QGIS med Qt Designer inkludert mtp. utforming av plugin + - logo hentet fra https://www.flaticon.com + Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/ + ------------------- + begin : 2021-12-22 + git sha : $Format:%H$ + copyright : (C) 2021 by ban, NIBIO + email : ban@nibio.no + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" +#Default modules +from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication +from qgis.PyQt.QtGui import QIcon +from qgis.PyQt.QtWidgets import QAction, QFileDialog + +#Import additional modules +from qgis.core import QgsProject, Qgis, QgsMessageLog, QgsRasterLayer, QgsVectorLayer, QgsCoordinateReferenceSystem, QgsCoordinateTransform, QgsPointXY +from qgis.gui import QgsMapCanvas +from qgis.utils import iface +from urllib import request, parse # for å lese url, gå gjennom streng +import os + +# Initialize Qt resources from file resources.py +from .resources import * +# Import the code for the dialog +from .get_nib_dialog import getnibDialog +import os.path + + +class getnib: + """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', + 'getnib_{}.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'&NIB of-prosjekt') + + # Check if plugin was started the first time in current QGIS session + # Must be set in initGui() to survive plugin reloads + self.first_start = None + + # 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('getnib', 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 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 show 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: + # Adds plugin icon to Plugins toolbar + self.iface.addToolBarIcon(action) + + if add_to_menu: + self.iface.addPluginToMenu( + self.menu, + action) + + self.actions.append(action) + + return action + + def initGui(self): + """Create the menu entries and toolbar icons inside the QGIS GUI.""" + + icon_path = ':/plugins/get_nib/icon.png' + self.add_action( + icon_path, + text=self.tr(u'Hent of-prosjekt'), + callback=self.run, + parent=self.iface.mainWindow()) + + # will be set False in run() + self.first_start = True + + + def unload(self): + """Removes the plugin menu item and icon from QGIS GUI.""" + for action in self.actions: + self.iface.removePluginMenu( + self.tr(u'&NIB of-prosjekt'), + action) + self.iface.removeToolBarIcon(action) + + """ Additional methods """ + def select_input_file(self): + """ Får å velge fil som skal tjene som bounding box """ + filename, _filter = QFileDialog.getOpenFileName( + self.dlg, "Select a file ","", 'geo-files (*.shp *.geojson *.gpkg *.gml *.jpg *.tif);; All files (*.*)') + self.dlg.lineEdit.setText(filename) + + def check_bbsize(self, srid, xmin, xmax, ymin, ymax): + """ Check length and height of bounding box. Limit is set to 50 km """ + sourceCrs = QgsCoordinateReferenceSystem(srid) # Input project or layer crs + destCrs = QgsCoordinateReferenceSystem('EPSG:3035') # ETRS89-extended / LAEA Europe + transformContext = QgsProject.instance().transformContext() + xform = QgsCoordinateTransform(sourceCrs, destCrs, transformContext) + # Forward transformation: src -> dest + # Computes length and height in LAE regardless input crs + ll = xform.transform(QgsPointXY(xmin,ymin)) # Bounding box's lower left corner + ur = xform.transform(QgsPointXY(xmax,ymax)) # Bounding box's upper right corner + # Get the maximum height and length of the bounding box (limit is set to 50 km) + xdist = (ur.x()-ll.x())/1000 # Get lenght in km (xmax-xmin) + ydist = (ur.y()-ll.y())/1000 # Get height in km (ymax-ymin) + if xdist > 50 or ydist > 50: + self.iface.messageBar().pushMessage("Error", "Height or length of bounding box can't be > 50 km",level=Qgis.Critical, duration=3) + ok = False + else: + ok = True # Bounding box is small enough + return ok + """ end additional methods """ + + def run(self): + """Run method that performs all the real work""" + + # Create the dialog with elements (after translation) and keep reference + # Only create GUI ONCE in callback, so that it will only load when the plugin is started + if self.first_start == True: + self.first_start = False + self.dlg = getnibDialog() + """ Additional code """ + #connect the select_input_file method to the clicked signal of the push button widget + self.dlg.pushButton.clicked.connect(self.select_input_file) + + # Fetch the currently loaded layers + layers = QgsProject.instance().mapLayers() + # Clear the contents of the combobox from previous runs + self.dlg.comboBox.clear() + # Populate the combobox with names of all the loaded layers + layer_list = [] + unique_lyr = [] + for layer in layers.values(): + item = layer.name() + layer_list.append(item) # Includes duplicates + unique_lyr = list(set(layer_list)) # No duplicates + self.dlg.comboBox.addItems(unique_lyr) # Populate combobox + self.dlg.comboBox.model().sort(0) # Sort layer names (includes filepath) alfabetically + # Clear the contents of the lineEdit from previous runs + self.dlg.lineEdit.clear() + # As default: Remember user input from previous run + """ If this should not be the default, remove comment # from next line """ + # self.dlg.checkBoxNib.setChecked(False) # Unchecked + # As default: Set map canvas checkbox to checked + """ If this should not be the default, comment # next line """ + self.dlg.checkBox.setChecked(True) # Checked + + # Get projects epsg-code # e.g. + crs_proj_str = iface.mapCanvas().mapSettings().destinationCrs().authid() # EPSG:25832 + crs_proj_int = int(crs_proj_str[5:]) # 25832 + """ end additional code """ + + # show the dialog + self.dlg.show() + # Run the dialog event loop + result = self.dlg.exec_() + # See if OK was pressed + if result: + # Do something useful here - delete the line containing pass and + # substitute with your code. + # pass + """" Additional code""" + selectedLayer = '' # Initialise + reset = False + if self.dlg.checkBoxNib.isChecked(): + reset = True + # If checked, use the bounding box (= extent of current map canvas) + if self.dlg.checkBox.isChecked(): + # Get the extent of current map canvas (coordinates in the project's crs) + e = iface.mapCanvas().extent() + xmin = e.xMinimum() + xmax = e.xMaximum() + ymin = e.yMinimum() + ymax = e.yMaximum() + ok = self.check_bbsize(crs_proj_str, xmin, xmax, ymin, ymax) # Check if bb is small enough + else: # If not checked, use existing layer or open new from file + fname = self.dlg.lineEdit.text() # get the text (path and filename) + lname = os.path.splitext(os.path.basename(fname))[0] #get only the filename without the extension, will be used as layer name in the Layers panel in QGIS + # No file is chosen + if fname == "": # Use selected layer from combobox + lyr_name = self.dlg.comboBox.currentText() # Get the layer name + if lyr_name != "": # If a layer is present/chosen + selectedLayer = QgsProject.instance().mapLayersByName(lyr_name)[0] # Get this vector layer + # Get the extent of the file (coordinates in the selected layer's crs) + e = selectedLayer.extent() + else: # If no file or layer is selcted, throw an error mesage and end plugin + self.iface.messageBar().pushMessage("Error", "Nothing selected!", level=Qgis.Critical, duration=3) + return # Return from (end) plugin + else: # Use selected file + file = r""+fname+"" # Reads the file + fLayer = QgsVectorLayer(file, lname, "ogr") # If vector fie + if not fLayer.isValid(): # If not valid vector laayer + fLayer = QgsRasterLayer(file, lname, "gdal") # If raster file + if not fLayer.isValid(): # If not valid raster layer either, show error message and end plugin + self.iface.messageBar().pushMessage("Error", "Not a valid geo-file: "+ str(lname),level=Qgis.Critical, duration=3) + return # Return from (end) plugin + QgsProject.instance().addMapLayer(fLayer, True) # Add the layer and show it (True) + selectedLayer = QgsProject.instance().mapLayersByName(lname)[0] # Get this layer + # Get the extent of the active layer (coordinates in the selected file's crs) + e = selectedLayer.extent() + + # Activate (select) the selected layer in the combobox or in the lineEdit + iface.setActiveLayer(selectedLayer) + # Zoom to activated layer + iface.zoomToActiveLayer() + + # Get selected layer's epsg:code + crs_lyr = selectedLayer.crs() # example: + crs_lyr_str = crs_lyr.authid() # EPSG:4258 + try: + crs_lyr_int = int(crs_lyr_str[5:]) # 4258 + except: # In case a non-geo-layer (e.g. csv-file) is selected from the combobox + self.iface.messageBar().pushMessage("Error", "Layer is missing crs", level=Qgis.Critical, duration=3) + layers = [] # Empty layers to get a fresh start when rerunning the plugin + return # Return from (end) plugin + + # Get the extent of the active layer (coordinates in file or layer crs) + xmin = e.xMinimum() + xmax = e.xMaximum() + ymin = e.yMinimum() + ymax = e.yMaximum() + # If selected file or layer and project have different crs, the layer's + # bounding box coordinates must be transformed into the project's crs + if crs_lyr_int != crs_proj_int: + sourceCrs = QgsCoordinateReferenceSystem(crs_lyr_str) + destCrs = QgsCoordinateReferenceSystem(crs_proj_str) + transformContext = QgsProject.instance().transformContext() + xform = QgsCoordinateTransform(sourceCrs, destCrs, transformContext) + # forward transformation: src -> dest + pt1 = xform.transform(QgsPointXY(xmin,ymin)) + pt2 = xform.transform(QgsPointXY(xmax,ymax)) + xmin = pt1.x() + xmax = pt2.x() + ymin = pt1.y() + ymax = pt2.y() + # Check if bb is small enough - input crs and transformed bb coordinates are in project crs + ok = self.check_bbsize(crs_proj_str, xmin, xmax, ymin, ymax) + else: # Selected file or layer and project have the same crs + # Check if bb is small enough - input crs and bb coordinates are in layer crs = project crs + ok = self.check_bbsize(crs_lyr_str, xmin, xmax, ymin, ymax) + + if ok: # If bb small enough, get the corner coordinates (to be used in url-request) + # Set bounding box corner coordinates as geojson (x1,y1;x2,y2;...) + coords = "%f,%f;%f,%f;%f,%f;%f,%f" %(xmin,ymin,xmin,ymax,xmax,ymax,xmax,ymin) + else: # If bb too large + return # Return from (end) plugin + + # Accessing layers' tree root + root = QgsProject.instance().layerTreeRoot() + + # If reset box is checked, group "Nib-prosjekt" is deleted before recreated + # and filled with layers + if reset: # The reset box is checked + group = root.findGroup('Nib-prosjekt') # Find the group + root.removeChildNode(group) # Remove the group + # Recreate Nib-prosjekt group + # Add a layer group to be used for all orthophoto-projects within the active layer's extent + if not root.findGroup("Nib-prosjekt"): # If the group don't exist + group = root.addGroup('Nib-prosjekt') # add the group and name it "Nib-prosjekt" + # group.setExpanded(False) # Collapse the layer group + + # Load Norge i bilder-project based on active layer's bounding box + # (geojson-format x1,y1;x2,y2;x3,y3;...) + # https://stackoverflow.com/questions/50337388/how-to-use-special-character-%c3%a6-%c3%b8-or-%c3%a5-in-a-urllib-request-urlopen-in-python-3 + para=parse.quote('{Filter:"ortofototype in (1,2,3,4,8,9,12)",Coordinates:"'+coords+'",InputWKID:'+str(crs_proj_int)+',StopOnCover:false}') + inn = request.urlopen('https://tjenester.norgeibilder.no/rest/projectMetadata.ashx?request='+para).read() #list with of-projects + ut = inn.decode() # Convert from bytes to string + ut = ut.replace('"','') # Remove quotes, i.e. replace " with nothing + a = ut.split("[") # Split string in two at bracket [ + b = a[1].split("]") # Split 2nd. substring at each bracket [ gives 2 elements since there is only one occurence of [ (counting starts at 0) + nib_liste = b[0].split(",") + lyr = '' # Initiate + for nibprosjwms in nib_liste: # Loads WMS (raster layer) for each of-project within the bounding box in question + urlWithParams = 'contextualWMSLegend=0&crs=EPSG:'+str(crs_proj_int)+'&dpiMode=7&featureCount=10&format=image/png&layers='+nibprosjwms+'&styles&url=https://wms.geonorge.no/skwms1/wms.nib-prosjekter' + rlayer = QgsRasterLayer(urlWithParams, nibprosjwms, 'wms') # Get the raster layer + if rlayer.isValid(): # Valid raster layer + layers = QgsProject.instance().mapLayersByName(nibprosjwms) # Check if loaded layer already exists + if layers: + lyr = layers[0] + tree_layer = root.findLayer(lyr.id()) + if tree_layer: # True if layer exists, otherwise False + layer_parent = tree_layer.parent() + if str(layer_parent.name()) == 'Nib-prosjekt': # If layer exists in group Nib-prosjekt, it will not be added + self.iface.messageBar().pushMessage("Info", "WMS layer exists: "+ str(nibprosjwms),level=Qgis.Info, duration=1) + continue # Return the control to the beginning of the for loop + else: # The layer exists but not in the Nib-prsjekt group + QgsProject.instance().addMapLayer(rlayer, False) # Add the raster layer without showing it (False) + mygroup = root.findGroup("Nib-prosjekt") # Get the group named "Nib-prosjekt" + mygroup.addLayer(rlayer) # Add the layer to this group + # Uncheck the raster layer + QgsProject.instance().layerTreeRoot().findLayer(rlayer.id()).setItemVisibilityChecked(False) + self.iface.messageBar().pushMessage("Success", "WMS reloaded", level=Qgis.Success, duration=3) + else: # layer does not exist, thus it will be addedd + QgsProject.instance().addMapLayer(rlayer, False) # Add the raster layer without showing it (False) + mygroup = root.findGroup("Nib-prosjekt") # Get the group named "Nib-prosjekt" + mygroup.addLayer(rlayer) # Add the layer to this group + # Uncheck the raster layer + QgsProject.instance().layerTreeRoot().findLayer(rlayer.id()).setItemVisibilityChecked(False) + self.iface.messageBar().pushMessage("Success", "WMS added in Nib-prosjekt", level=Qgis.Success, duration=3) + else: # If not valid raster layer, an error message will appear + self.iface.messageBar().pushMessage("Warning", "Can't load: "+ str(nibprosjwms),level=Qgis.Warning, duration=3) diff --git a/get_nib/get_nib_dialog.py b/get_nib/get_nib_dialog.py new file mode 100644 index 0000000000000000000000000000000000000000..36d9def7fc4501b232cb1e032d50ccd21f0b2495 --- /dev/null +++ b/get_nib/get_nib_dialog.py @@ -0,0 +1,50 @@ +# -*- coding: utf-8 -*- +""" +/*************************************************************************** + getnibDialog + A QGIS plugin + Plugin "NIB of-prosjekt" + Hent alle of-prosjekt i et utsnitt fra Norge i bilder (WMS) + Utsnittet kan være bounding boksen til + - et kartlag i Layers panel + - en fil man laster opp + - aktuelt map canvas + + Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/ + ------------------- + begin : 2021-12-22 + git sha : $Format:%H$ + copyright : (C) 2021 by ban, NIBIO + email : ban@nibio.no + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ +""" + +import os + +from qgis.PyQt import uic +from qgis.PyQt import QtWidgets + +# This loads your .ui file so that PyQt can populate your plugin with the elements from Qt Designer +FORM_CLASS, _ = uic.loadUiType(os.path.join( + os.path.dirname(__file__), 'get_nib_dialog_base.ui')) + + +class getnibDialog(QtWidgets.QDialog, FORM_CLASS): + def __init__(self, parent=None): + """Constructor.""" + super(getnibDialog, self).__init__(parent) + # Set up the user interface from Designer through FORM_CLASS. + # After self.setupUi() you can access any designer object by doing + # self.<objectname>, and you can use autoconnect slots - see + # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html + # #widgets-and-dialogs-with-auto-connect + self.setupUi(self) diff --git a/get_nib/get_nib_dialog_base.ui b/get_nib/get_nib_dialog_base.ui new file mode 100644 index 0000000000000000000000000000000000000000..2675efc6ff1c4a4f086d1f77981da2c5349f0aca --- /dev/null +++ b/get_nib/get_nib_dialog_base.ui @@ -0,0 +1,173 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>getnibDialogBase</class> + <widget class="QDialog" name="getnibDialogBase"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>331</width> + <height>180</height> + </rect> + </property> + <property name="windowTitle"> + <string>NIB of-prosjekt</string> + </property> + <widget class="QDialogButtonBox" name="button_box"> + <property name="geometry"> + <rect> + <x>-20</x> + <y>140</y> + <width>341</width> + <height>32</height> + </rect> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + <widget class="QPushButton" name="pushButton"> + <property name="geometry"> + <rect> + <x>280</x> + <y>110</y> + <width>40</width> + <height>23</height> + </rect> + </property> + <property name="text"> + <string>...</string> + </property> + </widget> + <widget class="QComboBox" name="comboBox"> + <property name="geometry"> + <rect> + <x>88</x> + <y>70</y> + <width>231</width> + <height>22</height> + </rect> + </property> + </widget> + <widget class="QCheckBox" name="checkBox"> + <property name="geometry"> + <rect> + <x>10</x> + <y>40</y> + <width>311</width> + <height>17</height> + </rect> + </property> + <property name="font"> + <font> + <pointsize>10</pointsize> + </font> + </property> + <property name="text"> + <string>Use current map canvas</string> + </property> + </widget> + <widget class="QLineEdit" name="lineEdit"> + <property name="geometry"> + <rect> + <x>90</x> + <y>110</y> + <width>181</width> + <height>22</height> + </rect> + </property> + </widget> + <widget class="QLabel" name="label_lyr"> + <property name="geometry"> + <rect> + <x>10</x> + <y>70</y> + <width>81</width> + <height>16</height> + </rect> + </property> + <property name="font"> + <font> + <pointsize>10</pointsize> + </font> + </property> + <property name="text"> + <string>Select layer</string> + </property> + </widget> + <widget class="QLabel" name="label_file"> + <property name="geometry"> + <rect> + <x>10</x> + <y>110</y> + <width>71</width> + <height>16</height> + </rect> + </property> + <property name="font"> + <font> + <pointsize>10</pointsize> + </font> + </property> + <property name="text"> + <string>Select file</string> + </property> + </widget> + <widget class="QCheckBox" name="checkBoxNib"> + <property name="geometry"> + <rect> + <x>10</x> + <y>10</y> + <width>271</width> + <height>17</height> + </rect> + </property> + <property name="font"> + <font> + <pointsize>10</pointsize> + </font> + </property> + <property name="text"> + <string>Reset (empty) "Nib-prosjekt"-group</string> + </property> + </widget> + </widget> + <resources/> + <connections> + <connection> + <sender>button_box</sender> + <signal>accepted()</signal> + <receiver>getnibDialogBase</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>20</x> + <y>20</y> + </hint> + <hint type="destinationlabel"> + <x>20</x> + <y>20</y> + </hint> + </hints> + </connection> + <connection> + <sender>button_box</sender> + <signal>rejected()</signal> + <receiver>getnibDialogBase</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>20</x> + <y>20</y> + </hint> + <hint type="destinationlabel"> + <x>20</x> + <y>20</y> + </hint> + </hints> + </connection> + </connections> +</ui> diff --git a/get_nib/icon.png b/get_nib/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..763888c820bc556df47ea0fce2b581e22a5f0894 Binary files /dev/null and b/get_nib/icon.png differ diff --git a/get_nib/metadata.txt b/get_nib/metadata.txt new file mode 100644 index 0000000000000000000000000000000000000000..19e175154f72e0a5021bff4343169fc28ee19e0b --- /dev/null +++ b/get_nib/metadata.txt @@ -0,0 +1,63 @@ +# This file contains metadata for your plugin. +# This file should be included when you package your plugin. + +# Mandatory items: + +[general] +name=NIB-ortofoto-prosjekt +qgisMinimumVersion=3.0 +description=Hent alle ortofoto-prosjekt fra Norge i bilder (WMS) som ligger innafor et utsnitt + +version=0.5 +author=ban, NIBIO +email=ban@nibio.no + +about=Utsnittet kan være bounding boksen til + - et kartlag i Layers panel (table of contents (TOC)) + - en fil man laster opp + - aktuelt map canvas (default) + + Utsnittet kan ikke overskride 50 km x 50 km. + Alle WMS-layere (ortofoto) havner i en egen gruppe "Nib-prosjekt". + Tidligere innhenta ortofoto kan slettes før nye hentes inn (husker siste valg). + +tracker=http://bugs +repository=http://repo + +# End of mandatory metadata + + +# Recommended items: + +hasProcessingProvider=no +# Uncomment the following line and add your changelog: +changelog= + 0.1: Default logo og kun vektor-layer og -fil mulig for utsnitt, Nib-prosjekt kollapser + 0.2: Egen logo, inkludert current map canvas for utsnitt, bruke prosjektets crs som WMS-crs + 0.3: Slette eksisterende WMS-layere i Nib-prosjekt-gruppa, maks. utsnitt satt til 50 km x 50 km og current map canvas satt til default + 0.4: Inkludert raster-layer og -fil for utsnitt + 0.5: Mulig å tømme "Nib-prosjekt" før ny ortofoto-innhenting (husker siste valg), Nib-prosjekt ekspanderer slik at alle wms-lag sees umiddelbart - alle lag er imidlertid slått av for raskere opptegning + +# Tags are comma separated with spaces allowed +tags=python, wms, vector, extent + +homepage=http://homepage +category=WMS +icon=icon.png +# experimental flag +experimental=True + +# deprecated flag (applies to the whole plugin, not just a single version) +deprecated=False + +# Since QGIS 3.8, a comma separated list of plugins to be installed +# (or upgraded) can be specified. +# Check the documentation for more information. +# plugin_dependencies= + +Category of the plugin: Raster, Vector, Database or Web +#category=Vector + +# If the plugin can run on QGIS Server. +server=False + diff --git a/get_nib/resources.py b/get_nib/resources.py new file mode 100644 index 0000000000000000000000000000000000000000..19091ab6aadee93bf8396f864f54e2c3db56e73e --- /dev/null +++ b/get_nib/resources.py @@ -0,0 +1,105 @@ +# -*- coding: utf-8 -*- + +# Resource object code +# +# Created by: The Resource Compiler for PyQt5 (Qt v5.15.2) +# +# WARNING! All changes made in this file will be lost! + +from PyQt5 import QtCore + +qt_resource_data = b"\ +\x00\x00\x02\x94\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x17\x00\x00\x00\x17\x08\x06\x00\x00\x00\xe0\x2a\xd4\xa0\ +\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ +\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x04\x67\x41\x4d\x41\x00\x00\xb1\x8f\x0b\xfc\x61\x05\x00\x00\x00\ +\x09\x70\x48\x59\x73\x00\x00\x0e\xc4\x00\x00\x0e\xc4\x01\x95\x2b\ +\x0e\x1b\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\x74\x77\x61\ +\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\x70\x65\x2e\ +\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x01\xf4\x49\x44\x41\x54\x48\ +\x4b\x8d\x95\xbb\xcf\x31\x41\x14\xc6\xe7\xfb\x3a\x3a\x8d\x88\x42\ +\xaf\x52\xd0\xe8\x14\x22\xa1\xd7\xea\x68\xe8\x84\x0a\x89\x42\x41\ +\xa2\xa5\xd1\xb9\x25\x88\x4a\xad\x11\x7f\x83\x84\x28\x49\xd4\x12\ +\xa2\x9a\x77\x9f\xb3\x33\xbb\xec\xce\x0e\xbf\x64\x9c\xdb\x73\x9e\ +\x5d\x77\xc6\x7f\xa0\xd1\x68\x70\xbf\xdf\xcf\x19\x63\x14\x51\xff\ +\xc2\x57\x73\x18\xe2\xb4\xdb\x6d\xbe\xdd\x6e\x29\xca\xde\x37\xb4\ +\x8a\x74\x3a\xfd\x61\xb2\xdb\xed\x44\x66\x5e\x14\x73\x1d\x5a\x73\ +\x18\x6c\x36\x1b\x2b\x97\x07\xa0\x2f\x73\x2f\x3c\xa7\x87\xc3\xc1\ +\x5a\xae\xd5\x6a\x56\x8e\x88\x5a\xe6\xd0\x79\xf1\xdf\x10\x28\x09\ +\x87\xc3\x14\xaf\xd7\x2b\x4b\xa5\x52\x94\xe7\xf3\x79\x8a\xa8\x2f\ +\x97\x0b\xe5\x52\xa7\x44\x5c\x44\x09\xc6\xf5\x7a\x9d\xf2\x7e\xbf\ +\xcf\x23\x91\x08\x45\x50\xad\x56\xad\x67\xe3\x85\x76\xda\xe9\x74\ +\x3c\x0d\xd0\xef\x76\xbb\xa2\x52\xe3\x69\x7e\x3a\x9d\xc8\x00\x67\ +\x34\x1a\x89\xae\xc9\x70\x38\xb4\x66\xc7\xe3\x51\x74\xdd\x28\xcd\ +\x8d\xd7\x93\x16\x73\xb9\x1c\x2f\x95\x4a\x94\xbf\x83\xba\x52\xa9\ +\xf0\x6c\x36\x4b\x39\xf4\x2a\x94\xe6\x58\x88\x46\xa3\xa2\x32\xeb\ +\x62\xb1\x48\x79\xa1\x50\xf8\xb8\x18\x74\xef\xf5\x3b\xae\xee\x64\ +\x32\x71\x89\xa7\xd3\x29\xf5\xd6\xeb\x35\xc5\xd5\x6a\x25\x26\x26\ +\xe8\x61\xcf\x89\xcb\x3c\x1e\x8f\x73\xe3\xa3\x26\x2a\x1b\x79\x87\ +\xb1\x58\x4c\x74\x6c\xa0\x4f\x24\x12\xa2\xb2\xb1\xcc\x6f\xb7\x1b\ +\x1f\x0c\x06\x64\x90\xc9\x64\xf8\x62\xb1\x10\x13\x1b\xcc\x9c\x2c\ +\x97\x4b\xd2\x63\x86\x7d\xf8\x48\x2c\xf5\x7e\xbf\x27\x81\x3c\xc1\ +\x60\x50\x4c\xf4\x40\xf7\xbe\x07\x1f\x89\xeb\x56\x02\x81\x80\xf5\ +\xc5\xf9\x15\xe8\xb1\xe7\xc4\x65\xae\xfa\xe8\x7d\x03\x7a\xec\x39\ +\x71\xb9\xdc\xef\x77\x12\x8f\xc7\x63\xd1\xd1\x03\x1d\xf4\xd8\x73\ +\xa2\xbc\xc5\x72\xb9\x4c\x0b\xe7\xf3\x59\x74\xd4\x60\x0e\x1d\xf4\ +\x2a\x3c\x9f\x7f\x32\x99\xa4\xc5\x66\xb3\x49\xf5\xeb\xf5\xa2\x1a\ +\x11\xb4\x5a\x2d\xaa\xa1\xf3\x42\xfb\xe2\xf6\x7a\x3d\x32\xc0\x09\ +\x85\x42\x1f\x11\x07\x73\x1d\x3f\xbd\x73\xf3\xf9\x9c\x1b\xbf\xe5\ +\x64\x88\x38\x9b\xcd\xc4\x44\xcf\x3f\x3c\x18\x4b\x5f\x79\x3e\x9f\ +\xcc\xf8\xe7\x67\x8f\xc7\x83\xf9\x7c\x3e\xd1\xd5\xc1\xd8\x1f\x3c\ +\x0b\x5d\x40\x01\xcd\x27\xcb\x00\x00\x00\x00\x49\x45\x4e\x44\xae\ +\x42\x60\x82\ +" + +qt_resource_name = b"\ +\x00\x07\ +\x07\x3b\xe0\xb3\ +\x00\x70\ +\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\x00\x73\ +\x00\x07\ +\x0d\xca\x64\x32\ +\x00\x67\ +\x00\x65\x00\x74\x00\x5f\x00\x6e\x00\x69\x00\x62\ +\x00\x08\ +\x0a\x61\x5a\xa7\ +\x00\x69\ +\x00\x63\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\ +" + +qt_resource_struct_v1 = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ +\x00\x00\x00\x14\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\ +\x00\x00\x00\x28\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +" + +qt_resource_struct_v2 = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x14\x00\x02\x00\x00\x00\x01\x00\x00\x00\x03\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x28\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01\x7d\xed\xb0\x55\xea\ +" + +qt_version = [int(v) for v in QtCore.qVersion().split('.')] +if qt_version < [5, 8, 0]: + rcc_version = 1 + qt_resource_struct = qt_resource_struct_v1 +else: + rcc_version = 2 + qt_resource_struct = qt_resource_struct_v2 + +def qInitResources(): + QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/get_nib/resources.qrc b/get_nib/resources.qrc new file mode 100644 index 0000000000000000000000000000000000000000..222c90e84b0edf0086ceb79d41982db36bd9904e --- /dev/null +++ b/get_nib/resources.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/plugins/get_nib" > + <file>icon.png</file> + </qresource> +</RCC>