def test_create_layer(self): """Test create layer work""" # Lines line_layer = QgsVectorLayer( self.line_before + '.shp', 'test', 'ogr') new_layer = create_layer(line_layer) self.assertEquals(new_layer.geometryType(), line_layer.geometryType()) self.assertEquals(new_layer.crs(), line_layer.crs()) fields = line_layer.dataProvider().fields() new_fields = new_layer.dataProvider().fields() self.assertEquals(new_fields.toList(), fields.toList()) # Polygon polygon_layer = QgsVectorLayer( self.polygon_base + '.shp', 'test', 'ogr') new_layer = create_layer(polygon_layer) self.assertEquals( new_layer.geometryType(), polygon_layer.geometryType() ) self.assertEquals(new_layer.crs(), polygon_layer.crs()) fields = polygon_layer.dataProvider().fields() new_fields = new_layer.dataProvider().fields() self.assertEquals(new_fields.toList(), fields.toList())
def testLayerGeometry(self): layer = QgsVectorLayer("Point", "test", "memory") myMessage = "Expected: %s\nGot: %s\n" % (QGis.Point, layer.geometryType()) assert layer.geometryType() == QGis.Point, myMessage myMessage = "Expected: %s\nGot: %s\n" % (QGis.WKBPoint, layer.wkbType()) assert layer.wkbType() == QGis.WKBPoint, myMessage
def create_grid(size): """Create a polygonal grid using Processing. :param size: The cell size. :type size: int :return: The grid layer in memory. :rtype: QgsVectorLayer """ output_filename = unique_filename(prefix='grid', suffix='.shp') result = processing.runalg( 'qgis:vectorgrid', '336199.970553,352338.397991,7636164.67975,7648562.41208', size, # X spacing size, # Y spacing 0, # Output as polygons output_filename) layer = QgsVectorLayer(output_filename, 'grid', 'ogr') layer.setCrs(QgsCoordinateReferenceSystem(32740)) remove_fields(layer, ['xmin', 'xmax', 'ymin', 'ymax']) # Make a copy in memory memory = create_memory_layer( 'grid', layer.geometryType(), layer.crs(), layer.fields()) copy_layer(layer, memory) print "NB cells : %s" % layer.featureCount() return memory
def load_loss_layer(self, loss_layer_path): # Load loss layer if self.loss_layer_is_vector: loss_layer = QgsVectorLayer(loss_layer_path, tr('Loss map'), 'ogr') if not loss_layer.geometryType() == QGis.Point: msg = 'Loss map must contain points' self.iface.messageBar().pushMessage( tr("Error"), tr(msg), level=QgsMessageBar.CRITICAL) return False else: loss_layer = QgsRasterLayer(loss_layer_path, tr('Loss map')) # Add loss layer to registry if loss_layer.isValid(): QgsMapLayerRegistry.instance().addMapLayer(loss_layer) else: msg = 'Invalid loss map' self.iface.messageBar().pushMessage( tr("Error"), tr(msg), level=QgsMessageBar.CRITICAL) return None # Zoom depending on the zonal layer's extent return loss_layer
def load(fileName, name=None, crs=None, style=None): """Loads a layer/table into the current project, given its file. """ if fileName is None: return prjSetting = None settings = QSettings() if crs is not None: prjSetting = settings.value('/Projections/defaultBehaviour') settings.setValue('/Projections/defaultBehaviour', '') if name is None: name = os.path.split(fileName)[1] qgslayer = QgsVectorLayer(fileName, name, 'ogr') if qgslayer.isValid(): if crs is not None and qgslayer.crs() is None: qgslayer.setCrs(crs, False) if style is None: if qgslayer.geometryType() == QGis.Point: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_POINT_STYLE) elif qgslayer.geometryType() == QGis.Line: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_LINE_STYLE) else: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_POLYGON_STYLE) qgslayer.loadNamedStyle(style) QgsMapLayerRegistry.instance().addMapLayers([qgslayer]) else: qgslayer = QgsRasterLayer(fileName, name) if qgslayer.isValid(): if crs is not None and qgslayer.crs() is None: qgslayer.setCrs(crs, False) if style is None: style = ProcessingConfig.getSetting(ProcessingConfig.RASTER_STYLE) qgslayer.loadNamedStyle(style) QgsMapLayerRegistry.instance().addMapLayers([qgslayer]) iface.legendInterface().refreshLayerSymbology(qgslayer) else: if prjSetting: settings.setValue('/Projections/defaultBehaviour', prjSetting) raise RuntimeError('Could not load layer: ' + unicode(fileName) + '\nCheck the procesing framework log to look for errors') if prjSetting: settings.setValue('/Projections/defaultBehaviour', prjSetting) return qgslayer
def testLayerGeometry(self): testVectors = [("Point", QGis.Point, QGis.WKBPoint), ("LineString", QGis.Line, QGis.WKBLineString), ("Polygon", QGis.Polygon, QGis.WKBPolygon), ("MultiPoint", QGis.Point, QGis.WKBMultiPoint), ("MultiLineString", QGis.Line, QGis.WKBMultiLineString), ("MultiPolygon", QGis.Polygon, QGis.WKBMultiPolygon), ("None", QGis.NoGeometry, QGis.WKBNoGeometry)] for v in testVectors: layer = QgsVectorLayer(v[0], "test", "memory") myMessage = ('Expected: %s\nGot: %s\n' % (v[1], layer.geometryType())) assert layer.geometryType() == v[1], myMessage myMessage = ('Expected: %s\nGot: %s\n' % (v[2], layer.wkbType())) assert layer.wkbType() == v[2], myMessage
def testLayerGeometry(self): testVectors = [("Point", QgsWkbTypes.PointGeometry, QgsWkbTypes.Point), ("LineString", QgsWkbTypes.LineGeometry, QgsWkbTypes.LineString), ("Polygon", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.Polygon), ("MultiPoint", QgsWkbTypes.PointGeometry, QgsWkbTypes.MultiPoint), ("MultiLineString", QgsWkbTypes.LineGeometry, QgsWkbTypes.MultiLineString), ("MultiPolygon", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.MultiPolygon), ("PointZ", QgsWkbTypes.PointGeometry, QgsWkbTypes.PointZ), ("LineStringZ", QgsWkbTypes.LineGeometry, QgsWkbTypes.LineStringZ), ("PolygonZ", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.PolygonZ), ("MultiPointZ", QgsWkbTypes.PointGeometry, QgsWkbTypes.MultiPointZ), ("MultiLineStringZ", QgsWkbTypes.LineGeometry, QgsWkbTypes.MultiLineStringZ), ("MultiPolygonZ", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.MultiPolygonZ), ("PointM", QgsWkbTypes.PointGeometry, QgsWkbTypes.PointM), ("LineStringM", QgsWkbTypes.LineGeometry, QgsWkbTypes.LineStringM), ("PolygonM", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.PolygonM), ("MultiPointM", QgsWkbTypes.PointGeometry, QgsWkbTypes.MultiPointM), ("MultiLineStringM", QgsWkbTypes.LineGeometry, QgsWkbTypes.MultiLineStringM), ("MultiPolygonM", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.MultiPolygonM), ("PointZM", QgsWkbTypes.PointGeometry, QgsWkbTypes.PointZM), ("LineStringZM", QgsWkbTypes.LineGeometry, QgsWkbTypes.LineStringZM), ("PolygonZM", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.PolygonZM), ("MultiPointZM", QgsWkbTypes.PointGeometry, QgsWkbTypes.MultiPointZM), ("MultiLineStringZM", QgsWkbTypes.LineGeometry, QgsWkbTypes.MultiLineStringZM), ("MultiPolygonZM", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.MultiPolygonZM), ("Point25D", QgsWkbTypes.PointGeometry, QgsWkbTypes.Point25D), ("LineString25D", QgsWkbTypes.LineGeometry, QgsWkbTypes.LineString25D), ("Polygon25D", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.Polygon25D), ("MultiPoint25D", QgsWkbTypes.PointGeometry, QgsWkbTypes.MultiPoint25D), ("MultiLineString25D", QgsWkbTypes.LineGeometry, QgsWkbTypes.MultiLineString25D), ("MultiPolygon25D", QgsWkbTypes.PolygonGeometry, QgsWkbTypes.MultiPolygon25D), ("None", QgsWkbTypes.NullGeometry, QgsWkbTypes.NoGeometry)] for v in testVectors: layer = QgsVectorLayer(v[0], "test", "pythonprovider") myMessage = ('Expected: %s\nGot: %s\n' % (v[1], layer.geometryType())) assert layer.geometryType() == v[1], myMessage myMessage = ('Expected: %s\nGot: %s\n' % (v[2], layer.wkbType())) assert layer.wkbType() == v[2], myMessage
def loadData(self, resultFile, chunkId): """ Load data to the map """ if isMimeTypeVector(self.mimeType, True) != None: # Memory layer: geometryTypes = ["Point","LineString","Polygon","Unknown", "NoGeometry"] vlayer = QgsVectorLayer(resultFile, "chunk", "ogr") if self.__bFirstChunk: self.__bFirstChunk = False self.__geometryType = geometryTypes[vlayer.geometryType()] self.__bGeomMulti = vlayer.wkbType() in [4,5,6,11,12,13] self.__memoryLayer = QgsVectorLayer(self.__geometryType,"Streamed data","memory") self.__memoryLayer.dataProvider().addAttributes(vlayer.pendingFields().values()) self.__memoryLayer.updateFieldMap() provider = vlayer.dataProvider() allAttrs = provider.attributeIndexes() vlayer.select(allAttrs) # Visualize temporal geometries during the downloading process # Don't add temporal geometries if last chunk if self.DEBUG: print "Loaded chunkId:",chunkId res = self.__memoryLayer.dataProvider().addFeatures( [feat for feat in vlayer] ) self.__deliveredChunks += 1 if not self.allChunksDelivered(): inFeat = QgsFeature() inGeom = QgsGeometry() self.createTempGeometry(chunkId, self.__geometryType) while provider.nextFeature( inFeat ): inGeom = inFeat.geometry() featList = self.extractAsSingle(self.__geometryType, inGeom) if self.__bGeomMulti else [inGeom] for geom in featList: self.addTempGeometry(chunkId, self.__geometryType, geom) else: self.finishLoading() # Raster data elif isMimeTypeRaster(self.mimeType, True) != None: # We can directly attach the new layer if self.__bFirstChunk: self.__bFirstChunk = False self.__groupIndex = self.__legend.addGroup("Streamed-raster") rLayer = QgsRasterLayer(resultFile, "raster_"+str(chunkId)) bLoaded = QgsMapLayerRegistry.instance().addMapLayer(rLayer) self.stretchRaster(rLayer) self.__legend.moveLayer(rLayer, self.__groupIndex + 1) self.__deliveredChunks += 1 if self.allChunksDelivered(): self.finishLoading()
def __snap(self): self.report_message.emit(self.layer_id, 'preparing ...') orig_layer = QgsMapLayerRegistry.instance().mapLayer(self.layer_id) # create a copy of the layer just for editing layer = QgsVectorLayer(orig_layer.source(), orig_layer.name(), orig_layer.providerType()) geom_type = layer.geometryType() # layer.wkbType() does not return reliable results wkb_type = layer.wkbType() if self.create_backup: self.report_message.emit(self.layer_id, 'creating backup ...') self.__create_backup_file(orig_layer) self.report_message.emit(self.layer_id, 'preparing ...') layer.startEditing() request = QgsFeatureRequest().setFilterRect(self.snap_extent) total_features = 0 for feature in layer.getFeatures(request): total_features += 1 QgsMessageLog.logMessage(self.plugin.tr('Features to be snapped in layer <{0}>: {1}'). format(orig_layer.name(), total_features), self.plugin.tr('Vertex Tools'), QgsMessageLog.INFO) if total_features == 0: self.report_message.emit(self.layer_id, 'no features') count = 0 for feature in layer.getFeatures(request): with QMutexLocker(self.mutex): if self.stopped: layer.rollBack() return if geom_type == QGis.Point: snapped_geom = self.__point_grid(feature, wkb_type) elif geom_type == QGis.Line: snapped_geom = self.__line_grid(feature, wkb_type) elif geom_type == QGis.Polygon: snapped_geom = self.__polygon_grid(feature, wkb_type) layer.changeGeometry(feature.id(), snapped_geom) count += 1 self.run_progressed.emit(self.layer_id, count, total_features) layer.commitChanges() self.completed = True
def _get_cursor_columns(self, c): tf = QTemporaryFile() tf.open() tmp = tf.fileName() tf.close() q = QUrl.toPercentEncoding(c.sql) p = QgsVectorLayer("%s?query=%s" % (QUrl.fromLocalFile(tmp).toString(), q), "vv", "virtual") if not p.isValid(): return [] f = [f.name() for f in p.fields()] if p.geometryType() != QGis.WKBNoGeometry: gn = getQueryGeometryName(tmp) if gn: f += [gn] return f
def test_sql5(self): l2 = QgsVectorLayer( os.path.join(self.testDataDir_, "france_parts.shp"), "france_parts", "ogr", False ) self.assertEqual( l2.isValid(), True ) QgsMapLayerRegistry.instance().addMapLayer(l2) query = QUrl.toPercentEncoding( "SELECT st_union(geometry) as geom from france_parts" ) l4 = QgsVectorLayer( "?query=%s" % query, "tt", "virtual", False ) self.assertEqual( l4.isValid(), True ) # self.assertEqual( l4.dataProvider().geometryType(), 3 ) #self.assertEqual( l4.geometryType(), 2 ) query = QUrl.toPercentEncoding( "SELECT st_collect(geometry) as geom from france_parts" ) l4 = QgsVectorLayer( "?query=%s" % query, "tt", "virtual", False ) self.assertEqual( l4.isValid(), True ) self.assertEqual( l4.dataProvider().geometryType(), 0 ) self.assertEqual( l4.geometryType(), 3 ) # unknown geometry
def make_OD_markers(nb, xo, yo, xd, yd, list_coords=None): """ Prepare the Origin (green), Destination (red) and Intalternative_geometriesermediates (grey) markers. """ OD_layer = QgsVectorLayer( "Point?crs=epsg:4326&field=id_route:integer&field=role:string(80)", "markers_osrm{}".format(nb), "memory") features = [] fet = QgsFeature() fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(float(xo), float(yo)))) fet.setAttributes([nb, 'Origin']) features.append(fet) fet = QgsFeature() fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(float(xd), float(yd)))) fet.setAttributes([nb, 'Destination']) features.append(fet) marker_rules = [ ('Origin', '"role" LIKE \'Origin\'', '#50b56d', 4), ('Destination', '"role" LIKE \'Destination\'', '#d31115', 4), ] if list_coords: for i, pt in enumerate(list_coords): fet = QgsFeature() fet.setGeometry( QgsGeometry.fromPoint(QgsPoint(float(pt[0]), float(pt[1]))) ) fet.setAttributes([nb, 'Via point n°{}'.format(i)]) features.append(fet) marker_rules.insert( 1, ('Intermediate', '"role" LIKE \'Via point%\'', 'grey', 2)) OD_layer.dataProvider().addFeatures(features) symbol = QgsSymbolV2.defaultSymbol(OD_layer.geometryType()) renderer = QgsRuleBasedRendererV2(symbol) root_rule = renderer.rootRule() for label, expression, color_name, size in marker_rules: rule = root_rule.children()[0].clone() rule.setLabel(label) rule.setFilterExpression(expression) rule.symbol().setColor(QtGui.QColor(color_name)) rule.symbol().setSize(size) root_rule.appendChild(rule) root_rule.removeChildAt(0) OD_layer.setRendererV2(renderer) return OD_layer
def make_OD_markers(nb, xo, yo, xd, yd, list_coords=None): """ Prepare the Origin (green), Destination (red) and Intermediates (grey) markers. """ OD_layer = QgsVectorLayer( "Point?crs=epsg:4326&field=id_route:integer&field=role:string(80)", "markers_osrm{}".format(nb), "memory") features = [] fet = QgsFeature() fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(float(xo), float(yo)))) fet.setAttributes([nb, 'Origin']) features.append(fet) fet = QgsFeature() fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(float(xd), float(yd)))) fet.setAttributes([nb, 'Destination']) features.append(fet) marker_rules = [ ('Origin', '"role" LIKE \'Origin\'', '#50b56d', 4), ('Destination', '"role" LIKE \'Destination\'', '#d31115', 4), ] if list_coords: for i, pt in enumerate(list_coords): fet = QgsFeature() fet.setGeometry( QgsGeometry.fromPoint(QgsPoint(float(pt[0]), float(pt[1])))) fet.setAttributes([nb, 'Via point n°{}'.format(i)]) features.append(fet) marker_rules.insert( 1, ('Intermediate', '"role" LIKE \'Via point%\'', 'grey', 2)) OD_layer.dataProvider().addFeatures(features) symbol = QgsSymbolV2.defaultSymbol(OD_layer.geometryType()) renderer = QgsRuleBasedRendererV2(symbol) root_rule = renderer.rootRule() for label, expression, color_name, size in marker_rules: rule = root_rule.children()[0].clone() rule.setLabel(label) rule.setFilterExpression(expression) rule.symbol().setColor(QtGui.QColor(color_name)) rule.symbol().setSize(size) root_rule.appendChild(rule) root_rule.removeChildAt(0) OD_layer.setRendererV2(renderer) return OD_layer
def create_vtx_outofbbox_lyr(): vtx_outofbbox_lyr = QgsVectorLayer(r"Point?crs=epsg:4326&index=yes", vtx_outofbbox_lname, r"memory") p_vtx_outofbbox_lyr = vtx_outofbbox_lyr.dataProvider() QgsProject.instance().addMapLayer(vtx_outofbbox_lyr, True) # Create a simple symbol rend_symb=QgsSymbol.defaultSymbol(vtx_outofbbox_lyr.geometryType()) rend_symb.setSize(vtx_outofbbox_size) rend_symb.setColor(QColor(vtx_outofbbox_color)) rend_symb.setOpacity(vtx_outofbbox_opc) rend_vtx_outofbbox = QgsSingleSymbolRenderer(rend_symb) vtx_outofbbox_lyr.setRenderer(rend_vtx_outofbbox) p_vtx_outofbbox_lyr.addAttributes(vtx_atts) vtx_outofbbox_lyr.updateFields() # Refresh the canvas vtx_outofbbox_lyr.triggerRepaint() return vtx_outofbbox_lyr
def create_edge_outofbbox_lyr(): edge_outofbbox_lyr = QgsVectorLayer(r"LineString?crs=epsg:4326&index=yes", edge_outofbbox_lname, r"memory") p_edge_outofbbox_lyr = edge_outofbbox_lyr.dataProvider() QgsProject.instance().addMapLayer(edge_outofbbox_lyr, True) # Create a simple symbol rend_symb=QgsSymbol.defaultSymbol(edge_outofbbox_lyr.geometryType()) rend_symb.setWidth(edge_outofbbox_width) rend_symb.setColor(QColor(edge_outofbbox_color)) rend_symb.setOpacity(edge_outofbbox_opc) rend_edge_outofbbox = QgsSingleSymbolRenderer(rend_symb) edge_outofbbox_lyr.setRenderer(rend_edge_outofbbox) p_edge_outofbbox_lyr.addAttributes(edge_atts) edge_outofbbox_lyr.updateFields() # Refresh the canvas edge_outofbbox_lyr.triggerRepaint() return edge_outofbbox_lyr
def JSONGeometryFromLayer(qgsLayer: QgsVectorLayer)->str: features: QgsFeatureIterator = qgsLayer.getFeatures() geomType: QgsWkbTypes.GeometryType = qgsLayer.geometryType() ret_geom = None for feature in features: geom:QgsGeometry = QgsGeometry(feature.geometry()) if ret_geom is None: if geomType == QgsWkbTypes.Polygon: ret_geom = geom.asMultiPolygon() if geomType == QgsWkbTypes.MultiPolygon: ret_geom = geom if geomType == QgsWkbTypes.Polygon: ret_geom.addPartGeometry(geom) elif geomType == QgsWkbTypes.MultiPolygon: for i in geom.parts(): ret_geom.addPartGeometry(i) return geometry.QgsGeometrytoGeoJSON(ret_geom)
def onValidationSetsLoadButtonClicked(self) -> None: assert self.contentItem assert self.contentItem['ContentID'] self.contentItemFilename = tempfile.NamedTemporaryFile().name # TODO this lock is not working for some reason :/ self.loginGroupBox.setEnabled(False) self.projectsGroupBox.setEnabled(False) self.validationSetsGroupBox.setEnabled(False) self.boundaryStringsGroupBox.setEnabled(False) try: self.service.download_content_item(self.contentItem['ContentID'], self.contentItemFilename) layer = QgsVectorLayer(self.contentItemFilename, self.validationSet['Name'], 'ogr') if layer.geometryType() != QgsWkbTypes.LineGeometry: utils.show_info( __('Validation set file is not with line geometries')) return utils.add_layer(layer, self.validationSet['Name'], parent=utils.get_group(), index=0) layer = self.plugin.setSegmentsLayer( layer, name=self.validationSet['Name']) if layer: # TODO the ugliest thing in the whole project self.plugin.dockWidget.segmentsLayerComboBox.setLayer(layer) except Its4landException as e: if e.code == 404: utils.show_info( __('Unable to load the selected validation set, check the web interface for more information' )) return else: raise e finally: self.loginGroupBox.setEnabled(True) self.projectsGroupBox.setEnabled(True) self.validationSetsGroupBox.setEnabled(True) self.boundaryStringsGroupBox.setEnabled(True)
def _get_cursor_columns(self, c): tf = QTemporaryFile() tf.open() tmp = tf.fileName() tf.close() q = QUrl.toPercentEncoding(c.sql) p = QgsVectorLayer( "%s?query=%s" % (QUrl.fromLocalFile(tmp).toString(), q), "vv", "virtual") if not p.isValid(): return [] f = [f.name() for f in p.fields()] if p.geometryType() != QgsWkbTypes.NullGeometry: gn = getQueryGeometryName(tmp) if gn: f += [gn] return f
def _get_cursor_columns(self, c): tf = QTemporaryFile() tf.open() tmp = tf.fileName() tf.close() df = QgsVirtualLayerDefinition() df.setFilePath(tmp) df.setQuery(c.sql) p = QgsVectorLayer(df.toString(), "vv", "virtual") if not p.isValid(): return [] f = [f.name() for f in p.fields()] if p.geometryType() != QgsWkbTypes.NullGeometry: gn = getQueryGeometryName(tmp) if gn: f += [gn] return f
def newDatasourceIsValid(self, layer, newDS): """ Probe new datasource to prevent layer issues """ ds, uri = self.splitSource(newDS) if not ds: # if datasource type is not specified uri is probed with current one ds = layer.dataProvider().name() nlayer = QgsVectorLayer(uri, "probe", ds) if not nlayer.isValid(): self.iface.messageBar().pushMessage("Error", "incorrect source|uri string: " + newDS, level=Qgis.Critical, duration=4) self.updateLog("\nERROR: incorrect source|uri string: " + newDS) return None if nlayer.geometryType() != layer.geometryType(): self.iface.messageBar().pushMessage("Error", "geometry type mismatch on new datasource: " + newDS, level=Qgis.Critical, duration=4) self.updateLog("\nERROR: geometry type mismatch on new datasource: " + newDS) return None return True
def getShapesByGeometryType(baseDir, inShapes, geomType): outShapes = [] for fileName in inShapes: layerPath = QFileInfo(baseDir + "/" + fileName).absoluteFilePath() vLayer = QgsVectorLayer(layerPath, QFileInfo(layerPath).baseName(), "ogr") if not vLayer.isValid(): continue layerGeometry = vLayer.geometryType() if layerGeometry == QGis.Polygon and geomType == 0: outShapes.append(fileName) elif layerGeometry == QGis.Line and geomType == 1: outShapes.append(fileName) elif layerGeometry == QGis.Point and geomType == 2: outShapes.append(fileName) if len(outShapes) == 0: return None return outShapes
def __init__(self, db, sql, parent=None): # create a virtual layer with non-geometry results t = QTime() t.start() tf = QTemporaryFile() tf.open() tmp = tf.fileName() tf.close() df = QgsVirtualLayerDefinition() df.setFilePath(tmp) df.setQuery(sql) p = QgsVectorLayer(df.toString(), "vv", "virtual") self._secs = t.elapsed() / 1000.0 if not p.isValid(): data = [] header = [] raise DbError(p.dataProvider().error().summary(), sql) else: header = [f.name() for f in p.fields()] has_geometry = False if p.geometryType() != QgsWkbTypes.NullGeometry: gn = getQueryGeometryName(tmp) if gn: has_geometry = True header += [gn] data = [] for f in p.getFeatures(): a = f.attributes() if has_geometry: if f.hasGeometry(): a += [f.geometry().exportToWkt()] else: a += [None] data += [a] self._secs = 0 self._affectedRows = len(data) BaseTableModel.__init__(self, header, data, parent)
def __init__(self, db, sql, parent=None, layer=None, path=None): t = QTime() t.start() if not layer: tf = QTemporaryFile() tf.open() path = tf.fileName() tf.close() df = QgsVirtualLayerDefinition() df.setFilePath(path) df.setQuery(sql) layer = QgsVectorLayer(df.toString(), "vv", "virtual") self._secs = t.elapsed() / 1000.0 data = [] header = [] if not layer.isValid(): raise DbError(layer.dataProvider().error().summary(), sql) else: header = [f.name() for f in layer.fields()] has_geometry = False if layer.geometryType() != QgsWkbTypes.NullGeometry: gn = getQueryGeometryName(path) if gn: has_geometry = True header += [gn] for f in layer.getFeatures(): a = f.attributes() if has_geometry: if f.hasGeometry(): a += [f.geometry().asWkt()] else: a += [None] data += [a] self._secs = 0 self._affectedRows = len(data) BaseTableModel.__init__(self, header, data, parent)
def load_loss_layer(self, loss_layer_path): # Load loss layer if self.loss_layer_is_vector: loss_layer = QgsVectorLayer(loss_layer_path, tr('Loss map'), 'ogr') if not loss_layer.geometryType() == QGis.Point: msg = 'Loss map must contain points' log_msg(msg, level='C', message_bar=self.iface.messageBar()) return False else: loss_layer = QgsRasterLayer(loss_layer_path, tr('Loss map')) # Add loss layer to registry if loss_layer.isValid(): QgsMapLayerRegistry.instance().addMapLayer(loss_layer) else: msg = 'Invalid loss map' log_msg(msg, level='C', message_bar=self.iface.messageBar()) return None # Zoom depending on the zonal layer's extent return loss_layer
def __init__(self, db, sql, parent=None): # create a virtual layer with non-geometry results q = QUrl.toPercentEncoding(sql) t = QTime() t.start() tf = QTemporaryFile() tf.open() tmp = tf.fileName() tf.close() p = QgsVectorLayer( "%s?query=%s" % (QUrl.fromLocalFile(tmp).toString(), q), "vv", "virtual") self._secs = t.elapsed() / 1000.0 if not p.isValid(): data = [] header = [] raise DbError(p.dataProvider().error().summary(), sql) else: header = [f.name() for f in p.fields()] has_geometry = False if p.geometryType() != QGis.WKBNoGeometry: gn = getQueryGeometryName(tmp) if gn: has_geometry = True header += [gn] data = [] for f in p.getFeatures(): a = f.attributes() if has_geometry: if f.geometry(): a += [f.geometry().exportToWkt()] else: a += [None] data += [a] self._secs = 0 self._affectedRows = len(data) BaseTableModel.__init__(self, header, data, parent)
def test_sql5(self): l2 = QgsVectorLayer( os.path.join(self.testDataDir_, "france_parts.shp"), "france_parts", "ogr", False) self.assertEqual(l2.isValid(), True) QgsMapLayerRegistry.instance().addMapLayer(l2) query = QUrl.toPercentEncoding( "SELECT st_union(geometry) as geom from france_parts") l4 = QgsVectorLayer("?query=%s" % query, "tt", "virtual", False) self.assertEqual(l4.isValid(), True) # self.assertEqual( l4.dataProvider().geometryType(), 3 ) #self.assertEqual( l4.geometryType(), 2 ) query = QUrl.toPercentEncoding( "SELECT st_collect(geometry) as geom from france_parts") l4 = QgsVectorLayer("?query=%s" % query, "tt", "virtual", False) self.assertEqual(l4.isValid(), True) self.assertEqual(l4.dataProvider().geometryType(), 0) self.assertEqual(l4.geometryType(), 3) # unknown geometry
def is_valid_polygon_selection(layer: QgsVectorLayer) -> bool: """"Checks if the layer type is polygon and if anything is selected.""" if layer.geometryType() != QgsWkbTypes.PolygonGeometry: msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("Unsupported layer type!") msg.setInformativeText("Please select polygon layer.") msg.setWindowTitle("Info") msg.setStandardButtons(QMessageBox.Ok) msg.exec_() return False if not layer.selectedFeatures(): msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("Please select at least one feature!") msg.setWindowTitle("Info") msg.setStandardButtons(QMessageBox.Ok) msg.exec_() return False return True
def __init__(self, db, sql, parent=None): # create a virtual layer with non-geometry results q = QUrl.toPercentEncoding(sql) t = QTime() t.start() tf = QTemporaryFile() tf.open() tmp = tf.fileName() tf.close() p = QgsVectorLayer("%s?query=%s" % (QUrl.fromLocalFile(tmp).toString(), q), "vv", "virtual") self._secs = t.elapsed() / 1000.0 if not p.isValid(): data = [] header = [] raise DbError(p.dataProvider().error().summary(), sql) else: header = [f.name() for f in p.fields()] has_geometry = False if p.geometryType() != QGis.WKBNoGeometry: gn = getQueryGeometryName(tmp) if gn: has_geometry = True header += [gn] data = [] for f in p.getFeatures(): a = f.attributes() if has_geometry: if f.geometry(): a += [f.geometry().exportToWkt()] else: a += [None] data += [a] self._secs = 0 self._affectedRows = len(data) BaseTableModel.__init__(self, header, data, parent)
def load_zonal_layer(self, zonal_layer_path): # Load zonal layer zonal_layer = QgsVectorLayer(zonal_layer_path, tr('Zonal data'), 'ogr') if not zonal_layer.geometryType() == QGis.Polygon: msg = 'Zonal layer must contain zone polygons' self.iface.messageBar().pushMessage( tr("Error"), tr(msg), level=QgsMessageBar.CRITICAL) return False # Add zonal layer to registry if zonal_layer.isValid(): QgsMapLayerRegistry.instance().addMapLayer(zonal_layer) else: msg = 'Invalid zonal layer' self.iface.messageBar().pushMessage( tr("Error"), tr(msg), level=QgsMessageBar.CRITICAL) return None return zonal_layer
def load_zonal_layer(self, zonal_layer_path, make_a_copy=False): # Load zonal layer zonal_layer = QgsVectorLayer(zonal_layer_path, tr('Zonal data'), 'ogr') if not zonal_layer.geometryType() == QGis.Polygon: msg = 'Zonal layer must contain zone polygons' log_msg(msg, level='C', message_bar=self.iface.messageBar()) return False if make_a_copy: # Make a copy, where stats will be added zonal_layer_plus_stats = ProcessLayer( zonal_layer).duplicate_in_memory() else: zonal_layer_plus_stats = zonal_layer # Add zonal layer to registry if zonal_layer_plus_stats.isValid(): QgsMapLayerRegistry.instance().addMapLayer(zonal_layer_plus_stats) else: msg = 'Invalid zonal layer' log_msg(msg, level='C', message_bar=self.iface.messageBar()) return None return zonal_layer_plus_stats
def load_unloaded_data(project_path): operators_path = join(project_path, PROJECT_GROUP[2]) try: operators_content = get_elements_name(operators_path, True, None) except FileNotFoundError: return qgis_groups = get_group() for i_op, item in enumerate(operators_content): # load vectors shp_path = join(operators_path, item, 'SHP') for shp_file in glob.glob(join(shp_path, '*.shp')): layer_name = basename(shp_file).replace(".shp", "") layer = QgsVectorLayer(shp_file, layer_name, "ogr") if layer.geometryType() == 1: try: if layer_name not in get_layers_in_group(PROJECT_GROUP[2]): add_layer_in_group( layer, qgis_groups.findGroup(PROJECT_GROUP[2]), i_op, 'line_style.qml') except TypeError: return else: try: if layer_name not in get_layers_in_group('BUF'): add_layer_in_group(layer, qgis_groups.findGroup('BUF'), i_op, 'buffer_style.qml') except TypeError: return # load raster tif_path = join(operators_path, item, 'TIF') for i_tif, tif_file in enumerate(glob.glob(join(tif_path, '*.tif'))): raster_name = basename(tif_file).replace(".tif", "") raster = QgsRasterLayer(tif_file, raster_name, 'gdal') if raster_name not in get_layers_in_group(item): add_layer_in_group(raster, qgis_groups.findGroup(item), i_tif, None)
def sample_layer(self): source_layer = QgsVectorLayer( os.path.join(self.plugin_dir, "data", "Austria_PopulationByNUTS2.gml"), "" ) # (empty) memory layer sample_layer = QgsVectorLayer( QgsWkbTypes.geometryDisplayString(source_layer.geometryType()) + "?crs=" + source_layer.crs().authid() + "&index=yes", "Austria_Population_NUTS2_20170101", "memory" ) sample_layer_data_provider = sample_layer.dataProvider() sample_layer_data_provider.addAttributes(source_layer.fields().toList()) sample_layer.updateFields() sample_layer_data_provider.addFeatures(list(source_layer.getFeatures())) sample_layer.loadNamedStyle( os.path.join(self.plugin_dir, "data", "Austria_PopulationByNUTS2.qml") ) sample_layer.setTitle("Austria: Population by NUTS2 regions, 1 Jan 2017") sample_layer.setShortName("Austria_Population_NUTS2_20170101") sample_layer.setAbstract( "Austria’s population by NUTS2 region, as of 1 Jan 2017 \n" + "\n" + "Data sources: \n" + " http://ec.europa.eu/eurostat/web/gisco/geodata/" + "reference-data/administrative-units-statistical-units/" + "nuts#nuts13 \n" + " http://www.statistik.at/web_de/statistiken/" + "menschen_und_gesellschaft/bevoelkerung/" + "bevoelkerungsstand_und_veraenderung/" + "bevoelkerung_zu_jahres-_quartalsanfang/index.html" ) return sample_layer
def checkShapefile(createDialog): shapefileOKBool = True if createDialog.puLineEdit.text() == '': warningMessage('Shapefile error', 'No shapefile was specified.') shapefileOKBool = False if shapefileOKBool: puLayer = QgsVectorLayer(createDialog.puLineEdit.text(), 'Shapefile', 'ogr') layerGeomType = puLayer.geometryType() puProvider = puLayer.dataProvider() puIdFieldOrder = puProvider.fieldNameIndex('Unit_ID') puCostFieldOrder = puProvider.fieldNameIndex('Area') puAreaFieldOrder = puProvider.fieldNameIndex('Cost') puStatusFieldOrder = puProvider.fieldNameIndex('Status') if layerGeomType != 2: warningMessage('Incorrect format', 'The specified shapefile is not a polygon layer.') shapefileOKBool = False if puIdFieldOrder != -1 or puCostFieldOrder != -1 or puAreaFieldOrder != -1 or puStatusFieldOrder != -1: warningMessage('Incorrect format', 'The specified shapefile cannot contain fields named Unit_ID, Area, Cost or Status as these will be created here. Please remove/rename these fields and try again.') shapefileOKBool = False return shapefileOKBool
def addDiffLayer(repo, layername, commit): styles = [diffStylePoints, diffStyleLines, diffStylePolygons] geomTypes = ["Point","LineString","Polygon"] beforeFilename = tempFilename("gpkg") repo.exportdiff(layername, commit.commitid, commit.parent.commitid, beforeFilename) beforeLayer = loadLayerNoCrsDialog(beforeFilename, layername, "ogr") afterFilename = tempFilename("gpkg") repo.exportdiff(layername, commit.parent.commitid, commit.commitid, afterFilename) afterLayer = loadLayerNoCrsDialog(afterFilename, layername, "ogr") beforeCon = sqlite3.connect(beforeFilename) beforeCursor = beforeCon.cursor() afterCon = sqlite3.connect(afterFilename) afterCursor = afterCon.cursor() attributes = [v[1] for v in beforeCursor.execute("PRAGMA table_info('%s');" % layername)] attrnames = [f.name() for f in beforeLayer.pendingFields()] layerFeatures = [] beforeCursor.execute("SELECT * FROM %s_changes WHERE audit_op=2;" % layername) modified = beforeCursor.fetchall() for m in modified: geogigfid = m[0] beforeGpkgfid = gpkgfidFromGeogigfid(beforeCursor, layername, geogigfid) beforeCursor.execute("SELECT * FROM %s WHERE fid='%s';" % (layername, beforeGpkgfid)) featureRow = beforeCursor.fetchone() attrs = {attr: featureRow[attributes.index(attr)] for attr in attrnames} attrs["changetype"] = MODIFIED_BEFORE request = QgsFeatureRequest() request.setFilterFid(beforeGpkgfid) feature = next(beforeLayer.getFeatures(request)) layerFeatures.append({"attrs":attrs, "geom": QgsGeometry(feature.geometry())}) afterGpkgfid = gpkgfidFromGeogigfid(afterCursor, layername, geogigfid) afterCursor.execute("SELECT * FROM %s WHERE fid='%s';" % (layername,afterGpkgfid)) featureRow = afterCursor.fetchone() attrs = {attr: featureRow[attributes.index(attr)] for attr in attrnames} attrs["changetype"] = MODIFIED_AFTER request = QgsFeatureRequest() request.setFilterFid(beforeGpkgfid) feature = next(afterLayer.getFeatures(request)) layerFeatures.append({"attrs":attrs, "geom": QgsGeometry(feature.geometry())}) afterCursor.execute("SELECT * FROM %s_changes WHERE audit_op=1;" % layername) added = afterCursor.fetchall() for a in added: geogigfid = a[0] afterGpkgfid = gpkgfidFromGeogigfid(afterCursor, layername, geogigfid) afterCursor.execute("SELECT * FROM %s WHERE fid='%s';" % (layername, afterGpkgfid)) featureRow = afterCursor.fetchone() attrs = {attr: featureRow[attributes.index(attr)] for attr in attrnames} attrs["changetype"] = ADDED request = QgsFeatureRequest() request.setFilterFid(afterGpkgfid) feature = next(afterLayer.getFeatures(request)) layerFeatures.append({"attrs":attrs, "geom": QgsGeometry(feature.geometry())}) beforeCursor.execute("SELECT * FROM %s_changes WHERE audit_op=1;" % layername) removed = beforeCursor.fetchall() for r in removed: geogigfid = r[0] beforeGpkgfid = gpkgfidFromGeogigfid(beforeCursor, layername, geogigfid) beforeCursor.execute("SELECT * FROM %s WHERE fid='%s';" % (layername, beforeGpkgfid)) featureRow = beforeCursor.fetchone() attrs = {attr: featureRow[attributes.index(attr)] for attr in attrnames} attrs["changetype"] = REMOVED request = QgsFeatureRequest() request.setFilterFid(beforeGpkgfid) feature = next(beforeLayer.getFeatures(request)) layerFeatures.append({"attrs":attrs, "geom": QgsGeometry(feature.geometry())}) attrnames.append("changetype") uriFields = "&".join(["field=%s" % f for f in attrnames]) uri = "%s?crs=%s&%s" % (geomTypes[beforeLayer.geometryType()], beforeLayer.crs().authid(), uriFields) layer = QgsVectorLayer(uri, "diff", "memory") featuresList = [] for feature in layerFeatures: qgsfeature = QgsFeature() qgsfeature.setGeometry(feature["geom"]) qgsfeature.setAttributes([feature["attrs"][attr] for attr in attrnames]) featuresList.append(qgsfeature) layer.dataProvider().addFeatures(featuresList) layer.updateExtents() QgsMapLayerRegistry.instance().addMapLayers([layer]) layer.loadNamedStyle(styles[layer.geometryType()])
def addDiffLayers(repo, commit, commit2, layernames): styles = [diffStylePoints, diffStyleLines, diffStylePolygons] geomTypes = ["Point","LineString","Polygon"] beforeFilename = tempFilename("gpkg") repo.exportdiff(commit.commitid, commit2.commitid, beforeFilename) afterFilename = tempFilename("gpkg") repo.exportdiff(commit2.commitid, commit.commitid, afterFilename) for layername in layernames: styles = [diffStylePoints, diffStyleLines, diffStylePolygons] geomTypes = ["Point","LineString","Polygon"] beforeLayer = loadLayerNoCrsDialog("%s|layername=%s" % (beforeFilename, layername), layername, "ogr") afterLayer = loadLayerNoCrsDialog("%s|layername=%s" % (afterFilename, layername), layername, "ogr") beforeCon = sqlite3.connect(beforeFilename) beforeCursor = beforeCon.cursor() afterCon = sqlite3.connect(afterFilename) afterCursor = afterCon.cursor() attributes = [v[1] for v in beforeCursor.execute("PRAGMA table_info('%s');" % layername)] attrnames = [f.name() for f in beforeLayer.pendingFields()] layerFeatures = [] beforeCursor.execute("SELECT * FROM %s_changes WHERE audit_op=2;" % layername) modified = beforeCursor.fetchall() for m in modified: geogigfid = m[0] beforeGpkgfid = gpkgfidFromGeogigfid(beforeCursor, layername, geogigfid) beforeCursor.execute("SELECT * FROM %s WHERE fid='%s';" % (layername, beforeGpkgfid)) featureRow = beforeCursor.fetchone() attrs = {attr: featureRow[attributes.index(attr)] for attr in attrnames} attrs["changetype"] = MODIFIED_BEFORE request = QgsFeatureRequest() request.setFilterFid(beforeGpkgfid) feature = next(beforeLayer.getFeatures(request)) layerFeatures.append({"attrs":attrs, "geom": QgsGeometry(feature.geometry())}) afterGpkgfid = gpkgfidFromGeogigfid(afterCursor, layername, geogigfid) afterCursor.execute("SELECT * FROM %s WHERE fid='%s';" % (layername,afterGpkgfid)) featureRow = afterCursor.fetchone() attrs = {attr: featureRow[attributes.index(attr)] for attr in attrnames} attrs["changetype"] = MODIFIED_AFTER request = QgsFeatureRequest() request.setFilterFid(afterGpkgfid) feature = next(afterLayer.getFeatures(request)) layerFeatures.append({"attrs":attrs, "geom": QgsGeometry(feature.geometry())}) afterCursor.execute("SELECT * FROM %s_changes WHERE audit_op=1;" % layername) added = afterCursor.fetchall() for a in added: geogigfid = a[0] afterGpkgfid = gpkgfidFromGeogigfid(afterCursor, layername, geogigfid) afterCursor.execute("SELECT * FROM %s WHERE fid='%s';" % (layername, afterGpkgfid)) featureRow = afterCursor.fetchone() attrs = {attr: featureRow[attributes.index(attr)] for attr in attrnames} attrs["changetype"] = ADDED request = QgsFeatureRequest() request.setFilterFid(afterGpkgfid) feature = next(afterLayer.getFeatures(request)) layerFeatures.append({"attrs":attrs, "geom": QgsGeometry(feature.geometry())}) beforeCursor.execute("SELECT * FROM %s_changes WHERE audit_op=1;" % layername) removed = beforeCursor.fetchall() for r in removed: geogigfid = r[0] beforeGpkgfid = gpkgfidFromGeogigfid(beforeCursor, layername, geogigfid) beforeCursor.execute("SELECT * FROM %s WHERE fid='%s';" % (layername, beforeGpkgfid)) featureRow = beforeCursor.fetchone() attrs = {attr: featureRow[attributes.index(attr)] for attr in attrnames} attrs["changetype"] = REMOVED request = QgsFeatureRequest() request.setFilterFid(beforeGpkgfid) feature = next(beforeLayer.getFeatures(request)) layerFeatures.append({"attrs":attrs, "geom": QgsGeometry(feature.geometry())}) if layerFeatures: attrnames.append("changetype") uriFields = "&".join(["field=%s" % f for f in attrnames]) uri = "%s?crs=%s&%s" % (geomTypes[beforeLayer.geometryType()], beforeLayer.crs().authid(), uriFields) layer = QgsVectorLayer(uri, "%s(diff)" % layername, "memory") featuresList = [] for feature in layerFeatures: qgsfeature = QgsFeature() qgsfeature.setGeometry(feature["geom"]) qgsfeature.setAttributes([feature["attrs"][attr] for attr in attrnames]) featuresList.append(qgsfeature) layer.dataProvider().addFeatures(featuresList) layer.updateExtents() QgsMapLayerRegistry.instance().addMapLayers([layer]) layer.loadNamedStyle(styles[layer.geometryType()])
def cloneToMemory(self): curlayer = self.iface.mapCanvas().currentLayer() selectedFeatCount = curlayer.selectedFeatureCount() geo = QgsWkbTypes.displayString( curlayer.wkbType()) # wkbType string name of geometry targetLayer = QgsVectorLayer(geo, self.dlg.lineEdit_2.text(), "memory") targetLayer.setCrs(curlayer.sourceCrs()) QgsProject.instance().addMapLayer(targetLayer, False) root = QgsProject.instance().layerTreeRoot() self.setStyleLayer(targetLayer) if self.dlg.checkBoxAtrib.isChecked(): #copy attributes curlayer_attribute_list = curlayer.fields().toList() targetLayer_attribute_list = [] targetLayerpr = targetLayer.dataProvider() for attrib in curlayer_attribute_list: if targetLayer.fields().lookupField(attrib.name()) == -1: targetLayer_attribute_list.append( QgsField(attrib.name(), attrib.type())) with edit(targetLayer): for attr in targetLayer_attribute_list: if attr.type( ) == 1: # иначе игнорируется поле с типом 1 (bool) attr = QgsField( attr.name(), QVariant.String) # конвертируем bool в string res_add = targetLayer.addAttribute(attr) if not res_add: print(u'Не создано поле {}'.format(attr.name())) targetLayer.updateFields() # for feat in curlayer.selectedFeatures(): # not work more # targetLayer.dataProvider().addFeatures([feat]) # not work more # ИЗ МОДУЛЯ Apend Features To layer ----------------------------------------------- # В старом варианте в QGIS3 при добавлении объектов с отличающимся набором аттрибутов # происходила задержка с выводом сообщений в логи. Что затягивало процесс. mapping = dict() for target_idx in targetLayer.fields().allAttributesList(): target_field = targetLayer.fields().field(target_idx) source_idx = curlayer.fields().indexOf(target_field.name()) if source_idx != -1: mapping[target_idx] = source_idx features = curlayer.selectedFeatures() destType = targetLayer.geometryType() destIsMulti = QgsWkbTypes.isMultiType(targetLayer.wkbType()) new_features = [] for current, in_feature in enumerate(features): attrs = { target_idx: in_feature[source_idx] for target_idx, source_idx in mapping.items() } geom = QgsGeometry() if in_feature.hasGeometry() and targetLayer.isSpatial(): # Convert geometry to match destination layer # Adapted from QGIS qgisapp.cpp, pasteFromClipboard() geom = in_feature.geometry() if destType != QgsWkbTypes.UnknownGeometry: newGeometry = geom.convertToType(destType, destIsMulti) if newGeometry.isNull(): continue geom = newGeometry # Avoid intersection if enabled in digitize settings geom.avoidIntersections( QgsProject.instance().avoidIntersectionsLayers()) new_feature = QgsVectorLayerUtils().createFeature( targetLayer, geom, attrs) new_features.append(new_feature) with edit(targetLayer): res = targetLayer.addFeatures(new_features) # ИЗ МОДУЛЯ Apend Features To layer -----------------------------------------------end root.insertLayer(0, targetLayer) self.iface.messageBar().clearWidgets() self.iface.setActiveLayer(targetLayer) curlayer.selectByIds([]) if res: self.iface.messageBar().pushMessage( u"Выполнено", u"Склонировано {0}/{1} объектов".format( len(new_features), selectedFeatCount), duration=5, level=0)
def showRequestResult(self, items, append, last, message): # print("showRequestResult") if items is None or len(items) == 0: QApplication.restoreOverrideCursor() self.__show_status_label(StatusMessageType.LOAD_FINISHED) self.getDataButton.setEnabled(True) if message is None or len(message) == 0: message = "По указанным параметрам ничего не найдено" self._show_message(self, "Загузка завершена", message) return color = QColor(237, 28, 36, 200) pjt = QgsProject.instance() layersList = pjt.mapLayersByName(self.resultsLayerName) if not append: if layersList is not None and len(layersList) > 0: pjt.removeMapLayer(layersList[0]) # print("remove results") layersList.clear() if not append or layersList is None or len(layersList) == 0: # print("create layer") layer = QgsVectorLayer("Point?crs=EPSG:4326" "&field=coordinatesWKT:string(255)&field=shootingDateTime:string(255)" "&field=temperature:double(7)&field=pixelSizeInDirection:double(5)" "&field=pixelSizeAcross:double(5)&field=thermalPower:double(5)" "&field=baseResourceId:string(255)&field=id:string(255)&field=updated:string(255)" "&field=satellite:string(10)", self.resultsLayerName, "memory") else: layer = layersList[0] symbol = QgsSymbol.defaultSymbol(layer.geometryType()) svg_marker = QgsSvgMarkerSymbolLayer(":/plugins/thermal_anomaly/fire.svg") svg_marker.setSize(6.0) symbol.changeSymbolLayer(0, svg_marker) layer.renderer().setSymbol(symbol) layer.startEditing() print("all items=", len(items)) poly = QgsGeometry.fromWkt(self.polygon) for point in items: symbols = layer.renderer().symbols(QgsRenderContext()) # todo which context ? symbols[0].setColor(color) feature = QgsFeature() coord = QgsGeometry.fromWkt(point["coordinatesWKT"]) feature.setGeometry(coord) feature.setAttributes([point["coordinatesWKT"], point["shootingDateTime"], point["temperature"], point["pixelSizeInDirection"], point["pixelSizeAcross"], point["thermalPower"], point["baseResourceId"], point["id"], point["updated"], point["satellite"]]) layer.dataProvider().addFeatures([feature]) # if not poly.contains(coord): # print("point out of poly: id =", point["id"], "coord =", point["coordinatesWKT"]) layer.commitChanges() if not append: pjt.addMapLayer(layer, False) if pjt.layerTreeRoot().findGroup(self.tr(self.groupName)) is None: pjt.layerTreeRoot().insertChildNode(0, QgsLayerTreeGroup(self.tr(self.groupName))) group = pjt.layerTreeRoot().findGroup(self.tr(self.groupName)) group.insertLayer(0, layer) self.iface.layerTreeView().refreshLayerSymbology(layer.id()) self.iface.mapCanvas().refresh() if last: QApplication.restoreOverrideCursor() self.__show_status_label(StatusMessageType.LOAD_FINISHED) self.getDataButton.setEnabled(True) else: self.__show_status_label(StatusMessageType.LOAD_STARTED, message)
def delimitedTextData(self, testname, filename, requests, verbose, **params): # Retrieve the data for a delimited text url # Create a layer for the specified file and query parameters # and return the data for the layer (fields, data) filepath = os.path.join(unitTestDataPath("delimitedtext"), filename) url = MyUrl.fromLocalFile(filepath) if not requests: requests = [{}] for k in list(params.keys()): url.addQueryItem(k, params[k]) urlstr = url.toString() log = [] with MessageLogger('DelimitedText') as logger: if verbose: print(testname) layer = QgsVectorLayer(urlstr, 'test', 'delimitedtext') uri = layer.dataProvider().dataSourceUri() if verbose: print(uri) basename = os.path.basename(filepath) if not basename.startswith('test'): basename = 'file' uri = re.sub(r'^file\:\/\/[^\?]*', 'file://' + basename, uri) fields = [] fieldTypes = [] data = {} if layer.isValid(): for nr, r in enumerate(requests): if verbose: print(("Processing request", nr + 1, repr(r))) if isinstance(r, collections.Callable): r(layer) if verbose: print("Request function executed") if isinstance(r, collections.Callable): continue rfields, rtypes, rdata = self.layerData(layer, r, nr * 1000) if len(rfields) > len(fields): fields = rfields fieldTypes = rtypes data.update(rdata) if not rdata: log.append("Request " + str(nr) + " did not return any data") if verbose: print(("Request returned", len(list(rdata.keys())), "features")) for msg in logger.messages(): filelogname = 'temp_file' if 'tmp' in filename.lower() else filename msg = re.sub(r'file\s+.*' + re.escape(filename), 'file ' + filelogname, msg) msg = msg.replace(filepath, filelogname) log.append(msg) return dict(fields=fields, fieldTypes=fieldTypes, data=data, log=log, uri=uri, geometryType=layer.geometryType())
class MissionTrack(QObject): mission_changed = pyqtSignal(int) step_removed = pyqtSignal(int) def __init__(self, mission_name="Mission", mission_filename=None, mission_layer=None, mission_renderer=None, canvas=None): super(MissionTrack, self).__init__() self.mission_filename = mission_filename self.mission_name = mission_name self.mission_layer = mission_layer self.mission_renderer = mission_renderer self.mission = Mission() self.canvas = canvas self.start_end_marker = StartEndMarker( canvas, self.find_waypoints_in_mission(), QColor(200, 0, 0)) self.saved = False self.modified = False def is_saved(self): """ :return: return True if mission is saved, otherwise False """ return self.saved def is_modified(self): """ :return: return True if mission is modified, otherwise False """ return self.modified def set_modified(self, modified): """ Set modified state""" self.modified = modified def load_mission(self, filename): """ Load mission with name 'filename'""" try: self.mission.load_mission(filename) self.mission_filename = filename self.update_start_end_markers() self.saved = True self.modifed = False except: logger.error("Invalid mission file") raise Exception("Invalid mission file") def set_mission(self, mission): """ Set Mission.""" self.mission = mission def set_mission_filename(self, filename): """ Set Mission Filename""" self.mission_filename = filename def set_mission_name(self, name): """ Set Mission name.""" self.mission_name = name def set_mission_layer(self, layer): """ Set mission layer.""" self.mission_layer.name = self.mission_name self.mission_layer = layer def set_mission_renderer(self, renderer): """ Set mission renderer.""" self.mission_renderer = renderer self.mission_layer.setRenderer(self.mission_renderer) def get_mission(self): """ Returns the mission""" return self.mission def get_step(self, step): """ Returns the step 'step' of the mission""" return self.mission.get_step(step) def get_mission_length(self): """ Returns mission length""" return self.mission.num_steps def get_mission_layer(self): """ Returns mission layer""" return self.mission_layer def get_mission_name(self): """ Returns mission name""" return self.mission_name def get_mission_filename(self): """ Returns mission filename""" return self.mission_filename def copy_mission(self): """ Returns a copy of the current mission""" return copy.deepcopy(self.mission) def change_position(self, wp_id, point): """ Changes a position of the waypoint 'wp_id' with a new position 'point' :param wp_id: Current step :param point: Point position """ position = self.mission.get_step(wp_id).get_maneuver().get_position() position.set_lat_lon(point.y(), point.x()) if wp_id != self.mission.get_length() - 1: # not last point if self.mission.get_step( wp_id + 1).get_maneuver().get_maneuver_type() == SECTION_MANEUVER: logger.debug("Next step is a section") # if next step is a section change its initial position position_next = self.mission.get_step( wp_id + 1).get_maneuver().get_initial_position() position_next.set_lat_lon(point.y(), point.x()) self.mission_changed.emit(wp_id) self.update_start_end_markers() self.modified = True def remove_step(self, wp_id): """ Remove step 'wp_id' :param wp_id: the step number to delete """ initial_num_steps = self.mission.num_steps # if is first point and next waypoint is a Section, show warning message if (wp_id == 0 and initial_num_steps > 1 and self.mission.get_step(wp_id + 1).get_maneuver().get_maneuver_type() == SECTION_MANEUVER): reply = QMessageBox.warning( None, "Mission Error", "Impossible to remove the point because the next point is a section" ) else: if (initial_num_steps - 1 != wp_id and self.mission.get_step(wp_id + 1).get_maneuver( ).get_maneuver_type() == SECTION_MANEUVER): logger.debug("Next step is a section") # if it's not the last step # if next step is a section change its initial position to the one of the point before position_previous = self.mission.get_step( wp_id - 1).get_maneuver().get_position() position_next = self.mission.get_step( wp_id + 1).get_maneuver().get_initial_position() position_next.set_lat_lon(position_previous.latitude, position_previous.longitude) self.mission.remove_step(wp_id) self.step_removed.emit(wp_id) # When point is deleted, layer may need a geometry type change if initial_num_steps <= 2: self.update_layer_geometry() if wp_id == initial_num_steps - 1: # if last waypoint is removed show previous self.mission_changed.emit(wp_id - 1) else: self.mission_changed.emit(wp_id) self.update_start_end_markers() self.modified = True def update_steps(self, id_list, mission_step_list): """ Update the number of the step 'wp_id' with new number 'step' :param id_list: list of step ids to update :param mission_step_list: list of mission steps to update :return: """ if len(id_list) > 0: for i in range(0, len(id_list)): self.mission.update_step(id_list[i], mission_step_list[i]) self.mission_changed.emit(id_list[0]) self.update_start_end_markers() self.modified = True def add_step(self, wp_id, point): """ Add new step""" initial_num_steps = self.mission.num_steps logger.debug("Add step: Mission has {} steps and wp_id is {}".format( initial_num_steps, wp_id)) step = MissionStep() position = MissionPosition() tolerance = MissionTolerance() # If more than one point, get maneuver from surrounding waypoint and copy data if initial_num_steps > 0: if wp_id != 0: # if point is at the end or in the middle copy from the previous manv_to_copy = self.mission.get_step(wp_id - 1).get_maneuver() if manv_to_copy.get_maneuver_type() == SECTION_MANEUVER: # if section, initial pos will be the final pos of the previous manv = MissionSection() position.copy(manv_to_copy.get_position()) tolerance.copy(manv_to_copy.get_tolerance()) manv.set(manv_to_copy.get_final_position(), position, manv_to_copy.get_speed(), tolerance) manv.get_final_position().set_lat_lon(point.y(), point.x()) if wp_id != initial_num_steps: # if point in the middle check if next is also section, we need to modify it manv_next = self.mission.get_step(wp_id).get_maneuver() if manv_next.get_maneuver_type() == SECTION_MANEUVER: manv_next.get_initial_position().set_lat_lon( point.y(), point.x()) else: # wp_id == 0 # copy from the next wp, next cannot be a section if was first waypoint until now, so no need to check manv_to_copy = self.mission.get_step(wp_id).get_maneuver() if manv_to_copy.get_maneuver_type() == WAYPOINT_MANEUVER: manv = MissionWaypoint() position.copy(manv_to_copy.get_position()) tolerance.copy(manv_to_copy.get_tolerance()) manv.set(position, manv_to_copy.get_speed(), tolerance) manv.get_position().set_lat_lon(point.y(), point.x()) elif manv_to_copy.get_maneuver_type() == PARK_MANEUVER: manv = MissionPark() position.copy(manv_to_copy.get_position()) tolerance.copy(manv_to_copy.get_tolerance()) manv.set(position, manv_to_copy.get_speed(), manv_to_copy.get_time(), tolerance) manv.get_position().set_lat_lon(point.y(), point.x()) else: # is first point of the mission, fill maneuver by default type waypoint with clicked position manv = MissionWaypoint( MissionPosition(point.y(), point.x(), 0.0, False), 0.5, MissionTolerance( 2.0, 2.0, 1.0)) # todo: define default z, mode, speed and tolerance step.add_maneuver(manv) self.mission.insert_step(wp_id, step) logger.debug("Mission has now {} steps".format(self.mission.num_steps)) # When point is added, layer may need a geometry type change if initial_num_steps <= 1: self.update_layer_geometry() self.mission_changed.emit(wp_id) self.update_start_end_markers() self.modified = True def save_mission(self): """ Saves a mission""" if self.mission.num_steps == 0: reply = QMessageBox.question( None, "Save Mission", "You are about to save an empty mission. Do you want to proceed?", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) if reply == QMessageBox.No: return False elif float( self.mission.get_step(self.mission.get_length() - 1). get_maneuver().get_position().get_z()) != 0.0: # vehicle last waypoint is not at zero depth. reply = QMessageBox.question( None, "Save Mission", "You are about to save and the last waypoint is not at zero depth. " "Do you want to proceed?", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) if reply == QMessageBox.No: return False logger.info("Saving mission to {}".format(self.mission_filename)) self.mission.write_mission(self.mission_filename) self.mission_layer.setCustomProperty("mission_xml", self.mission_filename) self.saved = True self.modified = False return True def saveas_mission(self): """ Save a mission with new name""" if self.mission.num_steps == 0: reply = QMessageBox.question( None, "Save Mission", "You are about to save an empty mission. Do you want to proceed?", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) if reply == QMessageBox.No: return False, None elif float( self.mission.get_step(self.mission.get_length() - 1). get_maneuver().get_position().get_z()) != 0.0: # vehicle last waypoint is not at zero depth. reply = QMessageBox.question( None, "Save Mission", "You are about to save and the last waypoint is not at zero depth. " "Do you want to proceed?", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) if reply == QMessageBox.No: return False, None mission_filename, selected_filter = QFileDialog.getSaveFileName( None, 'Save mission', self.mission_filename, 'XML (*.xml)') if mission_filename != '': if selected_filter == "XML (*.xml)": file_info = QFileInfo(mission_filename) self.mission.write_mission(mission_filename) logger.debug(file_info.fileName()) self.set_mission_name(file_info.fileName()) self.set_mission_filename(mission_filename) self.mission_layer.setName(file_info.baseName()) self.mission_layer.setCustomProperty("mission_xml", self.mission_filename) self.saved = True self.modified = False return True, mission_filename else: return False, None def render_mission(self): """ Render the mission, it will render the mission layer with Point geometry if it has only 1 point oterwise it will be with LineString geometry. """ waypoints = self.find_waypoints_in_mission() if self.mission_layer is None: if len(waypoints) == 1: self.mission_layer = QgsVectorLayer("Point?crs=epsg:4326", self.mission_name, "memory") self.mission_layer.setCustomProperty("mission_xml", self.mission_filename) feature = QgsFeature() feature.setGeometry(QgsGeometry(waypoints[0])) self.mission_layer.dataProvider().addFeatures([feature]) else: self.mission_layer = QgsVectorLayer("LineString?crs=epsg:4326", self.mission_name, "memory") self.mission_layer.setCustomProperty("mission_xml", self.mission_filename) feature = QgsFeature() feature.setGeometry(QgsGeometry.fromPolyline(waypoints)) self.mission_layer.dataProvider().addFeatures([feature]) else: # mission layer exists, now check if it has already a feature or not feats = self.mission_layer.getFeatures() logger.debug("layer feature count {}".format( self.mission_layer.featureCount())) if self.mission_layer.featureCount() == 0: feature = QgsFeature() if len(waypoints) == 1: feature.setGeometry(QgsGeometry(waypoints[0])) else: feature.setGeometry(QgsGeometry.fromPolyline(waypoints)) self.mission_layer.dataProvider().addFeatures([feature]) else: logger.debug("layer has feature mission already, updating...") for f in feats: self.mission_layer.dataProvider().deleteFeatures([f.id()]) feature = QgsFeature() if len(waypoints) == 1: feature.setGeometry(QgsGeometry(waypoints[0])) else: feature.setGeometry( QgsGeometry.fromPolyline(waypoints)) self.mission_layer.dataProvider().addFeatures([feature]) self.set_mission_renderer(self.get_default_track_renderer()) def find_waypoints_in_mission(self, indexes=None): """ Gets all waypoints from a mission structure """ waypoints = [] if indexes is None: step_indexes = range(0, self.mission.size()) else: step_indexes = indexes for stepindex in step_indexes: step = self.mission.get_step(stepindex) maneuver = step.get_maneuver() if maneuver.get_maneuver_type( ) == SECTION_MANEUVER: # for a Section position = maneuver.get_final_position() else: position = maneuver.get_position() # for Waypoint and Park waypoints.append( QgsPoint(float(position.longitude), float(position.latitude))) return waypoints def get_default_track_renderer(self): # Renderer for track lines registry = QgsSymbolLayerRegistry() line_meta = registry.symbolLayerMetadata("SimpleLine") marker_meta = registry.symbolLayerMetadata("MarkerLine") symbol = QgsSymbol.defaultSymbol(self.mission_layer.geometryType()) # Line layer line_layer = line_meta.createSymbolLayer({ 'width': '0.5', 'color': '255,0,0', 'offset': '0.0', 'penstyle': 'solid', 'use_custom_dash': '0', 'joinstyle': 'bevel', 'capstyle': 'square' }) # Marker layer marker_layer = marker_meta.createSymbolLayer({ 'width': '1.5', 'color': '255,0,0', 'placement': 'vertex', 'offset': '0.0' }) sub_symbol = marker_layer.subSymbol() # Replace the default layer with our own SimpleMarker sub_symbol.deleteSymbolLayer(0) cross = registry.symbolLayerMetadata("SimpleMarker").createSymbolLayer( { 'name': 'circle', 'color': '255,0,0', 'color_border': '0,0,0', 'offset': '0,0', 'size': '2.5', 'angle': '0' }) sub_symbol.appendSymbolLayer(cross) # Replace the default layer with our two custom layers symbol.deleteSymbolLayer(0) symbol.appendSymbolLayer(line_layer) symbol.appendSymbolLayer(marker_layer) # Replace the renderer of the current layer renderer = QgsSingleSymbolRenderer(symbol) return renderer def update_start_end_markers(self): """ Updates start_end_markers""" self.start_end_marker.update_markers(self.find_waypoints_in_mission()) def hide_start_end_markers(self): """ Hide start_end_markers""" self.start_end_marker.hide_markers() def remove_start_end_markers(self): """ Removes start end markers""" self.start_end_marker.close_markers() def update_layer_geometry(self): """ This function needs to be called every time a point is added or deleted from the layer If needed, a new layer is created with the apropiate geometry Point if only one point, LineString otherwise """ options = QgsDataProvider.ProviderOptions() waypoints = self.find_waypoints_in_mission() if (len(waypoints) != 1) and self.mission_layer.geometryType( ) == QgsWkbTypes.PointGeometry: self.mission_layer.setDataSource("LineString?crs=epsg:4326", self.mission_name, "memory", options) self.set_mission_renderer(self.get_default_track_renderer()) elif len(waypoints) == 1 and self.mission_layer.geometryType( ) == QgsWkbTypes.LineGeometry: self.mission_layer.setDataSource("Point?crs=epsg:4326", self.mission_name, "memory", options) self.set_mission_renderer(self.get_default_track_renderer())
def post_process_layer(self, layer: QgsVectorLayer, position: int): if layer.geometryType() == QgsWkbTypes.PointGeometry: for symbol in layer.renderer().symbols(self.layer_context(layer)): symbol.symbolLayer(0).setShape( MARKER_SHAPE[position % (len(MARKER_SHAPE) - 1)])
class CommonAutocorrelationDialog(QDialog): signalAskCloseWindow = pyqtSignal(int, name='signalAskCloseWindow') signalStatus = pyqtSignal(int, str, name='signalStatus') def __init__(self, parent=None): """Constructor. Base class for Incidence and Density dialogs. use_area : If you use the area of the polygon or the population field. use_point_layer : If you a point a layer, or a field in the polygon layer. """ self.parent = parent QDialog.__init__(self, parent) self.name_field = None self.admin_layer = None self.figure = None self.canvas = None self.toolbar = None self.output_file_path = None self.output_layer = None # Settings self.use_area = None def setup_ui(self): # Connect slot. # noinspection PyUnresolvedReferences self.button_browse.clicked.connect(self.open_file_browser) self.button_box_ok.button(QDialogButtonBox.Ok).clicked.connect( self.run_stats) self.button_box_ok.button(QDialogButtonBox.Cancel).clicked.connect( self.hide) self.button_box_ok.button(QDialogButtonBox.Cancel).clicked.connect( self.signalAskCloseWindow.emit) self.cbx_aggregation_layer.setFilters( QgsMapLayerProxyModel.PolygonLayer) self.cbx_indicator_field.setFilters(QgsFieldProxyModel.Numeric) self.cbx_indicator_field.setLayer( self.cbx_aggregation_layer.currentLayer()) self.cbx_aggregation_layer.layerChanged.connect( self.cbx_indicator_field.setLayer) self.lisa = { 1: ("#b92815", "High - High"), 2: ("#3f70df", "Low - High"), 3: ("#aecbdd", "Low - Low"), 4: ("#e79e2c", "High - Low") } def open_file_browser(self): output_file, __ = QFileDialog.getSaveFileName(self.parent, tr('Save shapefile'), filter='SHP (*.shp)') #Fix the filename bug self.le_output_filepath.setText(output_file) def run_stats(self): """Main function which do the process.""" # Get the common fields..currentField() self.admin_layer = self.cbx_aggregation_layer.currentLayer() input_name = self.admin_layer.name() field = self.cbx_indicator_field.currentField() self.layer = QgsProject.instance().mapLayersByName(input_name)[0] # Output. self.output_file_path = self.le_output_filepath.text() try: self.button_box_ok.setDisabled(True) # noinspection PyArgumentList QApplication.setOverrideCursor(Qt.WaitCursor) # noinspection PyArgumentList QApplication.processEvents() if not self.admin_layer: raise NoLayerProvidedException if not self.admin_layer and self.use_point_layer: raise NoLayerProvidedException crs_admin_layer = self.admin_layer.crs() # Output if not self.output_file_path: temp_file = NamedTemporaryFile(delete=False, suffix='-geopublichealth.shp') self.output_file_path = temp_file.name temp_file.flush() temp_file.close() else: with open(self.output_file_path, 'w') as document: pass admin_layer_provider = self.layer.dataProvider() fields = admin_layer_provider.fields() if admin_layer_provider.fields().indexFromName( self.name_field) != -1: raise FieldExistingException(field=self.name_field) fields.append(QgsField('LISA_P', QVariant.Double)) fields.append(QgsField('LISA_Z', QVariant.Double)) fields.append(QgsField('LISA_Q', QVariant.Int)) fields.append(QgsField('LISA_I', QVariant.Double)) fields.append(QgsField('LISA_C', QVariant.Double)) # The QgsVectorFileWriter was Deprecated since 3.10 However,....... #The create() function DOEST NOT Flush the feature unless QGIS close. #options = QgsVectorFileWriter.SaveVectorOptions() #options.driverName = "ESRI Shapefile" #file_writer=QgsVectorFileWriter.create(self.output_file_path,fields,QgsWkbTypes.Polygon,self.admin_layer.crs(),QgsCoordinateTransformContext(),options) #It's currently a bug https://github.com/qgis/QGIS/issues/35021 # So I will keep it for now file_writer = QgsVectorFileWriter(self.output_file_path, 'utf-8', fields, QgsWkbTypes.Polygon, self.admin_layer.crs(), 'ESRI Shapefile') if self.cbx_contiguity.currentIndex() == 0: # queen # fix_print_with_import print('Info: Local Moran\'s using queen contiguity') #Pysal 2.0 change #https://github.com/pysal/pysal/blob/master/MIGRATING.md w = Queen.from_shapefile(self.admin_layer.source()) else: # 1 for rook # fix_print_with_import print('Info: Local Moran\'s using rook contiguity') w = Rook.from_shapefile(self.admin_layer.source()) #Pysal 2.0 #https://stackoverflow.com/questions/59455383/pysal-does-not-have-attribute-open import geopandas f = geopandas.read_file(self.admin_layer.source().replace( '.shp', '.dbf')) y = f[str(field)] lm = Moran_Local(y, w, transformation="r", permutations=999) sig_q = lm.q * (lm.p_sim <= 0.05 ) # could make significance level an option outFeat = QgsFeature() i = 0 count = self.admin_layer.featureCount() for i, feature in enumerate(self.admin_layer.getFeatures()): attributes = feature.attributes() attributes.append(float(lm.p_sim[i])) attributes.append(float(lm.z_sim[i])) attributes.append(int(lm.q[i])) attributes.append(float(lm.Is[i])) attributes.append(int(sig_q[i])) new_feature = QgsFeature() new_geom = QgsGeometry(feature.geometry()) new_feature.setAttributes(attributes) new_feature.setGeometry(new_geom) file_writer.addFeature(new_feature) del file_writer self.output_layer = QgsVectorLayer(self.output_file_path, "LISA Moran's I - " + field, 'ogr') QgsProject.instance().addMapLayer(self.output_layer) self.add_symbology() self.signalStatus.emit(3, tr('Successful process')) except GeoPublicHealthException as e: display_message_bar(msg=e.msg, level=e.level, duration=e.duration) finally: self.button_box_ok.setDisabled(False) # noinspection PyArgumentList QApplication.restoreOverrideCursor() # noinspection PyArgumentList QApplication.processEvents() def add_symbology(self): categories = [] for lisaCategory, (color, label) in list(self.lisa.items()): sym = QgsSymbol.defaultSymbol(self.output_layer.geometryType()) sym.setColor(QColor(color)) category = QgsRendererCategory(lisaCategory, sym, label) categories.append(category) self.newlayer = QgsVectorLayer( self.output_layer.source(), self.output_layer.name() + " significance test", self.output_layer.providerType()) self.output_layer.setOpacity(0.4) QgsProject.instance().addMapLayer(self.newlayer) # noinspection PyArgumentList renderer = QgsCategorizedSymbolRenderer('LISA_Q', categories) self.output_layer.setRenderer(renderer) symbol = QgsSymbol.defaultSymbol( QgsWkbTypes.geometryType(QgsWkbTypes.Polygon)) color_ramp = QgsGradientColorRamp(QColor(0, 0, 0), QColor(255, 0, 0)) # noinspection PyArgumentList renderer = QgsGraduatedSymbolRenderer.createRenderer( self.newlayer, 'LISA_C', 4, QgsGraduatedSymbolRenderer.Jenks, symbol, color_ramp) self.newlayer.setRenderer(renderer) #The input val of seOPacity is 0-1 not 0-100 as setLyerTransvarency #https://gis.stackexchange.com/questions/150858/setting-transparency-of-layer-group-with-python-in-qgis self.newlayer.setOpacity(0.4)
def load_path_vector_layer(path, **kwargs): """Return the test vector layer. :param path: Path to the vector layer. :type path: str :param kwargs: It can be : clone=True if you want to copy the layer first to a temporary file. clone_to_memory=True if you want to create a memory layer. with_keywords=False if you do not want keywords. "clone_to_memory" is required. :type kwargs: dict :return: The vector layer. :rtype: QgsVectorLayer .. versionadded:: 4.0 """ if not exists(path): raise Exception('%s do not exist.' % path) path = os.path.normcase(os.path.abspath(path)) name = splitext(basename(path))[0] extension = splitext(path)[1] extensions = [ '.shp', '.shx', '.dbf', '.prj', '.gpkg', '.geojson', '.xml', '.qml' ] if kwargs.get('with_keywords'): if not kwargs.get('clone_to_memory'): raise Exception('with_keywords needs a clone_to_memory') if kwargs.get('clone', False): target_directory = mkdtemp() current_path = splitext(path)[0] path = join(target_directory, name + extension) for ext in extensions: src_path = current_path + ext if exists(src_path): target_path = join(target_directory, name + ext) shutil.copy2(src_path, target_path) if path.endswith('.csv'): # Explicitly use URI with delimiter or tests fail in Windows. TS. uri = 'file:///%s?delimiter=%s' % (path, ',') layer = QgsVectorLayer(uri, name, 'delimitedtext') else: layer = QgsVectorLayer(path, name, 'ogr') if not layer.isValid(): raise Exception('%s is not a valid layer.' % name) monkey_patch_keywords(layer) if kwargs.get('clone_to_memory', False): keywords = layer.keywords.copy() memory_layer = create_memory_layer(name, layer.geometryType(), layer.crs(), layer.fields()) copy_layer(layer, memory_layer) if kwargs.get('with_keywords', True): memory_layer.keywords = keywords return memory_layer else: return layer
class LoadOutputAsLayerDialog(QDialog, FORM_CLASS): """ Modal dialog to load an oq-engine output as layer """ def __init__(self, iface, viewer_dock, session, hostname, calc_id, output_type=None, path=None, mode=None, zonal_layer_path=None, engine_version=None): # sanity check if output_type not in OQ_TO_LAYER_TYPES: raise NotImplementedError(output_type) self.iface = iface self.viewer_dock = viewer_dock self.path = path self.session = session self.hostname = hostname self.calc_id = calc_id self.output_type = output_type self.mode = mode # if 'testing' it will avoid some user interaction self.zonal_layer_path = zonal_layer_path self.engine_version = engine_version QDialog.__init__(self) # Set up the user interface from Designer. self.setupUi(self) # Disable ok_button until all user options are set self.ok_button = self.buttonBox.button(QDialogButtonBox.Ok) self.ok_button.setDisabled(True) def create_file_hlayout(self): self.file_hlayout = QHBoxLayout() self.file_lbl = QLabel('File to load') self.file_browser_tbn = QToolButton() self.file_browser_tbn.setText('...') self.file_browser_tbn.clicked.connect(self.on_file_browser_tbn_clicked) self.path_le = QLineEdit() self.path_le.setEnabled(False) self.file_hlayout.addWidget(self.file_lbl) self.file_hlayout.addWidget(self.file_browser_tbn) self.file_hlayout.addWidget(self.path_le) self.vlayout.addLayout(self.file_hlayout) def create_num_sites_indicator(self): self.num_sites_msg = 'Number of sites: %s' self.num_sites_lbl = QLabel(self.num_sites_msg % '') self.vlayout.addWidget(self.num_sites_lbl) def create_file_size_indicator(self): self.file_size_msg = 'File size: %s' self.file_size_lbl = QLabel(self.file_size_msg % '') self.vlayout.addWidget(self.file_size_lbl) def create_rlz_or_stat_selector(self, label='Realization'): self.rlz_or_stat_lbl = QLabel(label) self.rlz_or_stat_cbx = QComboBox() self.rlz_or_stat_cbx.setEnabled(False) self.rlz_or_stat_cbx.currentIndexChanged['QString'].connect( self.on_rlz_or_stat_changed) self.vlayout.addWidget(self.rlz_or_stat_lbl) self.vlayout.addWidget(self.rlz_or_stat_cbx) def create_imt_selector(self): self.imt_lbl = QLabel('Intensity Measure Type') self.imt_cbx = QComboBox() self.imt_cbx.setEnabled(False) self.imt_cbx.currentIndexChanged['QString'].connect( self.on_imt_changed) self.vlayout.addWidget(self.imt_lbl) self.vlayout.addWidget(self.imt_cbx) def create_poe_selector(self): self.poe_lbl = QLabel('Probability of Exceedance') self.poe_cbx = QComboBox() self.poe_cbx.setEnabled(False) self.poe_cbx.currentIndexChanged['QString'].connect( self.on_poe_changed) self.vlayout.addWidget(self.poe_lbl) self.vlayout.addWidget(self.poe_cbx) def create_loss_type_selector(self): self.loss_type_lbl = QLabel('Loss Type') self.loss_type_cbx = QComboBox() self.loss_type_cbx.setEnabled(False) self.loss_type_cbx.currentIndexChanged['QString'].connect( self.on_loss_type_changed) self.vlayout.addWidget(self.loss_type_lbl) self.vlayout.addWidget(self.loss_type_cbx) def create_eid_selector(self): self.eid_lbl = QLabel('Event ID') self.eid_sbx = QSpinBox() self.eid_sbx.setEnabled(False) self.vlayout.addWidget(self.eid_lbl) self.vlayout.addWidget(self.eid_sbx) def create_dmg_state_selector(self): self.dmg_state_lbl = QLabel('Damage state') self.dmg_state_cbx = QComboBox() self.dmg_state_cbx.setEnabled(False) self.dmg_state_cbx.currentIndexChanged['QString'].connect( self.on_dmg_state_changed) self.vlayout.addWidget(self.dmg_state_lbl) self.vlayout.addWidget(self.dmg_state_cbx) def create_taxonomy_selector(self): self.taxonomy_lbl = QLabel('Taxonomy') self.taxonomy_cbx = QComboBox() self.taxonomy_cbx.setEnabled(False) self.vlayout.addWidget(self.taxonomy_lbl) self.vlayout.addWidget(self.taxonomy_cbx) def create_style_by_selector(self): self.style_by_lbl = QLabel('Style by') self.style_by_cbx = QComboBox() self.vlayout.addWidget(self.style_by_lbl) self.vlayout.addWidget(self.style_by_cbx) def create_load_selected_only_ckb(self): self.load_selected_only_ckb = QCheckBox("Load only the selected items") self.load_selected_only_ckb.setChecked(True) self.vlayout.addWidget(self.load_selected_only_ckb) def create_save_as_shp_ckb(self): self.save_as_shp_ckb = QCheckBox("Save the loaded layer as shapefile") self.save_as_shp_ckb.setChecked(False) self.vlayout.addWidget(self.save_as_shp_ckb) def create_zonal_layer_selector(self): self.zonal_layer_gbx = QGroupBox() self.zonal_layer_gbx.setTitle('Aggregate by zone (optional)') self.zonal_layer_gbx.setCheckable(True) self.zonal_layer_gbx.setChecked(False) self.zonal_layer_gbx_v_layout = QVBoxLayout() self.zonal_layer_gbx.setLayout(self.zonal_layer_gbx_v_layout) self.zonal_layer_cbx = QComboBox() self.zonal_layer_cbx.addItem('') self.zonal_layer_lbl = QLabel('Zonal layer') self.zonal_layer_tbn = QToolButton() self.zonal_layer_tbn.setText('...') self.zonal_layer_h_layout = QHBoxLayout() self.zonal_layer_h_layout.addWidget(self.zonal_layer_cbx) self.zonal_layer_h_layout.addWidget(self.zonal_layer_tbn) self.zonal_layer_gbx_v_layout.addWidget(self.zonal_layer_lbl) self.zonal_layer_gbx_v_layout.addLayout(self.zonal_layer_h_layout) self.zone_id_field_lbl = QLabel('Field containing zone ids') self.zone_id_field_cbx = QComboBox() self.zonal_layer_gbx_v_layout.addWidget(self.zone_id_field_lbl) self.zonal_layer_gbx_v_layout.addWidget(self.zone_id_field_cbx) self.vlayout.addWidget(self.zonal_layer_gbx) self.zonal_layer_tbn.clicked.connect(self.on_zonal_layer_tbn_clicked) self.zonal_layer_cbx.currentIndexChanged[int].connect( self.on_zonal_layer_cbx_currentIndexChanged) self.zonal_layer_gbx.toggled[bool].connect( self.on_zonal_layer_gbx_toggled) def pre_populate_zonal_layer_cbx(self): for key, layer in \ QgsMapLayerRegistry.instance().mapLayers().iteritems(): # populate loss cbx only with layers containing points if layer.type() != QgsMapLayer.VectorLayer: continue if layer.geometryType() == QGis.Polygon: self.zonal_layer_cbx.addItem(layer.name()) self.zonal_layer_cbx.setItemData( self.zonal_layer_cbx.count() - 1, layer.id()) def on_zonal_layer_cbx_currentIndexChanged(self, new_index): self.zone_id_field_cbx.clear() zonal_layer = None if not self.zonal_layer_cbx.currentText(): if self.zonal_layer_gbx.isChecked(): self.ok_button.setEnabled(False) return zonal_layer_id = self.zonal_layer_cbx.itemData(new_index) zonal_layer = QgsMapLayerRegistry.instance().mapLayer(zonal_layer_id) # if the zonal_layer doesn't have a field containing a unique zone id, # the user can choose to add such unique id self.zone_id_field_cbx.addItem("Add field with unique zone id") for field in zonal_layer.fields(): # for the zone id accept both numeric or textual fields self.zone_id_field_cbx.addItem(field.name()) # by default, set the selection to the first textual field self.set_ok_button() def on_zonal_layer_gbx_toggled(self, on): if on and not self.zonal_layer_cbx.currentText(): self.ok_button.setEnabled(False) else: self.set_ok_button() def on_output_type_changed(self): if self.output_type in OQ_TO_LAYER_TYPES: self.create_load_selected_only_ckb() elif self.output_type in OQ_COMPLEX_CSV_TO_LAYER_TYPES: self.create_save_as_shp_ckb() self.set_ok_button() @pyqtSlot() def on_file_browser_tbn_clicked(self): path = self.open_file_dialog() if path: self.populate_out_dep_widgets() self.set_ok_button() def on_rlz_or_stat_changed(self): self.dataset = self.npz_file[self.rlz_or_stat_cbx.currentText()] self.set_ok_button() def on_loss_type_changed(self): self.set_ok_button() def on_imt_changed(self): self.set_ok_button() def on_poe_changed(self): self.set_ok_button() def on_eid_changed(self): self.set_ok_button() def on_dmg_state_changed(self): self.set_ok_button() def open_file_dialog(self): """ Open a file dialog to select the data file to be loaded """ text = self.tr('Select the OQ-Engine output file to import') if self.output_type in OQ_CSV_TO_LAYER_TYPES: filters = self.tr('CSV files (*.csv)') else: raise NotImplementedError(self.output_type) default_dir = QSettings().value('irmt/load_as_layer_dir', QDir.homePath()) path = QFileDialog.getOpenFileName(self, text, default_dir, filters) if not path: return selected_dir = QFileInfo(path).dir().path() QSettings().setValue('irmt/load_as_layer_dir', selected_dir) self.path = path self.path_le.setText(self.path) return path def populate_out_dep_widgets(self): self.populate_rlz_or_stat_cbx() self.show_num_sites() def get_taxonomies(self): raise NotImplementedError() def populate_rlz_or_stat_cbx(self): self.rlzs_or_stats = [ key for key in sorted(self.npz_file) if key not in ('imtls', 'array') ] self.rlz_or_stat_cbx.clear() self.rlz_or_stat_cbx.setEnabled(True) self.rlz_or_stat_cbx.addItems(self.rlzs_or_stats) def populate_loss_type_cbx(self, loss_types): self.loss_type_cbx.clear() self.loss_type_cbx.setEnabled(True) self.loss_type_cbx.addItems(loss_types) def show_num_sites(self): # NOTE: we are assuming all realizations have the same number of sites, # which currently is always true. # If different realizations have a different number of sites, we # need to move this block of code inside on_rlz_or_stat_changed() rlz_or_stat_data = self.npz_file[self.rlz_or_stat_cbx.currentText()] self.num_sites_lbl.setText(self.num_sites_msg % rlz_or_stat_data.shape) def set_ok_button(self): raise NotImplementedError() def build_layer_name(self, *args, **kwargs): raise NotImplementedError() def get_field_names(self, **kwargs): raise NotImplementedError() def add_field_to_layer(self, field_name): raise NotImplementedError() def read_npz_into_layer(self, field_names, **kwargs): raise NotImplementedError() def load_from_npz(self): raise NotImplementedError() def get_investigation_time(self): if self.output_type in ('hcurves', 'uhs', 'hmaps'): try: investigation_time = self.npz_file['investigation_time'] except KeyError: msg = ('investigation_time not found. It is mandatory for %s.' ' Please check if the ouptut was produced by an' ' obsolete version of the OpenQuake Engine' ' Server.') % self.output_type log_msg(msg, level='C', message_bar=self.iface.messageBar()) else: return investigation_time else: # some outputs do not need the investigation time return None def build_layer(self, rlz_or_stat=None, taxonomy=None, poe=None, loss_type=None, dmg_state=None, gsim=None): layer_name = self.build_layer_name(rlz_or_stat=rlz_or_stat, taxonomy=taxonomy, poe=poe, loss_type=loss_type, dmg_state=dmg_state, gsim=gsim) field_names = self.get_field_names(rlz_or_stat=rlz_or_stat, taxonomy=taxonomy, poe=poe, loss_type=loss_type, dmg_state=dmg_state) # create layer self.layer = QgsVectorLayer("Point?crs=epsg:4326", layer_name, "memory") for field_name in field_names: if field_name in ['lon', 'lat']: continue added_field_name = self.add_field_to_layer(field_name) if field_name != added_field_name: if field_name == self.default_field_name: self.default_field_name = added_field_name # replace field_name with the actual added_field_name field_name_idx = field_names.index(field_name) field_names.remove(field_name) field_names.insert(field_name_idx, added_field_name) self.read_npz_into_layer(field_names, rlz_or_stat=rlz_or_stat, taxonomy=taxonomy, poe=poe, loss_type=loss_type, dmg_state=dmg_state) self.layer.setCustomProperty('output_type', self.output_type) investigation_time = self.get_investigation_time() if investigation_time is not None: self.layer.setCustomProperty('investigation_time', investigation_time) if self.engine_version is not None: self.layer.setCustomProperty('engine_version', self.engine_version) irmt_version = get_irmt_version() self.layer.setCustomProperty('irmt_version', irmt_version) self.layer.setCustomProperty('calc_id', self.calc_id) QgsMapLayerRegistry.instance().addMapLayer(self.layer) self.iface.setActiveLayer(self.layer) self.iface.zoomToActiveLayer() def _set_symbol_size(self, symbol): if self.iface.mapCanvas().mapUnits() == QGis.Degrees: point_size = 0.05 elif self.iface.mapCanvas().mapUnits() == QGis.Meters: point_size = 4000 else: # it is not obvious how to choose the point size in the other # cases, so we conservatively keep the default sizing return symbol.symbolLayer(0).setSizeUnit(symbol.MapUnit) symbol.symbolLayer(0).setSize(point_size) map_unit_scale = QgsMapUnitScale() map_unit_scale.maxSizeMMEnabled = True map_unit_scale.minSizeMMEnabled = True map_unit_scale.minSizeMM = 0.5 map_unit_scale.maxSizeMM = 10 symbol.symbolLayer(0).setSizeMapUnitScale(map_unit_scale) def style_maps(self, layer=None, style_by=None): if layer is None: layer = self.layer if style_by is None: style_by = self.default_field_name symbol = QgsSymbolV2.defaultSymbol(layer.geometryType()) # see properties at: # https://qgis.org/api/qgsmarkersymbollayerv2_8cpp_source.html#l01073 symbol.setAlpha(1) # opacity if isinstance(symbol, QgsMarkerSymbolV2): # do it only for the layer with points self._set_symbol_size(symbol) symbol.symbolLayer(0).setOutlineStyle(Qt.PenStyle(Qt.NoPen)) style = get_style(layer, self.iface.messageBar()) # this is the default, as specified in the user settings ramp = QgsVectorGradientColorRampV2(style['color_from'], style['color_to']) mode = style['mode'] # in most cases, we override the user-specified setting, and use # instead a setting that was required by scientists if self.output_type in OQ_TO_LAYER_TYPES: default_qgs_style = QgsStyleV2().defaultStyle() default_color_ramp_names = default_qgs_style.colorRampNames() if self.output_type in ('dmg_by_asset', 'losses_by_asset', 'avg_losses-stats'): # options are EqualInterval, Quantile, Jenks, StdDev, Pretty # jenks = natural breaks mode = QgsGraduatedSymbolRendererV2.Jenks ramp_type_idx = default_color_ramp_names.index('Reds') inverted = False elif self.output_type in ('hmaps', 'gmf_data', 'ruptures'): # options are EqualInterval, Quantile, Jenks, StdDev, Pretty if self.output_type == 'ruptures': mode = QgsGraduatedSymbolRendererV2.Pretty else: mode = QgsGraduatedSymbolRendererV2.EqualInterval ramp_type_idx = default_color_ramp_names.index('Spectral') inverted = True ramp = default_qgs_style.colorRamp( default_color_ramp_names[ramp_type_idx]) graduated_renderer = QgsGraduatedSymbolRendererV2.createRenderer( layer, style_by, style['classes'], mode, symbol, ramp, inverted=inverted) label_format = graduated_renderer.labelFormat() # label_format.setTrimTrailingZeroes(True) # it might be useful label_format.setPrecision(2) graduated_renderer.setLabelFormat(label_format, updateRanges=True) # add a class for 0 values, unless while styling ruptures if self.output_type != 'ruptures': VERY_SMALL_VALUE = 1e-20 graduated_renderer.updateRangeLowerValue(0, VERY_SMALL_VALUE) symbol_zeros = QgsSymbolV2.defaultSymbol(layer.geometryType()) symbol_zeros.setColor(QColor(240, 240, 240)) # very light grey if isinstance(symbol, QgsMarkerSymbolV2): # do it only for the layer with points self._set_symbol_size(symbol_zeros) symbol_zeros.symbolLayer(0).setOutlineStyle( Qt.PenStyle(Qt.NoPen)) zeros_min = 0.0 zeros_max = VERY_SMALL_VALUE range_zeros = QgsRendererRangeV2( zeros_min, zeros_max, symbol_zeros, " %.2f - %.2f" % (zeros_min, zeros_max), True) graduated_renderer.addClassRange(range_zeros) graduated_renderer.moveClass( len(graduated_renderer.ranges()) - 1, 0) layer.setRendererV2(graduated_renderer) layer.setLayerTransparency(30) # percent layer.triggerRepaint() self.iface.legendInterface().refreshLayerSymbology(layer) self.iface.mapCanvas().refresh() def style_categorized(self, layer, style_by): # get unique values fni = layer.fieldNameIndex(style_by) unique_values = layer.dataProvider().uniqueValues(fni) # define categories categories = [] for unique_value in unique_values: # initialize the default symbol for this geometry type symbol = QgsSymbolV2.defaultSymbol(layer.geometryType()) # configure a symbol layer layer_style = {} layer_style['color'] = '%d, %d, %d' % (randrange( 0, 256), randrange(0, 256), randrange(0, 256)) layer_style['outline'] = '#000000' symbol_layer = QgsSimpleFillSymbolLayerV2.create(layer_style) # replace default symbol layer with the configured one if symbol_layer is not None: symbol.changeSymbolLayer(0, symbol_layer) # create renderer object category = QgsRendererCategoryV2(unique_value, symbol, str(unique_value)) # entry for the list of category items categories.append(category) # create renderer object renderer = QgsCategorizedSymbolRendererV2(style_by, categories) # assign the created renderer to the layer if renderer is not None: layer.setRendererV2(renderer) layer.triggerRepaint() self.iface.legendInterface().refreshLayerSymbology(layer) self.iface.mapCanvas().refresh() def style_curves(self): registry = QgsSymbolLayerV2Registry.instance() cross = registry.symbolLayerMetadata("SimpleMarker").createSymbolLayer( { 'name': 'cross2', 'color': '0,0,0', 'color_border': '0,0,0', 'offset': '0,0', 'size': '1.5', 'angle': '0' }) symbol = QgsSymbolV2.defaultSymbol(self.layer.geometryType()) symbol.deleteSymbolLayer(0) symbol.appendSymbolLayer(cross) self._set_symbol_size(symbol) renderer = QgsSingleSymbolRendererV2(symbol) effect = QgsOuterGlowEffect() effect.setSpread(0.5) effect.setTransparency(0) effect.setColor(QColor(255, 255, 255)) effect.setBlurLevel(1) renderer.paintEffect().appendEffect(effect) renderer.paintEffect().setEnabled(True) self.layer.setRendererV2(renderer) self.layer.setLayerTransparency(30) # percent self.layer.triggerRepaint() self.iface.legendInterface().refreshLayerSymbology(self.layer) self.iface.mapCanvas().refresh() def open_zonal_layer_dialog(self): """ Open a file dialog to select the zonal layer to be loaded :returns: the zonal layer """ text = self.tr('Select zonal layer to import') filters = self.tr('Vector shapefiles (*.shp);;SQLite (*.sqlite);;' 'All files (*.*)') default_dir = QSettings().value('irmt/select_layer_dir', QDir.homePath()) file_name, file_type = QFileDialog.getOpenFileNameAndFilter( self, text, default_dir, filters) if not file_name: return None selected_dir = QFileInfo(file_name).dir().path() QSettings().setValue('irmt/select_layer_dir', selected_dir) zonal_layer_plus_stats = self.load_zonal_layer(file_name) return zonal_layer_plus_stats def load_zonal_layer(self, zonal_layer_path, make_a_copy=False): # Load zonal layer zonal_layer = QgsVectorLayer(zonal_layer_path, tr('Zonal data'), 'ogr') if not zonal_layer.geometryType() == QGis.Polygon: msg = 'Zonal layer must contain zone polygons' log_msg(msg, level='C', message_bar=self.iface.messageBar()) return False if make_a_copy: # Make a copy, where stats will be added zonal_layer_plus_stats = ProcessLayer( zonal_layer).duplicate_in_memory() else: zonal_layer_plus_stats = zonal_layer # Add zonal layer to registry if zonal_layer_plus_stats.isValid(): QgsMapLayerRegistry.instance().addMapLayer(zonal_layer_plus_stats) else: msg = 'Invalid zonal layer' log_msg(msg, level='C', message_bar=self.iface.messageBar()) return None return zonal_layer_plus_stats def on_zonal_layer_tbn_clicked(self): zonal_layer_plus_stats = self.open_zonal_layer_dialog() if (zonal_layer_plus_stats and zonal_layer_plus_stats.geometryType() == QGis.Polygon): self.populate_zonal_layer_cbx(zonal_layer_plus_stats) def populate_zonal_layer_cbx(self, zonal_layer_plus_stats): cbx = self.zonal_layer_cbx cbx.addItem(zonal_layer_plus_stats.name()) last_index = cbx.count() - 1 cbx.setItemData(last_index, zonal_layer_plus_stats.id()) cbx.setCurrentIndex(last_index) def show_file_size(self): file_size = get_file_size(self.path) self.file_size_lbl.setText(self.file_size_msg % file_size) def accept(self): if self.output_type in OQ_EXTRACT_TO_LAYER_TYPES: self.load_from_npz() if self.output_type in ('losses_by_asset', 'dmg_by_asset', 'avg_losses-stats'): # check if also aggregating by zone or not if (not self.zonal_layer_cbx.currentText() or not self.zonal_layer_gbx.isChecked()): super(LoadOutputAsLayerDialog, self).accept() return loss_layer = self.layer self.iface.legendInterface().setLayerVisible(loss_layer, False) zonal_layer_id = self.zonal_layer_cbx.itemData( self.zonal_layer_cbx.currentIndex()) zonal_layer = QgsMapLayerRegistry.instance().mapLayer( zonal_layer_id) # if the two layers have different projections, display an # error message and return have_same_projection, check_projection_msg = ProcessLayer( loss_layer).has_same_projection_as(zonal_layer) if not have_same_projection: log_msg(check_projection_msg, level='C', message_bar=self.iface.messageBar()) # TODO: load only loss layer super(LoadOutputAsLayerDialog, self).accept() return loss_attr_names = [ field.name() for field in loss_layer.fields() ] zone_id_in_losses_attr_name = None # index 0 is for "Add field with unique zone id" if self.zone_id_field_cbx.currentIndex() == 0: zone_id_in_zones_attr_name = None else: zone_id_in_zones_attr_name = \ self.zone_id_field_cbx.currentText() # aggregate losses by zone (calculate count of points in the # zone, sum and average loss values for the same zone) loss_layer_is_vector = True try: res = calculate_zonal_stats(loss_layer, zonal_layer, loss_attr_names, loss_layer_is_vector, zone_id_in_losses_attr_name, zone_id_in_zones_attr_name, self.iface, extra=False) except TypeError as exc: log_msg(str(exc), level='C', message_bar=self.iface.messageBar()) return (loss_layer, zonal_layer, loss_attrs_dict) = res # sanity check assert len(loss_attrs_dict) == 1, ( "Only one attribute should be added to the zonal layer." " %s were added insted" % len(loss_attrs_dict)) # NOTE: in scenario damage, keys are like # u'structural_no_damage_mean', and not just # u'structural', therefore we can't just use the selected # loss type, but we must use the actual only key in the # dict [added_loss_attr] = loss_attrs_dict style_by = loss_attrs_dict[added_loss_attr]['sum'] self.style_maps(layer=zonal_layer, style_by=style_by) elif self.output_type in OQ_CSV_TO_LAYER_TYPES: self.load_from_csv() super(LoadOutputAsLayerDialog, self).accept() def reject(self): if (hasattr(self, 'npz_file') and self.npz_file is not None and self.output_type in OQ_TO_LAYER_TYPES): self.npz_file.close() super(LoadOutputAsLayerDialog, self).reject()
def load_path_vector_layer(path, **kwargs): """Return the test vector layer. :param path: Path to the vector layer. :type path: str :param kwargs: It can be : clone=True if you want to copy the layer first to a temporary file. clone_to_memory=True if you want to create a memory layer. with_keywords=False if you do not want keywords. "clone_to_memory" is required. :type kwargs: dict :return: The vector layer. :rtype: QgsVectorLayer .. versionadded:: 4.0 """ if not exists(path): raise Exception('%s do not exist.' % path) path = os.path.normcase(os.path.abspath(path)) name = splitext(basename(path))[0] extension = splitext(path)[1] extensions = [ '.shp', '.shx', '.dbf', '.prj', '.gpkg', '.geojson', '.xml', '.qml'] if kwargs.get('with_keywords'): if not kwargs.get('clone_to_memory'): raise Exception('with_keywords needs a clone_to_memory') if kwargs.get('clone', False): target_directory = mkdtemp() current_path = splitext(path)[0] path = join(target_directory, name + extension) for ext in extensions: src_path = current_path + ext if exists(src_path): target_path = join(target_directory, name + ext) shutil.copy2(src_path, target_path) if path.endswith('.csv'): # Explicitly use URI with delimiter or tests fail in Windows. TS. uri = 'file:///%s?delimiter=%s' % (path, ',') layer = QgsVectorLayer(uri, name, 'delimitedtext') else: layer = QgsVectorLayer(path, name, 'ogr') if not layer.isValid(): raise Exception('%s is not a valid layer.' % name) monkey_patch_keywords(layer) if kwargs.get('clone_to_memory', False): keywords = layer.keywords.copy() memory_layer = create_memory_layer( name, layer.geometryType(), layer.crs(), layer.fields()) copy_layer(layer, memory_layer) if kwargs.get('with_keywords', True): memory_layer.keywords = keywords return memory_layer else: return layer
def addRowInLayer(row, errTable, table_codif): """ Rows will be converted in a geometry thanks to codification. All attributes will be added thanks to QgsExpressionContext. Parameters ---------- row: list of list A row contains one or many list of points. errTable: list of list Contains points in error. Some points can be added after the end of this function. table_codif: dictionnary The codification file. See the information about qlsc format. """ # TODO: assert? code = row[CODE_POSITION][0] parameters = row[PARAM_POSITION] codif = table_codif['Codification'][code] layerName = codif['Layer'] layer = QgsVectorLayer(layerName) dim = 4 if QgsWkbTypes.hasZ(layer.dataProvider().wkbType()) else 3 geom = geomFromType(list(zip(*row[1:dim])), parameters, codif['GeometryType'], layer.geometryType()) if geom: layer.startEditing() fields = layer.fields() newFeature = QgsFeature(fields) newFeature.setGeometry(geom) for e in codif['Attributes']: # print(e, e[1], e[1].startswith('_att')) if e[1].startswith('_att'): # len('_att') == 4 try: nb = int(e[1][4:]) - 1 assert(nb >= 0) val = row[ATTRS_POSITION + nb][0] newFeature[e[0]] = val except: # print("attributes error") pass else: context = QgsExpressionContext() scope = QgsExpressionContextScope() try: exp = QgsExpression(e[1]) scope.setFeature(newFeature) context.appendScope(scope) newFeature[e[0]] = exp.evaluate(context) except: # print('key error') pass ret = layer.addFeature(newFeature) # if not ret: # print(ret) layer.commitChanges() layer.updateExtents() else: # can it happen? errTable.append(row)
def run(self): # layer base name and dir path base_name = QFileInfo(self._fn).baseName() dir_path = QFileInfo(self._fn).absoluteDir() # create the uri for the delimitedtext provider from .settings_dlg import Settings csvUrl = QUrl.fromLocalFile( self._fn ) csvUrl.setQueryItems( [ ( "delimiter", Settings.delimiter() ), ( "delimiterType", "plain"), ( "xField", Settings.longitudeField() ), ( "yField", Settings.latitudeField() ) ] ) # load the layer from qgis.core import QgsVectorLayer csvVl = QgsVectorLayer(csvUrl.toString(), base_name, "delimitedtext") if not csvVl.isValid(): # invalid layer csvVl.deleteLater() QMessageBox.warning( self.parent(), "Invalid layer", u"Unable to load the layer %s" % self._fn ) return (self.INVALID_INPUT, None) # check the layer geometry type from qgis.core import QGis if csvVl.geometryType() != QGis.Point: csvVl.deleteLater() QMessageBox.warning( self.parent(), "Invalid layer", u"Unable to get data from the selected file. \nSetup Lat/Long field names and delimiter from the Settings dialog, \nthen try again." ) return (self.INVALID_LATLON, None) # check whether the CSV file has to be imported to SL db if not Settings.importCsvToSl(): return (self.OK, csvVl) # uri pointing to the new SL database from qgis.core import QgsDataSourceURI sqlite_path = dir_path.absoluteFilePath( u"%s.sqlite" % base_name ) slUri = QgsDataSourceURI() slUri.setDatabase( sqlite_path ) slUri.setDataSource( "", base_name, "GEOMETRY" ) importer = Ogr2ogrImporter(csvVl, slUri, self.parent()) #importer = QGisLayerImporter(csvVl, slUri, self.parent()) ret = importer.start() # get the importer exit code if not ret: if importer.wasCanceled(): ret = self.CANCELED else: ret = self.ERROR QMessageBox.warning( self.parent(), "Error", importer.errorMessage() ) else: ret = self.OK # cleanup importer.deleteLater() importer = None csvVl.deleteLater() csvVl = None if ret != self.OK: return (ret, None) # load the layer from the SL database slVl = QgsVectorLayer(slUri.uri(), slUri.table(), "spatialite") if not slVl.isValid(): # invalid layer slVl.deleteLater() QMessageBox.warning( self.parent(), "Invalid layer", u"Unable to load the layer %s" % slUri.database() ) return (self.ERROR, None) # check the layer geometry type if slVl.geometryType() != QGis.Point: slVl.deleteLater() return (self.ERROR, None) return (self.OK, slVl)
class OSRM_DialogTSP(QtGui.QDialog, FORM_CLASS_tsp, TemplateOsrm): def __init__(self, iface, parent=None): """ Constructor""" super(OSRM_DialogTSP, self).__init__(parent) self.setupUi(self) self.iface = iface self.pushButton_display.clicked.connect(self.run_tsp) self.pushButton_clear.clicked.connect(self.clear_results) self.comboBox_layer.setFilters(QgsMapLayerProxyModel.PointLayer) self.nb_route = 0 def clear_results(self): """ Clear previous result and set back counter to 0. """ for layer in QgsMapLayerRegistry.instance().mapLayers(): if 'tsp_solution_osrm' in layer: QgsMapLayerRegistry.instance().removeMapLayer(layer) self.nb_route = 0 def run_tsp(self): """ Main method, preparing the query and displaying the result on the canvas. """ layer = self.comboBox_layer.currentLayer() coords, _ = get_coords_ids( layer, '', on_selected=self.checkBox_selec_features.isChecked()) if len(coords) < 2: return -1 try: self.host = check_host(self.lineEdit_host.text()) profile = check_profile_name(self.lineEdit_profileName.text()) except (ValueError, AssertionError) as err: print(err) self.iface.messageBar().pushMessage( "Error", "Please provide a valid non-empty URL and profile name", duration=10) return query = ''.join( ["http://", self.host, "/trip/", profile, "/", ";".join(["{},{}".format(coord[0], coord[1]) for coord in coords])]) try: self.parsed = self.query_url(query) except Exception as err: self.iface.messageBar().pushMessage( "Error", "An error occured when trying to contact the OSRM " "instance (see QGis log for error traceback)", duration=10) QgsMessageLog.logMessage( 'OSRM-plugin error report :\n {}'.format(err), level=QgsMessageLog.WARNING) return try: line_geoms = \ [decode_geom(self.parsed['trips'][i]['geometry']) for i in range(len(self.parsed['trips']))] except KeyError: self.iface.messageBar().pushMessage( "Error", "?...", duration=5) return tsp_route_layer = QgsVectorLayer( "Linestring?crs=epsg:4326&field=id:integer" "&field=total_time:integer(20)&field=distance:integer(20)", "tsp_solution_osrm{}".format(self.nb_route), "memory") my_symb = prepare_route_symbol(self.nb_route) tsp_route_layer.setRendererV2(QgsSingleSymbolRendererV2(my_symb)) features = [] for idx, feature in enumerate(self.parsed['trips']): ft = QgsFeature() ft.setGeometry(line_geoms[idx]) ft.setAttributes([idx, feature['distance'], feature['duration']]) features.append(ft) self.prepare_ordered_marker(coords, idx) tsp_route_layer.dataProvider().addFeatures(features) tsp_route_layer.updateExtents() QgsMapLayerRegistry.instance().addMapLayer(tsp_route_layer) self.iface.setActiveLayer(tsp_route_layer) self.iface.zoomToActiveLayer() put_on_top(self.tsp_marker_lr.id(), tsp_route_layer.id()) self.nb_route += 1 # if self.checkBox_instructions.isChecked(): # pr_instruct, instruct_layer = self.prep_instruction() # QgsMapLayerRegistry.instance().addMapLayer(instruct_layer) # self.iface.setActiveLayer(instruct_layer) def prepare_ordered_marker(self, coords, idx): """ Try to display nice marker on a point layer, showing the order of the path computed by OSRM. """ self.tsp_marker_lr = QgsVectorLayer( "Point?crs=epsg:4326&field=id:integer" "&field=TSP_nb:integer(20)&field=Origin_nb:integer(20)", "tsp_markers_osrm{}".format(self.nb_route), "memory") symbol = QgsSymbolV2.defaultSymbol(self.tsp_marker_lr.geometryType()) symbol.setSize(4.5) symbol.setColor(QtGui.QColor("yellow")) ordered_pts = \ [coords[i["waypoint_index"]] for i in self.parsed['waypoints']] print("ordered_pts : ", ordered_pts) features = [] for nb, pt in enumerate(ordered_pts): ft = QgsFeature() ft.setGeometry(QgsGeometry.fromPoint(QgsPoint(pt))) ft.setAttributes([nb, nb + 1, coords.index(pt)]) features.append(ft) self.tsp_marker_lr.dataProvider().addFeatures(features) pal_lyr = QgsPalLayerSettings() pal_lyr.readFromLayer(self.tsp_marker_lr) pal_lyr.enabled = True pal_lyr.fieldName = 'TSP_nb' pal_lyr.placement= QgsPalLayerSettings.OverPoint pal_lyr.setDataDefinedProperty(QgsPalLayerSettings.Size,True,True,'12','') pal_lyr.writeToLayer(self.tsp_marker_lr) self.tsp_marker_lr.setRendererV2(QgsSingleSymbolRendererV2(symbol)) QgsMapLayerRegistry.instance().addMapLayer(self.tsp_marker_lr)
def run(self): """Run method that performs all the real work""" self.dlg.layerComboBox.clear() self.dlg.sheetTypeComboBox.clear() self.dlg.scaleComboBox.clear() #self.dlg.label_2.setText('') Alllayers = self.iface.legendInterface().layers() #layer_list = [] lcount=0 for layer in Alllayers: xyCrs = layer.crs() if xyCrs.projectionAcronym()=='longlat': lcount=lcount+1 self.dlg.layerComboBox.addItem(layer.name(),layer) self.dlg.sheetTypeComboBox.addItem('Indian and Adjoining Countries Series Maps') self.dlg.sheetTypeComboBox.addItem('Open Series Maps') scale_list=['1:1M','1:250,000','1:125,000','1:50,000','1:25,000'] self.dlg.scaleComboBox.addItems(scale_list) # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: global scaleID global sheetw global sheeth if lcount>0: scaleID=self.dlg.scaleComboBox.currentIndex()+1 maptype= self.dlg.sheetTypeComboBox.currentIndex()+1 if maptype==1: sheetw,sheeth=setFactor1(scaleID) if maptype==2: sheetw,sheeth=setFactor2(scaleID) index = self.dlg.layerComboBox.currentIndex() clayer = self.dlg.layerComboBox.itemData(index) e=clayer.extent() a,b,c=degDec2dms(e.xMinimum()) slongs=dmstosec(a,b,c) a,b,c=degDec2dms(e.xMaximum()) elongs=dmstosec(a,b,c) a,b,c=degDec2dms(e.yMinimum()) slats=dmstosec(a,b,c) a,b,c=degDec2dms(e.yMaximum()) elats=dmstosec(a,b,c) slongs,elongs,slats,elats=CalculateExtentInTermsOfSheet(slongs,elongs,slats,elats) Xgrids=int(elongs-slongs)//sheetw # // is used for modular division Ygrids=int(elats-slats)//sheeth layer = QgsVectorLayer("Polygon?crs=EPSG:4326", "TopoSheets", "memory") global poly global pr pr = layer.dataProvider() pr.addAttributes([QgsField("id",QVariant.Int),QgsField("SheetNo",QVariant.String),QgsField("Inside",QVariant.String)]) layer.updateFields() poly = QgsFeature() CalculateSheet(maptype,slats,slongs,Xgrids,Ygrids) n=0 # check intersection of selected layer feature with sheets fieldIdx = pr.fields().indexFromName('Inside' ) updateMap = {} for f in clayer.getFeatures(): for a in layer.getFeatures(): if a.geometry().intersects(f.geometry()): n=n+1 updateMap[a.id()] = { fieldIdx:1 } pr.changeAttributeValues(updateMap) # set the layer symbology values = ( ('In', True,True,QColor.fromRgb(95,254,99)), ('Out', False,False,'yellow'), ) # create a category for each item in values ranges=[] for label, lower, upper, color in values: symbol = QgsSymbolV2.defaultSymbol(layer.geometryType()) symbol.setColor(QColor(color)) rng = QgsRendererRangeV2(lower, upper, symbol, label) ranges.append(rng) expression = 'Inside' # field name renderer = QgsGraduatedSymbolRendererV2(expression, ranges) layer.setRendererV2(renderer) # set layer transparence and dolabelling layer.setLayerTransparency(65) layer.updateExtents() QgsMapLayerRegistry.instance().addMapLayers([layer]) layer.setCustomProperty("labeling", "pal") layer.setCustomProperty("labeling/enabled", "true") layer.setCustomProperty("labeling/fontFamily", "Arial") layer.setCustomProperty("labeling/fontSize", "10") layer.setCustomProperty("labeling/fieldName", "SheetNo") layer.setCustomProperty("labeling/placement", "1") iface.mapCanvas().refresh() else: iface.messageBar().pushMessage("Error", "No layers loaded, Load layer with Geographic Corrdinates", level=QgsMessageBar.CRITICAL) pass
def WPT2Layer(self): mapUnits = define._canvas.mapUnits() if define._mapCrs == None: if mapUnits == QGis.Meters: resultLayer = QgsVectorLayer( "Point?crs=EPSG:32633", "WPT_" + self.surfaceType.replace(" ", "_").replace("-", "_"), "memory") else: resultLayer = QgsVectorLayer( "Point?crs=EPSG:4326", "WPT_" + self.surfaceType.replace(" ", "_").replace("-", "_"), "memory") else: resultLayer = QgsVectorLayer( "Point?crs=%s" % define._mapCrs.authid(), "WPT_" + self.surfaceType.replace(" ", "_").replace("-", "_"), "memory") shpPath = "" if define.obstaclePath != None: shpPath = define.obstaclePath elif define.xmlPath != None: shpPath = define.xmlPath else: shpPath = define.appPath er = QgsVectorFileWriter.writeAsVectorFormat( resultLayer, shpPath + "/" + "RnavTurningSegmentAnalyserWpt" + ".shp", "utf-8", resultLayer.crs()) resultLayer = QgsVectorLayer( shpPath + "/" + "RnavTurningSegmentAnalyserWpt" + ".shp", "WPT_RnavTurningSegmentAnalyser", "ogr") fieldName = "CATEGORY" resultLayer.dataProvider().addAttributes( [QgsField(fieldName, QVariant.String)]) resultLayer.startEditing() fields = resultLayer.pendingFields() i = 1 feature = QgsFeature() feature.setFields(fields) feature.setGeometry( QgsGeometry.fromPoint(self.parametersPanel.pnlWaypoint1.Point3d)) feature.setAttribute(fieldName, "Waypoint1") pr = resultLayer.dataProvider() pr.addFeatures([feature]) # resultLayer.addFeature(feature) feature.setGeometry( QgsGeometry.fromPoint(self.parametersPanel.pnlWaypoint2.Point3d)) feature.setAttribute(fieldName, "Waypoint2") pr = resultLayer.dataProvider() pr.addFeatures([feature]) # resultLayer.addFeature(feature) resultLayer.commitChanges() renderCatFly = None if self.parametersPanel.cmbType1.SelectedIndex == 1: '''FlyOver''' symbolFlyOver = QgsSymbolV2.defaultSymbol( resultLayer.geometryType()) symbolFlyOver.deleteSymbolLayer(0) svgSymLayer = QgsSvgMarkerSymbolLayerV2("Resource/flyover.svg", 10.0, 0.0) symbolFlyOver.appendSymbolLayer(svgSymLayer) renderCatFly = QgsRendererCategoryV2(0, symbolFlyOver, "Fly Over") elif self.parametersPanel.cmbType1.SelectedIndex == 0: '''FlyBy''' symbolFlyBy = QgsSymbolV2.defaultSymbol(resultLayer.geometryType()) symbolFlyBy.deleteSymbolLayer(0) svgSymLayer = QgsSvgMarkerSymbolLayerV2("Resource/flyby.svg", 10.0, 0.0) symbolFlyBy.appendSymbolLayer(svgSymLayer) renderCatFly = QgsRendererCategoryV2(0, symbolFlyBy, "Fly By") else: return None WPT_EXPRESION = "CASE WHEN \"CATEGORY\" = 'Waypoint1' THEN 0 " + \ "END" symRenderer = QgsCategorizedSymbolRendererV2(WPT_EXPRESION, [renderCatFly]) resultLayer.setRendererV2(symRenderer) return resultLayer