def executeOtb(command, feedback, addToLog=True): loglines = [] with subprocess.Popen( [command], shell=True, stdout=subprocess.PIPE, stdin=subprocess.DEVNULL, stderr=subprocess.STDOUT, universal_newlines=True ) as proc: try: for line in iter(proc.stdout.readline, ''): line = line.strip() #'* ]' and ' ]' says its some progress update #print('line[-3:]',line[-3:]) if line[-3:] == "* ]" or line[-3:] == " ]": part = line.split(':')[1] percent = part.split('%')[0] try: if int(percent) >= 100: loglines.append(line) feedback.setProgress(int(percent)) except: pass else: loglines.append(line) except BaseException as e: loglines.append(str(e)) pass for logline in loglines: if feedback is None: QgsMessageLog.logMessage(logline, 'Processing', Qgis.Info) else: feedback.pushConsoleInfo(logline)
def executeSaga(feedback): if isWindows(): command = ['cmd.exe', '/C ', sagaBatchJobFilename()] else: os.chmod(sagaBatchJobFilename(), stat.S_IEXEC | stat.S_IREAD | stat.S_IWRITE) command = ["'" + sagaBatchJobFilename() + "'"] loglines = [] loglines.append(QCoreApplication.translate('SagaUtils', 'SAGA execution console output')) with subprocess.Popen( command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.DEVNULL, stderr=subprocess.STDOUT, universal_newlines=True, ) as proc: try: for line in iter(proc.stdout.readline, ''): if '%' in line: s = ''.join([x for x in line if x.isdigit()]) try: feedback.setProgress(int(s)) except: pass else: line = line.strip() if line != '/' and line != '-' and line != '\\' and line != '|': loglines.append(line) feedback.pushConsoleInfo(line) except: pass if ProcessingConfig.getSetting(SAGA_LOG_CONSOLE): QgsMessageLog.logMessage('\n'.join(loglines), 'Processing', Qgis.Info)
def postInputs(self): """ After layer imports, we need to update some internal parameters """ # If projection has not already be set, use the project self.setSessionProjectionFromProject() # Build GRASS region if self.region.isEmpty(): self.region = QgsProcessingUtils.combineLayerExtents(self.inputLayers) command = 'g.region n={} s={} e={} w={}'.format( self.region.yMaximum(), self.region.yMinimum(), self.region.xMaximum(), self.region.xMinimum() ) # Handle cell size if self.parameterDefinition(self.GRASS_REGION_CELLSIZE_PARAMETER): if self.cellSize: cellSize = self.cellSize else: cellSize = self.getDefaultCellSize() command += ' res={}'.format(cellSize) # Handle align to resolution if self.alignToResolution: command += ' -a' # Add the default parameters commands self.commands.append(command) QgsMessageLog.logMessage(self.tr('processInputs end. Commands: {}').format(self.commands), 'Grass7', Qgis.Info)
def __calculate_statistics(self, thema, subthema, layers): #features = processing.features(self.coverage_layer) features = self.coverage_layer.selectedFeatures() for gstk in features: try: gnr = gstk[self.settings.fld_gnr()] flaeche = gstk.geometry().area() gstk_stats = VRPStatistik(gnr, thema.name, flaeche, self.gem_name) #pyqtRemoveInputHook() #pdb.set_trace() #go thru all data sources of subthema for quelle in subthema.quellen: if VRP_DEBUG is True: QgsMessageLog.logMessage(u'quelle:{0}'.format(quelle.name), DLG_CAPTION) #only use those with statistik == True if quelle.statistik is False: continue lyr_curr_quelle = None for lyr in layers: if quelle.name == lyr.name(): lyr_curr_quelle = lyr if lyr_curr_quelle is None: continue text_flaeche = self.__get_text_flaeche(quelle, gstk, lyr_curr_quelle, quelle.attribut) sub_stat = VRPStatistikSubThema(quelle.name, text_flaeche) gstk_stats.add_subthema(thema.name, sub_stat) if gnr in self.statistics: self.statistics[gnr].append(gstk_stats) else: self.statistics[gnr] = [gstk_stats] except: msg = '__calculate_statistics:\n\n{0}'.format(traceback.format_exc()) QgsMessageLog.logMessage(msg, DLG_CAPTION, QgsMessageLog.CRITICAL) msg = msg.replace('\n', '') self.iface.messageBar().pushMessage(msg, QgsMessageBar.CRITICAL) return
def __init__(self, alg): super(HelpEditionDialog, self).__init__(None) self.setupUi(self) self.alg = alg self.descriptions = {} if isinstance(self.alg, QgsProcessingModelAlgorithm): self.descriptions = self.alg.helpContent() else: if self.alg.descriptionFile is not None: helpfile = alg.descriptionFile + '.help' if os.path.exists(helpfile): try: with open(helpfile) as f: self.descriptions = json.load(f) except Exception: QgsMessageLog.logMessage(self.tr('Cannot open help file: {0}').format(helpfile), self.tr('Processing'), Qgis.Warning) self.currentName = self.ALG_DESC if self.ALG_DESC in self.descriptions: self.text.setText(self.descriptions[self.ALG_DESC]) self.tree.itemClicked.connect(self.changeItem) self.fillTree() self.updateHtmlView()
def killWorker(self): """Kill the worker thread.""" if self.worker is not None: QgsMessageLog.logMessage(self.tr('Killing worker'), self.HISTOGRAM, QgsMessageLog.INFO) self.worker.kill()
def copy(self, destinationFolder): """ Copy inventoried files considering the dataset destinationFolder: copy destination folder """ for fileName in self.files: # adjusting the separators according to the OS fileName = fileName.replace('/', os.sep) file = fileName.split(os.sep)[-1] newFileName = os.path.join(destinationFolder, file) newFileName = newFileName.replace('/', os.sep) try: gdalSrc = gdal.Open(fileName) ogrSrc = ogr.Open(fileName) if ogrSrc: self.copyOGRDataSource(ogrSrc, newFileName) elif gdalSrc: self.copyGDALDataSource(gdalSrc, newFileName) except Exception as e: QgsMessageLog.logMessage(self.messenger.getCopyErrorMessage()+'\n'+':'.join(e.args), "DSG Tools Plugin", QgsMessageLog.INFO) return (0, self.messenger.getCopyErrorMessage()+'\n'+':'.join(e.args)) QgsMessageLog.logMessage(self.messenger.getSuccessInventoryAndCopyMessage(), "DSG Tools Plugin", QgsMessageLog.INFO) return (1, self.messenger.getSuccessInventoryAndCopyMessage())
def addToLog(msgtype, msg): try: # It seems that this fails sometimes depending on the msg # added. To avoid it stopping the normal functioning of the # algorithm, we catch all errors, assuming that is better # to miss some log info than breaking the algorithm. if msgtype == ProcessingLog.LOG_ALGORITHM: line = msgtype + '|' + datetime.datetime.now().strftime( ProcessingLog.DATE_FORMAT) + '|' \ + msg + '\n' with codecs.open(ProcessingLog.logFilename(), 'a', encoding='utf-8') as logfile: logfile.write(line) algname = msg[len('Processing.runalg("'):] algname = algname[:algname.index('"')] if algname not in ProcessingLog.recentAlgs: ProcessingLog.recentAlgs.append(algname) recentAlgsString = ';'.join(ProcessingLog.recentAlgs[-6:]) ProcessingConfig.setSettingValue( ProcessingConfig.RECENT_ALGORITHMS, recentAlgsString) else: if isinstance(msg, list): msg = '\n'.join([m for m in msg]) msgtypes = {ProcessingLog.LOG_ERROR: QgsMessageLog.CRITICAL, ProcessingLog.LOG_INFO: QgsMessageLog.INFO, ProcessingLog.LOG_WARNING: QgsMessageLog.WARNING, } QgsMessageLog.logMessage(msg, ProcessingLog.tr("Processing"), msgtypes[msgtype]) except: pass
def killWorker(self): """Kill the worker thread.""" if self.worker is not None: QgsMessageLog.logMessage(self.tr('Killing worker'), self.SDELLIPSE, Qgis.Info) self.worker.kill()
def startConnection(self): if self.storage_combo_box.currentIndex() == 0: bucket_name = 'oam-qgis-plugin-test' else: bucket_name = str(self.specify_edit.text()) if not bucket_name: self.bar2.clearWidgets() self.bar2.pushMessage( 'WARNING', 'The bucket for upload must be provided', level=QgsMessageBar.WARNING) bucket_key = str(self.key_id_edit.text()) bucket_secret = str(self.secret_key_edit.text()) self.bucket = None for trial in xrange(3): if self.bucket: break try: connection = S3Connection(bucket_key,bucket_secret) self.bucket = connection.get_bucket(bucket_name) QgsMessageLog.logMessage( 'Connection established' % trial, 'OAM', level=QgsMessageLog.INFO) except: if trial == 2: QgsMessageLog.logMessage( 'Failed to connect after 3 attempts', 'OAM', level=QgsMessageLog.CRITICAL) return self.bucket
def testBlocker(self): app_log = QgsApplication.messageLog() spy = QSignalSpy(app_log.messageReceived) spy_received = QSignalSpy(app_log.messageReceived[bool]) QgsMessageLog.logMessage('test', 'tag', Qgis.Warning, notifyUser=True) self.assertEqual(len(spy), 1) self.assertEqual(spy[-1], ['test', 'tag', Qgis.Warning]) self.assertEqual(len(spy_received), 1) # block notifications b = QgsMessageLogNotifyBlocker() QgsMessageLog.logMessage('test', 'tag', Qgis.Warning, notifyUser=True) self.assertEqual(len(spy), 2) # should not be blocked self.assertEqual(len(spy_received), 1) # should be blocked # another blocker b2 = QgsMessageLogNotifyBlocker() QgsMessageLog.logMessage('test', 'tag', Qgis.Warning, notifyUser=True) self.assertEqual(len(spy), 3) # should not be blocked self.assertEqual(len(spy_received), 1) # should be blocked del b # still blocked because of b2 QgsMessageLog.logMessage('test', 'tag', Qgis.Warning, notifyUser=True) self.assertEqual(len(spy), 4) # should not be blocked self.assertEqual(len(spy_received), 1) # should be blocked del b2 # not blocked QgsMessageLog.logMessage('test', 'tag', Qgis.Warning, notifyUser=True) self.assertEqual(len(spy), 5) # should not be blocked self.assertEqual(len(spy_received), 2) # should not be blocked
def run(self): if not os.path.isdir(self.dataDirectory): os.mkdir(self.dataDirectory) self.prepare() self.consolidateProject() layers = QgsProject.instance().mapLayers() total = 100.0 / len(layers) for count, layer in enumerate(layers.values()): QgsMessageLog.logMessage('Consolidating {layer}.'.format(layer=layer.name()), 'QConsolidate', Qgis.Info) if self.isCanceled(): break layerType = layer.type() if layerType == QgsMapLayer.VectorLayer: self.consolidateVectorLayer(layer) elif layerType == QgsMapLayer.RasterLayer: self.consolidateRasterLayer(layer) elif layerType == QgsMapLayer.PluginLayer: self.consolidatePluginLayer(layer) elif layerType == QgsMapLayer.MeshLayer: self.consolidateMeshLayer(layer) self.setProgress(int(count * total)) self.project.write(self.projectFile) return self.cleanup()
def validateFile(self,filename): # check that file exists if not os.path.exists(filename): self.bar0.clearWidgets() self.bar0.pushMessage( "CRITICAL", "The file %s does not exist" % filename, level=QgsMessageBar.CRITICAL) return False # check that file is an image if imghdr.what(filename) is None: self.bar0.clearWidgets() self.bar0.pushMessage( "CRITICAL", "The file %s is not a supported data source" % filename, level=QgsMessageBar.CRITICAL) return False # check if gdal can read file try: raster = gdal.Open(filename,gdal.GA_ReadOnly) except: self.bar0.clearWidgets() self.bar0.pushMessage( "CRITICAL", "GDAL could not read file %s" % filename, level=QgsMessageBar.CRITICAL) return False # check if there is an object raster if not raster: self.bar0.clearWidgets() self.bar0.pushMessage( "CRITICAL", "GDAL could not read file %s" % filename, level=QgsMessageBar.CRITICAL) return False # check that image has at least 3 bands if raster.RasterCount < 3: self.bar0.clearWidgets() self.bar0.pushMessage( "CRITICAL", "The file %s has less than 3 raster bands" % filename, level=QgsMessageBar.CRITICAL) return False # check if projection is set if raster.GetProjection() is '': self.bar0.clearWidgets() self.bar0.pushMessage( "CRITICAL", "Could not extract projection from file %s" % filename, level=QgsMessageBar.CRITICAL) return False # finally, check if bbox has valid data xy_points = [(0.0,0.0),(0.0,raster.RasterYSize),(raster.RasterXSize,0.0),(raster.RasterXSize,raster.RasterYSize)] for point in xy_points: if point != self.GDALInfoReportCorner(raster,point[0],point[1]): QgsMessageLog.logMessage( 'File %s is a valid data source' % filename, 'OAM', level=QgsMessageLog.INFO) return True
def _processGdalDatasource(self, layer, destDirectory): uri = layer.source() filePath = layer.source() newDirectory = destDirectory.replace(self.baseDirectory, '.') newSource = '{dirName}/{fileName}'.format(dirName=newDirectory, fileName=os.path.split(filePath)[1]) if uri.startswith(('/vsizip/', '/vsigzip/', '/vsitar/')): m = GDAL_VSI.search(uri) if m is not None: prefix = m.group(1) filePath = m.group(2) layerPath = m.group(4) newSource = '{vsi}{dirName}/{fileName}/{layer}'.format(vsi=prefix, dirName=newDirectory, fileName=os.path.split(filePath)[1], layer=layerPath) else: QgsMessageLog.logMessage(self.tr('Failed to parse URI: "{uri}"'.format(uri=uri)), 'QConsolidate', Qgis.Warning) return else: # ignore other virtual filesystems if uri.startswith('/vsi'): prefix = uri.slit('/')[0] QgsMessageLog.logMessage(self.tr('Not supported GDAL virtual filesystem layer "{layerType}"'.format(layerType=prefix)), 'QConsolidate', Qgis.Info) return # handle multiple layers in the single dataset if '|' in uri: filePath = uri.split('|')[0] layerPath = uri.split('|')[1] newSource = '{dirName}/{fileName}|{layer}'.format(dirName=newDirectory, fileName=os.path.split(filePath)[1], layer=layerPath) self._copyLayerFiles(filePath, destDirectory) self.updateLayerSource(layer.id(), newSource)
def processAlgorithm(self, parameters, context, feedback): layerA = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(Difference.INPUT), context) layerB = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(Difference.OVERLAY), context) geomType = QgsWkbTypes.multiType(layerA.wkbType()) writer = self.getOutputFromName( Difference.OUTPUT).getVectorWriter(layerA.fields(), geomType, layerA.crs(), context) outFeat = QgsFeature() index = QgsProcessingUtils.createSpatialIndex(layerB, context) selectionA = QgsProcessingUtils.getFeatures(layerA, context) total = 100.0 / layerA.featureCount() if layerA.featureCount() else 0 for current, inFeatA in enumerate(selectionA): geom = inFeatA.geometry() diff_geom = QgsGeometry(geom) attrs = inFeatA.attributes() intersections = index.intersects(geom.boundingBox()) request = QgsFeatureRequest().setFilterFids(intersections).setSubsetOfAttributes([]) for inFeatB in layerB.getFeatures(request): tmpGeom = inFeatB.geometry() if diff_geom.intersects(tmpGeom): diff_geom = QgsGeometry(diff_geom.difference(tmpGeom)) try: outFeat.setGeometry(diff_geom) outFeat.setAttributes(attrs) writer.addFeature(outFeat, QgsFeatureSink.FastInsert) except: QgsMessageLog.logMessage(self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'), self.tr('Processing'), QgsMessageLog.WARNING) continue feedback.setProgress(int(current * total)) del writer
def getAuxiliaryDataDirectories(): gdal_data_dir = None gtiff_csv_dir = None otb_folder = OtbUtils.otbFolder() if os.name == 'nt': gdal_data_dir = os.path.join(otb_folder, 'share', 'data') gtiff_csv_dir = os.path.join(otb_folder, 'share', 'epsg_csv') else: env_profile = os.path.join(otb_folder, 'otbenv.profile') try: if os.path.exists(env_profile): with open(env_profile) as f: lines = f.readlines() lines = [x.strip() for x in lines] for line in lines: if not line or line.startswith('#'): continue if 'GDAL_DATA=' in line: gdal_data_dir = line.split("GDAL_DATA=")[1] if 'GEOTIFF_CSV='in line: gtiff_csv_dir = line.split("GEOTIFF_CSV=")[1] except BaseException as exc: errmsg = "Cannot find gdal and geotiff data directory." + str(exc) QgsMessageLog.logMessage(errmsg, OtbUtils.tr('Processing'), Qgis.Info) pass return gdal_data_dir, gtiff_csv_dir
def search(url, callback): QgsMessageLog.logMessage("URL:" + url, "Gazetteer") def requestFinished(reply): # Disconnect from the signal networkAccessManager = QgsNetworkAccessManager.instance() networkAccessManager.finished.disconnect(requestFinished) # Handle the reply if reply.error() != QNetworkReply.NoError: QgsMessageLog.logMessage("Network error #{0}: {1}".format(reply.error(), reply.errorString()), "Gazetteer") callback(u'') else: charset = 'UTF-8' try: _, params = cgi.parse_header(reply.header(QNetworkRequest.ContentTypeHeader)) charset = params['charset'] except: pass QgsMessageLog.logMessage("charset: " + charset, "Gazetteer") data = unicode(reply.readAll(), charset) reply.deleteLater() callback(data) networkAccessManager = QgsNetworkAccessManager.instance() networkAccessManager.finished.connect(requestFinished) networkAccessManager.get(QNetworkRequest(QUrl(QUrl.fromPercentEncoding(url))))
def _fill_data_sources_list(self): self.data_sources = {} for ds_path in self.ds_paths: for root, dirs, files in os.walk(ds_path): for ini_file in [f for f in files if f.endswith('.ini')]: try: ini_full_path = os.path.join(root, ini_file) ds = DataSourceSerializer.read_from_ini(ini_full_path) # set contrib&user if ds_path in ROOT_MAPPING.keys(): ds.category = ROOT_MAPPING[ds_path] else: ds.category = DataSourceCategory.USER # action ds.action = QAction(QIcon(ds.icon_path), self.tr(ds.alias), None) ds.action.setData(ds) # append to array self.data_sources[ds.id] = ds except Exception, e: error_message = 'INI file can\'t be parsed: ' + e.message QgsMessageLog.logMessage(error_message, level=QgsMessageLog.CRITICAL)
def make_paging_query(self, url, json_export): """ Runs an item query and returns the results :param url: The url to query :param json_export: True if exporting; False if rendering :return: A list of items if successful; None if not """ response = None headers = self.get_headers().copy() headers[HEADER_CONTENT_TYPE] = CONTENT_TYPE_JSON for i in range(0, NUM_TIMES_TO_TRY): try: request = urllib2.Request(url=url, headers=headers) response = self.get_opener().open(request, timeout=TIMEOUT_IN_SECONDS) self.is_login_successful = True except Exception, e: self.is_login_successful = False QgsMessageLog.instance().logMessage("Unable to run get on url: " + url + " due to: " + str(e) + "; trying " + str(NUM_TIMES_TO_TRY - i - 1) + " times", TAG_NAME, level=QgsMessageLog.CRITICAL) if response and self.is_login_successful: paging_id = self.process_paging_request(response.read()) if paging_id: return self.query_for_pages(paging_id, json_export) return None
def return_batch_route(self, features): """Save and/or display the routes retrieved""" osrm_batch_route_layer = QgsVectorLayer( "Linestring?crs=epsg:4326&field=id:integer" "&field=total_time:integer(20)&field=distance:integer(20)", "routes_osrm{}".format(self.nb_done), "memory") provider = osrm_batch_route_layer.dataProvider() provider.addFeatures(features) QgsMapLayerRegistry.instance().addMapLayer(osrm_batch_route_layer) if self.filename: error = QgsVectorFileWriter.writeAsVectorFormat( osrm_batch_route_layer, self.filename, self.encoding, None, "ESRI Shapefile") if error != QgsVectorFileWriter.NoError: self.iface.messageBar().pushMessage( "Error", "Can't save the result into {} - Output have been " "added to the canvas (see QGis log for error trace" "back)".format(self.filename), duration=10) QgsMessageLog.logMessage( 'OSRM-plugin error report :\n {}'.format(error), level=QgsMessageLog.WARNING) self.iface.setActiveLayer(osrm_batch_route_layer) return -1 else: QtGui.QMessageBox.information( self.iface.mainWindow(), 'Info', "Result saved in {}".format(self.filename)) if self.check_add_layer.isChecked(): self.iface.setActiveLayer(osrm_batch_route_layer) else: QgsMapLayerRegistry.instance().removeMapLayer( osrm_batch_route_layer.id()) self.iface.messageBar().clearWidgets()
def readXml(self, node): # early read of custom properties self.readCustomProperties(node) # get layer type ol_layer_type = None ol_layer_type_name = self.customProperty( OpenlayersLayer.LAYER_PROPERTY, "") if ol_layer_type_name != "": ol_layer_type = self.olLayerTypeRegistry.getByName( ol_layer_type_name) else: # handle ol_layer_type idx stored in layer node # (OL plugin <= 1.1.2) ol_layer_type_idx = int(node.toElement().attribute( "ol_layer_type", "-1")) if ol_layer_type_idx != -1: ol_layer_type = self.olLayerTypeRegistry.getById( ol_layer_type_idx) if ol_layer_type is not None: self.setLayerType(ol_layer_type) else: # Set default layer type self.setLayerType( self.olLayerTypeRegistry.getByName("OpenStreetMap")) msg = "Obsolete or unknown layer type '%s', using OpenStreetMap\ instead" % ol_layer_type_name self.iface.messageBar().pushMessage("OpenLayers Plugin", msg, level=Qgis.MessageLevel(1)) QgsMessageLog.logMessage(msg, "OpenLayers Plugin", QgsMessageLog.WARNING) return True
def install(self): """Install the processing scripts in the collection. We copy the processing scripts exist in the processing dir to the user's processing scripts directory and refresh the provider. """ # Check if the dir exists, pass installing silently if it doesn't exist if not os.path.exists(self.resource_dir): return # Get all the script files under self.resource_dir processing_files = [] for item in os.listdir(self.resource_dir): file_path = os.path.join(self.resource_dir, item) if fnmatch.fnmatch(file_path, '*.py'): processing_files.append(file_path) valid = 0 for processing_file in processing_files: # Install silently the processing file try: shutil.copy(processing_file, self.scripts_folder()) valid += 1 except OSError as e: QgsMessageLog.logMessage("Could not copy script '{}'\n{}".format(processing_file, str(e)), "Processing", Qgis.Warning) if valid > 0: self.refresh_script_provider()
def loadLessonsFromPaths(paths): hasErrors = False for path in paths: for folder in os.listdir(path): if os.path.isdir(os.path.join(path, folder)): groupFiles = [os.path.join(path, folder, f) for f in ["group.html", "group.md"]] for groupFile in groupFiles: if os.path.exists(groupFile): groups[folder.replace("_", " ")] = groupFile break for subfolder in os.listdir(os.path.join(path, folder)): if os.path.isdir(os.path.join(path, folder, subfolder)): try: f = os.path.join(path, folder, subfolder, "__init__.py") if os.path.exists(f): m = imp.load_source("{}.{}".format(folder, subfolder), f) addLessonModule(m) except Exception as e: QgsMessageLog.logMessage("Can not load lesson from {}:\n{}".format(f, str(e)), "Lessons") hasErrors = True if isYamlLessonFolder(os.path.join(path, folder), subfolder): lesson = lessonFromYamlFile(os.path.join(path, folder, subfolder, "lesson.yaml")) if lesson: _addLesson(lesson) else: hasErrors = True return hasErrors
def showWarning(self, text): """Show a warning.""" self.iface.messageBar().pushMessage(self.tr('Warning'), text, level=QgsMessageBar.WARNING, duration=2) QgsMessageLog.logMessage('Warning: ' + text, self.THINGREYSCALE, QgsMessageLog.WARNING)
def showInfo(self, text): """Show info.""" self.iface.messageBar().pushMessage(self.tr('Info'), text, level=Qgis.Info, duration=2) QgsMessageLog.logMessage('Info: ' + text, self.THINGREYSCALE, Qgis.Info)
def do_aoi_search(self, order_params, csv_element): """ Performs an AOI search for strips in GBD and generates stats from them :param order_params: The order params for the GBD query :param csv_element: The entry in the CSV row to update :return: """ data = { KEY_DATA_SEARCH_AREA_WKT: order_params.polygon, KEY_DATA_START_DATE: order_params.time_begin.isoformat() + "Z", KEY_DATA_END_DATE: order_params.time_end.isoformat() + "Z", KEY_DATA_FILTERS: VALUE_DATA_FILTERS, KEY_DATA_TAG_RESULTS: VALUE_DATA_TAG_RESULTS, KEY_DATA_TYPES: VALUE_DATA_TYPES, } json_data = json.dumps(data) headers = self.headers.copy() headers[HEADER_CONTENT_TYPE] = CONTENT_TYPE_JSON try: request = urllib2.Request(GBD_SEARCH_AOI_AND_TIME_URL, json_data, headers) response = self.opener.open(request) response_data = response.read() result_data = json.loads(response_data, strict=False) self.update_csv_data(order_params.time_end, result_data, csv_element) except Exception, e: QgsMessageLog.instance().logMessage( "Exception detected during aoi search: " + str(e), TAG_NAME, level=QgsMessageLog.CRITICAL )
def showError(self, text): """Show an error.""" self.iface.messageBar().pushMessage(self.tr('Error'), text, level=QgsMessageBar.CRITICAL, duration=3) QgsMessageLog.logMessage('Error: ' + text, self.THINGREYSCALE, QgsMessageLog.CRITICAL)
def unserialize(self, st): style = None orig_geom = None geom = None try: t = pickle.loads(st) except Exception as e: try: t = pickle.loads(st, encoding='utf-8') # strange, Exception says : No module named 'PyQt4' except Exception as e: for m in e.args: QgsMessageLog.logMessage(str(m), 'Extensions') raise Exception("Mask - Error when loading mask") if len(t) == 12: # older version (self.do_buffer, self.buffer_units, self.buffer_segments, self.do_simplify, self.simplify_tolerance, self.do_save_as, self.file_path, self.file_format, self.limited_layers_obsolete, style, self.polygon_mask_method, self.line_mask_method) = t else: (self.do_buffer, self.buffer_units, self.buffer_segments, self.do_simplify, self.simplify_tolerance, self.do_save_as, self.file_path, self.file_format, self.limited_layers_obsolete, style, self.polygon_mask_method, self.line_mask_method, orig_geom, geom ) = t self.style = None self.geometry = None if style is not None: self.style = style if geom is not None: self.geometry = QgsGeometry() self.geometry.fromWkb(geom) if orig_geom is not None: gl = [] for g in orig_geom: geo = QgsGeometry() geo.fromWkb(g) gl.append(geo) self.orig_geometry = gl
def acquisition_search(self, order_params): """ Performs a search for acquisitions. :param order_params: The order params for the GBD query :return: """ self.log_in() # build request body json request_body = { KEY_DATA_SEARCH_AREA_WKT: order_params.polygon, KEY_DATA_FILTERS: order_params.filters, KEY_DATA_TAG_RESULTS: VALUE_DATA_TAG_RESULTS, KEY_DATA_TYPES: VALUE_DATA_TYPES } if order_params.time_begin: request_body[KEY_DATA_START_DATE] = order_params.time_begin if order_params.time_end: request_body[KEY_DATA_END_DATE] = order_params.time_end request_body_json = json.dumps(request_body) # build header headers = self.headers.copy() headers[HEADER_CONTENT_TYPE] = CONTENT_TYPE_JSON try: request = urllib2.Request(ACQUISITION_SEARCH_URL, request_body_json, headers) response = self.opener.open(request) response_data = response.read() result_data = json.loads(response_data, strict=False) return result_data except Exception, e: QgsMessageLog.instance().logMessage("Exception during acquisition search: " + str(e), TAG_NAME, level=QgsMessageLog.CRITICAL)
def accept(self): """Creates and loads the WMS layer.""" self.close() currentIndex = self.comboBoxLayer.currentIndex() currentLayerId, unused_dataType = self.comboBoxLayer.itemData(currentIndex) currentLayerName = unicode(self.comboBoxLayer.currentText()) mapId = self.labelMapId.text() # Create the WMS layer token = oauth2_utils.getToken() url = 'https://mapsengine.google.com/%s-4/wms/%s/' wmsUrl = url % (mapId, token.access_token) currentFormatIndex = self.comboBoxFormat.currentIndex() imageFormat = unicode(self.comboBoxFormat.itemData(currentFormatIndex)) crs = self.comboBoxCrs.currentText() uri = QgsDataSourceURI() uri.setParam('url', wmsUrl) uri.setParam('layers', currentLayerId) uri.setParam('format', imageFormat) uri.setParam('crs', crs) uri.setParam('styles', '') rlayer = QgsRasterLayer(str(uri.encodedUri()), currentLayerName, 'wms') if rlayer.isValid(): QgsMapLayerRegistry.instance().addMapLayer(rlayer) else: logText = 'Failed to add WMS layer %s with URI %s' % ( currentLayerName, str(uri.encodedUri())) warnText = 'Failed to add WMS layer %s' % currentLayerName QgsMessageLog.logMessage(logText, 'GMEConnector', QgsMessageLog.CRITICAL) self.iface.messageBar().pushMessage( 'Google Maps Engine Connector', warnText, level=QgsMessageBar.CRITICAL, duration=3)
def _log(*args, **kw): """ Log messages to the QgsMessageLog viewer """ QgsMessageLog.logMessage(" ".join(map(str, args)), "Factory")
def processAlgorithm(self, parameters, context, feedback): if isWindows(): path = Grass7Utils.grassPath() if path == '': raise QgsProcessingException( self.tr( 'GRASS GIS 7 folder is not configured. Please ' 'configure it before running GRASS GIS 7 algorithms.')) # Create brand new commands lists self.commands = [] self.outputCommands = [] self.exportedLayers = {} # If GRASS session has been created outside of this algorithm then # get the list of layers loaded in GRASS otherwise start a new # session existingSession = Grass7Utils.sessionRunning if existingSession: self.exportedLayers = Grass7Utils.getSessionLayers() else: Grass7Utils.startGrassSession() # Handle default GRASS parameters self.grabDefaultGrassParameters(parameters, context) # Handle ext functions for inputs/command/outputs for fName in ['Inputs', 'Command', 'Outputs']: fullName = 'process{}'.format(fName) if self.module and hasattr(self.module, fullName): getattr(self.module, fullName)(self, parameters, context, feedback) else: getattr(self, fullName)(parameters, context, feedback) # Run GRASS loglines = [] loglines.append(self.tr('GRASS GIS 7 execution commands')) for line in self.commands: feedback.pushCommandInfo(line) loglines.append(line) if ProcessingConfig.getSetting(Grass7Utils.GRASS_LOG_COMMANDS): QgsMessageLog.logMessage("\n".join(loglines), self.tr('Processing'), Qgis.Info) Grass7Utils.executeGrass(self.commands, feedback, self.outputCommands) # If the session has been created outside of this algorithm, add # the new GRASS GIS 7 layers to it otherwise finish the session if existingSession: Grass7Utils.addSessionLayers(self.exportedLayers) else: Grass7Utils.endGrassSession() # Return outputs map outputs = {} for out in self.outputDefinitions(): outName = out.name() if outName in parameters: outputs[outName] = parameters[outName] if isinstance(out, QgsProcessingOutputHtml): self.convertToHtml(parameters[outName]) return outputs
def defineCharacteristicsFromFile(self): """ Create algorithm parameters and outputs from a text file. """ with open(self.descriptionFile) as lines: # First line of the file is the Grass algorithm name line = lines.readline().strip('\n').strip() self.grass7Name = line # Second line if the algorithm name in Processing line = lines.readline().strip('\n').strip() self._name = line self._display_name = QCoreApplication.translate( "GrassAlgorithm", line) if " - " not in self._name: self._name = self.grass7Name + " - " + self._name self._display_name = self.grass7Name + " - " + self._display_name self._name = self._name[:self._name.find(' ')].lower() # Read the grass group line = lines.readline().strip('\n').strip() self._group = QCoreApplication.translate("GrassAlgorithm", line) self._groupId = self.groupIdRegex.search(line).group(0).lower() hasRasterOutput = False hasRasterInput = False hasVectorInput = False vectorOutputs = False # Then you have parameters/output definition line = lines.readline().strip('\n').strip() while line != '': try: line = line.strip('\n').strip() if line.startswith('Hardcoded'): self.hardcodedStrings.append(line[len('Hardcoded|'):]) parameter = getParameterFromString(line) if parameter is not None: self.params.append(parameter) if isinstance(parameter, (QgsProcessingParameterVectorLayer, QgsProcessingParameterFeatureSource)): hasVectorInput = True elif isinstance(parameter, QgsProcessingParameterRasterLayer): hasRasterInput = True elif isinstance(parameter, QgsProcessingParameterMultipleLayers): if parameter.layerType( ) < 3 or parameter.layerType() == 5: hasVectorInput = True elif parameter.layerType() == 3: hasRasterInput = True elif isinstance( parameter, QgsProcessingParameterVectorDestination): vectorOutputs = True elif isinstance( parameter, QgsProcessingParameterRasterDestination): hasRasterOutput = True line = lines.readline().strip('\n').strip() except Exception as e: QgsMessageLog.logMessage( self.tr( 'Could not open GRASS GIS 7 algorithm: {0}\n{1}'). format(self.descriptionFile, line), self.tr('Processing'), Qgis.Critical) raise e param = QgsProcessingParameterExtent( self.GRASS_REGION_EXTENT_PARAMETER, self.tr('GRASS GIS 7 region extent'), optional=True) param.setFlags(param.flags() | QgsProcessingParameterDefinition.FlagAdvanced) self.params.append(param) if hasRasterOutput or hasRasterInput: # Add a cellsize parameter param = QgsProcessingParameterNumber( self.GRASS_REGION_CELLSIZE_PARAMETER, self.tr('GRASS GIS 7 region cellsize (leave 0 for default)'), type=QgsProcessingParameterNumber.Double, minValue=0.0, maxValue=sys.float_info.max + 1, defaultValue=0.0) param.setFlags(param.flags() | QgsProcessingParameterDefinition.FlagAdvanced) self.params.append(param) if hasRasterOutput: # Add a createopt parameter for format export param = QgsProcessingParameterString( self.GRASS_RASTER_FORMAT_OPT, self.tr('Output Rasters format options (createopt)'), multiLine=True, optional=True) param.setFlags(param.flags() | QgsProcessingParameterDefinition.FlagAdvanced) self.params.append(param) # Add a metadata parameter for format export param = QgsProcessingParameterString( self.GRASS_RASTER_FORMAT_META, self.tr('Output Rasters format metadata options (metaopt)'), multiLine=True, optional=True) param.setFlags(param.flags() | QgsProcessingParameterDefinition.FlagAdvanced) self.params.append(param) if hasVectorInput: param = QgsProcessingParameterNumber( self.GRASS_SNAP_TOLERANCE_PARAMETER, self.tr('v.in.ogr snap tolerance (-1 = no snap)'), type=QgsProcessingParameterNumber.Double, minValue=-1.0, maxValue=sys.float_info.max + 1, defaultValue=-1.0) param.setFlags(param.flags() | QgsProcessingParameterDefinition.FlagAdvanced) self.params.append(param) param = QgsProcessingParameterNumber( self.GRASS_MIN_AREA_PARAMETER, self.tr('v.in.ogr min area'), type=QgsProcessingParameterNumber.Double, minValue=0.0, maxValue=sys.float_info.max + 1, defaultValue=0.0001) param.setFlags(param.flags() | QgsProcessingParameterDefinition.FlagAdvanced) self.params.append(param) if vectorOutputs: param = QgsProcessingParameterEnum( self.GRASS_OUTPUT_TYPE_PARAMETER, self.tr('v.out.ogr output type'), self.OUTPUT_TYPES) param.setFlags(param.flags() | QgsProcessingParameterDefinition.FlagAdvanced) self.params.append(param)
def runGdal(commands, feedback=None): if feedback is None: feedback = QgsProcessingFeedback() envval = os.getenv('PATH') # We need to give some extra hints to get things picked up on OS X isDarwin = False try: isDarwin = platform.system() == 'Darwin' except IOError: # https://travis-ci.org/m-kuhn/QGIS#L1493-L1526 pass if isDarwin and os.path.isfile( os.path.join(QgsApplication.prefixPath(), "bin", "gdalinfo")): # Looks like there's a bundled gdal. Let's use it. os.environ['PATH'] = "{}{}{}".format( os.path.join(QgsApplication.prefixPath(), "bin"), os.pathsep, envval) os.environ['DYLD_LIBRARY_PATH'] = os.path.join( QgsApplication.prefixPath(), "lib") else: # Other platforms should use default gdal finder codepath settings = QgsSettings() path = settings.value('/GdalTools/gdalPath', '') if not path.lower() in envval.lower().split(os.pathsep): envval += '{}{}'.format(os.pathsep, path) os.putenv('PATH', envval) fused_command = ' '.join([str(c) for c in commands]) QgsMessageLog.logMessage(fused_command, 'Processing', Qgis.Info) feedback.pushInfo('GDAL command:') feedback.pushCommandInfo(fused_command) feedback.pushInfo('GDAL command output:') success = False retry_count = 0 while not success: loglines = [] loglines.append('GDAL execution console output') try: with subprocess.Popen( fused_command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.DEVNULL, stderr=subprocess.STDOUT, universal_newlines=True, ) as proc: for line in proc.stdout: feedback.pushConsoleInfo(line) loglines.append(line) success = True except IOError as e: if retry_count < 5: retry_count += 1 else: raise IOError( str(e) + u'\nTried 5 times without success. Last iteration stopped after reading {} line(s).\nLast line(s):\n{}' .format(len(loglines), u'\n'.join(loglines[-10:]))) QgsMessageLog.logMessage('\n'.join(loglines), 'Processing', Qgis.Info) GdalUtils.consoleOutput = loglines
def processAlgorithm(self, parameters, context, feedback): inLayer = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.INPUT), context) boundary = self.getParameterValue(self.MODE) == self.MODE_BOUNDARY smallestArea = self.getParameterValue( self.MODE) == self.MODE_SMALLEST_AREA if inLayer.selectedFeatureCount() == 0: QgsMessageLog.logMessage( self.tr('{0}: (No selection in input layer "{1}")').format( self.displayName(), self.getParameterValue(self.INPUT)), self.tr('Processing'), QgsMessageLog.WARNING) featToEliminate = [] selFeatIds = inLayer.selectedFeatureIds() output = self.getOutputFromName(self.OUTPUT) writer = output.getVectorWriter(inLayer.fields(), inLayer.wkbType(), inLayer.crs(), context) for aFeat in inLayer.getFeatures(): if aFeat.id() in selFeatIds: # Keep references to the features to eliminate featToEliminate.append(aFeat) else: # write the others to output writer.addFeature(aFeat, QgsFeatureSink.FastInsert) # Delete all features to eliminate in processLayer processLayer = output.layer processLayer.startEditing() # ANALYZE if len(featToEliminate) > 0: # Prevent zero division start = 20.00 add = 80.00 / len(featToEliminate) else: start = 100 feedback.setProgress(start) madeProgress = True # We go through the list and see if we find any polygons we can # merge the selected with. If we have no success with some we # merge and then restart the whole story. while madeProgress: # Check if we made any progress madeProgress = False featNotEliminated = [] # Iterate over the polygons to eliminate for i in range(len(featToEliminate)): feat = featToEliminate.pop() geom2Eliminate = feat.geometry() bbox = geom2Eliminate.boundingBox() fit = processLayer.getFeatures( QgsFeatureRequest().setFilterRect( bbox).setSubsetOfAttributes([])) mergeWithFid = None mergeWithGeom = None max = 0 min = -1 selFeat = QgsFeature() # use prepared geometries for faster intersection tests engine = QgsGeometry.createGeometryEngine( geom2Eliminate.geometry()) engine.prepareGeometry() while fit.nextFeature(selFeat): selGeom = selFeat.geometry() if engine.intersects(selGeom.geometry()): # We have a candidate iGeom = geom2Eliminate.intersection(selGeom) if not iGeom: continue if boundary: selValue = iGeom.length() else: # area. We need a common boundary in # order to merge if 0 < iGeom.length(): selValue = selGeom.area() else: selValue = -1 if -1 != selValue: useThis = True if smallestArea: if -1 == min: min = selValue else: if selValue < min: min = selValue else: useThis = False else: if selValue > max: max = selValue else: useThis = False if useThis: mergeWithFid = selFeat.id() mergeWithGeom = QgsGeometry(selGeom) # End while fit if mergeWithFid is not None: # A successful candidate newGeom = mergeWithGeom.combine(geom2Eliminate) if processLayer.changeGeometry(mergeWithFid, newGeom): madeProgress = True else: raise GeoAlgorithmExecutionException( self. tr('Could not replace geometry of feature with id {0}' ).format(mergeWithFid)) start = start + add feedback.setProgress(start) else: featNotEliminated.append(feat) # End for featToEliminate featToEliminate = featNotEliminated # End while if not processLayer.commitChanges(): raise GeoAlgorithmExecutionException( self.tr('Could not commit changes')) for feature in featNotEliminated: writer.addFeature(feature, QgsFeatureSink.FastInsert)
def runAlgorithm(algOrName, onFinish, *args, **kwargs): if isinstance(algOrName, GeoAlgorithm): alg = algOrName else: alg = QgsApplication.processingRegistry().algorithmById(algOrName) if alg is None: # fix_print_with_import print('Error: Algorithm not found\n') QgsMessageLog.logMessage( Processing.tr('Error: Algorithm {0} not found\n').format( algOrName), Processing.tr("Processing")) return alg = alg.getCopy() if len(args) == 1 and isinstance(args[0], dict): # Set params by name and try to run the alg even if not all parameter values are provided, # by using the default values instead. setParams = [] for (name, value) in list(args[0].items()): param = alg.getParameterFromName(name) if param and param.setValue(value): setParams.append(name) continue output = alg.getOutputFromName(name) if output and output.setValue(value): continue # fix_print_with_import print('Error: Wrong parameter value %s for parameter %s.' % (value, name)) QgsMessageLog.logMessage( Processing.tr( 'Error: Wrong parameter value {0} for parameter {1}.'). format(value, name), Processing.tr("Processing")) ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, Processing. tr('Error in {0}. Wrong parameter value {1} for parameter {2}.' ).format(alg.name(), value, name)) return # fill any missing parameters with default values if allowed for param in alg.parameters: if param.name not in setParams: if not param.setDefaultValue(): # fix_print_with_import print( 'Error: Missing parameter value for parameter %s.' % param.name) QgsMessageLog.logMessage( Processing. tr('Error: Missing parameter value for parameter {0}.' ).format(param.name), Processing.tr("Processing")) ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, Processing. tr('Error in {0}. Missing parameter value for parameter {1}.' ).format(alg.name(), param.name)) return else: if len(args) != alg.getVisibleParametersCount( ) + alg.getVisibleOutputsCount(): # fix_print_with_import print('Error: Wrong number of parameters') QgsMessageLog.logMessage( Processing.tr('Error: Wrong number of parameters'), Processing.tr("Processing")) processing.algorithmHelp(algOrName) return i = 0 for param in alg.parameters: if not param.hidden: if not param.setValue(args[i]): # fix_print_with_import print('Error: Wrong parameter value: ' + str(args[i])) QgsMessageLog.logMessage( Processing.tr('Error: Wrong parameter value: ') + str(args[i]), Processing.tr("Processing")) return i = i + 1 for output in alg.outputs: if not output.hidden: if not output.setValue(args[i]): # fix_print_with_import print('Error: Wrong output value: ' + str(args[i])) QgsMessageLog.logMessage( Processing.tr('Error: Wrong output value: ') + str(args[i]), Processing.tr("Processing")) return i = i + 1 msg = alg._checkParameterValuesBeforeExecuting() if msg: # fix_print_with_import print('Unable to execute algorithm\n' + str(msg)) QgsMessageLog.logMessage( Processing.tr('Unable to execute algorithm\n{0}').format(msg), Processing.tr("Processing")) return if not alg.checkInputCRS(): print('Warning: Not all input layers use the same CRS.\n' + 'This can cause unexpected results.') QgsMessageLog.logMessage( Processing. tr('Warning: Not all input layers use the same CRS.\nThis can cause unexpected results.' ), Processing.tr("Processing")) # Don't set the wait cursor twice, because then when you # restore it, it will still be a wait cursor. overrideCursor = False if iface is not None: cursor = QApplication.overrideCursor() if cursor is None or cursor == 0: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) overrideCursor = True elif cursor.shape() != Qt.WaitCursor: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) overrideCursor = True feedback = None if kwargs is not None and "feedback" in list(kwargs.keys()): feedback = kwargs["feedback"] elif iface is not None: feedback = MessageBarProgress(alg.displayName()) ret = execute(alg, feedback) if ret: if onFinish is not None: onFinish(alg, feedback) else: QgsMessageLog.logMessage( Processing.tr("There were errors executing the algorithm."), Processing.tr("Processing")) if overrideCursor: QApplication.restoreOverrideCursor() if isinstance(feedback, MessageBarProgress): feedback.close() return alg
def info(self, msg=""): QgsMessageLog.logMessage('{} {}'.format(self.__class__.__name__, msg), 'PDOKLocatieserverLocatorFilter', Qgis.Info)
def msg_log(self, msg): if self.debug: QgsMessageLog.logMessage(msg, "NetworkAccessManager")
def loadAlgorithms(self): if not self.canBeActivated(): return version_file = os.path.join(OtbUtils.otbFolder(), 'share', 'doc', 'otb', 'VERSION') if not os.path.isfile(version_file): version_file = os.path.join(OtbUtils.otbFolder(), 'VERSION') if os.path.isfile(version_file): with open(version_file) as vf: vlines = vf.readlines() vlines = [l.strip() for l in vlines] vline = vlines[0] if 'OTB Version:' in vline: self.version = vline.split(':')[1].strip() QgsMessageLog.logMessage(self.tr("Loading OTB '{}'.".format(self.version)), self.tr('Processing'), Qgis.Info) self.algs = self.createAlgsList() for a in self.algs: self.addAlgorithm(a) self.algs = [] otb_folder = self.normalize_path(OtbUtils.otbFolder()) otb_app_path_env = os.pathsep.join(self.appDirs(OtbUtils.appFolder())) gdal_data_dir = None geotiff_csv_dir = None otbcli_path = OtbUtils.cliPath() try: if os.name == 'nt': app_vargs = " %*" export_cmd = 'SET ' first_line = ':: Setup environment for OTB package. Generated by QGIS plugin' otb_app_launcher = os.path.join(otb_folder, 'bin', 'otbApplicationLauncherCommandLine.exe') gdal_data_dir = os.path.join(otb_folder, 'share', 'data') geotiff_csv_dir = os.path.join(otb_folder, 'share', 'epsg_csv') else: app_vargs = " \"$@\"" export_cmd = 'export ' first_line = '#!/bin/sh' otb_app_launcher = os.path.join(otb_folder, 'bin', 'otbApplicationLauncherCommandLine') lines = None env_profile = os.path.join(otb_folder, 'otbenv.profile') if os.path.exists(env_profile): with open(env_profile) as f: lines = f.readlines() lines = [x.strip() for x in lines] for line in lines: if not line or line.startswith('#'): continue if 'GDAL_DATA=' in line: gdal_data_dir = line.split("GDAL_DATA=")[1] if 'GEOTIFF_CSV='in line: geotiff_csv_dir = line.split("GEOTIFF_CSV=")[1] with open(otbcli_path, 'w') as otb_cli_file: otb_cli_file.write(first_line + os.linesep) otb_cli_file.write(export_cmd + "LC_NUMERIC=C" + os.linesep) otb_cli_file.write(export_cmd + "GDAL_DRIVER_PATH=disable" + os.linesep) if gdal_data_dir: otb_cli_file.write(export_cmd + "GDAL_DATA=" + "\"" + gdal_data_dir + "\"" + os.linesep) if geotiff_csv_dir: otb_cli_file.write(export_cmd + "GEOTIFF_CSV=" + "\"" + geotiff_csv_dir + "\"" + os.linesep) if OtbUtils.loggerLevel(): otb_cli_file.write(export_cmd + "OTB_LOGGER_LEVEL=" + OtbUtils.loggerLevel() + os.linesep) max_ram_hint = OtbUtils.maxRAMHint() if max_ram_hint and not int(max_ram_hint) == 128: otb_cli_file.write(export_cmd + "OTB_MAX_RAM_HINT=" + max_ram_hint + os.linesep) otb_cli_file.write(export_cmd + "OTB_APPLICATION_PATH=" + "\"" + otb_app_path_env + "\"" + os.linesep) otb_cli_file.write("\"" + otb_app_launcher + "\"" + app_vargs + os.linesep) if not os.name == 'nt': os.chmod(otbcli_path, 0o744) except BaseException as e: import traceback os.remove(otbcli_path) errmsg = "Cannot write:" + otbcli_path + "\nError:\n" + traceback.format_exc() QgsMessageLog.logMessage(self.tr(errmsg), self.tr('Processing'), Qgis.Critical) raise e QgsMessageLog.logMessage(self.tr("Using otbcli: '{}'.".format(otbcli_path)), self.tr('Processing'), Qgis.Info)
def getFeatureDetails(self, featureList, layerList): QgsMessageLog.logMessage("In getFeatureDetails", tag="TOMs panel") self.featureList = featureList self.layerList = layerList # Creates the context menu and returns the selected feature and layer QgsMessageLog.logMessage("In getFeatureDetails: nrFeatures: " + str(len(featureList)), tag="TOMs panel") self.actions = [] self.menu = QMenu(self.iface.mapCanvas()) for feature in featureList: try: title = str(feature.id()) QgsMessageLog.logMessage("In featureContextMenu: adding: " + str(title), tag="TOMs panel") except TypeError: title = " (" + feature.attribute("SignType_1") + ")" action = QAction(title, self.menu) self.actions.append(action) self.menu.addAction(action) QgsMessageLog.logMessage("In getFeatureDetails: showing menu?", tag="TOMs panel") clicked_action = self.menu.exec_(self.iface.mapCanvas().mapToGlobal(self.event.pos())) QgsMessageLog.logMessage(("In getFeatureDetails:clicked_action: " + str(clicked_action)), tag="TOMs panel") if clicked_action is not None: QgsMessageLog.logMessage(("In getFeatureDetails:clicked_action: " + str(clicked_action.text())), tag="TOMs panel") idxList = self.getIdxFromGeometryID(clicked_action.text(), featureList) QgsMessageLog.logMessage("In getFeatureDetails: idx = " + str(idxList), tag="TOMs panel") if idxList >= 0: QgsMessageLog.logMessage("In getFeatureDetails: feat = " + str(featureList[idxList].attribute('id')), tag="TOMs panel") return featureList[idxList], layerList[idxList] QgsMessageLog.logMessage(("In getFeatureDetails. No action found."), tag="TOMs panel") return None, None
def handleAlgorithmResults(alg, context, feedback=None, showResults=True, parameters={}): wrongLayers = [] if feedback is None: feedback = QgsProcessingFeedback() feedback.setProgressText(QCoreApplication.translate('Postprocessing', 'Loading resulting layers')) i = 0 for l, details in context.layersToLoadOnCompletion().items(): if feedback.isCanceled(): return False if len(context.layersToLoadOnCompletion()) > 2: # only show progress feedback if we're loading a bunch of layers feedback.setProgress(100 * i / float(len(context.layersToLoadOnCompletion()))) try: layer = QgsProcessingUtils.mapLayerFromString(l, context, typeHint=details.layerTypeHint) if layer is not None: set_layer_name(layer, details) '''If running a model, the execution will arrive here when an algorithm that is part of that model is executed. We check if its output is a final otuput of the model, and adapt the output name accordingly''' outputName = details.outputName expcontext = QgsExpressionContext() scope = QgsExpressionContextScope() expcontext.appendScope(scope) for out in alg.outputDefinitions(): if out.name() not in parameters: continue outValue = parameters[out.name()] if hasattr(outValue, "sink"): outValue = outValue.sink.valueAsString(expcontext)[0] else: outValue = str(outValue) if outValue == l: outputName = out.name() break style = None if outputName: style = RenderingStyles.getStyle(alg.id(), outputName) if style is None: if layer.type() == QgsMapLayerType.RasterLayer: style = ProcessingConfig.getSetting(ProcessingConfig.RASTER_STYLE) else: if layer.geometryType() == QgsWkbTypes.PointGeometry: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_POINT_STYLE) elif layer.geometryType() == QgsWkbTypes.LineGeometry: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_LINE_STYLE) else: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_POLYGON_STYLE) if style: layer.loadNamedStyle(style) details.project.addMapLayer(context.temporaryLayerStore().takeMapLayer(layer)) if details.postProcessor(): details.postProcessor().postProcessLayer(layer, context, feedback) else: wrongLayers.append(str(l)) except Exception: QgsMessageLog.logMessage(QCoreApplication.translate('Postprocessing', "Error loading result layer:") + "\n" + traceback.format_exc(), 'Processing', Qgis.Critical) wrongLayers.append(str(l)) i += 1 feedback.setProgress(100) if wrongLayers: msg = QCoreApplication.translate('Postprocessing', "The following layers were not correctly generated.") msg += "<ul>" + "".join(["<li>%s</li>" % lay for lay in wrongLayers]) + "</ul>" msg += QCoreApplication.translate('Postprocessing', "You can check the 'Log Messages Panel' in QGIS main window to find more information about the execution of the algorithm.") feedback.reportError(msg) return len(wrongLayers) == 0
def executeGrass(commands, feedback, outputCommands=None): loglines = [] loglines.append(Grass7Utils.tr('GRASS GIS 7 execution console output')) grassOutDone = False command, grassenv = Grass7Utils.prepareGrassExecution(commands) # QgsMessageLog.logMessage('exec: {}'.format(command), 'DEBUG', Qgis.Info) # For MS-Windows, we need to hide the console window. if isWindows(): si = subprocess.STARTUPINFO() si.dwFlags |= subprocess.STARTF_USESHOWWINDOW si.wShowWindow = subprocess.SW_HIDE with subprocess.Popen( command, shell=False, stdout=subprocess.PIPE, stdin=subprocess.DEVNULL, stderr=subprocess.STDOUT, universal_newlines=True, env=grassenv, encoding="cp{}".format(Grass7Utils.getWindowsCodePage()) if isWindows() else None, startupinfo=si if isWindows() else None ) as proc: for line in iter(proc.stdout.readline, ''): if 'GRASS_INFO_PERCENT' in line: try: feedback.setProgress(int(line[len('GRASS_INFO_PERCENT') + 2:])) except: pass else: if 'r.out' in line or 'v.out' in line: grassOutDone = True loglines.append(line) if any([l in line for l in ['WARNING', 'ERROR']]): feedback.reportError(line.strip()) elif 'Segmentation fault' in line: feedback.reportError(line.strip()) feedback.reportError('\n' + Grass7Utils.tr('GRASS command crashed :( Try a different set of input parameters and consult the GRASS algorithm manual for more information.') + '\n') if ProcessingConfig.getSetting(Grass7Utils.GRASS_USE_VEXTERNAL): feedback.reportError(Grass7Utils.tr( 'Suggest disabling the experimental "use v.external" option from the Processing GRASS Provider options.') + '\n') elif line.strip(): feedback.pushConsoleInfo(line.strip()) # Some GRASS scripts, like r.mapcalculator or r.fillnulls, call # other GRASS scripts during execution. This may override any # commands that are still to be executed by the subprocess, which # are usually the output ones. If that is the case runs the output # commands again. if not grassOutDone and outputCommands: command, grassenv = Grass7Utils.prepareGrassExecution(outputCommands) with subprocess.Popen( command, shell=False, stdout=subprocess.PIPE, stdin=subprocess.DEVNULL, stderr=subprocess.STDOUT, universal_newlines=True, env=grassenv, startupinfo=si if isWindows() else None ) as proc: for line in iter(proc.stdout.readline, ''): if 'GRASS_INFO_PERCENT' in line: try: feedback.setProgress(int( line[len('GRASS_INFO_PERCENT') + 2:])) except: pass if any([l in line for l in ['WARNING', 'ERROR']]): loglines.append(line.strip()) feedback.reportError(line.strip()) elif line.strip(): loglines.append(line.strip()) feedback.pushConsoleInfo(line.strip()) if ProcessingConfig.getSetting(Grass7Utils.GRASS_LOG_CONSOLE): QgsMessageLog.logMessage('\n'.join(loglines), 'Processing', Qgis.Info)
def error(self, text): QMessageBox.critical(self, "Error", text) QgsMessageLog.logMessage(text, self.tr('Processing'), Qgis.Critical)
def processAlgorithm(self, context, feedback): source_layer = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(Clip.INPUT), context) mask_layer = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(Clip.OVERLAY), context) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( source_layer.fields(), QgsWkbTypes.multiType(source_layer.wkbType()), source_layer.crs(), context) # first build up a list of clip geometries clip_geoms = [] for maskFeat in QgsProcessingUtils.getFeatures( mask_layer, context, QgsFeatureRequest().setSubsetOfAttributes([])): clip_geoms.append(maskFeat.geometry()) # are we clipping against a single feature? if so, we can show finer progress reports if len(clip_geoms) > 1: combined_clip_geom = QgsGeometry.unaryUnion(clip_geoms) single_clip_feature = False else: combined_clip_geom = clip_geoms[0] single_clip_feature = True # use prepared geometries for faster intersection tests engine = QgsGeometry.createGeometryEngine( combined_clip_geom.geometry()) engine.prepareGeometry() tested_feature_ids = set() for i, clip_geom in enumerate(clip_geoms): input_features = [ f for f in QgsProcessingUtils.getFeatures( source_layer, context, QgsFeatureRequest().setFilterRect(clip_geom.boundingBox())) ] if not input_features: continue if single_clip_feature: total = 100.0 / len(input_features) else: total = 0 for current, in_feat in enumerate(input_features): if not in_feat.geometry(): continue if in_feat.id() in tested_feature_ids: # don't retest a feature we have already checked continue tested_feature_ids.add(in_feat.id()) if not engine.intersects(in_feat.geometry().geometry()): continue if not engine.contains(in_feat.geometry().geometry()): cur_geom = in_feat.geometry() new_geom = combined_clip_geom.intersection(cur_geom) if new_geom.wkbType( ) == QgsWkbTypes.Unknown or QgsWkbTypes.flatType( new_geom.geometry().wkbType( )) == QgsWkbTypes.GeometryCollection: int_com = in_feat.geometry().combine(new_geom) int_sym = in_feat.geometry().symDifference(new_geom) new_geom = int_com.difference(int_sym) else: # clip geometry totally contains feature geometry, so no need to perform intersection new_geom = in_feat.geometry() try: out_feat = QgsFeature() out_feat.setGeometry(new_geom) out_feat.setAttributes(in_feat.attributes()) writer.addFeature(out_feat) except: QgsMessageLog.logMessage( self.tr('Feature geometry error: One or more ' 'output features ignored due to ' 'invalid geometry.'), self.tr('Processing'), QgsMessageLog.CRITICAL) continue if single_clip_feature: feedback.setProgress(int(current * total)) if not single_clip_feature: # coarse progress report for multiple clip geometries feedback.setProgress(100.0 * i / len(clip_geoms)) del writer
def requestReady(self): QgsMessageLog.logMessage("SimpleHelloFilter.requestReady")
def processAlgorithm(self, parameters, context, feedback): commands = list() self.exportedLayers = {} self.preProcessInputs() extent = None crs = None # 1: Export rasters to sgrd and vectors to shp # Tables must be in dbf format. We check that. for param in self.parameterDefinitions(): if isinstance(param, QgsProcessingParameterRasterLayer): if param.name( ) not in parameters or parameters[param.name()] is None: continue if isinstance(parameters[param.name()], str): if parameters[param.name()].lower().endswith('sdat'): self.exportedLayers[param.name( )] = parameters[param.name()][:-4] + 'sgrd' if parameters[param.name()].lower().endswith('sgrd'): self.exportedLayers[param.name()] = parameters[ param.name()] else: layer = self.parameterAsRasterLayer( parameters, param.name(), context) exportCommand = self.exportRasterLayer( param.name(), layer) if exportCommand is not None: commands.append(exportCommand) else: if parameters[param.name()].source().lower().endswith( 'sdat'): self.exportedLayers[param.name( )] = parameters[param.name()].source()[:-4] + 'sgrd' if parameters[param.name()].source().lower().endswith( 'sgrd'): self.exportedLayers[param.name()] = parameters[ param.name()].source() else: exportCommand = self.exportRasterLayer( param.name(), parameters[param.name()]) if exportCommand is not None: commands.append(exportCommand) elif isinstance(param, QgsProcessingParameterFeatureSource): if param.name( ) not in parameters or parameters[param.name()] is None: continue if not crs: source = self.parameterAsSource(parameters, param.name(), context) if source is None: raise QgsProcessingException( self.invalidSourceError(parameters, param.name())) crs = source.sourceCrs() layer_path = self.parameterAsCompatibleSourceLayerPath( parameters, param.name(), context, ['shp'], 'shp', feedback=feedback) if layer_path: self.exportedLayers[param.name()] = layer_path else: raise QgsProcessingException( self.tr('Unsupported file format')) elif isinstance(param, QgsProcessingParameterMultipleLayers): if param.name( ) not in parameters or parameters[param.name()] is None: continue layers = self.parameterAsLayerList(parameters, param.name(), context) if layers is None or len(layers) == 0: continue if param.layerType() == QgsProcessing.TypeRaster: files = [] for i, layer in enumerate(layers): if layer.source().lower().endswith('sdat'): files.append( parameters[param.name()].source()[:-4] + 'sgrd') if layer.source().lower().endswith('sgrd'): files.append(parameters[param.name()].source()) else: exportCommand = self.exportRasterLayer( param.name(), layer) files.append(self.exportedLayers[param.name()]) if exportCommand is not None: commands.append(exportCommand) self.exportedLayers[param.name()] = files else: for layer in layers: temp_params = {} temp_params[param.name()] = layer if not crs: source = self.parameterAsSource( temp_params, param.name(), context) if source is None: raise QgsProcessingException( self.invalidSourceError( parameters, param.name())) crs = source.sourceCrs() layer_path = self.parameterAsCompatibleSourceLayerPath( temp_params, param.name(), context, ['shp'], 'shp', feedback=feedback) if layer_path: if param.name() in self.exportedLayers: self.exportedLayers[param.name()].append( layer_path) else: self.exportedLayers[param.name()] = [ layer_path ] else: raise QgsProcessingException( self.tr('Unsupported file format')) # 2: Set parameters and outputs command = self.undecorated_group + ' "' + self.cmdname + '"' command += ' ' + ' '.join(self.hardcoded_strings) for param in self.parameterDefinitions(): if not param.name() in parameters or parameters[ param.name()] is None: continue if param.isDestination(): continue if isinstance(param, (QgsProcessingParameterRasterLayer, QgsProcessingParameterFeatureSource)): command += ' -{} "{}"'.format( param.name(), self.exportedLayers[param.name()]) elif isinstance(param, QgsProcessingParameterMultipleLayers): if parameters[ param.name()]: # parameter may have been an empty list command += ' -{} "{}"'.format( param.name(), ';'.join(self.exportedLayers[param.name()])) elif isinstance(param, QgsProcessingParameterBoolean): if self.parameterAsBool(parameters, param.name(), context): command += ' -{} true'.format(param.name().strip()) else: command += ' -{} false'.format(param.name().strip()) elif isinstance(param, QgsProcessingParameterMatrix): tempTableFile = getTempFilename('txt') with open(tempTableFile, 'w') as f: f.write('\t'.join([col for col in param.headers()]) + '\n') values = self.parameterAsMatrix(parameters, param.name(), context) for i in range(0, len(values), 3): s = '{}\t{}\t{}\n'.format(values[i], values[i + 1], values[i + 2]) f.write(s) command += ' -{} "{}"'.format(param.name(), tempTableFile) elif isinstance(param, QgsProcessingParameterExtent): # 'We have to substract/add half cell size, since SAGA is # center based, not corner based halfcell = self.getOutputCellsize(parameters, context) / 2 offset = [halfcell, -halfcell, halfcell, -halfcell] rect = self.parameterAsExtent(parameters, param.name(), context) values = [] values.append(rect.xMinimum()) values.append(rect.xMaximum()) values.append(rect.yMinimum()) values.append(rect.yMaximum()) for i in range(4): command += ' -{} {}'.format(param.name().split(' ')[i], float(values[i]) + offset[i]) elif isinstance(param, QgsProcessingParameterNumber): if param.dataType() == QgsProcessingParameterNumber.Integer: command += ' -{} {}'.format( param.name(), self.parameterAsInt(parameters, param.name(), context)) else: command += ' -{} {}'.format( param.name(), self.parameterAsDouble(parameters, param.name(), context)) elif isinstance(param, QgsProcessingParameterEnum): command += ' -{} {}'.format( param.name(), self.parameterAsEnum(parameters, param.name(), context)) elif isinstance( param, (QgsProcessingParameterString, QgsProcessingParameterFile)): command += ' -{} "{}"'.format( param.name(), self.parameterAsFile(parameters, param.name(), context)) elif isinstance( param, (QgsProcessingParameterString, QgsProcessingParameterField)): command += ' -{} "{}"'.format( param.name(), self.parameterAsString(parameters, param.name(), context)) output_layers = [] output_files = {} for out in self.destinationParameterDefinitions(): filePath = self.parameterAsOutputLayer(parameters, out.name(), context) if isinstance(out, (QgsProcessingParameterRasterDestination, QgsProcessingParameterVectorDestination)): output_layers.append(filePath) output_files[out.name()] = filePath command += ' -{} "{}"'.format(out.name(), filePath) commands.append(command) # special treatment for RGB algorithm # TODO: improve this and put this code somewhere else for out in self.destinationParameterDefinitions(): if isinstance(out, QgsProcessingParameterRasterDestination): filename = self.parameterAsOutputLayer(parameters, out.name(), context) filename2 = os.path.splitext(filename)[0] + '.sgrd' if self.cmdname == 'RGB Composite': commands.append( 'io_grid_image 0 -COLOURING 4 -GRID:"{}" -FILE:"{}"'. format(filename2, filename)) # 3: Run SAGA commands = self.editCommands(commands) SagaUtils.createSagaBatchJobFileFromSagaCommands(commands) loglines = [] loglines.append(self.tr('SAGA execution commands')) for line in commands: feedback.pushCommandInfo(line) loglines.append(line) if ProcessingConfig.getSetting(SagaUtils.SAGA_LOG_COMMANDS): QgsMessageLog.logMessage('\n'.join(loglines), self.tr('Processing'), Qgis.Info) SagaUtils.executeSaga(feedback) if crs is not None: for out in output_layers: prjFile = os.path.splitext(out)[0] + '.prj' with open(prjFile, 'w') as f: f.write(crs.toWkt()) result = {} for o in self.outputDefinitions(): if o.name() in output_files: result[o.name()] = output_files[o.name()] return result
def debug_msg(debug_on_off, msg_str, msg_list_var): if debug_on_off == 'DEBUG': msg = msg_str % msg_list_var QgsMessageLog.logMessage(msg, 'Sgm debug')
def sendResponse(self): QgsMessageLog.logMessage("SimpleHelloFilter.sendResponse")
def execute_in_place_run(alg, parameters, context=None, feedback=None, raise_exceptions=False): """Executes an algorithm modifying features in-place in the input layer. :param alg: algorithm to run :type alg: QgsProcessingAlgorithm :param parameters: parameters of the algorithm :type parameters: dict :param context: context, defaults to None :type context: QgsProcessingContext, optional :param feedback: feedback, defaults to None :type feedback: QgsProcessingFeedback, optional :param raise_exceptions: useful for testing, if True exceptions are raised, normally exceptions will be forwarded to the feedback :type raise_exceptions: boo, default to False :raises QgsProcessingException: raised when there is no active layer, or it cannot be made editable :return: a tuple with true if success and results :rtype: tuple """ if feedback is None: feedback = QgsProcessingFeedback() if context is None: context = dataobjects.createContext(feedback) # Only feature based algs have sourceFlags try: if alg.sourceFlags( ) & QgsProcessingFeatureSource.FlagSkipGeometryValidityChecks: context.setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck) except AttributeError: pass active_layer = parameters['INPUT'] # Run some checks and prepare the layer for in-place execution by: # - getting the active layer and checking that it is a vector # - making the layer editable if it was not already # - selecting all features if none was selected # - checking in-place support for the active layer/alg/parameters # If one of the check fails and raise_exceptions is True an exception # is raised, else the execution is aborted and the error reported in # the feedback try: if active_layer is None: raise QgsProcessingException(tr("There is not active layer.")) if not isinstance(active_layer, QgsVectorLayer): raise QgsProcessingException( tr("Active layer is not a vector layer.")) if not active_layer.isEditable(): if not active_layer.startEditing(): raise QgsProcessingException( tr("Active layer is not editable (and editing could not be turned on)." )) if not alg.supportInPlaceEdit(active_layer): raise QgsProcessingException( tr("Selected algorithm and parameter configuration are not compatible with in-place modifications." )) except QgsProcessingException as e: if raise_exceptions: raise e QgsMessageLog.logMessage(str(sys.exc_info()[0]), 'Processing', Qgis.Critical) if feedback is not None: feedback.reportError(getattr(e, 'msg', str(e)), fatalError=True) return False, {} if not active_layer.selectedFeatureIds(): active_layer.selectAll() # Make sure we are working on selected features only parameters['INPUT'] = QgsProcessingFeatureSourceDefinition( active_layer.id(), True) parameters['OUTPUT'] = 'memory:' req = QgsFeatureRequest(QgsExpression(r"$id < 0")) req.setFlags(QgsFeatureRequest.NoGeometry) req.setSubsetOfAttributes([]) # Start the execution # If anything goes wrong and raise_exceptions is True an exception # is raised, else the execution is aborted and the error reported in # the feedback try: new_feature_ids = [] active_layer.beginEditCommand(alg.displayName()) # Checks whether the algorithm has a processFeature method if hasattr(alg, 'processFeature'): # in-place feature editing # Make a clone or it will crash the second time the dialog # is opened and run alg = alg.create() if not alg.prepare(parameters, context, feedback): raise QgsProcessingException( tr("Could not prepare selected algorithm.")) # Check again for compatibility after prepare if not alg.supportInPlaceEdit(active_layer): raise QgsProcessingException( tr("Selected algorithm and parameter configuration are not compatible with in-place modifications." )) # some algorithms have logic in outputFields/outputCrs/outputWkbType which they require to execute before # they can start processing features _ = alg.outputFields(active_layer.fields()) _ = alg.outputWkbType(active_layer.wkbType()) _ = alg.outputCrs(active_layer.crs()) field_idxs = range(len(active_layer.fields())) iterator_req = QgsFeatureRequest(active_layer.selectedFeatureIds()) iterator_req.setInvalidGeometryCheck( context.invalidGeometryCheck()) feature_iterator = active_layer.getFeatures(iterator_req) step = 100 / len(active_layer.selectedFeatureIds() ) if active_layer.selectedFeatureIds() else 1 for current, f in enumerate(feature_iterator): feedback.setProgress(current * step) if feedback.isCanceled(): break # need a deep copy, because python processFeature implementations may return # a shallow copy from processFeature input_feature = QgsFeature(f) new_features = alg.processFeature(input_feature, context, feedback) new_features = QgsVectorLayerUtils.makeFeaturesCompatible( new_features, active_layer) if len(new_features) == 0: active_layer.deleteFeature(f.id()) elif len(new_features) == 1: new_f = new_features[0] if not f.geometry().equals(new_f.geometry()): active_layer.changeGeometry(f.id(), new_f.geometry()) if f.attributes() != new_f.attributes(): active_layer.changeAttributeValues( f.id(), dict(zip(field_idxs, new_f.attributes())), dict(zip(field_idxs, f.attributes()))) new_feature_ids.append(f.id()) else: active_layer.deleteFeature(f.id()) # Get the new ids old_ids = set( [f.id() for f in active_layer.getFeatures(req)]) if not active_layer.addFeatures(new_features): raise QgsProcessingException( tr("Error adding processed features back into the layer." )) new_ids = set( [f.id() for f in active_layer.getFeatures(req)]) new_feature_ids += list(new_ids - old_ids) results, ok = {}, True else: # Traditional 'run' with delete and add features cycle # There is no way to know if some features have been skipped # due to invalid geometries if context.invalidGeometryCheck( ) == QgsFeatureRequest.GeometrySkipInvalid: selected_ids = active_layer.selectedFeatureIds() else: selected_ids = [] results, ok = alg.run(parameters, context, feedback) if ok: result_layer = QgsProcessingUtils.mapLayerFromString( results['OUTPUT'], context) # TODO: check if features have changed before delete/add cycle new_features = [] # Check if there are any skipped features if context.invalidGeometryCheck( ) == QgsFeatureRequest.GeometrySkipInvalid: missing_ids = list( set(selected_ids) - set(result_layer.allFeatureIds())) if missing_ids: for f in active_layer.getFeatures( QgsFeatureRequest(missing_ids)): if not f.geometry().isGeosValid(): new_features.append(f) active_layer.deleteFeatures(active_layer.selectedFeatureIds()) for f in result_layer.getFeatures(): new_features.extend( QgsVectorLayerUtils.makeFeaturesCompatible( [f], active_layer)) # Get the new ids old_ids = set([f.id() for f in active_layer.getFeatures(req)]) if not active_layer.addFeatures(new_features): raise QgsProcessingException( tr("Error adding processed features back into the layer." )) new_ids = set([f.id() for f in active_layer.getFeatures(req)]) new_feature_ids += list(new_ids - old_ids) active_layer.endEditCommand() if ok and new_feature_ids: active_layer.selectByIds(new_feature_ids) elif not ok: active_layer.rollBack() return ok, results except QgsProcessingException as e: active_layer.endEditCommand() active_layer.rollBack() if raise_exceptions: raise e QgsMessageLog.logMessage(str(sys.exc_info()[0]), 'Processing', Qgis.Critical) if feedback is not None: feedback.reportError(getattr(e, 'msg', str(e)), fatalError=True) return False, {}
def executeGrass(commands, feedback, outputCommands=None): loglines = [] loglines.append(Grass7Utils.tr('GRASS GIS 7 execution console output')) grassOutDone = False command, grassenv = Grass7Utils.prepareGrassExecution(commands) #QgsMessageLog.logMessage('exec: {}'.format(command), 'DEBUG', Qgis.Info) # For MS-Windows, we need to hide the console window. if isWindows(): si = subprocess.STARTUPINFO() si.dwFlags |= subprocess.STARTF_USESHOWWINDOW si.wShowWindow = subprocess.SW_HIDE with subprocess.Popen(command, shell=True if isMac() else False, stdout=subprocess.PIPE, stdin=subprocess.DEVNULL, stderr=subprocess.STDOUT, universal_newlines=True, env=grassenv, startupinfo=si if isWindows() else None) as proc: for line in iter(proc.stdout.readline, ''): if 'GRASS_INFO_PERCENT' in line: try: feedback.setProgress( int(line[len('GRASS_INFO_PERCENT') + 2:])) except: pass else: if 'r.out' in line or 'v.out' in line: grassOutDone = True loglines.append(line) feedback.pushConsoleInfo(line) # Some GRASS scripts, like r.mapcalculator or r.fillnulls, call # other GRASS scripts during execution. This may override any # commands that are still to be executed by the subprocess, which # are usually the output ones. If that is the case runs the output # commands again. if not grassOutDone and outputCommands: command, grassenv = Grass7Utils.prepareGrassExecution( outputCommands) with subprocess.Popen( command, shell=True if isMac() else False, stdout=subprocess.PIPE, stdin=subprocess.DEVNULL, stderr=subprocess.STDOUT, universal_newlines=True, env=grassenv, startupinfo=si if isWindows() else None) as proc: for line in iter(proc.stdout.readline, ''): if 'GRASS_INFO_PERCENT' in line: try: feedback.setProgress( int(line[len('GRASS_INFO_PERCENT') + 2:])) except: pass else: loglines.append(line) feedback.pushConsoleInfo(line) if ProcessingConfig.getSetting(Grass7Utils.GRASS_LOG_CONSOLE): QgsMessageLog.logMessage('\n'.join(loglines), 'Processing', Qgis.Info)
def processAlgorithm(self, parameters, context, feedback): sourceA = self.parameterAsSource(parameters, self.INPUT, context) sourceB = self.parameterAsSource(parameters, self.OVERLAY, context) geomType = QgsWkbTypes.multiType(sourceA.wkbType()) fields = QgsProcessingUtils.combineFields(sourceA.fields(), sourceB.fields()) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, geomType, sourceA.sourceCrs()) featB = QgsFeature() outFeat = QgsFeature() indexA = QgsSpatialIndex(sourceA, feedback) indexB = QgsSpatialIndex( sourceB.getFeatures(QgsFeatureRequest().setSubsetOfAttributes( []).setDestinationCrs(sourceA.sourceCrs())), feedback) total = 100.0 / (sourceA.featureCount() * sourceB.featureCount()) if sourceA.featureCount( ) and sourceB.featureCount() else 1 count = 0 for featA in sourceA.getFeatures(): if feedback.isCanceled(): break geom = featA.geometry() diffGeom = QgsGeometry(geom) attrs = featA.attributes() intersects = indexB.intersects(geom.boundingBox()) request = QgsFeatureRequest().setFilterFids( intersects).setSubsetOfAttributes([]) request.setDestinationCrs(sourceA.sourceCrs()) for featB in sourceB.getFeatures(request): if feedback.isCanceled(): break tmpGeom = featB.geometry() if diffGeom.intersects(tmpGeom): diffGeom = QgsGeometry(diffGeom.difference(tmpGeom)) try: outFeat.setGeometry(diffGeom) outFeat.setAttributes(attrs) sink.addFeature(outFeat, QgsFeatureSink.FastInsert) except: QgsMessageLog.logMessage( self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' ), self.tr('Processing'), QgsMessageLog.WARNING) continue count += 1 feedback.setProgress(int(count * total)) length = len(sourceA.fields()) for featA in sourceB.getFeatures(QgsFeatureRequest().setDestinationCrs( sourceA.sourceCrs())): if feedback.isCanceled(): break geom = featA.geometry() diffGeom = QgsGeometry(geom) attrs = featA.attributes() attrs = [NULL] * length + attrs intersects = indexA.intersects(geom.boundingBox()) request = QgsFeatureRequest().setFilterFids( intersects).setSubsetOfAttributes([]) for featB in sourceA.getFeatures(request): if feedback.isCanceled(): break tmpGeom = featB.geometry() if diffGeom.intersects(tmpGeom): diffGeom = QgsGeometry(diffGeom.difference(tmpGeom)) try: outFeat.setGeometry(diffGeom) outFeat.setAttributes(attrs) sink.addFeature(outFeat, QgsFeatureSink.FastInsert) except: QgsMessageLog.logMessage( self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' ), self.tr('Processing'), QgsMessageLog.WARNING) continue count += 1 feedback.setProgress(int(count * total)) return {self.OUTPUT: dest_id}
def detectTripleStoreConfiguration(self): self.configuration={} self.configuration["name"]=self.triplestorename self.configuration["endpoint"]=self.triplestoreurl self.configuration["geoconceptlimit"]=500 self.configuration["crs"]=4326 self.configuration["staticconcepts"]=[] self.configuration["active"]=True self.configuration["prefixes"]={"owl": "http://www.w3.org/2002/07/owl#","rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#","rdfs": "http://www.w3.org/2000/01/rdf-schema#","geosparql": "http://www.opengis.net/ont/geosparql#","geof": "http://www.opengis.net/def/function/geosparql/","geor":"http://www.opengis.net/def/rule/geosparql/","sf":"http://www.opengis.net/ont/sf#","wgs84_pos": "http://www.w3.org/2003/01/geo/wgs84_pos#"} testQueries={"geosparql":"PREFIX geof:<http://www.opengis.net/def/function/geosparql/> SELECT ?a ?b ?c WHERE { BIND( \"POINT(1 1)\"^^<http://www.opengis.net/ont/geosparql#wktLiteral> AS ?a) BIND( \"POINT(1 1)\"^^<http://www.opengis.net/ont/geosparql#wktLiteral> AS ?b) FILTER(geof:sfIntersects(?a,?b))}","available":"SELECT ?a ?b ?c WHERE { ?a ?b ?c .} LIMIT 1","hasRDFSLabel":"PREFIX rdfs:<http://www.w3.org/2000/01/rdf-schema#> ASK { ?a rdfs:label ?c . }","hasRDFType":"PREFIX rdf:<http:/www.w3.org/1999/02/22-rdf-syntax-ns#> ASK { ?a <http:/www.w3.org/1999/02/22-rdf-syntax-ns#type> ?c . }","hasWKT":"PREFIX geosparql:<http://www.opengis.net/ont/geosparql#> ASK { ?a geosparql:asWKT ?c .}","hasGML":"PREFIX geosparql:<http://www.opengis.net/ont/geosparql#> ASK { ?a geosparql:asGML ?c .}","hasGeoJSON":"PREFIX geosparql:<http://www.opengis.net/ont/geosparql#> ASK { ?a geosparql:asGeoJSON ?c .}","hasLatLon":"PREFIX geo:<http://www.w3.org/2003/01/geo/wgs84_pos#> ASK { ?a geo:lat ?c . ?a geo:long ?d . }","namespaceQuery":"select distinct ?ns where { ?s ?p ?o . bind( replace( str(?s), \"(#|/)[^#/]*$\", \"$1\" ) as ?ns )} limit 10"} if self.testTripleStoreConnection(testQueries["available"]): if self.testTripleStoreConnection(testQueries["hasWKT"]): if self.testTripleStoreConnection(testQueries["geosparql"]): self.configuration["bboxquery"]={} self.configuration["bboxquery"]["type"]="geosparql" self.configuration["bboxquery"]["query"]="FILTER(<http://www.opengis.net/def/function/geosparql/sfIntersects>(?geo,\"POLYGON((%%x1%% %%y1%%, %%x1%% %%y2%%, %%x2%% %%y2%%, %%x2%% %%y1%%, %%x1%% %%y1%%))\"^^<http://www.opengis.net/ont/geosparql#wktLiteral>))" self.message="URL depicts a valid GeoSPARQL Endpoint and contains WKT Literals!\nWould you like to add this SPARQL endpoint?" else: self.message="URL depicts a valid SPARQL Endpoint and contains WKT Literals!\nWould you like to add this SPARQL endpoint?" self.configuration["mandatoryvariables"]=["item","geo"] self.configuration["querytemplate"]=[] self.configuration["querytemplate"].append({"label":"10 Random Geometries","query": "SELECT ?item ?geo WHERE {\n ?item <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <%%concept%%>.\n ?item <http://www.opengis.net/ont/geosparql#hasGeometry> ?geom_obj .\n ?geom_obj <http://www.opengis.net/ont/geosparql#asWKT> ?geo .\n } LIMIT 10"}) self.configuration["geoconceptquery"]="SELECT DISTINCT ?class WHERE { ?a <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?class . ?a <http://www.opengis.net/ont/geosparql#hasGeometry> ?a_geom . ?a_geom <http://www.opengis.net/ont/geosparql#asWKT> ?wkt .}" res=set(self.detectNamespaces(-1)+self.detectNamespaces(0)+self.detectNamespaces(1)) i=0 for ns in res: if ns!="http://" and ns.startswith("http://"): if ns in self.prefixstore["reversed"]: self.configuration["prefixes"][self.prefixstore["reversed"][ns]]=ns else: self.configuration["prefixes"]["ns"+str(i)]=ns i=i+1 self.feasibleConfiguration=True QgsMessageLog.logMessage(str(self.configuration)) elif self.testTripleStoreConnection(testQueries["hasLatLon"]): self.message="URL depicts a valid SPARQL Endpoint and contains Lat/long!\nWould you like to add this SPARQL endpoint?" self.configuration["mandatoryvariables"]=["item","lat", "lon"] self.configuration["querytemplate"]=[] self.configuration["querytemplate"].append({"label":"10 Random Geometries","query": "SELECT ?item ?lat ?lon WHERE {\n ?item <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Class> .\n ?item <http://www.w3.org/2003/01/geo/wgs84_pos#lat> ?lat .\n ?item <http://www.w3.org/2003/01/geo/wgs84_pos#long> ?lon .\n } LIMIT 10"}) self.configuration["geoconceptquery"]="SELECT DISTINCT ?class WHERE { ?a <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?class . ?a <http://www.w3.org/2003/01/geo/wgs84_pos#lat> ?lat . ?a <http://www.w3.org/2003/01/geo/wgs84_pos#long> ?lon .}" res=set(self.detectNamespaces(-1)+self.detectNamespaces(0)+self.detectNamespaces(1)) i=0 for ns in res: if ns!="http://" and ns.startswith("http://"): if ns in self.prefixstore["reversed"]: self.configuration["prefixes"][self.prefixstore["reversed"][ns]]=ns else: self.configuration["prefixes"]["ns"+str(i)]=ns i=i+1 self.feasibleConfiguration=True QgsMessageLog.logMessage(str(self.configuration)) elif self.testTripleStoreConnection(testQueries["hasGeoJSON"]): if self.testTripleStoreConnection(testQueries["geosparql"]): self.configuration["bboxquery"]={} self.configuration["bboxquery"]["type"]="geosparql" self.configuration["bboxquery"]["query"]="FILTER(<http://www.opengis.net/def/function/geosparql/sfIntersects>(?geo,\"POLYGON((%%x1%% %%y1%%, %%x1%% %%y2%%, %%x2%% %%y2%%, %%x2%% %%y1%%, %%x1%% %%y1%%))\"^^<http://www.opengis.net/ont/geosparql#geoJSONLiteral>))" self.message="URL depicts a valid GeoSPARQL Endpoint and contains GeoJSON Literals!\nWould you like to add this SPARQL endpoint?" else: self.message="URL depicts a valid SPARQL Endpoint and contains GeoJSON Literals!\nWould you like to add this SPARQL endpoint?" self.configuration["mandatoryvariables"]=["item","geo"] self.configuration["querytemplate"]=[] self.configuration["querytemplate"].append({"label":"10 Random Geometries","query": "SELECT ?item ?geo WHERE {\n ?item a <%%concept%%>.\n ?item <http://www.opengis.net/ont/geosparql#hasGeometry> ?geom_obj .\n ?geom_obj <http://www.opengis.net/ont/geosparql#asGeoJSON> ?geo .\n } LIMIT 10"}) self.configuration["querytemplate"].append({"label":"10 Random Geometries (All Attributes","query": "SELECT DISTINCT ?item ?rel ?val ?geo WHERE {\n ?item rdf:type <%%concept%%> .\n ?item ?rel ?val . \n ?val <http://www.opengis.net/ont/geosparql#asGeoJSON> ?geo .\n}\n LIMIT 100"}) self.configuration["geoconceptquery"]="SELECT DISTINCT ?class WHERE { ?a <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> ?class . ?a ?rel ?a_geom . ?a_geom <http://www.opengis.net/ont/geosparql#asGeoJSON> ?wkt .}" res=set(self.detectNamespaces(-1)+self.detectNamespaces(0)+self.detectNamespaces(1)) i=0 for ns in res: if ns!="http://" and ns.startswith("http://"): if ns in self.prefixstore["reversed"]: self.configuration["prefixes"][self.prefixstore["reversed"][ns]]=ns else: self.configuration["prefixes"]["ns"+str(i)]=ns i=i+1 self.feasibleConfiguration=True QgsMessageLog.logMessage(str(self.configuration)) else: self.message="SPARQL endpoint does not seem to include the following geometry relations: geo:asWKT, geo:asGeoJSON, geo:lat, geo:long.\nA manual configuration is probably necessary to include this SPARQL endpoint" self.feasibleConfiguration=False return False else: self.message="URL does not depict a valid SPARQL Endpoint!" self.feasibleConfiguration=False return False if self.testTripleStoreConnection(testQueries["hasRDFSLabel"]) and self.testTripleStoreConnection(testQueries["hasRDFType"]): self.configuration["classfromlabelquery"]="SELECT DISTINCT ?class ?label { ?class <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Class> . ?class <http://www.w3.org/2000/01/rdf-schema#label> ?label . FILTER(CONTAINS(?label,\"%%label%%\"))} LIMIT 100 " self.configuration["propertyfromlabelquery"]="SELECT DISTINCT ?class ?label { ?class <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#ObjectProperty> . ?class <http://www.w3.org/2000/01/rdf-schema#label> ?label . FILTER(CONTAINS(?label,\"%%label%%\"))} LIMIT 100 " self.configuration["whattoenrichquery"]="SELECT DISTINCT (COUNT(distinct ?con) AS ?countcon) (COUNT(?rel) AS ?countrel) ?rel WHERE { ?con <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> %%concept%% . ?con ?rel ?val . } GROUP BY ?rel ORDER BY DESC(?countrel)" return True
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.VECTOR), context) pointCount = float(self.getParameterValue(self.POINT_NUMBER)) minDistance = float(self.getParameterValue(self.MIN_DISTANCE)) fields = QgsFields() fields.append(QgsField('id', QVariant.Int, '', 10, 0)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, QgsWkbTypes.Point, layer.crs(), context) nPoints = 0 nIterations = 0 maxIterations = pointCount * 200 featureCount = layer.featureCount() total = 100.0 / pointCount if pointCount else 1 index = QgsSpatialIndex() points = dict() da = QgsDistanceArea() da.setSourceCrs(layer.sourceCrs()) da.setEllipsoid(QgsProject.instance().ellipsoid()) request = QgsFeatureRequest() random.seed() while nIterations < maxIterations and nPoints < pointCount: # pick random feature fid = random.randint(0, featureCount - 1) f = next( layer.getFeatures( request.setFilterFid(fid).setSubsetOfAttributes([]))) fGeom = f.geometry() if fGeom.isMultipart(): lines = fGeom.asMultiPolyline() # pick random line lineId = random.randint(0, len(lines) - 1) vertices = lines[lineId] else: vertices = fGeom.asPolyline() # pick random segment if len(vertices) == 2: vid = 0 else: vid = random.randint(0, len(vertices) - 2) startPoint = vertices[vid] endPoint = vertices[vid + 1] length = da.measureLine(startPoint, endPoint) dist = length * random.random() if dist > minDistance: d = dist / (length - dist) rx = (startPoint.x() + d * endPoint.x()) / (1 + d) ry = (startPoint.y() + d * endPoint.y()) / (1 + d) # generate random point pnt = QgsPointXY(rx, ry) geom = QgsGeometry.fromPoint(pnt) if vector.checkMinDistance(pnt, index, minDistance, points): f = QgsFeature(nPoints) f.initAttributes(1) f.setFields(fields) f.setAttribute('id', nPoints) f.setGeometry(geom) writer.addFeature(f, QgsFeatureSink.FastInsert) index.insertFeature(f) points[nPoints] = pnt nPoints += 1 feedback.setProgress(int(nPoints * total)) nIterations += 1 if nPoints < pointCount: QgsMessageLog.logMessage( self.tr('Can not generate requested number of random points. ' 'Maximum number of attempts exceeded.'), self.tr('Processing'), QgsMessageLog.INFO) del writer
def processCommand(self, parameters, context, feedback, delOutputs=False): """ Prepare the GRASS algorithm command :param parameters: :param context: :param delOutputs: do not add outputs to commands. """ noOutputs = [ o for o in self.parameterDefinitions() if o not in self.destinationParameterDefinitions() ] command = '{} '.format(self.grass7Name) command += '{}'.join(self.hardcodedStrings) # Add algorithm command for param in noOutputs: paramName = param.name() value = None # Exclude default GRASS parameters if paramName in [ self.GRASS_REGION_CELLSIZE_PARAMETER, self.GRASS_REGION_EXTENT_PARAMETER, self.GRASS_MIN_AREA_PARAMETER, self.GRASS_SNAP_TOLERANCE_PARAMETER, self.GRASS_OUTPUT_TYPE_PARAMETER, self.GRASS_REGION_ALIGN_TO_RESOLUTION, self.GRASS_RASTER_FORMAT_OPT, self.GRASS_RASTER_FORMAT_META, self.GRASS_VECTOR_DSCO, self.GRASS_VECTOR_LCO, self.GRASS_VECTOR_EXPORT_NOCAT ]: continue # Raster and vector layers if isinstance(param, (QgsProcessingParameterRasterLayer, QgsProcessingParameterVectorLayer, QgsProcessingParameterFeatureSource)): if paramName in self.exportedLayers: value = self.exportedLayers[paramName] else: value = self.parameterAsCompatibleSourceLayerPath( parameters, paramName, context, QgsVectorFileWriter.supportedFormatExtensions()) # MultipleLayers elif isinstance(param, QgsProcessingParameterMultipleLayers): layers = self.parameterAsLayerList(parameters, paramName, context) values = [] for idx in range(len(layers)): layerName = '{}_{}'.format(paramName, idx) values.append(self.exportedLayers[layerName]) value = ','.join(values) # For booleans, we just add the parameter name elif isinstance(param, QgsProcessingParameterBoolean): if self.parameterAsBool(parameters, paramName, context): command += ' {}'.format(paramName) # For Extents, remove if the value is null elif isinstance(param, QgsProcessingParameterExtent): if self.parameterAsExtent(parameters, paramName, context): value = self.parameterAsString(parameters, paramName, context) # For enumeration, we need to grab the string value elif isinstance(param, QgsProcessingParameterEnum): # Handle multiple values if param.allowMultiple(): indexes = self.parameterAsEnums(parameters, paramName, context) else: indexes = [ self.parameterAsEnum(parameters, paramName, context) ] if indexes: value = '"{}"'.format(','.join( [param.options()[i] for i in indexes])) # For strings, we just translate as string elif isinstance(param, QgsProcessingParameterString): data = self.parameterAsString(parameters, paramName, context) # if string is empty, we don't add it if len(data) > 0: value = '"{}"'.format( self.parameterAsString(parameters, paramName, context)) # For fields, we just translate as string elif isinstance(param, QgsProcessingParameterField): value = ','.join( self.parameterAsFields(parameters, paramName, context)) elif isinstance(param, QgsProcessingParameterFile): if self.parameterAsString(parameters, paramName, context): value = '"{}"'.format( self.parameterAsString(parameters, paramName, context)) elif isinstance(param, QgsProcessingParameterPoint): if self.parameterAsString(parameters, paramName, context): # parameter specified, evaluate as point # TODO - handle CRS transform point = self.parameterAsPoint(parameters, paramName, context) value = '{},{}'.format(point.x(), point.y()) # For numbers, we translate as a string elif isinstance( param, (QgsProcessingParameterNumber, QgsProcessingParameterPoint)): value = self.parameterAsString(parameters, paramName, context) # For everything else, we assume that it is a string else: value = '"{}"'.format( self.parameterAsString(parameters, paramName, context)) if value: command += ' {}={}'.format(paramName.replace('~', ''), value) # Handle outputs if not delOutputs: for out in self.destinationParameterDefinitions(): # We exclude hidden parameters if out.flags() & QgsProcessingParameterDefinition.FlagHidden: continue outName = out.name() # For File destination if isinstance(out, QgsProcessingParameterFileDestination): if outName in parameters and parameters[ outName] is not None: # for HTML reports, we need to redirect stdout if out.defaultFileExtension().lower() == 'html': command += ' {}=- > "{}"'.format( outName, self.parameterAsFileOutput( parameters, outName, context)) else: command += ' {}="{}"'.format( outName, self.parameterAsFileOutput( parameters, outName, context)) # For folders destination elif isinstance(out, QgsProcessingParameterFolderDestination): # We need to add a unique temporary basename uniqueBasename = outName + self.uniqueSuffix command += ' {}={}'.format(outName, uniqueBasename) else: if outName in parameters and parameters[ outName] is not None: # We add an output name to make sure it is unique if the session # uses this algorithm several times. uniqueOutputName = outName + self.uniqueSuffix command += ' {}={}'.format(outName, uniqueOutputName) # Add output file to exported layers, to indicate that # they are present in GRASS self.exportedLayers[outName] = uniqueOutputName command += ' --overwrite' self.commands.append(command) QgsMessageLog.logMessage( self.tr('processCommands end. Commands: {}').format(self.commands), 'Grass7', Qgis.Info)
def execute(self): """ Reimplementation of the execute method from the parent class """ QgsMessageLog.logMessage( self.tr('Starting ') + self.getName() + self.tr(' Process.'), "DSG Tools Plugin", QgsMessageLog.CRITICAL) try: self.setStatus(self.tr('Running'), 3) #now I'm running! # getting frame and reference parameters refWithElem = self.parameters['Reference and Layers'][0] lines = self.parameters['Reference and Layers'][1] frame, frameGeometryColumn = refWithElem.split(':') if len(lines) == 0: self.setStatus( self.tr('No classes selected!. Nothing to be done.'), 1) #Finished QgsMessageLog.logMessage( self.tr('No classes selected! Nothing to be done.'), "DSG Tools Plugin", QgsMessageLog.CRITICAL) return 1 if not refWithElem: self.setStatus( self.tr('One reference must be selected! Stopping.'), 1) #Finished QgsMessageLog.logMessage( self.tr('One reference must be selected! Stopping.'), "DSG Tools Plugin", QgsMessageLog.CRITICAL) return 1 tol = self.parameters['Snap'] for classAndGeom in lines: # preparation cl, geometryColumn = classAndGeom.split(':') localProgress = ProgressWidget( 0, 1, self.tr('Preparing execution for ') + cl, parent=self.iface.mapCanvas()) localProgress.step() processTableName, lyr, keyColumn = self.prepareExecution( cl, geometryColumn) frameTableName, frameLyr, frameKeyColumn = self.prepareExecution( frame, frameGeometryColumn) localProgress.step() #running the process in the temp table localProgress = ProgressWidget(0, 1, self.tr('Running process on ') + cl, parent=self.iface.mapCanvas()) localProgress.step() self.abstractDb.snapLinesToFrame([processTableName], frameTableName, tol, geometryColumn, keyColumn, frameGeometryColumn) self.abstractDb.densifyFrame([processTableName], frameTableName, tol, geometryColumn, frameGeometryColumn) localProgress.step() # finalization self.postProcessSteps(processTableName, lyr) self.postProcessSteps(frameTableName, frameLyr) msg = self.tr('All features snapped to frame succesfully.') self.setStatus(msg, 1) #Finished QgsMessageLog.logMessage(msg, "DSG Tools Plugin", QgsMessageLog.CRITICAL) return 1 except Exception as e: QgsMessageLog.logMessage(':'.join(e.args), "DSG Tools Plugin", QgsMessageLog.CRITICAL) self.finishedWithError() return 0
def handleAlgorithmResults(alg, context, feedback=None, showResults=True): wrongLayers = [] if feedback is None: feedback = QgsProcessingFeedback() feedback.setProgressText( QCoreApplication.translate('Postprocessing', 'Loading resulting layers')) i = 0 for l, details in context.layersToLoadOnCompletion().items(): if feedback.isCanceled(): return False if len(context.layersToLoadOnCompletion()) > 2: # only show progress feedback if we're loading a bunch of layers feedback.setProgress( 100 * i / float(len(context.layersToLoadOnCompletion()))) try: layer = QgsProcessingUtils.mapLayerFromString(l, context) if layer is not None: if not ProcessingConfig.getSetting( ProcessingConfig.USE_FILENAME_AS_LAYER_NAME): layer.setName(details.name) style = None if details.outputName: style = RenderingStyles.getStyle(alg.id(), details.outputName) if style is None: if layer.type() == QgsMapLayer.RasterLayer: style = ProcessingConfig.getSetting( ProcessingConfig.RASTER_STYLE) else: if layer.geometryType() == QgsWkbTypes.PointGeometry: style = ProcessingConfig.getSetting( ProcessingConfig.VECTOR_POINT_STYLE) elif layer.geometryType() == QgsWkbTypes.LineGeometry: style = ProcessingConfig.getSetting( ProcessingConfig.VECTOR_LINE_STYLE) else: style = ProcessingConfig.getSetting( ProcessingConfig.VECTOR_POLYGON_STYLE) if style: layer.loadNamedStyle(style) details.project.addMapLayer( context.temporaryLayerStore().takeMapLayer(layer)) else: wrongLayers.append(str(l)) except Exception: QgsMessageLog.logMessage( QCoreApplication.translate( 'Postprocessing', "Error loading result layer:") + "\n" + traceback.format_exc(), 'Processing', QgsMessageLog.CRITICAL) wrongLayers.append(str(l)) i += 1 feedback.setProgress(100) if wrongLayers: msg = QCoreApplication.translate( 'Postprocessing', "The following layers were not correctly generated.") msg += "<ul>" + "".join(["<li>%s</li>" % lay for lay in wrongLayers]) + "</ul>" msg += QCoreApplication.translate( 'Postprocessing', "You can check the 'Log Messages Panel' in QGIS main window to find more information about the execution of the algorithm." ) feedback.reportError(msg) return len(wrongLayers) == 0
def logMessage(msg): if QgsSettings().value('PythonPlugins/GeoCoding/writeDebug'): QgsMessageLog.logMessage(msg, 'GeoCoding')
def processAlgorithm(self, parameters, context, feedback): commands = list() self.exportedLayers = {} self.preProcessInputs() # 1: Export rasters to sgrd and vectors to shp # Tables must be in dbf format. We check that. for param in self.parameterDefinitions(): if isinstance(param, ParameterRaster): if param.name( ) not in parameters or parameters[param.name()] is None: continue if parameters[param.name()].endswith('sdat'): parameters[ param.name()] = parameters[param.name()][:-4] + "sgrd" elif not parameters[param.name()].endswith('sgrd'): exportCommand = self.exportRasterLayer( parameters[param.name()]) if exportCommand is not None: commands.append(exportCommand) if isinstance(param, ParameterVector): if param.name( ) not in parameters or parameters[param.name()] is None: continue layer = QgsProcessingUtils.mapLayerFromString( parameters[param.name()], context, False) if layer: filename = dataobjects.exportVectorLayer(layer) self.exportedLayers[param.value] = filename elif not parameteres[param.name()].endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) if isinstance(param, ParameterTable): if param.name( ) not in parameters or parameters[param.name()] is None: continue table = QgsProcessingUtils.mapLayerFromString( parameters[param.name()], context, False) if table: filename = dataobjects.exportTable(table) self.exportedLayers[parameters[param.name()]] = filename elif not parameters[param.name()].endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) if isinstance(param, ParameterMultipleInput): if param.name( ) not in parameters or parameters[param.name()] is None: continue layers = param.value.split(';') if layers is None or len(layers) == 0: continue if param.datatype == dataobjects.TYPE_RASTER: for i, layerfile in enumerate(layers): if layerfile.endswith('sdat'): layerfile = param.value[:-4] + "sgrd" layers[i] = layerfile elif not layerfile.endswith('sgrd'): exportCommand = self.exportRasterLayer(layerfile) if exportCommand is not None: commands.append(exportCommand) param.value = ";".join(layers) elif param.datatype in [ dataobjects.TYPE_VECTOR_ANY, dataobjects.TYPE_VECTOR_LINE, dataobjects.TYPE_VECTOR_POLYGON, dataobjects.TYPE_VECTOR_POINT ]: for layerfile in layers: layer = QgsProcessingUtils.mapLayerFromString( layerfile, context, False) if layer: filename = dataobjects.exportVectorLayer(layer) self.exportedLayers[layerfile] = filename elif not layerfile.endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) # TODO - set minimum extent if not extent: extent = QgsProcessingUtils.combineLayerExtents([layer]) # 2: Set parameters and outputs command = self.undecoratedGroup + ' "' + self.cmdname + '"' command += ' ' + ' '.join(self.hardcodedStrings) for param in self.parameterDefinitions(): if not param.name() in parameters or parameters[ param.name()] is None: continue if isinstance(param, (ParameterRaster, ParameterVector, ParameterTable)): value = parameters[param.name()] if value in list(self.exportedLayers.keys()): command += ' -' + param.name() + ' "' \ + self.exportedLayers[value] + '"' else: command += ' -' + param.name() + ' "' + value + '"' elif isinstance(param, ParameterMultipleInput): s = parameters[param.name()] for layer in list(self.exportedLayers.keys()): s = s.replace(layer, self.exportedLayers[layer]) command += ' -' + param.name() + ' "' + s + '"' elif isinstance(param, ParameterBoolean): if parameters[param.name()]: command += ' -' + param.name().strip() + " true" else: command += ' -' + param.name().strip() + " false" elif isinstance(param, ParameterFixedTable): tempTableFile = getTempFilename('txt') with open(tempTableFile, 'w') as f: f.write('\t'.join([col for col in param.cols]) + '\n') values = parameters[param.name()].split(',') for i in range(0, len(values), 3): s = values[i] + '\t' + values[i + 1] + '\t' + values[ i + 2] + '\n' f.write(s) command += ' -' + param.name() + ' "' + tempTableFile + '"' elif isinstance(param, ParameterExtent): # 'We have to substract/add half cell size, since SAGA is # center based, not corner based halfcell = self.getOutputCellsize(parameters) / 2 offset = [halfcell, -halfcell, halfcell, -halfcell] values = parameters[param.name()].split(',') for i in range(4): command += ' -' + self.extentParamNames[i] + ' ' \ + str(float(values[i]) + offset[i]) elif isinstance(param, (ParameterNumber, ParameterSelection)): command += ' -' + param.name() + ' ' + str(param.value) else: command += ' -' + param.name() + ' "' + str(param.value) + '"' for out in self.outputs: command += ' -' + out.name + ' "' + out.getCompatibleFileName( self) + '"' commands.append(command) # special treatment for RGB algorithm # TODO: improve this and put this code somewhere else for out in self.outputs: if isinstance(out, OutputRaster): filename = out.getCompatibleFileName(self) filename2 = filename + '.sgrd' if self.cmdname == 'RGB Composite': commands.append('io_grid_image 0 -IS_RGB -GRID:"' + filename2 + '" -FILE:"' + filename + '"') # 3: Run SAGA commands = self.editCommands(commands) SagaUtils.createSagaBatchJobFileFromSagaCommands(commands) loglines = [] loglines.append(self.tr('SAGA execution commands')) for line in commands: feedback.pushCommandInfo(line) loglines.append(line) if ProcessingConfig.getSetting(SagaUtils.SAGA_LOG_COMMANDS): QgsMessageLog.logMessage('\n'.join(loglines), self.tr('Processing'), QgsMessageLog.INFO) SagaUtils.executeSaga(feedback) if self.crs is not None: for out in self.outputs: if isinstance(out, (OutputVector, OutputRaster)): prjFile = os.path.splitext( out.getCompatibleFileName(self))[0] + ".prj" with open(prjFile, "w") as f: f.write(self.crs.toWkt())
def processAlgorithm(self, context, feedback): layer = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.INPUT_VECTOR), context) startPoints = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.START_POINTS), context) endPoint = self.getParameterValue(self.END_POINT) strategy = self.getParameterValue(self.STRATEGY) directionFieldName = self.getParameterValue(self.DIRECTION_FIELD) forwardValue = self.getParameterValue(self.VALUE_FORWARD) backwardValue = self.getParameterValue(self.VALUE_BACKWARD) bothValue = self.getParameterValue(self.VALUE_BOTH) defaultDirection = self.getParameterValue(self.DEFAULT_DIRECTION) bothValue = self.getParameterValue(self.VALUE_BOTH) defaultDirection = self.getParameterValue(self.DEFAULT_DIRECTION) speedFieldName = self.getParameterValue(self.SPEED_FIELD) defaultSpeed = self.getParameterValue(self.DEFAULT_SPEED) tolerance = self.getParameterValue(self.TOLERANCE) fields = QgsFields() fields.append(QgsField('start', QVariant.String, '', 254, 0)) fields.append(QgsField('end', QVariant.String, '', 254, 0)) fields.append(QgsField('cost', QVariant.Double, '', 20, 7)) feat = QgsFeature() feat.setFields(fields) writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter( fields, QgsWkbTypes.LineString, layer.crs(), context) tmp = endPoint.split(',') endPoint = QgsPoint(float(tmp[0]), float(tmp[1])) directionField = -1 if directionFieldName is not None: directionField = layer.fields().lookupField(directionFieldName) speedField = -1 if speedFieldName is not None: speedField = layer.fields().lookupField(speedFieldName) director = QgsVectorLayerDirector(layer, directionField, forwardValue, backwardValue, bothValue, defaultDirection) distUnit = iface.mapCanvas().mapSettings().destinationCrs().mapUnits() multiplier = QgsUnitTypes.fromUnitToUnitFactor( distUnit, QgsUnitTypes.DistanceMeters) if strategy == 0: strategy = QgsNetworkDistanceStrategy() else: strategy = QgsNetworkSpeedStrategy(speedField, defaultSpeed, multiplier * 1000.0 / 3600.0) multiplier = 3600 director.addStrategy(strategy) builder = QgsGraphBuilder( iface.mapCanvas().mapSettings().destinationCrs(), True, tolerance) feedback.pushInfo(self.tr('Loading start points...')) request = QgsFeatureRequest() request.setFlags(request.flags() ^ QgsFeatureRequest.SubsetOfAttributes) features = QgsProcessingUtils.getFeatures(startPoints, context, request) count = QgsProcessingUtils.featureCount(startPoints, context) points = [endPoint] for f in features: points.append(f.geometry().asPoint()) feedback.pushInfo(self.tr('Building graph...')) snappedPoints = director.makeGraph(builder, points) feedback.pushInfo(self.tr('Calculating shortest paths...')) graph = builder.graph() idxEnd = graph.findVertex(snappedPoints[0]) route = [] total = 100.0 / count for i in range(1, count + 1): idxStart = graph.findVertex(snappedPoints[i]) tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 0) if tree[idxEnd] == -1: msg = self.tr( 'There is no route from start point ({}) to end point ({}).' .format(points[i].toString(), endPoint.toString())) feedback.setProgressText(msg) QgsMessageLog.logMessage(msg, self.tr('Processing'), QgsMessageLog.WARNING) continue cost = 0.0 current = idxEnd while current != idxStart: cost += graph.edge(tree[current]).cost(0) route.append( graph.vertex(graph.edge(tree[current]).inVertex()).point()) current = graph.edge(tree[current]).outVertex() route.append(snappedPoints[i]) route.reverse() geom = QgsGeometry.fromPolyline(route) feat.setGeometry(geom) feat['start'] = points[i].toString() feat['end'] = endPoint.toString() feat['cost'] = cost / multiplier writer.addFeature(feat) route[:] = [] feedback.setProgress(int(i * total)) del writer
def export_baskets(self): java_home_set = self.java_dependency.set_java_home() if not java_home_set: message_java = QCoreApplication.translate( "BasketExporter", """Configuring Java {}...""").format(JAVA_REQUIRED_VERSION) self.logger.status(message_java) self.java_dependency.get_java_on_demand() return self.base_configuration = BaseConfiguration() self.ilicache = IliCache(self.base_configuration) self.ilicache.refresh() db_factory = self._dbs_supported.get_db_factory(self._db.engine) self.configuration = ExportConfiguration() db_factory.set_ili2db_configuration_params(self._db.dict_conn_params, self.configuration) self.configuration.with_exporttid = True full_java_exe_path = JavaDependency.get_full_java_exe_path() if full_java_exe_path: self.base_configuration.java_path = full_java_exe_path # Check custom model directories if QSettings().value( 'Asistente-LADM-COL/models/custom_model_directories_is_checked', DEFAULT_USE_CUSTOM_MODELS, type=bool): custom_model_directories = QSettings().value( 'Asistente-LADM-COL/models/custom_models', DEFAULT_MODELS_DIR) if not custom_model_directories: self.base_configuration.custom_model_directories_enabled = False else: self.base_configuration.custom_model_directories = custom_model_directories self.base_configuration.custom_model_directories_enabled = True self.configuration.base_configuration = self.base_configuration if self.get_ili_models(): self.configuration.ilimodels = ';'.join(self.get_ili_models()) self.exporter = iliexporter.Exporter() self.exporter.tool = db_factory.get_model_baker_db_ili_mode() self.exporter.process_started.connect(self.on_process_started) self.exporter.stderr.connect(self.on_stderr) #self.exporter.process_finished.connect(self.on_process_finished) res = dict() count = 0 total = len(self._basket_dict) with OverrideCursor(Qt.WaitCursor): for basket, name in self._basket_dict.items(): self.log = '' self.configuration.xtffile = os.path.join( self._export_dir, "{}.xtf".format(name)) self.configuration.baskets = basket self.exporter.configuration = self.configuration try: if self.exporter.run() != iliexporter.Exporter.SUCCESS: msg = QCoreApplication.translate( "BasketExporter", "An error occurred when exporting the data for '{}' (check the QGIS log panel)." ).format(name) res[basket] = (False, msg) QgsMessageLog.logMessage( self.log, QCoreApplication.translate( "BasketExporter", "Allocate to coordinators"), Qgis.Critical) else: res[basket] = (True, QCoreApplication.translate( "BasketExporter", "XTF export for '{}' successful!"). format(name)) except JavaNotFoundError: msg = QCoreApplication.translate( "BasketExporter", "Java {} could not be found. You can configure the JAVA_HOME environment variable manually, restart QGIS and try again." ).format(JAVA_REQUIRED_VERSION) res[basket] = (False, msg) count += 1 self.total_progress_updated.emit(count / total * 100) return res