def testGeopackageLargeFID(self): tmpfile = os.path.join(self.basetestpath, 'testGeopackageLargeFID.gpkg') ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile) lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint) lyr.CreateField(ogr.FieldDefn('str_field', ogr.OFTString)) ds = None vl = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=" + "test", 'test', u'ogr') f = QgsFeature() f.setAttributes([1234567890123, None]) self.assertTrue(vl.startEditing()) self.assertTrue(vl.dataProvider().addFeatures([f])) self.assertTrue(vl.commitChanges()) got = [feat for feat in vl.getFeatures()][0] self.assertEqual(got['fid'], 1234567890123) self.assertTrue(vl.startEditing()) self.assertTrue(vl.changeGeometry(1234567890123, QgsGeometry.fromWkt('Point (3 50)'))) self.assertTrue(vl.changeAttributeValue(1234567890123, 1, 'foo')) self.assertTrue(vl.commitChanges()) got = [feat for feat in vl.getFeatures()][0] self.assertEqual(got['str_field'], 'foo') got_geom = got.geometry() self.assertIsNotNone(got_geom) self.assertTrue(vl.startEditing()) self.assertTrue(vl.deleteFeature(1234567890123)) self.assertTrue(vl.commitChanges())
def create_layer(vector): """Create empty layer. The CRS and Geometry Type of new layer are the same as of vector layer. Attributes of the layer are copied from vector. :param vector: Vector layer :type vector: QgsVectorLayer :returns: Empty vector layer (stored in memory) :rtype: QgsVectorLayer """ crs = vector.crs().toWkt() if vector.geometryType() == 0: # We can create layer from Point. Do not need to split it. uri = "Point?crs=" + crs elif vector.geometryType() == 1: uri = "LineString?crs=" + crs elif vector.geometryType() == 2: uri = "Polygon?crs=" + crs else: msg = "Received unexpected type of layer geometry: %s" % (vector.geometryType(),) raise WrongDataTypeException(msg) result_layer = QgsVectorLayer(uri, "intersected", "memory") result_provider = result_layer.dataProvider() result_layer.startEditing() # Copy fields from vector vector_provider = vector.dataProvider() fields = vector_provider.fields() result_provider.addAttributes(fields.toList()) result_layer.commitChanges() return result_layer
def _create_points(self): """Create points for testing""" point_layer = QgsVectorLayer('Point?crs=EPSG:4326', 'points', 'memory') point_provider = point_layer.dataProvider() point_provider.addAttributes([QgsField('X', QVariant.Double)]) point_provider.addAttributes([QgsField('Y', QVariant.Double)]) x_index = point_provider.fieldNameIndex('X') y_index = point_provider.fieldNameIndex('Y') point_layer.startEditing() for x in [10.0, 20.0, 30.0]: for y in [10.0, 20.0, 30.0]: feature = QgsFeature() feature.initAttributes(2) feature.setAttribute(x_index, x) feature.setAttribute(y_index, y) # noinspection PyCallByClass geom = QgsGeometry.fromPoint(QgsPoint(x, y)) feature.setGeometry(geom) _ = point_layer.dataProvider().addFeatures([feature]) point_layer.commitChanges() return point_layer
def create_memory_layer(self, layer): """Create an in-memory copy of an existing vector layer.""" data_provider = layer.dataProvider() # create the layer path defining geometry type and reference system geometry_type = QGis.vectorGeometryType(layer.geometryType()) crs_id = layer.crs().authid() path = geometry_type + '?crs=' + crs_id + '&index=yes' # create the memory layer and get a reference to the data provider memory_layer = QgsVectorLayer(path, 'Cartogram', 'memory') memory_layer_data_provider = memory_layer.dataProvider() # copy all attributes from the source layer to the memory layer memory_layer.startEditing() memory_layer_data_provider.addAttributes( data_provider.fields().toList()) memory_layer.commitChanges() # copy all features from the source layer to the memory layer for feature in data_provider.getFeatures(): memory_layer_data_provider.addFeatures([feature]) return memory_layer
def testEditGeoJsonAddFieldAndThenAddFeatures(self): """ Test bugfix of https://issues.qgis.org/issues/18596 (adding a new field)""" datasource = os.path.join(self.basetestpath, 'testEditGeoJsonAddField.json') with open(datasource, 'wt') as f: f.write("""{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "x": 1 }, "geometry": { "type": "Point", "coordinates": [ 0, 0 ] } } ] }""") vl = QgsVectorLayer(datasource, 'test', 'ogr') self.assertTrue(vl.isValid()) self.assertTrue(vl.startEditing()) self.assertTrue(vl.addAttribute(QgsField('strfield', QVariant.String))) self.assertTrue(vl.commitChanges()) self.assertEqual(len(vl.dataProvider().fields()), 1 + 1) self.assertEqual([f.name() for f in vl.dataProvider().fields()], ['x', 'strfield']) f = QgsFeature() self.assertTrue(vl.getFeatures(QgsFeatureRequest()).nextFeature(f)) self.assertIsNone(f['strfield']) self.assertEqual([field.name() for field in f.fields()], ['x', 'strfield']) self.assertTrue(vl.startEditing()) vl.changeAttributeValue(f.id(), 1, 'x') self.assertTrue(vl.commitChanges()) f = QgsFeature() self.assertTrue(vl.getFeatures(QgsFeatureRequest()).nextFeature(f)) self.assertEqual(f['strfield'], 'x') self.assertEqual([field.name() for field in f.fields()], ['x', 'strfield']) # Completely reload file vl = QgsVectorLayer(datasource, 'test', 'ogr') self.assertEqual(len(vl.fields()), 2)
def add_flooded_field(self, shapefile_path): """Create the layer from the local shp adding the flooded field. .. versionadded:: 3.3 Use this method to add a calculated field to a shapefile. The shapefile should have a field called 'count' containing the number of flood reports for the field. The field values will be set to 0 if the count field is < 1, otherwise it will be set to 1. :param shapefile_path: Path to the shapefile that will have the flooded field added. :type shapefile_path: basestring :return: A vector layer with the flooded field added. :rtype: QgsVectorLayer """ layer = QgsVectorLayer( shapefile_path, self.tr('Jakarta Floods'), 'ogr') # Add a calculated field indicating if a poly is flooded or not # from PyQt4.QtCore import QVariant layer.startEditing() field = QgsField('flooded', QVariant.Int) layer.dataProvider().addAttributes([field]) layer.commitChanges() layer.startEditing() idx = layer.fieldNameIndex('flooded') expression = QgsExpression('state > 0') expression.prepare(layer.pendingFields()) for feature in layer.getFeatures(): feature[idx] = expression.evaluate(feature) layer.updateFeature(feature) layer.commitChanges() return layer
def testUpdatedFields(self): """Test when referenced layer update its fields https://issues.qgis.org/issues/20893 """ ml = QgsVectorLayer("Point?srid=EPSG:4326&field=a:int", "mem", "memory") self.assertEqual(ml.isValid(), True) QgsProject.instance().addMapLayer(ml) ml.startEditing() f1 = QgsFeature(ml.fields()) f1.setGeometry(QgsGeometry.fromWkt('POINT(2 3)')) ml.addFeatures([f1]) ml.commitChanges() vl = QgsVectorLayer("?query=select a, geometry from mem", "vl", "virtual") self.assertEqual(vl.isValid(), True) # add one more field ml.dataProvider().addAttributes([QgsField('newfield', QVariant.Int)]) ml.updateFields() self.assertEqual(ml.featureCount(), vl.featureCount()) self.assertEqual(vl.fields().count(), 1) geometry = next(vl.getFeatures()).geometry() self.assertTrue(geometry) point = geometry.asPoint() self.assertEqual(point.x(), 2) self.assertEqual(point.y(), 3) QgsProject.instance().removeMapLayer(ml)
def _loadBufferLayer(self, sourceLayer, layerPath, layerName): layer = None layerId = '' layerList = QgsMapLayerRegistry.instance().mapLayersByName(layerName) if (len(layerList) > 0): layer = layerList[0] self._iface.legendInterface().moveLayer(layer, self._bufferGroupIndex) else: fullLayerPath = self.projectPath + '/' + layerPath if (layerName and layerPath and sourceLayer and sourceLayer.isValid()): if not QFile.exists(fullLayerPath): # If the layer doesn't exist, clone from the source layer layer = layers.cloneAsShapefile(sourceLayer, fullLayerPath, layerName) else: # If the layer does exist, then load it and copy the style layer = QgsVectorLayer(fullLayerPath, layerName, 'ogr') layer = layers.addLayerToLegend(self._iface, layer, self._bufferGroupIndex) if layer and layer.isValid(): layerId = layer.id() layers.loadStyle(layer, fromLayer=sourceLayer) self._setDefaultSnapping(layer) layer.startEditing() layer.setFeatureFormSuppress(QgsVectorLayer.SuppressOn) self._iface.legendInterface().setLayerExpanded(layer, False) else: layer = None return layer, layerId
def create_layer(self, data): display_name = 'some-layer' uri = 'Point?crs=epsg:4326&index=yes&uuid=%s' % uuid.uuid4() vlayer = QgsVectorLayer(uri, display_name, 'memory') QgsMapLayerRegistry.instance().addMapLayer(vlayer) provider = vlayer.dataProvider() vlayer.startEditing() provider.addAttributes([ QgsField('population_density', QtCore.QVariant.Double), ]) features = [] for x, y, density in data: feat = QgsFeature() geom = QgsGeometry.fromPoint(QgsPoint(x, y)) feat.setGeometry(geom) feat.setAttributes([density]) features.append(feat) provider.addFeatures(features) vlayer.commitChanges() vlayer.updateExtents() self.canvas.setExtent(vlayer.extent()) cl = QgsMapCanvasLayer(vlayer) self.canvas.setLayerSet([cl]) vlayer.triggerRepaint()
def to_shp(path, any_features_list, layer_fields, crs, name, encoding, geom_type): if path is None: if geom_type == 0: network = QgsVectorLayer('Point?crs=' + crs.toWkt(), name, "memory") else: network = QgsVectorLayer('LineString?crs=' + crs.toWkt(), name, "memory") else: fields = QgsFields() for field in layer_fields: fields.append(field) file_writer = QgsVectorFileWriter(path, encoding, fields, geom_type, crs, "ESRI Shapefile") if file_writer.hasError() != QgsVectorFileWriter.NoError: print "Error when creating shapefile: ", file_writer.errorMessage() del file_writer network = QgsVectorLayer(path, name, "ogr") pr = network.dataProvider() if path is None: pr.addAttributes(layer_fields) new_features = [] for i in any_features_list: new_feat = QgsFeature() new_feat.setFeatureId(i[0]) new_feat.setAttributes([attr[0] for attr in i[1]]) new_feat.setGeometry(QgsGeometry(QgsGeometry.fromWkt(str(i[2])))) #QgsGeometry() new_features.append(new_feat) network.startEditing() pr.addFeatures(new_features) network.commitChanges() return network
def test_SplitFeature(self): """Test sqlite feature can be split""" tmpfile = os.path.join(self.basetestpath, 'testGeopackageSplitFeatures.sqlite') ds = ogr.GetDriverByName('SQlite').CreateDataSource(tmpfile) lyr = ds.CreateLayer('test', geom_type=ogr.wkbPolygon) lyr.CreateField(ogr.FieldDefn('str_field', ogr.OFTString)) f = ogr.Feature(lyr.GetLayerDefn()) f.SetGeometry(ogr.CreateGeometryFromWkt('POLYGON ((0 0,0 1,1 1,1 0,0 0))')) lyr.CreateFeature(f) f = None ds = None layer = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=" + "test", 'test', u'ogr') # Check that pk field has unique constraint fields = layer.fields() pkfield = fields.at(0) self.assertTrue(pkfield.constraints().constraints() & QgsFieldConstraints.ConstraintUnique) self.assertTrue(layer.isValid()) self.assertTrue(layer.isSpatial()) self.assertEqual([f for f in layer.getFeatures()][0].geometry().asWkt(), 'Polygon ((0 0, 0 1, 1 1, 1 0, 0 0))') layer.startEditing() self.assertEqual(layer.splitFeatures([QgsPointXY(0.5, 0), QgsPointXY(0.5, 1)], 0), 0) self.assertTrue(layer.commitChanges()) self.assertEqual(layer.featureCount(), 2) layer = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=" + "test", 'test', u'ogr') self.assertEqual(layer.featureCount(), 2) self.assertEqual([f for f in layer.getFeatures()][0].geometry().asWkt(), 'Polygon ((0.5 0, 0.5 1, 1 1, 1 0, 0.5 0))') self.assertEqual([f for f in layer.getFeatures()][1].geometry().asWkt(), 'Polygon ((0.5 1, 0.5 0, 0 0, 0 1, 0.5 1))')
def __createMemoryLayer(self, layer_name, gtype, geometries, attributes, fNames, fTypes): """ Create a memory layer from parameters :param layer_name: name for the layer :param gtype: geometry type of the layer :param geometries: objects geometries :param attributes: objects attributes :param fNames: fields names :param fTypes: fields types """ layerList = QgsMapLayerRegistry.instance().mapLayersByName(layer_name) if layerList: QgsMapLayerRegistry.instance().removeMapLayers([layerList[0].id()]) epsg = self.canvas().mapRenderer().destinationCrs().authid() fieldsParam = "" for i in range(len(fNames)): fieldsParam += "&field=" + fNames[i] + ":" + fTypes[i] layer = QgsVectorLayer(gtype + "?crs=" + epsg + fieldsParam + "&index=yes", layer_name, "memory") QgsMapLayerRegistry.instance().addMapLayer(layer) layer.startEditing() for i in range(len(geometries)): feature = QgsFeature() feature.setGeometry(QgsGeometry().fromWkt(geometries[i])) fields = layer.pendingFields() feature.setFields(fields) for j in range(len(fNames)): feature.setAttribute(fNames[j], attributes[i][j]) layer.addFeature(feature) layer.commitChanges()
def testNull(self): """ Asserts that 0, '' and NULL are treated as different values on insert """ vl = QgsVectorLayer(self.dbconn + ' sslmode=disable key=\'gid\' table="qgis_test"."constraints" sql=', 'test1', 'postgres') self.assertTrue(vl.isValid()) QgsProject.instance().addMapLayer(vl) tg = QgsTransactionGroup() tg.addLayer(vl) vl.startEditing() def onError(message): """We should not get here. If we do, fail and say why""" self.assertFalse(True, message) vl.raiseError.connect(onError) f = QgsFeature(vl.fields()) f['gid'] = 100 f['val'] = 0 f['name'] = '' self.assertTrue(vl.addFeature(f)) feature = next(vl.getFeatures('"gid" = 100')) self.assertEqual(f['val'], feature['val']) self.assertEqual(f['name'], feature['name'])
def getmap(self): if self.canvas: settings = self.canvas.mapSettings() layers = settings.layers() if GPS.isConnected: try: gpslayer = QgsMapLayerRegistry.instance().mapLayersByName("__gps_layer")[0] except IndexError: gpslayer = QgsVectorLayer("Point", "__gps_layer", "memory") symbol = QgsMarkerSymbolV2.createSimple({'name': 'circle', 'color': 'blue', "size": '5'}) gpslayer.rendererV2().setSymbol(symbol) QgsMapLayerRegistry.instance().addMapLayer(gpslayer, False) layers.append(gpslayer.id()) settings.setLayers(layers) map_pos = QgsPoint(GPS.gpsinfo("longitude"), GPS.gpsinfo("latitude")) # map_pos = QgsPoint(115.72589,-32.29597) geom = QgsGeometry.fromPoint(map_pos) feature = QgsFeature() feature.setGeometry(geom) gpslayer.startEditing() gpslayer.addFeature(feature) # gpslayer.commitChanges() self.renderjob = QgsMapRendererParallelJob(settings) self.renderjob.finished.connect(self.rendermap) self.renderjob.start()
def pixels_to_points( raster, threshold_min=0.0, threshold_max=float('inf'), field_name='value'): """ Convert raster to points. Areas (pixels) with threshold_min < pixel_values < threshold_max will be converted to point layer. :param raster: Raster layer :type raster: QgsRasterLayer :param threshold_min: Value that splits raster to flooded or not flooded. :type threshold_min: float :param threshold_max: Value that splits raster to flooded or not flooded. :type threshold_max: float :param field_name: Field name to store pixel value. :type field_name: string :returns: Point layer of pixels :rtype: QgsVectorLayer """ if raster.bandCount() != 1: msg = "Current version allows using of one-band raster only" raise NotImplementedError(msg) extent = raster.extent() width, height = raster.width(), raster.height() provider = raster.dataProvider() block = provider.block(1, extent, width, height) # Create points crs = raster.crs().toWkt() point_layer = QgsVectorLayer('Point?crs=' + crs, 'pixels', 'memory') point_provider = point_layer.dataProvider() point_provider.addAttributes([QgsField(field_name, QVariant.Double)]) field_index = point_provider.fieldNameIndex(field_name) attribute_count = 1 point_layer.startEditing() for row in range(height): for col in range(width): value = block.value(row, col) x, y = _get_pixel_coordinates(extent, width, height, row, col) # noinspection PyCallByClass,PyTypeChecker,PyArgumentList geom = QgsGeometry.fromPoint(QgsPoint(x, y)) if threshold_min < value < threshold_max: feature = QgsFeature() feature.initAttributes(attribute_count) feature.setAttribute(field_index, value) feature.setGeometry(geom) _ = point_layer.dataProvider().addFeatures([feature]) point_layer.commitChanges() return point_layer
def create_memory_layer(layer, new_name=''): """Return a memory copy of a layer :param layer: QgsVectorLayer that shall be copied to memory. :type layer: QgsVectorLayer :param new_name: The name of the copied layer. :type new_name: str :returns: An in-memory copy of a layer. :rtype: QgsMapLayer """ if new_name is '': new_name = layer.name() + ' TMP' if layer.type() == QgsMapLayer.VectorLayer: vType = layer.geometryType() if vType == QGis.Point: typeStr = 'Point' elif vType == QGis.Line: typeStr = 'Line' elif vType == QGis.Polygon: typeStr = 'Polygon' else: raise MemoryLayerCreationError('Layer is whether Point nor ' 'Line nor Polygon') else: raise MemoryLayerCreationError('Layer is not a VectorLayer') crs = layer.crs().authid().toLower() myUUID = str(uuid.uuid4()) uri = '%s?crs=%s&index=yes&uuid=%s' % (typeStr, crs, myUUID) memLayer = QgsVectorLayer(uri, new_name, 'memory') memProvider = memLayer.dataProvider() provider = layer.dataProvider() attribute_indexes = provider.attributeIndexes() vFields = provider.fields() fields = [] for i in vFields: fields.append(vFields[i]) memProvider.addAttributes(fields) provider.select(attribute_indexes) ft = QgsFeature() while provider.nextFeature(ft): memProvider.addFeatures([ft]) if qgis_version() <= 10800: # Next two lines a workaround for a QGIS bug (lte 1.8) # preventing mem layer attributes being saved to shp. memLayer.startEditing() memLayer.commitChanges() return memLayer
def create_neighbors_layer(): vl = QgsVectorLayer("Polygon", LAYER_NEIGHBORS, "memory") pr = vl.dataProvider() vl.startEditing() pr.addAttributes( [ QgsField(FIELD_UUID, QVariant.String), QgsField(FIELD_NEIGHBORS_UUID, QVariant.String), QgsField(FIELD_SV, QVariant.Double)] ) vl.updateFields() return vl
def get_poi(self): try: client_id = self.dlg.lineEdit_clientID.text() client_secret = self.dlg.lineEdit_clientSecret.text() radius = self.dlg.lineEdit_radius.text() category_name = self.dlg.comboBox_category.currentText() category_id = foursquare_categories[category_name] current_date = str(datetime.datetime.now().date()).replace("-", "") url = "https://api.foursquare.com/v2/venues/search?ll=%s,%s&radius=%s&intent=browse&categoryId=%s&limit=50&client_id=%s&client_secret=%s&v=%s" % (lat, lon, radius, category_id, client_id, client_secret, current_date) req = urllib2.Request(url) opener = urllib2.build_opener() f = opener.open(req) data = json.loads(f.read()) json_object_count = len(data['response']['venues']) if json_object_count == 0: iface.messageBar().pushMessage(u"Info:", "Unfortunately, there is no POI at the specified location...", level=QgsMessageBar.INFO, duration=5) else: iface.messageBar().pushMessage(u"Info:", str(json_object_count) + " POI(s) fetched for " + category_name + " category", level=QgsMessageBar.SUCCESS, duration=5) poi_id = [] poi_name = [] poi_lon = [] poi_lat = [] for i in range(0, json_object_count): poi_id.append(data['response']['venues'][i]['id']) poi_name.append(data['response']['venues'][i]['name']) poi_lon.append(data['response']['venues'][i]['location']['lng']) poi_lat.append(data['response']['venues'][i]['location']['lat']) coord_pairs = [] layer_name = "POI - %s" % category_name memory_layer = QgsVectorLayer("Point?crs=epsg:4326", layer_name, "memory") memory_layer.startEditing() provider = memory_layer.dataProvider() provider.addAttributes([QgsField("FoursqID", QVariant.String), QgsField("Name", QVariant.String), QgsField("Category", QVariant.String), QgsField("Date", QVariant.String)]) for fsid, name, x, y in zip(poi_id, poi_name, poi_lon, poi_lat): geometry = QgsGeometry.fromPoint(QgsPoint(x, y)) feature = QgsFeature() feature.setGeometry(geometry) feature.setAttributes([fsid, name, category_name, current_date]) coord_pairs.append(feature) memory_layer.dataProvider().addFeatures(coord_pairs) memory_layer.updateExtents() memory_layer.commitChanges() QgsMapLayerRegistry.instance().addMapLayer(memory_layer) except: iface.messageBar().pushMessage(u"Error:", "Please make sure to drop a pin on Google Map or fill in all \ the fields!", level=QgsMessageBar.CRITICAL, duration=5)
def test_SplitFeatureWithMultiKey(self): """Create SpatiaLite database""" layer = QgsVectorLayer("dbname=%s table=test_pg_mk (geometry)" % self.dbname, "test_pg_mk", "spatialite") self.assertTrue(layer.isValid()) self.assertTrue(layer.isSpatial()) layer.startEditing() self.assertEqual(layer.splitFeatures([QgsPointXY(0.5, -0.5), QgsPointXY(0.5, 1.5)], 0), 0) self.assertEqual(layer.splitFeatures([QgsPointXY(-0.5, 0.5), QgsPointXY(1.5, 0.5)], 0), 0) self.assertTrue(layer.commitChanges())
def create_layer(name, attributes): layer = QgsVectorLayer("Polygon", name, "memory") pr = layer.dataProvider() layer.startEditing() pr.addAttributes(attributes) layer.updateFields() layer.commitChanges() QgsMapLayerRegistry.instance().addMapLayer(layer) return layer
def addParcelleMap(self): ''' Add content in the first page with a map and basic information ''' # First add headers for key, item in list(self.composerTemplates.items()): if 'sticky' in item: self.buildComposerLabel(key, item, 0) # Get feature extent exp = QgsExpression('"geo_parcelle" = \'%s\'' % self.geo_parcelle) request = QgsFeatureRequest(exp) extent = None features = self.layer.getFeatures(request) for feature in features: geom = feature.geometry() peri = geom.length() buf = peri / 20 extent = geom.buffer(buf,5).boundingBox() # Add memory layer to highlight parcelle if extent: if self.redlineLayer: self.mProject.removeMapLayer(self.redlineLayer.id()) crs = self.layer.crs().authid() vl = QgsVectorLayer("Polygon?crs=" + crs, "temporary", "memory") pr = vl.dataProvider() vl.startEditing() pr.addFeatures([f for f in self.layer.getFeatures(request)]) vl.commitChanges() vl.updateExtents() props = vl.renderer().symbol().symbolLayer(0).properties() props['outline_width'] = u'1' props['outline_color'] = u'0,85,255,255' props['outline_style'] = u'solid' props['style'] = u'no' vl.renderer().setSymbol(QgsFillSymbol.createSimple(props)) self.mProject.addMapLayer(vl) self.redlineLayer = vl # Add composer map & to parcelle miLayers = self.mInstance.layers() miLayers.insert( 0, vl ) cm = QgsLayoutItemMap(self.currentComposition) cm.updateBoundingRect() cm.setRect(QRectF(0, 0, 286, 190)) cm.setPos(6,15) cm.setLayers(self.mProject.mapThemeCollection().masterVisibleLayers()) if extent: cm.zoomToExtent(extent) cm.setFrameEnabled(True) cm.setBackgroundEnabled(True) self.currentComposition.addItem(cm)
def copyInMemory(vLayer, copyName=''): """Return a memory copy of a layer Input origLayer: layer copyName: the name of the copy Output memory copy of a layer """ if copyName is '': copyName = vLayer.name() + ' TMP' if vLayer.type() == QgsMapLayer.VectorLayer: vType = vLayer.geometryType() if vType == QGis.Point: typeStr = 'Point' elif vType == QGis.Line: typeStr = 'Line' elif vType == QGis.Polygon: typeStr = 'Polygon' else: raise MemoryLayerCreationError('Layer is whether Point nor ' 'Line nor Polygon') else: raise MemoryLayerCreationError('Layer is not a VectorLayer') crs = vLayer.crs().authid().toLower() myUUID = str(uuid.uuid4()) uri = '%s?crs=%s&index=yes&uuid=%s' % (typeStr, crs, myUUID) memLayer = QgsVectorLayer(uri, copyName, 'memory') memProvider = memLayer.dataProvider() vProvider = vLayer.dataProvider() vAttrs = vProvider.attributeIndexes() vFields = vProvider.fields() fields = [] for i in vFields: fields.append(vFields[i]) memProvider.addAttributes(fields) vProvider.select(vAttrs) ft = QgsFeature() while vProvider.nextFeature(ft): memProvider.addFeatures([ft]) if qgisVersion() <= 10800: # Next two lines a workaround for a QGIS bug (lte 1.8) # preventing mem layer attributes being saved to shp. memLayer.startEditing() memLayer.commitChanges() return memLayer
def test_SplitTruToCreateCutEdge(self): """Try to creat a cut edge""" layer = QgsVectorLayer("dbname=test.sqlite table=test_pg (geometry)", "test_pg", "spatialite") assert(layer.isValid()) assert(layer.hasGeometryType()) layer.featureCount() == 1 or die("wrong number of features") layer.startEditing() layer.splitFeatures([QgsPoint(1.5, -0.5), QgsPoint(1.5, 1.5)], 0) == 0 or die("error when trying to create an invalid polygon in split") layer.commitChanges() or die("this commit should work") layer.featureCount() == 1 or die("wrong number of features, polygon should be unafected by cut")
def test_SplitFeature(self): """Create spatialite database""" layer = QgsVectorLayer("dbname=%s table=test_pg (geometry)" % self.dbname, "test_pg", "spatialite") self.assertTrue(layer.isValid()) self.assertTrue(layer.hasGeometryType()) layer.startEditing() self.assertEqual(layer.splitFeatures([QgsPoint(0.5, -0.5), QgsPoint(0.5, 1.5)], 0), 0) self.assertEqual(layer.splitFeatures([QgsPoint(-0.5, 0.5), QgsPoint(1.5, 0.5)], 0), 0) self.assertTrue(layer.commitChanges()) self.assertEqual(layer.featureCount(), 4)
def testFieldsWithSpecialCharacters(self): ml = QgsVectorLayer("Point?srid=EPSG:4326&field=123:int", "mem_with_nontext_fieldnames", "memory") self.assertEqual(ml.isValid(), True) QgsProject.instance().addMapLayer(ml) ml.startEditing() self.assertTrue(ml.addAttribute(QgsField('abc:123', QVariant.String))) self.assertTrue(ml.addAttribute(QgsField('map', QVariant.String))) # matches QGIS expression function name f1 = QgsFeature(ml.fields()) f1.setGeometry(QgsGeometry.fromWkt('POINT(0 0)')) f1.setAttributes([1, 'a', 'b']) f2 = QgsFeature(ml.fields()) f2.setGeometry(QgsGeometry.fromWkt('POINT(1 1)')) f2.setAttributes([2, 'c', 'd']) ml.addFeatures([f1, f2]) ml.commitChanges() vl = QgsVectorLayer("?query=select * from mem_with_nontext_fieldnames", "vl", "virtual") self.assertEqual(vl.isValid(), True) self.assertEqual(vl.fields().at(0).name(), '123') self.assertEqual(vl.fields().at(1).name(), 'abc:123') self.assertEqual(vl.featureCount(), 2) features = [f for f in vl.getFeatures(QgsFeatureRequest().setFilterExpression('"abc:123"=\'c\''))] self.assertEqual(len(features), 1) self.assertEqual(features[0].attributes(), [2, 'c', 'd']) features = [f for f in vl.getFeatures(QgsFeatureRequest().setFilterExpression('"map"=\'b\''))] self.assertEqual(len(features), 1) self.assertEqual(features[0].attributes(), [1, 'a', 'b']) vl2 = QgsVectorLayer("?query=select * from mem_with_nontext_fieldnames where \"abc:123\"='c'", "vl", "virtual") self.assertEqual(vl2.isValid(), True) self.assertEqual(vl2.fields().at(0).name(), '123') self.assertEqual(vl2.fields().at(1).name(), 'abc:123') self.assertEqual(vl2.featureCount(), 1) features = [f for f in vl2.getFeatures()] self.assertEqual(len(features), 1) self.assertEqual(features[0].attributes(), [2, 'c', 'd']) vl3 = QgsVectorLayer("?query=select * from mem_with_nontext_fieldnames where \"map\"='b'", "vl", "virtual") self.assertEqual(vl3.isValid(), True) self.assertEqual(vl3.fields().at(0).name(), '123') self.assertEqual(vl3.fields().at(1).name(), 'abc:123') self.assertEqual(vl3.featureCount(), 1) features = [f for f in vl3.getFeatures()] self.assertEqual(len(features), 1) self.assertEqual(features[0].attributes(), [1, 'a', 'b']) QgsProject.instance().removeMapLayer(ml)
def create_layer(self, parameters, name, is_memory, dest_crs, layer_style=None): save_as = parameters.file_path file_format = parameters.file_format # save paramaters serialized = base64.b64encode(parameters.serialize(with_style=False, with_geometry=False)) # save geometry layer = QgsVectorLayer("MultiPolygon?crs=%s" % dest_crs.authid(), name, "memory") pr = layer.dataProvider() layer.startEditing() layer.addAttribute(QgsField("params", QVariant.String)) fet1 = QgsFeature(0) fet1.setFields(layer.fields()) fet1.setAttribute("params", str(serialized)[2:-1]) fet1.setGeometry(parameters.geometry) pr.addFeatures([fet1]) layer.commitChanges() # copy layer style if layer_style is not None: self.set_layer_style(layer, layer_style) if is_memory: return layer if os.path.isfile(save_as): # delete first if already exists if save_as.endswith(".shp"): QgsVectorFileWriter.deleteShapeFile(save_as) else: os.unlink(save_as) # create the disk layer QgsMessageLog.logMessage("Mask saving '{}' as {}".format(save_as, file_format), 'Extensions') error = QgsVectorFileWriter.writeAsVectorFormat(layer, save_as, "System", dest_crs, file_format) if error == 0: nlayer = QgsVectorLayer(save_as, name, "ogr") if not nlayer.dataProvider().isValid(): return None if not nlayer.hasGeometryType(): return None # force CRS nlayer.setCrs(dest_crs) # copy layer style layer_style = self.get_layer_style(layer) self.set_layer_style(nlayer, layer_style) return nlayer else: raise RuntimeError(error) return None
def testVectorLayerUtilsUniqueWithProviderDefault(self): vl = QgsVectorLayer('%s table="qgis_test"."someData" sql=' % (self.dbconn), "someData", "postgres") default_clause = "nextval('qgis_test.\"someData_pk_seq\"'::regclass)" self.assertEqual(vl.dataProvider().defaultValueClause(0), default_clause) self.assertTrue(QgsVectorLayerUtils.valueExists(vl, 0, 4)) vl.startEditing() f = QgsFeature(vl.fields()) f.setAttribute(0, default_clause) self.assertTrue(vl.addFeatures([f])) self.assertFalse(QgsVectorLayerUtils.valueExists(vl, 0, default_clause))
def test_SplitMultipolygon(self): """Split multipolygon""" layer = QgsVectorLayer("dbname=test.sqlite table=test_mpg (geometry)", "test_mpg", "spatialite") assert(layer.isValid()) assert(layer.hasGeometryType()) layer.featureCount() == 1 or die("wrong number of features") layer.startEditing() layer.splitFeatures([QgsPoint(0.5, -0.5), QgsPoint(0.5, 1.5)], 0) == 0 or die("error in split of one polygon of multipolygon") layer.splitFeatures([QgsPoint(2.5, -0.5), QgsPoint(2.5, 4)], 0) == 0 or die("error in split of two polygons of multipolygon at a time") layer.commitChanges() or die("this commit should work") layer.featureCount() == 7 or die("wrong number of features after 2 split")
def test_SplitFeature(self): """Create spatialite database""" layer = QgsVectorLayer("dbname=%s table=test_pg (geometry)" % self.dbname, "test_pg", "spatialite") assert(layer.isValid()) assert(layer.hasGeometryType()) layer.startEditing() layer.splitFeatures([QgsPoint(0.5, -0.5), QgsPoint(0.5, 1.5)], 0) == 0 or die("error in split") layer.splitFeatures([QgsPoint(-0.5, 0.5), QgsPoint(1.5, 0.5)], 0) == 0 or die("error in split") if not layer.commitChanges(): die("this commit should work") layer.featureCount() == 4 or die("we should have 4 features after 2 split")
def create_layer_bk(download_path, tmp_layer, indicator, indicator_name, data, year): tmp_data_provider = tmp_layer.dataProvider() tmp_layer.startEditing() tmp_feature = QgsFeature() # get world bank data # data = get_world_bank_data(indicator, year) # getting layer_name layer_name = indicator_name + " (" + year + ")" clean_layer_name = re.sub('\W+', '_', indicator_name) + "_" + year # creating output path # output_base_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "output") # if not os.path.exists(output_base_path): # os.mkdir(output_base_path) # retrieving input shp # output_file = os.path.join(output_base_path, clean_layer_name + ".shp") output_file = os.path.join(download_path, clean_layer_name + ".shp") input_base_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "resources") # copy resource file to output # resource_files = glob.glob(os.path.join(input_base_path, "ne_110m_admin_0_*")) resource_files = glob.glob(os.path.join(input_base_path, "ne_110m_admin_0_*")) for resource_file in resource_files: base, extension = os.path.splitext(resource_file) copyfile(resource_file, os.path.join(download_path, clean_layer_name + extension)) # Editing output_file layer = QgsVectorLayer(output_file, layer_name, "ogr") layer.startEditing() # TODO: add data check instead of the addedValue boolean? addedValue = False for feat in layer.getFeatures(): if feat['iso_a2'] is not None: for d in data: code = d['country']['id'] value = d['value'] if code == feat['iso_a2']: if value: # TODO: automatize the index 5 of feat['iso_a2'] layer.changeAttributeValue(feat.id(), 5, float(value)) tmp_feature.setAttributes([float(value)]) # TODO add all togheter tmp_data_provider.addFeatures([tmp_feature]) addedValue = True break layer.commitChanges() return layer, addedValue
class RightOfWay(QObject): def __init__(self, iface, qgis_utils): QObject.__init__(self) self.qgis_utils = qgis_utils self.iface = iface self.log = QgsApplication.messageLog() self._layers = { PLOT_TABLE: { 'name': PLOT_TABLE, 'geometry': QgsWkbTypes.PolygonGeometry, LAYER: None }, RIGHT_OF_WAY_TABLE: { 'name': RIGHT_OF_WAY_TABLE, 'geometry': QgsWkbTypes.PolygonGeometry, LAYER: None }, SURVEY_POINT_TABLE: { 'name': SURVEY_POINT_TABLE, 'geometry': None, LAYER: None } } self._right_of_way_line_layer = None self.addedFeatures = None def prepare_right_of_way_creation(self, db, iface): # Load layers self.add_db_required_layers(db) # Disable transactions groups and configure Snapping self.set_layers_settings() # Don't suppress feature form form_config = self._layers[RIGHT_OF_WAY_TABLE][LAYER].editFormConfig() form_config.setSuppress(QgsEditFormConfig.SuppressOff) self._layers[RIGHT_OF_WAY_TABLE][LAYER].setEditFormConfig(form_config) # Enable edition mode iface.layerTreeView().setCurrentLayer( self._layers[RIGHT_OF_WAY_TABLE][LAYER]) self._layers[RIGHT_OF_WAY_TABLE][LAYER].startEditing() iface.actionAddFeature().trigger() iface.messageBar().pushMessage( 'Asistente LADM_COL', QCoreApplication.translate( "CreateRightOfWayCadastreWizard", "You can now start capturing right of ways digitizing on the map..." ), Qgis.Info) def prepare_right_of_way_line_creation(self, db, translatable_config_strings, iface, width_value): # Load layers self.add_db_required_layers(db) # Add Memory line layer self._right_of_way_line_layer = QgsVectorLayer( "MultiLineString?crs=EPSG:{}".format(DEFAULT_EPSG), translatable_config_strings.RIGHT_OF_WAY_LINE_LAYER, "memory") QgsProject.instance().addMapLayer(self._right_of_way_line_layer, True) # Disable transactions groups and configure Snapping self.set_layers_settings() # Suppress feature form form_config = self._right_of_way_line_layer.editFormConfig() form_config.setSuppress(QgsEditFormConfig.SuppressOn) self._right_of_way_line_layer.setEditFormConfig(form_config) # Enable edition mode iface.layerTreeView().setCurrentLayer(self._right_of_way_line_layer) self._right_of_way_line_layer.startEditing() iface.actionAddFeature().trigger() self._right_of_way_line_layer.featureAdded.connect( self.store_features_ids) self._right_of_way_line_layer.editCommandEnded.connect( self.update_attributes_after_adding) self._right_of_way_line_layer.committedFeaturesAdded.connect( partial(self.finish_right_of_way_line, width_value, iface)) iface.messageBar().pushMessage( 'Asistente LADM_COL', QCoreApplication.translate( "CreateRightOfWayCadastreWizard", "You can now start capturing right of way lines digitizing on the map..." ), Qgis.Info) def set_layers_settings(self): # Disable transactions groups QgsProject.instance().setAutoTransaction(False) # Configure Snapping snapping = QgsProject.instance().snappingConfig() snapping.setEnabled(True) snapping.setMode(QgsSnappingConfig.AllLayers) snapping.setType(QgsSnappingConfig.Vertex) snapping.setUnits(QgsTolerance.Pixels) snapping.setTolerance(9) QgsProject.instance().setSnappingConfig(snapping) def add_db_required_layers(self, db): # Load layers self.qgis_utils.get_layers(db, self._layers, load=True) if not self._layers: return None form_config = self._layers[RIGHT_OF_WAY_TABLE][LAYER].editFormConfig() form_config.setSuppress(QgsEditFormConfig.SuppressOff) self._layers[RIGHT_OF_WAY_TABLE][LAYER].setEditFormConfig(form_config) def store_features_ids(self, featId): """ This method only stores featIds in a class variable. It's required to avoid a bug with SLOTS connected to featureAdded. """ self.addedFeatures = featId def update_attributes_after_adding(self): layer = self.sender() # Get the layer that has sent the signal layer.featureAdded.disconnect(self.store_features_ids) self.log.logMessage( "RigthOfWayLine's featureAdded SIGNAL disconnected", PLUGIN_NAME, Qgis.Info) res = layer.commitChanges() QgsProject.instance().removeMapLayer(layer) self.addedFeatures = None def finish_right_of_way_line(self, width_value, iface): self._right_of_way_line_layer.committedFeaturesAdded.disconnect() self.log.logMessage( "RigthOfWayLine's committedFeaturesAdded SIGNAL disconnected", PLUGIN_NAME, Qgis.Info) params = { 'INPUT': self._right_of_way_line_layer, 'DISTANCE': width_value, 'SEGMENTS': 5, 'END_CAP_STYLE': 1, # Flat 'JOIN_STYLE': 2, 'MITER_LIMIT': 2, 'DISSOLVE': False, 'OUTPUT': 'memory:' } buffered_right_of_way_layer = processing.run("native:buffer", params)['OUTPUT'] buffer_geometry = buffered_right_of_way_layer.getFeature(1).geometry() feature = QgsVectorLayerUtils().createFeature( self._layers[RIGHT_OF_WAY_TABLE][LAYER], buffer_geometry) if feature: self._layers[RIGHT_OF_WAY_TABLE][LAYER].startEditing() self._layers[RIGHT_OF_WAY_TABLE][LAYER].addFeature(feature) form = iface.getFeatureForm( self._layers[RIGHT_OF_WAY_TABLE][LAYER], feature) form.show() def fill_right_of_way_relations(self, db): layers = { ADMINISTRATIVE_SOURCE_TABLE: { 'name': ADMINISTRATIVE_SOURCE_TABLE, 'geometry': None, LAYER: None }, PARCEL_TABLE: { 'name': PARCEL_TABLE, 'geometry': None, LAYER: None }, PLOT_TABLE: { 'name': PLOT_TABLE, 'geometry': QgsWkbTypes.PolygonGeometry, LAYER: None }, RESTRICTION_TABLE: { 'name': RESTRICTION_TABLE, 'geometry': None, LAYER: None }, RIGHT_OF_WAY_TABLE: { 'name': RIGHT_OF_WAY_TABLE, 'geometry': QgsWkbTypes.PolygonGeometry, LAYER: None }, RRR_SOURCE_RELATION_TABLE: { 'name': RRR_SOURCE_RELATION_TABLE, 'geometry': None, LAYER: None }, SURVEY_POINT_TABLE: { 'name': SURVEY_POINT_TABLE, 'geometry': None, LAYER: None }, UEBAUNIT_TABLE: { 'name': UEBAUNIT_TABLE, 'geometry': None, LAYER: None } } # Load layers self.qgis_utils.get_layers(db, layers, load=True) if not layers: return None if layers[PLOT_TABLE][LAYER].selectedFeatureCount( ) == 0 or layers[RIGHT_OF_WAY_TABLE][LAYER].selectedFeatureCount( ) == 0 or layers[ADMINISTRATIVE_SOURCE_TABLE][ LAYER].selectedFeatureCount() == 0: if self.qgis_utils.get_layer_from_layer_tree( db, PLOT_TABLE, geometry_type=QgsWkbTypes.PolygonGeometry) is None: self.qgis_utils.message_with_button_load_layer_emitted.emit( QCoreApplication.translate( "RightOfWay", "First load the layer {} into QGIS and select at least one plot!" ).format(PLOT_TABLE), QCoreApplication.translate( "RightOfWay", "Load layer {} now").format(PLOT_TABLE), [PLOT_TABLE, None], Qgis.Warning) else: self.qgis_utils.message_emitted.emit( QCoreApplication.translate( "RightOfWay", "Select at least one benefited plot, one right of way and at least one administrative source to create relations!" ), Qgis.Warning) return else: ue_baunit_features = layers[UEBAUNIT_TABLE][LAYER].getFeatures() # Get unique pairs id_right_of_way-id_parcel existing_pairs = [ (ue_baunit_feature[UEBAUNIT_TABLE_PARCEL_FIELD], ue_baunit_feature[UEBAUNIT_TABLE_RIGHT_OF_WAY_FIELD]) for ue_baunit_feature in ue_baunit_features ] existing_pairs = set(existing_pairs) plot_ids = [ f[ID_FIELD] for f in layers[PLOT_TABLE][LAYER].selectedFeatures() ] right_of_way_id = layers[RIGHT_OF_WAY_TABLE][ LAYER].selectedFeatures()[0].attribute(ID_FIELD) id_pairs = list() for plot in plot_ids: exp = "\"{uebaunit}\" = {plot}".format( uebaunit=UEBAUNIT_TABLE_PLOT_FIELD, plot=plot) parcels = layers[UEBAUNIT_TABLE][LAYER].getFeatures(exp) for parcel in parcels: id_pair = (parcel.attribute(UEBAUNIT_TABLE_PARCEL_FIELD), right_of_way_id) id_pairs.append(id_pair) if len(id_pairs) < len(plot_ids): # If any relationship plot-parcel is not found, we don't need to continue self.qgis_utils.message_emitted.emit( QCoreApplication.translate( "RightOfWay", "One or more pairs id_plot-id_parcel weren't found, this is needed to create benefited and restriction relations." ), Qgis.Warning) return if id_pairs: new_features = list() for id_pair in id_pairs: if not id_pair in existing_pairs: #Create feature new_feature = QgsVectorLayerUtils().createFeature( layers[UEBAUNIT_TABLE][LAYER]) new_feature.setAttribute(UEBAUNIT_TABLE_PARCEL_FIELD, id_pair[0]) new_feature.setAttribute( UEBAUNIT_TABLE_RIGHT_OF_WAY_FIELD, id_pair[1]) self.log.logMessage( "Saving RightOfWay-Parcel: {}-{}".format( id_pair[1], id_pair[0]), PLUGIN_NAME, Qgis.Info) new_features.append(new_feature) layers[UEBAUNIT_TABLE][LAYER].dataProvider().addFeatures( new_features) self.qgis_utils.message_emitted.emit( QCoreApplication.translate( "RightOfWay", "{} out of {} records were saved into {}! {} out of {} records already existed in the database." ).format(len(new_features), len(id_pairs), UEBAUNIT_TABLE, len(id_pairs) - len(new_features), len(id_pairs)), Qgis.Info) spatial_join_layer = processing.run( "qgis:joinattributesbylocation", { 'INPUT': layers[PLOT_TABLE][LAYER], 'JOIN': QgsProcessingFeatureSourceDefinition( layers[RIGHT_OF_WAY_TABLE][LAYER].id(), True), 'PREDICATE': [0], 'JOIN_FIELDS': [ID_FIELD, RIGHT_OF_WAY_TABLE_IDENTIFICATOR_FIELD], 'METHOD': 0, 'DISCARD_NONMATCHING': True, 'PREFIX': '', 'OUTPUT': 'memory:' })['OUTPUT'] restriction_features = layers[RESTRICTION_TABLE][ LAYER].getFeatures() existing_restriction_pairs = [ (restriction_feature[RESTRICTION_TABLE_PARCEL_FIELD], restriction_feature[RESTRICTION_TABLE_DESCRIPTION_FIELD]) for restriction_feature in restriction_features ] existing_restriction_pairs = set(existing_restriction_pairs) id_pairs_restriction = list() plot_ids = spatial_join_layer.getFeatures() for plot in plot_ids: exp = "\"uebaunit\" = {plot}".format( uebaunit=UEBAUNIT_TABLE_PLOT_FIELD, plot=plot.attribute(ID_FIELD)) parcels = layers[UEBAUNIT_TABLE][LAYER].getFeatures(exp) for parcel in parcels: id_pair_restriction = ( parcel.attribute(UEBAUNIT_TABLE_PARCEL_FIELD), "Asociada a la servidumbre {}".format( plot.attribute( RIGHT_OF_WAY_TABLE_IDENTIFICATOR_FIELD))) id_pairs_restriction.append(id_pair_restriction) new_restriction_features = list() if id_pairs_restriction: for id_pair in id_pairs_restriction: if not id_pair in existing_restriction_pairs: #Create feature new_feature = QgsVectorLayerUtils().createFeature( layers[RESTRICTION_TABLE][LAYER]) new_feature.setAttribute( RESTRICTION_TABLE_PARCEL_FIELD, id_pair[0]) new_feature.setAttribute( RESTRICTION_TABLE_DESCRIPTION_FIELD, id_pair[1]) new_feature.setAttribute( TYPE_FIELD, COL_RESTRICTION_TYPE_RIGHT_OF_WAY_VALUE) self.log.logMessage( "Saving RightOfWay-Parcel: {}-{}".format( id_pair[1], id_pair[0]), PLUGIN_NAME, Qgis.Info) new_restriction_features.append(new_feature) layers[RESTRICTION_TABLE][LAYER].dataProvider().addFeatures( new_restriction_features) self.qgis_utils.message_emitted.emit( QCoreApplication.translate( "RightOfWay", "{} out of {} records were saved into {}! {} out of {} records already existed in the database." ).format( len(new_restriction_features), len(id_pairs_restriction), RESTRICTION_TABLE, len(id_pairs_restriction) - len(new_restriction_features), len(id_pairs_restriction)), Qgis.Info) administrative_source_ids = [ f[ID_FIELD] for f in layers[ADMINISTRATIVE_SOURCE_TABLE] [LAYER].selectedFeatures() ] source_relation_features = layers[RRR_SOURCE_RELATION_TABLE][ LAYER].getFeatures() existing_source_pairs = [ (source_relation_feature[RRR_SOURCE_SOURCE_FIELD], source_relation_feature[RRR_SOURCE_RESTRICTION_FIELD]) for source_relation_feature in source_relation_features ] existing_source_pairs = set(existing_source_pairs) rrr_source_relation_pairs = list() for administrative_source_id in administrative_source_ids: for restriction_feature in new_restriction_features: rrr_source_relation_pair = ( administrative_source_id, restriction_feature.attribute(ID_FIELD)) rrr_source_relation_pairs.append(rrr_source_relation_pair) new_rrr_source_relation_features = list() if rrr_source_relation_pairs: for id_pair in rrr_source_relation_pairs: if not id_pair in existing_source_pairs: new_feature = QgsVectorLayerUtils().createFeature( layers[RRR_SOURCE_RELATION_TABLE][LAYER]) new_feature.setAttribute(RRR_SOURCE_SOURCE_FIELD, id_pair[0]) new_feature.setAttribute(RRR_SOURCE_RESTRICTION_FIELD, id_pair[1]) self.log.logMessage( "Saving Restriction-Source: {}-{}".format( id_pair[1], id_pair[0]), PLUGIN_NAME, Qgis.Info) new_rrr_source_relation_features.append(new_feature) layers[RRR_SOURCE_RELATION_TABLE][LAYER].dataProvider( ).addFeatures(new_rrr_source_relation_features) self.qgis_utils.message_emitted.emit( QCoreApplication.translate( "RightOfWay", "{} out of {} records were saved into {}! {} out of {} records already existed in the database." ).format( len(new_rrr_source_relation_features), len(rrr_source_relation_pairs), RRR_SOURCE_RELATION_TABLE, len(rrr_source_relation_pairs) - len(new_rrr_source_relation_features), len(rrr_source_relation_pairs)), Qgis.Info)
def testInteraction(self): # pylint: disable=too-many-statements """ Test tool interaction """ canvas = QgsMapCanvas() canvas.setDestinationCrs(QgsCoordinateReferenceSystem(4326)) canvas.setFrameStyle(0) canvas.resize(600, 400) self.assertEqual(canvas.width(), 600) self.assertEqual(canvas.height(), 400) layer = QgsVectorLayer("Polygon?crs=epsg:4326&field=fldtxt:string", "layer", "memory") f = QgsFeature() f.setAttributes(['a']) f.setGeometry(QgsGeometry.fromRect(QgsRectangle(5, 32, 15, 45))) f2 = QgsFeature() f2.setAttributes(['b']) f2.setGeometry(QgsGeometry.fromRect(QgsRectangle(15, 25, 18, 45))) success, (f, f2) = layer.dataProvider().addFeatures([f, f2]) self.assertTrue(success) canvas.setLayers([layer]) canvas.setExtent(QgsRectangle(10, 30, 20, 35)) canvas.show() handler = RedistrictHandler(layer, 'fldtxt') factory = DecoratorFactory() registry = DistrictRegistry(districts=['a', 'b']) tool = InteractiveRedistrictingTool(canvas, handler, district_registry=registry, decorator_factory=factory) # mouse over a feature's interior point = canvas.mapSettings().mapToPixel().transform(20, 33) event = QgsMapMouseEvent(canvas, QEvent.MouseMove, QPoint(point.x(), point.y())) tool.canvasMoveEvent(event) self.assertFalse(tool.is_active) self.assertFalse(tool.snap_indicator.match().isValid()) # mouse over a single feature's boundary (not valid district boundary) point = canvas.mapSettings().mapToPixel().transform(5, 33) event = QgsMapMouseEvent(canvas, QEvent.MouseMove, QPoint(point.x(), point.y())) tool.canvasMoveEvent(event) self.assertFalse(tool.is_active) self.assertFalse(tool.snap_indicator.match().isValid()) # mouse over a two feature's boundary (valid district boundary) point = canvas.mapSettings().mapToPixel().transform(15, 33) event = QgsMapMouseEvent(canvas, QEvent.MouseMove, QPoint(point.x(), point.y())) tool.canvasMoveEvent(event) self.assertFalse(tool.is_active) self.assertTrue(tool.snap_indicator.match().isValid()) # avoid segfault tool.snap_indicator.setMatch(QgsPointLocator.Match()) # clicks to ignore point = canvas.mapSettings().mapToPixel().transform(10, 33) event = QgsMapMouseEvent(canvas, QEvent.MouseButtonPress, QPoint(point.x(), point.y()), Qt.MidButton) tool.canvasPressEvent(event) self.assertFalse(tool.is_active) event = QgsMapMouseEvent(canvas, QEvent.MouseButtonPress, QPoint(point.x(), point.y()), Qt.RightButton) tool.canvasPressEvent(event) self.assertFalse(tool.is_active) # click over bad area point = canvas.mapSettings().mapToPixel().transform(10, 30) event = QgsMapMouseEvent(canvas, QEvent.MouseButtonPress, QPoint(point.x(), point.y()), Qt.LeftButton) tool.canvasPressEvent(event) self.assertFalse(tool.is_active) # click over feature area layer.startEditing() point = canvas.mapSettings().mapToPixel().transform(10, 33) event = QgsMapMouseEvent(canvas, QEvent.MouseButtonPress, QPoint(point.x(), point.y()), Qt.LeftButton) tool.canvasPressEvent(event) self.assertTrue(tool.is_active) self.assertEqual(tool.click_point.x(), 10) self.assertEqual(tool.click_point.y(), 33) self.assertEqual(tool.districts, {'a'}) self.assertFalse(tool.modified) # now move over current feature - should do nothing! point = canvas.mapSettings().mapToPixel().transform(10, 33) event = QgsMapMouseEvent(canvas, QEvent.MouseMove, QPoint(point.x(), point.y())) tool.canvasMoveEvent(event) self.assertTrue(tool.is_active) self.assertFalse(tool.modified) # move over other feature self.assertEqual(layer.getFeature(f2.id())[0], 'b') point = canvas.mapSettings().mapToPixel().transform(16, 33) event = QgsMapMouseEvent(canvas, QEvent.MouseMove, QPoint(point.x(), point.y())) tool.canvasMoveEvent(event) self.assertTrue(tool.is_active) self.assertEqual(tool.modified, {f2.id()}) self.assertEqual(tool.current_district, 'a') self.assertEqual(layer.getFeature(f2.id())[0], 'a') # move over nothing point = canvas.mapSettings().mapToPixel().transform(26, 33) event = QgsMapMouseEvent(canvas, QEvent.MouseMove, QPoint(point.x(), point.y())) tool.canvasMoveEvent(event) self.assertTrue(tool.is_active) self.assertEqual(tool.modified, {f2.id()}) # left click - commit changes event = QgsMapMouseEvent(canvas, QEvent.MouseButtonPress, QPoint(point.x(), point.y()), Qt.LeftButton) tool.canvasPressEvent(event) self.assertFalse(tool.is_active) layer.rollBack() layer.startEditing() # add a decorator tool.decorator_factory = TestDecoratorFactory() # now try with clicks over boundary point = canvas.mapSettings().mapToPixel().transform(15, 33) event = QgsMapMouseEvent(canvas, QEvent.MouseButtonPress, QPoint(point.x(), point.y()), Qt.LeftButton) tool.canvasPressEvent(event) self.assertTrue(tool.is_active) self.assertEqual(tool.click_point.x(), 15) self.assertEqual(tool.click_point.y(), 33) self.assertEqual(tool.districts, {'a', 'b'}) self.assertFalse(tool.modified) # move left self.assertEqual(layer.getFeature(f.id())[0], 'a') self.assertEqual(layer.getFeature(f2.id())[0], 'b') point = canvas.mapSettings().mapToPixel().transform(10, 33) event = QgsMapMouseEvent(canvas, QEvent.MouseMove, QPoint(point.x(), point.y())) tool.canvasMoveEvent(event) self.assertTrue(tool.is_active) self.assertEqual(tool.modified, {f.id()}) self.assertEqual(tool.current_district, 'b') self.assertEqual(layer.getFeature(f.id())[0], 'b') self.assertEqual(layer.getFeature(f2.id())[0], 'b') # move over nothing point = canvas.mapSettings().mapToPixel().transform(26, 33) event = QgsMapMouseEvent(canvas, QEvent.MouseMove, QPoint(point.x(), point.y())) tool.canvasMoveEvent(event) self.assertTrue(tool.is_active) self.assertEqual(tool.modified, {f.id()}) # right click - discard changes event = QgsMapMouseEvent(canvas, QEvent.MouseButtonPress, QPoint(point.x(), point.y()), Qt.RightButton) tool.canvasPressEvent(event) self.assertFalse(tool.is_active) self.assertEqual(layer.getFeature(f.id())[0], 'a') self.assertEqual(layer.getFeature(f2.id())[0], 'b') # try again, move right point = canvas.mapSettings().mapToPixel().transform(15, 33) event = QgsMapMouseEvent(canvas, QEvent.MouseButtonPress, QPoint(point.x(), point.y()), Qt.LeftButton) tool.canvasPressEvent(event) self.assertTrue(tool.is_active) self.assertEqual(tool.click_point.x(), 15) self.assertEqual(tool.click_point.y(), 33) self.assertEqual(tool.districts, {'a', 'b'}) self.assertFalse(tool.modified) # move right self.assertEqual(layer.getFeature(f.id())[0], 'a') self.assertEqual(layer.getFeature(f2.id())[0], 'b') point = canvas.mapSettings().mapToPixel().transform(17, 33) event = QgsMapMouseEvent(canvas, QEvent.MouseMove, QPoint(point.x(), point.y())) tool.canvasMoveEvent(event) self.assertTrue(tool.is_active) self.assertEqual(tool.modified, {f2.id()}) self.assertEqual(tool.current_district, 'a') self.assertEqual(layer.getFeature(f.id())[0], 'a') self.assertEqual(layer.getFeature(f2.id())[0], 'a') event = QgsMapMouseEvent(canvas, QEvent.MouseButtonPress, QPoint(point.x(), point.y()), Qt.RightButton) tool.canvasPressEvent(event) self.assertFalse(tool.is_active) self.assertEqual(layer.getFeature(f.id())[0], 'a') self.assertEqual(layer.getFeature(f2.id())[0], 'b') layer.rollBack()
def testFullExtent(self): p = QgsProject() p.setCrs(QgsCoordinateReferenceSystem('EPSG:3857')) self.assertTrue(p.viewSettings().fullExtent().isNull()) p.viewSettings().setPresetFullExtent( QgsReferencedRectangle(QgsRectangle(1, 2, 3, 4), QgsCoordinateReferenceSystem("EPSG:4326"))) self.assertAlmostEqual(p.viewSettings().fullExtent().xMinimum(), 111319, -1) self.assertAlmostEqual(p.viewSettings().fullExtent().xMaximum(), 333958, -1) self.assertAlmostEqual(p.viewSettings().fullExtent().yMinimum(), 222684, -1) self.assertAlmostEqual(p.viewSettings().fullExtent().yMaximum(), 445640, -1) self.assertEqual(p.viewSettings().fullExtent().crs().authid(), 'EPSG:3857') # add layers shapefile = os.path.join(TEST_DATA_DIR, 'polys.shp') layer = QgsVectorLayer(shapefile, 'Polys', 'ogr') p.addMapLayer(layer) # no change, because preset extent is set self.assertAlmostEqual(p.viewSettings().fullExtent().xMinimum(), 111319, -1) self.assertAlmostEqual(p.viewSettings().fullExtent().xMaximum(), 333958, -1) self.assertAlmostEqual(p.viewSettings().fullExtent().yMinimum(), 222684, -1) self.assertAlmostEqual(p.viewSettings().fullExtent().yMaximum(), 445640, -1) self.assertEqual(p.viewSettings().fullExtent().crs().authid(), 'EPSG:3857') # remove preset extent p.viewSettings().setPresetFullExtent(QgsReferencedRectangle()) # extent should come from layers self.assertAlmostEqual(p.viewSettings().fullExtent().xMinimum(), -13238432, -2) self.assertAlmostEqual(p.viewSettings().fullExtent().xMaximum(), -9327461, -2) self.assertAlmostEqual(p.viewSettings().fullExtent().yMinimum(), 2815417, -2) self.assertAlmostEqual(p.viewSettings().fullExtent().yMaximum(), 5897492, -2) self.assertEqual(p.viewSettings().fullExtent().crs().authid(), 'EPSG:3857') # add another layer shapefile = os.path.join(TEST_DATA_DIR, 'lines.shp') layer = QgsVectorLayer(shapefile, 'Lines', 'ogr') p.addMapLayer(layer) self.assertAlmostEqual(p.viewSettings().fullExtent().xMinimum(), -13238432, -2) self.assertAlmostEqual(p.viewSettings().fullExtent().xMaximum(), -9164115, -2) self.assertAlmostEqual(p.viewSettings().fullExtent().yMinimum(), 2657217, -2) self.assertAlmostEqual(p.viewSettings().fullExtent().yMaximum(), 5897492, -2) self.assertEqual(p.viewSettings().fullExtent().crs().authid(), 'EPSG:3857') # add a layer with a different crs layer = QgsVectorLayer( "Point?crs=EPSG:3857&field=fldtxt:string&field=fldint:integer", "x", "memory") p.addMapLayer(layer) f = QgsFeature() f.setAttributes(["test", 123]) f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(-8164115, 5997492))) layer.startEditing() layer.addFeatures([f]) layer.commitChanges() self.assertAlmostEqual(p.viewSettings().fullExtent().xMinimum(), -13238432, -2) self.assertAlmostEqual(p.viewSettings().fullExtent().xMaximum(), -8164115, -2) self.assertAlmostEqual(p.viewSettings().fullExtent().yMinimum(), 2657217, -2) self.assertAlmostEqual(p.viewSettings().fullExtent().yMaximum(), 5997492, -2) self.assertEqual(p.viewSettings().fullExtent().crs().authid(), 'EPSG:3857')
def link_irrig_swat(self): QSWATMOD_path_dict = self.dirs_and_paths() output_dir = QSWATMOD_path_dict['Scenarios'] name_ext = "irrig_swat_grid.shp" irrig_swat_grid = os.path.join(output_dir, name_ext) # Create layer field layer_swat_col = QgsVectorLayer(irrig_swat_grid, '{0}'.format("irrig_swat_grid"), 'ogr') lyrProvider = layer_swat_col.dataProvider() if lyrProvider.fields().indexFromName('layer') == -1: lyr_field = QgsField('layer', QVariant.Int) lyrProvider.addAttributes([lyr_field]) layer_swat_col.updateFields() # Get the index numbers of the fields lyrIdx = lyrProvider.fields().indexFromName('layer') # Get features (Find out a way to change attribute values using another field) feats = layer_swat_col.getFeatures() layer_swat_col.startEditing() # add layer number for f in feats: layer_swat_col.changeAttributeValue(f.id(), lyrIdx, 1) layer_swat_col.commitChanges() # Join sub and hru id n3_ext = "irrig_swat_grid_s.shp" irrig_swat_grid_s = os.path.join(output_dir, n3_ext) # QgsVectorFileWriter.deleteShapeFile(irrig_mf_s) sub_shp = QgsProject.instance().mapLayersByName("sub (SWAT)")[0] processing.run( "qgis:joinattributesbylocation", irrig_swat_grid, sub_shp, ['intersects'],0,0,"sum,mean,min,max,median",0, irrig_swat_grid_s) # Join sub id n4_ext = "irrig_swat_grid_f.shp" irrig_swat_grid_f = os.path.join(output_dir, n4_ext) # QgsVectorFileWriter.deleteShapeFile(irrig_mf_f) hru_shp = QgsProject.instance().mapLayersByName("hru (SWAT)")[0] processing.run( "qgis:joinattributesbylocation", irrig_swat_grid_s, hru_shp, ['intersects'],0,0,"sum,mean,min,max,median",0, irrig_swat_grid_f) layer_swat = QgsVectorLayer(irrig_swat_grid_f, '{0}'.format("irrig_swat"), 'ogr') QgsProject.instance().addMapLayer(layer_swat, False) root = QgsProject.instance().layerTreeRoot() p_swat_tree = root.findGroup("Pumping from SWAT") p_swat_tree.insertChildNode(0, QgsLayerTreeLayer(layer_swat)) self.dlg.lineEdit_irrig_swat_grids.setText(irrig_swat_grid_f) # delete unnecessary fields input2 = QgsProject.instance().mapLayersByName("irrig_swat")[0] fields = input2.dataProvider() fdname = [ fields.indexFromName(field.name()) for field in fields.fields() if not ( field.name() == 'Subbasin' or field.name() == 'row' or field.name() == 'col' or field.name() == 'HRU_ID' or field.name() == 'layer')] fields.deleteAttributes(fdname) input2.updateFields() msgBox.setWindowTitle("Created!") msgBox.setText( "'irrig_swat.shp' file has been created!\n"+ "If you have multiple HRUs for a well, open its Attribute table and modify it." ) msgBox.exec_()
def polygonize(layer, callback=None): """Polygonize a raster layer into a vector layer using GDAL. Issue https://github.com/inasafe/inasafe/issues/3183 :param layer: The layer to reproject. :type layer: QgsRasterLayer :param callback: A function to all to indicate progress. The function should accept params 'current' (int) and 'maximum' (int). Defaults to None. :type callback: function :return: Reprojected memory layer. :rtype: QgsRasterLayer .. versionadded:: 4.0 """ output_layer_name = polygonize_steps['output_layer_name'] processing_step = polygonize_steps['step_name'] output_layer_name = output_layer_name % layer.keywords['layer_purpose'] gdal_layer_name = polygonize_steps['gdal_layer_name'] if layer.keywords.get('layer_purpose') == 'exposure': output_field = exposure_type_field else: output_field = hazard_value_field input_raster = gdal.Open(layer.source(), gdal.GA_ReadOnly) srs = osr.SpatialReference() srs.ImportFromWkt(input_raster.GetProjectionRef()) temporary_dir = temp_dir(sub_dir='pre-process') out_shapefile = unique_filename(suffix='-%s.shp' % output_layer_name, dir=temporary_dir) driver = ogr.GetDriverByName("ESRI Shapefile") destination = driver.CreateDataSource(out_shapefile) output_layer = destination.CreateLayer(gdal_layer_name, srs) # We have no other way to use a shapefile. We need only the first 10 chars. field_name = output_field['field_name'][0:10] fd = ogr.FieldDefn(field_name, ogr.OFTInteger) output_layer.CreateField(fd) input_band = input_raster.GetRasterBand(1) # Fixme : add our own callback to Polygonize gdal.Polygonize(input_band, None, output_layer, 0, [], callback=None) destination.Destroy() vector_layer = QgsVectorLayer(out_shapefile, output_layer_name, 'ogr') # Let's remove polygons which were no data request = QgsFeatureRequest() expression = '"%s" = %s' % (field_name, no_data_value) request.setFilterExpression(expression) vector_layer.startEditing() for feature in vector_layer.getFeatures(request): vector_layer.deleteFeature(feature.id()) vector_layer.commitChanges() # We transfer keywords to the output. vector_layer.keywords = layer.keywords.copy() vector_layer.keywords[ layer_geometry['key']] = layer_geometry_polygon['key'] vector_layer.keywords['title'] = output_layer_name # We just polygonized the raster layer. inasafe_fields do not exist. vector_layer.keywords['inasafe_fields'] = {output_field['key']: field_name} check_layer(vector_layer) return vector_layer
def run(self, surf_sel, sub_sel, i_surf, i_sub, depths, offset): warning_flag = 0 # create layer layer_name = self.orbit.get_instrument() + '_' + self.orbit.get_id( ) + '_' + str(self.band) + '_depth' vl = QgsVectorLayer("Point", layer_name, "memory") pr = vl.dataProvider() # changes are only possible when editing the layer vl.startEditing() # add fields pr.addAttributes([ QgsField("orbit", QtCore.QVariant.Int), QgsField("point_id", QtCore.QVariant.Int), QgsField("band", QtCore.QVariant.Int), QgsField("surf_px", QtCore.QVariant.Double), QgsField("surf_t", QtCore.QVariant.Double), QgsField("surf_sel_x", QtCore.QVariant.Double), QgsField("surf_sel_y", QtCore.QVariant.Double) ]) x_list = [] i_surf_d = dict(zip(i_surf[0], i_surf[1])) i_sub_d = [] depths_d = [] for ii in range(len(depths)): i_sub_d.append(dict(zip(i_sub[ii][0], i_sub[ii][1]))) depths_d.append(dict(zip(depths[ii][0], depths[ii][1]))) pr.addAttributes([ QgsField("sub_" + str(ii) + "_px", QtCore.QVariant.Double), QgsField("sub_" + str(ii) + "_t", QtCore.QVariant.Double), QgsField("sub_" + str(ii) + "_sel_x", QtCore.QVariant.Double), QgsField("sub_" + str(ii) + "_sel_y", QtCore.QVariant.Double), QgsField("depth_" + str(ii) + "_px", QtCore.QVariant.Double), QgsField("depth_" + str(ii) + "_t", QtCore.QVariant.Double) ]) # x_list = x_list+depths[ii][0] x_list = i_surf[0] x_list = list(set(x_list)) x_list.sort() for xx in x_list: surf, sub = self._find_sel(xx, surf_sel, sub_sel) if surf[1] == None: surf_off_1 = None else: surf_off_1 = surf[1] - offset attr_list = [ self.orbit.get_id(), xx, self.band, float(i_surf_d[xx]) - offset, self.orbit.px2t(float(i_surf_d[xx]) - offset), surf[0], surf_off_1 ] feat = self.orbit.get_feature(xx) if not (feat == -1): for ii in range(len(depths)): if sub[ii][1] == None: sub_off_1 = None else: sub_off_1 = sub[ii][1] - offset if i_sub_d[ii].has_key(xx): attr_list = attr_list + [ float(i_sub_d[ii][xx]) - offset, self.orbit.px2t(float(i_sub_d[ii][xx]) - offset), sub[ii][0], sub_off_1, float(depths_d[ii][xx]), self.orbit.px2t(float(depths_d[ii][xx])) ] else: attr_list = attr_list + [None] * 6 new_feat = QgsFeature() new_feat.setGeometry(feat.geometry()) new_feat.setAttributes(attr_list) pr.addFeatures([new_feat]) else: warning_flag = 1 if warning_flag: QtGui.QMessageBox.warning( None, "Warning", "Some surface point is outside the map available features") # commit to stop editing the layer vl.commitChanges() # update layer's extent when new features have been added # because change of extent in provider is not propagated to the layer vl.updateExtents() # add layer to the legend #QgsMapLayerRegistry.instance().addMapLayer(vl) file_name = os.path.join(self.saving_dir, layer_name + '.sqlite') fname = QtGui.QFileDialog().getSaveFileName(self.iface.mainWindow(), 'Depth measure file', file_name, '*.sqlite') QgsVectorFileWriter.writeAsVectorFormat(vl, fname, "utf-8", None, "SQLite") self.iface.addVectorLayer(fname, fname.split('/')[-1][0:-len('.sqlite')], "ogr")
def test_invalidGeometryFilter(self): layer = QgsVectorLayer( "Polygon?field=x:string", "joinlayer", "memory") # add some features, one has invalid geometry pr = layer.dataProvider() f1 = QgsFeature(1) f1.setAttributes(["a"]) f1.setGeometry(QgsGeometry.fromWkt('Polygon((0 0, 1 0, 1 1, 0 1, 0 0))')) # valid f2 = QgsFeature(2) f2.setAttributes(["b"]) f2.setGeometry(QgsGeometry.fromWkt('Polygon((0 0, 1 0, 0 1, 1 1, 0 0))')) # invalid f3 = QgsFeature(3) f3.setAttributes(["c"]) f3.setGeometry(QgsGeometry.fromWkt('Polygon((0 0, 1 0, 1 1, 0 1, 0 0))')) # valid self.assertTrue(pr.addFeatures([f1, f2, f3])) res = [f['x'] for f in layer.getFeatures(QgsFeatureRequest().setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck))] self.assertEqual(res, ['a', 'b', 'c']) res = [f['x'] for f in layer.getFeatures(QgsFeatureRequest().setInvalidGeometryCheck(QgsFeatureRequest.GeometrySkipInvalid))] self.assertEqual(res, ['a', 'c']) res = [f['x'] for f in layer.getFeatures(QgsFeatureRequest().setInvalidGeometryCheck(QgsFeatureRequest.GeometryAbortOnInvalid))] self.assertEqual(res, ['a']) # with callback self.callback_feature_val = None def callback(feature): self.callback_feature_val = feature['x'] res = [f['x'] for f in layer.getFeatures(QgsFeatureRequest().setInvalidGeometryCheck( QgsFeatureRequest.GeometryAbortOnInvalid).setInvalidGeometryCallback(callback))] self.assertEqual(res, ['a']) self.assertEqual(self.callback_feature_val, 'b') # clear callback res = [f['x'] for f in layer.getFeatures(QgsFeatureRequest().setInvalidGeometryCheck( QgsFeatureRequest.GeometryAbortOnInvalid).setInvalidGeometryCallback(None))] self.assertEqual(res, ['a']) # check with filter fids res = [f['x'] for f in layer.getFeatures(QgsFeatureRequest().setFilterFid(f2.id()).setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck))] self.assertEqual(res, ['b']) res = [f['x'] for f in layer.getFeatures(QgsFeatureRequest().setFilterFid(f2.id()).setInvalidGeometryCheck(QgsFeatureRequest.GeometrySkipInvalid))] self.assertEqual(res, []) res = [f['x'] for f in layer.getFeatures(QgsFeatureRequest().setFilterFid(f2.id()).setInvalidGeometryCheck(QgsFeatureRequest.GeometryAbortOnInvalid))] self.assertEqual(res, []) f4 = QgsFeature(4) f4.setAttributes(["d"]) f4.setGeometry(QgsGeometry.fromWkt('Polygon((0 0, 1 0, 0 1, 1 1, 0 0))')) # invalid # check with added features layer.startEditing() self.assertTrue(layer.addFeatures([f4])) res = [f['x'] for f in layer.getFeatures(QgsFeatureRequest().setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck))] self.assertEqual(set(res), {'a', 'b', 'c', 'd'}) res = [f['x'] for f in layer.getFeatures(QgsFeatureRequest().setInvalidGeometryCheck(QgsFeatureRequest.GeometrySkipInvalid))] self.assertEqual(set(res), {'a', 'c'}) res = [f['x'] for f in layer.getFeatures(QgsFeatureRequest().setInvalidGeometryCheck(QgsFeatureRequest.GeometryAbortOnInvalid))] self.assertEqual(res, ['a']) # check with features with changed geometry layer.rollBack() layer.startEditing() layer.changeGeometry(2, QgsGeometry.fromWkt('Polygon((0 0, 1 0, 1 1, 0 1, 0 0))')) # valid layer.changeGeometry(3, QgsGeometry.fromWkt('Polygon((0 0, 1 0, 0 1, 1 1, 0 0))'))# invalid res = [f['x'] for f in layer.getFeatures(QgsFeatureRequest().setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck))] self.assertEqual(set(res), {'a', 'b', 'c'}) res = [f['x'] for f in layer.getFeatures(QgsFeatureRequest().setInvalidGeometryCheck(QgsFeatureRequest.GeometrySkipInvalid))] self.assertEqual(set(res), {'a', 'b'}) res = [f['x'] for f in layer.getFeatures(QgsFeatureRequest().setInvalidGeometryCheck(QgsFeatureRequest.GeometryAbortOnInvalid))] self.assertEqual(res, ['a', 'b']) layer.rollBack()
class TestQgsMapLayerAction(unittest.TestCase): def __init__(self, methodName): """Run once on class initialization.""" unittest.TestCase.__init__(self, methodName) self.vector_layer = QgsVectorLayer( "Point?field=fldtxt:string&field=fldint:integer&field=flddate:datetime", "test_layer", "memory") assert self.vector_layer.isValid() self.vector_layer2 = QgsVectorLayer( "Point?field=fldtxt:string&field=fldint:integer&field=flddate:datetime", "test_layer", "memory") assert self.vector_layer2.isValid() raster_path = os.path.join(unitTestDataPath(), 'landsat.tif') self.raster_layer = QgsRasterLayer(raster_path, 'raster') assert self.raster_layer.isValid() def testCanRunUsingLayer(self): """ Test that actions correctly indicate when they can run for a layer """ action_all_layers = QgsMapLayerAction('action1', None) self.assertTrue(action_all_layers.canRunUsingLayer(None)) self.assertTrue(action_all_layers.canRunUsingLayer(self.vector_layer)) self.assertTrue(action_all_layers.canRunUsingLayer(self.raster_layer)) action_vector_layers_only = QgsMapLayerAction('action2', None, QgsMapLayer.VectorLayer) self.assertFalse(action_vector_layers_only.canRunUsingLayer(None)) self.assertTrue( action_vector_layers_only.canRunUsingLayer(self.vector_layer)) self.assertFalse( action_vector_layers_only.canRunUsingLayer(self.raster_layer)) action_raster_layers_only = QgsMapLayerAction('action3', None, QgsMapLayer.RasterLayer) self.assertFalse(action_raster_layers_only.canRunUsingLayer(None)) self.assertFalse( action_raster_layers_only.canRunUsingLayer(self.vector_layer)) self.assertTrue( action_raster_layers_only.canRunUsingLayer(self.raster_layer)) action_specific_layer_only = QgsMapLayerAction('action4', None, self.vector_layer) self.assertFalse(action_specific_layer_only.canRunUsingLayer(None)) self.assertTrue( action_specific_layer_only.canRunUsingLayer(self.vector_layer)) self.assertFalse( action_specific_layer_only.canRunUsingLayer(self.vector_layer2)) self.assertFalse( action_specific_layer_only.canRunUsingLayer(self.raster_layer)) action_specific_raster_layer_only = QgsMapLayerAction( 'action4', None, self.raster_layer) self.assertFalse( action_specific_raster_layer_only.canRunUsingLayer(None)) self.assertFalse( action_specific_raster_layer_only.canRunUsingLayer( self.vector_layer)) self.assertFalse( action_specific_raster_layer_only.canRunUsingLayer( self.vector_layer2)) self.assertTrue( action_specific_raster_layer_only.canRunUsingLayer( self.raster_layer)) action_editable_layer_only = QgsMapLayerAction( 'action1', None, flags=QgsMapLayerAction.EnabledOnlyWhenEditable) self.assertFalse(action_editable_layer_only.canRunUsingLayer(None)) self.assertFalse( action_editable_layer_only.canRunUsingLayer(self.vector_layer)) self.assertFalse( action_editable_layer_only.canRunUsingLayer(self.vector_layer2)) self.assertFalse( action_editable_layer_only.canRunUsingLayer(self.raster_layer)) self.vector_layer.startEditing() self.assertFalse(action_editable_layer_only.canRunUsingLayer(None)) self.assertTrue( action_editable_layer_only.canRunUsingLayer(self.vector_layer)) self.assertFalse( action_editable_layer_only.canRunUsingLayer(self.vector_layer2)) self.assertFalse( action_editable_layer_only.canRunUsingLayer(self.raster_layer)) self.vector_layer.commitChanges() self.assertFalse(action_editable_layer_only.canRunUsingLayer(None)) self.assertFalse( action_editable_layer_only.canRunUsingLayer(self.vector_layer)) self.assertFalse( action_editable_layer_only.canRunUsingLayer(self.vector_layer2)) self.assertFalse( action_editable_layer_only.canRunUsingLayer(self.raster_layer))
def testGeopackageTwoLayerEdition(self): ''' test https://issues.qgis.org/issues/17034 ''' tmpfile = os.path.join(self.basetestpath, 'testGeopackageTwoLayerEdition.gpkg') ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile) lyr = ds.CreateLayer('layer1', geom_type=ogr.wkbPoint) lyr.CreateField(ogr.FieldDefn('attr', ogr.OFTInteger)) f = ogr.Feature(lyr.GetLayerDefn()) f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(0 0)')) lyr.CreateFeature(f) f = None lyr = ds.CreateLayer('layer2', geom_type=ogr.wkbPoint) lyr.CreateField(ogr.FieldDefn('attr', ogr.OFTInteger)) f = ogr.Feature(lyr.GetLayerDefn()) f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(1 1)')) lyr.CreateFeature(f) f = None ds = None vl1 = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=layer1", u'layer1', u'ogr') vl2 = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=layer2", u'layer2', u'ogr') # Edit vl1, vl2 multiple times self.assertTrue(vl1.startEditing()) self.assertTrue(vl2.startEditing()) self.assertTrue( vl1.changeGeometry(1, QgsGeometry.fromWkt('Point (2 2)'))) self.assertTrue( vl2.changeGeometry(1, QgsGeometry.fromWkt('Point (3 3)'))) self.assertTrue(vl1.commitChanges()) self.assertTrue(vl2.commitChanges()) self.assertTrue(vl1.startEditing()) self.assertTrue(vl2.startEditing()) self.assertTrue(vl1.changeAttributeValue(1, 1, 100)) self.assertTrue(vl2.changeAttributeValue(1, 1, 101)) self.assertTrue(vl1.commitChanges()) self.assertTrue(vl2.commitChanges()) self.assertTrue(vl1.startEditing()) self.assertTrue(vl2.startEditing()) self.assertTrue( vl1.changeGeometry(1, QgsGeometry.fromWkt('Point (4 4)'))) self.assertTrue( vl2.changeGeometry(1, QgsGeometry.fromWkt('Point (5 5)'))) self.assertTrue(vl1.commitChanges()) self.assertTrue(vl2.commitChanges()) vl1 = None vl2 = None # Check everything is as expected after re-opening vl1 = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=layer1", u'layer1', u'ogr') vl2 = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=layer2", u'layer2', u'ogr') got = [feat for feat in vl1.getFeatures()][0] got_geom = got.geometry() self.assertEqual(got['attr'], 100) reference = QgsGeometry.fromWkt('Point (4 4)') self.assertEqual( got_geom.asWkb(), reference.asWkb(), 'Expected {}, got {}'.format(reference.asWkt(), got_geom.asWkt())) got = [feat for feat in vl2.getFeatures()][0] got_geom = got.geometry() self.assertEqual(got['attr'], 101) reference = QgsGeometry.fromWkt('Point (5 5)') self.assertEqual( got_geom.asWkb(), reference.asWkb(), 'Expected {}, got {}'.format(reference.asWkt(), got_geom.asWkt()))
class QDViewer: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join(self.plugin_dir, 'i18n', 'QDViewer_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Create the dialog (after translation) and keep reference self.dlg = QDViewerDialog() # Declare instance attributes self.actions = [] self.menu = self.tr(u'&QDViewer') self.toolbar = self.iface.addToolBar(u'QDViewer') self.toolbar.setObjectName(u'QDViewer') self.achsen = None self.achsenData = None self.querschnitte = None self.querschnittData = None # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('QDViewer', message) def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToMenu(self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/QDViewer/icon.png' self.add_action(icon_path, text=self.tr(u'QDViewer'), callback=self.run, parent=self.iface.mainWindow()) def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginMenu(self.tr(u'&QDViewer'), action) self.iface.removeToolBarIcon(action) # remove the toolbar del self.toolbar @staticmethod def sqrt(t): return math.sqrt(t) # Vektor berechnen @staticmethod def dist(p_x1, p_x2, p_y1, p_y2): p_dx = p_x2 - p_x1 p_dy = p_y2 - p_y1 return QDViewer.einheit(p_dx, p_dy) # Einheitsvektor berechnen @staticmethod def einheit(p_dx, p_dy): p_strecke = math.sqrt(p_dx * p_dx + p_dy * p_dy) if p_strecke > 0: p_dx = p_dx / p_strecke p_dy = p_dy / p_strecke return p_dx, p_dy, p_strecke # Polygon schreiben def write_polygon(self, p_x, p_y, row, quer): feat = QgsFeature(self.querschnitte.fields()) feat.setAttributes([ row[0], row[1], quer[0], quer[1], quer[2], quer[3], quer[8], quer[9], quer[10], quer[11], quer[12], quer[13], quer[14], quer[15] ]) if len(p_x) > 0: points = [] for i in range(len(p_x)): points.append(QgsPointXY(p_x[i], p_y[i])) feat.setGeometry(QgsGeometry.fromPolygonXY([points])) self.querschnittData.addFeatures([feat]) # text = "POLYGON ((" # for i in range(len(p_x)): # text += str(p_x[i]) + " " + str(p_y[i]) + ", " # if len(p_x) > 0: # text = text[:-2] # text += ")); " + str(row[0]) + "; " + str(row[1]) + "; " + str(quer[0]) + "; " + str(quer[1]) + "; " + \ # str(quer[2]) + "; " + str(quer[3]) + "; " + str(quer[4]) + "; " + str(quer[5]) + "; " + \ # str(quer[6]) + "; " + str(quer[7]) + "; " + str(quer[8]) # print(text) # self.txt.write(text + "\n") def write_linestring(self, p_punkte, row): feat = QgsFeature(self.achsen.fields()) feat.setAttributes([row[0], row[1]]) if len(p_punkte) > 0: points = [] for p_p in p_punkte: points.append(QgsPointXY(p_p[1], p_p[2])) feat.setGeometry(QgsGeometry.fromPolylineXY(points)) self.achsenData.addFeatures([feat]) # text = "LINESTRING (" # for p_p in p_punkte: # text += str(p_p[1]) + " " + str(p_p[2]) + ", " # if len(p_punkte) > 0: # text = text[:-2] # text += "); " + str(row[0]) + "; " + str(row[1]) # print(text) # self.txt2.write(text + "\n") # Normalisiert Vektoren @staticmethod def norm(p_dx, p_dy): p_s = math.sqrt(p_dx * p_dx + p_dy * p_dy) if p_s > 0: p_dx = p_dx / p_s p_dy = p_dy / p_s return p_dx, p_dy, p_s def make_layers(self): # WKT-Dateien anlegen # self.txt = open(self.dlg.fw_speichern.filePath(), "w") # self.txt.write("Geometrie; VNK; NNK; VST; BST; STREIFEN; STREIFENNR; ABSTAND_VST1; " + # "ABSTAND_VST2; ABSTAND_BST1; ABSTAND_BST2; ART\n") # self.txt2 = open(self.dlg.fw_speichern.filePath() + "_achsen.wkt", "w") # self.txt2.write("Geometrie; VNK; NNK\n") # from qgis.core import QgsMapLayerRegistry self.querschnitte = QgsVectorLayer("polygon?crs=epsg:25832", "Querschnitte", "memory") self.querschnitte.startEditing() self.querschnittData = self.querschnitte.dataProvider() self.querschnittData.addAttributes([ QgsField("VNK", QVariant.String), QgsField("NNK", QVariant.String), QgsField("VST", QVariant.Int), QgsField("BST", QVariant.Int), QgsField("STREIFEN", QVariant.String), QgsField("STREIFENNR", QVariant.Int), QgsField("ART", QVariant.String), QgsField("ARTOBER", QVariant.String), QgsField("BREITE", QVariant.Int), QgsField("BISBREITE", QVariant.Int), QgsField("BLPART", QVariant.String), QgsField("BLPART3", QVariant.String), QgsField("UIPART", QVariant.String), QgsField("UIPART3", QVariant.String), QgsField("LAENGE", QVariant.Int), QgsField("FLAECHE", QVariant.Double), QgsField("BAUJAHRGEW", QVariant.Date), QgsField("ABNAHMEGEW", QVariant.Date), QgsField("DAUERGEW", QVariant.Int), QgsField("ABLAUFGEW", QVariant.Date), QgsField("ERFART", QVariant.String), QgsField("QUELLE", QVariant.String), QgsField("ADATUM", QVariant.Date), QgsField("BEMERKUNG", QVariant.String), QgsField("BEARBEITER", QVariant.String), QgsField("STAND", QVariant.Date), QgsField("PARENTID", QVariant.String), QgsField("OBJEKTID", QVariant.String), QgsField("FLAG", QVariant.String) ]) self.querschnitte.commitChanges() QgsProject.instance().addMapLayer(self.querschnitte) self.achsen = QgsVectorLayer("linestring?crs=epsg:25832", "Achsen", "memory") self.achsen.startEditing() self.achsenData = self.achsen.dataProvider() self.achsenData.addAttributes([ QgsField("VNK", QVariant.String), QgsField("NNK", QVariant.String) ]) # self.achsen.commitChanges() QgsProject.instance().addMapLayer(self.achsen) def arbeite(self): # QgsVectorFileWriter.writeAsVectorFormat(vlyr, newSQLiteFilePath, "utf-8", crs, "SQLite", False, None, # ["SPATIALITE=YES"]) self.make_layers() print("Connect DB and copy...") dbabschn = QgsVectorLayer(self.dlg.fw_abschn.filePath(), "dbabschn", "ogr") db1030 = QgsVectorLayer(self.dlg.fw_1030.filePath(), "db1030", "ogr") db255 = QgsVectorLayer(self.dlg.fw_255.filePath(), "db255", "ogr") QgsVectorFileWriter.writeAsVectorFormat( dbabschn, self.dlg.fw_speichern.filePath() + "\dbabschn.sqlite", "utf-8", QgsCoordinateReferenceSystem(), "SQLite") QgsVectorFileWriter.writeAsVectorFormat( db255, self.dlg.fw_speichern.filePath() + "\db000255.sqlite", "utf-8", QgsCoordinateReferenceSystem(), "SQLite") QgsVectorFileWriter.writeAsVectorFormat( db1030, self.dlg.fw_speichern.filePath() + "\db001030.sqlite", "utf-8", QgsCoordinateReferenceSystem(), "SQLite") mem_db = sqlite3.connect(':memory:') # create a memory database for old_db_pfad in [ self.dlg.fw_speichern.filePath() + "\dbabschn.sqlite", self.dlg.fw_speichern.filePath() + "\db000255.sqlite", self.dlg.fw_speichern.filePath() + "\db001030.sqlite" ]: old_db = sqlite3.connect(old_db_pfad) c = old_db.cursor() c.execute('''DROP TABLE geometry_columns''') c.execute('''DROP TABLE spatial_ref_sys''') query = "".join(line for line in old_db.iterdump()) mem_db.executescript(query) daten = mem_db.cursor() mem_db.create_function("sqrt", 1, QDViewer.sqrt) print("Tabellen anlegen...") daten.execute( '''CREATE TABLE "tmp11" ("VNK" varchar(10), "NNK" varchar(10), "SORT" float, "XKOORD" float, "YKOORD" float, "STAND" text, "FLAG" varchar(1), DX float default 0, DY float default 0, laenge float default NULL, STATION float default NULL, ABSTAND float default NULL)''' ) daten.execute( '''CREATE TABLE "tmp12" ("VNK" varchar(10), "NNK" varchar(10), "SORT" float, "XKOORD" float, "YKOORD" float, "STAND" text, "FLAG" varchar(1), DX float default 0, DY float default 0, laenge float default NULL, STATION float default NULL, ABSTAND float default NULL)''' ) daten.execute( '''CREATE TABLE "tmp13" ("VNK" varchar(10), "NNK" varchar(10), "SORT" float, "XKOORD" float, "YKOORD" float, "STAND" text, "FLAG" varchar(1), DX float default 0, DY float default 0, laenge float default NULL, STATION float default NULL, ABSTAND float default NULL)''' ) daten.execute( '''CREATE TABLE "tmp14" ("VNK" varchar(10), "NNK" varchar(10), "SORT" float, "XKOORD" float, "YKOORD" float, "STAND" text, "FLAG" varchar(1), DX float default 0, DY float default 0, laenge float default NULL, STATION float default NULL, ABSTAND float default NULL, DXP float default 0, DYP float default 0)''') # DX/DY berechnen print("DX/DY berechnen...") daten.execute('''INSERT INTO tmp11 SELECT a.VNK, a.NNK, a.SORT, a.XKOORD, a.YKOORD, a.STAND, a.FLAG, (b.XKOORD - a.XKOORD) DX, (b.YKOORD - a.YKOORD) DY, NULL, NULL, NULL FROM DB000255 a, DB000255 b WHERE a.VNK = b.VNK AND a.NNK = b.NNK AND a.SORT = (b.SORT + 1);''' ) # Laenge berechnen und Vektor DX/DY zu Einheitsvektor print("Laenge berechnen und Vektor DX/DY zu Einheitsvektor...") daten.execute( '''UPDATE tmp11 SET laenge = sqrt(DX*DX+DY*DY), DX = DX / sqrt(DX*DX+DY*DY), DY = DY / sqrt(DX*DX+DY*DY) WHERE DX != 0 OR DY != 0;''') # DX/DY vom zweiten Punkt für ersten übernehmen print("DX/DY vom zweiten Punkt für ersten übernehmen...") daten.execute('''INSERT INTO tmp11 SELECT a.VNK, a.NNK, a.SORT, a.XKOORD, a.YKOORD, a.STAND, a.FLAG, b.DX DX, b.DY DY, 0, 0, 0 FROM DB000255 a, tmp11 b WHERE a.VNK = b.VNK AND a.NNK = b.NNK AND a.SORT = 1 AND b.SORT = 2;''' ) # ABSTAND berechnen (Summe der Laenge) print("ABSTAND berechnen (Summe der Laenge)...") daten.execute('''INSERT INTO tmp12 SELECT a.VNK, a.NNK, a.SORT, a.XKOORD, a.YKOORD, a.STAND, a.FLAG, a.DX, a.DY, a.laenge, NULL, SUM(b.laenge) FROM tmp11 a, tmp11 b WHERE a.VNK = b.VNK AND a.NNK = b.NNK AND a.SORT >= b.SORT GROUP BY a.VNK, a.NNK, a.SORT;''' ) # Station berechnen print("Station berechnen...") daten.execute('''INSERT INTO tmp13 SELECT a.VNK, a.NNK, a.SORT, a.XKOORD, a.YKOORD, a.STAND, a.FLAG, a.DX, a.DY, a.laenge, a.ABSTAND * b.faktor , a.ABSTAND FROM tmp12 a, (SELECT b.VNK, b.NNK, c.LEN / max(b.ABSTAND) faktor FROM tmp12 b, DBABSCHN c WHERE b.VNK = c.VNK AND b.NNK = c.NNK GROUP BY b.VNK, b.NNK) b WHERE a.VNK = b.VNK AND a.NNK = b.NNK GROUP BY a.VNK, a.NNK, a.SORT;''') # DXP/DYP berechnen (Verschiebe-Vektor an Stützpunkten) print("DXP/DYP berechnen (Verschiebe-Vektor an Stützpunkten)...") daten.execute('''INSERT INTO tmp14 SELECT a.*, a.DX + b.DX, a.DY + b.DY FROM tmp13 a, tmp13 b WHERE a.VNK = b.VNK AND a.NNK = b.NNK AND a.SORT = (b.SORT - 1);''' ) # Letzten Punkt übernehmen print("Letzten Punkt übernehmen...") daten.execute('''INSERT INTO tmp14 SELECT a.*, a.DX, a.DY FROM tmp13 a, (SELECT VNK, NNK, max(SORT) SORT FROM tmp13 GROUP BY VNK, NNK) b WHERE a.VNK = b.VNK AND a.NNK = b.NNK AND a.SORT = b.SORT;''') # DXP/DYP zu Einheitsvektor print("DXP/DYP zu Einheitsvektor...") daten.execute( '''UPDATE tmp14 SET DXP = DXP / sqrt(DXP*DXP+DYP*DYP), DYP = DYP / sqrt(DXP*DXP+DYP*DYP) WHERE DXP != 0 OR DYP != 0;''') mem_db.commit() print("Querschnitte summieren:") print("Tabellen anlegen...") daten.execute( '''CREATE TABLE tmp1 ("VNK" varchar(10), "NNK" varchar(10), "VST" float, "BST" float, "STREIFEN" varchar(1), "STREIFENNR" float, "ART" varchar(3), "ARTOBER" varchar(3), "BREITE" float, "BISBREITE" float, "BLPART" varchar(2), "BLPART3" varchar(5), "UIPART" varchar(2), "UIPART3" varchar(5), "LAENGE" float, "FLAECHE" float, "BAUJAHRGEW" text, "ABNAHMEGEW" text, "DAUERGEW" float, "ABLAUFGEW" text, "ERFART" varchar(2), "QUELLE" varchar(2), "ADATUM" text, "BEMERKUNG" varchar(254), "BEARBEITER" varchar(64), "STAND" text, "PARENTID" varchar(32), "OBJEKTID" varchar(32), "FLAG" varchar(1), ABSTAND_VST1 float default 0, ABSTAND_VST2 float default 0, ABSTAND_BST1 float default 0, ABSTAND_BST2 float default 0);''') daten.execute( '''CREATE TABLE tmp2 ("VNK" varchar(10), "NNK" varchar(10), "VST" float, "BST" float, "STREIFEN" varchar(1), "STREIFENNR" float, "ART" varchar(3), "ARTOBER" varchar(3), "BREITE" float, "BISBREITE" float, "BLPART" varchar(2), "BLPART3" varchar(5), "UIPART" varchar(2), "UIPART3" varchar(5), "LAENGE" float, "FLAECHE" float, "BAUJAHRGEW" text, "ABNAHMEGEW" text, "DAUERGEW" float, "ABLAUFGEW" text, "ERFART" varchar(2), "QUELLE" varchar(2), "ADATUM" text, "BEMERKUNG" varchar(254), "BEARBEITER" varchar(64), "STAND" text, "PARENTID" varchar(32), "OBJEKTID" varchar(32), "FLAG" varchar(1), ABSTAND_VST1 float default 0, ABSTAND_VST2 float default 0, ABSTAND_BST1 float default 0, ABSTAND_BST2 float default 0);''') print("Summe links und rechts...") daten.execute( '''INSERT INTO tmp1 SELECT a.VNK, a.NNK, a.VST, a.BST, a.STREIFEN, a.STREIFENNR, a.ART, a.ARTOBER, a.BREITE, a.BISBREITE, a.BLPART, a.BLPART3, a.UIPART, a.UIPART3, a.LAENGE, a.FLAECHE, a.BAUJAHRGEW, a.ABNAHMEGEW, a.DAUERGEW, a.ABLAUFGEW, a.ERFART, a.QUELLE, a.ADATUM, a.BEMERKUNG, a.BEARBEITER, a.STAND, a.PARENTID, a.OBJEKTID, a.FLAG, (SUM(b.BREITE)) ABSTAND_VST1, NULL, (SUM(b.BISBREITE)) ABSTAND_BST1, NULL FROM DB001030 a, DB001030 b WHERE a.VNK = b.VNK AND b.NNK = a.NNK AND a.VST = b.VST AND a.STREIFEN = b.STREIFEN AND a.STREIFENNR > b.STREIFENNR and a.STREIFEN != "M" GROUP BY a.VNK, a.NNK, a.VST, a.STREIFEN, a.STREIFENNR;''') print("Streifen 1 kopieren...") daten.execute('''INSERT INTO tmp1 SELECT VNK, NNK, VST,BST, STREIFEN, STREIFENNR, ART, ARTOBER, BREITE, BISBREITE, BLPART, BLPART3, UIPART, UIPART3, LAENGE, FLAECHE, BAUJAHRGEW, ABNAHMEGEW, DAUERGEW, ABLAUFGEW, ERFART, QUELLE, ADATUM, BEMERKUNG, BEARBEITER, STAND, PARENTID, OBJEKTID, FLAG, 0 ABSTAND_VST1, NULL ABSTAND_VST2, 0 ABSTAND_BST1, NULL ABSTAND_BST2 FROM DB001030 WHERE STREIFENNR = 1;''') print("Mittelstreifen addieren...") daten.execute('''INSERT INTO tmp2 SELECT a.VNK, a.NNK, a.VST,a.BST,a.STREIFEN,a.STREIFENNR,a.ART,a.ARTOBER,a.BREITE,a.BISBREITE,a.BLPART, a.BLPART3, a.UIPART,a.UIPART3,a.LAENGE,a.FLAECHE,a.BAUJAHRGEW,a.ABNAHMEGEW,a.DAUERGEW,a.ABLAUFGEW,a.ERFART, a.QUELLE, a.ADATUM, a.BEMERKUNG,a.BEARBEITER,a.STAND,a.PARENTID,a.OBJEKTID,a.FLAG, (a.ABSTAND_VST1+round(IFNULL(m.BREITE,0) / 2)) ABSTAND_VST1, NULL ABSTAND_VST2, (a.ABSTAND_BST1+round(IFNULL(m.BISBREITE,0) / 2)) ABSTAND_BST1, NULL ABSTAND_BST2 FROM tmp1 a left join (select * from DB001030 where STREIFEN = "M") m on a.VNK = m.VNK AND a.NNK = m.NNK AND a.VST = m.VST;''') print("Abstand der Außenkante berechnen...") daten.execute('''UPDATE tmp2 SET ABSTAND_VST2 = ABSTAND_VST1 + BREITE, ABSTAND_BST2 = ABSTAND_BST1 + BISBREITE;''') print("Linke drehen...") daten.execute('''UPDATE tmp2 SET ABSTAND_VST1 = - ABSTAND_VST1, ABSTAND_VST2 = - ABSTAND_VST2, ABSTAND_BST1 = - ABSTAND_BST1, ABSTAND_BST2 = - ABSTAND_BST2 WHERE STREIFEN = "L";''') print("Mittelstreifen berechnen...") daten.execute('''INSERT INTO tmp2 SELECT VNK, NNK, VST, BST, STREIFEN, STREIFENNR, ART, ARTOBER, BREITE, BISBREITE, BLPART, BLPART3, UIPART, UIPART3, LAENGE, FLAECHE, BAUJAHRGEW, ABNAHMEGEW, DAUERGEW, ABLAUFGEW, ERFART, QUELLE, ADATUM, BEMERKUNG, BEARBEITER, STAND, PARENTID, OBJEKTID, FLAG, ROUND(- BREITE / 2) ABSTAND_VST1, ROUND(BREITE / 2) ABSTAND_VST2, ROUND(- BISBREITE / 2) ABSTAND_BST1, ROUND(BISBREITE / 2) ABSTAND_BST2 FROM DB001030 WHERE STREIFEN = "M";''' ) print("Nicht benötigte Tabellen löschen...") daten.execute('''DROP TABLE tmp11''') daten.execute('''DROP TABLE tmp12''') daten.execute('''DROP TABLE tmp13''') daten.execute('''DROP TABLE tmp1''') mem_db.commit() print("Arbeiten...") # Abschnitte selektieren und durchgehen daten.execute('SELECT VNK, NNK, LEN FROM DBABSCHN') abschn = daten.fetchall() for row in abschn: # Koordinaten der Achse abfragen sql = 'SELECT STATION, XKOORD, YKOORD, DXP, DYP, DX, DY FROM tmp14 WHERE VNK = "' + row[0] + '" AND ' \ 'NNK = "' + row[1] + '" AND STATION IS NOT NULL AND XKOORD IS NOT NULL AND YKOORD IS NOT NULL AND ' \ 'DX IS NOT NULL AND DY IS NOT NULL ORDER BY SORT' daten.execute(sql) punkte = daten.fetchall() # Achse als WKT ablegen self.write_linestring(punkte, row) # Querschnitte laden sql = 'SELECT VST, BST, STREIFEN, STREIFENNR, ABSTAND_VST1, ABSTAND_VST2, ABSTAND_BST1, ABSTAND_BST2,' + \ ' ART,ARTOBER, BREITE, BISBREITE, BLPART, BLPART3, UIPART, UIPART3, LAENGE, FLAECHE, BAUJAHRGEW,' + \ 'ABNAHMEGEW, DAUERGEW, ABLAUFGEW, ERFART, QUELLE, ADATUM, BEMERKUNG, BEARBEITER, STAND, PARENTID, ' \ 'OBJEKTID, FLAG FROM tmp2 WHERE VNK = "' + row[0] + '" AND NNK = "' + row[1] + '" AND ' + \ 'ABSTAND_VST1 IS NOT NULL AND ABSTAND_VST2 IS NOT NULL AND ABSTAND_BST1 IS NOT NULL AND ' \ 'ABSTAND_BST2 IS NOT NULL ORDER BY VST, STREIFEN, STREIFENNR' daten.execute(sql) for quer in daten.fetchall(): # print(quer) x = [] y = [] c = 0 pa = None for p in punkte: if p[0] >= quer[0] and c == 0 and pa is not None: # Berechnung Anfangspunkt dx = p[1] - pa[1] dy = p[2] - pa[2] diff = p[0] - pa[0] f = 0 if diff > 0: f = (quer[0] - pa[0]) / diff # print(f) dxn, dyn, s = QDViewer.norm(dx, dy) # print("P1") # print(quer[4]) if quer[4] is not None: x.append(pa[1] + dx * f + dyn * quer[4] / 100) y.append(pa[2] + dy * f - dxn * quer[4] / 100) x.append(pa[1] + dx * f + dyn * quer[5] / 100) y.append(pa[2] + dy * f - dxn * quer[5] / 100) c = 1 if c == 1 and p[0] <= quer[1]: # print("P2") # Prozentualer Abstand f = (p[0] - quer[0]) / (quer[1] - quer[0]) # print(f) # Abstand interpolieren a = quer[4] + f * (quer[6] - quer[4]) # print(a) # Abstand2 interpolieren b = quer[5] + f * (quer[7] - quer[5]) # print(b) try: x.insert(0, p[1] - p[4] * a / 100) y.insert(0, p[2] + p[3] * a / 100) x.append(p[1] - p[4] * b / 100) y.append(p[2] + p[3] * b / 100) except TypeError: break if c == 1 and p[0] > quer[1]: # print("P3") # Berechnung Endpunkt dx = p[1] - pa[1] dy = p[2] - pa[2] if (p[0] - pa[0]) != 0: f = (quer[1] - pa[0]) / (p[0] - pa[0]) else: f = 1 # print(p[0]) # print(f) dxn, dyn, s = QDViewer.norm(dx, dy) if quer[6] is not None: x.insert(0, pa[1] + dx * f + dyn * quer[6] / 100) y.insert(0, pa[2] + dy * f - dxn * quer[6] / 100) if quer[7] is not None: x.append(pa[1] + dx * f + dyn * quer[7] / 100) y.append(pa[2] + dy * f - dxn * quer[7] / 100) break pa = p self.write_polygon(x, y, row, quer) print("Fertig") def run(self): """Run method that performs all the real work""" # show the dialog self.dlg.show() self.dlg.fw_speichern.setStorageMode(QgsFileWidget.GetDirectory) # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. self.arbeite() pass
class TestLayerDependencies(unittest.TestCase): @classmethod def setUpClass(cls): """Run before all tests""" # create a temp spatialite db with a trigger fo = tempfile.NamedTemporaryFile() fn = fo.name fo.close() cls.fn = fn con = spatialite_connect(fn) cur = con.cursor() cur.execute("SELECT InitSpatialMetadata(1)") cur.execute("create table node(id integer primary key autoincrement);") cur.execute("select AddGeometryColumn('node', 'geom', 4326, 'POINT');") cur.execute( "create table section(id integer primary key autoincrement, node1 integer, node2 integer);" ) cur.execute( "select AddGeometryColumn('section', 'geom', 4326, 'LINESTRING');") cur.execute( "create trigger add_nodes after insert on section begin insert into node (geom) values (st_startpoint(NEW.geom)); insert into node (geom) values (st_endpoint(NEW.geom)); end;" ) cur.execute( "insert into node (geom) values (geomfromtext('point(0 0)', 4326));" ) cur.execute( "insert into node (geom) values (geomfromtext('point(1 0)', 4326));" ) cur.execute( "create table node2(id integer primary key autoincrement);") cur.execute( "select AddGeometryColumn('node2', 'geom', 4326, 'POINT');") cur.execute( "create trigger add_nodes2 after insert on node begin insert into node2 (geom) values (st_translate(NEW.geom, 0.2, 0, 0)); end;" ) con.commit() con.close() cls.pointsLayer = QgsVectorLayer( "dbname='%s' table=\"node\" (geom) sql=" % fn, "points", "spatialite") assert (cls.pointsLayer.isValid()) cls.linesLayer = QgsVectorLayer( "dbname='%s' table=\"section\" (geom) sql=" % fn, "lines", "spatialite") assert (cls.linesLayer.isValid()) cls.pointsLayer2 = QgsVectorLayer( "dbname='%s' table=\"node2\" (geom) sql=" % fn, "_points2", "spatialite") assert (cls.pointsLayer2.isValid()) QgsProject.instance().addMapLayers( [cls.pointsLayer, cls.linesLayer, cls.pointsLayer2]) # save the project file fo = tempfile.NamedTemporaryFile() fn = fo.name fo.close() cls.projectFile = fn QgsProject.instance().setFileName(cls.projectFile) QgsProject.instance().write() @classmethod def tearDownClass(cls): """Run after all tests""" pass def setUp(self): """Run before each test.""" pass def tearDown(self): """Run after each test.""" pass def test_resetSnappingIndex(self): self.pointsLayer.setDependencies([]) self.linesLayer.setDependencies([]) self.pointsLayer2.setDependencies([]) ms = QgsMapSettings() ms.setOutputSize(QSize(100, 100)) ms.setExtent(QgsRectangle(0, 0, 1, 1)) self.assertTrue(ms.hasValidSettings()) u = QgsSnappingUtils() u.setMapSettings(ms) cfg = u.config() cfg.setEnabled(True) cfg.setMode(QgsSnappingConfig.AdvancedConfiguration) cfg.setIndividualLayerSettings( self.pointsLayer, QgsSnappingConfig.IndividualLayerSettings(True, QgsSnappingConfig.Vertex, 20, QgsTolerance.Pixels)) u.setConfig(cfg) m = u.snapToMap(QPoint(95, 100)) self.assertTrue(m.isValid()) self.assertTrue(m.hasVertex()) self.assertEqual(m.point(), QgsPoint(1, 0)) f = QgsFeature(self.linesLayer.fields()) f.setId(1) geom = QgsGeometry.fromWkt("LINESTRING(0 0,1 1)") f.setGeometry(geom) self.linesLayer.startEditing() self.linesLayer.addFeatures([f]) self.linesLayer.commitChanges() l1 = len([f for f in self.pointsLayer.getFeatures()]) self.assertEqual(l1, 4) m = u.snapToMap(QPoint(95, 0)) # snapping not updated self.pointsLayer.setDependencies([]) self.assertEqual(m.isValid(), False) # set layer dependencies self.pointsLayer.setDependencies( [QgsMapLayerDependency(self.linesLayer.id())]) # add another line f = QgsFeature(self.linesLayer.fields()) f.setId(2) geom = QgsGeometry.fromWkt("LINESTRING(0 0,0.5 0.5)") f.setGeometry(geom) self.linesLayer.startEditing() self.linesLayer.addFeatures([f]) self.linesLayer.commitChanges() # check the snapped point is ok m = u.snapToMap(QPoint(45, 50)) self.assertTrue(m.isValid()) self.assertTrue(m.hasVertex()) self.assertEqual(m.point(), QgsPoint(0.5, 0.5)) self.pointsLayer.setDependencies([]) # test chained layer dependencies A -> B -> C cfg.setIndividualLayerSettings( self.pointsLayer2, QgsSnappingConfig.IndividualLayerSettings(True, QgsSnappingConfig.Vertex, 20, QgsTolerance.Pixels)) u.setConfig(cfg) self.pointsLayer.setDependencies( [QgsMapLayerDependency(self.linesLayer.id())]) self.pointsLayer2.setDependencies( [QgsMapLayerDependency(self.pointsLayer.id())]) # add another line f = QgsFeature(self.linesLayer.fields()) f.setId(3) geom = QgsGeometry.fromWkt("LINESTRING(0 0.2,0.5 0.8)") f.setGeometry(geom) self.linesLayer.startEditing() self.linesLayer.addFeatures([f]) self.linesLayer.commitChanges() # check the second snapped point is ok m = u.snapToMap(QPoint(75, 100 - 80)) self.assertTrue(m.isValid()) self.assertTrue(m.hasVertex()) self.assertEqual(m.point(), QgsPoint(0.7, 0.8)) self.pointsLayer.setDependencies([]) self.pointsLayer2.setDependencies([]) def test_cycleDetection(self): self.assertTrue( self.pointsLayer.setDependencies( [QgsMapLayerDependency(self.linesLayer.id())])) self.assertFalse( self.linesLayer.setDependencies( [QgsMapLayerDependency(self.pointsLayer.id())])) self.pointsLayer.setDependencies([]) self.linesLayer.setDependencies([]) def test_layerDefinitionRewriteId(self): tmpfile = os.path.join(tempfile.tempdir, "test.qlr") ltr = QgsProject.instance().layerTreeRoot() self.pointsLayer.setDependencies( [QgsMapLayerDependency(self.linesLayer.id())]) QgsLayerDefinition.exportLayerDefinition(tmpfile, [ltr]) grp = ltr.addGroup("imported") QgsLayerDefinition.loadLayerDefinition(tmpfile, QgsProject.instance(), grp) newPointsLayer = None newLinesLayer = None for l in grp.findLayers(): if l.layerId().startswith('points'): newPointsLayer = l.layer() elif l.layerId().startswith('lines'): newLinesLayer = l.layer() self.assertIsNotNone(newPointsLayer) self.assertIsNotNone(newLinesLayer) self.assertTrue(newLinesLayer.id( ) in [dep.layerId() for dep in newPointsLayer.dependencies()]) self.pointsLayer.setDependencies([]) def test_signalConnection(self): # remove all layers QgsProject.instance().removeAllMapLayers() # set dependencies and add back layers self.pointsLayer = QgsVectorLayer( "dbname='%s' table=\"node\" (geom) sql=" % self.fn, "points", "spatialite") assert (self.pointsLayer.isValid()) self.linesLayer = QgsVectorLayer( "dbname='%s' table=\"section\" (geom) sql=" % self.fn, "lines", "spatialite") assert (self.linesLayer.isValid()) self.pointsLayer2 = QgsVectorLayer( "dbname='%s' table=\"node2\" (geom) sql=" % self.fn, "_points2", "spatialite") assert (self.pointsLayer2.isValid()) self.pointsLayer.setDependencies( [QgsMapLayerDependency(self.linesLayer.id())]) self.pointsLayer2.setDependencies( [QgsMapLayerDependency(self.pointsLayer.id())]) # this should update connections between layers QgsProject.instance().addMapLayers([self.pointsLayer]) QgsProject.instance().addMapLayers([self.linesLayer]) QgsProject.instance().addMapLayers([self.pointsLayer2]) ms = QgsMapSettings() ms.setOutputSize(QSize(100, 100)) ms.setExtent(QgsRectangle(0, 0, 1, 1)) self.assertTrue(ms.hasValidSettings()) u = QgsSnappingUtils() u.setMapSettings(ms) cfg = u.config() cfg.setEnabled(True) cfg.setMode(QgsSnappingConfig.AdvancedConfiguration) cfg.setIndividualLayerSettings( self.pointsLayer, QgsSnappingConfig.IndividualLayerSettings(True, QgsSnappingConfig.Vertex, 20, QgsTolerance.Pixels)) cfg.setIndividualLayerSettings( self.pointsLayer2, QgsSnappingConfig.IndividualLayerSettings(True, QgsSnappingConfig.Vertex, 20, QgsTolerance.Pixels)) u.setConfig(cfg) # add another line f = QgsFeature(self.linesLayer.fields()) f.setId(4) geom = QgsGeometry.fromWkt("LINESTRING(0.5 0.2,0.6 0)") f.setGeometry(geom) self.linesLayer.startEditing() self.linesLayer.addFeatures([f]) self.linesLayer.commitChanges() # check the second snapped point is ok m = u.snapToMap(QPoint(75, 100 - 0)) self.assertTrue(m.isValid()) self.assertTrue(m.hasVertex()) self.assertEqual(m.point(), QgsPoint(0.8, 0.0)) self.pointsLayer.setDependencies([]) self.pointsLayer2.setDependencies([])
def testFieldsWithSpecialCharacters(self): ml = QgsVectorLayer("Point?srid=EPSG:4326&field=123:int", "mem_with_nontext_fieldnames", "memory") self.assertEqual(ml.isValid(), True) QgsProject.instance().addMapLayer(ml) ml.startEditing() self.assertTrue(ml.addAttribute(QgsField('abc:123', QVariant.String))) self.assertTrue(ml.addAttribute(QgsField( 'map', QVariant.String))) # matches QGIS expression function name f1 = QgsFeature(ml.fields()) f1.setGeometry(QgsGeometry.fromWkt('POINT(0 0)')) f1.setAttributes([1, 'a', 'b']) f2 = QgsFeature(ml.fields()) f2.setGeometry(QgsGeometry.fromWkt('POINT(1 1)')) f2.setAttributes([2, 'c', 'd']) ml.addFeatures([f1, f2]) ml.commitChanges() vl = QgsVectorLayer("?query=select * from mem_with_nontext_fieldnames", "vl", "virtual") self.assertEqual(vl.isValid(), True) self.assertEqual(vl.fields().at(0).name(), '123') self.assertEqual(vl.fields().at(1).name(), 'abc:123') self.assertEqual(vl.featureCount(), 2) features = [ f for f in vl.getFeatures(QgsFeatureRequest().setFilterExpression( '"abc:123"=\'c\'')) ] self.assertEqual(len(features), 1) self.assertEqual(features[0].attributes(), [2, 'c', 'd']) features = [ f for f in vl.getFeatures(QgsFeatureRequest().setFilterExpression( '"map"=\'b\'')) ] self.assertEqual(len(features), 1) self.assertEqual(features[0].attributes(), [1, 'a', 'b']) vl2 = QgsVectorLayer( "?query=select * from mem_with_nontext_fieldnames where \"abc:123\"='c'", "vl", "virtual") self.assertEqual(vl2.isValid(), True) self.assertEqual(vl2.fields().at(0).name(), '123') self.assertEqual(vl2.fields().at(1).name(), 'abc:123') self.assertEqual(vl2.featureCount(), 1) features = [f for f in vl2.getFeatures()] self.assertEqual(len(features), 1) self.assertEqual(features[0].attributes(), [2, 'c', 'd']) vl3 = QgsVectorLayer( "?query=select * from mem_with_nontext_fieldnames where \"map\"='b'", "vl", "virtual") self.assertEqual(vl3.isValid(), True) self.assertEqual(vl3.fields().at(0).name(), '123') self.assertEqual(vl3.fields().at(1).name(), 'abc:123') self.assertEqual(vl3.featureCount(), 1) features = [f for f in vl3.getFeatures()] self.assertEqual(len(features), 1) self.assertEqual(features[0].attributes(), [1, 'a', 'b']) QgsProject.instance().removeMapLayer(ml)
def newLULayer(self): if self.ludlg.LUincUFcheckBox.checkState( ) == 0 and self.ludlg.LUincLFcheckBox.checkState( ) == 0 and self.ludlg.LUincGFcheckBox.checkState() == 0: msgBar = self.iface.messageBar() msg = msgBar.createMessage(u'Select floors') msgBar.pushWidget(msg, Qgis.Info, 10) else: idcolumn = self.ludlg.getSelectedLULayerID() # if create from existing building layer if self.ludlg.createNewLUFileCheckBox.isChecked(): print('aaaa') building_layer = self.getSelectedLULayer() crs = building_layer.crs() vl = QgsVectorLayer("Polygon?crs=" + crs.authid(), "memory:landuse", "memory") else: # create memory layer vl = QgsVectorLayer("Polygon?crs=", "memory:landuse", "memory") if vl.crs().toWkt() == "": vl.setCrs(QgsProject.instance().crs()) provider = vl.dataProvider() # provider.addAttributes([]) ground_floor_attributes = [ QgsField(LanduseTool.lu_id_attribute, QVariant.Int), QgsField(LanduseTool.floors_attribute, QVariant.Int), QgsField(LanduseTool.area_attribute, QVariant.Double), QgsField(LanduseTool.gf_cat_attribute, QVariant.String), QgsField(LanduseTool.gf_subcat_attribute, QVariant.String), QgsField(LanduseTool.gf_ssx_attribute, QVariant.String), QgsField(LanduseTool.gf_nlud_attribute, QVariant.String), QgsField(LanduseTool.gf_tcpa_attribute, QVariant.String), QgsField(LanduseTool.gf_descrip_attribute, QVariant.String) ] lower_floor_attributes = [ QgsField(LanduseTool.lf_cat_attribute, QVariant.String), QgsField(LanduseTool.lf_subcat_attribute, QVariant.String), QgsField(LanduseTool.lf_ssx_attribute, QVariant.String), QgsField(LanduseTool.lf_nlud_attribute, QVariant.String), QgsField(LanduseTool.lf_tcpa_attribute, QVariant.String), QgsField(LanduseTool.lf_descrip_attribute, QVariant.String) ] upper_floor_attributes = [ QgsField(LanduseTool.uf_cat_attribute, QVariant.String), QgsField(LanduseTool.uf_subcat_attribute, QVariant.String), QgsField(LanduseTool.uf_ssx_attribute, QVariant.String), QgsField(LanduseTool.uf_nlud_attribute, QVariant.String), QgsField(LanduseTool.uf_ntcpa_attribute, QVariant.String), QgsField(LanduseTool.uf_descrip_attribute, QVariant.String) ] if self.ludlg.LUincGFcheckBox.checkState() == 2: provider.addAttributes(ground_floor_attributes) self.dockwidget.LUGroundfloorradioButton.setEnabled(1) if self.ludlg.LUincLFcheckBox.checkState() == 2: provider.addAttributes(lower_floor_attributes) self.dockwidget.LULowerfloorradioButton.setEnabled(1) if self.ludlg.LUincUFcheckBox.checkState() == 2: provider.addAttributes(upper_floor_attributes) self.dockwidget.LULowerfloorradioButton.setEnabled(1) vl.updateFields() # if create from existing building layer if self.ludlg.createNewLUFileCheckBox.isChecked(): null_attr = [] provider.addAttributes([QgsField('build_id', QVariant.String)]) if self.ludlg.LUincGFcheckBox.checkState() == 2: # TODO: has removed [QgsField("Build_ID", QVariant.Int)] + provider.addAttributes(ground_floor_attributes) self.dockwidget.LUGroundfloorradioButton.setEnabled(1) null_attr += [ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ] if self.ludlg.LUincLFcheckBox.checkState() == 2: provider.addAttributes(lower_floor_attributes) self.dockwidget.LULowerfloorradioButton.setEnabled(1) null_attr += [NULL, NULL, NULL, NULL, NULL, NULL] if self.ludlg.LUincUFcheckBox.checkState() == 2: provider.addAttributes(upper_floor_attributes) self.dockwidget.LULowerfloorradioButton.setEnabled(1) null_attr += [NULL, NULL, NULL, NULL, NULL, NULL] new_feat_list = [] i = 1 for feat in building_layer.getFeatures(): new_feat = QgsFeature() new_feat.setAttributes([i] + null_attr + [feat[idcolumn]]) i += 1 new_feat.setGeometry(feat.geometry()) new_feat_list.append(new_feat) vl.updateFields() provider.addFeatures(new_feat_list) vl.commitChanges() if self.ludlg.lu_shp_radioButton.isChecked( ): # layer_type == 'shapefile': path = self.ludlg.lineEditLU.text() if path and path != '': filename = os.path.basename(path) location = os.path.abspath(path) shph.createShapeFile(vl, path, vl.crs()) print('cri', vl.crs().authid()) input2 = self.iface.addVectorLayer(location, filename[:-4], "ogr") else: input2 = 'invalid data source' elif self.ludlg.lu_postgis_radioButton.isChecked(): db_path = self.ludlg.lineEditLU.text() if db_path and db_path != '': (database, schema, table_name) = db_path.split(':') db_con_info = self.ludlg.dbsettings_dlg.available_dbs[ database] uri = QgsDataSourceUri() # passwords, usernames need to be empty if not provided or else connection will fail if 'service' in list(db_con_info.keys()): uri.setConnection(db_con_info['service'], '', '', '') elif 'password' in list(db_con_info.keys()): uri.setConnection(db_con_info['host'], db_con_info['port'], db_con_info['dbname'], db_con_info['user'], db_con_info['password']) else: print(db_con_info) # db_con_info['host'] uri.setConnection('', db_con_info['port'], db_con_info['dbname'], '', '') uri.setDataSource(schema, table_name, "geom") error = QgsVectorLayerExporter.exportLayer( vl, uri.uri(), "postgres", vl.crs()) if error[0] != QgsVectorLayerExporter.NoError: print("Error when creating postgis layer: ", error[1]) input2 = 'duplicate' else: input2 = QgsVectorLayer(uri.uri(), table_name, "postgres") else: input2 = 'invalid data source' else: input2 = vl if input2 == 'invalid data source': msgBar = self.iface.messageBar() msg = msgBar.createMessage(u'Specify output path!') msgBar.pushWidget(msg, Qgis.Info, 10) elif input2 == 'duplicate': msgBar = self.iface.messageBar() msg = msgBar.createMessage(u'Land use layer already exists!') msgBar.pushWidget(msg, Qgis.Info, 10) elif not input2: msgBar = self.iface.messageBar() msg = msgBar.createMessage(u'Land use layer failed to load!') msgBar.pushWidget(msg, Qgis.Info, 10) else: QgsProject.instance().addMapLayer(input2) msgBar = self.iface.messageBar() msg = msgBar.createMessage(u'Land use layer created!') msgBar.pushWidget(msg, Qgis.Info, 10) input2.startEditing() self.updateLULayer() self.ludlg.closePopUpLU() self.ludlg.lineEditLU.clear()
def testDuplicateFeature(self): """ test duplicating a feature """ project = QgsProject().instance() # LAYERS # - add first layer (parent) layer1 = QgsVectorLayer("Point?field=fldtxt:string&field=pkid:integer", "parentlayer", "memory") # > check first layer (parent) self.assertTrue(layer1.isValid()) # - set the value for the copy layer1.setDefaultValueDefinition(1, QgsDefaultValue("rand(1000,2000)")) # > check first layer (parent) self.assertTrue(layer1.isValid()) # - add second layer (child) layer2 = QgsVectorLayer( "Point?field=fldtxt:string&field=id:integer&field=foreign_key:integer", "childlayer", "memory") # > check second layer (child) self.assertTrue(layer2.isValid()) # - add layers project.addMapLayers([layer1, layer2]) # FEATURES # - add 2 features on layer1 (parent) l1f1orig = QgsFeature() l1f1orig.setFields(layer1.fields()) l1f1orig.setAttributes(["F_l1f1", 100]) l1f2orig = QgsFeature() l1f2orig.setFields(layer1.fields()) l1f2orig.setAttributes(["F_l1f2", 101]) # > check by adding features self.assertTrue(layer1.dataProvider().addFeatures([l1f1orig, l1f2orig])) # add 4 features on layer2 (child) l2f1orig = QgsFeature() l2f1orig.setFields(layer2.fields()) l2f1orig.setAttributes(["F_l2f1", 201, 100]) l2f2orig = QgsFeature() l2f2orig.setFields(layer2.fields()) l2f2orig.setAttributes(["F_l2f2", 202, 100]) l2f3orig = QgsFeature() l2f3orig.setFields(layer2.fields()) l2f3orig.setAttributes(["F_l2f3", 203, 100]) l2f4orig = QgsFeature() l2f4orig.setFields(layer2.fields()) l2f4orig.setAttributes(["F_l2f4", 204, 101]) # > check by adding features self.assertTrue(layer2.dataProvider().addFeatures( [l2f1orig, l2f2orig, l2f3orig, l2f4orig])) # RELATION # - create the relationmanager relMgr = project.relationManager() # - create the relation rel = QgsRelation() rel.setId('rel1') rel.setName('childrel') rel.setReferencingLayer(layer2.id()) rel.setReferencedLayer(layer1.id()) rel.addFieldPair('foreign_key', 'pkid') rel.setStrength(QgsRelation.Composition) # > check relation self.assertTrue(rel.isValid()) # - add relation relMgr.addRelation(rel) # > check if referencedLayer is layer1 self.assertEqual(rel.referencedLayer(), layer1) # > check if referencingLayer is layer2 self.assertEqual(rel.referencingLayer(), layer2) # > check if the layers are correct in relation when loading from relationManager relations = project.relationManager().relations() relation = relations[list(relations.keys())[0]] # > check if referencedLayer is layer1 self.assertEqual(relation.referencedLayer(), layer1) # > check if referencingLayer is layer2 self.assertEqual(relation.referencingLayer(), layer2) # > check the relatedfeatures ''' # testoutput 1 print( "\nAll Features and relations") featit=layer1.getFeatures() f=QgsFeature() while featit.nextFeature(f): print( f.attributes()) childFeature = QgsFeature() relfeatit=rel.getRelatedFeatures(f) while relfeatit.nextFeature(childFeature): print( childFeature.attributes() ) print( "\n--------------------------") print( "\nFeatures on layer1") for f in layer1.getFeatures(): print( f.attributes() ) print( "\nFeatures on layer2") for f in layer2.getFeatures(): print( f.attributes() ) ''' # DUPLICATION # - duplicate feature l1f1orig with children layer1.startEditing() results = QgsVectorLayerUtils.duplicateFeature(layer1, l1f1orig, project, 0) # > check if name is name of duplicated (pk is different) result_feature = results[0] self.assertEqual(result_feature.attribute('fldtxt'), l1f1orig.attribute('fldtxt')) # > check duplicated child layer result_layer = results[1].layers()[0] self.assertEqual(result_layer, layer2) # > check duplicated child features self.assertTrue(results[1].duplicatedFeatures(result_layer)) ''' # testoutput 2 print( "\nFeatures on layer1 (after duplication)") for f in layer1.getFeatures(): print( f.attributes() ) print( "\nFeatures on layer2 (after duplication)") for f in layer2.getFeatures(): print( f.attributes() ) print( "\nAll Features and relations") featit=layer1.getFeatures() f=QgsFeature() while featit.nextFeature(f): print( f.attributes()) childFeature = QgsFeature() relfeatit=rel.getRelatedFeatures(f) while relfeatit.nextFeature(childFeature): print( childFeature.attributes() ) ''' # > compare text of parent feature self.assertEqual(result_feature.attribute('fldtxt'), l1f1orig.attribute('fldtxt')) # - create copyValueList childFeature = QgsFeature() relfeatit = rel.getRelatedFeatures(result_feature) copyValueList = [] while relfeatit.nextFeature(childFeature): copyValueList.append(childFeature.attribute('fldtxt')) # - create origValueList childFeature = QgsFeature() relfeatit = rel.getRelatedFeatures(l1f1orig) origValueList = [] while relfeatit.nextFeature(childFeature): origValueList.append(childFeature.attribute('fldtxt')) # - check if the ids are still the same self.assertEqual(copyValueList, origValueList)
def run(self): self.dlg.populateComboBox() # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result == 1: # create layers dict #layers = QgsProject.instance().mapLayers() layers = {} for name, layer in QgsProject.instance().mapLayers().items(): layers[layer.name()] = layer #choose point-source chosenPoint = self.dlg.pointsComboBox.currentText() if chosenPoint != 'Choose layer...': point_layer = layers[chosenPoint] else: pointPath = self.dlg.pointPathLineEdit.text() point_layer = QgsVectorLayer( pointPath, 'points', 'ogr') #shp-file with attribute field name try: p = open(pointPath, 'r') p.close() except IOError: QMessageBox.information( None, "Error", "Shape-file not found. Check file path.") return point_name_index = 0 # choose csv-source lines_list = [] chosenCsv = self.dlg.csvComboBox.currentText() if chosenCsv != 'Choose layer...': csv_layer = layers[chosenCsv] csv_features = csv_layer.getFeatures() for line in csv_features: attrs = line.attributes() lines_list.append(((str(attrs[0])), str(attrs[1]))) else: csvPath = self.dlg.csvPathLineEdit.text() # test if csv is valid try: f = codecs.open(csvPath, 'r', 'utf-8-sig') for line in f: pass f = codecs.open(csvPath, 'r', 'utf-8-sig') except UnicodeDecodeError: try: f = open(csvPath, 'r') re.search('\\\\', f) == None except: QMessageBox.information( None, "Error", "PointConnector can not read csv-file. Try saving it with utf-8 encoding or import it as a layer." ) return except IOError: QMessageBox.information( None, "Error", "Csv-file not found. Check file path or select a csv-layer." ) return #creating lines list from file for line in f: line = line.splitlines() for s in line[:1]: s = tuple(s.split(',')) lines_list.append(s) f.close() point_layer_crs = point_layer.crs().authid() lines_layer = QgsVectorLayer( 'LineString?crs=' + point_layer_crs, 'PointConnector lines ' + str(self.addedLayers), 'memory') pr = lines_layer.dataProvider() lines_layer.startEditing() pr.addAttributes([ QgsField('id', QVariant.Int), QgsField('from', QVariant.String), QgsField('to', QVariant.String) ]) #creating point coordinate dict points = point_layer.getFeatures() points_dict = {} #Progress bar widget progressMessageBar = iface.messageBar().createMessage( "Building point database...") progress = QProgressBar() progress.setMaximum(point_layer.featureCount()) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) iface.messageBar().pushWidget(progressMessageBar, Qgis.Info) i = 0 for p in points: geom = p.geometry() attrs = p.attributes() p = geom.asPoint() key = attrs[point_name_index] points_dict[str( key)] = p #attrs[point_name_index] = name field i += 1 progress.setValue(i) iface.messageBar().clearWidgets() QgsProject.instance().addMapLayer(point_layer) #Progress bar widget progressMessageBar = iface.messageBar().createMessage( "Drawing lines...") progress = QProgressBar() progress.setMaximum(len(lines_list)) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) iface.messageBar().pushWidget(progressMessageBar, Qgis.Info) #Drawing the lines i = 1 not_processed_list = [] for line in lines_list: if (line[0] in list(points_dict.keys()) and line[1] in list(points_dict.keys())): frPoint = points_dict[line[0]] toPoint = points_dict[line[1]] attrs = [i, line[0], line[1]] new_line = QgsGeometry.fromPolyline( [QgsPoint(frPoint), QgsPoint(toPoint)]) feat = QgsFeature() feat.setGeometry(new_line) feat.setAttributes(attrs) (res, outFeats) = pr.addFeatures([feat]) lines_layer.commitChanges() if res != True: pass i += 1 progress.setValue(i) else: not_processed_list.append(line) progress.setValue(i) iface.messageBar().clearWidgets() # add lines layer to canvas QgsProject.instance().addMapLayer(lines_layer) self.addedLayers += 1 if not not_processed_list: QMessageBox.information(None, 'Success', 'All lines drawn without error') else: QMessageBox.information( None, 'Error', str(len(not_processed_list)) + ' out of ' + str(len(lines_list)) + ' line(s) not drawn.')
def testUpdateMode(self): """ Test that on-the-fly re-opening in update/read-only mode works """ tmpdir = tempfile.mkdtemp() self.dirs_to_cleanup.append(tmpdir) srcpath = os.path.join(TEST_DATA_DIR, 'provider') for file in glob.glob(os.path.join(srcpath, 'shapefile.*')): shutil.copy(os.path.join(srcpath, file), tmpdir) datasource = os.path.join(tmpdir, 'shapefile.shp') vl = QgsVectorLayer('{}|layerid=0'.format(datasource), 'test', 'ogr') caps = vl.dataProvider().capabilities() self.assertTrue(caps & QgsVectorDataProvider.AddFeatures) self.assertTrue(caps & QgsVectorDataProvider.DeleteFeatures) self.assertTrue(caps & QgsVectorDataProvider.ChangeAttributeValues) self.assertTrue(caps & QgsVectorDataProvider.AddAttributes) self.assertTrue(caps & QgsVectorDataProvider.DeleteAttributes) self.assertTrue(caps & QgsVectorDataProvider.CreateSpatialIndex) self.assertTrue(caps & QgsVectorDataProvider.SelectAtId) self.assertTrue(caps & QgsVectorDataProvider.ChangeGeometries) # self.assertTrue(caps & QgsVectorDataProvider.ChangeFeatures) # We should be really opened in read-only mode even if write capabilities are declared self.assertEqual(vl.dataProvider().property("_debug_open_mode"), "read-only") # Unbalanced call to leaveUpdateMode() self.assertFalse(vl.dataProvider().leaveUpdateMode()) # Test that startEditing() / commitChanges() plays with enterUpdateMode() / leaveUpdateMode() self.assertTrue(vl.startEditing()) self.assertEqual(vl.dataProvider().property("_debug_open_mode"), "read-write") self.assertTrue(vl.dataProvider().isValid()) self.assertTrue(vl.commitChanges()) self.assertEqual(vl.dataProvider().property("_debug_open_mode"), "read-only") self.assertTrue(vl.dataProvider().isValid()) # Manual enterUpdateMode() / leaveUpdateMode() with 2 depths self.assertTrue(vl.dataProvider().enterUpdateMode()) self.assertEqual(vl.dataProvider().property("_debug_open_mode"), "read-write") caps = vl.dataProvider().capabilities() self.assertTrue(caps & QgsVectorDataProvider.AddFeatures) f = QgsFeature() f.setAttributes([200]) f.setGeometry(QgsGeometry.fromWkt('Point (2 49)')) (ret, feature_list) = vl.dataProvider().addFeatures([f]) self.assertTrue(ret) fid = feature_list[0].id() features = [ f_iter for f_iter in vl.getFeatures(QgsFeatureRequest().setFilterFid(fid)) ] values = [f_iter['pk'] for f_iter in features] self.assertEqual(values, [200]) got_geom = [f_iter.geometry() for f_iter in features][0].constGet() self.assertEqual((got_geom.x(), got_geom.y()), (2.0, 49.0)) self.assertTrue(vl.dataProvider().changeGeometryValues( {fid: QgsGeometry.fromWkt('Point (3 50)')})) self.assertTrue(vl.dataProvider().changeAttributeValues( {fid: { 0: 100 }})) features = [ f_iter for f_iter in vl.getFeatures(QgsFeatureRequest().setFilterFid(fid)) ] values = [f_iter['pk'] for f_iter in features] got_geom = [f_iter.geometry() for f_iter in features][0].constGet() self.assertEqual((got_geom.x(), got_geom.y()), (3.0, 50.0)) self.assertTrue(vl.dataProvider().deleteFeatures([fid])) # Check that it has really disappeared osgeo.gdal.PushErrorHandler('CPLQuietErrorHandler') features = [ f_iter for f_iter in vl.getFeatures(QgsFeatureRequest().setFilterFid(fid)) ] osgeo.gdal.PopErrorHandler() self.assertEqual(features, []) self.assertTrue(vl.dataProvider().addAttributes( [QgsField("new_field", QVariant.Int, "integer")])) self.assertTrue(vl.dataProvider().deleteAttributes( [len(vl.dataProvider().fields()) - 1])) self.assertTrue(vl.startEditing()) self.assertEqual(vl.dataProvider().property("_debug_open_mode"), "read-write") self.assertTrue(vl.commitChanges()) self.assertEqual(vl.dataProvider().property("_debug_open_mode"), "read-write") self.assertTrue(vl.dataProvider().enterUpdateMode()) self.assertEqual(vl.dataProvider().property("_debug_open_mode"), "read-write") self.assertTrue(vl.dataProvider().leaveUpdateMode()) self.assertEqual(vl.dataProvider().property("_debug_open_mode"), "read-write") self.assertTrue(vl.dataProvider().leaveUpdateMode()) self.assertEqual(vl.dataProvider().property("_debug_open_mode"), "read-only") # Test that update mode will be implictly enabled if doing an action # that requires update mode (ret, _) = vl.dataProvider().addFeatures([QgsFeature()]) self.assertTrue(ret) self.assertEqual(vl.dataProvider().property("_debug_open_mode"), "read-write")
# check if point lies within bbox def in_bbox(point): x, y = point if (x>=xmin and x<=xmax) and \ (y>=ymin and y<=ymax): return True return False # create check layer checkLayer = QgsVectorLayer('Linestring', 'check', 'memory') provider = checkLayer.dataProvider() checkLayer.startEditing() # fetch ways feats # lying within the bbox segments = [] for feat in ways.getFeatures(): geom = feat.geometry() # if only one point for point in geom.get(): if in_bbox((point.x(), point.y())): # create feat feat = QgsFeature() feat.setGeometry(geom) provider.addFeature(feat) break
def doLayer(self, item): ogrFeature = item.data(Qt.UserRole) geom = QgsGeometry.fromWkt(ogrFeature.GetGeometryRef().ExportToWkt()) self.transform(geom) fields = QgsFields() fields.append(QgsField("id", QVariant.String)) fields.append(QgsField("name", QVariant.String)) fet = QgsFeature() fet.initAttributes(2) fet.setFields(fields) fet.setGeometry(geom) fet.setAttribute("id", (ogrFeature.GetFieldAsString('id'))) fet.setAttribute("name", (ogrFeature.GetFieldAsString('name'))) vl = None if not self.plugin.singleLayer: if geom.type() == QgsWkbTypes.PolygonGeometry: layerName = "OSMPlaceSearch Polygon" layerId = self.MultiPolygonLayerId if geom.type() == QgsWkbTypes.LineGeometry: layerName = "OSMPlaceSearch Line" layerId = self.LineLayerId if geom.type() == QgsWkbTypes.PointGeometry: layerName = "OSMPlaceSearch Point" layerId = self.PointLayerId vl = QgsProject.instance().mapLayer(layerId) if vl is not None: pr = vl.dataProvider() else: if geom.type() == QgsWkbTypes.PolygonGeometry: vl = QgsVectorLayer("MultiPolygon", layerName, "memory") self.MultiPolygonLayerId = vl.id() if geom.type() == QgsWkbTypes.LineGeometry: vl = QgsVectorLayer("MultiLineString", layerName, "memory") self.LineLayerId = vl.id() if geom.type() == QgsWkbTypes.PointGeometry: vl = QgsVectorLayer("Point", layerName, "memory") self.PointLayerId = vl.id() if vl is not None: pr = vl.dataProvider() # ajout de champs pr.addAttributes(fields.toList()) QgsProject.instance().addMapLayer(vl) else: layerName = "OSM "+ogrFeature.GetFieldAsString('id') # creer une nouvelle couche si n'existe pas encore if geom.type() == QgsWkbTypes.PolygonGeometry: vl = QgsVectorLayer("MultiPolygon", layerName, "memory") if geom.type() == QgsWkbTypes.LineGeometry: vl = QgsVectorLayer("MultiLineString", layerName, "memory") if geom.type() == QgsWkbTypes.PointGeometry: vl = QgsVectorLayer("Point", layerName, "memory") if vl is not None: pr = vl.dataProvider() # ajout de champs pr.addAttributes(fields.toList()) vl.setCrs(self.plugin.canvas.mapSettings().destinationCrs()) QgsProject.instance().addMapLayer(vl) if vl is not None: vl.setProviderEncoding('UTF-8') vl.startEditing() pr.addFeatures([fet]) vl.commitChanges() # mise a jour etendue de la couche vl.updateExtents() layerTree = QgsProject.instance().layerTreeRoot().findLayer(vl) if layerTree: self.plugin.iface.layerTreeView()\ .layerTreeModel().refreshLayerLegend(layerTree) # Refresh legend self.go(item, False)
def set_contour_properties(self, input_file): """Set the X, Y, RGB, ROMAN attributes of the contour layer. :param input_file: (Required) Name of the contour layer. :type input_file: str :raise: InvalidLayerError if anything is amiss with the layer. """ LOGGER.debug('set_contour_properties requested for %s.' % input_file) layer = QgsVectorLayer(input_file, 'mmi-contours', "ogr") if not layer.isValid(): raise InvalidLayerError(input_file) layer.startEditing() # Now loop through the db adding selected features to mem layer request = QgsFeatureRequest() fields = layer.dataProvider().fields() for feature in layer.getFeatures(request): if not feature.isValid(): LOGGER.debug('Skipping feature') continue # Work out x and y line = feature.geometry().asPolyline() y = line[0].y() x_max = line[0].x() x_min = x_max for point in line: if point.y() < y: y = point.y() x = point.x() if x < x_min: x_min = x if x > x_max: x_max = x x = x_min + ((x_max - x_min) / 2) # Get length length = feature.geometry().length() mmi_value = float(feature['MMI']) # We only want labels on the whole number contours if mmi_value != round(mmi_value): roman = '' else: roman = romanise(mmi_value) # RGB from http://en.wikipedia.org/wiki/Mercalli_intensity_scale rgb = mmi_colour(mmi_value) # Now update the feature feature_id = feature.id() layer.changeAttributeValue(feature_id, fields.indexFromName('X'), x) layer.changeAttributeValue(feature_id, fields.indexFromName('Y'), y) layer.changeAttributeValue(feature_id, fields.indexFromName('RGB'), rgb) layer.changeAttributeValue(feature_id, fields.indexFromName('ROMAN'), roman) layer.changeAttributeValue(feature_id, fields.indexFromName('ALIGN'), 'Center') layer.changeAttributeValue(feature_id, fields.indexFromName('VALIGN'), 'HALF') layer.changeAttributeValue(feature_id, fields.indexFromName('LEN'), length) layer.commitChanges()
def doMask(self, item): mapcrs = self.plugin.canvas.mapSettings().destinationCrs() ogrFeature = item.data(Qt.UserRole) layerName = "OSM "+ogrFeature.GetFieldAsString('id') geom = QgsGeometry.fromWkt(ogrFeature.GetGeometryRef().ExportToWkt()) self.transform(geom) if (geom.type() == QgsWkbTypes.PolygonGeometry): try: try: from mask import aeag_mask except: from mask_plugin import aeag_mask aeag_mask.do(mapcrs, {geom}, "Mask "+layerName) except: geom = QgsGeometry.fromWkt(ogrFeature.GetGeometryRef().ExportToWkt()) self.transform(geom) toCrs = self.plugin.canvas.mapSettings().destinationCrs() larg = max(geom.boundingBox().width(), geom.boundingBox().height()) x = geom.boundingBox().center().x() y = geom.boundingBox().center().y() rect = QgsRectangle(x-larg, y-larg, x+larg, y+larg) # geom.boundingBox() rect.scale(4) mask = QgsGeometry.fromRect(rect) mask = mask.difference(geom) maskLayer = QgsVectorLayer("MultiPolygon", "Mask "+layerName, "memory") maskLayer.setCrs(toCrs) QgsProject.instance().addMapLayer(maskLayer) pr = maskLayer.dataProvider() fields = QgsFields() fields.append(QgsField("id", QVariant.String)) fields.append(QgsField("name", QVariant.String)) fet = QgsFeature() fet.initAttributes(2) fet.setGeometry(mask) fet.setFields(fields) fet.setAttribute("id", (ogrFeature.GetFieldAsString('id'))) fet.setAttribute("name", (ogrFeature.GetFieldAsString('name'))) pr.addAttributes(fields.toList()) maskLayer.startEditing() pr.addFeatures([fet]) maskLayer.commitChanges() maskLayer.updateExtents() # transparence, epaisseur renderer = maskLayer.renderer() s = renderer.symbol() s.setOpacity(0.90) s.setColor(QColor(255, 255, 255)) if isinstance(s, QgsLineSymbol): s.setWidth(0) layerTree = QgsProject.instance().layerTreeRoot().findLayer(maskLayer) if layerTree: self.plugin.iface.layerTreeView().layerTreeModel()\ .refreshLayerLegend(layerTree) # Refresh legend self.go(item)
def test_check_gaps_in_plots(self): gpkg_path = get_test_copy_path('geopackage/tests_data.gpkg') uri = gpkg_path + '|layername={layername}'.format( layername='check_gaps_in_plots') test_plots_layer = QgsVectorLayer(uri, 'check_gaps_in_plots', 'ogr') print( '\nINFO: Validating Gaps in Plots using roads and multiple geometries...' ) gaps = self.qgis_utils.geometry.get_gaps_in_polygon_layer( test_plots_layer, include_roads=True) geometries = [g.asWkt() for g in gaps] expected_list = [ 'Polygon ((1001839.42949045938439667 1013500.23419545334763825, 1001838.68766217899974436 1013479.83391774445772171, 1001839.42949045938439667 1013450.16078653128352016, 1001855.74971262644976377 1013449.78987239114940166, 1001858.3461116076214239 1013430.87325124291237444, 1001885.42284383939113468 1013430.87325124291237444, 1001901.72405463655013591 1013411.57209242216777056, 1001910.64500537037383765 1013418.26217047742102295, 1001917.32145989337004721 1013392.29818066605366766, 1001845.19794039404951036 1013415.08188382943626493, 1001851.47861975431442261 1013424.31817700632382184, 1001833.74493685469496995 1013433.92392191023100168, 1001829.49624199338722974 1013421.7320149167208001, 1001839.42949045938439667 1013500.23419545334763825))', 'Polygon ((1001935.86716690135654062 1013432.35690780356526375, 1001921.03060129494406283 1013446.08073098957538605, 1001920.28877301455941051 1013475.7538622027495876, 1001957.38018703076522797 1013429.01868054212536663, 1001935.86716690135654062 1013432.35690780356526375))', 'Polygon ((1001935.86716690135654062 1013432.35690780356526375, 1001921.03060129494406283 1013446.08073098957538605, 1001920.28877301455941051 1013475.7538622027495876, 1001957.38018703076522797 1013429.01868054212536663, 1001935.86716690135654062 1013432.35690780356526375))', 'Polygon ((1001920.28877301455941051 1013475.7538622027495876, 1001861.31342472892720252 1013477.9793470436707139, 1001862.05525300919543952 1013498.37962475256063044, 1001920.28877301455941051 1013475.7538622027495876))', 'Polygon ((1001895.43752562382724136 1013467.22283697873353958, 1001907.30677810893394053 1013464.25552385742776096, 1001907.67769224906805903 1013454.2408420731080696, 1001895.43752562382724136 1013454.2408420731080696, 1001895.43752562382724136 1013467.22283697873353958))', 'Polygon ((1001847.96051568305119872 1013470.1901501000393182, 1001867.98987925180699676 1013469.07740767952054739, 1001869.10262167232576758 1013455.72449863376095891, 1001847.58960154291708022 1013455.72449863376095891, 1001847.96051568305119872 1013470.1901501000393182))' ] for expected in expected_list: self.assertIn(expected, geometries) self.assertEqual(len(geometries), 5) print( '\nINFO: Validating Gaps in Plots using roads for one geometry...') test_plots_layer.startEditing() test_plots_layer.deleteFeature(2) gaps = self.qgis_utils.geometry.get_gaps_in_polygon_layer( test_plots_layer, include_roads=True) geometries = [g.asWkt() for g in gaps] self.assertIn( 'Polygon ((1001895.43752562382724136 1013467.22283697873353958, 1001907.30677810893394053 1013464.25552385742776096, 1001907.67769224906805903 1013454.2408420731080696, 1001895.43752562382724136 1013454.2408420731080696, 1001895.43752562382724136 1013467.22283697873353958))', geometries) self.assertIn( 'Polygon ((1001847.96051568305119872 1013470.1901501000393182, 1001867.98987925180699676 1013469.07740767952054739, 1001869.10262167232576758 1013455.72449863376095891, 1001847.58960154291708022 1013455.72449863376095891, 1001847.96051568305119872 1013470.1901501000393182))', geometries) self.assertEqual(len(geometries), 2) test_plots_layer.rollBack() print( '\nINFO: Validating Gaps in Plots without using roads and multiple geometries...' ) gaps = self.qgis_utils.geometry.get_gaps_in_polygon_layer( test_plots_layer, include_roads=False) geometries = [g.asWkt() for g in gaps] self.assertIn( 'Polygon ((1001895.43752562382724136 1013467.22283697873353958, 1001907.30677810893394053 1013464.25552385742776096, 1001907.67769224906805903 1013454.2408420731080696, 1001895.43752562382724136 1013454.2408420731080696, 1001895.43752562382724136 1013467.22283697873353958))', geometries) self.assertIn( 'Polygon ((1001847.96051568305119872 1013470.1901501000393182, 1001867.98987925180699676 1013469.07740767952054739, 1001869.10262167232576758 1013455.72449863376095891, 1001847.58960154291708022 1013455.72449863376095891, 1001847.96051568305119872 1013470.1901501000393182))', geometries) self.assertEqual(len(geometries), 2) print( '\nINFO: Validating Gaps in Plots without using roads for one geometry...' ) test_plots_layer.startEditing() test_plots_layer.deleteFeature(2) gaps = self.qgis_utils.geometry.get_gaps_in_polygon_layer( test_plots_layer, include_roads=False) geometries = [g.asWkt() for g in gaps] self.assertIn( 'Polygon ((1001895.43752562382724136 1013467.22283697873353958, 1001907.30677810893394053 1013464.25552385742776096, 1001907.67769224906805903 1013454.2408420731080696, 1001895.43752562382724136 1013454.2408420731080696, 1001895.43752562382724136 1013467.22283697873353958))', geometries) self.assertIn( 'Polygon ((1001847.96051568305119872 1013470.1901501000393182, 1001867.98987925180699676 1013469.07740767952054739, 1001869.10262167232576758 1013455.72449863376095891, 1001847.58960154291708022 1013455.72449863376095891, 1001847.96051568305119872 1013470.1901501000393182))', geometries) self.assertEqual(len(geometries), 2) test_plots_layer.rollBack() print( '\nINFO: Validating Gaps in Plots using roads for only one geometry...' ) test_plots_layer.startEditing() test_plots_layer.deleteFeature(1) test_plots_layer.deleteFeature(2) test_plots_layer.deleteFeature(3) gaps = self.qgis_utils.geometry.get_gaps_in_polygon_layer( test_plots_layer, include_roads=True) geometries = [g.asWkt() for g in gaps] self.assertEqual([], geometries) self.assertEqual(len(geometries), 0) test_plots_layer.rollBack() print( '\nINFO: Validating Gaps in Plots without using roads for only one geometry...' ) test_plots_layer.startEditing() test_plots_layer.deleteFeature(1) test_plots_layer.deleteFeature(2) test_plots_layer.deleteFeature(3) gaps = self.qgis_utils.geometry.get_gaps_in_polygon_layer( test_plots_layer, include_roads=False) geometries = [g.asWkt() for g in gaps] self.assertEqual([], geometries) self.assertEqual(len(geometries), 0) test_plots_layer.rollBack() print( '\nINFO: Validating Gaps in Plots using roads for two geometries...' ) test_plots_layer.startEditing() test_plots_layer.deleteFeature(1) test_plots_layer.deleteFeature(3) gaps = self.qgis_utils.geometry.get_gaps_in_polygon_layer( test_plots_layer, include_roads=True) geometries = [g.asWkt() for g in gaps] self.assertIn( 'Polygon ((1001889.87381352134980261 1013447.93530169036239386, 1001885.42284383939113468 1013430.87325124291237444, 1001901.72405463655013591 1013411.57209242216777056, 1001845.19794039404951036 1013415.08188382943626493, 1001851.47861975431442261 1013424.31817700632382184, 1001833.74493685469496995 1013433.92392191023100168, 1001889.87381352134980261 1013447.93530169036239386))', geometries) self.assertEqual(len(geometries), 1) test_plots_layer.rollBack() print( '\nINFO: Validating Gaps in Plots without using roads for two geometries...' ) test_plots_layer.startEditing() test_plots_layer.deleteFeature(1) test_plots_layer.deleteFeature(3) gaps = self.qgis_utils.geometry.get_gaps_in_polygon_layer( test_plots_layer, include_roads=False) geometries = [g.asWkt() for g in gaps] self.assertEqual([], geometries) self.assertEqual(len(geometries), 0) test_plots_layer.rollBack()
def epa2gis(inpname): plugin_path = os.path.dirname(__file__) file_extension = os.path.dirname(inpname) inpname = os.path.basename(inpname) inp = file_extension + '/' + inpname if len(file_extension) == 0: inp = inpname newpath = file_extension + '/_shapefiles_' if not os.path.exists(newpath): os.makedirs(newpath) iface = qgis.utils.iface d.LoadFile(inp) d.BinUpdateClass() nlinkCount = d.getBinLinkCount() res = newpath + '\\' saveFile = res + inpname[:len(inpname) - 4] # Get all Sections mixing = d.getMixingSection() reactions = d.getReactionsSection() sources = d.getSourcesSection() rules = d.getRulesSection() quality = d.getQualitySection() curves = d.getCurvesSection() patterns = d.getPatternsSection() controls = d.getControlsSection() emitters = d.getEmittersSection() status = d.getStatusSection() demands = d.getDemandsSection() energy = d.getEnergySection() optReactions = d.getReactionsOptionsSection() times = d.getTimesSection() report = d.getReportSection() options = d.getOptionsSection() # Get all Section lengths allSections = [len(energy), len(optReactions), len(demands), len(status), len(emitters), len(controls), len(patterns), len(curves[0]), len(quality), len(rules), len(sources), len(reactions), len(mixing), len(times), len(report), len(options), d.getBinNodeCount(), d.getBinLinkCount()] ss = max(allSections) root = QgsProject.instance().layerTreeRoot() idx = root.insertGroup(0, inpname[:len(inpname) - 4]) xy = d.getBinNodeCoordinates() x = xy[0] y = xy[1] vertx = xy[2] verty = xy[3] vertxyFinal = [] for i in range(len(vertx)): vertxy = [] for u in range(len(vertx[i])): vertxy.append([float(vertx[i][u]), float(verty[i][u])]) if vertxy: vertxyFinal.append(vertxy) otherDemads = d.getBinNodeBaseDemandsDemSection() ndID = d.getBinNodeNameID() ndBaseD = d.getBinNodeBaseDemands() ndPatID = d.getBinNodeDemandPatternID() otherDemadsIndex = [] otherDemadsPatterns = [] for i, p in enumerate(otherDemads[1]): otherDemadsIndex.append(ndID.index(p)) otherDemadsPatterns.append(otherDemads[2][i]) counter = collections.Counter(otherDemadsIndex) maxCategories = 1 if counter: maxCategories = max(counter.values()) if not ndBaseD: ndBaseD = otherDemads[0] # Get data of Junctions if d.getBinNodeJunctionCount() > 0: ndBaseTmp = np.empty((len(ndBaseD), maxCategories,)) ndPatTmp = [] for t in range(0, maxCategories): for u in range(0, len(ndBaseD)): ndBaseTmp[u][t] = 0 ndPatTmp.append(['None'] * 2) for uu in range(0, len(ndBaseD)): if d.getBinNodeBaseDemands(): ndBaseTmp[uu][0] = ndBaseD[uu] ndPatTmp[uu][0] = ndPatID[uu] t = 0 for i, p in enumerate(otherDemadsIndex): if d.getBinNodeBaseDemands(): ndBaseTmp[p][t] = ndBaseD[otherDemadsIndex[i]] ndPatTmp[p][t] = ndPatID[otherDemadsIndex[i]] else: ndBaseTmp[p][t] = otherDemads[0][i] ndPatTmp[p][t] = otherDemads[2][i] t = t + 1 if t > max(counter.values()) - 1: t = max(counter.values()) - 1 if i > 0: if otherDemadsIndex[i - 1] == p: ndBaseTmp[p][t] = otherDemads[0][i] ndPatTmp[p][t] = otherDemads[2][i] t = t - 1 # Write Junction Shapefile fields = ["ID", "Elevation"] # , "pattern", "demand"] fieldsCode = [0, 1] for u in range(0, maxCategories): fields.append('Demand' + str(u + 1)) fields.append('Pattern' + str(u + 1)) fieldsCode.append(1) fieldsCode.append(0) posJunction = QgsVectorLayer("point?crs=EPSG:4326", "Junctions", "memory") prJunction = posJunction.dataProvider() ndBaseTmp = ndBaseTmp.tolist() createColumnsAttrb(prJunction, fields, fieldsCode) posJunction.startEditing() ndEle = d.getBinNodeJunctionElevations() # Get data of Pipes # Write shapefile pipe if nlinkCount > 0: posPipe = QgsVectorLayer("LineString?crs=EPSG:4326", "Pipes", "memory") prPipe = posPipe.dataProvider() fields = ["ID", "NodeFrom", "NodeTo", "Status", "Length", "Diameter", "Roughness", "MinorLoss"] fieldsCode = [0, 0, 0, 0, 1, 1, 1, 1] createColumnsAttrb(prPipe, fields, fieldsCode) posPipe.startEditing() pIndex = d.getBinLinkPumpIndex() vIndex = d.getBinLinkValveIndex() ndlConn = d.getBinNodesConnectingLinksID() x1 = [] x2 = [] y1 = [] y2 = [] stat = d.getBinLinkInitialStatus() kk = 0 ch = 0 linkID = d.getBinLinkNameID() linkLengths = d.getBinLinkLength() linkDiameters = d.getBinLinkDiameter() linkRough = d.getBinLinkRoughnessCoeff() linkMinorloss = d.getBinLinkMinorLossCoeff() # Write Tank Shapefile and get tank data posTank = QgsVectorLayer("point?crs=EPSG:4326", "Tanks", "memory") prTank = posTank.dataProvider() fields = ["ID", "Elevation", "InitLevel", "MinLevel", "MaxLevel", "Diameter", "MinVolume", "VolumeCurve"] fieldsCode = [0, 1, 1, 1, 1, 1, 1, 0] createColumnsAttrb(prTank, fields, fieldsCode) posTank.startEditing() if d.getBinNodeTankCount() > 0: ndTankelevation = d.getBinNodeTankElevations() initiallev = d.getBinNodeTankInitialLevel() minimumlev = d.getBinNodeTankMinimumWaterLevel() maximumlev = d.getBinNodeTankMaximumWaterLevel() diameter = d.getBinNodeTankDiameter() minimumvol = d.getBinNodeTankMinimumWaterVolume() volumecurv = d.getBinNodeTankVolumeCurveID() ndTankID = d.getBinNodeTankNameID() # Write Reservoir Shapefile posReservoirs = QgsVectorLayer("point?crs=EPSG:4326", "Reservoirs", "memory") prReservoirs = posReservoirs.dataProvider() fields = ["ID", "Head"] fieldsCode = [0, 1] createColumnsAttrb(prReservoirs, fields, fieldsCode) head = d.getBinNodeReservoirElevations() posReservoirs.startEditing() if times: posTimes = QgsVectorLayer("point?crs=EPSG:4326", "Times", "memory") prTimes = posTimes.dataProvider() if energy: posE = QgsVectorLayer("point?crs=EPSG:4326", "Energy", "memory") prE = posE.dataProvider() if report: posRep = QgsVectorLayer("point?crs=EPSG:4326", "Report", "memory") prRep = posRep.dataProvider() if options: posOpt = QgsVectorLayer("point?crs=EPSG:4326", "Options", "memory") prOpt = posOpt.dataProvider() if optReactions: posO = QgsVectorLayer("point?crs=EPSG:4326", "Reactions", "memory") prO = posO.dataProvider() ppE = [] ppO = [] ppTimes = [] ppRep = [] ppOpt = [] ppMix = [] ppReactions = [] ppSourc = [] ppRul = [] ppPat = [] ppQual = [] ppDem = [] ppStat = [] ppEmit = [] ppCont = [] ppCurv = [] for i in range(ss): if i < d.getBinNodeJunctionCount(): featJ = QgsFeature() point = QgsPointXY(float(x[i]), float(y[i])) featJ.initAttributes(2 + len(ndBaseTmp[0]) * 2) featJ.setGeometry(QgsGeometry.fromPointXY(point)) featJ.setAttribute(0, ndID[i]) featJ.setAttribute(1, ndEle[i]) w = 2 for j in range(0, len(ndBaseTmp[0])): featJ.setAttribute(w, ndBaseTmp[i][j]) featJ.setAttribute(w + 1, ndPatTmp[i][j]) w = w + 2 prJunction.addFeatures([featJ]) if i < nlinkCount: if len(stat) == i: ch = 1 if ch == 1: stat.append('OPEN') x1.append(x[ndID.index(d.getBinLinkFromNode()[i])]) y1.append(y[ndID.index(d.getBinLinkFromNode()[i])]) x2.append(x[ndID.index(d.getBinLinkToNode()[i])]) y2.append(y[ndID.index(d.getBinLinkToNode()[i])]) if i in pIndex: pass elif i in vIndex: pass else: point1 = QgsPointXY(float(x1[i]), float(y1[i])) point2 = QgsPointXY(float(x2[i]), float(y2[i])) featPipe = QgsFeature() if vertx[i]: parts = [] parts.append(point1) for mm in range(len(vertxyFinal[kk])): a = vertxyFinal[kk][mm] parts.append(QgsPointXY(a[0], a[1])) parts.append(point2) featPipe.setGeometry((QgsGeometry.fromPolylineXY(parts))) kk = kk + 1 else: featPipe.setGeometry(QgsGeometry.fromPolylineXY([point1, point2])) featPipe.setAttributes( [linkID[i], ndlConn[0][i], ndlConn[1][i], stat[i], linkLengths[i], linkDiameters[i], linkRough[i], linkMinorloss[i]]) prPipe.addFeatures([featPipe]) if i < d.getBinNodeTankCount(): p = d.getBinNodeTankIndex()[i] - 1 featTank = QgsFeature() point = QgsPointXY(float(x[p]), float(y[p])) featTank.setGeometry(QgsGeometry.fromPointXY(point)) featTank.setAttributes( [ndTankID[i], ndTankelevation[i], initiallev[i], minimumlev[i], maximumlev[i], diameter[i], minimumvol[i], volumecurv[i]]) prTank.addFeatures([featTank]) if i < d.getBinNodeReservoirCount(): p = d.getBinNodeReservoirIndex()[i] - 1 feature = QgsFeature() point = QgsPointXY(float(x[p]), float(y[p])) feature.setGeometry(QgsGeometry.fromPointXY(point)) feature.setAttributes([ndID[p], head[i]]) prReservoirs.addFeatures([feature]) if i < allSections[12]: if len(mixing[i]) == 3: ppMix.append([mixing[i][0], mixing[i][1], mixing[i][2]]) else: ppMix.append([mixing[i][0], mixing[i][1]]) if i < allSections[11]: ppReactions.append([reactions[i][0], reactions[i][1], reactions[i][2]]) if i < allSections[10]: if len(sources[i]) == 4: ppSourc.append([sources[i][0], sources[i][1], sources[i][2], sources[i][3]]) elif len(sources[i]) == 3: ppSourc.append([sources[i][0], sources[i][1], sources[i][2]]) else: ppSourc.append([sources[i][0], sources[i][1]]) if i < allSections[9]: if len(rules[i]) > 2: ppRul.append([rules[i][0][1][1], rules[i][1][0] + rules[i][2][0] + rules[i][3][0]]) if i < allSections[8]: ppQual.append([quality[i][0], quality[i][1]]) if i < allSections[7]: ppCurv.append([str(curves[0][i][0]), str(curves[0][i][1]), str(curves[0][i][2]), str(curves[1][i])]) if i < allSections[6]: ppPat.append([patterns[i][0], str(patterns[i][1])]) if i < allSections[5]: ppCont.append([controls[i]]) if i < allSections[4]: ppEmit.append([emitters[i][0], emitters[i][1]]) if i < allSections[3]: ppStat.append([status[i][0], status[i][1]]) if i < allSections[2]: if len(demands[i]) > 2: ppDem.append([demands[i][0], demands[i][1], demands[i][2]]) if i < allSections[0]: mm = energy[i][0] if mm.upper() == "GLOBAL": prE.addAttributes([QgsField("Global" + energy[i][1], QVariant.String)]) if len(energy[i]) > 2: ppE.append(energy[i][2]) else: ppE.append('') if mm.upper() == "PUMP": prE.addAttributes([QgsField("Pump", QVariant.String)]) if len(energy[i]) > 2: ppE.append(energy[i][1] + ' ' + energy[i][2]) else: ppE.append(energy[i][1]) elif mm.upper() == "DEMAND": if energy[i][1].upper() == "CHARGE": prE.addAttributes([QgsField("DemCharge", QVariant.String)]) if len(energy[i]) > 2: ppE.append(energy[i][2]) if i < allSections[1]: mm = optReactions[i][0] if mm.upper() == "ORDER": prO.addAttributes([QgsField("Order" + optReactions[i][1], QVariant.String)]) if len(optReactions[i]) > 2: ppO.append(optReactions[i][2]) else: ppO.append('') elif mm.upper() == "GLOBAL": prO.addAttributes([QgsField("Global" + optReactions[i][1], QVariant.String)]) if len(optReactions[i]) > 2: ppO.append(optReactions[i][2]) else: ppO.append('') elif mm.upper() == "BULK": prO.addAttributes([QgsField("Bulk", QVariant.String)]) if len(optReactions[i]) > 2: ppO.append(optReactions[i][1] + ' ' + optReactions[i][2]) else: ppO.append(optReactions[i][1]) elif mm.upper() == "WALL": prO.addAttributes([QgsField("Wall", QVariant.String)]) if len(optReactions[i]) > 2: ppO.append(optReactions[i][1] + ' ' + optReactions[i][2]) else: ppO.append(optReactions[i][1]) elif mm.upper() == "TANK": prO.addAttributes([QgsField("Tank", QVariant.String)]) if len(optReactions[i]) > 2: ppO.append(optReactions[i][1] + ' ' + optReactions[i][2]) else: ppO.append(optReactions[i][1]) elif mm.upper() == "LIMITING": if optReactions[i][1].upper() == "POTENTIAL": prO.addAttributes([QgsField("LimPotent", QVariant.String)]) if len(optReactions[i]) > 2: ppO.append(optReactions[i][2]) elif mm.upper() == "ROUGHNESS": if optReactions[i][1].upper() == "CORRELATION": prO.addAttributes([QgsField("RoughCorr", QVariant.String)]) if len(optReactions[i]) > 2: ppO.append(optReactions[i][2]) if i < allSections[13]: mm = times[i][0] if mm.upper() == "DURATION": prTimes.addAttributes([QgsField("Duration", QVariant.String)]) ppTimes.append(times[i][1]) if mm.upper() == "HYDRAULIC": prTimes.addAttributes([QgsField("HydStep", QVariant.String)]) ppTimes.append(times[i][2]) elif mm.upper() == "QUALITY": prTimes.addAttributes([QgsField("QualStep", QVariant.String)]) ppTimes.append(times[i][2]) elif mm.upper() == "RULE": prTimes.addAttributes([QgsField("RuleStep", QVariant.String)]) ppTimes.append(times[i][2]) elif mm.upper() == "PATTERN": if times[i][1].upper() == "TIMESTEP": prTimes.addAttributes([QgsField("PatStep", QVariant.String)]) ppTimes.append(times[i][2]) if times[i][1].upper() == "START": prTimes.addAttributes([QgsField("PatStart", QVariant.String)]) ppTimes.append(times[i][2]) elif mm.upper() == "REPORT": if times[i][1].upper() == "TIMESTEP": prTimes.addAttributes([QgsField("RepStep", QVariant.String)]) ppTimes.append(times[i][2]) if times[i][1].upper() == "START": prTimes.addAttributes([QgsField("RepStart", QVariant.String)]) ppTimes.append(times[i][2]) elif mm.upper() == "START": if times[i][1].upper() == "CLOCKTIME": prTimes.addAttributes([QgsField("StartClock", QVariant.String)]) if len(times[i]) > 3: ppTimes.append(times[i][2] + ' ' + times[i][3]) else: ppTimes.append(times[i][2]) elif mm.upper() == "STATISTIC": prTimes.addAttributes([QgsField("Statistic", QVariant.String)]) if times[i][1].upper() == 'NONE' or times[i][1].upper() == 'AVERAGE' or times[i][1].upper() \ == 'MINIMUM' or times[i][1].upper() == 'MAXIMUM' or times[i][1].upper() == 'RANGE': ppTimes.append(times[i][1]) if i < allSections[14]: mm = report[i][0] if mm.upper() == "PAGESIZE": prRep.addAttributes([QgsField("PageSize", QVariant.String)]) ppRep.append(report[i][1]) if mm.upper() == "FILE": prRep.addAttributes([QgsField("FileName", QVariant.String)]) ppRep.append(report[i][1]) elif mm.upper() == "STATUS": prRep.addAttributes([QgsField("Status", QVariant.String)]) ppRep.append(report[i][1]) elif mm.upper() == "SUMMARY": prRep.addAttributes([QgsField("Summary", QVariant.String)]) ppRep.append(report[i][1]) elif mm.upper() == "ENERGY": prRep.addAttributes([QgsField("Energy", QVariant.String)]) ppRep.append(report[i][1]) elif mm.upper() == "NODES": prRep.addAttributes([QgsField("Nodes", QVariant.String)]) if len(report[i]) > 2: ppRep.append(report[i][1] + ' ' + report[i][2]) else: ppRep.append(report[i][1]) elif mm.upper() == "LINKS": prRep.addAttributes([QgsField("Links", QVariant.String)]) if len(report[i]) > 2: ppRep.append(report[i][1] + ' ' + report[i][2]) else: ppRep.append(report[i][1]) else: prRep.addAttributes([QgsField(mm, QVariant.String)]) if len(report[i]) > 2: ppRep.append(report[i][1] + ' ' + report[i][2]) else: ppRep.append(report[i][1]) if i < allSections[15]: mm = options[i][0] if mm.upper() == "UNITS": prOpt.addAttributes([QgsField("Units", QVariant.String)]) ppOpt.append(options[i][1]) if mm.upper() == "HYDRAULICS": prOpt.addAttributes([QgsField("Hydraulics", QVariant.String)]) if len(options[i]) > 2: ppOpt.append(options[i][1] + ' ' + options[i][2]) else: ppOpt.append(options[i][1]) elif mm.upper() == "QUALITY": prOpt.addAttributes([QgsField("Quality", QVariant.String)]) if len(options[i]) > 2: ppOpt.append(options[i][1] + ' ' + options[i][2]) elif len(options[i]) > 3: ppOpt.append(options[i][1] + ' ' + options[i][2] + ' ' + options[i][3]) else: ppOpt.append(options[i][1]) elif mm.upper() == "VISCOSITY": prOpt.addAttributes([QgsField("Viscosity", QVariant.String)]) ppOpt.append(options[i][1]) elif mm.upper() == "DIFFUSIVITY": prOpt.addAttributes([QgsField("Diffusivity", QVariant.String)]) ppOpt.append(options[i][1]) elif mm.upper() == "SPECIFIC": if options[i][1].upper() == "GRAVITY": prOpt.addAttributes([QgsField("SpecGrav", QVariant.String)]) ppOpt.append(options[i][2]) elif mm.upper() == "TRIALS": prOpt.addAttributes([QgsField("Trials", QVariant.String)]) ppOpt.append(options[i][1]) elif mm.upper() == "HEADLOSS": prOpt.addAttributes([QgsField("Headloss", QVariant.String)]) ppOpt.append(options[i][1]) elif mm.upper() == "ACCURACY": prOpt.addAttributes([QgsField("Accuracy", QVariant.String)]) ppOpt.append(options[i][1]) elif mm.upper() == "UNBALANCED": prOpt.addAttributes([QgsField("Unbalanced", QVariant.String)]) if len(options[i]) > 2: ppOpt.append(options[i][1] + ' ' + options[i][2]) else: ppOpt.append(options[i][1]) elif mm.upper() == "PATTERN": prOpt.addAttributes([QgsField("PatID", QVariant.String)]) ppOpt.append(options[i][1]) elif mm.upper() == "TOLERANCE": prOpt.addAttributes([QgsField("Tolerance", QVariant.String)]) ppOpt.append(options[i][1]) elif mm.upper() == "MAP": prOpt.addAttributes([QgsField("Map", QVariant.String)]) ppOpt.append(options[i][1]) elif mm.upper() == "DEMAND": if options[i][1].upper() == "MULTIPLIER": prOpt.addAttributes([QgsField("DemMult", QVariant.String)]) ppOpt.append(options[i][2]) elif mm.upper() == "EMITTER": if options[i][1].upper() == "EXPONENT": prOpt.addAttributes([QgsField("EmitExp", QVariant.String)]) ppOpt.append(options[i][2]) elif mm.upper() == "CHECKFREQ": prOpt.addAttributes([QgsField("CheckFreq", QVariant.String)]) ppOpt.append(options[i][1]) elif mm.upper() == "MAXCHECK": prOpt.addAttributes([QgsField("MaxCheck", QVariant.String)]) ppOpt.append(options[i][1]) elif mm.upper() == "DAMPLIMIT": prOpt.addAttributes([QgsField("DampLimit", QVariant.String)]) ppOpt.append(options[i][1]) writeDBF(posOpt, [ppOpt], prOpt, saveFile, inpname, "_OPTIONS", idx) writeDBF(posRep, [ppRep], prRep, saveFile, inpname, "_REPORT", idx) #if times: writeDBF(posTimes, [ppTimes], prTimes, saveFile, inpname, "_TIMES", idx) #if energy: writeDBF(posE, [ppE], prE, saveFile, inpname, "_ENERGY", idx) #if optReactions: writeDBF(posO, [ppO], prO, saveFile, inpname, "_REACTIONS", idx) posMix = QgsVectorLayer("point?crs=EPSG:4326", "Mixing", "memory") prMix = posMix.dataProvider() fields = ["Tank_ID", "Model", "Fraction"] fieldsCode = [0, 0, 1] # 0 String, 1 Double createColumnsAttrb(prMix, fields, fieldsCode) writeDBF(posMix, ppMix, prMix, saveFile, inpname, "_MIXING", idx) posReact = QgsVectorLayer("point?crs=EPSG:4326", "ReactionsI", "memory") prReact = posReact.dataProvider() fields = ["Type", "Pipe/Tank", "Coeff."] fieldsCode = [0, 0, 1] createColumnsAttrb(prReact, fields, fieldsCode) writeDBF(posReact, ppReactions, prReact, saveFile, inpname, "_REACTIONS_I", idx) posSourc = QgsVectorLayer("point?crs=EPSG:4326", "Sources", "memory") prSourc = posSourc.dataProvider() fields = ["Node_ID", "Type", "Strength", "Pattern"] fieldsCode = [0, 0, 1, 0] createColumnsAttrb(prSourc, fields, fieldsCode) writeDBF(posSourc, ppSourc, prSourc, saveFile, inpname, "_SOURCES", idx) posRul = QgsVectorLayer("point?crs=EPSG:4326", "Rules", "memory") prRul = posRul.dataProvider() fields = ["Rule_ID", "Rule"] fieldsCode = [0, 0] createColumnsAttrb(prRul, fields, fieldsCode) writeDBF(posRul, ppRul, prRul, saveFile, inpname, "_RULES", idx) posQual = QgsVectorLayer("point?crs=EPSG:4326", "Sources", "memory") prQual = posQual.dataProvider() fields = ["Node_ID", "Init_Qual"] fieldsCode = [0, 1] createColumnsAttrb(prQual, fields, fieldsCode) writeDBF(posQual, ppQual, prQual, saveFile, inpname, "_QUALITY", idx) posStat = QgsVectorLayer("point?crs=EPSG:4326", "Status", "memory") prStat = posStat.dataProvider() fields = ["Link_ID", "Status/Setting"] fieldsCode = [0, 0] createColumnsAttrb(prStat, fields, fieldsCode) writeDBF(posStat, ppStat, prStat, saveFile, inpname, "_STATUS", idx) posEmit = QgsVectorLayer("point?crs=EPSG:4326", "Emitters", "memory") prEmit = posEmit.dataProvider() fields = ["Junc_ID", "Coeff."] fieldsCode = [0, 1] createColumnsAttrb(prEmit, fields, fieldsCode) writeDBF(posEmit, ppEmit, prEmit, saveFile, inpname, "_EMITTERS", idx) posCont = QgsVectorLayer("point?crs=EPSG:4326", "Controls", "memory") prCont = posCont.dataProvider() fields = ["Controls"] fieldsCode = [0] createColumnsAttrb(prCont, fields, fieldsCode) writeDBF(posCont, ppCont, prCont, saveFile, inpname, "_CONTROLS", idx) posPat = QgsVectorLayer("point?crs=EPSG:4326", "Patterns", "memory") prPat = posPat.dataProvider() fields = ["Pattern_ID", "Multipliers"] fieldsCode = [0, 0] createColumnsAttrb(prPat, fields, fieldsCode) writeDBF(posPat, ppPat, prPat, saveFile, inpname, "_PATTERNS", idx) posCurv = QgsVectorLayer("point?crs=EPSG:4326", "Curves", "memory") prCurv = posCurv.dataProvider() fields = ["Curve_ID", "X-Value", "Y-Value", "Type"] fieldsCode = [0, 0, 0, 0] createColumnsAttrb(prCurv, fields, fieldsCode) writeDBF(posCurv, ppCurv, prCurv, saveFile, inpname, "_CURVES", idx) # Write Valve Shapefile posValve = QgsVectorLayer("LineString?crs=EPSG:4326", "Valve", "memory") prValve = posValve.dataProvider() fields = ["ID", "NodeFrom", "NodeTo", "Diameter", "Type", "Setting", "MinorLoss"] fieldsCode = [0, 0, 0, 1, 0, 1, 1] createColumnsAttrb(prValve, fields, fieldsCode) posValve.startEditing() if d.getBinLinkValveCount() > 0: linkID = d.getBinLinkValveNameID() linkType = d.getBinLinkValveType() # valve type linkDiameter = d.getBinLinkValveDiameters() linkInitSett = d.getBinLinkValveSetting() # BinLinkValveSetting linkMinorloss = d.getBinLinkValveMinorLoss() for i, p in enumerate(d.getBinLinkValveIndex()): point1 = QgsPointXY(float(x[ndID.index(d.getBinLinkFromNode()[p])]), float(y[ndID.index(d.getBinLinkFromNode()[p])])) point2 = QgsPointXY(float(x[ndID.index(d.getBinLinkToNode()[p])]), float(y[ndID.index(d.getBinLinkToNode()[p])])) feature = QgsFeature() feature.setGeometry(QgsGeometry.fromPolylineXY([point1, point2])) feature.setAttributes( [linkID[i], ndlConn[0][p], ndlConn[1][p], linkDiameter[i], linkType[i], linkInitSett[i], linkMinorloss[i]]) prValve.addFeatures([feature]) QgsVectorFileWriter.writeAsVectorFormat(posValve, saveFile + "_valves" + '.shp', "utf-8", QgsCoordinateReferenceSystem(posValve.crs().authid()), "ESRI Shapefile") ll = QgsVectorLayer(saveFile + "_valves" + '.shp', inpname[:len(inpname) - 4] + "_valves", "ogr") QgsProject.instance().addMapLayer(ll, False) nvalves = QgsLayerTreeLayer(ll) idx.insertChildNode(0, nvalves) nvalves.setCustomProperty("showFeatureCount", True) ll.loadNamedStyle(plugin_path + "/qmls/" + 'valvesline' + ".qml") ll.triggerRepaint() # Write Pump Shapefile posPump = QgsVectorLayer("LineString?crs=EPSG:4326", "Pump", "memory") prPump = posPump.dataProvider() fields = ["ID", "NodeFrom", "NodeTo", "Power", "Pattern", "Curve"] fieldsCode = [0, 0, 0, 0, 0, 0] createColumnsAttrb(prPump, fields, fieldsCode) posPump.startEditing() if d.getBinLinkPumpCount() > 0: curveXY = d.getBinCurvesXY() curvesID = d.getBinCurvesNameID() a = curvesID b = [] for l in a: if l not in b: b.append(l) curvesIDunique = b CurvesTmpIndices = [] for p in range(0, len(curvesIDunique)): CurvesTmpIndices.append(curvesID.count(curvesIDunique[p])) curveIndices = [] Curve = d.getBinLinkPumpCurveNameID() for i in range(len(Curve)): curveIndices.append(curvesIDunique.index(Curve[i])) if d.getBinCurveCount(): CurvesTmpIndicesFinal = [] CurvesTmpIndicesFinal.append([CurvesTmpIndices[index] for index in curveIndices]) CurvesTmp = [] i = 0 for u in range(max(CurvesTmpIndicesFinal[0])): fields.append('Head' + str(u + 1)) fields.append('Flow' + str(u + 1)) fieldsCode.append(1) fieldsCode.append(1) if u < d.getBinCurveCount(): tmp1 = [] for p in range(CurvesTmpIndices[u]): tmp1.append([curveXY[i][0], curveXY[i][1]]) i = i + 1 CurvesTmp.append(tmp1) createColumnsAttrb(prPump, fields, fieldsCode) chPowerPump = d.getBinLinkPumpPower() pumpID = d.getBinLinkPumpNameID() patternsIDs = d.getBinLinkPumpPatterns() ppatt = d.getBinLinkPumpPatternsPumpID() linkID = d.getBinLinkNameID() for i, p in enumerate(d.getBinLinkPumpIndex()): Curve = [] power = [] pattern = [] pumpNameIDPower = d.getBinLinkPumpNameIDPower() if len(pumpNameIDPower) > 0: for uu in range(0, len(pumpNameIDPower)): if pumpNameIDPower[uu] == pumpID[i]: power = chPowerPump[uu] if len(patternsIDs) > 0: for uu in range(0, len(ppatt)): if ppatt[uu] == pumpID[i]: pattern = patternsIDs[uu] point1 = QgsPointXY(float(x[ndID.index(d.getBinLinkFromNode()[p])]), float(y[ndID.index(d.getBinLinkFromNode()[p])])) point2 = QgsPointXY(float(x[ndID.index(d.getBinLinkToNode()[p])]), float(y[ndID.index(d.getBinLinkToNode()[p])])) feature = QgsFeature() feature.setGeometry(QgsGeometry.fromPolylineXY([point1, point2])) if not Curve: Curve = 'NULL' if not power: power = 'NULL' if not pattern: pattern = 'NULL' if d.getBinCurveCount() > 0 and len(pumpNameIDPower) == 0: Curve = d.getBinLinkPumpCurveNameID()[i] curveIndex = curvesIDunique.index(Curve) feature.initAttributes(6 + sum(CurvesTmpIndices) * 2 + 1) feature.setAttribute(0, linkID[p]) feature.setAttribute(1, ndlConn[0][p]) feature.setAttribute(2, ndlConn[1][p]) feature.setAttribute(3, power) feature.setAttribute(4, pattern) feature.setAttribute(5, Curve) if d.getBinCurveCount() == 1: w = 6 for p in range(CurvesTmpIndices[curveIndex]): feature.setAttribute(w, CurvesTmp[curveIndex][p][0]) feature.setAttribute(w + 1, CurvesTmp[curveIndex][p][1]) w = w + 2 for j in range(d.getBinCurveCount() - 1): w = 6 for p in range(CurvesTmpIndices[curveIndex]): feature.setAttribute(w, CurvesTmp[curveIndex][p][0]) feature.setAttribute(w + 1, CurvesTmp[curveIndex][p][1]) w = w + 2 prPump.addFeatures([feature]) QgsVectorFileWriter.writeAsVectorFormat(posPump,saveFile+"_pumps"+'.shp', "utf-8", QgsCoordinateReferenceSystem(posPump.crs().authid()), "ESRI Shapefile") ll = QgsVectorLayer(saveFile + "_pumps" + '.shp', inpname[:len(inpname) - 4] + "_pumps", "ogr") QgsProject.instance().addMapLayer(ll, False) npump = QgsLayerTreeLayer(ll) idx.insertChildNode(0, npump) npump.setCustomProperty("showFeatureCount", True) ll.loadNamedStyle(plugin_path + "/qmls/" + 'pumpsline' + ".qml") ll.triggerRepaint() QgsVectorFileWriter.writeAsVectorFormat(posPipe,saveFile+"_pipes"+'.shp', "utf-8", QgsCoordinateReferenceSystem(posPipe.crs().authid()), "ESRI Shapefile") ll = QgsVectorLayer(saveFile + "_pipes" + '.shp', inpname[:len(inpname) - 4] + "_pipes", "ogr") QgsProject.instance().addMapLayer(ll, False) npipe = QgsLayerTreeLayer(ll) idx.insertChildNode(0, npipe) npipe.setCustomProperty("showFeatureCount", True) ll.loadNamedStyle(plugin_path + "/qmls/" + 'pipes' + ".qml") ll.triggerRepaint() iface.mapCanvas().setExtent(ll.extent()) QgsVectorFileWriter.writeAsVectorFormat(posJunction,saveFile+"_junctions"+'.shp', "utf-8", QgsCoordinateReferenceSystem(posJunction.crs().authid()), "ESRI Shapefile") ll = QgsVectorLayer(saveFile + "_junctions" + '.shp', inpname[:len(inpname) - 4] + "_junctions", "ogr") QgsProject.instance().addMapLayer(ll, False) njunc = QgsLayerTreeLayer(ll) idx.insertChildNode(0, njunc) njunc.setCustomProperty("showFeatureCount", True) ll.loadNamedStyle(plugin_path + "/qmls/" + 'junctions' + ".qml") ll.triggerRepaint() QgsVectorFileWriter.writeAsVectorFormat(posTank, saveFile + "_tanks" + '.shp', "utf-8", QgsCoordinateReferenceSystem(posTank.crs().authid()), "ESRI Shapefile") ll = QgsVectorLayer(saveFile + "_tanks" + '.shp', inpname[:len(inpname) - 4] + "_tanks", "ogr") QgsProject.instance().addMapLayer(ll, False) ntanks = QgsLayerTreeLayer(ll) idx.insertChildNode(0, ntanks) ntanks.setCustomProperty("showFeatureCount", True) ll.loadNamedStyle(plugin_path + "/qmls/" + 'tanks' + ".qml") ll.triggerRepaint() QgsVectorFileWriter.writeAsVectorFormat(posReservoirs, saveFile + "_reservoirs" + '.shp', "utf-8", QgsCoordinateReferenceSystem(posReservoirs.crs().authid()), "ESRI Shapefile") ll = QgsVectorLayer(saveFile + "_reservoirs" + '.shp', inpname[:len(inpname) - 4] + "_reservoirs", "ogr") QgsProject.instance().addMapLayer(ll, False) nres = QgsLayerTreeLayer(ll) idx.insertChildNode(0, nres) nres.setCustomProperty("showFeatureCount", True) ll.loadNamedStyle(plugin_path + "/qmls/" + 'reservoirs' + ".qml") ll.triggerRepaint()
def runAndCreateLayer(parent): geomDialog = QgsNewVectorLayerDialog(parent) if (geomDialog.exec_() == QDialog.Rejected): return "" geometrytype = geomDialog.selectedType() fileformat = geomDialog.selectedFileFormat() enc = geomDialog.selectedFileEncoding() crsId = geomDialog.selectedCrsId() print(QString("New file format will be: %1").arg(fileformat)) attributes = dict() geomDialog.attributes(attributes) settings = QSettings() lastUsedDir = settings.value("/UI/lastVectorFileFilterDir", QDir.homePath()).toString() filterString = QgsVectorFileWriter.filterForDriver(fileformat) fileName = QFileDialog.getSaveFileName(parent, "Save layer as...", lastUsedDir, filterString) if (fileName.isNull()): return "" if (fileformat == "ESRI Shapefile" and not fileName.endsWith(".shp", Qt.CaseInsensitive)): fileName += ".shp" settings.setValue("/UI/lastVectorFileFilterDir", QFileInfo(fileName).absolutePath()) settings.setValue("/UI/encoding", enc) #try to create the new layer with OGRProvider instead of QgsVectorFileWriter pReg = QgsProviderRegistry.instance() ogrlib = pReg.library("ogr") # load the data provider myLib = QLibrary(ogrlib) loaded = myLib.load() constructionLineLayer = None mapUnits = define._canvas.mapUnits() layerName = String.QString2Str(fileName).split("\\")[-1] path = "memory" selectedCrs = geomDialog.selectedCrs() if geometrytype == QGis.Line: # if mapUnits == QGis.Meters: constructionLineLayer = QgsVectorLayer( "linestring?crs=%s" % selectedCrs.authid(), layerName, path) # else: # constructionLineLayer = QgsVectorLayer("linestring?crs=%s"%define._latLonCrs.authid (), layerName, path) elif geometrytype == QGis.Polygon: # if mapUnits == QGis.Meters: constructionLineLayer = QgsVectorLayer( "polygon?crs=%s" % selectedCrs.authid(), layerName, path) # else: # constructionLineLayer = QgsVectorLayer("polygon?crs=%s"%define._latLonCrs.authid (), layerName, path) elif geometrytype == QGis.Point: # if mapUnits == QGis.Meters: constructionLineLayer = QgsVectorLayer( "Point?crs=%s" % selectedCrs.authid(), layerName, path) # else: # constructionLineLayer = QgsVectorLayer("Point?crs=%s"%define._latLonCrs.authid (), layerName, path) fieldList = [] for key in attributes.iterkeys(): fieldList.append(QgsField(key, attributes[key][0])) constructionLineLayer.startEditing() constructionLineLayer.dataProvider().addAttributes(fieldList) constructionLineLayer.commitChanges() er = QgsVectorFileWriter.writeAsVectorFormat( constructionLineLayer, fileName, "utf-8", constructionLineLayer.crs()) constructionLineLayer = QgsVectorLayer(fileName, layerName, "ogr") QgisHelper.appendToCanvas(define._canvas, [constructionLineLayer], "NewLayers") # if ( loaded ): # print( "ogr provider loaded" ) # # typedef bool ( *createEmptyDataSourceProc )( const QString&, const QString&, const QString&, QGis::WkbType, # const QList< QPair<QString, QString> >&, const QgsCoordinateReferenceSystem * ) # createEmptyDataSourceProc createEmptyDataSource = ( createEmptyDataSourceProc ) cast_to_fptr( myLib.resolve( "createEmptyDataSource" ) ) # if ( createEmptyDataSource ) # { # if ( geometrytype not = QGis::WKBUnknown ) # { # QgsCoordinateReferenceSystem srs = QgsCRSCache::instance().crsBySrsId( crsId ) # if ( not createEmptyDataSource( fileName, fileformat, enc, geometrytype, attributes, &srs ) ) # { # return QString::null # } # } # else # { # QgsDebugMsg( "geometry type not recognised" ) # return QString::null # } # } # else # { # QgsDebugMsg( "Resolving newEmptyDataSource(...) failed" ) # return QString::null # } # } # # if ( pEnc ) # *pEnc = enc return fileName
def testCreateFeature(self): """ test creating a feature respecting defaults and constraints """ layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer&field=flddbl:double", "addfeat", "memory") # add a bunch of features f = QgsFeature() f.setAttributes(["test", 123, 1.0]) f1 = QgsFeature(2) f1.setAttributes(["test_1", 124, 1.1]) f2 = QgsFeature(3) f2.setAttributes(["test_2", 125, 2.4]) f3 = QgsFeature(4) f3.setAttributes(["test_3", 126, 1.7]) f4 = QgsFeature(5) f4.setAttributes(["superpig", 127, 0.8]) self.assertTrue(layer.dataProvider().addFeatures([f, f1, f2, f3, f4])) # no layer self.assertFalse(QgsVectorLayerUtils.createFeature(None).isValid()) # basic tests f = QgsVectorLayerUtils.createFeature(layer) self.assertTrue(f.isValid()) self.assertEqual(f.fields(), layer.fields()) self.assertFalse(f.hasGeometry()) self.assertEqual(f.attributes(), [NULL, NULL, NULL]) # set geometry g = QgsGeometry.fromPointXY(QgsPointXY(100, 200)) f = QgsVectorLayerUtils.createFeature(layer, g) self.assertTrue(f.hasGeometry()) self.assertEqual(f.geometry().asWkt(), g.asWkt()) # using attribute map f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'a', 2: 6.0}) self.assertEqual(f.attributes(), ['a', NULL, 6.0]) # layer with default value expression layer.setDefaultValueDefinition(2, QgsDefaultValue('3*4')) f = QgsVectorLayerUtils.createFeature(layer) self.assertEqual(f.attributes(), [NULL, NULL, 12]) # we do not expect the default value expression to take precedence over the attribute map f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'a', 2: 6.0}) self.assertEqual(f.attributes(), ['a', NULL, 6.0]) # layer with default value expression based on geometry layer.setDefaultValueDefinition(2, QgsDefaultValue('3*$x')) f = QgsVectorLayerUtils.createFeature(layer, g) #adjusted so that input value and output feature are the same self.assertEqual(f.attributes(), [NULL, NULL, 300.0]) layer.setDefaultValueDefinition(2, QgsDefaultValue(None)) # test with violated unique constraints layer.setFieldConstraint(1, QgsFieldConstraints.ConstraintUnique) f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'test_1', 1: 123}) # since field 1 has Unique Constraint, it ignores value 123 that already has been set and sets to 128 self.assertEqual(f.attributes(), ['test_1', 128, NULL]) layer.setFieldConstraint(0, QgsFieldConstraints.ConstraintUnique) # since field 0 and 1 already have values test_1 and 123, the output must be a new unique value f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'test_1', 1: 123}) self.assertEqual(f.attributes(), ['test_4', 128, NULL]) # test with violated unique constraints and default value expression providing unique value layer.setDefaultValueDefinition(1, QgsDefaultValue('130')) f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'test_1', 1: 123}) # since field 1 has Unique Constraint, it ignores value 123 that already has been set and adds the default value self.assertEqual(f.attributes(), ['test_4', 130, NULL]) # fallback: test with violated unique constraints and default value expression providing already existing value # add the feature with the default value: self.assertTrue(layer.dataProvider().addFeatures([f])) f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'test_1', 1: 123}) # since field 1 has Unique Constraint, it ignores value 123 that already has been set and adds the default value # and since the default value providing an already existing value (130) it generates a unique value (next int: 131) self.assertEqual(f.attributes(), ['test_5', 131, NULL]) layer.setDefaultValueDefinition(1, QgsDefaultValue(None)) # test with manually correct unique constraint f = QgsVectorLayerUtils.createFeature(layer, attributes={0: 'test_1', 1: 132}) self.assertEqual(f.attributes(), ['test_5', 132, NULL]) """ test creating a feature respecting unique values of postgres provider """ layer = QgsVectorLayer("Point?field=fldtxt:string&field=fldint:integer&field=flddbl:double", "addfeat", "memory") # init connection string dbconn = 'dbname=\'qgis_test\'' if 'QGIS_PGTEST_DB' in os.environ: dbconn = os.environ['QGIS_PGTEST_DB'] # create a vector layer pg_layer = QgsVectorLayer('{} table="qgis_test"."authors" sql='.format(dbconn), "authors", "postgres") self.assertTrue(pg_layer.isValid()) # check the default clause default_clause = 'nextval(\'qgis_test.authors_pk_seq\'::regclass)' self.assertEqual(pg_layer.dataProvider().defaultValueClause(0), default_clause) # though default_clause is after the first create not unique (until save), it should fill up all the features with it pg_layer.startEditing() f = QgsVectorLayerUtils.createFeature(pg_layer) self.assertEqual(f.attributes(), [default_clause, NULL]) self.assertTrue(pg_layer.addFeatures([f])) self.assertTrue(QgsVectorLayerUtils.valueExists(pg_layer, 0, default_clause)) f = QgsVectorLayerUtils.createFeature(pg_layer) self.assertEqual(f.attributes(), [default_clause, NULL]) self.assertTrue(pg_layer.addFeatures([f])) f = QgsVectorLayerUtils.createFeature(pg_layer) self.assertEqual(f.attributes(), [default_clause, NULL]) self.assertTrue(pg_layer.addFeatures([f])) # if a unique value is passed, use it f = QgsVectorLayerUtils.createFeature(pg_layer, attributes={0: 40, 1: NULL}) self.assertEqual(f.attributes(), [40, NULL]) # and if a default value is configured use it as well pg_layer.setDefaultValueDefinition(0, QgsDefaultValue('11*4')) f = QgsVectorLayerUtils.createFeature(pg_layer) self.assertEqual(f.attributes(), [44, NULL]) pg_layer.rollBack()
def run(self): """Run method that performs all the real work""" # Create the dialog with elements (after translation) and keep reference # Only create GUI ONCE in callback, so that it will only load when the plugin is started if self.first_start == True: self.first_start = False self.dlg = HealthSIGDialog() # Clear the contents of the comboBox from previous runs self.dlg.comboBox.clear() # Populate the comboBox self.dlg.comboBox.addItems(["Hospitais", "ACES", "Farmácias"]) # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed and check index index = self.dlg.comboBox.currentIndex() # file directory for relative paths dirn = os.path.dirname(__file__) # escolheu unidades de saude if result and index == 1: # create layer vl = QgsVectorLayer("Point?crs=epsg:3763&index=yes", "aces", "memory") pr = vl.dataProvider() # Enter editing mode vl.startEditing() # add fields pr.addAttributes([ QgsField("ACES", QVariant.String), QgsField("ARS", QVariant.String), QgsField("Coord_X", QVariant.Double), QgsField("Coord_Y", QVariant.Double), QgsField("Num_USF", QVariant.Int) ]) vl.updateFields( ) # tell the vector layer to fetch changes from the provider # add features ---> IR BUSCAR AO JSON.... filename = os.path.join(dirn, 'unidades_saude.json') #with open("/home/skywalker/.local/share/QGIS/QGIS3/profiles/default/python/plugins/health_sig/unidades_saude.json", # "r") as read_file: with open(filename, "r") as read_file: json_file = json.load(read_file) # transformar coordenadas gps para as pretendidas crsSrc = QgsCoordinateReferenceSystem(4326) # gps crsDest = QgsCoordinateReferenceSystem(3763) # pt xform = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance()) # addfeatures for entry in json_file: if entry["fields"]["tempo"] == "2019-01": # valores recentes x_coord = float(entry["geometry"]["coordinates"][0]) y_coord = float(entry["geometry"]["coordinates"][1]) num_usf = int( entry["fields"] ["total_usf"]) #numero de unidades de saude familiares entidade = entry["fields"]["entidade"] ars = entry["fields"]["ars"] fet = QgsFeature() fet.setGeometry(QgsGeometry().buffer( distance=num_usf * 10, segments=100).fromPointXY( xform.transform(QgsPointXY(x_coord, y_coord)))) fet.setAttributes([ QVariant(entidade), QVariant(ars), QVariant(x_coord), QVariant(y_coord), QVariant(num_usf) ]) pr.addFeatures([fet]) vl.updateExtents() vl.commitChanges() # fazer render categorizado features = vl.getFeatures() categories = [] for feat in features: f = feat.attributes()[4] # num_usf entidade = feat.attributes()[0] # entidade symbol = QgsSymbol.defaultSymbol(vl.geometryType()) svgStyle = {} path_uni = os.path.join(dirn, 'medicine.svg') svgStyle['name'] = path_uni svgStyle['size'] = str((f / 10) + 1) symbol_layer = QgsSvgMarkerSymbolLayer.create(svgStyle) if symbol_layer is not None: symbol.changeSymbolLayer(0, symbol_layer) # create renderer object category = QgsRendererCategory(f, symbol, str(entidade)) # entry for the list of category items categories.append(category) # create renderer object renderer = QgsCategorizedSymbolRenderer('Num_USF', categories) # assign the created renderer to the layer if renderer is not None: vl.setRenderer(renderer) vl.triggerRepaint() QgsProject.instance().addMapLayer(vl) # hospitais elif result and index == 0: vl = QgsVectorLayer("Point?crs=epsg:3763&index=yes", "hospitais", "memory") pr = vl.dataProvider() # Enter editing mode vl.startEditing() # add fields pr.addAttributes([ QgsField("Hospital", QVariant.String), QgsField("Morada", QVariant.String), QgsField("Coord_X", QVariant.Double), QgsField("Coord_Y", QVariant.Double) ]) vl.updateFields( ) # tell the vector layer to fetch changes from the provider # add features ---> IR BUSCAR AO JSON.... filename = os.path.join(dirn, 'hospitais.json') with open(filename, "r") as read_file: json_file = json.load(read_file) # transformar coordenadas gps para as pretendidas crsSrc = QgsCoordinateReferenceSystem(4326) # gps crsDest = QgsCoordinateReferenceSystem(3763) # pt xform = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance()) # addfeatures for entry in json_file.keys(): x_coord = float(json_file[entry][1][1]) y_coord = float(json_file[entry][1][0]) morada = json_file[entry][0] fet = QgsFeature() fet.setGeometry(QgsGeometry().fromPointXY( xform.transform(QgsPointXY(x_coord, y_coord)))) fet.setAttributes([ QVariant(entry), QVariant(morada), QVariant(x_coord), QVariant(y_coord) ]) pr.addFeatures([fet]) vl.updateExtents() vl.commitChanges() #symbol = QgsMarkerSymbol.createSimple({'name': 'square', 'color': 'red'}) svgStyle = {} path_hosp = os.path.join(dirn, 'hospital.svg') svgStyle['name'] = path_hosp svgStyle['size'] = '6' symbol_layer = QgsSvgMarkerSymbolLayer.create(svgStyle) symbol = QgsSymbol.defaultSymbol(vl.geometryType()) #vl.renderer().setSymbol(symbol) symbol.changeSymbolLayer(0, symbol_layer) vl.renderer().setSymbol(symbol) # show the change vl.triggerRepaint() QgsProject.instance().addMapLayer(vl) # farmacias elif result and index == 2: vl = QgsVectorLayer("Point?crs=epsg:3763&index=yes", "farmacias", "memory") pr = vl.dataProvider() # Enter editing mode vl.startEditing() # add fields pr.addAttributes([ QgsField("Farmácia", QVariant.String), QgsField("Morada", QVariant.String), QgsField("Coord_X", QVariant.Double), QgsField("Coord_Y", QVariant.Double) ]) vl.updateFields( ) # tell the vector layer to fetch changes from the provider # add features ---> IR BUSCAR AO JSON.... filename = os.path.join(dirn, 'farmacias.json') with open(filename, "r") as read_file: json_file = json.load(read_file) # transformar coordenadas gps para as pretendidas crsSrc = QgsCoordinateReferenceSystem(4326) # gps crsDest = QgsCoordinateReferenceSystem(3763) # pt xform = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance()) # addfeatures for entry in json_file.keys(): x_coord = float(json_file[entry][1][1]) y_coord = float(json_file[entry][1][0]) morada = json_file[entry][0] fet = QgsFeature() fet.setGeometry(QgsGeometry().fromPointXY( xform.transform(QgsPointXY(x_coord, y_coord)))) fet.setAttributes([ QVariant(entry), QVariant(morada), QVariant(x_coord), QVariant(y_coord) ]) pr.addFeatures([fet]) vl.updateExtents() vl.commitChanges() #symbol = QgsMarkerSymbol.createSimple({'name': 'square', 'color': 'purplet'}) #vl.renderer().setSymbol(symbol) svgStyle = {} path_farm = os.path.join(dirn, 'pharmacy.svg') svgStyle['name'] = path_farm svgStyle['size'] = '4' symbol_layer = QgsSvgMarkerSymbolLayer.create(svgStyle) symbol = QgsSymbol.defaultSymbol(vl.geometryType()) # vl.renderer().setSymbol(symbol) symbol.changeSymbolLayer(0, symbol_layer) vl.renderer().setSymbol(symbol) # show the change vl.triggerRepaint() QgsProject.instance().addMapLayer(vl)
def test_insert_srsName(self): """Test srsName is respected when insering""" post_data = """ <Transaction xmlns="http://www.opengis.net/wfs" xsi:schemaLocation="http://www.qgis.org/gml http://localhost:8000/?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=1.0.0&TYPENAME=as_symbols" service="WFS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="{version}" xmlns:gml="http://www.opengis.net/gml"> <Insert xmlns="http://www.opengis.net/wfs"> <as_symbols xmlns="http://www.qgis.org/gml"> <name xmlns="http://www.qgis.org/gml">{name}</name> <geometry xmlns="http://www.qgis.org/gml"> <gml:Point srsName="{srsName}"> <gml:coordinates cs="," ts=" ">{coordinates}</gml:coordinates> </gml:Point> </geometry> </as_symbols> </Insert> </Transaction> """ project = self.testdata_path + \ "test_project_wms_grouped_layers.qgs" assert os.path.exists(project), "Project file not found: " + project query_string = '?SERVICE=WFS&MAP={}'.format( urllib.parse.quote(project)) request = post_data.format(name='4326-test1', version='1.1.0', srsName='EPSG:4326', coordinates='10.67,52.48') header, body = self._execute_request( query_string, requestMethod=QgsServerRequest.PostMethod, data=request.encode('utf-8')) # Verify vl = QgsVectorLayer( self.testdata_path + 'test_project_wms_grouped_layers.gpkg|layername=as_symbols', 'as_symbols') self.assertTrue(vl.isValid()) feature = next( vl.getFeatures( QgsFeatureRequest(QgsExpression('"name" = \'4326-test1\'')))) geom = feature.geometry() tr = QgsCoordinateTransform( QgsCoordinateReferenceSystem.fromEpsgId(4326), vl.crs(), QgsCoordinateTransformContext()) geom_4326 = QgsGeometry.fromWkt('point( 10.67 52.48)') geom_4326.transform(tr) self.assertEqual(geom.asWkt(0), geom_4326.asWkt(0)) # Now: insert a feature in layer's CRS request = post_data.format(name='25832-test1', version='1.1.0', srsName='EPSG:25832', coordinates='613412,5815738') header, body = self._execute_request( query_string, requestMethod=QgsServerRequest.PostMethod, data=request.encode('utf-8')) feature = next( vl.getFeatures( QgsFeatureRequest(QgsExpression('"name" = \'25832-test1\'')))) geom = feature.geometry() self.assertEqual(geom.asWkt(0), geom_4326.asWkt(0)) # Tests for inverted axis issue GH #36584 # Cleanup self.assertTrue(vl.startEditing()) vl.selectByExpression('"name" LIKE \'4326-test%\'') vl.deleteSelectedFeatures() self.assertTrue(vl.commitChanges()) self.i = 0 def _test(version, srsName, lat_lon=False): self.i += 1 name = '4326-test_%s' % self.i request = post_data.format( name=name, version=version, srsName=srsName, coordinates='52.48,10.67' if lat_lon else '10.67,52.48') header, body = self._execute_request( query_string, requestMethod=QgsServerRequest.PostMethod, data=request.encode('utf-8')) feature = next( vl.getFeatures( QgsFeatureRequest(QgsExpression('"name" = \'%s\'' % name)))) geom = feature.geometry() self.assertEqual( geom.asWkt(0), geom_4326.asWkt(0), "Transaction Failed: %s , %s, lat_lon=%s" % (version, srsName, lat_lon)) _test('1.1.0', 'urn:ogc:def:crs:EPSG::4326', lat_lon=True) _test('1.1.0', 'http://www.opengis.net/def/crs/EPSG/0/4326', lat_lon=True) _test('1.1.0', 'http://www.opengis.net/gml/srs/epsg.xml#4326', lat_lon=False) _test('1.1.0', 'EPSG:4326', lat_lon=False) _test('1.0.0', 'urn:ogc:def:crs:EPSG::4326', lat_lon=True) _test('1.0.0', 'http://www.opengis.net/def/crs/EPSG/0/4326', lat_lon=True) _test('1.0.0', 'http://www.opengis.net/gml/srs/epsg.xml#4326', lat_lon=False) _test('1.0.0', 'EPSG:4326', lat_lon=False) def _test_getFeature(version, srsName, lat_lon=False): # Now get the feature through WFS using BBOX filter bbox = QgsGeometry.fromWkt('point( 10.7006 52.4317)').boundingBox() bbox.grow(0.0001) bbox_text = "%s,%s,%s,%s" % ( (bbox.yMinimum(), bbox.xMinimum(), bbox.yMaximum(), bbox.xMaximum()) if lat_lon else (bbox.xMinimum(), bbox.yMinimum(), bbox.xMaximum(), bbox.yMaximum())) req = query_string + '&REQUEST=GetFeature&VERSION={version}&TYPENAME=as_symbols&SRSNAME={srsName}&BBOX={bbox},{srsName}'.format( version=version, srsName=srsName, bbox=bbox_text) header, body = self._execute_request(req) self.assertTrue( b'gid>7' in body, "GetFeature Failed: %s , %s, lat_lon=%s" % (version, srsName, lat_lon)) _test_getFeature('1.1.0', 'urn:ogc:def:crs:EPSG::4326', lat_lon=True) _test_getFeature('1.1.0', 'EPSG:4326', lat_lon=False) _test_getFeature('1.0.0', 'urn:ogc:def:crs:EPSG::4326', lat_lon=True) _test_getFeature('1.0.0', 'EPSG:4326', lat_lon=False) # Cleanup self.assertTrue(vl.startEditing()) vl.selectByExpression('"name" LIKE \'4326-test%\'') vl.deleteSelectedFeatures() self.assertTrue(vl.commitChanges())
def ReadAndMergeVectorLayers(vectorLayers): # pylint: disable=too-many-locals # pylint: disable=too-many-branches # pylint: disable=too-many-statements category = "" feats = [] for i in vectorLayers: if shared.vectorFileType[i] == "ogr": thisLayer = QgsVectorLayer(shared.vectorFileName[i], shared.vectorFileTitle[i], "ogr") elif shared.vectorFileType[i] == "spatialite": uri = QgsDataSourceUri() uri.setDatabase(shared.vectorFileName[i]) schema = '' geom_column = 'Geometry' uri.setDataSource(schema, shared.vectorFileTable[i], geom_column) thisLayer = QgsVectorLayer(uri.uri(), shared.vectorFileTitle[i], shared.vectorFileType[i]) elif shared.vectorFileType[i] == "xyz": uri = shared.vectorFileName[ i] + "?type=csv&useHeader=No&xField=field_1&yField=field_2&spatialIndex=no&subsetIndex=no&watchFile=no" thisLayer = QgsVectorLayer(uri, shared.vectorFileTitle[i], "delimitedtext") else: shared.fpOut.write("Cannot load vector file of type '" + shared.vectorFileType[i] + "'") return -1, -1 if not thisLayer.isValid(): shared.fpOut.write("Vector layer '" + shared.vectorFileTitle[i] + "' failed to load") return -1, -1 shared.fpOut.write("Vector layer '" + shared.vectorFileTitle[i] + "' loaded\n") # Copy the features from this layer that are within the displayed extent, to a new list extentRectWithBorder = QgsRectangle() borderSize = 100 extentRectWithBorder.setXMinimum(shared.extentRect.xMinimum() - borderSize) extentRectWithBorder.setYMinimum(shared.extentRect.yMinimum() - borderSize) extentRectWithBorder.setXMaximum(shared.extentRect.xMaximum() + borderSize) extentRectWithBorder.setYMaximum(shared.extentRect.yMaximum() + borderSize) request = QgsFeatureRequest(extentRectWithBorder) features = thisLayer.getFeatures(request) #features = thisLayer.getFeatures() print("Copying features from vector layer '" + shared.vectorFileTitle[i] + "'") feats += features #print("N features =", len(feats)) #for feat in features: #newFeature = QgsFeature() #newFeature.setGeometry(feat.geometry()) #fields = feat.fields() #newFeature.setFields(fields) #attrs = feat.attributes() #newFeature.setAttributes(attrs) #feats.append(newFeature) ##print(feat) ##feats.append(feat) flds = thisLayer.fields() #print(shared.vectorFileTitle[i] + " FIELD NAMES " + str(flds.names())) #print(shared.vectorFileTitle[i] + " number of attribute fields = " + str(len(flds.names()))) category = shared.vectorFileCategory[i] # Get the Coordinate Reference System and the list of fields from the last input file thisLayerCRS = thisLayer.crs().toWkt() thisLayerFieldList = thisLayer.dataProvider().fields().toList() # Create the merged layer by checking the geometry type of the input files layerGeom = thisLayer.geometryType() layerWkb = thisLayer.wkbType() isMulti = QgsWkbTypes.isMultiType(layerWkb) if layerGeom == QgsWkbTypes.PointGeometry: if isMulti: mergedLayer = QgsVectorLayer('MultiPoint?crs=' + thisLayerCRS, 'merged', "memory") else: mergedLayer = QgsVectorLayer('Point?crs=' + thisLayerCRS, 'merged', "memory") elif layerGeom == QgsWkbTypes.LineGeometry: if isMulti: mergedLayer = QgsVectorLayer('MultiLineString?crs=' + thisLayerCRS, 'merged', "memory") else: mergedLayer = QgsVectorLayer('LineString?crs=' + thisLayerCRS, 'merged', "memory") elif layerGeom == QgsWkbTypes.PolygonGeometry: if isMulti: mergedLayer = QgsVectorLayer('MultiPolygon?crs=' + thisLayerCRS, 'merged', "memory") else: mergedLayer = QgsVectorLayer('Polygon?crs=' + thisLayerCRS, 'merged', "memory") else: geomTypeString = QgsWkbTypes.displayString(int(layerWkb)) errStr = "ERROR: layer type " + geomTypeString + " could not be merged" print(errStr) shared.fpOut.write(errStr + "\n") return -1, -1 # Is the new (but still empty) merged layer OK? if not mergedLayer.isValid(): titleStr = "" for i in vectorLayers: titleStr += shared.vectorFileTitle[i] if i < len(vectorLayers): titleStr += "' '" errStr = "ERROR: could not create new vector layer for merge of '" + titleStr + "'" print(errStr) shared.fpOut.write(errStr + "\n") return -1, -1 # Sort the list of features by identifier feats.sort(key=lambda feat: feat.attributes()[1]) #for i in range(10): #print("BEFORE MERGE " + str(feats[i].attributes())) #print("=================") ##BODGE This is needed because QGIS 3 handles Boolean layers incorrectly #print("*********************") #print("*** ORIGINAL: " + str(thisLayerFieldList)) #for fld in thisLayerFieldList: #print(fld.type()) #print("*********************") #for fld in thisLayerFieldList: #fldName = fld.typeName() #if fldName == "Boolean": #fld.setTypeName("Integer64") #fld.setType(4) #print("**** CHANGED : " + str(thisLayerFieldList)) #for fld in thisLayerFieldList: #print(fld.type()) #print("*********************") # Add the field attributes to the merged layer provider = mergedLayer.dataProvider() #print("PROVIDER: " + str(provider)) #print("PROVIDER Number of attribute fields = " + str(len(thisLayerFieldList))) if not provider.addAttributes(thisLayerFieldList): errStr = "ERROR: could not add attributes to merged layer" print(errStr) shared.fpOut.write(errStr + "\n") return -1, -1 mergedLayer.updateFields() flds = mergedLayer.fields() #print("MERGED FIELD NAMES " + str(flds.names())) #print("MERGED number of attribute fields = " + str(len(flds.names()))) if not mergedLayer.startEditing(): errStr = "ERROR: could not edit merged layer" print(errStr) shared.fpOut.write(errStr + "\n") return -1, -1 if not mergedLayer.addFeatures(feats): errStr = "ERROR: could not add features to merged layer" print(errStr) shared.fpOut.write(errStr + "\n") return -1, -1 #testFeats = mergedLayer.getFeatures() #print("BEFORE testFeats = " + str(testFeats)) #nMergedFeat = 0 #for feat in features: #nMergedFeat += 1 #print("BEFORE N features in testFeats =", nMergedFeat) mergedLayer.commitChanges() #testFeats = mergedLayer.getFeatures() #print("AFTER testFeats = " + str(testFeats)) #nMergedFeat = 0 #for feat in features: #nMergedFeat += 1 #print("AFTER N features in testFeats =", nMergedFeat) #features = mergedLayer.getFeatures() #for feat in features: #shared.fpOut.write(str(feat.attributes())) #for field in mergedLayer.fields().toList(): #shared.fpOut.write(str(field.name())) # Sort out style i = vectorLayers[-1] if not shared.vectorFileStyle[i]: shared.vectorFileStyle[i] = mergedLayer.styleURI() #shared.fpOut.write(shared.vectorFileStyle[i]) if not mergedLayer.loadDefaultStyle(): errStr = "ERROR: could not load default style '" + shared.vectorFileStyle[ i] + "' for vector layer '" + shared.vectorFileTitle[i] + "'" print(errStr) shared.fpOut.write(errStr + "\n") else: if not mergedLayer.loadNamedStyle(shared.vectorFileStyle[i]): errStr = "ERROR: could not load style '" + shared.vectorFileStyle[ i] + "' for vector layer '" + shared.vectorFileTitle[i] + "'" print(errStr) shared.fpOut.write(errStr + "\n") # Set transparency mergedLayer.setOpacity(shared.vectorFileOpacity[i]) # Add this layer to the app's registry QgsProject.instance().addMapLayer(mergedLayer) mergedNames = "" for i in vectorLayers: mergedNames += "'" mergedNames += shared.vectorFileTitle[i] mergedNames += "' " shared.fpOut.write("\tMerged layers " + mergedNames + "\n") print("Merged layers " + mergedNames) return mergedLayer, category
class AddField: def __init__(self, parent_widget): """This class handle the creation of Fields. This class is also imported in the MeanAnalyse class. Parameters ---------- parent_widget: GeoDataFarm """ self.iface = parent_widget.iface self.tsk_mngr = parent_widget.tsk_mngr self.db = parent_widget.db translate = TR('AddField') self.tr = translate.tr self.dock_widget = parent_widget.dock_widget self.parent = parent_widget self.AFD = AddFieldFileDialog() self.field = None self.defined_field = '' def run(self): """Presents the sub widget AddField and connects the different buttons to their function""" self.AFD.show() self.AFD.PBSelectExtent.clicked.connect(self.clicked_define_field) self.AFD.PBSave.clicked.connect(self.save) self.AFD.PBHelp.clicked.connect(self.help) self.AFD.PBQuit.clicked.connect(self.quit) self.AFD.exec() self.parent.populate.reload_fields() def set_widget_connections(self): """Function that sets the main widget connections.""" self.parent.dock_widget.PBAddField.clicked.connect(self.run) self.parent.dock_widget.PBRemoveField.clicked.connect( self.remove_field) self.parent.dock_widget.PBViewFields.clicked.connect(self.view_fields) def clicked_define_field(self, ignore_name=True): """Creates an empty polygon that's define a field""" if ignore_name: self.field = QgsVectorLayer("Polygon?crs=epsg:4326", 'Search area', "memory") else: name = self.AFD.LEFieldName.text() if len(name) == 0: QMessageBox.information( None, self.tr('Error:'), self.tr('Field name must be filled in.')) return self.field = QgsVectorLayer("Polygon?crs=epsg:4326", name, "memory") add_background() set_zoom(self.parent.iface, 2) self.field.startEditing() self.iface.actionAddFeature().trigger() QgsProject.instance().addMapLayer(self.field) def remove_field(self): """Removes a field that the user wants, a check that there are no data that is depended on is made.""" j = -1 for i in range(self.parent.dock_widget.LWFields.count()): j += 1 item = self.parent.dock_widget.LWFields.item(j) if item.checkState() == 2: field_name = item.text() qm = QMessageBox() res = qm.question( None, self.tr('Question'), self.tr("Do you want to delete ") + str(field_name), qm.Yes, qm.No) if res == qm.No: continue field_names = [] for tble_type in [ 'plant', 'ferti', 'spray', 'harvest', 'soil' ]: field_names.extend( self.db.execute_and_return( "select field from {type}.manual".format( type=tble_type))) sql = """SELECT table_name FROM information_schema.tables WHERE table_schema = 'other'""" for tble_type in self.db.execute_and_return(sql): tbl = tble_type[0] field_names.extend( self.db.execute_and_return( "select field from other.{tbl}".format(tbl=tbl))) stop_removing = False for row in field_names: if row[0] == field_name: QMessageBox.information( None, self.tr('Error'), self. tr('There are data sets that are dependent on this field, ' 'it cant be removed.')) stop_removing = True if stop_removing: continue sql = "delete from fields where field_name='{f}'".format( f=field_name) self.db.execute_sql(sql) self.parent.dock_widget.LWFields.takeItem(j) j -= 1 def view_fields(self): """Add all fields that aren't displayed on the canvas, if no background map is loaded Google maps are loaded.""" defined_field = self.defined_field if defined_field == '': add_background() sources = [ layer.name().split('_')[0] for layer in QgsProject.instance().mapLayers().values() ] fields_db = self.db.execute_and_return("select field_name from fields") task = QgsTask.fromFunction('Adding fields to the canvas', add_fields_2_canvas, self.db, fields_db, defined_field, sources, on_finished=self.finish) self.tsk_mngr.addTask(task) def finish(self, result, values): """Produces either an error message telling what went wrong or adds the fields to canvas and zoom to the layers. Parameters ---------- result: object values: list If all went ok: [True, list of layers] Else: [False, exception, traceback] """ if values[0] is False: QMessageBox.information( None, self.tr('Error'), self.tr( 'Following error occurred: {m}\n\n Traceback: {t}'.format( m=values[1], t=values[2]))) return for layer in values[-1]: QgsProject.instance().addMapLayer(layer) if self.defined_field == '': set_zoom(self.parent.iface, 1.1) self.defined_field = '' def quit(self): """Closes the widget.""" self.AFD.PBSelectExtent.clicked.disconnect() self.AFD.PBSave.clicked.disconnect() self.AFD.PBHelp.clicked.disconnect() self.AFD.PBQuit.clicked.disconnect() self.AFD.done(0) def save(self): """Saves the field in the database""" try: self.iface.actionSaveActiveLayerEdits().trigger() self.iface.actionToggleEditing().trigger() feature = self.field.getFeature(1) QgsProject.instance().removeMapLayers([self.field.id()]) except: QMessageBox.information( None, self.tr("Error:"), self. tr('No coordinates were found, did you mark the field on the canvas?' )) return polygon = feature.geometry().asWkt() name = self.AFD.LEFieldName.text() if len(name) == 0: QMessageBox.information(None, self.tr('Error:'), self.tr('Field name must be filled in.')) return sql = """Insert into fields (field_name, polygon) VALUES ('{name}', st_geomfromtext('{poly}', 4326))""".format( name=name, poly=polygon) try: self.db.execute_sql(sql) except IntegrityError: QMessageBox.information( None, self.tr('Error:'), self.tr('Field name already exist, please select a new name')) return except InternalError as e: QMessageBox.information(None, self.tr('Error:'), str(e)) return _name = QApplication.translate("qadashboard", name, None) item = QListWidgetItem(_name, self.dock_widget.LWFields) item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable) item.setCheckState(QtCore.Qt.Unchecked) self.defined_field = name self.view_fields() def help(self): """A function that gives some advice on how the function works for the user. """ QMessageBox.information( None, self.tr("Help:"), self. tr('Here is where you add a field.\n' '1. Start with giving the field a name.\n' '2. Press "select extent" and switch to the QGIS window and zoom to your field.\n' '3. To mark your field, left click with the mouse in one corner of the field.\n' 'then left click in all corners of the field then right click anywhere on the map.\n' '(There might be some errors while clicking the corners if the lines are crossing each other but in the end this does not matter if they does not do it in the end)\n' '4. Press "Save field" to store the field.\n' '5. When all fields are added press "Finished"')) return
class GpxFeatureBuilder: """ Builds gpx layers and features """ def __init__(self, layer_name, attribute_definitions, attribute_select='Last', crs=None): self.error_message = '' layer_definition = 'LineString' if crs is not None: layer_definition = layer_definition + "?crs=epsg:" + str(crs.postgisSrid()) self.vector_layer = QgsVectorLayer(layer_definition, layer_name, "memory") self.data_provider = self.vector_layer.dataProvider() # Enter editing mode self.vector_layer.startEditing() attributes = list() for attribute in attribute_definitions: if attribute.selected: # select attribute [boolean] for attribute_select_option in ['First', 'Last']: if attribute_select_option != attribute_select and attribute_select != 'Both': continue key = str(attribute.attribute_key_modified) if attribute_select == 'Both' and attribute.attribute_key_modified != '_distance' \ and attribute.attribute_key_modified != '_duration' \ and attribute.attribute_key_modified != '_speed': if attribute_select_option == 'First': key = 'a_' + key elif attribute_select_option == 'Last': key = 'b_' + key if attribute.datatype == DataTypes.Integer: # data type [Integer|Double|String] attributes.append(QgsField(key, QVariant.Int, 'Integer')) elif attribute.datatype == DataTypes.Double: attributes.append(QgsField(key, QVariant.Double, 'Real')) elif attribute.datatype == DataTypes.Boolean: # QVariant.Bool is not available for QgsField # attributes.append(QgsField(key, QVariant.Bool, 'Boolean')) attributes.append(QgsField(key, QVariant.String, 'String')) # elif attribute.datatype == DataTypes.Date: # attributes.append(QgsField(key, QVariant.DateTime, 'String')) elif attribute.datatype == DataTypes.String: attributes.append(QgsField(key, QVariant.String, 'String')) self.data_provider.addAttributes(attributes) self.vector_layer.updateFields() def add_feature(self, line_coordinates, attributes): feature = QgsFeature() feature.setGeometry(QgsGeometry.fromPolylineXY(line_coordinates)) feature.setFields(self.vector_layer.fields(), True) for attribute_key in list(attributes.keys()): try: feature.setAttribute(attribute_key, attributes[attribute_key]) except KeyError: pass self.data_provider.addFeatures([feature]) def save_layer(self, output_directory, overwrite): self.vector_layer.commitChanges() self.error_message = '' if self.vector_layer.featureCount() > 0: self.vector_layer.updateExtents() # Write vector layer to file if output_directory is not None: if os.path.isdir(output_directory): vector_layer_writer = VectorFileWriter(output_directory) output_file_path = vector_layer_writer.write(self.vector_layer, overwrite) if output_file_path is not None: return QgsVectorLayer(output_file_path, os.path.basename(output_file_path), 'ogr') else: self.error_message = 'Writing vector layer failed...' return None else: self.error_message = 'Cannot find output directory' return None return self.vector_layer
def draw(self): rb = self.tool.rb g = rb.asGeometry() ok = True warning = False errBuffer_noAtt = False errBuffer_Vertices = False layer = self.iface.layerTreeView().currentLayer() if self.toolname == 'drawBuffer': if self.bGeom is None: warning = True errBuffer_noAtt = True else: perim, ok = QInputDialog.getDouble( self.iface.mainWindow(), self.tr('Perimeter'), self.tr('Give a perimeter in m:') + '\n' + self.tr('(works only with metric crs)'), min=0) g = self.bGeom.buffer(perim, 40) rb.setToGeometry( g, QgsVectorLayer("Polygon?crs=" + layer.crs().authid(), "", "memory")) if g.length() == 0 and ok: warning = True errBuffer_Vertices = True if self.toolname == 'drawCopies': if g.length() < 0: warning = True errBuffer_noAtt = True if ok and not warning: name = '' ok = True add = False index = 0 layers = [] while not name.strip() and not add and ok: dlg = QDrawLayerDialog(self.iface, self.drawShape) name, add, index, layers, ok = dlg.getName( self.iface, self.drawShape) if ok and not warning: layer = None if add: layer = layers[index] if self.drawShape in ['point', 'XYpoint']: g = g.centroid() else: if self.drawShape == 'point': layer = QgsVectorLayer( "Point?crs=" + self.iface.mapCanvas().mapSettings( ).destinationCrs().authid() + "&field=" + self.tr('Drawings') + ":string(255)", name, "memory") g = g.centroid() # force geometry as point elif self.drawShape == 'XYpoint': layer = QgsVectorLayer( "Point?crs=" + self.XYcrs.authid() + "&field=" + self.tr('Drawings') + ":string(255)", name, "memory") g = g.centroid() elif self.drawShape == 'line': layer = QgsVectorLayer( "LineString?crs=" + self.iface.mapCanvas().mapSettings( ).destinationCrs().authid() + "&field=" + self.tr('Drawings') + ":string(255)", name, "memory") # fix_print_with_import print("LineString?crs=" + self.iface.mapCanvas( ).mapSettings().destinationCrs().authid() + "&field=" + self.tr('Drawings') + ":string(255)") else: layer = QgsVectorLayer( "Polygon?crs=" + self.iface.mapCanvas().mapSettings( ).destinationCrs().authid() + "&field=" + self.tr('Drawings') + ":string(255)", name, "memory") layer.startEditing() symbols = layer.renderer().symbols( QgsRenderContext()) # todo which context ? symbols[0].setColor(self.settings.getColor()) feature = QgsFeature() feature.setGeometry(g) feature.setAttributes([name]) layer.dataProvider().addFeatures([feature]) layer.commitChanges() if not add: pjt = QgsProject.instance() pjt.addMapLayer(layer, False) if pjt.layerTreeRoot().findGroup(self.tr('Drawings')) is None: pjt.layerTreeRoot().insertChildNode( 0, QgsLayerTreeGroup(self.tr('Drawings'))) group = pjt.layerTreeRoot().findGroup(self.tr('Drawings')) group.insertLayer(0, layer) self.iface.layerTreeView().refreshLayerSymbology(layer.id()) self.iface.mapCanvas().refresh() else: if warning: if errBuffer_noAtt: self.iface.messageBar().pushWarning( self.tr('Warning'), self.tr('You didn\'t click on a layer\'s attribute !')) elif errBuffer_Vertices: self.iface.messageBar().pushWarning( self.tr('Warning'), self.tr('You must give a non-null value for a \ point\'s or line\'s perimeter !')) else: self.iface.messageBar().pushWarning( self.tr('Warning'), self.tr('There is no selected layer, or it is not \ vector nor visible !')) self.tool.reset() self.resetSB() self.bGeom = None