Пример #1
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()
Пример #2
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)
Пример #3
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
Пример #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
Пример #5
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()
Пример #6
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())
Пример #7
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)
Пример #8
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
    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
Пример #10
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
Пример #11
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
Пример #12
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
    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)
Пример #14
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
Пример #15
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)
Пример #16
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
Пример #17
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")
Пример #18
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
Пример #19
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)
Пример #20
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")
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
Пример #22
0
 def copySelected(self, layer, mem_layer, geom_type):
     ''' Copy from selected layer to memory layer 
     '''
     self.manageMemLayers()
     
     # Create memory layer if not already set
     if mem_layer is None: 
         uri = geom_type+"?crs=epsg:25831" 
         mem_layer = QgsVectorLayer(uri, "selected_"+layer.name(), "memory")                     
      
         # Copy attributes from main layer to memory layer
         attrib_names = layer.dataProvider().fields()
         names_list = attrib_names.toList()
         newattributeList = []
         for attrib in names_list:
             aux = mem_layer.fieldNameIndex(attrib.name())
             if aux == -1:
                 newattributeList.append(QgsField(attrib.name(), attrib.type()))
         mem_layer.dataProvider().addAttributes(newattributeList)
         mem_layer.updateFields()
         
         # Insert layer in the top of the TOC           
         root = QgsProject.instance().layerTreeRoot()           
         QgsMapLayerRegistry.instance().addMapLayer(mem_layer, False)
         node_layer = QgsLayerTreeLayer(mem_layer)
         root.insertChildNode(0, node_layer)                 
  
     # Prepare memory layer for editing
     mem_layer.startEditing()
     
     # Iterate over selected features   
     cfeatures = []
     for sel_feature in layer.selectedFeatures():
         attributes = []
         attributes.extend(sel_feature.attributes())
         cfeature = QgsFeature()    
         cfeature.setGeometry(sel_feature.geometry())
         cfeature.setAttributes(attributes)
         cfeatures.append(cfeature)
                  
     # Add features, commit changes and refresh canvas
     mem_layer.dataProvider().addFeatures(cfeatures)             
     mem_layer.commitChanges()
     self.iface.mapCanvas().refresh() 
     self.iface.mapCanvas().zoomToSelected(layer)
     
     # Make sure layer is always visible 
     self.iface.legendInterface().setLayerVisible(mem_layer, True)
                 
     return mem_layer
Пример #23
0
    def __snap(self):

        self.report_message.emit(self.layer_id, 'preparing ...')
        orig_layer = QgsMapLayerRegistry.instance().mapLayer(self.layer_id)
        # create a copy of the layer just for editing
        layer = QgsVectorLayer(orig_layer.source(), orig_layer.name(), orig_layer.providerType())
        geom_type = layer.geometryType()
        # layer.wkbType() does not return reliable results
        wkb_type = layer.wkbType()

        if self.create_backup:
            self.report_message.emit(self.layer_id, 'creating backup ...')
            self.__create_backup_file(orig_layer)

        self.report_message.emit(self.layer_id, 'preparing ...')
        layer.startEditing()
        request = QgsFeatureRequest().setFilterRect(self.snap_extent)
        total_features = 0
        for feature in layer.getFeatures(request):
            total_features += 1

        QgsMessageLog.logMessage(self.plugin.tr('Features to be snapped in layer <{0}>: {1}').
                                 format(orig_layer.name(), total_features), self.plugin.tr('Vertex Tools'),
                                 QgsMessageLog.INFO)
        if total_features == 0:
            self.report_message.emit(self.layer_id, 'no features')

        count = 0
        for feature in layer.getFeatures(request):
            with QMutexLocker(self.mutex):
                if self.stopped:
                    layer.rollBack()
                    return

            if geom_type == QGis.Point:
                snapped_geom = self.__point_grid(feature, wkb_type)
            elif geom_type == QGis.Line:
                snapped_geom = self.__line_grid(feature, wkb_type)
            elif geom_type == QGis.Polygon:
                snapped_geom = self.__polygon_grid(feature, wkb_type)

            layer.changeGeometry(feature.id(), snapped_geom)

            count += 1
            self.run_progressed.emit(self.layer_id, count, total_features)

        layer.commitChanges()

        self.completed = True
Пример #24
0
 def generateMemoryLayer(self, targetLayer, fieldDict):
     epsg = 'EPSG:'+ str(targetLayer.crs().postgisSrid())
     if self.geometryText.has_key(targetLayer.wkbType()):
         geometry = self.wkbText[targetLayer.wkbType()]
     else:
         geometry = self.geometryText[targetLayer.geometryType()]
     name = targetLayer.name()
     memoryLayer = QgsVectorLayer(geometry + '?crs=' + epsg, name, "memory")
     memoryLayer.startEditing()#to add field it needs to be in editing mode
     for fieldName in fieldDict:
         field = QgsField(fieldName, fieldDict[fieldName])
         memoryLayer.dataProvider().addAttributes([field])
     memoryLayer.updateFields()
     memoryLayer.commitChanges()
     return  memoryLayer
Пример #25
0
    def testStringArray(self):
        vl = QgsVectorLayer('%s table="qgis_test"."string_array" sql=' % (self.dbconn), "teststringarray", "postgres")
        self.assertTrue(vl.isValid())

        fields = vl.dataProvider().fields()
        self.assertEqual(fields.at(fields.indexFromName('value')).type(), QVariant.StringList)
        self.assertEqual(fields.at(fields.indexFromName('value')).subType(), QVariant.String)

        f = next(vl.getFeatures(QgsFeatureRequest()))

        value_idx = vl.fields().lookupField('value')
        self.assertIsInstance(f.attributes()[value_idx], list)
        self.assertEqual(f.attributes()[value_idx], ['a', 'b', 'c'])

        new_f = QgsFeature(vl.fields())
        new_f['pk'] = NULL
        new_f['value'] = ['simple', '"doubleQuote"', "'quote'", 'back\\slash']
        r, fs = vl.dataProvider().addFeatures([new_f])
        self.assertTrue(r)
        new_pk = fs[0]['pk']
        self.assertNotEqual(new_pk, NULL, fs[0].attributes())

        try:
            read_back = vl.getFeature(new_pk)
            self.assertEqual(read_back['pk'], new_pk)
            self.assertEqual(read_back['value'], new_f['value'])
        finally:
            self.assertTrue(vl.startEditing())
            self.assertTrue(vl.deleteFeatures([new_pk]))
            self.assertTrue(vl.commitChanges())
Пример #26
0
    def testSaveFields(self):
        # Create a new memory layer with no fields
        myMemoryLayer = QgsVectorLayer(("Point?crs=epsg:4326&index=yes"), "test", "memory")

        # Add some fields to the layer
        myFields = [
            QgsField("TestInt", QVariant.Int, "integer", 2, 0),
            QgsField("TestLong", QVariant.LongLong, "long", -1, 0),
            QgsField("TestDbl", QVariant.Double, "double", 8, 6),
            QgsField("TestString", QVariant.String, "string", 50, 0),
            QgsField("TestDate", QVariant.Date, "date"),
            QgsField("TestTime", QVariant.Time, "time"),
            QgsField("TestDateTime", QVariant.DateTime, "datetime"),
        ]
        assert myMemoryLayer.startEditing()
        for f in myFields:
            assert myMemoryLayer.addAttribute(f)
        assert myMemoryLayer.commitChanges()
        myMemoryLayer.updateFields()

        # Export the layer to a layer-definition-XML
        qlr = QgsMapLayer.asLayerDefinition([myMemoryLayer])
        assert qlr is not None

        # Import the layer from the layer-definition-XML
        layers = QgsMapLayer.fromLayerDefinition(qlr)
        assert layers is not None
        myImportedLayer = layers[0]
        assert myImportedLayer is not None

        # Check for the presence of the fields
        importedFields = myImportedLayer.fields()
        assert importedFields is not None
        for f in myFields:
            assert f == importedFields.field(f.name())
Пример #27
0
    def testEditGeoJsonAddField(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)

        f = QgsFeature()
        self.assertTrue(vl.getFeatures(QgsFeatureRequest()).nextFeature(f))
        self.assertIsNone(f['strfield'])

        # Completely reload file
        vl = QgsVectorLayer(datasource, 'test', 'ogr')
        # As we didn't set any value to the new field, it is not written at
        # all in the GeoJSON file, so it has disappeared
        self.assertEqual(len(vl.fields()), 1)
Пример #28
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))')
Пример #29
0
    def testHstore(self):
        vl = QgsVectorLayer('%s table="qgis_test"."dict" sql=' % (self.dbconn), "testhstore", "postgres")
        self.assertTrue(vl.isValid())

        fields = vl.dataProvider().fields()
        self.assertEqual(fields.at(fields.indexFromName('value')).type(), QVariant.Map)

        f = next(vl.getFeatures(QgsFeatureRequest()))

        value_idx = vl.fields().lookupField('value')
        self.assertIsInstance(f.attributes()[value_idx], dict)
        self.assertEqual(f.attributes()[value_idx], {'a': 'b', '1': '2'})

        new_f = QgsFeature(vl.fields())
        new_f['pk'] = NULL
        new_f['value'] = {'simple': '1', 'doubleQuote': '"y"', 'quote': "'q'", 'backslash': '\\'}
        r, fs = vl.dataProvider().addFeatures([new_f])
        self.assertTrue(r)
        new_pk = fs[0]['pk']
        self.assertNotEqual(new_pk, NULL, fs[0].attributes())

        try:
            read_back = vl.getFeature(new_pk)
            self.assertEqual(read_back['pk'], new_pk)
            self.assertEqual(read_back['value'], new_f['value'])
        finally:
            self.assertTrue(vl.startEditing())
            self.assertTrue(vl.deleteFeatures([new_pk]))
            self.assertTrue(vl.commitChanges())
Пример #30
0
    def testDeleteShapes(self):
        ''' Test fix for #11007 '''

        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')
        feature_count = vl.featureCount()
        # Start an iterator that will open a new connection
        iterator = vl.getFeatures()
        f = next(iterator)

        # Delete a feature
        self.assertTrue(vl.startEditing())
        self.assertTrue(vl.deleteFeature(1))
        self.assertTrue(vl.commitChanges())

        # Test the content of the shapefile while it is still opened
        ds = osgeo.ogr.Open(datasource)
        # Test repacking has been done
        self.assertTrue(ds.GetLayer(0).GetFeatureCount(), feature_count - 1)
        ds = None

        vl = None
Пример #31
0
class FlyingTrackerDialog(QtGui.QDockWidget, FORM_CLASS):
    def __init__(self, iface, parent=None):
        """Constructor."""
        super(FlyingTrackerDialog, self).__init__(parent)

        self.setupUi(self)
        self.iface = iface

        self.course_comboBox.clear()
        self.lcdNumberWpt.display(1)

        self.GpsFixlcdNumber.display(0)
        self.SatelliteslcdNumber.display(0)

        self.pushButtonDisconnect.hide()
        self.pushButtonConnect.clicked.connect(self.Connect)
        self.pushButtonDisconnect.clicked.connect(self.Disconnect)
        self.pushCloseButton.clicked.connect(self.Close)
        self.LoadtoolButton.clicked.connect(self.FillComboBox)
        self.wptplus_toolButton.clicked.connect(self.NextWpt)
        self.wptmin_toolButton.clicked.connect(self.BackWpt)
        QtCore.QObject.connect(self.wptplus_toolButton,
                               QtCore.SIGNAL("valueChanged(int)"),
                               self.AdjNxtWpt)
        QtCore.QObject.connect(self.wptmin_toolButton,
                               QtCore.SIGNAL("valueChanged(int)"),
                               self.AdjNxtWpt)
        self.ZoomIntoolButton.clicked.connect(self.ZoomIn)
        self.ZoomOuttoolButton.clicked.connect(self.ZoomOut)

        shortcut = QtGui.QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_S),
                                   self.iface.mainWindow())
        shortcut.setContext(QtCore.Qt.ApplicationShortcut)
        shortcut.activated.connect(self.ZoomIn)
        shortcut2 = QtGui.QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_A),
                                    self.iface.mainWindow())
        shortcut2.setContext(QtCore.Qt.ApplicationShortcut)
        shortcut2.activated.connect(self.ZoomOut)
        shortcut3 = QtGui.QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_X),
                                    self.iface.mainWindow())
        shortcut3.setContext(QtCore.Qt.ApplicationShortcut)
        shortcut3.activated.connect(self.NextWpt)
        shortcut4 = QtGui.QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Z),
                                    self.iface.mainWindow())
        shortcut4.setContext(QtCore.Qt.ApplicationShortcut)
        shortcut4.activated.connect(self.BackWpt)

        self.timer = QtCore.QTimer()
        QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"),
                               self.SendSerial)

        self.NxtWptRubber = False
        self.PositionMarker = False
        self.RubberBand = False
        self.WptVertexSignal = False

        self.trackCounter = 4

    def AdjNxtWpt(self):

        if self.WptVertexSignal == True:
            self.iface.mapCanvas().scene().removeItem(self.WptVertex)
            del self.WptVertex
            self.WptVertexSignal = False

        if self.NxtWptRubber == True:
            self.iface.mapCanvas().scene().removeItem(self.rdue)
            del self.rdue
            self.iface.mapCanvas().scene().removeItem(self.rtre)
            del self.rtre
            self.NxtWptRubber = False

        canvas = self.iface.mapCanvas()
        mapRenderer = canvas.mapRenderer()
        crsSrc = QgsCoordinateReferenceSystem(4326)  # NMEA is in WGS 84
        crsDest = mapRenderer.destinationCrs()
        xform = QgsCoordinateTransform(crsSrc, crsDest)

        WptValue = int(self.lcdNumberWpt.value())

        try:
            Wpt = self.pts[WptValue - 1]

        except IndexError:
            return

        self.WptVertex = QgsVertexMarker(self.iface.mapCanvas())
        self.WptVertex.setIconSize(20)
        self.WptVertex.setIconType(QgsVertexMarker.ICON_X)
        self.WptVertex.setPenWidth(20)
        self.WptVertex.setCenter(xform.transform(Wpt))
        self.WptVertexSignal = True

        if WptValue != 1:

            Wpt2 = self.pts[WptValue - 2]
            self.rdue = QgsRubberBand(self.iface.mapCanvas(),
                                      False)  # False = not a polygon
            pointsdue = [xform.transform(Wpt), xform.transform(Wpt2)]

            self.rdue.setColor(QtGui.QColor(255, 0, 0))
            self.rdue.setWidth(8)
            self.rdue.setLineStyle(QtCore.Qt.PenStyle(QtCore.Qt.DotLine))
            self.rdue.setToGeometry(QgsGeometry.fromPolyline(pointsdue),
                                    None)  #creation of NextWayPoint rubberband

            self.rtre = QgsRubberBand(self.iface.mapCanvas(), False)
            pointstre = self.pts[0:WptValue - 1]

            for i in xrange(len(pointstre)):
                pointstre[i] = xform.transform(pointstre[i])

            self.rtre.setColor(QtGui.QColor(127, 0, 255))
            self.rtre.setWidth(8)
            self.rtre.setLineStyle(QtCore.Qt.PenStyle(QtCore.Qt.DotLine))
            self.rtre.setToGeometry(QgsGeometry.fromPolyline(pointstre), None)

            self.NxtWptRubber = True

    def Connect(self):

        try:

            self.positionMarker = PositionMarker(self.iface.mapCanvas())
            self.PositionMarker = True
            portName = self.comboBox.currentText()
            self.ser = serial.Serial(portName, 38400)
            layername = self.course_comboBox.itemData(
                self.course_comboBox.currentIndex())
            RouteLayer = QgsMapLayerRegistry.instance().mapLayer(layername)
            RouteLayer.selectAll()
            feats = RouteLayer.selectedFeatures()
            RouteLayer.removeSelection()
            feat = feats[0]
            geom = feat.geometry()
            self.pts = geom.asPolyline()
            SourceIntCRS = int(RouteLayer.crs().authid().split(':')[1])

            if SourceIntCRS != 4326:
                SourceIntCRS = int(RouteLayer.crs().authid().split(':')[1])
                SourceCRS = QgsCoordinateReferenceSystem(SourceIntCRS)
                DestCRS = QgsCoordinateReferenceSystem(4326)
                xformRouteLayer = QgsCoordinateTransform(SourceCRS, DestCRS)
                for i in xrange(len(self.pts)):
                    x = self.pts[i][0]
                    y = self.pts[i][
                        1]  #if track layer is not in WGS84 Geographic every coordinate is transformed
                    TmpPoint = QgsPoint(x, y)
                    Tmp2Point = xformRouteLayer.transform(TmpPoint)
                    self.pts[i] = Tmp2Point

            self.TrackLayer = QgsVectorLayer("Point?crs=epsg:4326&index=yes",
                                             "Flight_track", "memory")
            self.TrackLayerProvider = self.TrackLayer.dataProvider()
            self.TrackLayerProvider.addAttributes([
                QgsField("id", QtCore.QVariant.Int),
                QgsField('Time', QtCore.QVariant.String),
                QgsField('Ele', QtCore.QVariant.String),
            ])

            QgsMapLayerRegistry.instance().addMapLayer(self.TrackLayer)
            symbols = self.TrackLayer.rendererV2().symbols()
            symbol = symbols[0]
            symbol.setColor(QtGui.QColor(0, 255, 0))
            self.iface.legendInterface().refreshLayerSymbology(self.TrackLayer)

            if self.lcdNumberWpt.value() == 0:
                self.lcdNumberWpt.display(1)

            elif self.lcdNumberWpt.value() > len(self.pts):
                self.lcdNumberWpt.display(1)

            self.InRouteTolerance = float(
                self.DTrack_spinBox.value()
            )  #if we are distant from route less than this value path become green, otherwise red
            self.CompassTolerance = self.DCompass_spinBox.value(
            )  #if compass to next wpt confront to actual compass diverge less than this value projection of direction become green, otherwise red
            self.WptArrivedTolerance = float(
                self.DWpt_spinBox.value()
            )  #if we pass near a wpt less than this value (in meters) the program will set the next wpt
            self.EleTolerance = float(
                self.DHeightspinBox.value()
            )  #if our elevation diverge from planned elevation more than this value our cursor will be red, otherwise green

            canvas = self.iface.mapCanvas()
            mapRenderer = canvas.mapRenderer()
            crsSrc = QgsCoordinateReferenceSystem(4326)  # NMEA is in WGS 84
            crsDest = mapRenderer.destinationCrs()

            self.backxform = QgsCoordinateTransform(crsDest, crsSrc)

            self.xform = QgsCoordinateTransform(
                crsSrc, crsDest)  #usage: xform.transform(QgsPoint)
            self.AdjNxtWpt()
            self.timer.start(1000)

        except:
            pass

    def SendSerial(self):
        thread = Thread(target=self.ReadSerial)
        thread.start()
        thread.join()

    def Disconnect(self, serialPort):

        self.timer.stop()
        self.lcdNumberSpeed.display(0)
        self.lcdNumberCompass.display(0)
        try:
            self.iface.mapCanvas().scene().removeItem(self.WptVertex)
            self.ser.close()
            self.iface.mapCanvas().scene().removeItem(self.r)
            self.iface.mapCanvas().scene().removeItem(self.runo)
            self.iface.mapCanvas().scene().removeItem(self.positionMarker)
            del self.WptVertex
            del self.r
            del self.runo
        except:
            pass

        self.iface.mapCanvas().setRotation(0)

        self.RubberBand = False

        if self.NxtWptRubber == True:
            self.iface.mapCanvas().scene().removeItem(self.rdue)
            self.iface.mapCanvas().scene().removeItem(self.rtre)
            del self.rdue
            del self.rtre
            self.NxtWptRubber = False

        else:
            pass

        self.WptVertexSignal = False
        self.lcdNumberHeights.display(0)
        self.lcdNumberSpeed.display(0)
        self.lcdNumberCompass.display(0)
        self.lcdCompassWpt.display(0)
        self.GpsFixlcdNumber.display(0)
        self.SatelliteslcdNumber.display(0)

    def FillComboBox(self):
        try:
            self.comboBox.clear()
            portlist = []
            system_name = platform.system()
            if system_name == "Windows":
                # Scan for available ports.
                available = []
                for i in range(256):
                    try:
                        s = serial.Serial(i)
                        available.append(i)
                        s.close()
                    except serial.SerialException:  #Search for active serial port
                        pass
                #print available
                list1 = available
            elif system_name == "Darwin":
                # Mac
                #print glob.glob('/dev/tty*') + glob.glob('/dev/cu*')
                list1 = glob.glob('/dev/tty*') + glob.glob('/dev/cu*')
            else:
                # Assume Linux or something else
                #print glob.glob('/dev/ttyS*') + glob.glob('/dev/ttyUSB*')
                list1 = glob.glob('/dev/ttyS*') + glob.glob('/dev/ttyUSB*')
            for i in list1:
                try:
                    serial.Serial(i).close()
                    portlist.append(i)
                except IOError:
                    pass

            for x in portlist:
                self.comboBox.addItem(x)

            self.course_comboBox.clear()

            LayerRegistryItem = QgsMapLayerRegistry.instance().mapLayers()
            for id, layer in LayerRegistryItem.iteritems():
                if layer.type() == QgsMapLayer.VectorLayer:
                    self.course_comboBox.addItem(layer.name(), id)

            layername = self.course_comboBox.itemData(
                self.course_comboBox.currentIndex())
            RouteLayer = QgsMapLayerRegistry.instance().mapLayer(layername)
            RouteLayer.selectAll()
            RouteLayer.featureCount()
            feats = RouteLayer.selectedFeatures()
            RouteLayer.removeSelection()
            feat = feats[0]
            geom = feat.geometry()
            self.pts = geom.asPolyline()
            SourceIntCRS = int(RouteLayer.crs().authid().split(':')[1])

            if SourceIntCRS != 4326:
                SourceIntCRS = int(RouteLayer.crs().authid().split(':')[1])
                SourceCRS = QgsCoordinateReferenceSystem(SourceIntCRS)
                DestCRS = QgsCoordinateReferenceSystem(4326)
                xformRouteLayer = QgsCoordinateTransform(SourceCRS, DestCRS)
                for i in xrange(len(self.pts)):
                    x = self.pts[i][0]
                    y = self.pts[i][
                        1]  #if track layer is not in WGS84 Geographic every coordinate is transformed
                    TmpPoint = QgsPoint(x, y)
                    Tmp2Point = xformRouteLayer.transform(TmpPoint)
                    self.pts[i] = Tmp2Point

            self.AdjNxtWpt()
        except:
            pass

    def Close(self):

        self.timer.stop()
        self.lcdNumberHeights.display(0)
        self.lcdNumberSpeed.display(0)
        self.lcdNumberCompass.display(0)
        self.lcdCompassWpt.display(0)

        self.course_comboBox.clear()
        if self.PositionMarker == True:
            self.iface.mapCanvas().scene().removeItem(self.positionMarker)

        if self.NxtWptRubber == True:
            self.iface.mapCanvas().scene().removeItem(self.rdue)
            self.iface.mapCanvas().scene().removeItem(self.rtre)
            del self.rdue
            del self.rtre
            self.NxtWptRubber = False

        else:
            pass

        if self.WptVertexSignal == True:
            self.iface.mapCanvas().scene().removeItem(self.WptVertex)
            del self.WptVertex
            self.WptVertexSignal = False

        self.close()

    def ZoomIn(self):
        self.iface.mapCanvas().zoomIn()

    def ZoomOut(self):
        self.iface.mapCanvas().zoomOut()

    def NextWpt(self):
        try:
            currentValue = self.lcdNumberWpt.value()
            if currentValue == len(self.pts):
                pass
            else:
                self.lcdNumberWpt.display(currentValue + 1)
                self.AdjNxtWpt()
        except:
            pass

    def BackWpt(self):
        try:
            currentValue = self.lcdNumberWpt.value()
            if currentValue >= 2:
                self.lcdNumberWpt.display(currentValue - 1)
                self.AdjNxtWpt()
        except:
            pass

    def ReadSerial(self):

        if self.trackCounter > 5:
            self.trackCounter = 4
        self.trackCounter = self.trackCounter + 1  # when it arrive to 5 a gps point is painted (default is 4)

        GPGGA = 0
        GPVTG = 0

        data = self.ser.read(1)
        n = self.ser.inWaiting()
        if n:
            data = data + self.ser.read(n)

        if re.search("\r\n", data):
            # Since we found a CRLF, split it out
            data2 = data.split("\r\n")

            for i in range(len(data2)):

                if data2[i][0:6] == '$GPGGA':
                    GPGGA = data2[i].split(',')
                    #print GPGGA

                elif data2[i][0:6] == '$GPVTG':
                    GPVTG = data2[i].split(',')
                    #print GPRMC

            if GPGGA == 0:
                #print 'mancato'
                return

            elif GPVTG == 0:
                #print 'mancato'
                return

            else:

                decimalsLat = (float(GPGGA[2][2:])) / 60
                degreeLat = float(GPGGA[2][0:2])
                decimalsLon = (float(GPGGA[4][3:])) / 60
                degreeLon = float(GPGGA[4][0:3])

                Lat = degreeLat + decimalsLat
                Lon = degreeLon + decimalsLon

                if GPGGA[5] == 'W':
                    Lon = -Lon
                if GPGGA[3] == 'S':
                    Lat = -Lat

                Ele = float(GPGGA[9])
                Compass = float(GPVTG[1])
                Speed = (float(GPVTG[7]))  # in Km/h
                GpsFix = int(GPGGA[6])
                GpsSatellites = int(GPGGA[7])

                self.ser.flushInput()
                self.ser.flushOutput()

                self.GpsFixlcdNumber.display(GpsFix)
                self.SatelliteslcdNumber.display(GpsSatellites)

                if self.RubberBand == True:
                    self.iface.mapCanvas().scene().removeItem(self.r)
                    del self.r

                    self.RubberBand = False

                Point = QgsPoint()
                Point.set(Lon, Lat)

                TransfPoint = self.xform.transform(Point)

                canvas = self.iface.mapCanvas()
                if Compass <= 180:
                    #canvas.setRotation(-(Compass-self.rotation))
                    canvas.setRotation(
                        -Compass
                    )  # set canvas rotation according to:  UP of the map = Compass Direction
                else:
                    Compass = 360 - Compass
                    canvas.setRotation(Compass)

                canvas.setCenter(TransfPoint)

                self.positionMarker.newCoords(
                    TransfPoint)  # Put the arrow on screen
                #self.positionMarker.angle = 0.0

                WptValue = int(self.lcdNumberWpt.value())
                WptE = self.pts[WptValue - 1][0]
                WptN = self.pts[WptValue - 1][1]

                GeodesicAircraftToWpt = Geodesic.WGS84.Inverse(
                    Lat, Lon, WptN, WptE)
                distance = GeodesicAircraftToWpt['s12']
                azim = GeodesicAircraftToWpt[
                    'azi1']  #determine azimuth from next wpt
                if azim < 0:
                    azim += 360

                if distance <= self.WptArrivedTolerance:  # tolerance in meter for next wpt
                    self.NextWpt()

                #feetEle = Ele * 3.2808399            #meters to feet

                if self.comboBox_2.currentText() == 'ft.':
                    feetEle = Ele * 3.2808399  #Convert if needed
                    self.lcdNumberHeights.display(feetEle)
                else:
                    self.lcdNumberHeights.display(Ele)

                if self.comboBox_3.currentText() != 'km/h':
                    Speed = Speed * 0.53995694  #Convert if needed
                    self.lcdNumberSpeed.display(float(Speed))
                else:
                    self.lcdNumberSpeed.display(float(Speed))

                self.lcdNumberCompass.display(float(Compass))
                self.lcdCompassWpt.display(azim)

                canvasInPixel = canvas.getCoordinateTransform()
                ExtentHeightInPixel = canvasInPixel.mapHeight()
                ExtentWidthInPixel = canvasInPixel.mapWidth()

                LocateCompassProjectionEndInMapUnit = canvasInPixel.toMapPoint(
                    ExtentWidthInPixel / 2.0,
                    ExtentHeightInPixel - (ExtentHeightInPixel * 0.95))

                self.r = QgsRubberBand(self.iface.mapCanvas(),
                                       False)  # False = not a polygon

                #points = [TransfPoint, QgsPoint(x,y)]							#creazione della proiezione della prua su mappa
                points = [TransfPoint, LocateCompassProjectionEndInMapUnit]
                self.r.setWidth(8)
                self.r.setToGeometry(QgsGeometry.fromPolyline(points), None)

                if abs(Compass -
                       azim) <= self.CompassTolerance:  #Compass tolerance
                    self.r.setColor(QtGui.QColor(0, 255, 0))
                else:
                    self.r.setColor(QtGui.QColor(255, 0, 0))

                self.RubberBand = True

                try:
                    self.iface.mapCanvas().scene().removeItem(
                        self.runo)  # remove track for first waypoint
                except:
                    pass

                if WptValue != 1:

                    #DistanceFromLineTolerance = 100   #meter      set distance from route

                    BackwardLat = self.rdue.asGeometry().asPolyline()[1][
                        1]  #start to design a QgsRectangle buffer around current route to confront to Point
                    BackwardLon = self.rdue.asGeometry().asPolyline()[1][0]
                    BackwardPoint = QgsPoint(BackwardLon, BackwardLat)

                    BackwardPointTransformed = self.backxform.transform(
                        BackwardPoint)

                    GeodesicWptWpt = Geodesic.WGS84.Inverse(
                        BackwardPointTransformed.y(),
                        BackwardPointTransformed.x(), WptN, WptE)
                    #GeodesicWptWpt = Geodesic.WGS84.Inverse(BackwardLat, BackwardLon, WptN, WptE)
                    WptWptCompass = GeodesicWptWpt['azi1']

                    if WptWptCompass < 0:
                        WptWptCompass += 360
                    #print WptWptCompass

                    WptWptCompassRight = WptWptCompass + 90
                    if WptWptCompassRight > 360:
                        WptWptCompassRight = WptWptCompassRight - 360
                    #print WptWptCompassRight

                    WptWptCompassLeft = WptWptCompass - 90
                    if WptWptCompassLeft < 0:
                        WptWptCompassLeft += 360
                    #print WptWptCompassLeft

                    origin = geopy.Point(WptN, WptE)
                    URBufferVertex = vincenty(
                        meters=self.InRouteTolerance).destination(
                            origin, WptWptCompassRight)
                    URBufferVertexPoint = QgsPoint(URBufferVertex.longitude,
                                                   URBufferVertex.latitude)

                    ULBufferVertex = vincenty(
                        meters=self.InRouteTolerance).destination(
                            origin, WptWptCompassLeft)
                    ULBufferVertexPoint = QgsPoint(ULBufferVertex.longitude,
                                                   ULBufferVertex.latitude)
                    del origin

                    origin = geopy.Point(BackwardPointTransformed.y(),
                                         BackwardPointTransformed.x())
                    DRBufferVertex = vincenty(
                        meters=self.InRouteTolerance).destination(
                            origin, WptWptCompassRight)
                    DRBufferVertexPoint = QgsPoint(DRBufferVertex.longitude,
                                                   DRBufferVertex.latitude)

                    DLBufferVertex = vincenty(
                        meters=self.InRouteTolerance).destination(
                            origin, WptWptCompassLeft)
                    DLBufferVertexPoint = QgsPoint(DLBufferVertex.longitude,
                                                   DLBufferVertex.latitude)
                    del origin

                    gPolygon = QgsGeometry.fromPolygon([[
                        URBufferVertexPoint, ULBufferVertexPoint,
                        DLBufferVertexPoint, DRBufferVertexPoint
                    ]])

                    if not gPolygon.contains(Point):
                        self.rdue.setColor(QtGui.QColor(255, 0, 0))
                        #print 'noncontiene'
                    else:
                        self.rdue.setColor(QtGui.QColor(0, 255, 0))
                        #print 'contiene'
                else:
                    self.runo = QgsRubberBand(self.iface.mapCanvas(), False)
                    points = [TransfPoint,
                              self.xform.transform(self.pts[0])
                              ]  # draw track for first waypoint
                    self.runo.setColor(QtGui.QColor(255, 0, 0))
                    self.runo.setWidth(6)
                    self.runo.setLineStyle(
                        QtCore.Qt.PenStyle(QtCore.Qt.DotLine))
                    self.runo.setToGeometry(QgsGeometry.fromPolyline(points),
                                            None)

                #if abs(float((self.fixedHeightspinBox.value()/ 3.2808399)) - (feetEle/ 3.2808399)) <= self.EleTolerance:         #ele tolerance expressed in meters
                if abs(self.fixedHeightspinBox.value() -
                       Ele) <= self.EleTolerance:
                    self.positionMarker.setHasPosition(
                        True)  #True or False to change color
                else:
                    self.positionMarker.setHasPosition(False)

                if self.trackCounter == 5:
                    #pass
                    fc = int(self.TrackLayerProvider.featureCount())
                    time = str(GPGGA[1])[0:2] + ':' + str(
                        GPGGA[1])[2:4] + ':' + str(
                            GPGGA[1])[4:6]  # timestamp for GPX layer

                    feature = QgsFeature()
                    feature.setGeometry(QgsGeometry.fromPoint(Point))
                    feature.setAttributes([fc, time, Ele])
                    self.TrackLayer.startEditing()
                    self.TrackLayer.addFeature(feature, True)
                    self.TrackLayer.commitChanges()
                    self.TrackLayer.setCacheImage(None)
                    self.TrackLayer.triggerRepaint()
                    self.trackCounter = 0

                return
Пример #32
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)
Пример #33
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.')
    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)
Пример #35
0
    def sampling(self, outPath, tableName):  # main process
        # open sampling points layer
        pointLayer = self.sampItems[str(self.inSample.currentText())][0]
        pointProvider = pointLayer.dataProvider()
        allAttrs = pointProvider.attributeIndexes()
        sRs = pointLayer.crs()
        # create destination layer: first create list of selected fields
        fieldList = QgsFields()
        for i in range(len(self.fields)):
            if self.fields[i][0] == "point":  #copying fields from source layer
                field = pointProvider.fields()[pointProvider.fieldNameIndex(
                    self.sampItems[self.fields[i][1]][self.fields[i][2]][0])]
                field.setName(
                    self.sampItems[self.fields[i][1]][self.fields[i][2]][1])
            elif self.fields[i][
                    0] == "poly":  #copying fields from polygon layers
                polyLayer = self.polyItems[self.fields[i][1]][0]
                polyProvider = polyLayer.dataProvider()
                field = polyProvider.fields()[polyProvider.fieldNameIndex(
                    self.polyItems[self.fields[i][1]][self.fields[i][2]][0])]
                field.setName(
                    self.polyItems[self.fields[i][1]][self.fields[i][2]][1])
            else:  #creating fields for raster layers
                field = QgsField(
                    self.rastItems[self.fields[i][1]][self.fields[i][2]][1],
                    QVariant.Double, "real", 20, 5, "")
                ##### Better data type fit will be implemented in next versions
            fieldList.append(field)
        # create temporary memory layer (as it's currently impossible to set GPKG table name when writting features to QgsVectorFileWriter directly)
        memLayer = QgsVectorLayer("Point?crs=epsg:%d" % sRs.postgisSrid(),
                                  'temp layer', 'memory')
        memLayer.startEditing()
        for field in fieldList:
            memLayer.addAttribute(field)
        memLayer.commitChanges()

        self.statusLabel.setText("Writing data to the new layer...")
        self.repaint()
        # process point after point...
        pointFeat = QgsFeature()
        np = 0
        snp = pointProvider.featureCount()
        for pointFeat in pointProvider.getFeatures():
            np += 1
            if snp < 100 or (snp < 5000 and (np // 10.0 == np / 10.0)) or (
                    np // 100.0 == np /
                    100.0):  # display each or every 10th or every 100th point:
                self.statusLabel.setText("Processing point %s of %s" %
                                         (np, snp))
                self.repaint()
            # convert multipoint[0] to point
            pointGeom = pointFeat.geometry()
            if pointGeom.wkbType() == QgsWkbTypes.MultiPoint:
                pointPoint = pointGeom.asMultiPoint()[0]
            else:
                pointPoint = pointGeom.asPoint()
            outFeat = QgsFeature()
            outFeat.setGeometry(pointGeom)
            # ...and next loop inside: field after field
            bBox = QgsRectangle(
                pointPoint.x() - 0.001,
                pointPoint.y() - 0.001,
                pointPoint.x() + 0.001,
                pointPoint.y() +
                0.001)  # reuseable rectangle buffer around the point feature
            previousPolyLayer = None  # reuse previous feature if it's still the same layer
            previousPolyFeat = None  # reuse previous feature if it's still the same layer
            previousRastLayer = None  # reuse previous raster multichannel sample if it's still the same layer
            previousRastSample = None  # reuse previous raster multichannel sample if it's still the same layer
            attrs = []
            for i in range(len(self.fields)):
                field = self.fields[i]
                if field[0] == "point":
                    attr = pointFeat.attributes()[pointProvider.fieldNameIndex(
                        self.sampItems[field[1]][field[2]][0])]
                    attrs += [attr]
                elif field[0] == "poly":
                    polyLayer = self.polyItems[field[1]][0]
                    polyProvider = polyLayer.dataProvider()
                    if polyLayer == previousPolyLayer:
                        polyFeat = previousPolyFeat
                    else:
                        polyFeat = None
                        pointGeom = QgsGeometry().fromPointXY(pointPoint)
                        for iFeat in polyProvider.getFeatures(
                                QgsFeatureRequest().setFilterRect(bBox)):
                            if pointGeom.intersects(iFeat.geometry()):
                                polyFeat = iFeat
                    if polyFeat:
                        attr = polyFeat.attributes()[
                            polyProvider.fieldNameIndex(
                                self.polyItems[field[1]][field[2]][0])]
                    else:
                        attr = None
                    attrs += [
                        attr
                    ]  #only last one if more polygons overlaps!! This way we avoid attribute list overflow
                    previousPolyLayer = polyLayer
                    previousPolyFeat = polyFeat
                else:  # field source is raster
                    rastLayer = self.rastItems[field[1]][0]
                    if rastLayer == previousRastLayer:
                        rastSample = previousRastSample
                    else:
                        rastSample = rastLayer.dataProvider().identify(
                            pointPoint,
                            QgsRaster.IdentifyFormatValue).results()
                    try:
                        #bandName = self.rastItems[field[1]][field[2]][0] #depreciated
                        bandNo = field[2]
                        attr = float(
                            rastSample[bandNo]
                        )  ##### !! float() - I HAVE TO IMPLEMENT RASTER TYPE HANDLING!!!!
                    except:  # point is out of raster extent
                        attr = None
                    attrs += [attr]
                    previousRastLayer = rastLayer
                    previousRastSample = rastSample
            outFeat.initAttributes(len(attrs))
            outFeat.setAttributes(attrs)
            memLayer.dataProvider().addFeature(outFeat)

        # write the memlayer to the output file
        so = QgsVectorFileWriter.SaveVectorOptions()
        so.fileEncoding = 'UTF-8'
        if outPath.upper().endswith('SHP'):
            so.driverName = "ESRI Shapefile"
        elif outPath.upper().endswith('CSV'):
            so.driverName = "CSV"
        else:
            so.driverName = "GPKG"
            if tableName:
                so.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer
                so.layerName = tableName
        result, errMsg = QgsVectorFileWriter.writeAsVectorFormat(
            memLayer, outPath, so)
        if result:
            QMessageBox.critical(self, "Point sampling tool", errMsg)
            return False
        else:
            del memLayer
            self.statusLabel.setText("The new layer has been created.")
            return True
class StartOutofBoundsAngles:

    def __init__(self, iface, layer):
        
        self.iface = iface

        self.layer = layer
        self.tableSchema = 'edgv'
        self.geometryColumn = 'geom'
        self.keyColumn = 'id'
        self.angle = 10

        
    def run(self, fid = 0):

    ##################################
    ###### PEGA A LAYER ATIVA ########
    ##################################

        parametros = self.layer.source().split(" ") # recebe todos os parametros em uma lista ( senha, porta, password etc..)

    ####################################
    ###### INICIANDO CONEXÃO DB ########
    ####################################

        # Outra opção para isso, seria usar ex: self.dbname.. self.host.. etc.. direto dentro do laço for.
        dbname = "" 
        host = ""
        port = 0
        user = ""
        password = ""

        for i in parametros:
            part = i.split("=")
            
        # Recebe os parametros guardados na própria Layer

            if "dbname" in part[0]:
                dbname = part[1].replace("'", "")

            elif "host" in part[0]:
                host = part[1].replace("'", "")

            elif "port" in part[0]:
                port = int(part[1].replace("'", ""))

            elif "user" in part[0]:
                user = part[1].replace("'", "")

            elif "password" in part[0]:
                password = part[1].split("|")[0].replace("'", "")

        print dbname, host, port, user, password


        # Testa se os parametros receberam os valores pretendidos, caso não, apresenta a mensagem informando..
        if len(dbname) == 0 or len(host) == 0 or port == 0 or len(user) == 0 or len(password) == 0:
            self.iface.messageBar().pushMessage("Erro", u'Um dos parametros não foram devidamente recebidos!', level=QgsMessageBar.CRITICAL, duration=4)
            return

    ####################################
    #### SETA VALORES DE CONEXÃO DB ####
    ####################################

        connection = QSqlDatabase.addDatabase('QPSQL')
        connection.setHostName(host)
        connection.setPort(port)
        connection.setUserName(user)
        connection.setPassword(password)
        connection.setDatabaseName(dbname)

        if not connection.isOpen(): # Testa se a conexão esta recebendo os parametros adequadamente.
            if not connection.open():
                print 'Error connecting to database!'
                self.iface.messageBar().pushMessage("Erro", u'Error connecting to database!', level=QgsMessageBar.CRITICAL, duration=4)
                print connection.lastError().text()
                return

    ####################################
    ###### CRIAÇÃO DE MEMORY LAYER #####
    ####################################
        
        layerCrs = self.layer.crs().authid() # Passa o formato (epsg: numeros)

        flagsLayerName = self.layer.name() + "_flags"
        flagsLayerExists = False

        for l in QgsMapLayerRegistry.instance().mapLayers().values(): # Recebe todas as camadas que estão abertas
            if l.name() == flagsLayerName: # ao encontrar o nome pretendido..
                self.flagsLayer = l # flagslayer vai receber o nome..
                self.flagsLayerProvider = l.dataProvider()
                flagsLayerExists = True # se encontrado os parametros buscados, recebe True.
                break
        
        if flagsLayerExists == False: # se não encontrado os parametros buscados, recebe False.
            tempString = "Point?crs="
            tempString += str(layerCrs)

            self.flagsLayer = QgsVectorLayer(tempString, flagsLayerName, "memory")
            self.flagsLayerProvider = self.flagsLayer.dataProvider()
            self.flagsLayerProvider.addAttributes([QgsField("flagId", QVariant.String), QgsField("geomId", QVariant.String), QgsField("motivo", QVariant.String)])
            self.flagsLayer.updateFields()

        if fid == 0: # Se for 0 então está iniciando e limpa, caso contrário não.
            self.flagsLayer.startEditing()
            ids = [feat.id() for feat in self.flagsLayer.getFeatures()]
            self.flagsLayer.deleteFeatures(ids)
            self.flagsLayer.commitChanges()
        
        
        lista_fid = [] # Iniciando lista
        for f in self.layer.getFeatures():
            lista_fid.append(str(f.id())) # Guarda na lista. A lista de Feature ids passa tipo "int", foi convertido e guardado como "str".

        source = self.layer.source().split(" ")
        self.tableName = "" # Inicia vazio
        layerExistsInDB = False
        
        for i in source:
                
            if "table=" in i or "layername=" in i: # Se encontrar os atributos pretendidos dentre todos do for
                self.tableName = source[source.index(i)].split(".")[1] # Faz split em ponto e pega a segunda parte.
                self.tableName = self.tableName.replace('"', '')
                layerExistsInDB = True
                break
             
        if layerExistsInDB == False:
            self.iface.messageBar().pushMessage("Erro", u"Provedor da camada corrente não provem do banco de dados!", level=QgsMessageBar.CRITICAL, duration=4)
            return

        
        geomType = self.layer.geometryType()

        if geomType == QGis.Line:
            
        # Busca através do SQL 
            sql = """
            WITH result AS (SELECT points."{4}", points.anchor, (degrees
                                        (
                                            ST_Azimuth(points.anchor, points.pt1) - ST_Azimuth(points.anchor, points.pt2)
                                        )::decimal + 360) % 360 as angle
                        FROM
                        (SELECT
                              ST_PointN("{3}", generate_series(1, ST_NPoints("{3}")-2)) as pt1, 
                              ST_PointN("{3}", generate_series(2, ST_NPoints("{3}")-1)) as anchor,
                              ST_PointN("{3}", generate_series(3, ST_NPoints("{3}"))) as pt2,
                              linestrings."{4}" as "{4}" 
                            FROM
                              (SELECT "{4}" as "{4}", (ST_Dump("{3}")).geom as "{3}"
                               FROM only "{0}"."{1}"
                               ) AS linestrings WHERE ST_NPoints(linestrings."{3}") > 2 ) as points)
            select distinct "{4}", ST_AsText(anchor), angle from result where (result.angle % 360) < {2} or result.angle > (360.0 - ({2} % 360.0)) and result.{4} in ({5})""".format( self.tableSchema, self.tableName, self.angle, self.geometryColumn, self.keyColumn,",".join(lista_fid))
        
        elif geomType == QGis.Polygon:
            sql = """
            WITH result AS (SELECT points."{4}", points.anchor, (degrees
                                        (
                                            ST_Azimuth(points.anchor, points.pt1) - ST_Azimuth(points.anchor, points.pt2)
                                        )::decimal + 360) % 360 as angle
                        FROM
                        (SELECT
                              ST_PointN("{3}", generate_series(1, ST_NPoints("{3}")-1)) as pt1,
                              ST_PointN("{3}", generate_series(1, ST_NPoints("{3}")-1) %  (ST_NPoints("{3}")-1)+1) as anchor,
                              ST_PointN("{3}", generate_series(2, ST_NPoints("{3}")) %  (ST_NPoints("{3}")-1)+1) as pt2,
                              linestrings."{4}" as "{4}"
                            FROM
                              (SELECT "{4}" as "{4}", (ST_Dump(ST_Boundary(ST_ForceRHR((ST_Dump("{3}")).geom)))).geom as "{3}"
                               FROM only "{0}"."{1}" 
                               ) AS linestrings WHERE ST_NPoints(linestrings."{3}") > 2 ) as points)
            select distinct "{4}", ST_AsText(anchor), angle from result where (result.angle % 360) < {2} or result.angle > (360.0 - ({2} % 360.0)) and result.{4} in ({5})""".format( self.tableSchema, self.tableName, self.angle, self.geometryColumn, self.keyColumn,",".join(lista_fid) )
        query = QSqlQuery(sql)
        
        self.flagsLayer.startEditing()
        flagCount = fid # iniciando contador que será referência para os IDs da camada de memória.

        listaFeatures = []
        while query.next():
            id = query.value(0)
            local = query.value(1)
            angulo = query.value(2)
            flagId = str(flagCount)

            flagFeat = QgsFeature()
            flagFeat.setFields(self.flagsLayer.fields()) # passa quais atributos serão usados.           
            flagGeom = QgsGeometry.fromWkt(local) # passa o local onde foi localizado o erro.
            flagFeat.setGeometry(flagGeom)
            flagFeat.initAttributes(3)
            flagFeat.setAttribute(0,flagId) # insere o id definido para a coluna 0 da layer de memória.
            flagFeat.setAttribute(1, id) # insere o id da geometria  para a coluna 1 da layer de memória.
            flagFeat.setAttribute(2, u"Ângle-ExcededBound")
        
            listaFeatures.append(flagFeat)    

            flagCount += 1 # incrementando o contador a cada iteração.

        self.flagsLayerProvider.addFeatures(listaFeatures)
        self.flagsLayer.commitChanges() # Aplica as alterações à camada.
        
        QgsMapLayerRegistry.instance().addMapLayer(self.flagsLayer) # Adicione a camada no mapa.

        return flagCount
        
Пример #37
0
    def processAlgorithm(self, parameters, context, feedback):
        """
        Here is where the processing itself takes place.
        """

        demLayer = self.parameterAsRasterLayer(parameters, self.INPUT_DEM,
                                               context)

        # If DEM layer was not found, throw an exception to indicate that the algorithm
        # encountered a fatal error. The exception text can be any string, but in this
        # case we use the pre-built invalidSourceError method to return a standard
        # helper text for when a source cannot be evaluated
        if demLayer is None:
            raise QgsProcessingException(
                self.invalidSourceError(parameters, self.INPUT_DEM))

        outDBF = self.parameterAsOutputLayer(parameters, self.OUTPUT_DBF,
                                             context)

        # If output DBF was not created, throw an exception to indicate that the algorithm
        # encountered a fatal error. The exception text can be any string, but in this
        # case we use the pre-built invalidSinkError method to return a standard
        # helper text for when a sink cannot be evaluated
        if outDBF is None:
            raise QgsProcessingException(
                self.invalidSinkError(parameters, self.OUTPUT_DBF))

        # Run the script
        stats = demLayer.dataProvider().bandStatistics(1)
        demMinimum = stats.minimumValue
        demMaximum = stats.maximumValue
        print("min:", demMinimum, "m")
        print("max:", demMaximum, "m")
        demRange = demMaximum - demMinimum
        print("Elevation Difference:", demRange, "m")
        increment = demRange / 10.0
        print("Increment:", increment)
        i = 0
        dbfList = []
        for level in self.frange(demMinimum, demMaximum + 1, increment):
            outTable = os.path.join(os.path.dirname(outDBF),
                                    "volume" + str(round(level * 100.0)))
            outTableDbf = str(outTable) + ".dbf"
            processing.run(
                "native:rastersurfacevolume", {
                    'INPUT': demLayer,
                    'BAND': 1,
                    'LEVEL': level,
                    'METHOD': 1,
                    'OUTPUT_HTML_FILE': 'TEMPORARY_OUTPUT',
                    'OUTPUT_TABLE': outTable + ".shp"
                })

            dbfTable = QgsVectorLayer(outTable + ".dbf", outTable, "ogr")
            for feature in dbfTable.getFeatures():
                VolumeKm3 = abs(feature["Volume"]) / 1000000000.0

            pr = dbfTable.dataProvider()
            pr.addAttributes([
                QgsField("Level", QVariant.Double),
                QgsField("VolAbsKm3", QVariant.Double)
            ])
            dbfTable.updateFields()
            dbfTable.startEditing()
            for f in dbfTable.getFeatures():
                f["Level"] = level
                f["VolAbsKm3"] = VolumeKm3
                dbfTable.updateFeature(f)
            dbfTable.commitChanges()

            dbfList.append(outTableDbf)

        volumetable = processing.run("native:mergevectorlayers", {
            'LAYERS': dbfList,
            'CRS': None,
            'OUTPUT': outDBF
        })

        # Return the results of the algorithm.
        outFile = os.path.splitext(outDBF)[0] + ".dbf"
        return {self.OUTPUT_DBF: outFile}
Пример #38
0
    def testTransaction(self):

        tmpfile = os.path.join(self.basetestpath, 'testTransaction.gpkg')
        ds = ogr.GetDriverByName('GPKG').CreateDataSource(tmpfile)
        lyr = ds.CreateLayer('lyr1', geom_type=ogr.wkbPoint)
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(0 1)'))
        lyr.CreateFeature(f)
        lyr = ds.CreateLayer('lyr2', geom_type=ogr.wkbPoint)
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(2 3)'))
        lyr.CreateFeature(f)
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetGeometry(ogr.CreateGeometryFromWkt('POINT(4 5)'))
        lyr.CreateFeature(f)
        ds = None

        vl1 = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=" + "lyr1",
                             'test', u'ogr')
        self.assertTrue(vl1.isValid())
        vl2 = QgsVectorLayer(u'{}'.format(tmpfile) + "|layername=" + "lyr2",
                             'test', u'ogr')
        self.assertTrue(vl2.isValid())

        # prepare a project with transactions enabled
        p = QgsProject()
        p.setAutoTransaction(True)
        p.addMapLayers([vl1, vl2])

        self.assertTrue(vl1.startEditing())
        self.assertIsNotNone(vl1.dataProvider().transaction())
        self.assertTrue(vl1.deleteFeature(1))

        # An iterator opened on the layer should see the feature deleted
        self.assertEqual(
            len([f for f in vl1.getFeatures(QgsFeatureRequest())]), 0)

        # But not if opened from another connection
        vl1_external = QgsVectorLayer(
            u'{}'.format(tmpfile) + "|layername=" + "lyr1", 'test', u'ogr')
        self.assertTrue(vl1_external.isValid())
        self.assertEqual(
            len([f for f in vl1_external.getFeatures(QgsFeatureRequest())]), 1)
        del vl1_external

        self.assertTrue(vl1.commitChanges())

        # Should still get zero features on vl1
        self.assertEqual(
            len([f for f in vl1.getFeatures(QgsFeatureRequest())]), 0)
        self.assertEqual(
            len([f for f in vl2.getFeatures(QgsFeatureRequest())]), 2)

        # Test undo/redo
        self.assertTrue(vl2.startEditing())
        self.assertIsNotNone(vl2.dataProvider().transaction())
        self.assertTrue(vl2.editBuffer().deleteFeature(1))
        self.assertEqual(
            len([f for f in vl2.getFeatures(QgsFeatureRequest())]), 1)
        self.assertTrue(vl2.editBuffer().deleteFeature(2))
        self.assertEqual(
            len([f for f in vl2.getFeatures(QgsFeatureRequest())]), 0)
        vl2.undoStack().undo()
        self.assertEqual(
            len([f for f in vl2.getFeatures(QgsFeatureRequest())]), 1)
        vl2.undoStack().undo()
        self.assertEqual(
            len([f for f in vl2.getFeatures(QgsFeatureRequest())]), 2)
        vl2.undoStack().redo()
        self.assertEqual(
            len([f for f in vl2.getFeatures(QgsFeatureRequest())]), 1)
        self.assertTrue(vl2.commitChanges())

        self.assertEqual(
            len([f for f in vl2.getFeatures(QgsFeatureRequest())]), 1)
        del vl1
        del vl2

        vl2_external = QgsVectorLayer(
            u'{}'.format(tmpfile) + "|layername=" + "lyr2", 'test', u'ogr')
        self.assertTrue(vl2_external.isValid())
        self.assertEqual(
            len([f for f in vl2_external.getFeatures(QgsFeatureRequest())]), 1)
        del vl2_external
Пример #39
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()
Пример #40
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].geometry()
        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].geometry()
        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")
Пример #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())
        QgsMapLayerRegistry.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.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.setFeatureId(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.setFeatureId(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.setFeatureId(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, 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.assertFalse(newPointsLayer is None)
        self.assertFalse(newLinesLayer is None)
        self.assertTrue(newLinesLayer.id(
        ) in [dep.layerId() for dep in newPointsLayer.dependencies()])

        self.pointsLayer.setDependencies([])

    def test_signalConnection(self):
        # remove all layers
        QgsMapLayerRegistry.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
        QgsMapLayerRegistry.instance().addMapLayers([self.pointsLayer])
        QgsMapLayerRegistry.instance().addMapLayers([self.linesLayer])
        QgsMapLayerRegistry.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.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.setFeatureId(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([])
Пример #42
0
class AutoFieldsTests( unittest.TestCase ):

    @classmethod
    def setUpClass( self ):
        self.msg = MessageManager( 'debug', None ) 
        self.msg.show( "Info! SetUp started", 'info', True )
        #Initialize QGIS app
        app = QgsApplication([], True)
        QgsApplication.setPrefixPath("/usr", True)
        QgsApplication.initQgis()
        
        #Configure QSettings (organization and application name)
        self.settings = QSettings("GeoTux", "QGIS-Plugin-Test") 

        #Load layer, add field f1, and add layer to Registry
        baseDir = os.path.dirname( os.path.realpath( __file__ ) )
        self.layerPath = os.path.join( baseDir, 'test_data', 'test_points.shp' )
        self.layer = QgsVectorLayer( self.layerPath, 'puntos', 'ogr' )   
        self.layer.dataProvider().addAttributes([QgsField('f1', QVariant.Double)])
        self.layer.updateFields()
        QgsMapLayerRegistry.instance().addMapLayer( self.layer )  
        
        #Instantiate AutoFieldManager
        self.autoFieldManager = AutoFieldManager( self.msg, None, '/AutoFieldsTest', 'GeoTux', 'QGIS-Plugin-Test' )
        
            
    def readStoredSettings( self, layer, fieldName ):
        """ Helper function to get a dictionary of stored QSettings for an AutoField """
        dictTmpProperties = {}
        autoFieldId = self.autoFieldManager.buildAutoFieldId( layer, fieldName )
        self.settings.beginGroup('/AutoFieldsTest/data/' + autoFieldId)
        dictTmpProperties['layer'] = self.settings.value( "layer", "", type=str )
        dictTmpProperties['field'] = self.settings.value( "field", u"", type=unicode )
        dictTmpProperties['expression'] = self.settings.value( "expression", u"", type=unicode )
        dictTmpProperties['layer2'] = self.settings.value( "layer2", "", type=str )
        dictTmpProperties['field2'] = self.settings.value( "field2", "", type=str )            
        dictTmpProperties['enabled'] = self.settings.value( "enabled", False, type=bool )
        self.settings.endGroup()
                
        return dictTmpProperties

    def test01CreateEnabledAutoField( self ):
        """ QSettings should be properly stored, AutoField should be enabled """
        self.msg.show( "Info! Test 1 started", 'info', True )

        self.autoFieldManager.createAutoField(
            layer=self.layer, 
            fieldName=u'f1', 
            expression=u'$x'
        )

        dictTmpProperties = self.readStoredSettings( self.layer, u'f1' )      
        dictExpectedProperties = {
            'layer':self.layerPath,
            'field':u'f1',
            'expression':u'$x',
            'layer2':"",
            'field2':"",
            'enabled':True
        }
        
        self.assertEqual( dictTmpProperties, dictExpectedProperties )
        
        
    def test02AvoidTwoAutoFieldsOnSameField( self ):
        """ AutoField should not be created if another one already exists on the same field."""
        self.msg.show( "Info! Test 2 started", 'info', True )

        res = self.autoFieldManager.createAutoField(
            layer=self.layer, 
            fieldName=u'f1', 
            expression=u'$y'
        )
        
        self.assertFalse( res )
        
        
    def test03EditAutoFieldLayer( self ):
        """ AutoField value should be updated if a feature is added.
            Note: It cannot handle the case when writing directly to the provider,
              as QGIS doesn't have a SIGNAL for that.
              self.layer.dataProvider().addFeatures( [ tmpFeature ] )        
         """
        self.msg.show( "Info! Test 3 started", 'info', True )

        tmpFeature = QgsFeature( self.layer.pendingFields() )
        tmpFeature.setGeometry( QgsGeometry.fromPoint( QgsPoint(-74.4, 4.5) ) )

        # Either 1:
        self.layer.startEditing()
        self.layer.addFeature( tmpFeature )
        self.layer.commitChanges()
        
        # Or 2:
        #with edit( self.layer ):
        #    self.layer.addFeature( tmpFeature )
            
        addedFeature = self.layer.getFeatures().next()
        self.assertEquals( addedFeature['f1'], -74.4 )


    def test04ChangeAttributeValue( self ):
        """ AutoField value should be updated if another AutoField value is changed """
        self.msg.show( "Info! Test 4 started", 'info', True )

        self.autoFieldManager.createAutoField(
            layer=self.layer, 
            fieldName=u'modified', 
            expression=u'\'now: \' + to_string("f1")'
        )

        self.layer.startEditing()
        self.layer.changeAttributeValue( 0, self.layer.fieldNameIndex( u'id' ), 1 )
        self.layer.commitChanges()
            
        feature = self.layer.getFeatures().next()
        self.assertEquals( feature['modified'], 'now: -74.4' )

    
    def test05FieldRemovedThenDisableAutoField( self ):
        """ AutoField should be disabled if its base field is removed """
        self.msg.show( "Info! Test 5 started", 'info', True )

        fieldIndex = self.layer.fieldNameIndex( u'f1' )
        self.layer.startEditing()
        self.layer.deleteAttribute( fieldIndex )
        self.layer.commitChanges()
        dictTmpProperties = self.readStoredSettings( self.layer, u'f1' )    
        
        self.assertFalse( dictTmpProperties['enabled'] )        
            

    def test06MissingFieldAddedThenEnableAutoField( self ):
        """ AutoField should be enabled if missing field is added """
        self.msg.show( "Info! Test 6 started", 'info', True )    

        self.layer.startEditing()
        self.layer.addAttribute( QgsField( 'f1', QVariant.Double, len=10, prec=2 ) )
        self.layer.commitChanges()
        
        dictTmpProperties = self.readStoredSettings( self.layer, u'f1' )    
        
        self.assertTrue( dictTmpProperties['enabled'] )   

        
    def test07LayerRemovedThenDisableAutoField( self ):
        """ AutoField should be disabled if its base layer is removed """
        self.msg.show( "Info! Test 7 started", 'info', True )

        QgsMapLayerRegistry.instance().removeMapLayer( self.layer.id() )

        # removeMapLayer deletes the underlying object, so create it again
        self.layer = QgsVectorLayer( self.layerPath, 'puntos', 'ogr' )   
        dictTmpProperties = self.readStoredSettings( self.layer, u'f1' )    
        
        self.assertFalse( dictTmpProperties['enabled'] )
        
     
    def test08MissingLayerAddedThenEnableAutoField( self ):
        """ AutoField should be enabled if missing layer is added """
        self.msg.show( "Info! Test 8 started", 'info', True )

        # test07 deletes the layer object, so create it again
        self.layer = QgsVectorLayer( self.layerPath, 'puntos', 'ogr' )
        QgsMapLayerRegistry.instance().addMapLayer( self.layer )  
        dictTmpProperties = self.readStoredSettings( self.layer, u'f1' )    
        
        self.assertTrue( dictTmpProperties['enabled'] )
           
        
    def test09RemoveAutoField( self ):
        """ QSettings should be deleted for the removed AutoField """
        self.msg.show( "Info! Test 9 started", 'info', True )

        # test07 deletes the layer object, so create it again
        self.layer = QgsVectorLayer( self.layerPath, 'puntos', 'ogr' )
        autoFieldId = self.autoFieldManager.buildAutoFieldId( self.layer, u'f1')
        self.autoFieldManager.removeAutoField( autoFieldId )
        dictTmpProperties = self.readStoredSettings( self.layer, u'f1' ) 
        
        self.assertEqual( dictTmpProperties, {'layer':"",'field':"",'expression':"",'layer2':"",'field2':"",'enabled':False} )
        

    @classmethod    
    def tearDownClass( self ):   
        self.msg.show( "Info! TearDown started", 'info', True )
    
        # test07 deletes the layer object, so create it again
        self.layer = QgsVectorLayer( self.layerPath, 'puntos', 'ogr' )

        #Remove AutoField modified
        autoFieldId = self.autoFieldManager.buildAutoFieldId( self.layer, u'modified' )
        self.autoFieldManager.removeAutoField( autoFieldId )

        #Delete field f1
        fieldIndex = self.layer.fieldNameIndex('f1')
        self.layer.dataProvider().deleteAttributes( [fieldIndex] )
        self.layer.updateFields()
        
        #Delete features from test layer
        fIds = self.layer.allFeatureIds()
        self.layer.dataProvider().deleteFeatures( fIds )
        
        #Remove layer from Registry
        QgsMapLayerRegistry.instance().removeMapLayer( self.layer.id() )
        self.msg.show( "Info! TearDown finished", 'info', True )

        QgsApplication.exitQgis()
Пример #43
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
Пример #44
0
    def generate_guide_file(self):
        """Generates the guide file, if CheckBPlanned.isChecked then add_to_db
        is called. Finalising with calling on the cleanup function."""
        path = self.path[:self.path.index('tmp_files123')]
        file_name = path + 'guide_file_{f}_{g}.shp'.format(
            f=check_text(self.dlg.CBFieldList.currentText()),
            g=datetime.date(datetime.today()).isoformat())
        if os.path.isfile(file_name):
            msgBox = QMessageBox()
            msgBox.setText(
                self.
                tr('You have already created a guide file for this field today, do you want to replace it?'
                   ))
            msgBox.addButton(QPushButton(self.tr('Yes')), QMessageBox.YesRole)
            msgBox.addButton(QPushButton(self.tr('No')), QMessageBox.NoRole)
            res = msgBox.exec_()
            if res == 1:
                return
            try:
                for ending in ['dbf', 'prj', 'shp', 'shx']:
                    os.remove(file_name[:-3] + ending)
            except PermissionError:
                QMessageBox.information(
                    None, self.tr('Error'),
                    self.
                    tr('The file could not automatically be removed, please try to do it manually and create the guide file again'
                       ))
                return
        params = {
            'INPUT': self.path + "raster_output.tif",
            'BAND': 1,
            'OUTPUT': file_name,
            'FIELD': 'indexValue'
        }
        alg_name = 'gdal:polygonize'
        try:
            processing.run(alg_name, params)
            vl = QgsVectorLayer(file_name, 'ferti_layert', 'ogr')
            vl.startEditing()
            ferti_field = QgsField('Fertilizin', QVariant.Int)
            vl.dataProvider().addAttributes([ferti_field])
            vl.updateFields()
            idx = vl.dataProvider().fieldNameIndex('Fertilizin')

            for f in vl.getFeatures():
                val = f.attributes()[0]
                if type(val) is not int:
                    break
                ferti = int(np.interp(val, self.x_values, self.y_values))
                vl.changeAttributeValue(f.id(), idx, ferti)
            vl.commitChanges()
            del vl
            self.file_name = file_name
            if self.dlg.CheckBPlanned.isChecked():
                self.add_to_db()
            self.cleanup()
        except QgsProcessingException:
            QMessageBox.information(
                None, self.tr("Error:"),
                self.
                tr('Currently QGIS does not allow you to have any non English '
                   'character in the directory path or filename'))
            return
Пример #45
0
def add_geojson_features(geojson,
                         project,
                         qgis_layer_id=None,
                         connection_id=None,
                         new_layer_name=None,
                         name=None,
                         style=None):
    """Add geojson features to a destination layer, the layer can be specified
    by passing a QgsVectorLayer instance or by specifying a connection and
    a new layer name plus the QDjango project for the new layer.

    The connection may assume the special values `__shapefile__`, `__spatialite__` or `__geopackage__`
    for the creation of new OGR files of the corresponding type.

    The creation of the new layer may raise an exception is a layer with the same name as
    new_layer_name already exists. For already existing layers the `qgis_layer_id` can be used,
    provided that the layer belongs to the current `project`.

    Returns the qgis_layer_id

    :param geojson: new features in GeoJSON format
    :type geojson: str
    :param project: QDjango Project instance for the new or the existing layer
    :type project: Project instance
    :param layer_id: optional, QGIS layer id
    :type layer_id: QGIS layer id
    :param connection: optional, connection id or the special value `__shapefile__`, `__spatialite__` or `__geopackage__`
    :type connection: str
    :param new_layer_name: optional, name of the new layer
    :type new_layer_name: str
    :param name: optional, name of the isochrone, default to current datetime
    :type name: str
    :param style: optional, dictionary with style properties: example {'color': [100, 50, 123], 'transparency': 0.5, 'stroke_width: 3 }
    :type style: dict
    :raises Exception: raise on error
    :rtype: str
    """

    # Additional fields that are not returned by the service as feature attributes
    json_data = json.loads(geojson)

    if name is None:
        name = "Isochrone %s" % QDateTime.currentDateTime().toString(
            Qt.ISODateWithMs)

    metadata = {
        'range_type': json_data['metadata']['query']['range_type'],
        'name': name,
        # 'timestamp': json_data['metadata']['timestamp'],  // Not supported
    }

    for f in json_data['features']:
        f['properties'].update(metadata)

    geojson = json.dumps(json_data)

    fields = QgsJsonUtils.stringToFields(geojson)

    # Patch timestamp type to DateTime // Not supported
    # fields.remove(fields.lookupField('timestamp'))
    #fields.append(QgsField('timestamp', QVariant.DateTime))

    # Create the new layer
    if connection_id is not None:

        def _write_to_ogr(destination_path, new_layer_name, driverName=None):
            """Writes features to new or existing OGR layer"""

            tmp_dir = QTemporaryDir()
            tmp_path = os.path.join(tmp_dir.path(), 'isochrone.json')
            with open(tmp_path, 'w+') as f:
                f.write(geojson)

            tmp_layer = QgsVectorLayer(tmp_path, 'tmp_isochrone', 'ogr')

            if not tmp_layer.isValid():
                raise Exception(
                    _('Cannot create temporary layer for isochrone result.'))

            # Note: shp attribute names are max 10 chars long
            save_options = QgsVectorFileWriter.SaveVectorOptions()
            if driverName is not None:
                save_options.driverName = driverName
            save_options.layerName = new_layer_name
            save_options.fileEncoding = 'utf-8'

            # This is nonsense to me: if the file does not exist the actionOnExistingFile
            # should be ignored instead of raising an error, probable QGIS bug
            if os.path.exists(destination_path):
                # Check if the layer already exists
                layer_exists = QgsVectorFileWriter.targetLayerExists(
                    destination_path, new_layer_name)

                if layer_exists:
                    raise Exception(
                        _('Cannot save isochrone result to destination layer: layer already exists (use "qgis_layer_id" instead)!'
                          ))

                save_options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer

            error_code, error_message = QgsVectorFileWriter.writeAsVectorFormatV2(
                tmp_layer, destination_path,
                project.qgis_project.transformContext(), save_options)

            if error_code != QgsVectorFileWriter.NoError:
                raise Exception(
                    _('Cannot save isochrone result to destination layer: ') +
                    error_message)

            layer_uri = destination_path

            if driverName != 'ESRI Shapefile':
                layer_uri += '|layername=' + new_layer_name

            provider = 'ogr'
            return layer_uri, provider

        destination_path = None

        if connection_id == '__shapefile__':  # new shapefile
            driverName = 'ESRI Shapefile'
            extension = 'shp'
        elif connection_id == '__spatialite__':  # new sqlite
            driverName = 'SpatiaLite'
            extension = 'sqlite'
        elif connection_id == '__geopackage__':  # new gpkg
            driverName = 'GPKG'
            extension = 'gpkg'
        else:  # Add new table to an existing DB connection

            try:
                connection = get_db_connections(
                    project.qgis_project)[connection_id]
            except:
                raise Exception(_('Wrong connection id.'))

            if connection['provider'] == 'ogr':
                destination_path = connection_id
                driverName = 'GPKG' if destination_path.lower().endswith(
                    '.gpkg') else 'SpatiaLite'
            else:
                driverName = None

        # Create a new file/layer
        if driverName is not None:
            new_layer_name = os.path.basename(new_layer_name)

            if destination_path is None:  # new files!
                destination_path = os.path.join(
                    settings.DATASOURCE_PATH,
                    "{}.{}".format(new_layer_name, extension))
                i = 0
                while os.path.exists(destination_path):
                    i += 1
                    destination_path = os.path.join(
                        settings.DATASOURCE_PATH,
                        "{}_{}.{}".format(new_layer_name, i, extension))

            layer_uri, provider = _write_to_ogr(destination_path,
                                                new_layer_name, driverName)

        # Create a new DB table
        else:
            assert connection['provider'] != 'ogr'
            md = QgsProviderRegistry.instance().providerMetadata(
                connection['provider'])
            if not md:
                raise Exception(
                    _('Error creating destination layer connection.'))
            conn = md.createConnection(connection_id, {})
            try:
                conn.createVectorTable(connection['schema'], new_layer_name,
                                       fields, QgsWkbTypes.Polygon,
                                       QgsCoordinateReferenceSystem(4326),
                                       False, {'geometryColumn': 'geom'})
            except QgsProviderConnectionException as ex:
                raise Exception(
                    _('Error creating destination layer: ') + str(ex))

            uri = QgsDataSourceUri(conn.uri())
            uri.setTable(new_layer_name)
            uri.setSchema(connection['schema'])
            uri.setSrid('4326')
            uri.setGeometryColumn('geom')
            provider = connection['provider']
            layer_uri = uri.uri()

        # Now reload the new layer and add it to the project
        qgis_layer = QgsVectorLayer(layer_uri, new_layer_name, provider)
        if not qgis_layer.isValid():
            raise Exception(
                _('Error creating destination layer: layer is not valid!'))

        qgis_layer_id = qgis_layer.id()

        with QgisProjectFileLocker(project) as project:
            apply_style(qgis_layer, style, True, name)
            project.qgis_project.addMapLayers([qgis_layer])
            root = project.qgis_project.layerTreeRoot()
            if qgis_layer_id not in root.findLayerIds():
                # Append layer at the end
                root.insertLayer(-1, qgis_layer)
            if not project.update_qgis_project():
                raise Exception(
                    _('Error saving the destination layer: could not write project!'
                      ))

        # Retrieve the layer again because saving the project deleted it
        qgis_layer = project.qgis_project.mapLayer(qgis_layer_id)

        # Create Layer object
        instance, created = Layer.objects.get_or_create(
            qgs_layer_id=qgis_layer_id,
            project=project,
            defaults={
                'origname':
                new_layer_name,
                'name':
                new_layer_name,
                'title':
                new_layer_name,
                'is_visible':
                True,
                'layer_type':
                provider,
                'srid':
                4326,
                'datasource':
                layer_uri,
                'geometrytype':
                'Polygon',
                # TODO: make this a property of the Layer object
                'database_columns':
                str([{
                    'name': f.name(),
                    'type': QVariant.typeToName(f.type()).upper(),
                    'label': f.displayName()
                } for f in qgis_layer.fields()]),
            })

        if not created:
            raise Exception(
                _('Error adding destination Layer to the project: layer already exists.'
                  ))

        # for OGR (already filled with features) returns the id of the new layer
        if driverName is not None:
            return qgis_layer_id

    # Append to an existing layer
    qgis_layer = project.qgis_project.mapLayer(qgis_layer_id)
    if qgis_layer is None:
        raise Exception(
            _('Error opening destination layer %s: layer not found in QGIS project!'
              % qgis_layer_id))

    features = QgsJsonUtils.stringToFeatureList(geojson, fields)

    compatible_features = []
    for f in features:
        compatible_features.extend(
            QgsVectorLayerUtils.makeFeatureCompatible(f, qgis_layer))

    if qgis_layer.crs().isValid(
    ) and qgis_layer.crs() != QgsCoordinateReferenceSystem(4326):
        ct = QgsCoordinateTransform(QgsCoordinateReferenceSystem(4326),
                                    qgis_layer.crs(), project.qgis_project)
        for f in compatible_features:
            geom = f.geometry()
            if geom.transform(ct) != QgsGeometry.Success:
                raise Exception(
                    _('Error transforming geometry from 4326 to destination layer CRS.'
                      ))
            f.setGeometry(geom)

    if len(compatible_features) == 0:
        raise Exception(_('No compatible features returned from isochrone.'))

    if not qgis_layer.startEditing():
        raise Exception(_('Destination layer is not editable.'))

    # Add features to the layer
    if not qgis_layer.addFeatures(compatible_features):
        raise Exception(_('Error adding features to the destination layer.'))

    if not qgis_layer.commitChanges():
        raise Exception(
            _('Error committing features to the destination layer.'))

    if style is not None:
        with QgisProjectFileLocker(project) as project:
            apply_style(qgis_layer, style, False, name)
            project.update_qgis_project()

    return qgis_layer_id
Пример #46
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_()
Пример #47
0
def points_along_line(layerout,
                      startpoint,
                      endpoint,
                      distance,
                      label,
                      layer,
                      selected_only=True,
                      force=False,
                      fo_fila=False,
                      divide=0,
                      decimal=2):
    """Adding Points along the line
    """

    crs = layer.crs().authid()

    # TODO check for virtual or shapelayer and set virt_layer according to it
    shape = False
    if shape:
        # define fields for feature attributes. A list of QgsField objects is needed
        fields = [
            QgsField("first", QVariant.Int),
            QgsField("second", QVariant.String)
        ]
        # create an instance of vector file writer, which will create the vector file.
        # Arguments:
        # 1. path to new file (will fail if exists already)
        # 2. encoding of the attributes
        # 3. field map
        # 4. geometry type - from WKBTYPE enum
        # 5. layer's spatial reference (instance of
        #    QgsCoordinateReferenceSystem) - optional
        # 6. driver name for the output file
        writer = QgsVectorFileWriter("my_shapes.shp", "CP1250", fields,
                                     Qgis.WKBPoint, crs, "ESRI Shapefile")
        if writer.hasError() != QgsVectorFileWriter.NoError:
            # fix_print_with_import
            print("Error when creating shapefile: ", writer.hasError())
        # add a feature
        fet = QgsFeature()
        fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(10, 10)))
        fet.setAttributes([1, "text"])
        writer.addFeature(fet)
        # delete the writer to flush features to disk (optional)
        del writer

        layer_type = "Shapefile"  # TODO Add Shapefile functionality here
    else:
        layer_type = "memory"

    virt_layer = QgsVectorLayer("Point?crs=%s" % crs, layerout, layer_type)
    provider = virt_layer.dataProvider()
    virt_layer.startEditing()  # actually writes attributes

    units = layer.crs().mapUnits()

    unitname = QgsUnitTypes.toString(units)
    provider.addAttributes([
        QgsField("fid", QVariant.Int),
        QgsField("cng" + unitname, QVariant.Double)
    ])

    def get_features():
        """Getting the features
        """
        if selected_only:
            return layer.selectedFeatures()
        else:
            return layer.getFeatures()

    # Loop through all (selected) features
    for feature in get_features():
        geom = feature.geometry()
        # Add feature ID of selected feature
        fid = feature.id()
        if not geom:
            QgsMessageLog.logMessage("No geometry", "QChainage")
            continue

        features = create_points_at(startpoint, endpoint, distance, geom, fid,
                                    force, fo_fila, divide)
        provider.addFeatures(features)
        virt_layer.updateExtents()

    proj = QgsProject.instance()
    proj.addMapLayers([virt_layer])
    virt_layer.commitChanges()
    virt_layer.reload()

    # generic labeling properties
    if label:
        virt_layer.setCustomProperty("labeling", "pal")
        virt_layer.setCustomProperty("labeling/enabled", "true")
        virt_layer.setCustomProperty("labeling/fieldName", "cng")
        virt_layer.setCustomProperty("labeling/fontSize", "10")
        virt_layer.setCustomProperty("labeling/multiLineLabels", "true")
        virt_layer.setCustomProperty("labeling/formatNumbers", "true")
        virt_layer.setCustomProperty("labeling/decimals", decimal)
        virt_layer.setCustomProperty("labeling/Size", "5")
    # symbol = QgsMarkerSymbol.createSimple({"name": "capital"})
    # virt_layer.setRenderer(QgsSingleSymbolRenderer(symbol))
    virt_layer.triggerRepaint()
    return
Пример #48
0
    def create_path_with_scratch_layer(self, path_links):
        # Create TSP route
        crs = self.link_layer.dataProvider().crs().authid()
        vl = QgsVectorLayer(f"LineString?crs={crs}", 'TSP Solution', "memory")
        pr = vl.dataProvider()

        # add fields
        pr.addAttributes(self.link_layer.dataProvider().fields())
        vl.updateFields(
        )  # tell the vector layer to fetch changes from the provider

        idx = self.link_layer.dataProvider().fieldNameIndex('link_id')
        self.link_features = {}
        for feat in self.link_layer.getFeatures():
            link_id = feat.attributes()[idx]
            self.link_features[link_id] = feat

        # add a feature
        all_links = []
        for k in path_links:
            fet = self.link_features[k]
            all_links.append(fet)

        # add all links to the temp layer
        pr.addFeatures(all_links)

        # add layer to the map
        QgsProject.instance().addMapLayer(vl)

        symbol = vl.renderer().symbol()
        symbol.setWidth(1.6)
        qgis.utils.iface.mapCanvas().refresh()

        # Create TSP stops
        crs = self.node_layer.dataProvider().crs().authid()
        nl = QgsVectorLayer(f"Point?crs={crs}", 'TSP Stops', "memory")
        pn = nl.dataProvider()

        # add fields
        pn.addAttributes(self.node_layer.dataProvider().fields())
        nl.updateFields(
        )  # tell the vector layer to fetch changes from the provider

        idx = self.node_layer.dataProvider().fieldNameIndex('node_id')
        self.node_features = {}
        for feat in self.node_layer.getFeatures():
            node_id = feat.attributes()[idx]
            self.node_features[node_id] = feat

        # add the feature
        stop_nodes = []
        seq = {}
        for i, k in enumerate(self.worker_thread.node_sequence[:-1]):
            fet = self.node_features[k]
            stop_nodes.append(fet)
            seq[k] = i + 1

        # add all links to the temp layer
        pn.addFeatures(stop_nodes)

        # Goes back and adds the order of visitation for each node
        pn.addAttributes([QgsField('sequence', QVariant.Int)])
        nl.updateFields()
        sdx = nl.dataProvider().fieldNameIndex('sequence')

        nl.startEditing()
        for feat in nl.getFeatures():
            node_id = feat.attributes()[idx]
            nl.changeAttributeValue(feat.id(), sdx, seq[node_id])

        nl.commitChanges()

        # add layer to the map
        QgsProject.instance().addMapLayer(nl)
        symbol = QgsMarkerSymbol.createSimple({'name': 'star', 'color': 'red'})
        symbol.setSize(6)
        nl.renderer().setSymbol(symbol)

        qgis.utils.iface.mapCanvas().refresh()
Пример #49
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')
Пример #50
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()))
Пример #51
0
class PointLayerImportWorker(QObject):

    finished = pyqtSignal(QgsVectorLayer, QgsVectorLayer)
    interrupted = pyqtSignal(QgsVectorLayer, QgsVectorLayer)
    progressed = pyqtSignal(bool, int)

    def __init__(self,
                 uldk_api,
                 source_layer,
                 selected_only,
                 layer_name,
                 skip_duplicates,
                 additional_output_fields=[]):
        super().__init__()
        self.source_layer = source_layer
        self.uldk_api = uldk_api
        self.selected_only = selected_only
        self.skip_duplicates = skip_duplicates
        self.additional_output_fields = additional_output_fields

        self.layer_found = QgsVectorLayer(f"Polygon?crs=EPSG:{2180}",
                                          layer_name, "memory")
        self.layer_found.setCustomProperty("ULDK",
                                           f"{layer_name} point_import_found")

        self.layer_not_found = QgsVectorLayer(f"Point?crs=EPSG:{2180}",
                                              f"{layer_name} (nieznalezione)",
                                              "memory")
        self.layer_not_found.setCustomProperty(
            "ULDK", f"{layer_name} point_import_not_found")

    @pyqtSlot()
    def search(self):
        plots_found = []
        features_not_found = []

        fields = PLOTS_LAYER_DEFAULT_FIELDS + self.additional_output_fields

        self.layer_found.startEditing()
        self.layer_found.dataProvider().addAttributes(fields)

        self.layer_not_found.startEditing()
        self.layer_not_found.dataProvider().addAttributes([
            QgsField("tresc_bledu", QVariant.String),
        ])

        features = []
        features_iterator = self.source_layer.getSelectedFeatures(
        ) if self.selected_only else self.source_layer.getFeatures()
        source_crs = self.source_layer.sourceCrs()
        if source_crs != CRS_2180:
            transformation = (QgsCoordinateTransform(
                source_crs, CRS_2180, QgsCoordinateTransformContext()))
            for f in features_iterator:
                point = f.geometry().asPoint()
                point = transformation.transform(point)
                f.setGeometry(QgsGeometry.fromPointXY(point))
                features.append(f)
        else:
            transformation = None
            features = features_iterator

        uldk_search = self.uldk_api.ULDKSearchPoint(
            "dzialka", ("geom_wkt", "wojewodztwo", "powiat", "gmina", "obreb",
                        "numer", "teryt"))

        found_features = []

        for source_feature in features:
            if QThread.currentThread().isInterruptionRequested():
                self.__commit()
                self.interrupted.emit(self.layer_found, self.layer_not_found)
                return

            skip = False
            for found_feature in found_features:
                if found_feature.geometry().intersects(
                        source_feature.geometry()):
                    if not self.skip_duplicates:
                        self.layer_found.dataProvider().addFeature(
                            found_feature)
                    skip = True
            if skip:
                self.progressed.emit(True, 1 if self.skip_duplicates else 0)
                continue

            point = source_feature.geometry().asPoint()
            uldk_point = self.uldk_api.ULDKPoint(point.x(), point.y(), 2180)

            try:
                uldk_response_row = uldk_search.search(uldk_point)
                additional_attributes = []
                for field in self.additional_output_fields:
                    additional_attributes.append(source_feature[field.name()])
                found_feature = uldk_response_to_qgs_feature(
                    uldk_response_row, additional_attributes)
                found_features.append(found_feature)
                self.layer_found.dataProvider().addFeature(found_feature)
                self.progressed.emit(True, 0)
            except Exception as e:
                not_found_feature = self.__make_not_found_feature(
                    source_feature.geometry(), e)
                self.layer_not_found.dataProvider().addFeature(
                    not_found_feature)
                self.progressed.emit(False, 0)

        self.__commit()
        self.finished.emit(self.layer_found, self.layer_not_found)

    def __make_not_found_feature(self, geometry, e):
        error_message = str(e)
        feature = QgsFeature()
        feature.setGeometry(geometry)
        feature.setAttributes([error_message])

        return feature

    def __commit(self):
        self.layer_found.commitChanges()
        self.layer_not_found.commitChanges()
Пример #52
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())
Пример #53
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")
Пример #54
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)
Пример #55
0
        def _test(autoTransaction):
            """Test buffer methods within and without transactions

            - create a feature
            - save
            - retrieve the feature
            - change geom and attrs
            - test changes are seen in the buffer
            """
            def _check_feature(wkt):

                f = next(layer_a.getFeatures())
                self.assertEqual(f.geometry().asWkt().upper(), wkt)
                f = list(buffer.addedFeatures().values())[0]
                self.assertEqual(f.geometry().asWkt().upper(), wkt)

            ml = QgsVectorLayer(
                'Point?crs=epsg:4326&field=int:integer&field=int2:integer',
                'test', 'memory')
            self.assertTrue(ml.isValid())

            d = QTemporaryDir()
            options = QgsVectorFileWriter.SaveVectorOptions()
            options.driverName = 'GPKG'
            options.layerName = 'layer_a'
            err, msg, newFileName, newLayer = QgsVectorFileWriter.writeAsVectorFormatV3(
                ml, os.path.join(d.path(), 'transaction_test.gpkg'),
                QgsCoordinateTransformContext(), options)

            self.assertEqual(err, QgsVectorFileWriter.NoError)
            self.assertTrue(os.path.isfile(newFileName))

            layer_a = QgsVectorLayer(newFileName + '|layername=layer_a')

            self.assertTrue(layer_a.isValid())

            project = QgsProject()
            project.setAutoTransaction(autoTransaction)
            project.addMapLayers([layer_a])

            ###########################################
            # Tests with a new feature

            self.assertTrue(layer_a.startEditing())
            buffer = layer_a.editBuffer()

            f = QgsFeature(layer_a.fields())
            f.setAttribute('int', 123)
            f.setGeometry(QgsGeometry.fromWkt('point(7 45)'))
            self.assertTrue(layer_a.addFeatures([f]))

            _check_feature('POINT (7 45)')

            # Need to fetch the feature because its ID is NULL (-9223372036854775808)
            f = next(layer_a.getFeatures())

            self.assertEqual(len(buffer.addedFeatures()), 1)
            layer_a.undoStack().undo()
            self.assertEqual(len(buffer.addedFeatures()), 0)
            layer_a.undoStack().redo()
            self.assertEqual(len(buffer.addedFeatures()), 1)
            f = list(buffer.addedFeatures().values())[0]
            self.assertEqual(f.attribute('int'), 123)

            # Now change attribute
            self.assertEqual(buffer.changedAttributeValues(), {})
            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.changeAttributeValue(f.id(), 1, 321)
            self.assertEqual(len(spy_attribute_changed), 1)
            self.assertEqual(spy_attribute_changed[0], [f.id(), 1, 321])

            self.assertEqual(len(buffer.addedFeatures()), 1)
            # This is surprising: because it was a new feature it has been changed directly
            self.assertEqual(buffer.changedAttributeValues(), {})
            f = list(buffer.addedFeatures().values())[0]
            self.assertEqual(f.attribute('int'), 321)

            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.undoStack().undo()
            self.assertEqual(len(spy_attribute_changed), 1)
            self.assertEqual(spy_attribute_changed[0], [f.id(), 1, 123])
            self.assertEqual(buffer.changedAttributeValues(), {})
            f = list(buffer.addedFeatures().values())[0]
            self.assertEqual(f.attribute('int'), 123)
            f = next(layer_a.getFeatures())
            self.assertEqual(f.attribute('int'), 123)

            # Change multiple attributes
            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.changeAttributeValues(f.id(), {1: 321, 2: 456})
            self.assertEqual(len(spy_attribute_changed), 2)
            self.assertEqual(spy_attribute_changed[0], [f.id(), 1, 321])
            self.assertEqual(spy_attribute_changed[1], [f.id(), 2, 456])
            buffer = layer_a.editBuffer()
            # This is surprising: because it was a new feature it has been changed directly
            self.assertEqual(buffer.changedAttributeValues(), {})

            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.undoStack().undo()
            # This is because QgsVectorLayerUndoCommandChangeAttribute plural
            if not autoTransaction:
                layer_a.undoStack().undo()
            f = next(layer_a.getFeatures())
            self.assertEqual(f.attribute('int'), 123)
            self.assertEqual(f.attribute('int2'), None)
            self.assertEqual(len(spy_attribute_changed), 2)
            self.assertEqual(
                spy_attribute_changed[1 if autoTransaction else 0],
                [f.id(), 2, None])
            self.assertEqual(
                spy_attribute_changed[0 if autoTransaction else 1],
                [f.id(), 1, 123])

            # Change geometry
            f = next(layer_a.getFeatures())
            spy_geometry_changed = QSignalSpy(layer_a.geometryChanged)
            self.assertTrue(
                layer_a.changeGeometry(f.id(),
                                       QgsGeometry.fromWkt('point(9 43)')))
            self.assertTrue(len(spy_geometry_changed), 1)
            self.assertEqual(spy_geometry_changed[0][0], f.id())
            self.assertEqual(spy_geometry_changed[0][1].asWkt(),
                             QgsGeometry.fromWkt('point(9 43)').asWkt())

            _check_feature('POINT (9 43)')
            self.assertEqual(buffer.changedGeometries(), {})

            layer_a.undoStack().undo()

            _check_feature('POINT (7 45)')
            self.assertEqual(buffer.changedGeometries(), {})

            self.assertTrue(
                layer_a.changeGeometry(f.id(),
                                       QgsGeometry.fromWkt('point(9 43)')))
            _check_feature('POINT (9 43)')

            self.assertTrue(
                layer_a.changeGeometry(f.id(),
                                       QgsGeometry.fromWkt('point(10 44)')))
            _check_feature('POINT (10 44)')

            # This is another surprise: geometry edits get collapsed into a single
            # one because they have the same hardcoded id
            layer_a.undoStack().undo()
            _check_feature('POINT (7 45)')

            self.assertTrue(layer_a.commitChanges())

            ###########################################
            # Tests with the existing feature

            # Get the feature
            f = next(layer_a.getFeatures())
            self.assertTrue(f.isValid())
            self.assertEqual(f.attribute('int'), 123)
            self.assertEqual(f.geometry().asWkt().upper(), 'POINT (7 45)')

            # Change single attribute
            self.assertTrue(layer_a.startEditing())
            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.changeAttributeValue(f.id(), 1, 321)
            self.assertEqual(len(spy_attribute_changed), 1)
            self.assertEqual(spy_attribute_changed[0], [f.id(), 1, 321])
            buffer = layer_a.editBuffer()
            self.assertEqual(buffer.changedAttributeValues(), {1: {1: 321}})

            f = next(layer_a.getFeatures())
            self.assertEqual(f.attribute(1), 321)

            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.undoStack().undo()
            f = next(layer_a.getFeatures())
            self.assertEqual(f.attribute(1), 123)
            self.assertEqual(len(spy_attribute_changed), 1)
            self.assertEqual(spy_attribute_changed[0], [f.id(), 1, 123])
            self.assertEqual(buffer.changedAttributeValues(), {})

            # Change attributes
            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.changeAttributeValues(f.id(), {1: 111, 2: 654})
            self.assertEqual(len(spy_attribute_changed), 2)
            self.assertEqual(spy_attribute_changed[0], [1, 1, 111])
            self.assertEqual(spy_attribute_changed[1], [1, 2, 654])
            f = next(layer_a.getFeatures())
            self.assertEqual(f.attributes(), [1, 111, 654])
            self.assertEqual(buffer.changedAttributeValues(),
                             {1: {
                                 1: 111,
                                 2: 654
                             }})

            spy_attribute_changed = QSignalSpy(layer_a.attributeValueChanged)
            layer_a.undoStack().undo()
            # This is because QgsVectorLayerUndoCommandChangeAttribute plural
            if not autoTransaction:
                layer_a.undoStack().undo()
            self.assertEqual(len(spy_attribute_changed), 2)
            self.assertEqual(
                spy_attribute_changed[0 if autoTransaction else 1],
                [1, 1, 123])
            self.assertEqual(
                spy_attribute_changed[1 if autoTransaction else 0],
                [1, 2, None])
            f = next(layer_a.getFeatures())
            self.assertEqual(f.attributes(), [1, 123, None])
            self.assertEqual(buffer.changedAttributeValues(), {})

            # Change geometry
            spy_geometry_changed = QSignalSpy(layer_a.geometryChanged)
            self.assertTrue(
                layer_a.changeGeometry(f.id(),
                                       QgsGeometry.fromWkt('point(9 43)')))
            self.assertEqual(spy_geometry_changed[0][0], 1)
            self.assertEqual(spy_geometry_changed[0][1].asWkt(),
                             QgsGeometry.fromWkt('point(9 43)').asWkt())

            f = next(layer_a.getFeatures())
            self.assertEqual(f.geometry().asWkt().upper(), 'POINT (9 43)')
            self.assertEqual(buffer.changedGeometries()[1].asWkt().upper(),
                             'POINT (9 43)')

            spy_geometry_changed = QSignalSpy(layer_a.geometryChanged)
            layer_a.undoStack().undo()
            self.assertEqual(spy_geometry_changed[0][0], 1)
            self.assertEqual(spy_geometry_changed[0][1].asWkt(),
                             QgsGeometry.fromWkt('point(7 45)').asWkt())
            self.assertEqual(buffer.changedGeometries(), {})
            f = next(layer_a.getFeatures())

            self.assertEqual(f.geometry().asWkt().upper(), 'POINT (7 45)')
            self.assertEqual(buffer.changedGeometries(), {})

            # Delete an existing feature
            self.assertTrue(layer_a.deleteFeature(f.id()))
            with self.assertRaises(StopIteration):
                next(layer_a.getFeatures())
            self.assertEqual(buffer.deletedFeatureIds(), [f.id()])

            layer_a.undoStack().undo()
            self.assertTrue(layer_a.getFeature(f.id()).isValid())
            self.assertEqual(buffer.deletedFeatureIds(), [])

            ###########################################
            # Test delete

            # Delete a new feature
            f = QgsFeature(layer_a.fields())
            f.setAttribute('int', 555)
            f.setGeometry(QgsGeometry.fromWkt('point(8 46)'))
            self.assertTrue(layer_a.addFeatures([f]))
            f = [
                f for f in layer_a.getFeatures() if f.attribute('int') == 555
            ][0]
            self.assertTrue(f.id() in buffer.addedFeatures())
            self.assertTrue(layer_a.deleteFeature(f.id()))
            self.assertFalse(f.id() in buffer.addedFeatures())
            self.assertFalse(f.id() in buffer.deletedFeatureIds())

            layer_a.undoStack().undo()
            self.assertTrue(f.id() in buffer.addedFeatures())

            ###########################################
            # Add attribute

            field = QgsField('attr1', QVariant.String)
            self.assertTrue(layer_a.addAttribute(field))
            self.assertNotEqual(layer_a.fields().lookupField(field.name()), -1)
            self.assertEqual(buffer.addedAttributes(), [field])

            layer_a.undoStack().undo()
            self.assertEqual(layer_a.fields().lookupField(field.name()), -1)
            self.assertEqual(buffer.addedAttributes(), [])

            layer_a.undoStack().redo()
            self.assertNotEqual(layer_a.fields().lookupField(field.name()), -1)
            self.assertEqual(buffer.addedAttributes(), [field])

            self.assertTrue(layer_a.commitChanges())

            ###########################################
            # Remove attribute

            self.assertTrue(layer_a.startEditing())
            buffer = layer_a.editBuffer()

            attr_idx = layer_a.fields().lookupField(field.name())
            self.assertNotEqual(attr_idx, -1)

            self.assertTrue(layer_a.deleteAttribute(attr_idx))
            self.assertEqual(buffer.deletedAttributeIds(), [attr_idx])
            self.assertEqual(layer_a.fields().lookupField(field.name()), -1)

            layer_a.undoStack().undo()
            self.assertEqual(buffer.deletedAttributeIds(), [])
            self.assertEqual(layer_a.fields().lookupField(field.name()),
                             attr_idx)

            # This is totally broken at least on OGR/GPKG: the rollback
            # does not restore the original fields
            if False:

                layer_a.undoStack().redo()
                self.assertEqual(buffer.deletedAttributeIds(), [attr_idx])
                self.assertEqual(layer_a.fields().lookupField(field.name()),
                                 -1)

                # Rollback!
                self.assertTrue(layer_a.rollBack())

                self.assertIn('attr1', layer_a.dataProvider().fields().names())
                self.assertIn('attr1', layer_a.fields().names())
                self.assertEqual(layer_a.fields().names(),
                                 layer_a.dataProvider().fields().names())

                attr_idx = layer_a.fields().lookupField(field.name())
                self.assertNotEqual(attr_idx, -1)

                self.assertTrue(layer_a.startEditing())
                attr_idx = layer_a.fields().lookupField(field.name())
                self.assertNotEqual(attr_idx, -1)

            ###########################################
            # Rename attribute

            attr_idx = layer_a.fields().lookupField(field.name())
            self.assertEqual(layer_a.fields().lookupField('new_name'), -1)
            self.assertTrue(layer_a.renameAttribute(attr_idx, 'new_name'))
            self.assertEqual(layer_a.fields().lookupField('new_name'),
                             attr_idx)

            layer_a.undoStack().undo()
            self.assertEqual(layer_a.fields().lookupField(field.name()),
                             attr_idx)
            self.assertEqual(layer_a.fields().lookupField('new_name'), -1)

            layer_a.undoStack().redo()
            self.assertEqual(layer_a.fields().lookupField('new_name'),
                             attr_idx)
            self.assertEqual(layer_a.fields().lookupField(field.name()), -1)

            #############################################
            # Try hard to make this fail for transactions
            if autoTransaction:
                self.assertTrue(layer_a.commitChanges())
                self.assertTrue(layer_a.startEditing())
                f = next(layer_a.getFeatures())

                # Do
                for i in range(10):
                    spy_attribute_changed = QSignalSpy(
                        layer_a.attributeValueChanged)
                    layer_a.changeAttributeValue(f.id(), 2, i)
                    self.assertEqual(len(spy_attribute_changed), 1)
                    self.assertEqual(spy_attribute_changed[0], [f.id(), 2, i])
                    buffer = layer_a.editBuffer()
                    self.assertEqual(buffer.changedAttributeValues(),
                                     {f.id(): {
                                          2: i
                                      }})
                    f = next(layer_a.getFeatures())
                    self.assertEqual(f.attribute(2), i)

                # Undo/redo
                for i in range(9):

                    # Undo
                    spy_attribute_changed = QSignalSpy(
                        layer_a.attributeValueChanged)
                    layer_a.undoStack().undo()
                    f = next(layer_a.getFeatures())
                    self.assertEqual(f.attribute(2), 8 - i)
                    self.assertEqual(len(spy_attribute_changed), 1)
                    self.assertEqual(spy_attribute_changed[0],
                                     [f.id(), 2, 8 - i])
                    buffer = layer_a.editBuffer()
                    self.assertEqual(buffer.changedAttributeValues(),
                                     {f.id(): {
                                          2: 8 - i
                                      }})

                    # Redo
                    spy_attribute_changed = QSignalSpy(
                        layer_a.attributeValueChanged)
                    layer_a.undoStack().redo()
                    f = next(layer_a.getFeatures())
                    self.assertEqual(f.attribute(2), 9 - i)
                    self.assertEqual(len(spy_attribute_changed), 1)
                    self.assertEqual(spy_attribute_changed[0],
                                     [f.id(), 2, 9 - i])

                    # Undo again
                    spy_attribute_changed = QSignalSpy(
                        layer_a.attributeValueChanged)
                    layer_a.undoStack().undo()
                    f = next(layer_a.getFeatures())
                    self.assertEqual(f.attribute(2), 8 - i)
                    self.assertEqual(len(spy_attribute_changed), 1)
                    self.assertEqual(spy_attribute_changed[0],
                                     [f.id(), 2, 8 - i])
                    buffer = layer_a.editBuffer()
                    self.assertEqual(buffer.changedAttributeValues(),
                                     {f.id(): {
                                          2: 8 - i
                                      }})

                    # Last check
                    f = next(layer_a.getFeatures())
                    self.assertEqual(f.attribute(2), 8 - i)

                self.assertEqual(buffer.changedAttributeValues(),
                                 {f.id(): {
                                      2: 0
                                  }})
                layer_a.undoStack().undo()
                buffer = layer_a.editBuffer()
                self.assertEqual(buffer.changedAttributeValues(), {})
                f = next(layer_a.getFeatures())
                self.assertEqual(f.attribute(2), None)
Пример #56
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
    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
Пример #58
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))
    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)
Пример #60
0
    def run_blur(self):

        self.progressBar_blur.setValue(0)
        self.label_progress.setText('')

        # Get all the fields.
        layer_to_blur = self.comboBox_layerToBlur.currentLayer()
        radius = self.spinBox_radius.value()
        display = self.checkBox_addToMap.isChecked()
        selected_features_only = self.checkBox_selectedOnlyFeatures.isChecked()
        file_name = self.lineEdit_outputFile.text()
        export_radius = self.checkBox_exportRadius.isChecked()
        export_centroid = self.checkBox_exportCentroid.isChecked()

        if self.checkBox_envelope.isChecked():
            layer_envelope = self.comboBox_envelope.currentLayer()
        else:
            layer_envelope = None

        # Test values
        try:
            if not layer_to_blur:
                raise NoLayerProvidedException

            if not file_name and not display:
                raise NoFileNoDisplayException

            if layer_to_blur.crs().mapUnits() != 0:
                msg = tr('The projection of the map or of the layer is not '
                         'in meters. These parameters should be in meters.')
                display_message_bar(msg,
                                    level=QgsMessageBar.WARNING,
                                    duration=5)

            if not file_name:
                file_name = getTempFilenameInTempFolder('blurring.shp')

            if layer_envelope:

                if layer_to_blur.crs() != layer_envelope.crs():
                    raise DifferentCrsException(
                        epsg1=layer_to_blur.crs().authid(),
                        epsg2=layer_envelope.crs().authid())

                self.label_progress.setText('Creating index ...')
                layer_envelope = LayerIndex(layer_envelope)
                self.progressBar_blur.setValue(0)

            self.label_progress.setText('Blurring ...')

            if selected_features_only:
                features = layer_to_blur.selectedFeatures()
                nb_features = layer_to_blur.selectedFeatureCount()
            else:
                features = layer_to_blur.getFeatures()
                nb_features = layer_to_blur.featureCount()

            # Fields
            fields = layer_to_blur.pendingFields()
            if export_radius:
                fields.append(QgsField(u"Radius", QVariant.Int))
            if export_centroid:
                fields.append(QgsField(u"X centroid", QVariant.Int))
                fields.append(QgsField(u"Y centroid", QVariant.Int))

            # Creating the output shapefile
            file_writer = QgsVectorFileWriter(file_name, 'utf-8', fields,
                                              QGis.WKBPolygon,
                                              layer_to_blur.crs(),
                                              'ESRI Shapefile')

            if file_writer.hasError() != QgsVectorFileWriter.NoError:
                raise CreatingShapeFileException(suffix=file_writer.hasError())

            # Creating the algorithm with radius
            algo = Blur(radius, layer_envelope, export_radius, export_centroid)

            for j, feature in enumerate(features):
                feature = algo.blur(feature)
                file_writer.addFeature(feature)

                # Update progress bar
                percent = int((j + 1) * 100 / nb_features)
                self.progressBar_blur.setValue(percent)

            # Write all features in the file
            del file_writer

            if display:
                old_default_projection = self.settings.value(
                    '/Projections/defaultBehaviour')
                self.settings.setValue('/Projections/defaultBehaviour',
                                       'useProject')

                layer_name = basename(file_name)
                new_layer = QgsVectorLayer(file_name, layer_name, 'ogr')
                new_layer.commitChanges()
                new_layer.clearCacheImage()
                # noinspection PyArgumentList
                QgsMapLayerRegistry.instance().addMapLayers([new_layer])

                self.settings.setValue('/Projections/defaultBehaviour',
                                       old_default_projection)

            msg = tr('Successful export in %s' % file_name)
            iface.messageBar().pushMessage(msg,
                                           level=QgsMessageBar.INFO,
                                           duration=5)

            self.signalAskCloseWindow.emit()

        except GeoHealthException, e:
            self.label_progress.setText('')
            display_message_bar(msg=e.msg, level=e.level, duration=e.duration)