Ejemplo n.º 1
0
    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())
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    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
Ejemplo n.º 5
0
    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
Ejemplo n.º 7
0
    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)
Ejemplo n.º 8
0
 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
Ejemplo n.º 9
0
    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()
Ejemplo n.º 10
0
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
Ejemplo n.º 11
0
    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))')
Ejemplo n.º 12
0
 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()
Ejemplo n.º 13
0
    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'])
Ejemplo n.º 14
0
    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()
Ejemplo n.º 15
0
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
Ejemplo n.º 16
0
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
Ejemplo n.º 17
0
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())
Ejemplo n.º 20
0
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
Ejemplo n.º 21
0
    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)
Ejemplo n.º 22
0
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
Ejemplo n.º 23
0
 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")
Ejemplo n.º 24
0
 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)
Ejemplo n.º 25
0
    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)
Ejemplo n.º 26
0
    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))
Ejemplo n.º 28
0
 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")
Ejemplo n.º 29
0
 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
Ejemplo n.º 31
0
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)
Ejemplo n.º 32
0
    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()
Ejemplo n.º 33
0
    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')
Ejemplo n.º 34
0
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_()
Ejemplo n.º 35
0
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
Ejemplo n.º 36
0
    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")
Ejemplo n.º 37
0
    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()
Ejemplo n.º 38
0
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))
Ejemplo n.º 39
0
    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()))
Ejemplo n.º 40
0
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
Ejemplo n.º 41
0
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([])
Ejemplo n.º 42
0
    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)
Ejemplo n.º 43
0
    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()
Ejemplo n.º 44
0
    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)
Ejemplo n.º 45
0
    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.')
Ejemplo n.º 46
0
    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")
Ejemplo n.º 47
0

# 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)
Ejemplo n.º 49
0
    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)
Ejemplo n.º 51
0
    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()
Ejemplo n.º 52
0
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()
Ejemplo n.º 55
0
    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)
Ejemplo n.º 56
0
    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&amp;REQUEST=DescribeFeatureType&amp;VERSION=1.0.0&amp;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())
Ejemplo n.º 57
0
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
Ejemplo n.º 58
0
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
Ejemplo n.º 60
0
    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