def onError(self, error): if error == QProcess.FailedToStart: msg = QCoreApplication.translate("GdalTools", "The process failed to start. Either the invoked program is missing, or you may have insufficient permissions to invoke the program.") elif error == QProcess.Crashed: msg = QCoreApplication.translate("GdalTools", "The process crashed some time after starting successfully.") else: msg = QCoreApplication.translate("GdalTools", "An unknown error occurred.") QErrorMessage(self).showMessage(msg) QApplication.processEvents() # give the user chance to see the message self.stop()
def end_process(self): """ Make some stuff after the process """ self.pushButton_runQuery.setDisabled(False) self.pushButton_runQuery.setText(self.pushButton_runQuery.initialText) self.progressBar_execution.setMinimum(0) self.progressBar_execution.setMaximum(100) self.progressBar_execution.setValue(100) QApplication.processEvents()
def execute(func, message = None, useThread = False): global _dialog cursor = QApplication.overrideCursor() waitCursor = (cursor is not None and cursor.shape() == Qt.WaitCursor) dialogCreated = False try: QCoreApplication.processEvents() if not waitCursor: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) if message is not None and useThread: t = Thread(func) loop = QEventLoop() t.finished.connect(loop.exit, Qt.QueuedConnection) if _dialog is None: dialogCreated = True _dialog = QProgressDialog(message, "Mapstory", 0, 0, config.iface.mainWindow()) _dialog.setWindowTitle("Mapstory") _dialog.setWindowModality(Qt.WindowModal); _dialog.setMinimumDuration(1000) _dialog.setMaximum(100) _dialog.setValue(0) _dialog.setMaximum(0) _dialog.setCancelButton(None) else: oldText = _dialog.labelText() _dialog.setLabelText(message) QApplication.processEvents() t.start() loop.exec_(flags = QEventLoop.ExcludeUserInputEvents) if t.exception is not None: raise t.exception return t.returnValue else: return func() finally: if message is not None and useThread: if dialogCreated: _dialog.reset() _dialog = None else: _dialog.setLabelText(oldText) if not waitCursor: QApplication.restoreOverrideCursor() QCoreApplication.processEvents()
def process_query( dialog=None, query=None, nominatim=None, bbox=None, output_dir=None, prefix_file=None, output_geometry_types=None, layer_name="OsmQuery", white_list_values=None, config_outputs=None): """execute a query and send the result file to open_file.""" # Prepare outputs dialog.set_progress_text(tr('Prepare outputs')) # Getting the default overpass api and running the query server = get_setting('defaultOAPI', OVERPASS_SERVERS[0]) + 'interpreter' dialog.set_progress_text( tr('Downloading data from Overpass {}').format(server)) # Replace Nominatim or BBOX query = QueryPreparation(query, bbox, nominatim, server) QApplication.processEvents() final_query = query.prepare_query() url = query.prepare_url() connexion_overpass_api = ConnexionOAPI(url) LOGGER.debug('Encoded URL: {}'.format(url)) osm_file = connexion_overpass_api.run() return open_file( dialog=dialog, osm_file=osm_file, output_geom_types=output_geometry_types, white_list_column=white_list_values, layer_name=layer_name, output_dir=output_dir, prefix_file=prefix_file, final_query=final_query, config_outputs=config_outputs)
def returnedBounds(self): rb = self.tool.rb warning = True ok = True active = False errBuffer_noAtt = False errBuffer_Vertices = False buffer_geom = None buffer_geom_crs = None # we check if there's at least one visible layer for layer in QgsProject().instance().mapLayers().values(): if QgsProject.instance().layerTreeRoot().findLayer(layer.id()).isVisible(): warning = False active = True break # buffer creation on the current layer if self.request == 'buffer': layer = self.iface.layerTreeView().currentLayer() if layer is not None and layer.type() == QgsMapLayer.VectorLayer and QgsProject.instance().layerTreeRoot().findLayer(layer.id()).isVisible(): # rubberband reprojection g = self.geomTransform(rb.asGeometry(), self.iface.mapCanvas().mapSettings().destinationCrs(), layer.crs()) features = layer.getFeatures(QgsFeatureRequest(g.boundingBox())) rbGeom = [] for feature in features: geom = feature.geometry() if g.intersects(geom): rbGeom.append(QgsGeometry(feature.geometry())) if len(rbGeom) > 0: union_geoms = rbGeom[0] for geometry in rbGeom: if union_geoms.combine(geometry) is not None: union_geoms = union_geoms.combine(geometry) rb.setToGeometry(union_geoms, layer) perim, ok = QInputDialog.getDouble(self.iface.mainWindow(), self.tr('Perimeter'), self.tr('Give a perimeter in m:')+'\n'+self.tr('(works only with metric crs)'), min=0) buffer_geom_crs = layer.crs() buffer_geom = union_geoms.buffer(perim, 40) rb.setToGeometry(buffer_geom, QgsVectorLayer("Polygon?crs="+layer.crs().authid(),"","memory")) if buffer_geom.length == 0 : warning = True errBuffer_Vertices = True else: warning = True errBuffer_noAtt = True else: warning = True if len(QgsProject().instance().mapLayers().values()) > 0 and warning == False and ok: self.loadingWindow.show() self.loadingWindow.activateWindow(); self.loadingWindow.showNormal(); for layer in QgsProject().instance().mapLayers().values(): if layer.type() == QgsMapLayer.VectorLayer and QgsProject.instance().layerTreeRoot().findLayer(layer.id()).isVisible(): if self.request == 'buffer' and self.iface.layerTreeView().currentLayer() == layer: layer.selectByIds([]) continue self.loadingWindow.reset() self.loadingWindow.setWindowTitle(self.tr('Selecting...')) self.loadingWindow.setLabelText(layer.name()) # rubberband reprojection if self.request == 'buffer': if buffer_geom_crs.authid() != layer.crs().authid(): g = self.geomTransform(buffer_geom, buffer_geom_crs, layer.crs()) else: g = self.geomTransform(buffer_geom, buffer_geom_crs, layer.crs()) else: g = self.geomTransform(rb.asGeometry(), self.iface.mapCanvas().mapSettings().destinationCrs(), layer.crs()) feat_id = [] features = layer.getFeatures(QgsFeatureRequest(g.boundingBox())) count = layer.getFeatures(QgsFeatureRequest(g.boundingBox())) nbfeatures = 0 for feature in count: nbfeatures+=1 # Select attributes intersecting with the rubberband index = 0 for feature in features: geom = feature.geometry() try: if g.intersects(geom): feat_id.append(feature.id()) except: # There's an error but it intersects print('error with '+layer.name()+' on '+str(feature.id())) feat_id.append(feature.id()) index += 1 self.loadingWindow.setValue(int((float(index)/nbfeatures)*100)) if self.loadingWindow.wasCanceled(): self.loadingWindow.reset() break QApplication.processEvents() layer.selectByIds(feat_id) self.loadingWindow.close() self.showAttributesTable() else: # Display a warning in the message bar depending of the error if active == False: self.iface.messageBar().pushWarning(self.tr('Warning'), self.tr('There is no active layer !')) elif ok == False: pass elif errBuffer_noAtt: self.iface.messageBar().pushWarning(self.tr('Warning'), self.tr('You didn\'t click on a layer\'s attribute !')) elif errBuffer_Vertices: self.iface.messageBar().pushWarning(self.tr('Warning'), self.tr('You must give a non-null value for a point\'s or line\'s perimeter !')) else: self.iface.messageBar().pushWarning(self.tr('Warning'), self.tr('There is no selected layer, or it is not vector nor visible !'))
def test(self): # This test is quite fragile as it depends on windows manager behaviour # regarding focus, so not surprising it doesn't pass # on other platforms than Linux. #if 'TRAVIS_OS_NAME' in os.environ and os.environ['TRAVIS_OS_NAME'] == 'osx': # return main_dialog = QgsProviderRegistry.instance().selectWidget("WFS") main_dialog.setProperty("hideDialogs", True) self.assertIsNotNone(main_dialog) # Create new connection btnNew = main_dialog.findChild(QWidget, "btnNew") self.assertIsNotNone(btnNew) QTest.mouseClick(btnNew, Qt.LeftButton) new_conn = find_window('QgsNewHttpConnectionBase') self.assertIsNotNone(new_conn) txtName = new_conn.findChild(QLineEdit, "txtName") self.assertIsNotNone(txtName) txtName.setText("test_connection") txtUrl = new_conn.findChild(QLineEdit, "txtUrl") self.assertIsNotNone(txtUrl) txtUrl.setText("test_url") new_conn.accept() # Wait for object to be destroyed new_conn = self.wait_object_destruction(new_conn) # Try to connect btnConnect = main_dialog.findChild(QWidget, "btnConnect") self.assertIsNotNone(btnConnect) QTest.mouseClick(btnConnect, Qt.LeftButton) # Depends on asynchronous signal QApplication.processEvents() error_box = find_window('WFSCapabilitiesErrorBox') self.assertIsNotNone(error_box) # Close error box error_box.accept() # Wait for object to be destroyed error_box = self.wait_object_destruction(error_box) # Edit connection btnEdit = main_dialog.findChild(QWidget, "btnEdit") self.assertIsNotNone(btnEdit) QTest.mouseClick(btnEdit, Qt.LeftButton) new_conn = find_window('QgsNewHttpConnectionBase',) self.assertIsNotNone(new_conn) txtName = new_conn.findChild(QLineEdit, "txtName") self.assertIsNotNone(txtName) txtName.setText("test_connection") txtUrl = new_conn.findChild(QLineEdit, "txtUrl") self.assertIsNotNone(txtUrl) endpoint = self.basetestpath + '/fake_qgis_http_endpoint' expected_endpoint = endpoint if sys.platform == 'win32' and expected_endpoint[1] == ':': expected_endpoint = expected_endpoint[0] + expected_endpoint[2:] with open(sanitize(endpoint, '?SERVICE=WFS?REQUEST=GetCapabilities?ACCEPTVERSIONS=2.0.0,1.1.0,1.0.0'), 'wb') as f: f.write(""" <wfs:WFS_Capabilities version="2.0.0" xmlns="http://www.opengis.net/wfs/2.0" xmlns:wfs="http://www.opengis.net/wfs/2.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:gml="http://schemas.opengis.net/gml/3.2" xmlns:fes="http://www.opengis.net/fes/2.0"> <FeatureTypeList> <FeatureType> <Name>my:typename</Name> <Title>Title</Title> <Abstract>Abstract</Abstract> <DefaultCRS>urn:ogc:def:crs:EPSG::4326</DefaultCRS> <ows:WGS84BoundingBox> <ows:LowerCorner>-71.123 66.33</ows:LowerCorner> <ows:UpperCorner>-65.32 78.3</ows:UpperCorner> </ows:WGS84BoundingBox> </FeatureType> </FeatureTypeList> <fes:Filter_Capabilities> <fes:Spatial_Capabilities> <fes:GeometryOperands> <fes:GeometryOperand name="gml:Envelope"/> <fes:GeometryOperand name="gml:Point"/> <fes:GeometryOperand name="gml:MultiPoint"/> <fes:GeometryOperand name="gml:LineString"/> <fes:GeometryOperand name="gml:MultiLineString"/> <fes:GeometryOperand name="gml:Polygon"/> <fes:GeometryOperand name="gml:MultiPolygon"/> <fes:GeometryOperand name="gml:MultiGeometry"/> </fes:GeometryOperands> <fes:SpatialOperators> <fes:SpatialOperator name="Disjoint"/> <fes:SpatialOperator name="Equals"/> <fes:SpatialOperator name="DWithin"/> <fes:SpatialOperator name="Beyond"/> <fes:SpatialOperator name="Intersects"/> <fes:SpatialOperator name="Touches"/> <fes:SpatialOperator name="Crosses"/> <fes:SpatialOperator name="Within"/> <fes:SpatialOperator name="Contains"/> <fes:SpatialOperator name="Overlaps"/> <fes:SpatialOperator name="BBOX"/> </fes:SpatialOperators> </fes:Spatial_Capabilities> <fes:Functions> <fes:Function name="abs"> <fes:Returns>xs:int</fes:Returns> <fes:Arguments> <fes:Argument name="param"> <fes:Type>xs:int</fes:Type> </fes:Argument> </fes:Arguments> </fes:Function> </fes:Functions> </fes:Filter_Capabilities> </wfs:WFS_Capabilities>""".encode('UTF-8')) txtUrl.setText("http://" + endpoint) new_conn.accept() # Wait for object to be destroyed new_conn = self.wait_object_destruction(new_conn) # Try to connect btnConnect = main_dialog.findChild(QWidget, "btnConnect") self.assertIsNotNone(btnConnect) QTest.mouseClick(btnConnect, Qt.LeftButton) buttonAdd = self.get_button_add(main_dialog) for i in range(10): QApplication.processEvents() if buttonAdd.isEnabled(): break self.assertTrue(buttonAdd.isEnabled()) # Add layer self.addWfsLayer_uri = None self.addWfsLayer_layer_name = None main_dialog.addWfsLayer.connect(self.slotAddWfsLayer) QTest.mouseClick(buttonAdd, Qt.LeftButton) self.assertEqual(self.addWfsLayer_uri, ' restrictToRequestBBOX=\'1\' srsname=\'EPSG:4326\' typename=\'my:typename\' url=\'' + "http://" + expected_endpoint + '\' version=\'auto\' table="" sql=') self.assertEqual(self.addWfsLayer_layer_name, 'my:typename') # Click on Build Query buttonBuildQuery = self.get_button_build_query(main_dialog) self.assertTrue(buttonBuildQuery.isEnabled()) QTest.mouseClick(buttonBuildQuery, Qt.LeftButton) error_box = find_window('WFSFeatureTypeErrorBox') self.assertIsNotNone(error_box) # Close error box error_box.accept() # Wait for object to be destroyed error_box = self.wait_object_destruction(error_box) # Click again but with valid DescribeFeatureType with open(sanitize(endpoint, '?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=2.0.0&TYPENAME=my:typename'), 'wb') as f: f.write(""" <xsd:schema xmlns:my="http://my" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://my"> <xsd:import namespace="http://www.opengis.net/gml/3.2"/> <xsd:complexType name="typenameType"> <xsd:complexContent> <xsd:extension base="gml:AbstractFeatureType"> <xsd:sequence> <xsd:element maxOccurs="1" minOccurs="0" name="intfield" nillable="true" type="xsd:int"/> <xsd:element maxOccurs="1" minOccurs="0" name="geometryProperty" nillable="true" type="gml:PolygonPropertyType"/> </xsd:sequence> </xsd:extension> </xsd:complexContent> </xsd:complexType> <xsd:element name="typename" substitutionGroup="gml:_Feature" type="my:typenameType"/> </xsd:schema> """.encode('UTF-8')) QTest.mouseClick(buttonBuildQuery, Qt.LeftButton) # Check that the combos are properly initialized dialog = find_window('QgsSQLComposerDialogBase') self.assertIsNotNone(dialog) mTablesCombo = dialog.findChild(QComboBox, "mTablesCombo") self.assertIsNotNone(mTablesCombo) self.assertEqual(mTablesCombo.itemText(1), 'typename (Title)') mColumnsCombo = dialog.findChild(QComboBox, "mColumnsCombo") self.assertIsNotNone(mColumnsCombo) self.assertEqual(mColumnsCombo.itemText(1), 'intfield (int)') self.assertEqual(mColumnsCombo.itemText(mColumnsCombo.count() - 2), 'geometryProperty (geometry)') self.assertEqual(mColumnsCombo.itemText(mColumnsCombo.count() - 1), '*') mFunctionsCombo = dialog.findChild(QComboBox, "mFunctionsCombo") self.assertIsNotNone(mFunctionsCombo) self.assertEqual(mFunctionsCombo.itemText(1), 'abs(param: int): int') mSpatialPredicatesCombo = dialog.findChild(QComboBox, "mSpatialPredicatesCombo") self.assertIsNotNone(mSpatialPredicatesCombo) self.assertEqual(mSpatialPredicatesCombo.itemText(1), 'ST_Disjoint(geometry, geometry): boolean') mWhereEditor = dialog.findChild(QTextEdit, "mWhereEditor") self.assertIsNotNone(mWhereEditor) mWhereEditor.setText('1 = 1') dialog.accept() # Wait for object to be destroyed dialog = self.wait_object_destruction(dialog) # Add layer buttonAdd = self.get_button_add(main_dialog) self.assertTrue(buttonAdd.isEnabled()) self.addWfsLayer_uri = None self.addWfsLayer_layer_name = None main_dialog.addWfsLayer.connect(self.slotAddWfsLayer) QTest.mouseClick(buttonAdd, Qt.LeftButton) self.assertEqual(self.addWfsLayer_uri, ' restrictToRequestBBOX=\'1\' srsname=\'EPSG:4326\' typename=\'my:typename\' url=\'' + "http://" + expected_endpoint + '\' version=\'auto\' table="" sql=SELECT * FROM typename WHERE 1 = 1') self.assertEqual(self.addWfsLayer_layer_name, 'my:typename')
def open_file(self): """ Open the osm file with the osmconf """ QApplication.setOverrideCursor(Qt.WaitCursor) self.start_process() QApplication.processEvents() # Get fields osm_file = self.osm_file.filePath() osm_conf = self.osm_conf.filePath() output_directory = self.output_directory.filePath() prefix_file = self.lineEdit_filePrefix.text() load_only = self.radioButton_osmConf.isChecked() # Which geometry at the end ? output_geometry_types = self.get_output_geometry_types() try: if not output_geometry_types: raise OutPutGeomTypesException if not isfile(osm_file): raise FileDoesntExistException(suffix="*.osm or *.pbf") if load_only: if not isfile(osm_conf): raise FileDoesntExistException(suffix="*.ini") if output_directory and not isdir(output_directory): raise DirectoryOutPutException if load_only: # Legacy, waiting to remove the OsmParser for QGIS >= 3.6 # Change in osm_file_dialog.py L131 too output_geom_legacy = [ l.value.lower() for l in output_geometry_types] osm_parser = OsmParser( osm_file, load_only=True, osm_conf=osm_conf, layers=output_geom_legacy) layers = osm_parser.parse() for item in list(layers.values()): QgsProject.instance().addMapLayer(item) else: open_file( dialog=self, osm_file=osm_file, output_geom_types=output_geometry_types, output_dir=output_directory, prefix_file=prefix_file) display_message_bar( tr('Successful query'), level=Qgis.Success, duration=5) except QuickOsmException as e: self.display_geo_algorithm_exception(e) except Exception as e: # pylint: disable=broad-except self.display_exception(e) finally: QApplication.restoreOverrideCursor() self.end_process() QApplication.processEvents()
def setProgress(self, value): try: self.progressBar.setValue(value) QApplication.processEvents() except: pass
def profiles_progress(self, msg): self.iface.mainWindow().statusBar().showMessage(msg) self.ui.IDC_lblCreateStatus.setText(msg) QApplication.processEvents()
def CreateVideoLayers(ele): ''' Create Video Layers ''' if qgsu.selectLayerByName(Footprint_lyr) is None: lyr_footprint = newPolygonsLayer(None, [ "Corner Longitude Point 1", "Corner Latitude Point 1", "Corner Longitude Point 2", "Corner Latitude Point 2", "Corner Longitude Point 3", "Corner Latitude Point 3", "Corner Longitude Point 4", "Corner Latitude Point 4" ], epsg, Footprint_lyr) SetDefaultFootprintStyle(lyr_footprint) addLayerNoCrsDialog(lyr_footprint) # 3D Style if ele: SetDefaultFootprint3DStyle(lyr_footprint) if qgsu.selectLayerByName(Beams_lyr) is None: lyr_beams = newLinesLayer(None, [ "longitude", "latitude", "altitude", "Corner Longitude", "Corner Latitude" ], epsg, Beams_lyr, LineZ) SetDefaultBeamsStyle(lyr_beams) addLayerNoCrsDialog(lyr_beams) # 3D Style if ele: SetDefaultBeams3DStyle(lyr_beams) if qgsu.selectLayerByName(Trajectory_lyr) is None: lyr_Trajectory = newLinesLayer(None, ["longitude", "latitude", "altitude"], epsg, Trajectory_lyr, LineZ) SetDefaultTrajectoryStyle(lyr_Trajectory) addLayerNoCrsDialog(lyr_Trajectory) # 3D Style if ele: SetDefaultTrajectory3DStyle(lyr_Trajectory) if qgsu.selectLayerByName(FrameAxis_lyr) is None: lyr_frameaxis = newLinesLayer(None, [ "longitude", "latitude", "altitude", "Corner Longitude", "Corner Latitude", "Corner altitude" ], epsg, FrameAxis_lyr, LineZ) SetDefaultFrameAxisStyle(lyr_frameaxis) addLayerNoCrsDialog(lyr_frameaxis) # 3D Style if ele: SetDefaultFrameAxis3DStyle(lyr_frameaxis) if qgsu.selectLayerByName(Platform_lyr) is None: lyr_platform = newPointsLayer(None, ["longitude", "latitude", "altitude"], epsg, Platform_lyr, PointZ) SetDefaultPlatformStyle(lyr_platform) addLayerNoCrsDialog(lyr_platform) # 3D Style if ele: SetDefaultPlatform3DStyle(lyr_platform) if qgsu.selectLayerByName(Point_lyr) is None: lyr_point = newPointsLayer( None, ["number", "longitude", "latitude", "altitude"], epsg, Point_lyr) SetDefaultPointStyle(lyr_point) addLayerNoCrsDialog(lyr_point) if qgsu.selectLayerByName(FrameCenter_lyr) is None: lyr_framecenter = newPointsLayer(None, ["longitude", "latitude", "altitude"], epsg, FrameCenter_lyr) SetDefaultFrameCenterStyle(lyr_framecenter) addLayerNoCrsDialog(lyr_framecenter) # 3D Style if ele: SetDefaultFrameCenter3DStyle(lyr_framecenter) if qgsu.selectLayerByName(Line_lyr) is None: # lyr_line = newLinesLayer( # None, ["longitude", "latitude", "altitude"], epsg, Line_lyr) lyr_line = newLinesLayer(None, [], epsg, Line_lyr) SetDefaultLineStyle(lyr_line) addLayerNoCrsDialog(lyr_line) if qgsu.selectLayerByName(Polygon_lyr) is None: lyr_polygon = newPolygonsLayer(None, [ "Centroid_longitude", "Centroid_latitude", "Centroid_altitude", "Area" ], epsg, Polygon_lyr) SetDefaultPolygonStyle(lyr_polygon) addLayerNoCrsDialog(lyr_polygon) QApplication.processEvents() return
def processEvents(): try: qApp.processEvents() except: QApplication.processEvents()
def wkblify_raster_level(self, options, ds, level, band_range, infile, i): band_from = band_range[0] band_to = band_range[1] # Collect raster and block dimensions raster_size = ( ds.RasterXSize, ds.RasterYSize ) if options['block_size'] is not None: block_size = self.parse_block_size(options, ds) read_block_size = ( block_size[0] * level, block_size[1] * level) grid_size = self.calculate_grid_size(raster_size, read_block_size) else: block_size = raster_size # Whole raster as a single block read_block_size = block_size grid_size = (1, 1) gen_table = options['schema_table'] # Write (original) raster to hex binary output tile_count = 0 hexwkb = '' self.progress_label.setText(self.tr("Uploading tiles...")) importString = "" sum_tiles = grid_size[0]*grid_size[1] copy_size = 500 for ycell in range(0, grid_size[1]): for xcell in range(0, grid_size[0]): xoff = xcell * read_block_size[0] yoff = ycell * read_block_size[1] if options['block_size'] is not None: hexwkb = '' # Reset buffer as single INSERT per tile is generated hexwkb += self.wkblify_raster_header(options, ds, level, (xoff, yoff), block_size[0], block_size[1]) else: hexwkb += self.wkblify_raster_header(options, ds, level, (xoff, yoff)) for b in range(band_from, band_to): band = ds.GetRasterBand(b) hexwkb += self.wkblify_band_header(options, band) hexwkb += self.wkblify_band(options, band, level, xoff, yoff, read_block_size, block_size, infile, b) # Creating COPY String importString += str(tile_count)+"\t"+hexwkb+"\n" tile_count = tile_count + 1 # Periodically update ui if (tile_count % copy_size) == 0: self.cursor.copy_from(StringIO(importString), '%s' % gen_table) importString = "" self.progress_label.setText(self.tr("{table}: {count} of {sum_tiles} tiles uploaded").format( table=gen_table, count=tile_count, sum_tiles= sum_tiles)) QApplication.processEvents() self.cursor.copy_from(StringIO(importString), '%s' % gen_table) self.conn.commit() self.progress_label.setText(self.tr("Calculating raster params for {sum_tiles} tiles ...").format( sum_tiles= sum_tiles)) QApplication.processEvents() self.cursor.execute(self.make_sql_addrastercolumn(options)) self.conn.commit() return (gen_table, tile_count)
def run_stats(self): """Main function which do the process.""" # Get the common fields. self.admin_layer = self.cbx_aggregation_layer.currentLayer() if self.use_point_layer: # If we use a point layer. point_layer = self.cbx_case_layer.currentLayer() else: # If we use a column with number of case. case_column = self.cbx_case_field.currentField() index_case = self.admin_layer.fields().indexFromName(case_column) #Replace laer.fieldNameIndex(name) to layer.fields().lookup\Field(name) #http://learn.openwaterfoundation.org/owf-app-geoprocessor-python-doc-dev/resources/migrate-qgis2-qgis3/ if not self.use_area: # If we don't use density. population = self.cbx_population_field.currentField() index_population = self.admin_layer.fields().indexFromName(population) self.name_field=self.le_new_column.text() if not self.name_field: self.name_field = self.le_new_column.placeholderText() # Add new column. add_nb_intersections = self.checkBox_addNbIntersections.isChecked() # Ratio ratio = self.cbx_ratio.currentText() ratio = ratio.replace(' ', '') # Output. self.output_file_path = self.le_output_filepath.text() try: self.button_box_ok.setDisabled(True) # noinspection PyArgumentList QApplication.setOverrideCursor(Qt.WaitCursor) # noinspection PyArgumentList QApplication.processEvents() if not self.admin_layer: QMessageBox.information(None, "DEBUG:", str("There is no layer")) raise NoLayerProvidedException if not self.admin_layer and self.use_point_layer: QMessageBox.information(None, "DEBUG:", str("There is no layer")) raise NoLayerProvidedException crs_admin_layer = self.admin_layer.crs() if self.use_point_layer: crs_point_layer = point_layer.crs() if crs_admin_layer != crs_point_layer: QMessageBox.information(None, "DEBUG:", str("CRS of two layers are not the same. Please set CRS.")) raise DifferentCrsException( epsg1=crs_point_layer.authid(), epsg2=crs_admin_layer.authid()) if not self.use_point_layer and not self.use_area: if index_population == index_case: QMessageBox.information(None, "DEBUG:", str("You are using the same variable for case and population. Please change.")) raise FieldException(field_1='Population', field_2='Case') try: ratio = float(ratio) except ValueError: QMessageBox.information(None, "DEBUG:", str("The variable is not number.")) raise NotANumberException(suffix=ratio) # Output if not self.output_file_path: temp_file = NamedTemporaryFile( delete=False, suffix='-geohealth.shp') self.output_file_path = temp_file.name temp_file.flush() temp_file.close() else: with open(self.output_file_path, 'w') as document: pass admin_layer_provider = self.admin_layer.dataProvider() fields = self.admin_layer.fields() if admin_layer_provider.fields().indexFromName(self.name_field) != -1: QMessageBox.information(None, "DEBUG:", str("The field name already exist.")) raise FieldExistingException(field=self.name_field) fields.append(QgsField(self.name_field, QVariant.Double)) if add_nb_intersections: fields.append(QgsField('nb_of_intersections', QVariant.Int)) data = [] file_writer = QgsVectorFileWriter( self.output_file_path, 'utf-8', fields, QgsWkbTypes.Polygon, self.admin_layer.crs(), 'ESRI Shapefile') if self.use_point_layer: total_case = point_layer.featureCount() else: total_case = 0 for i, feature in enumerate(self.admin_layer.getFeatures()): attributes = feature.attributes() if self.use_point_layer: count = 0 for f in point_layer.getFeatures(): if f.geometry().intersects(feature.geometry()): count += 1 else: count = int(attributes[index_case]) total_case += count try: if self.use_area: area = feature.geometry().area() value = float(count) / area * ratio else: try: population = float(attributes[index_population]) except ValueError: QMessageBox.information(None, "DEBUG:", str("This is not a number.")) raise NotANumberException( suffix=attributes[index_population]) value = float(count) / population * ratio except ZeroDivisionError: value = None except TypeError: value = None data.append(value) attributes.append(value) if add_nb_intersections: attributes.append(count) new_feature = QgsFeature() new_geom = QgsGeometry(feature.geometry()) new_feature.setAttributes(attributes) new_feature.setGeometry(new_geom) file_writer.addFeature(new_feature) del file_writer self.output_layer = QgsVectorLayer( self.output_file_path, self.name_field, 'ogr') QgsProject.instance().addMapLayer(self.output_layer) if self.checkBox_incidence_runStats.isChecked(): stats = Stats(data) items_stats = [ 'Incidence null,%d' % stats.null_values(), 'Count(point),%d' % total_case, 'Count(polygon),%d' % self.admin_layer.featureCount(), 'Min,%d' % stats.min(), 'Average,%f' % stats.average(), 'Max,%d' % stats.max(), 'Median,%f' % stats.median(), 'Range,%d' % stats.range(), 'Variance,%f' % stats.variance(), 'Standard deviation,%f' % stats.standard_deviation() ] self.tableWidget.clear() self.tableWidget.setColumnCount(2) labels = ['Parameters', 'Values'] self.tableWidget.setHorizontalHeaderLabels(labels) self.tableWidget.setRowCount(len(items_stats)) for i, item in enumerate(items_stats): s = item.split(',') self.tableWidget.setItem(i, 0, QTableWidgetItem(s[0])) self.tableWidget.setItem(i, 1, QTableWidgetItem(s[1])) self.tableWidget.resizeRowsToContents() self.draw_plot(data) else: self.hide() if self.symbology.isChecked(): self.add_symbology() self.signalStatus.emit(3, tr('Successful process')) except GeoPublicHealthException as e: display_message_bar(msg=e.msg, level=e.level, duration=e.duration) finally: self.button_box_ok.setDisabled(False) # noinspection PyArgumentList QApplication.restoreOverrideCursor() # noinspection PyArgumentList QApplication.processEvents()
def open_file(dialog=None, osm_file=None, output_geom_types=None, white_list_column=None, layer_name="OsmFile", config_outputs=None, output_dir=None, prefix_file=None): """ Open an osm file. Memory layer if no output directory is set, or Geojson in the output directory. """ outputs = {} if output_dir: for layer in ['points', 'lines', 'multilinestrings', 'multipolygons']: if not prefix_file: prefix_file = layer_name outputs[layer] = join(output_dir, prefix_file + "_" + layer + ".geojson") if isfile(outputs[layer]): raise FileOutPutException(suffix='(' + outputs[layer] + ')') # Parsing the file osm_parser = OsmParser(osm_file=osm_file, layers=output_geom_types, white_list_column=white_list_column) osm_parser.signalText.connect(dialog.set_progress_text) osm_parser.signalPercentage.connect(dialog.set_progress_percentage) layers = osm_parser.parse() # Finishing the process with geojson or memory layer num_layers = 0 for i, (layer, item) in enumerate(layers.items()): dialog.set_progress_percentage(i / len(layers) * 100) QApplication.processEvents() if item['featureCount'] and layer in output_geom_types: final_layer_name = layer_name # If configOutputs is not None (from My Queries) if config_outputs: if config_outputs[layer]['namelayer']: final_layer_name = config_outputs[layer]['namelayer'] if output_dir: dialog.set_progress_text( tr("QuickOSM", u"From memory to GeoJSON: " + layer)) # Transforming the vector file osm_geometries = { 'points': QgsWkbTypes.Point, 'lines': QgsWkbTypes.LineString, 'multilinestrings': QgsWkbTypes.MultiLineString, 'multipolygons': QgsWkbTypes.MultiPolygon } memory_layer = item['vector_layer'] encoding = get_default_encoding() writer = QgsVectorFileWriter(outputs[layer], encoding, memory_layer.fields(), osm_geometries[layer], memory_layer.crs(), "GeoJSON") for f in memory_layer.getFeatures(): writer.addFeature(f) del writer # Loading the final vector file new_layer = QgsVectorLayer(outputs[layer], final_layer_name, "ogr") else: new_layer = item['vector_layer'] new_layer.setName(final_layer_name) # Try to set styling if defined if config_outputs and config_outputs[layer]['style']: new_layer.loadNamedStyle(config_outputs[layer]['style']) else: # Loading default styles if layer == "multilinestrings" or layer == "lines": if "colour" in item['tags']: new_layer.loadNamedStyle( join(dirname(dirname(abspath(__file__))), "styles", layer + "_colour.qml")) # Add action about OpenStreetMap actions = new_layer.actions() actions.addAction( QgsAction.OpenUrl, "OpenStreetMap Browser", 'http://www.openstreetmap.org/browse/' '[% "osm_type" %]/[% "osm_id" %]', False) actions.addAction( QgsAction.GenericPython, 'JOSM', 'from QuickOSM.CoreQuickOSM.Actions import Actions;' 'Actions.run("josm","[% "full_id" %]")', False) actions.addAction( QgsAction.OpenUrl, "User default editor", 'http://www.openstreetmap.org/edit?' '[% "osm_type" %]=[% "osm_id" %]', False) for link in ['url', 'website', 'wikipedia', 'ref:UAI']: if link in item['tags']: link = link.replace(":", "_") actions.addAction( QgsAction.GenericPython, link, 'from QuickOSM.core.actions import Actions;' 'Actions.run("' + link + '","[% "' + link + '" %]")', False) if 'network' in item['tags'] and 'ref' in item['tags']: actions.addAction( QgsAction.GenericPython, "Sketchline", 'from QuickOSM.core.actions import Actions;' 'Actions.run_sketch_line("[% "network" %]","[% "ref" %]")', False) QgsProject.instance().addMapLayer(new_layer) num_layers += 1 return num_layers
def upload(self, db, data_sources_items, maxSize): import_ok = True layers_to_replace = {} raster_to_upload = {} self.status_bar.showMessage( self.tr("Uploading to database '{db}'...").format(db=db.database)) QApplication.processEvents() messages = "" # Connect to database try: conn = db.psycopg_connection() cursor = conn.cursor() except Exception as e: raise RuntimeError("Connection to database failed %s" % str(e)) for data_source, item in list(data_sources_items.items()): # Check available space, block if exceded size = DbConnections().db_size() if size > float(maxSize): QMessageBox.warning( None, self.tr("Database full"), self. tr("You have exceeded the maximum database size for your current QGIS Cloud plan. Please free up some space or upgrade your QGIS Cloud plan." )) break # Layers contains all layers with shared data source layer = item['layers'][0] if layer.type() == QgsMapLayer.VectorLayer: fields = QgsFields(layer.fields()) srid = layer.crs().postgisSrid() geom_column = "wkb_geometry" wkbType = layer.wkbType() if wkbType == QgsWkbTypes.NoGeometry: cloudUri = "dbname='%s' host=%s port=%d user='******' password='******' key='' table=\"public\".\"%s\"" % ( db.database, db.host, db.port, db.username, db.password, item['table']) geom_column = "" else: if not QgsWkbTypes.isMultiType(wkbType): wkbType = QgsWkbTypes.multiType(wkbType) # Create table (pk='' => always generate a new primary key) cloudUri = "dbname='%s' host=%s port=%d user='******' password='******' key='' table=\"public\".\"%s\" (%s)" % ( db.database, db.host, db.port, db.username, db.password, item['table'], geom_column) self.progress_label.setText( self.tr("Creating table '{table}'...").format( table=item['table'])) QApplication.processEvents() if wkbType != QgsWkbTypes.NoGeometry: # Check if SRID is known on database, otherwise create record cursor.execute( "SELECT srid FROM public.spatial_ref_sys WHERE srid = %s" % layer.crs().postgisSrid()) if not cursor.fetchone(): try: cursor.execute( "INSERT INTO public.spatial_ref_sys VALUES ({srid},'EPSG',{srid},'{wktstr}','{projstr}')" .format(srid=layer.crs().postgisSrid(), wktstr=layer.crs().toWkt(), projstr=layer.crs().toProj4())) conn.commit() except Exception as e: conn.rollback() import_ok &= False messages += "Failed to create SRS record on database: " + str( e) + "\n" continue # cursor.close() # TODO: Ask user for overwriting existing table # The postgres provider is terribly slow at creating tables with # many attribute columns in QGIS < 2.9.0 vectorLayerImport = PGVectorLayerImport( db, conn, cursor, cloudUri, fields, wkbType, layer.crs(), True) if vectorLayerImport.hasError(): import_ok &= False messages += "VectorLayerImport-Error: " + vectorLayerImport.errorMessage( ) + "\n" continue vectorLayerImport = None # Build import string attribs = list(range(0, fields.count())) count = 0 importstr = bytearray() ok = True self.progress_label.setText(self.tr("Uploading features...")) QApplication.processEvents() for feature in layer.getFeatures(): f_geometry = feature.geometry() f_geometry.convertToMultiType() # First field is primary key importstr.extend(str(count).encode('utf-8')) count += 1 if not feature.geometry(): if layer.isSpatial(): QgsMessageLog.logMessage( self. tr("Feature {id} of layer {layer} has no geometry" ).format(id=feature.id(), layer=layer.name()), "QGISCloud") importstr.extend(b"\t" + b"\\N") elif f_geometry.wkbType() != wkbType: QgsMessageLog.logMessage( self. tr("Feature {id} of layer {layer} has wrong geometry type {type}" ).format(id=feature.id(), layer=layer.name(), type=QgsWkbTypes.displayString( feature.geometry().wkbType())), "QGISCloud") importstr.extend(b"\t" + b"\\N") else: # Second field is geometry in EWKB Hex format importstr.extend( b"\t" + self._wkbToEWkbHex(f_geometry.asWkb(), srid)) # Finally, copy data attributes for attrib in attribs: val = feature[attrib] if val is None or isinstance(val, QVariant): val = b"\\N" elif isinstance(val, QDate) or isinstance( val, QDateTime): val = bytearray( val.toString(Qt.ISODate).encode('utf-8')) if not val: val = b"\\N" else: val = bytearray(str(val).encode('utf-8')) val = val.replace(b'\x00', b'?') val = val.replace(b'\t', b"E'\t'") val = val.replace(b'\n', b"E'\n'") val = val.replace(b'\r', b"E'\r'") val = val.replace(b'\\', b"\\") importstr += b"\t" + val importstr += b"\n" # Upload in chunks if (count % 100) == 0: try: cursor.copy_from( StringIO(importstr.decode('utf-8')), '"public"."%s"' % item['table']) except Exception as e: messages += str(e) + "\n" ok = False break importstr = bytearray() self.progress_label.setText( self.tr( "{table}: {count} features uploaded").format( table=item['table'], count=count)) QApplication.processEvents() # Periodically update ui if (count % 10) == 0: QApplication.processEvents() if ok and importstr: try: cursor.copy_from(StringIO(importstr.decode('utf-8')), '"public"."%s"' % item['table']) except Exception as e: messages += str(e) + "\n" ok = False if ok: try: conn.commit() except Exception as e: messages += str(e) + "\n" ok = False else: conn.rollback() import_ok &= ok if ok: for layer in item['layers']: layers_to_replace[layer.id()] = { 'layer': layer, 'data_source': data_source, 'db_name': db.database, 'table_name': item['table'], 'geom_column': geom_column } if wkbType != QgsWkbTypes.NoGeometry: sql = 'create index "%s_%s_idx" on "public"."%s" using gist ("%s");' % ( item['table'], geom_column, item['table'], geom_column) cursor.execute(sql) conn.commit() elif layer.type() == QgsMapLayer.RasterLayer: raster_to_upload = { 'layer': layer, 'data_source': layer.source(), 'db_name': db.database, 'table_name': item['table'], 'geom_column': 'rast' } RasterUpload(conn, cursor, raster_to_upload, maxSize, self.progress_label) layers_to_replace[layer.id()] = raster_to_upload sql = """SELECT 'SELECT SETVAL(' || quote_literal(quote_ident(PGT.schemaname) || '.' || quote_ident(S.relname)) || ', COALESCE(MAX(' ||quote_ident(C.attname)|| ')+1, 1) ) FROM ' || quote_ident(PGT.schemaname)|| '.' ||quote_ident(T.relname)|| ';' FROM pg_class AS S, pg_depend AS D, pg_class AS T, pg_attribute AS C, pg_tables AS PGT, pg_namespace as PGNS WHERE S.relkind = 'S' AND S.oid = D.objid AND S.relnamespace = PGNS.oid AND PGNS.nspname = 'public' AND D.refobjid = T.oid AND D.refobjid = C.attrelid AND D.refobjsubid = C.attnum AND T.relname = PGT.tablename AND schemaname = 'public' AND tablename = '%s' ORDER BY S.relname;""" % ( item['table']) cursor.execute(sql) rows = cursor.fetchall() for row in rows: cursor.execute(row[0]) cursor.close() conn.close() self._replace_local_layers(layers_to_replace) self.progress_label.setText("") if not import_ok: raise RuntimeError(str(messages))
def run_stats(self): self.progressBar_stats.setValue(0) self.label_progressStats.setText('') # noinspection PyArgumentList QApplication.processEvents() blurred_layer = self.comboBox_blurredLayer.currentLayer() stats_layer = self.comboBox_statsLayer.currentLayer() try: if not blurred_layer or not stats_layer: raise NoLayerProvidedException crs_blurred_layer = blurred_layer.crs() crs_stats_layer = stats_layer.crs() if crs_blurred_layer != crs_stats_layer: raise DifferentCrsException( epsg1=crs_blurred_layer.authid(), epsg2=crs_stats_layer.authid()) if blurred_layer == stats_layer: raise NoLayerProvidedException if not blurred_layer or not stats_layer: raise NoLayerProvidedException nb_feature_stats = stats_layer.featureCount() nb_feature_blurred = blurred_layer.featureCount() features_stats = {} label_preparing = tr('Preparing index on the stats layer') label_creating = tr('Creating index on the stats layer') label_calculating = tr('Calculating') if Qgis.QGIS_VERSION_INT < 20700: self.label_progressStats.setText('%s 1/3' % label_preparing) for i, feature in enumerate(stats_layer.getFeatures()): features_stats[feature.id()] = feature percent = int((i + 1) * 100 / nb_feature_stats) self.progressBar_stats.setValue(percent) # noinspection PyArgumentList QApplication.processEvents() self.label_progressStats.setText('%s 2/3' % label_creating) # noinspection PyArgumentList QApplication.processEvents() index = QgsSpatialIndex() for i, f in enumerate(stats_layer.getFeatures()): index.insertFeature(f) percent = int((i + 1) * 100 / nb_feature_stats) self.progressBar_stats.setValue(percent) # noinspection PyArgumentList QApplication.processEvents() self.label_progressStats.setText('%s 3/3' % label_calculating) else: # If QGIS >= 2.7, we can speed up the spatial index. # From 1 min 15 to 7 seconds on my PC. self.label_progressStats.setText('%s 1/2' % label_creating) # noinspection PyArgumentList QApplication.processEvents() index = QgsSpatialIndex(stats_layer.getFeatures()) self.label_progressStats.setText('%s 2/2' % label_calculating) # noinspection PyArgumentList QApplication.processEvents() self.tab = [] for i, feature in enumerate(blurred_layer.getFeatures()): count = 0 ids = index.intersects(feature.geometry().boundingBox()) for unique_id in ids: request = QgsFeatureRequest().setFilterFid(unique_id) f = next(stats_layer.getFeatures(request)) if f.geometry().intersects(feature.geometry()): count += 1 self.tab.append(count) percent = int((i + 1) * 100 / nb_feature_blurred) self.progressBar_stats.setValue(percent) # noinspection PyArgumentList QApplication.processEvents() stats = Stats(self.tab) items_stats = [ 'Count(blurred),%d' % nb_feature_blurred, 'Count(stats),%d' % nb_feature_stats, 'Min,%d' % stats.min(), 'Average,%f' % stats.average(), 'Max,%d' % stats.max(), 'Median,%f' % stats.median(), 'Range,%d' % stats.range(), 'Variance,%f' % stats.variance(), 'Standard deviation,%f' % stats.standard_deviation() ] self.tableWidget.clear() self.tableWidget.setColumnCount(2) labels = ['Parameters', 'Values'] self.tableWidget.setHorizontalHeaderLabels(labels) self.tableWidget.setRowCount(len(items_stats)) for i, item in enumerate(items_stats): s = item.split(',') self.tableWidget.setItem(i, 0, QTableWidgetItem(s[0])) self.tableWidget.setItem(i, 1, QTableWidgetItem(s[1])) self.tableWidget.resizeRowsToContents() self.draw_plot(self.tab) except GeoPublicHealthException as e: self.label_progressStats.setText('') display_message_bar(msg=e.msg, level=e.level, duration=e.duration)
def wkblify_raster_level(self, options, ds, level, band_range, infile, i): band_from = band_range[0] band_to = band_range[1] # Collect raster and block dimensions raster_size = (ds.RasterXSize, ds.RasterYSize) if options['block_size'] is not None: block_size = self.parse_block_size(options, ds) read_block_size = (block_size[0] * level, block_size[1] * level) grid_size = self.calculate_grid_size(raster_size, read_block_size) else: block_size = raster_size # Whole raster as a single block read_block_size = block_size grid_size = (1, 1) gen_table = options['table'] # Write (original) raster to hex binary output tile_count = 0 hexwkb = '' self.progress_label.setText(self.tr("Uploading tiles...")) importString = "" sum_tiles = grid_size[0] * grid_size[1] copy_size = 500 for ycell in range(0, grid_size[1]): for xcell in range(0, grid_size[0]): xoff = xcell * read_block_size[0] yoff = ycell * read_block_size[1] if options['block_size'] is not None: hexwkb = '' # Reset buffer as single INSERT per tile is generated hexwkb += self.wkblify_raster_header( options, ds, level, (xoff, yoff), block_size[0], block_size[1]) else: hexwkb += self.wkblify_raster_header( options, ds, level, (xoff, yoff)) for b in range(band_from, band_to): band = ds.GetRasterBand(b) hexwkb += self.wkblify_band_header(options, band) hexwkb += self.wkblify_band(options, band, level, xoff, yoff, read_block_size, block_size, infile, b) # Creating COPY String importString += str(tile_count) + "\t" + hexwkb + "\n" tile_count = tile_count + 1 # Periodically update ui if (tile_count % copy_size) == 0: self.cursor.copy_from(StringIO(importString), '"public"."%s"' % gen_table) importString = "" self.progress_label.setText( self.tr( "{table}: {count} of {sum_tiles} tiles uploaded"). format(table=gen_table, count=tile_count, sum_tiles=sum_tiles)) QApplication.processEvents() self.cursor.copy_from(StringIO(importString), '"public"."%s"' % gen_table) self.conn.commit() self.progress_label.setText( self.tr("Calculating raster params for {sum_tiles} tiles ..."). format(sum_tiles=sum_tiles)) QApplication.processEvents() self.cursor.execute(self.make_sql_addrastercolumn(options)) self.conn.commit() return (gen_table, tile_count)
def run_query(self): """ Process for running the query """ # Block the button and save the initial text self.output_directory.setDisabled(True) self.pushButton_generateQuery.setDisabled(True) QApplication.setOverrideCursor(Qt.WaitCursor) self.start_process() QApplication.processEvents() # Get all values query = self.textEdit_query.toPlainText() output_directory = self.output_directory.filePath() prefix_file = self.lineEdit_filePrefix.text() nominatim = self.nominatim_value() # Set bbox bbox = None if self.cb_query_type.isEnabled(): query_type = self.cb_query_type.currentData() if query_type in ['layer', 'canvas']: nominatim = None bbox = self.get_bounding_box() # Check nominatim if nominatim == '': nominatim = None # Which geometry at the end ? output_geometry_types = self.get_output_geometry_types() white_list_values = self.get_white_list_values() try: # Test values if not output_geometry_types: raise OutPutGeomTypesException if output_directory and not isdir(output_directory): raise DirectoryOutPutException if not nominatim and \ re.search(r'\{\{nominatim\}\}', query) or \ re.search(r'\{\{nominatimArea:\}\}', query) or \ re.search(r'\{\{geocodeArea:\}\}', query): raise MissingParameterException(suffix="nominatim field") num_layers = process_query( dialog=self, query=query, output_dir=output_directory, prefix_file=prefix_file, output_geometry_types=output_geometry_types, white_list_values=white_list_values, nominatim=nominatim, bbox=bbox) if num_layers: display_message_bar( tr('Successful query'), level=Qgis.Success, duration=5) self.label_progress.setText( tr('Successful query')) else: display_message_bar( tr('Successful query, but no result.'), level=Qgis.Warning, duration=7) except QuickOsmException as e: self.display_geo_algorithm_exception(e) pass except Exception as e: # pylint: disable=broad-except self.display_exception(e) pass finally: # Resetting the button self.output_directory.setDisabled(False) self.pushButton_generateQuery.setDisabled(False) QApplication.restoreOverrideCursor() self.end_process() QApplication.processEvents()
def _init_gui(self): # Setup base elements self.gridLayout = QGridLayout(self) self.gridLayout.setObjectName('glMain') self.gridLayout.addLayout(self.vlNotification, 0, 0, 1, 1) QApplication.processEvents() # set widgets values column_widget_area = self._setup_columns_content_area() self.gridLayout.addWidget(column_widget_area, 1, 0, 1, 1) QApplication.processEvents() # Add notification for mandatory columns if applicable next_row = 2 if self.has_mandatory: self.required_fields_lbl = QLabel(self) msg = self.tr('Please fill out all required (*) fields.') msg = self._highlight_asterisk(msg) self.required_fields_lbl.setText(msg) self.gridLayout.addWidget(self.required_fields_lbl, next_row, 0, 1, 2) # Bump up row reference next_row += 1 self.buttonBox = QDialogButtonBox(self) self.buttonBox.setObjectName('buttonBox') self.gridLayout.addWidget(self.buttonBox, next_row, 0, 1, 1) self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Save) if self.edit_model is None: if not self.collect_model: self.save_new_button = QPushButton( QApplication.translate('EntityEditorDialog', 'Save and New')) self.buttonBox.addButton(self.save_new_button, QDialogButtonBox.ActionRole) # edit model, collect model # adding new record for child # Saving in parent editor if not isinstance(self._parent._parent, EntityEditorDialog): # adding a new record if self.edit_model is None: # saving when digitizing. if self.collect_model: self.buttonBox.accepted.connect(self.on_model_added) # saving parent editor else: self.buttonBox.accepted.connect(self.save_parent_editor) self.save_new_button.clicked.connect(self.save_and_new) # updating existing record else: if not self.collect_model: # updating existing record of the parent editor self.buttonBox.accepted.connect(self.save_parent_editor) else: self.buttonBox.accepted.connect(self.on_model_added) # Saving in child editor else: # save and new record if self.edit_model is None: self.buttonBox.accepted.connect(self.on_child_saved) self.save_new_button.clicked.connect( lambda: self.on_child_saved(True)) else: # When updating an existing child editor save to the db self.buttonBox.accepted.connect(self.on_child_saved) # self.buttonBox.accepted.connect(self.submit) self.buttonBox.rejected.connect(self.cancel)
def run_query(self): """ Process for running the query """ # Block the button and save the initial text QApplication.setOverrideCursor(Qt.WaitCursor) self.output_directory.setDisabled(True) self.pushButton_showQuery.setDisabled(True) self.start_process() QApplication.processEvents() # Get all values key = self.comboBox_key.currentText() value = self.comboBox_value.currentText() nominatim = self.nominatim_value() timeout = self.spinBox_timeout.value() output_directory = self.output_directory.filePath() prefix_file = self.lineEdit_filePrefix.text() query_type = self.cb_query_type.currentData() is_around = query_type == 'around' distance = self.spinBox_distance_point.value() # Which geometry at the end ? output_geometry_types = self.get_output_geometry_types() # Which osm objects ? osm_objects = self._get_osm_objects() try: # Test values if not osm_objects: raise OsmObjectsException if not output_geometry_types: raise OutPutGeomTypesException # If bbox, we must set None to nominatim, we can't have both bbox = None if query_type in ['layer', 'canvas']: nominatim = None bbox = self.get_bounding_box() if nominatim == '': nominatim = None if output_directory and not isdir(output_directory): raise DirectoryOutPutException num_layers = process_quick_query( dialog=self, key=key, value=value, nominatim=nominatim, is_around=is_around, distance=distance, bbox=bbox, osm_objects=osm_objects, timeout=timeout, output_directory=output_directory, prefix_file=prefix_file, output_geometry_types=output_geometry_types) # We can test numLayers to see if there are some results if num_layers: self.label_progress.setText( tr('Successful query')) display_message_bar( tr('Successful query'), level=Qgis.Success, duration=5) else: self.label_progress.setText(tr('No result')) display_message_bar( tr('Successful query, but no result.'), level=Qgis.Warning, duration=7) except QuickOsmException as e: self.display_geo_algorithm_exception(e) except Exception as e: # pylint: disable=broad-except self.display_exception(e) finally: # Resetting the button self.output_directory.setDisabled(False) self.pushButton_showQuery.setDisabled(False) QApplication.restoreOverrideCursor() self.end_process() QApplication.processEvents()
def on_btnRun_clicked(self): #Check for combo and list box selections if self.ui.cmbBaseLayer.count() < 1 or self.ui.cmbProcessLayer.count( ) < 1: QMessageBox.critical(self, 'Vector Geoprocessor', 'Invalid layer selection.') return if len(self.ui.listFields.selectedItems()) < 1: QMessageBox.critical(self, 'Vector Geoprocessor', 'Invalid field selection.') return #Initializations self.ui.ProgressBar.setValue(0) self.setCursor(Qt.WaitCursor) data = [] #Add new attributes to base layer bprovider = self.blayer.dataProvider() pprovider = self.player.dataProvider() pfields = pprovider.fields() for item in self.ui.listFields.selectedItems(): fname = item.text() for fld in pfields.toList(): if fname == fld.name(): newfield = QgsField() newfield.setName(fld.name()) newfield.setType(fld.type()) newfield.setTypeName(fld.typeName()) newfield.setLength(fld.length()) newfield.setPrecision(fld.precision()) newfield.setComment(fld.comment()) bprovider.addAttributes([newfield]) #Create a spatial index for faster processing spindex = QgsSpatialIndex() for pfeat in pprovider.getFeatures(): spindex.insertFeature(pfeat) #Find the intersection of process layer features with base layer #To increase speed, intersect with a bounding box rectangle first #Then further process within the geometric shape #Add requested processed information to base layer featreq = QgsFeatureRequest() bfields = bprovider.fields() ddic = {} len1 = len(self.ui.listFields.selectedItems()) len2 = len(bfields) b1 = 0 b2 = bprovider.featureCount() attr = {} for bfeat in bprovider.getFeatures(): b1 += 1 attr.clear() bgeom = bfeat.geometry() intersect = spindex.intersects(bgeom.boundingBox()) data[:] = [] for fid in intersect: pfeat = next(self.player.getFeatures( featreq.setFilterFid(fid))) if pfeat.geometry().intersects(bgeom) == False: data.append(fid) for fid in data: intersect.pop(intersect.index(fid)) count = 0 for item in self.ui.listFields.selectedItems(): pfindx = pprovider.fieldNameIndex(item.text()) if pfindx < 0: self.setCursor(Qt.ArrowCursor) QMessageBox.critical(self, 'Vector Geoprocessor', 'Processing error.') return data[:] = [] for fid in intersect: pfeat = next( self.player.getFeatures(featreq.setFilterFid(fid))) if self.oindex in [0, 1, 2, 3, 4]: data.append(float(pfeat.attribute(item.text()))) elif self.oindex in [5, 6]: data.append(str(pfeat.attribute(item.text()))) if len(data) == 0: value = None elif self.oindex == 0: #Find mean value of points within polygons value = sum(data) / float(len(data)) elif self.oindex == 1: #Find median value of points within polygons data = sorted(data) lendata = len(data) if lendata % 2: value = data[(lendata + 1) / 2 - 1] else: d1 = data[lendata / 2 - 1] d2 = data[lendata / 2] value = (d1 + d2) / 2.0 elif self.oindex == 2: #Find maximum value of points within polygons value = max(data) elif self.oindex == 3: #Find minimum value of points within polygons value = min(data) elif self.oindex == 4: #Find mean value (area-weighted) of polygons within polygons value = 0.0 totalarea = 0.0 for fid in intersect: pfeat = next( self.player.getFeatures(featreq.setFilterFid(fid))) pgeom = pfeat.geometry() isect = bgeom.intersection(pgeom) parea = isect.area() value += (float(pfeat.attribute(item.text()) * parea)) totalarea += parea value = value / totalarea elif self.oindex == 5: #Find largest area polygon within polygons data = list(set(data)) #Get unique items in data ddic.clear() for i in data: ddic.update({i: 0.0}) for fid in intersect: pfeat = next( self.player.getFeatures(featreq.setFilterFid(fid))) pgeom = pfeat.geometry() isect = bgeom.intersection(pgeom) parea = isect.area() key = str(pfeat.attribute(item.text())) parea = parea + ddic[key] ddic.update({key: parea}) parea = -1 for key in list(ddic.keys()): if ddic[key] > parea: parea = ddic[key] value = key elif self.oindex == 6: #Add polygon attribute to points if len(data) != 1: QMessageBox.warning( self, 'Vector Geoprocessor', 'Point intersects more than one polygon.') value = data[0] attr.update({(len2 - len1 + count): value}) count += 1 result = bprovider.changeAttributeValues({bfeat.id(): attr}) if not result: QMessageBox.critical(self, 'Vector Geoprocessor', 'Could not change attribute value.') return self.ui.ProgressBar.setValue(float(b1) / float(b2) * 100.0) QApplication.processEvents() self.setCursor(Qt.ArrowCursor)
def __init__(self, conn, cursor, raster, max_size, progress_label): QObject.__init__(self) self.cursor = cursor self.conn = conn self.progress_label = progress_label self.messages = "" opts = {} opts['version'] = g_rt_version opts['endian'] = NDR opts['column'] = 'rast' opts['create_table'] = 1 opts['drop_table'] = 1 opts['overview_level'] = 1 opts['block_size'] = 'auto' opts['band'] = None opts['register'] = None # Create PostGIS Raster Tool Functions raster_tools_file = "%s/raster_tools.sql" % os.path.dirname(__file__) sql = open(raster_tools_file).read().encode('ascii', errors='ignore') self.cursor.execute(sql) self.conn.commit() i = 0 # Burn all specified input raster files into single WKTRaster table gt = None layer_info = raster opts['srid'] = layer_info['layer'].dataProvider().crs().postgisSrid() infile = layer_info['data_source'] file_info = QFileInfo(infile) file_size = file_info.size() size = DbConnections().db_size() file_size /= 1024 * 1024 size = size + file_size if size > float(max_size): QMessageBox.warning( None, self.tr("Database full"), self. tr("Upload would exceeded the maximum database size for your current QGIS Cloud plan. Please free up some space or upgrade your QGIS Cloud plan." )) return False opts['table'] = layer_info['table_name'] self.progress_label.setText( self.tr("Creating table '{table}'...").format(table=opts['table'])) QApplication.processEvents() self.cursor.execute(self.make_sql_drop_raster_table(opts['table'])) self.conn.commit() self.cursor.execute(self.make_sql_create_table(opts, opts['table'])) self.conn.commit() gt = self.wkblify_raster(opts, infile.replace('\\', '/'), i, gt) i += 1 self.cursor.execute( self.make_sql_create_gist(opts['table'], opts['column'])) self.conn.commit() # create raster overviews for level in [4, 8, 16, 32]: sql = 'drop table if exists o_%d_%s' % (level, opts['table']) self.cursor.execute(sql) self.conn.commit() sql = "select st_createoverview_qgiscloud('%s'::regclass, '%s'::name, %d)" % ( opts['table'], opts['column'], level) self.progress_label.setText( self.tr( "Creating overview-level {level} for table '{table}'..."). format(level=level, table=opts['table'])) QApplication.processEvents() self.cursor.execute(sql) self.conn.commit() index_table = 'o_' + str(level) + '_' + opts['table'] self.cursor.execute( self.make_sql_create_gist(index_table, opts['column'])) self.conn.commit() self.progress_label.setText( self.tr("Registering raster columns of table '%s'..." % (opts['table']))) QApplication.processEvents() self.cursor.execute(self.make_sql_addrastercolumn(opts)) self.conn.commit()
def run_query(self): """ Process for running the query """ # Block the button and save the initial text QApplication.setOverrideCursor(Qt.WaitCursor) self.output_directory.setDisabled(True) self.pushButton_showQuery.setDisabled(True) self.start_process() QApplication.processEvents() # Get all values key = str(self.comboBox_key.currentText()) value = str(self.comboBox_value.currentText()) nominatim = self.nominatim_value() timeout = self.spinBox_timeout.value() output_directory = self.output_directory.filePath() prefix_file = self.lineEdit_filePrefix.text() if self.comboBox_in_around.currentIndex() == 1: is_around = True else: is_around = False distance = self.spinBox_distance_point.value() # Which geometry at the end ? output_geometry_types = self.get_output_geometry_types() # Which osm objects ? osm_objects = self._get_osm_objects() try: # Test values if not osm_objects: raise OsmObjectsException if not output_geometry_types: raise OutPutGeomTypesException # If bbox, we must set None to nominatim, we can't have both bbox = None if self.radioButton_extentLayer.isChecked() or \ self.radioButton_extentMapCanvas.isChecked(): nominatim = None bbox = self.get_bounding_box() if nominatim == '': nominatim = None if output_directory and not isdir(output_directory): raise DirectoryOutPutException num_layers = process_quick_query( dialog=self, key=key, value=value, nominatim=nominatim, is_around=is_around, distance=distance, bbox=bbox, osm_objects=osm_objects, timeout=timeout, output_directory=output_directory, prefix_file=prefix_file, output_geometry_types=output_geometry_types) # We can test numLayers to see if there are some results if num_layers: self.label_progress.setText( tr('QuickOSM', u'Successful query !')) display_message_bar(tr('QuickOSM', u'Successful query !'), level=Qgis.Success, duration=5) else: self.label_progress.setText(tr("QuickOSM", u'No result')) display_message_bar(tr('QuickOSM', u'Successful query, but no result.'), level=Qgis.Warning, duration=7) except QuickOsmException as e: self.display_geo_algorithm_exception(e) except Exception as e: # pylint: disable=broad-except self.display_exception(e) finally: # Resetting the button self.output_directory.setDisabled(False) self.pushButton_showQuery.setDisabled(False) QApplication.restoreOverrideCursor() self.end_process() QApplication.processEvents()
def compute(self): from AcATaMa.gui.acatama_dockwidget import AcATaMaDockWidget as AcATaMa AcATaMa.dockwidget.QPBtn_ComputeViewAccurasyAssessment.setText("Processing, please wait ...") QApplication.processEvents() # get labels from classification buttons labels = {} for button_config in self.classification.buttons_config.values(): labels[button_config["thematic_class"]] = button_config["name"] # get the classified and thematic map values thematic_map_values = [] classified_values = [] samples_outside_the_thematic = [] classification_points = [point for point in self.classification.points if point.is_classified] points_ordered = sorted(classification_points, key=lambda p: p.shape_id) for point in points_ordered: # classification from the pixel values in the thematic map thematic_map_value = self.ThematicR.get_pixel_value_from_pnt(point.QgsPnt) if not thematic_map_value: samples_outside_the_thematic.append(point) continue thematic_map_values.append(int(thematic_map_value)) # classified value made/checked by user with classification buttons classified_value = self.classification.buttons_config[point.classif_id]["thematic_class"] classified_values.append(int(classified_value)) # all unique and sorted values values = sorted(set(thematic_map_values + classified_values)) # Construct a value->index dictionary indices = dict((val, i) for (i, val) in enumerate(values)) # calculate the error/confusion matrix # https://github.com/nltk/nltk/blob/develop/nltk/metrics/confusionmatrix.py # # classified # t | | L1 | L2 | L3 | L4 | # h | L1 | | | | | # e | L2 | | | | | # m | L3 | | | | | # a | L4 | | | | | # error_matrix = [[0 for column in values] for row in values] for thematic, classified in zip(thematic_map_values, classified_values): error_matrix[indices[thematic]][indices[classified]] += 1 # calculate the total number of pixel in the thematic raster # by each thematic raster class used in the classification buttons for thematic_map_value in values: if thematic_map_value not in self.thematic_pixels_count: self.thematic_pixels_count[thematic_map_value] = self.ThematicR.get_total_pixels_by_value(thematic_map_value) # values necessary for results self.values = values self.labels = labels self.error_matrix = error_matrix self.samples_outside_the_thematic = samples_outside_the_thematic # set area by pixel self.pixel_area_base = self.ThematicR.qgs_layer.rasterUnitsPerPixelX() * self.ThematicR.qgs_layer.rasterUnitsPerPixelY() self.pixel_area_value = self.pixel_area_base * QgsUnitTypes.fromUnitToUnitFactor(self.base_area_unit, self.area_unit) self.pixel_area_unit = QgsUnitTypes.toAbbreviatedString(self.area_unit)
from QGIS_FMV.utils.QgsFmvInstaller import WindowsInstaller import platform windows = platform.system() == 'Windows' from QGIS_FMV.utils.QgsUtils import QgsUtils as qgsu from qgis.PyQt.QtWidgets import QMessageBox from qgis.utils import iface from qgis.utils import reloadPlugin from qgis.core import Qgis as QGis from qgis.PyQt.QtCore import Qt from qgis.PyQt.QtWidgets import QApplication # Check dependencies if windows: try: QApplication.setOverrideCursor(Qt.PointingHandCursor) QApplication.processEvents() WindowsInstaller() reloadPlugin('QGIS_FMV') iface.messageBar().pushMessage( "QGIS FMV", "QGIS Full Motion Video installed correctly", QGis.Info, 3) QApplication.restoreOverrideCursor() except Exception as e: QApplication.restoreOverrideCursor() None # buttonReply = qgsu.CustomMessage("QGIS FMV", "", "you need to restart your QGIS,Do you really close?", icon="Information") # if buttonReply == QMessageBox.Yes: # # TODO : Restart QGIS # iface.actionExit().trigger()
def ExpandLayer(layer, value=True): '''Collapse/Expand layer''' ltl = QgsProject.instance().layerTreeRoot().findLayer(layer.id()) ltl.setExpanded(value) QApplication.processEvents() return
def set_progress_percentage(self, percent): """Slot to update percentage during process.""" self.progress_bar.setValue(percent) QApplication.processEvents()
def CreateMISB(self): ''' Create MISB Video ''' ''' Only tested using DJI Data ''' # Create ProgressBar self.iface.messageBar().clearWidgets() progressMessageBar = self.iface.messageBar().createMessage( "Creating video packets...") progress = QProgressBar() progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.iface.messageBar().pushWidget(progressMessageBar, QGis.Info) QApplication.setOverrideCursor(Qt.WaitCursor) QApplication.processEvents() HFOV = self.sp_hfov.value() index = self.cmb_telemetry.currentIndex() out_record = self.cmb_telemetry.itemData(index) rowCount = self.GetRows(out_record) progress.setMaximum(rowCount) d = {} with open(out_record, encoding=encoding) as csvfile: reader = csv.DictReader(csvfile) for row in reader: date_start = datetime.strptime(row["CUSTOM.updateTime"], '%Y/%m/%d %H:%M:%S.%f') break with open(out_record, encoding=encoding) as csvfile: reader = csv.DictReader(csvfile) for row in reader: for k in row: stripK = k.strip() stripV = row[k].strip() d[stripK] = stripV # We create the klv file for every moment sizeTotal = 0 bufferData = b'' cnt = 0 for k, v in d.items(): try: if k == "CUSTOM.updateTime": # We prevent it from failing in the exact times that don't have milliseconds try: date_end = datetime.strptime( v, '%Y/%m/%d %H:%M:%S.%f') except: date_end = datetime.strptime( v, '%Y/%m/%d %H:%M:%S') _bytes = datetime_to_bytes(date_end) _len = int_to_bytes(len(_bytes)) _bytes = _key2 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Platform Heading Angle if k == "OSD.yaw": OSD_yaw = float(v) if OSD_yaw < 0: OSD_yaw = OSD_yaw + 360 _bytes = float_to_bytes(round(OSD_yaw, 4), _domain5, _range5) _len = int_to_bytes(len(_bytes)) _bytes = _key5 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Platform Pitch Angle if k == "OSD.pitch": OSD_pitch = float(v) _bytes = float_to_bytes(round(OSD_pitch, 4), _domain6, _range6) _len = int_to_bytes(len(_bytes)) _bytes = _key6 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Platform Roll Angle if k == "OSD.roll": OSD_roll = float(v) _bytes = float_to_bytes(round(OSD_roll, 4), _domain7, _range7) _len = int_to_bytes(len(_bytes)) _bytes = _key7 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Sensor Latitude if k == "OSD.latitude": OSD_latitude = float(v) _bytes = float_to_bytes(round(OSD_latitude, 4), _domain13, _range13) _len = int_to_bytes(len(_bytes)) _bytes = _key13 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Sensor Longitude if k == "OSD.longitude": OSD_longitude = float(v) _bytes = float_to_bytes(OSD_longitude, _domain14, _range14) _len = int_to_bytes(len(_bytes)) _bytes = _key14 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Sensor True Altitude if k == "OSD.altitude [m]": OSD_altitude = float(v) _bytes = float_to_bytes(round(OSD_altitude, 4), _domain15, _range15) _len = int_to_bytes(len(_bytes)) _bytes = _key15 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Sensor Ellipsoid Height if k == "OSD.height [m]": OSD_height = float(v) _bytes = float_to_bytes(round(OSD_height, 4), _domain75, _range75) _len = int_to_bytes(len(_bytes)) _bytes = _key75 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Sensor Relative Azimuth Angle if k == "GIMBAL.yaw": # GIMBAL_yaw = float(v) GIMBAL_yaw = 0.0 _bytes = float_to_bytes(round(GIMBAL_yaw, 4), _domain18, _range18) _len = int_to_bytes(len(_bytes)) _bytes = _key18 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Sensor Relative Elevation Angle if k == "GIMBAL.pitch": GIMBAL_pitch = float(v) _bytes = float_to_bytes(round(GIMBAL_pitch, 4), _domain19, _range19) _len = int_to_bytes(len(_bytes)) _bytes = _key19 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Sensor Relative Roll Angle if k == "GIMBAL.roll": GIMBAL_roll = float(v) _bytes = float_to_bytes(round(GIMBAL_roll, 4), _domain20, _range20) _len = int_to_bytes(len(_bytes)) _bytes = _key20 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes except Exception: print("Multiplexer error") continue try: # Diference time td = date_end - date_start end_path = self.klv_folder + "/%.1f.klv" % (round( td.total_seconds(), 1)) # CheckSum v = abs(hash(end_path)) % (10**4) _bytes = int_to_bytes(v, 4) _len = int_to_bytes(len(_bytes)) _bytes = _key1 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Sensor Horizontal Field of View v = self.sp_hfov.value() _bytes = float_to_bytes(float(v), _domain16, _range16) _len = int_to_bytes(len(_bytes)) _bytes = _key16 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Sensor Vertical Field of View v = self.sp_vfov.value() _bytes = float_to_bytes(float(v), _domain17, _range17) _len = int_to_bytes(len(_bytes)) _bytes = _key17 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # TODO : Check these calculations # Slant Range anlge = 180 + (OSD_pitch + GIMBAL_pitch) slantRange = abs(OSD_altitude / (cos(radians(anlge)))) _bytes = float_to_bytes(round(slantRange, 4), _domain21, _range21) _len = int_to_bytes(len(_bytes)) _bytes = _key21 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Target Width # targetWidth = 0.0 targetWidth = 2.0 * slantRange * tan(radians(HFOV / 2.0)) _bytes = float_to_bytes(round(targetWidth, 4), _domain22, _range22) _len = int_to_bytes(len(_bytes)) _bytes = _key22 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Frame Center Latitude angle = 90 + (OSD_pitch + GIMBAL_pitch) tgHzDist = OSD_altitude * tan(radians(angle)) r_earth = 6371008.8 dy = tgHzDist * cos(radians(OSD_yaw)) framecenterlatitude = OSD_latitude + (dy / r_earth) * (180 / pi) _bytes = float_to_bytes(round(framecenterlatitude, 4), _domain23, _range23) _len = int_to_bytes(len(_bytes)) _bytes = _key23 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Frame Center Longitude dx = tgHzDist * sin(radians(OSD_yaw)) framecenterlongitude = OSD_longitude + (dx / r_earth) * ( 180 / pi) / cos(OSD_latitude * pi / 180) _bytes = float_to_bytes(round(framecenterlongitude, 4), _domain24, _range24) _len = int_to_bytes(len(_bytes)) _bytes = _key24 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Frame Center Elevation frameCenterElevation = 0.0 _bytes = float_to_bytes(frameCenterElevation, _domain25, _range25) _len = int_to_bytes(len(_bytes)) _bytes = _key25 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # TODO : If we save the corners in the klv have a overflow # # CALCULATE CORNERS COORDINATES # sensor = (OSD_longitude, OSD_latitude, OSD_altitude) # frameCenter = (destPoint[0], destPoint[1], frameCenterElevation) # FOV = (VFOV, HFOV) # others = (OSD_yaw, GIMBAL_yaw, targetWidth, slantRange) # cornerPointUL, cornerPointUR, cornerPointLR, cornerPointLL = CornerEstimationWithoutOffsets(sensor=sensor, frameCenter=frameCenter, FOV=FOV, others=others) # # # Corner Latitude Point 1 (Full) # _bytes = float_to_bytes(round(cornerPointUL[0],4), _domain82, _range82) # _len = int_to_bytes(len(_bytes)) # _bytes = _key82 + _len + _bytes # sizeTotal += len(_bytes) # bufferData += _bytes # # # Corner Longitude Point 1 (Full) # _bytes = float_to_bytes(round(cornerPointUL[1],4), _domain83, _range83) # _len = int_to_bytes(len(_bytes)) # _bytes = _key83 + _len + _bytes # sizeTotal += len(_bytes) # bufferData += _bytes # # # Corner Latitude Point 2 (Full) # _bytes = float_to_bytes(round(cornerPointUR[0],4), _domain84, _range84) # _len = int_to_bytes(len(_bytes)) # _bytes = _key84 + _len + _bytes # sizeTotal += len(_bytes) # bufferData += _bytes # # # Corner Longitude Point 2 (Full) # _bytes = float_to_bytes(round(cornerPointUR[1],4), _domain85, _range85) # _len = int_to_bytes(len(_bytes)) # _bytes = _key85 + _len + _bytes # sizeTotal += len(_bytes) # bufferData += _bytes # # # Corner Latitude Point 3 (Full) # _bytes = float_to_bytes(round(cornerPointLR[0],4), _domain86, _range86) # _len = int_to_bytes(len(_bytes)) # _bytes = _key86 + _len + _bytes # sizeTotal += len(_bytes) # bufferData += _bytes # # # Corner Longitude Point 3 (Full) # _bytes = float_to_bytes(round(cornerPointLR[1],4), _domain87, _range87) # _len = int_to_bytes(len(_bytes)) # _bytes = _key87 + _len + _bytes # sizeTotal += len(_bytes) # bufferData += _bytes # # # Corner Latitude Point 4 (Full) # _bytes = float_to_bytes(round(cornerPointLL[0],4), _domain88, _range88) # _len = int_to_bytes(len(_bytes)) # _bytes = _key88 + _len + _bytes # sizeTotal += len(_bytes) # bufferData += _bytes # # # Corner Longitude Point 4 (Full) # _bytes = float_to_bytes(round(cornerPointLL[1],4), _domain89, _range89) # _len = int_to_bytes(len(_bytes)) # _bytes = _key89 + _len + _bytes # sizeTotal += len(_bytes) # bufferData += _bytes # Platform Pitch Angle (Full) _bytes = float_to_bytes(round(OSD_pitch, 4), _domain90, _range90) _len = int_to_bytes(len(_bytes)) _bytes = _key90 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # Platform Roll Angle (Full) _bytes = float_to_bytes(round(OSD_roll, 4), _domain91, _range91) _len = int_to_bytes(len(_bytes)) _bytes = _key91 + _len + _bytes sizeTotal += len(_bytes) bufferData += _bytes # set packet header writeData = cle writeData += int_to_bytes(sizeTotal) writeData += bufferData # Write packet f_write = open(end_path, "wb+") f_write.write(writeData) f_write.close() cnt += 1 progress.setValue(cnt) except Exception as e: print("Multiplexer error : " + str(e)) QApplication.restoreOverrideCursor() QApplication.processEvents() progress.setValue(rowCount) self.iface.messageBar().clearWidgets() # We add it to the manager _, name = os.path.split(self.video_file) self.parent.AddFileRowToManager(name, self.video_file, islocal=True, klv_folder=self.klv_folder) # Close dialog self.close() return
def set_progress_text(self, text): """Slot to update text during process.""" self.progress_text.setText(text) QApplication.processEvents()
def setMsg(self, msg): self.widget.setText(msg) QApplication.processEvents()
def action_do_export(): default_folder = QgsSettings().value( "qgep_pluging/last_interlis_path", QgsProject.instance().absolutePath()) file_name, _ = QFileDialog.getSaveFileName( None, plugin.tr("Export to file"), os.path.join(default_folder, "qgep-export.xtf"), plugin.tr("Interlis transfer files (*.xtf)"), ) if not file_name: # Operation canceled return QgsSettings().setValue("qgep_pluging/last_interlis_path", os.path.dirname(file_name)) progress_dialog = QProgressDialog("", "", 0, 100, plugin.iface.mainWindow()) progress_dialog.setCancelButton(None) progress_dialog.setModal(True) progress_dialog.show() # Prepare the temporary ili2pg model progress_dialog.setLabelText("Creating ili schema...") QApplication.processEvents() log_path = make_log_path(None, "create") try: create_ili_schema( config.ABWASSER_SCHEMA, config.ABWASSER_ILI_MODEL, log_path, recreate_schema=True, ) except CmdException: progress_dialog.close() show_failure( "Could not create the ili2pg schema", "Open the logs for more details on the error.", log_path, ) return progress_dialog.setValue(25) # Export to the temporary ili2pg model progress_dialog.setLabelText("Converting from QGEP...") QApplication.processEvents() qgep_export(selection=export_dialog.selected_ids) progress_dialog.setValue(50) # Export from ili2pg model to file progress_dialog.setLabelText("Saving XTF file...") QApplication.processEvents() log_path = make_log_path(None, "export") try: export_xtf_data( config.ABWASSER_SCHEMA, config.ABWASSER_ILI_MODEL_NAME, file_name, log_path, ) except CmdException: progress_dialog.close() show_failure( "Could not export the ili2pg schema", "Open the logs for more details on the error.", log_path, ) return progress_dialog.setValue(75) progress_dialog.setLabelText("Validating the output file...") QApplication.processEvents() log_path = make_log_path(None, "validate") try: validate_xtf_data( file_name, log_path, ) except CmdException: progress_dialog.close() show_failure( "Invalid file", "The created file is not a valid XTF file.", log_path, ) return progress_dialog.setValue(100) show_success( "Sucess", f"Data successfully exported to {file_name}", os.path.dirname(log_path), )
def commit_str(self): """ Slot raised when the user clicks on Finish button in order to create a new STR entry. """ isValid = True # Create a progress dialog try: progress = STDMProgressDialog(iface.mainWindow()) progress.show() if not self.str_edit_node: QApplication.processEvents() progress.setRange(0, len(self.data_store)) progress.overall_progress('Creating a STR...', ) for i, str_store in enumerate(self.data_store.values()): progress.progress_message('Saving STR {}'.format(i + 1), '') progress.setValue(i + 1) self.on_add_str(str_store) # ==> progress.deleteLater() progress = None strMsg = QApplication.translate( "STRDBHandler", "The social tenure relationship has " "been successfully created!") QMessageBox.information( iface.mainWindow(), QApplication.translate("STRDBHandler", "Social Tenure Relationship"), strMsg) else: QApplication.processEvents() progress.setRange(0, 1) progress.setValue(0) progress.overall_progress('Editing a STR...', ) progress.progress_message('Updating STR', '') updated_str_obj = self.on_edit_str(self.data_store[1]) # ===> progress.deleteLater() progress = None strMsg = QApplication.translate( "STRDBHandler", "The social tenure relationship has " "been successfully updated!") QMessageBox.information( iface.mainWindow(), QApplication.translate("STRDBHandler", "Social Tenure Relationship"), strMsg) return updated_str_obj except exc.OperationalError as oe: errMsg = str(oe) QMessageBox.critical( iface.mainWindow(), QApplication.translate("STRDBHandler", "Unexpected Error"), errMsg) progress.deleteLater() progress = None isValid = False STDMDb.instance().session.rollback() LOGGER.debug(str(oe)) except exc.IntegrityError as ie: errMsg = str(ie) QMessageBox.critical( iface.mainWindow(), QApplication.translate("STRDBHandler", "Duplicate Relationship Error"), errMsg) progress.deleteLater() progress = None isValid = False STDMDb.instance().session.rollback() LOGGER.debug(str(ie)) except exc.InternalError as ie: QMessageBox.critical( iface.mainWindow(), QApplication.translate('STRDBHandler', 'InternalError Error'), QApplication.translate( 'STRDBHandler', 'Sorry, there is an internal error. \n' 'Restart QGIS to fix the issue.')) LOGGER.debug(str(ie)) progress.deleteLater() progress = None isValid = False STDMDb.instance().session.rollback() except DummyException as e: errMsg = str(e) QMessageBox.critical( iface.mainWindow(), QApplication.translate('STRDBHandler', 'Unexpected Error'), errMsg) LOGGER.debug(str(e)) isValid = False STDMDb.instance().session.rollback() progress.deleteLater() progress = None finally: STDMDb.instance().session.rollback() if progress is not None: progress.deleteLater() progress = None return isValid
def action_import(plugin, pgservice=None): """ Is executed when the user clicks the importAction tool """ global import_dialog # avoid garbage collection if not configure_from_modelbaker(plugin.iface): return if pgservice: config.PGSERVICE = pgservice default_folder = QgsSettings().value("qgep_pluging/last_interlis_path", QgsProject.instance().absolutePath()) file_name, _ = QFileDialog.getOpenFileName( None, plugin.tr("Import file"), default_folder, plugin.tr("Interlis transfer files (*.xtf)")) if not file_name: # Operation canceled return QgsSettings().setValue("qgep_pluging/last_interlis_path", os.path.dirname(file_name)) progress_dialog = QProgressDialog("", "", 0, 100, plugin.iface.mainWindow()) progress_dialog.setCancelButton(None) progress_dialog.setModal(True) progress_dialog.show() # Validating the input file progress_dialog.setLabelText("Validating the input file...") QApplication.processEvents() log_path = make_log_path(None, "validate") try: validate_xtf_data( file_name, log_path, ) except CmdException: progress_dialog.close() show_failure( "Invalid file", "The input file is not a valid XTF file. Open the logs for more details on the error.", log_path, ) return # Prepare the temporary ili2pg model progress_dialog.setLabelText("Creating ili schema...") QApplication.processEvents() log_path = make_log_path(None, "create") try: create_ili_schema( config.ABWASSER_SCHEMA, config.ABWASSER_ILI_MODEL, log_path, recreate_schema=True, ) except CmdException: progress_dialog.close() show_failure( "Could not create the ili2pg schema", "Open the logs for more details on the error.", log_path, ) return progress_dialog.setValue(33) # Export from ili2pg model to file progress_dialog.setLabelText("Importing XTF data...") QApplication.processEvents() log_path = make_log_path(None, "import") try: import_xtf_data( config.ABWASSER_SCHEMA, file_name, log_path, ) except CmdException: progress_dialog.close() show_failure( "Could not import data", "Open the logs for more details on the error.", log_path, ) return progress_dialog.setValue(66) # Export to the temporary ili2pg model progress_dialog.setLabelText("Converting to QGEP...") QApplication.processEvents() import_dialog = GuiImport(plugin.iface.mainWindow()) progress_dialog.setValue(100) qgep_import(precommit_callback=import_dialog.init_with_session, )
def open_file(dialog=None, osm_file=None, output_geom_types=None, white_list_column=None, layer_name="OsmFile", config_outputs=None, output_dir=None, final_query=None, prefix_file=None): """ Open an osm file. Memory layer if no output directory is set, or Geojson in the output directory. :param final_query: The query where the file comes from. Might be empty if it's a local OSM file. :type final_query: basestring """ outputs = {} if output_dir: for layer in ['points', 'lines', 'multilinestrings', 'multipolygons']: if not prefix_file: prefix_file = layer_name outputs[layer] = join(output_dir, prefix_file + "_" + layer + ".geojson") if isfile(outputs[layer]): raise FileOutPutException(suffix='(' + outputs[layer] + ')') # Legacy, waiting to remove the OsmParser for QGIS >= 3.6 # Change in osm_file_dialog.py L131 too output_geom_legacy = [l.value.lower() for l in output_geom_types] if not white_list_column: white_list_column = {} white_list_legacy = ({ l.value.lower(): csv for l, csv in white_list_column.items() }) LOGGER.info('The OSM file is: {}'.format(osm_file)) # Parsing the file osm_parser = OsmParser(osm_file=osm_file, layers=output_geom_legacy, white_list_column=white_list_legacy) osm_parser.signalText.connect(dialog.set_progress_text) osm_parser.signalPercentage.connect(dialog.set_progress_percentage) start_time = time.time() layers = osm_parser.parse() elapsed_time = time.time() - start_time parser_time = time.strftime("%Hh %Mm %Ss", time.gmtime(elapsed_time)) LOGGER.info('The OSM parser took: {}'.format(parser_time)) # Finishing the process with geojson or memory layer num_layers = 0 for i, (layer, item) in enumerate(layers.items()): dialog.set_progress_percentage(i / len(layers) * 100) QApplication.processEvents() if item['featureCount'] and (LayerType(layer.capitalize()) in output_geom_types): final_layer_name = layer_name # If configOutputs is not None (from My Queries) if config_outputs: if config_outputs[layer]['namelayer']: final_layer_name = config_outputs[layer]['namelayer'] if output_dir: dialog.set_progress_text( tr('From memory layer to GeoJSON: ' + layer)) # Transforming the vector file osm_geometries = { 'points': QgsWkbTypes.Point, 'lines': QgsWkbTypes.LineString, 'multilinestrings': QgsWkbTypes.MultiLineString, 'multipolygons': QgsWkbTypes.MultiPolygon } memory_layer = item['vector_layer'] encoding = get_default_encoding() writer = QgsVectorFileWriter(outputs[layer], encoding, memory_layer.fields(), osm_geometries[layer], memory_layer.crs(), "GeoJSON") for f in memory_layer.getFeatures(): writer.addFeature(f) del writer # Loading the final vector file new_layer = QgsVectorLayer(outputs[layer], final_layer_name, "ogr") else: new_layer = item['vector_layer'] new_layer.setName(final_layer_name) # Try to set styling if defined if config_outputs and config_outputs[layer]['style']: new_layer.loadNamedStyle(config_outputs[layer]['style']) else: # Loading default styles if layer == "multilinestrings" or layer == "lines": if "colour" in item['tags']: new_layer.loadNamedStyle( join(dirname(dirname(abspath(__file__))), "styles", layer + "_colour.qml")) # Add action about OpenStreetMap add_actions(new_layer, item['tags']) if final_query: QgsExpressionContextUtils.setLayerVariable( new_layer, 'quickosm_query', final_query) QgsProject.instance().addMapLayer(new_layer) num_layers += 1 return num_layers
def open_file( dialog=None, osm_file=None, output_geom_types=None, white_list_column=None, layer_name="OsmFile", config_outputs=None, output_dir=None, final_query=None, prefix_file=None): """ Open an osm file. Memory layer if no output directory is set, or Geojson in the output directory. :param final_query: The query where the file comes from. Might be empty if it's a local OSM file. :type final_query: basestring """ outputs = {} if output_dir: for layer in ['points', 'lines', 'multilinestrings', 'multipolygons']: if not prefix_file: prefix_file = layer_name outputs[layer] = join( output_dir, prefix_file + "_" + layer + ".geojson") if isfile(outputs[layer]): raise FileOutPutException(suffix='(' + outputs[layer] + ')') # Legacy, waiting to remove the OsmParser for QGIS >= 3.6 # Change in osm_file_dialog.py L131 too output_geom_legacy = [l.value.lower() for l in output_geom_types] if not white_list_column: white_list_column = {} white_list_legacy = ( {l.value.lower(): csv for l, csv in white_list_column.items()} ) LOGGER.info('The OSM file is: {}'.format(osm_file)) # Parsing the file osm_parser = OsmParser( osm_file=osm_file, layers=output_geom_legacy, white_list_column=white_list_legacy) osm_parser.signalText.connect(dialog.set_progress_text) osm_parser.signalPercentage.connect(dialog.set_progress_percentage) start_time = time.time() layers = osm_parser.parse() elapsed_time = time.time() - start_time parser_time = time.strftime("%Hh %Mm %Ss", time.gmtime(elapsed_time)) LOGGER.info('The OSM parser took: {}'.format(parser_time)) # Finishing the process with geojson or memory layer num_layers = 0 for i, (layer, item) in enumerate(layers.items()): dialog.set_progress_percentage(i / len(layers) * 100) QApplication.processEvents() if item['featureCount'] and LayerType(layer.capitalize()) in output_geom_types: final_layer_name = layer_name # If configOutputs is not None (from My Queries) if config_outputs: if config_outputs[layer]['namelayer']: final_layer_name = config_outputs[layer]['namelayer'] if output_dir: dialog.set_progress_text(tr('From memory to GeoJSON: ' + layer)) # Transforming the vector file osm_geometries = { 'points': QgsWkbTypes.Point, 'lines': QgsWkbTypes.LineString, 'multilinestrings': QgsWkbTypes.MultiLineString, 'multipolygons': QgsWkbTypes.MultiPolygon} memory_layer = item['vector_layer'] encoding = get_default_encoding() writer = QgsVectorFileWriter( outputs[layer], encoding, memory_layer.fields(), osm_geometries[layer], memory_layer.crs(), "GeoJSON") for f in memory_layer.getFeatures(): writer.addFeature(f) del writer # Loading the final vector file new_layer = QgsVectorLayer(outputs[layer], final_layer_name, "ogr") else: new_layer = item['vector_layer'] new_layer.setName(final_layer_name) # Try to set styling if defined if config_outputs and config_outputs[layer]['style']: new_layer.loadNamedStyle(config_outputs[layer]['style']) else: # Loading default styles if layer == "multilinestrings" or layer == "lines": if "colour" in item['tags']: new_layer.loadNamedStyle( join(dirname(dirname(abspath(__file__))), "styles", layer + "_colour.qml")) # Add action about OpenStreetMap add_actions(new_layer, item['tags']) if final_query: QgsExpressionContextUtils.setLayerVariable( new_layer, 'quickosm_query', final_query) QgsProject.instance().addMapLayer(new_layer) num_layers += 1 return num_layers
def upload(self, db, data_sources_items, maxSize): import_ok = True layers_to_replace = {} raster_to_upload = {} self.status_bar.showMessage(self.tr("Uploading to database '{db}'...").format(db=db.database)) QApplication.processEvents() messages = "" # Connect to database try: conn = db.psycopg_connection() cursor = conn.cursor() except Exception as e: raise RuntimeError("Connection to database failed %s" % str(e)) for data_source, item in list(data_sources_items.items()): # Check available space, block if exceded size = DbConnections().db_size() if size > float(maxSize): QMessageBox.warning(None, self.tr("Database full"), self.tr("You have exceeded the maximum database size for your current QGIS Cloud plan. Please free up some space or upgrade your QGIS Cloud plan.")) break # Layers contains all layers with shared data source layer = item['layers'][0] if layer.type() == QgsMapLayer.VectorLayer: fields = QgsFields(layer.fields()) srid = layer.crs().postgisSrid() geom_column = "wkb_geometry" wkbType = layer.wkbType() # Check if database schema exists cursor.execute("SELECT EXISTS(SELECT 1 FROM pg_namespace WHERE nspname = '%s')" % item['schema']) schema_exists = cursor.fetchone()[0] if not schema_exists: cursor.execute("create schema %s" % item['schema']) if wkbType == QgsWkbTypes.NoGeometry: cloudUri = "dbname='%s' host=%s port=%d user='******' password='******' key='' table=\"%s\".\"%s\"" % ( db.database, db.host, db.port, db.username, db.password, item['schema'], item['table']) geom_column = "" else: if not QgsWkbTypes.isMultiType(wkbType): wkbType = QgsWkbTypes.multiType(wkbType) # Create table (pk='' => always generate a new primary key) cloudUri = "dbname='%s' host=%s port=%d user='******' password='******' key='' table=\"%s\".\"%s\" (%s)" % ( db.database, db.host, db.port, db.username, db.password, item['schema'], item['table'], geom_column ) self.progress_label.setText(self.tr("Creating table '{table}'...").format(table=item['table'])) QApplication.processEvents() if wkbType != QgsWkbTypes.NoGeometry: # Check if SRID is known on database, otherwise create record cursor.execute("SELECT srid FROM public.spatial_ref_sys WHERE srid = %s" % layer.crs().postgisSrid()) if not cursor.fetchone(): try: cursor.execute("INSERT INTO public.spatial_ref_sys VALUES ({srid},'EPSG',{srid},'{wktstr}','{projstr}')".format( srid = layer.crs().postgisSrid(), wktstr = layer.crs().toWkt(), projstr = layer.crs().toProj4())) conn.commit() except Exception as e: conn.rollback() import_ok &= False messages += "Failed to create SRS record on database: " + str(e) + "\n" continue # cursor.close() # TODO: Ask user for overwriting existing table # The postgres provider is terribly slow at creating tables with # many attribute columns in QGIS < 2.9.0 vectorLayerImport = PGVectorLayerImport(db, conn, cursor, cloudUri, fields, wkbType, layer.crs(), True) if vectorLayerImport.hasError(): import_ok &= False messages += "VectorLayerImport-Error: "+vectorLayerImport.errorMessage() + "\n" continue vectorLayerImport = None # Build import string attribs = list(range(0, fields.count())) count = 0 importstr = bytearray() ok = True self.progress_label.setText(self.tr("Uploading features...")) QApplication.processEvents() for feature in layer.getFeatures(): f_geometry = feature.geometry() f_geometry.convertToMultiType() # First field is primary key importstr.extend(str(count).encode('utf-8')) count += 1 if not feature.geometry(): if layer.isSpatial(): QgsMessageLog.logMessage(self.tr("Feature {id} of layer {layer} has no geometry").format(id=feature.id(), layer=layer.name()), "QGISCloud") importstr.extend(b"\t" + b"\\N") elif f_geometry.wkbType() != wkbType: QgsMessageLog.logMessage(self.tr("Feature {id} of layer {layer} has wrong geometry type {type}").format(id=feature.id(), layer=layer.name(), type= QgsWkbTypes.displayString(feature.geometry().wkbType())), "QGISCloud") importstr.extend(b"\t" + b"\\N") else: # Second field is geometry in EWKB Hex format importstr.extend(b"\t" + self._wkbToEWkbHex(f_geometry.asWkb(), srid)) # Finally, copy data attributes for attrib in attribs: val = feature[attrib] if val is None or isinstance(val, QVariant): val = b"\\N" elif isinstance(val, QDate) or isinstance(val, QDateTime): val = bytearray(val.toString(Qt.ISODate).encode('utf-8')) if not val: val = b"\\N" else: if isinstance( val, list ): listString = '{' if len( val ) > 0: listString = listString + ('"' + '","'.join( val ) + '"') listString = listString + '}' val = listString val = bytearray(str(val).encode('utf-8')) val = val.replace(b'\x00',b'?') val = val.replace(b'\t', b"E'\t'") val = val.replace(b'\n', b"E'\n'") val = val.replace(b'\r', b"E'\r'") val = val.replace(b'\\', b"\\") importstr += b"\t" + val importstr += b"\n" # Upload in chunks if (count % 100) == 0: try: cursor.copy_from(StringIO(importstr.decode('utf-8')), '"%s"."%s"' % (item['schema'], item['table'])) except Exception as e: messages += str(e) + "\n" ok = False break importstr = bytearray() self.progress_label.setText(self.tr("{table}: {count} features uploaded").format( table=item['table'], count=count)) QApplication.processEvents() # Periodically update ui if (count % 10) == 0: QApplication.processEvents() if ok and importstr: try: cursor.copy_from(StringIO(importstr.decode('utf-8')), '"%s"."%s"' % (item['schema'], item['table'])) except Exception as e: messages += str(e) + "\n" ok = False if ok: try: conn.commit() except Exception as e: messages += str(e) + "\n" ok = False else: conn.rollback() import_ok &= ok if ok: for layer in item['layers']: layers_to_replace[layer.id()] = { 'layer': layer, 'data_source': data_source, 'db_name': db.database, 'schema_name':item['schema'], 'table_name': item['table'], 'geom_column': geom_column } if wkbType != QgsWkbTypes.NoGeometry: sql = 'create index "{1}_{2}_idx" on "{0}"."{1}" using gist ("{2}");'.format(item['schema'], item['table'], geom_column) cursor.execute(sql) conn.commit() elif layer.type() == QgsMapLayer.RasterLayer: raster_to_upload = { 'layer': layer, 'data_source': layer.source(), 'db_name': db.database, 'schema_name': item['schema'], 'table_name': item['table'], 'geom_column': 'rast' } RasterUpload(conn, cursor, raster_to_upload, maxSize, self.progress_label) layers_to_replace[layer.id()] = raster_to_upload sql = """SELECT 'SELECT SETVAL(' || quote_literal(quote_ident(PGT.schemaname) || '.' || quote_ident(S.relname)) || ', COALESCE(MAX(' ||quote_ident(C.attname)|| ')+1, 1) ) FROM ' || quote_ident(PGT.schemaname)|| '.' ||quote_ident(T.relname)|| ';' FROM pg_class AS S, pg_depend AS D, pg_class AS T, pg_attribute AS C, pg_tables AS PGT, pg_namespace as PGNS WHERE S.relkind = 'S' AND S.oid = D.objid AND S.relnamespace = PGNS.oid AND PGNS.nspname = '{0}' AND D.refobjid = T.oid AND D.refobjid = C.attrelid AND D.refobjsubid = C.attnum AND T.relname = PGT.tablename AND schemaname = '{0}' AND tablename = '{1}' ORDER BY S.relname;""".format(item['schema'], item['table']) cursor.execute(sql) rows = cursor.fetchall() for row in rows: cursor.execute(row[0]) cursor.close() conn.close() self._replace_local_layers(layers_to_replace) self.progress_label.setText("") if not import_ok: raise RuntimeError(str(messages))
def set_progress_percentage(self, percent): """ Slot to update percentage during process """ self.progressBar_execution.setValue(percent) QApplication.processEvents()
def __init__(self, conn, cursor, raster, max_size, progress_label): QObject.__init__(self) self.cursor = cursor self.conn = conn self.progress_label = progress_label self.messages = "" opts = {} opts['version'] = g_rt_version opts['endian'] = NDR opts['column'] = 'rast' opts['create_table'] = 1 opts['drop_table'] = 1 opts['overview_level'] = 1 opts['block_size'] = 'auto' opts['band'] = None opts['register'] = None # Create PostGIS Raster Tool Functions raster_tools_file = "%s/raster_tools.sql" % os.path.dirname(__file__) sql = open(raster_tools_file).read().encode('ascii',errors='ignore') self.cursor.execute(sql) self.conn.commit() i = 0 # Burn all specified input raster files into single WKTRaster table gt = None layer_info = raster opts['srid'] = layer_info['layer'].dataProvider().crs().postgisSrid() infile = layer_info['data_source'] file_info = QFileInfo(infile) file_size = file_info.size() size = DbConnections().db_size() file_size /= 1024 * 1024 size = size + file_size if size > float(max_size): QMessageBox.warning(None, self.tr("Database full"), self.tr("Upload would exceeded the maximum database size for your current QGIS Cloud plan. Please free up some space or upgrade your QGIS Cloud plan.")) return False opts['schema_table'] = "\"%s\".\"%s\"" % (layer_info['schema_name'], layer_info['table_name']) opts['table'] = layer_info['table_name'] opts['schema'] = layer_info['schema_name'] self.progress_label.setText(self.tr("Creating table '{table}'...").format(table=opts['schema_table'].replace('"', ''))) QApplication.processEvents() self.cursor.execute(self.make_sql_drop_raster_table(opts['schema_table'])) self.conn.commit() self.cursor.execute(self.make_sql_create_table(opts, opts['schema_table'])) self.conn.commit() gt = self.wkblify_raster(opts, infile.replace( '\\', '/') , i, gt) i += 1 self.cursor.execute(self.make_sql_create_gist(opts['schema_table'], opts['column'])) self.conn.commit() # create raster overviews for level in [4, 8, 16, 32]: sql = 'drop table if exists "%s"."o_%d_%s"' %(opts['schema'], level, opts['table']) self.cursor.execute(sql) self.conn.commit() sql = "select st_createoverview_qgiscloud('%s'::text, '%s'::name, %d)" % (opts['schema_table'].replace('"', ''), opts['column'], level) self.progress_label.setText(self.tr("Creating overview-level {level} for table '{table}'...").format(level=level, table=opts['schema_table'].replace('"', ''))) QApplication.processEvents() self.cursor.execute(sql) self.conn.commit() index_table = opts['schema']+'.o_'+str(level)+'_'+opts['table'] self.cursor.execute(self.make_sql_create_gist(index_table, opts['column'])) self.conn.commit() self.progress_label.setText(self.tr("Registering raster columns of table '%s'..." % (opts['schema_table'].replace('"', '')))) QApplication.processEvents() self.cursor.execute(self.make_sql_addrastercolumn(opts)) self.conn.commit()
def on_btnRun_clicked(self): if self.ui.cmbProcessLayer.count() <= 0: return if self.ui.tbxOutput.text() == '': QMessageBox.critical(self, 'Raster to Vector Converter', 'Please specify output shapefile.') return self.setCursor(Qt.WaitCursor) #Get raster properties numX = self.player.width() numY = self.player.height() pixsizeX = self.player.rasterUnitsPerPixelX() pixsizeY = self.player.rasterUnitsPerPixelY() extents = self.player.extent() LLX = extents.xMinimum() LLY = extents.yMinimum() URX = extents.xMaximum() URY = extents.yMaximum() rprovider = self.player.dataProvider() if LLX > URX or LLY > URY: self.setCursor(Qt.ArrowCursor) QMessageBox.critical(self, 'Raster to Vector Converter', 'Unexpected image extents.') return #Create vector layer of pixel polygons or points at pixel centers #Assumes image extents are given as the LL coordinate of LL pixel #and UR coordinate of UR pixel. pfeat = QgsFeature() crsid = str(self.player.crs().authid()) if self.ui.rbPoints.isChecked(): pvlayer = QgsVectorLayer("Point?crs=" + crsid, "templayer", "memory") elif self.ui.rbPolygons.isChecked(): pvlayer = QgsVectorLayer("Polygon?crs=" + crsid, "templayer", "memory") fields = [QgsField("ID", QVariant.Int)] for i in range(self.player.bandCount()): bandname = self.player.bandName(i + 1) fields.append(QgsField(bandname, QVariant.Double)) pprovider = pvlayer.dataProvider() pprovider.addAttributes(fields) pvlayer.startEditing() count = 0 attr = [] totpix = float(numX * numY) for y in range(numY): for x in range(numX): newpt = QgsPoint(LLX + x * pixsizeX + pixsizeX / 2.0, LLY + y * pixsizeY + pixsizeY / 2.0) data = rprovider.identify(newpt, 1).results() if self.ui.rbPoints.isChecked(): pfeat.setGeometry(QgsGeometry.fromPoint(newpt)) elif self.ui.rbPolygons.isChecked(): newrect = QgsRectangle(LLX + x * pixsizeX, LLY + y * pixsizeY, LLX + x * pixsizeX + pixsizeX, LLY + y * pixsizeY + pixsizeY) pfeat.setGeometry(QgsGeometry.fromRect(newrect)) attr = list(data.values()) attr.insert(0, count) pfeat.setAttributes(attr) result = pvlayer.addFeature(pfeat) if not result: self.setCursor(Qt.ArrowCursor) QMessageBox.critical(self, 'Raster to Vector Converter', 'Processing error 2.') return del newpt if self.ui.rbPolygons.isChecked(): del newrect count += 1 self.ui.ProgressBar.setValue(float(count) / totpix * 100.0) QApplication.processEvents() pvlayer.commitChanges() pvlayer.updateExtents() #Write the output shapefile if os.path.exists(self.outfile): QgsVectorFileWriter.deleteShapeFile(self.outfile) result = QgsVectorFileWriter.writeAsVectorFormat( pvlayer, self.outfile, 'utf-8', self.player.crs()) if result != QgsVectorFileWriter.NoError: QMessageBox.critical(self, 'Raster to Vector Converter', 'Error creating shapefile.') else: #Ask to add shapfile to map name = QFileInfo(self.outfile).completeBaseName() result = QMessageBox.question(self, 'Raster to Vector Converter', 'Add shapefile to map?', QMessageBox.Yes, QMessageBox.No) if result == QMessageBox.Yes: self.iface.addVectorLayer(self.outfile, name, 'ogr') self.setCursor(Qt.ArrowCursor) self.close()
def update_progress_bar(self): self.value += 5 self.progress_bar.setValue(self.value) QApplication.processEvents()
class SplashScreen(object): def __init__(self, iface): self.iface = iface self.plugin_dir = os.path.dirname(__file__) self.windowTitle = "3Di Modeller Interface - Powered by QGIS" self.app = QApplication.instance() self.QApp = QCoreApplication.instance() if self.QApp is None: self.QApp = QApplication(sys.argv) self.QApp.startingUp() self.QApp.processEvents() self.app.startDragTime() self.iface.initializationCompleted.connect(self.customization) qApp.processEvents() self.applyStyle() def initGui(self): QSettings().setValue("/qgis/hideSplash", True) qApp.processEvents() icon = QIcon(":/3Di_images/3Di_images/images/logo.png") self.app.setWindowIcon(icon) self.iface.mainWindow().setWindowIcon(icon) self.iface.mainWindow().setWindowTitle(self.windowTitle) qApp.processEvents() if not self.iface.mainWindow().isVisible(): self.splash_pix = QPixmap(":/3Di_images/3Di_images/images/splash.png") self.splash = QSplashScreen(self.splash_pix, Qt.WindowStaysOnTopHint) self.splash = QSplashScreen(self.splash_pix) self.splash.setMask(self.splash_pix.mask()) self.splash.show() qApp.processEvents() self.applyStyle() self.addHelpMenuItem() return def run(self): pass def unload(self): qApp.processEvents() self.iface.initializationCompleted.disconnect(self.customization) self.helpAction.deleteLater() return def customization(self): self.splash.finish(self.iface.mainWindow()) self.iface.mainWindow().setWindowTitle(self.windowTitle) qApp.processEvents() self.applyStyle() def applyStyle(self): path = os.path.abspath( os.path.join(self.plugin_dir, "Modeler Interface", "stylesheet.qss") ) watch.removePaths(watch.files()) reload_style(path) @staticmethod def open3DiHelp(self): webbrowser.open_new("https://docs.3di.live") @staticmethod def about_3di_mi_dialog(): dialog = About3DiMIDialog(iface.mainWindow()) dialog.exec_() def find_3di_menu(self): for i, action in enumerate(self.iface.mainWindow().menuBar().actions()): if action.menu().objectName() == "m3Di": return action.menu() return None def addHelpMenuItem(self): menu = self.find_3di_menu() if not menu: menu = QMenu("&3Di", self.iface.mainWindow().menuBar()) menu.setObjectName("m3Di") self.iface.mainWindow().menuBar().addMenu(menu) self.helpAction = QAction( QIcon(":/3Di_images/3Di_images/images/logo.png"), "Documentation", self.iface.mainWindow(), ) self.helpAction.triggered.connect(self.open3DiHelp) self.helpAction.setWhatsThis("3Di Documentation") menu.addAction(self.helpAction) about_action = QAction( # QIcon(":/3Di_images/3Di_images/images/logo.png"), "About 3Di Modeller Interface", self.iface.mainWindow(), ) about_action.triggered.connect(self.about_3di_mi_dialog) about_action.setWhatsThis("About 3Di Modeller Interface") menu.addAction(about_action)
def run(self): """Run method that performs all the real work""" self.dlg.show() ok_result = self.dlg.exec_() if ok_result: c = False error_msg = str() if not self.dlg.LE_input.text(): error_msg = error_msg + "Ajouter un chemin d'acces " + \ "au(x) fichier(s) source.\n\n" c = True if not self.dlg.LE_output.text(): error_msg = error_msg + "Ajouter un chemin d'acces pour " + \ "le dossier de destination ou seront déposes " + \ "les fichiers produits.\n\n" c = True if c: QMessageBox.warning(None, "Erreur(s)", error_msg) else: options = { # Chemin d'accès au Modèle Numérique de Canopée (entrée) "Path_input": str(self.dlg.LE_input.text()), # Chemin d'accès au dossier de sortie "Path_output": str(self.dlg.LE_output.text()), # Hauteur de la fenêtre de lissage "WinRad": int(self.dlg.LE_gradConvDiameter.text()), # Hauteur minimale des arbres "MinHeightThres": int(self.dlg.LE_minHeightThres.text()), # Hauteur maximale des arbres "MaxHeightThres": int(self.dlg.LE_maxHeightThres.text()), # Degré de recouvrement pour la foret dense "forestRatio": float(self.dlg.LE_DRFD.text()), # Degré de recouvrement pour le paturage boise "woodenPastureRatio": float(self.dlg.LE_DRPB.text()), # largeur minimale forêt "WidthThres": int(self.dlg.LE_minWidthThres.text()), # surface minimum forêt "MinAreaThres": int(self.dlg.LE_minForSurfThres.text()), # surface minimum clairière "MaxAreaThres": int(self.dlg.LE_minClearingSurfThres.text()), # Périmètre max des triangles de Delaunay "MaxTrianglePerimeter": float(self.dlg.txt_triangle_peri.text()), # Calcul selon la convolution uniquement "onlyConvolution": self.dlg.chkConvolution.isChecked(), "AddLayer": self.dlg.CB_addLayer.isChecked(), "plugin": True } # Set default values of process bar self.dlg.progressBar.reset() self.dlg.progressBar.setMinimum(0) self.dlg.progressBar.setMaximum(1000) # Print progress on user window self.dlg.label_printActualProcess.setText("ForLim...") self.dlg.progressBar.setValue(0) QApplication.processEvents() now_time = datetime.now() name = "forLim_" + str(uuid4()) options["Path_output"] = \ os.path.join(options["Path_output"], name) os.mkdir(options["Path_output"]) # Get file list path_input = options["Path_input"] files = options["Path_input"].split(";") nfiles = len(files) options['src'] = str(options['Path_input']) options['dst'] = str(options['Path_output']) f = open(options['Path_output'] + '/forlim_medatata.txt', 'w') f.write(str(options)) f.close() i = 0 for f in enumerate(files): i += 1 self.dlg.label_printActualProcess \ .setText("Processing tile " + str(i) + "/" + str(len((files)))) options['Path_input'] = f[1] options['src'] = str(options['Path_input']) delaunayMethod.main(self, options, i) self.dlg.label_printActualProcess.setText(u'Calcul terminé') self.iface.mapCanvas().zoomToFullExtent()
def displayPixmapUpdated(self, FIELD, pixmap): TOMsMessageLog.logMessage("In utils::displayPixmapUpdated ... ", level=Qgis.Info) FIELD.setPixmap(pixmap) FIELD.setScaledContents(True) QApplication.processEvents() # processes the event queue - https://stackoverflow.com/questions/43094589/opencv-imshow-prevents-qt-python-crashing
def set_progress_text(self, text): """ Slot to update text during process """ self.label_progress.setText(text) QApplication.processEvents()
def run_query(self): """ Process for running the query """ # Block the button and save the initial text self.output_directory.setDisabled(True) self.pushButton_generateQuery.setDisabled(True) QApplication.setOverrideCursor(Qt.WaitCursor) self.start_process() QApplication.processEvents() # Get all values query = self.textEdit_query.toPlainText() output_directory = self.output_directory.filePath() prefix_file = self.lineEdit_filePrefix.text() nominatim = self.nominatim_value() # Set bbox bbox = None if self.cb_query_type.isEnabled(): query_type = self.cb_query_type.currentData() if query_type in ['layer', 'canvas']: nominatim = None bbox = self.get_bounding_box() # Check nominatim if nominatim == '': nominatim = None # Which geometry at the end ? output_geometry_types = self.get_output_geometry_types() white_list_values = self.get_white_list_values() try: # Test values if not output_geometry_types: raise OutPutGeomTypesException if output_directory and not isdir(output_directory): raise DirectoryOutPutException if not nominatim and \ re.search(r'\{\{nominatim\}\}', query) or \ re.search(r'\{\{nominatimArea:\}\}', query) or \ re.search(r'\{\{geocodeArea:\}\}', query): raise MissingParameterException(suffix="nominatim field") num_layers = process_query( dialog=self, query=query, output_dir=output_directory, prefix_file=prefix_file, output_geometry_types=output_geometry_types, white_list_values=white_list_values, nominatim=nominatim, bbox=bbox) if num_layers: display_message_bar(tr('Successful query'), level=Qgis.Success, duration=5) self.label_progress.setText(tr('Successful query')) else: display_message_bar(tr('Successful query, but no result.'), level=Qgis.Warning, duration=7) except QuickOsmException as e: self.display_geo_algorithm_exception(e) pass except Exception as e: # pylint: disable=broad-except self.display_exception(e) pass finally: # Resetting the button self.output_directory.setDisabled(False) self.pushButton_generateQuery.setDisabled(False) QApplication.restoreOverrideCursor() self.end_process() QApplication.processEvents()
def run(self): """Run method that performs all the real work""" layers = self.iface.mapCanvas().layers() layer_list = [] self.dlg.layerComboBox.clear() for layer in layers: layer_list.append(layer.name()) self.dlg.layerComboBox.addItems(layer_list) # TODO: Make the active layer the selected item in combo box aLayer = qgis.utils.iface.activeLayer() # TODO: Add signal to update toleranceSpinBox.suffix (Degrees) from layerComboBox.crs.mapUnits when layer is selected: #my_UnitType = { 0: 'Meters', 1: 'Feet', 2: 'Degrees', 7: 'NauticalMiles', 8: 'Kilometers', 9: 'Yards', 10: 'Miles', 3: 'UnknownUnit'} #suffix = my_UnitType[aLayer.crs().mapUnits()] # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: if self.checkNetworkXModule() < 0: return -4 import networkx as nx layerName = self.dlg.layerComboBox.currentText() try: aLayer = QgsProject.instance().mapLayersByName(layerName)[0] except: self.iface.messageBar().pushMessage("Error", "Failed to load layer!", level=Qgis.Critical) return -1 try: previousEditingMode = True if not aLayer.isEditable(): aLayer.startEditing() #self.iface.messageBar().pushMessage("Info", "Layer " + aLayer.name() + " needs to be in edit mode", level=Qgis.Info) #self.iface.messageBar().pushMessage("Error", "Layer " + aLayer.name() + " needs to be in edit mode", level=Qgis.Critical) #return -2 previousEditingMode = False attrIdx = self.getAttributeIndex(aLayer) if attrIdx < 0: return -3 progressMessageBar = self.iface.messageBar().createMessage("Creating network graph...") progress = QProgressBar() progress.setMaximum(aLayer.featureCount()) progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.iface.messageBar().pushWidget(progressMessageBar, Qgis.Info) G = nx.Graph() aLayer.beginEditCommand("Clear group attribute, create graph") # construct undirected graph tolerance = self.dlg.toleranceSpinBox.value() if tolerance == 0: tolerance = 0.000001 count = 0 for feat in aLayer.getFeatures(): count += 1 progress.setValue(count) done = aLayer.changeAttributeValue(feat.id(), attrIdx, -1) geom = feat.geometry() QgsGeometry.convertToSingleType(geom) # QGIS 3.x seems to load single LineString as MultiLineString?? line = geom.asPolyline() for i in range(len(line)-1): G.add_edges_from([((int(line[i][0]/tolerance), int(line[i][1]/tolerance)), (int(line[i+1][0]/tolerance), int(line[i+1][1]/tolerance)), {'fid': feat.id()})]) # first scale by tolerance, then convert to int. Before doing this, there were problems (in NetworkX v1) with floats not equating, thus creating disconnects that weren't there. if count % 100 == 0: QApplication.processEvents() # keep the UI responsive, every 100 features #TODO: check to see if Esc pressed aLayer.endEditCommand() self.iface.messageBar().pushMessage("Finding connected subgraphs, please wait...", level=Qgis.Warning) # WARNING - to highlight the next stage, where we cannot show progress QApplication.processEvents() connected_components = list(nx.connected_component_subgraphs(G)) # this takes a long time. TODO: how to show progress? self.iface.messageBar().pushMessage("Updating group attribute...", level=Qgis.Info) QApplication.processEvents() # gather edges and components to which they belong fid_comp = {} for i, graph in enumerate(connected_components): for edge in graph.edges(data=True): fid_comp[edge[2].get('fid', None)] = i # write output to csv file #with open('C:/Tmp/Components.csv', 'wb') as f: # w = csv.DictWriter(f, fieldnames=['fid', 'group']) # w.writeheader() # for (fid, group) in fid_comp.items(): # w.writerow({'fid': fid, 'group': group}) aLayer.beginEditCommand("Update group attribute") for (fid, group) in fid_comp.items(): done = aLayer.changeAttributeValue(fid, attrIdx, group) aLayer.endEditCommand() groups = list(set(fid_comp.values())) if self.dlg.stylingCheckBox.isChecked(): aLayer.beginEditCommand("Update layer styling") categories = [] firstCat = True for cat in groups: symbol = QgsSymbol.defaultSymbol(aLayer.geometryType()) symbol.setColor(QColor(randint(0,255), randint(0,255), randint(0,255))) if firstCat: firstCat = False else: symbol.setWidth(symbol.width()*5) category = QgsRendererCategory(cat, symbol, "%d" % cat) categories.append(category) field = self.dlg.attributeNameEditBox.text() renderer = QgsCategorizedSymbolRenderer(field, categories) aLayer.setRenderer(renderer) # if self.iface.mapCanvas().isCachingEnabled(): # aLayer.setCacheImage(None) # else: # self.iface.mapCanvas().refresh() aLayer.triggerRepaint() aLayer.endEditCommand() self.iface.messageBar().clearWidgets() self.iface.messageBar().pushMessage("Found main network and %d disconnected islands in layer %s" % (len(groups)-1, aLayer.name()), level=Qgis.Success) aLayer.commitChanges() # if not previousEditingMode: except Exception as e: self.iface.messageBar().pushMessage("Error", "Exception caught: %s. Please report an issue to the author of the plugin." % repr(e), level=Qgis.Critical)