Example #1
0
def revertFeatures(fname,actions,layername):
    layerDeletes = QgsVectorLayer(fname+"|layername=geogig_deleted_rows")
    request = QgsFeatureRequest()
    request.setFilterFids(actions["addDeleted"])
    featuresToInsert1 = list(layerDeletes.getFeatures(request))
    sip.delete(layerDeletes)
    del layerDeletes


    layerUpdates = QgsVectorLayer(fname + "|layername=geogig_updated_rows_orig")
    request = QgsFeatureRequest()
    request.setFilterFids(actions["addUpdated"])
    featuresToInsert2 = list(layerUpdates.getFeatures(request))
    sip.delete(layerUpdates)
    del layerUpdates

    # do delete
    layer = QgsVectorLayer(fname + "|layername="+layername)
    provider = layer.dataProvider()

    r=provider.deleteFeatures(actions["delete"])
    r=provider.addFeatures(featuresToInsert1)
    r=provider.addFeatures(featuresToInsert2)

    sip.delete(layer)
    del layer
Example #2
0
    def test_sql2(self):
        l2 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"),
                            "france_parts", "ogr", False)
        self.assertEqual(l2.isValid(), True)
        QgsMapLayerRegistry.instance().addMapLayer(l2)

        query = toPercent("SELECT * FROM france_parts")
        l4 = QgsVectorLayer("?query=%s" % query, "tt", "virtual")
        self.assertEqual(l4.isValid(), True)

        self.assertEqual(l4.dataProvider().wkbType(), 3)
        self.assertEqual(l4.dataProvider().crs().postgisSrid(), 4326)

        n = 0
        r = QgsFeatureRequest(QgsRectangle(-1.677, 49.624, -0.816, 49.086))
        for f in l4.getFeatures(r):
            self.assertEqual(f.geometry() is not None, True)
            self.assertEqual(f.attributes()[0], 2661)
            n += 1
        self.assertEqual(n, 1)

        # use uid
        query = toPercent("SELECT * FROM france_parts")
        l5 = QgsVectorLayer(
            "?query=%s&geometry=geometry:polygon:4326&uid=ObjectId" % query,
            "tt", "virtual")
        self.assertEqual(l5.isValid(), True)

        idSum = sum(f.id() for f in l5.getFeatures())
        self.assertEqual(idSum, 10659)

        r = QgsFeatureRequest(2661)
        idSum2 = sum(f.id() for f in l5.getFeatures(r))
        self.assertEqual(idSum2, 2661)

        r = QgsFeatureRequest()
        r.setFilterFids([2661, 2664])
        self.assertEqual(sum(f.id() for f in l5.getFeatures(r)), 2661 + 2664)

        # test attribute subset
        r = QgsFeatureRequest()
        r.setFlags(QgsFeatureRequest.SubsetOfAttributes)
        r.setSubsetOfAttributes([1])
        s = [(f.id(), f.attributes()[1]) for f in l5.getFeatures(r)]
        self.assertEqual(sum([x[0] for x in s]), 10659)
        self.assertEqual(sum([x[1] for x in s]), 3064.0)

        # test NoGeometry
        # by request flag
        r = QgsFeatureRequest()
        r.setFlags(QgsFeatureRequest.NoGeometry)
        self.assertEqual(all([not f.hasGeometry() for f in l5.getFeatures(r)]),
                         True)

        # test subset
        self.assertEqual(l5.dataProvider().featureCount(), 4)
        l5.setSubsetString("ObjectId = 2661")
        idSum2 = sum(f.id() for f in l5.getFeatures(r))
        self.assertEqual(idSum2, 2661)
        self.assertEqual(l5.dataProvider().featureCount(), 1)
Example #3
0
    def get_nearest_point_name(self, point):

        # Check for projection
        c_proj = self.iface.mapCanvas().mapSettings().destinationCrs().authid()
        if c_proj not in self.allowed_projections:
            raise Exception(
                f'Your canvas projection {c_proj} is not allowed with plugin pub-tools;\
                 allowed projections: {self.allowed_projections}')
        elif c_proj == "EPSG:4326":
            point = QgsPoint(point)
            point.transform(self.pj_transformer)
            point = QgsPointXY(point)

        nearest_id = self.index.nearestNeighbor(point, 1)

        request = QgsFeatureRequest()
        request.setFilterFids(nearest_id)

        #TODO: Check if vector layer is activated!
        features = self.iface.activeLayer().getFeatures(request)

        # https://qgis.org/pyqgis/master/core/QgsSpatialIndex.html?highlight=spatialindex#module-QgsSpatialIndex
        elem = next(features, False)

        if not elem:
            raise Exception("No pub close")

        #TODO: Check if feature has Name attribute!
        return elem.attribute("Name")
Example #4
0
    def find_start_end_nodes_sindex(params, sindex, link_geom):

        # Find node FIDs that intersect the link bounding box
        bb = link_geom.boundingBox()

        # We grow slighlty the bb to prevent rounding errors: 10% of the link's length
        bb.grow(link_geom.length() * 0.1)
        cand_fids = sindex.intersects(bb)

        request = QgsFeatureRequest()
        request.setFilterFids(cand_fids)

        # Find features that intersect te link bb (from 3 possible layers)
        j_cands = params.junctions_vlay.getFeatures(request)
        r_cands = params.reservoirs_vlay.getFeatures(request)
        t_cands = params.tanks_vlay.getFeatures(request)

        intersecting_fts = [None, None]
        cands = []
        for j_cand in j_cands:
            cands.append(j_cand)
        for r_cand in r_cands:
            cands.append(r_cand)
        for t_cand in t_cands:
            cands.append(t_cand)

        # Check if any candidates are actually start or end nodes
        for node_ft in cands:
            if node_ft.geometry().distance(QgsGeometry.fromPoint(link_geom.asPolyline()[0])) < params.tolerance:
                intersecting_fts[0] = node_ft
            if node_ft.geometry().distance(QgsGeometry.fromPoint(link_geom.asPolyline()[-1])) < params.tolerance:
                intersecting_fts[1] = node_ft

        return intersecting_fts
    def get_new_electorates(self) -> Dict[int, int]:
        """
        Returns a dictionary of pending changes from meshblock number to new electorate id
        """
        assert self.task is not None

        electorate_field_name = '{}_id'.format(self.task)
        electorate_field_idx = self.meshblock_scenario_layer.fields(
        ).lookupField(electorate_field_name)
        assert electorate_field_idx >= 0

        if self.meshblock_layer.editBuffer() is None:
            return {}

        # get list of affected features
        changed_attribute_values = self.meshblock_layer.editBuffer(
        ).changedAttributeValues()

        request = QgsFeatureRequest()
        request.setSubsetOfAttributes([self.meshblock_number_idx])
        request.setFlags(QgsFeatureRequest.NoGeometry)
        request.setFilterFids(list(changed_attribute_values.keys()))
        meshblock_features = {
            f.id(): f
            for f in self.meshblock_layer.getFeatures(request)
        }

        # dict of meshblock number to new electorate
        new_electorates = {}
        for source_id, changes in changed_attribute_values.items():
            new_electorate = changes[self.staged_electorate_idx]
            meshblock_number = int(
                meshblock_features[source_id][self.meshblock_number_idx])
            new_electorates[meshblock_number] = new_electorate
        return new_electorates
Example #6
0
    def testFilterFids(self):
        req = QgsFeatureRequest().setFilterFids([5, 6])
        self.assertEqual(req.filterType(), QgsFeatureRequest.FilterFids)
        self.assertEqual(req.spatialFilterType(),
                         Qgis.SpatialFilterType.NoFilter)
        self.assertEqual(req.filterFid(), -1)
        self.assertCountEqual(req.filterFids(), [5, 6])
        self.assertTrue(req.filterRect().isNull())
        self.assertTrue(req.referenceGeometry().isNull())

        # filter rect doesn't affect fids filter
        req.setFilterRect(QgsRectangle(1, 2, 3, 4))
        self.assertEqual(req.filterType(), QgsFeatureRequest.FilterFids)
        self.assertEqual(req.filterFid(), -1)
        self.assertCountEqual(req.filterFids(), [5, 6])
        self.assertEqual(req.spatialFilterType(),
                         Qgis.SpatialFilterType.BoundingBox)
        self.assertEqual(req.filterRect(), QgsRectangle(1, 2, 3, 4))
        self.assertTrue(req.referenceGeometry().isNull())
        req.setFilterFids([8, 9])
        self.assertEqual(req.filterType(), QgsFeatureRequest.FilterFids)
        self.assertEqual(req.filterFid(), -1)
        self.assertCountEqual(req.filterFids(), [8, 9])
        self.assertEqual(req.spatialFilterType(),
                         Qgis.SpatialFilterType.BoundingBox)
        self.assertEqual(req.filterRect(), QgsRectangle(1, 2, 3, 4))
        self.assertTrue(req.referenceGeometry().isNull())
Example #7
0
def clone_layer(layer, keep_selection=True):
    """Duplicate the layer by taking the same source and copying keywords.

    :param keep_selection: If we should keep the selection. Default to true.
    :type keep_selection: bool

    :param layer: Layer to be duplicated.
    :type layer: QgsMapLayer

    :return: The new QgsMapLayer object.
    :rtype: QgsMapLayer
    """
    if is_vector_layer(layer):
        new_layer = QgsVectorLayer(
            layer.source(), layer.name(), layer.providerType())
        if keep_selection and layer.selectedFeatureCount() > 0:
            request = QgsFeatureRequest()
            request.setFilterFids(layer.selectedFeatureIds())
            request.setFlags(QgsFeatureRequest.NoGeometry)
            iterator = layer.getFeatures(request)
            new_layer.setSelectedFeatures([k.id() for k in iterator])
    else:
        new_layer = QgsRasterLayer(
            layer.source(), layer.name(), layer.providerType())

    new_layer.keywords = copy_layer_keywords(layer.keywords)

    return layer
Example #8
0
def clone_layer(layer, keep_selection=True):
    """Duplicate the layer by taking the same source and copying keywords.

    :param keep_selection: If we should keep the selection. Default to true.
    :type keep_selection: bool

    :param layer: Layer to be duplicated.
    :type layer: QgsMapLayer

    :return: The new QgsMapLayer object.
    :rtype: QgsMapLayer
    """
    if is_vector_layer(layer):
        new_layer = QgsVectorLayer(layer.source(), layer.name(),
                                   layer.providerType())
        if keep_selection and layer.selectedFeatureCount() > 0:
            request = QgsFeatureRequest()
            request.setFilterFids(layer.selectedFeaturesIds())
            request.setFlags(QgsFeatureRequest.NoGeometry)
            iterator = layer.getFeatures(request)
            new_layer.setSelectedFeatures([k.id() for k in iterator])
    else:
        new_layer = QgsRasterLayer(layer.source(), layer.name(),
                                   layer.providerType())

    new_layer.keywords = copy_layer_keywords(layer.keywords)

    return layer
Example #9
0
def copy_layer(source, target):
    """Copy a vector layer to another one.

    :param source: The vector layer to copy.
    :type source: QgsVectorLayer

    :param target: The destination.
    :type source: QgsVectorLayer
    """
    out_feature = QgsFeature()
    target.startEditing()

    request = QgsFeatureRequest()

    if source.keywords.get('layer_purpose') == 'aggregation':
        try:
            use_selected_only = source.use_selected_features_only
        except AttributeError:
            use_selected_only = False

        # We need to check if the user wants selected feature only and if there
        # is one minimum selected.
        if use_selected_only and source.selectedFeatureCount() > 0:
            request.setFilterFids(source.selectedFeaturesIds())

    for i, feature in enumerate(source.getFeatures(request)):
        geom = feature.geometry()
        out_feature.setGeometry(QgsGeometry(geom))
        out_feature.setAttributes(feature.attributes())
        target.addFeature(out_feature)

    target.commitChanges()
Example #10
0
 def explode_multi_parts(self, address=False):
     request = QgsFeatureRequest()
     if address:
         refs = {self.get_id(ad) for ad in address.getFeatures()}
         fids = [
             f.id() for f in self.getFeatures() if f["localId"] not in refs
         ]
         request.setFilterFids(fids)
     super(ConsLayer, self).explode_multi_parts(request)
Example #11
0
    def test_sql2(self):
        l2 = QgsVectorLayer(os.path.join(self.testDataDir, "france_parts.shp"), "france_parts", "ogr", False)
        self.assertEqual(l2.isValid(), True)
        QgsProject.instance().addMapLayer(l2)

        query = toPercent("SELECT * FROM france_parts")
        l4 = QgsVectorLayer("?query=%s&uid=ObjectId" % query, "tt", "virtual")
        self.assertEqual(l4.isValid(), True)

        self.assertEqual(l4.dataProvider().wkbType(), 3)
        self.assertEqual(l4.dataProvider().crs().postgisSrid(), 4326)

        n = 0
        r = QgsFeatureRequest(QgsRectangle(-1.677, 49.624, -0.816, 49.086))
        for f in l4.getFeatures(r):
            self.assertEqual(f.geometry() is not None, True)
            self.assertEqual(f.attributes()[0], 2661)
            n += 1
        self.assertEqual(n, 1)

        # use uid
        query = toPercent("SELECT * FROM france_parts")
        l5 = QgsVectorLayer("?query=%s&geometry=geometry:polygon:4326&uid=ObjectId" % query, "tt", "virtual")
        self.assertEqual(l5.isValid(), True)

        idSum = sum(f.id() for f in l5.getFeatures())
        self.assertEqual(idSum, 10659)

        r = QgsFeatureRequest(2661)
        idSum2 = sum(f.id() for f in l5.getFeatures(r))
        self.assertEqual(idSum2, 2661)

        r = QgsFeatureRequest()
        r.setFilterFids([2661, 2664])
        self.assertEqual(sum(f.id() for f in l5.getFeatures(r)), 2661 + 2664)

        # test attribute subset
        r = QgsFeatureRequest()
        r.setFlags(QgsFeatureRequest.SubsetOfAttributes)
        r.setSubsetOfAttributes([1])
        s = [(f.id(), f.attributes()[1]) for f in l5.getFeatures(r)]
        self.assertEqual(sum([x[0] for x in s]), 10659)
        self.assertEqual(sum([x[1] for x in s]), 3064.0)

        # test NoGeometry
        # by request flag
        r = QgsFeatureRequest()
        r.setFlags(QgsFeatureRequest.NoGeometry)
        self.assertEqual(all([not f.hasGeometry() for f in l5.getFeatures(r)]), True)

        # test subset
        self.assertEqual(l5.dataProvider().featureCount(), 4)
        l5.setSubsetString("ObjectId = 2661")
        idSum2 = sum(f.id() for f in l5.getFeatures(r))
        self.assertEqual(idSum2, 2661)
        self.assertEqual(l5.dataProvider().featureCount(), 1)
Example #12
0
 def modifyFeatures(self, geogiglayer, transactionid):
     if geogiglayer.modifiedFeatures:
         modifiedFeatures = [
             fid for fid in geogiglayer.modifiedFeatures if fid >= 0
         ]
         request = QgsFeatureRequest()
         request.setFilterFids(modifiedFeatures)
         features = [f for f in geogiglayer.layer.getFeatures(request)]
         self.addFeaturesToWorking(features, geogiglayer.user,
                                   geogiglayer.repo, geogiglayer.layername,
                                   transactionid)
    def _useAlgorithm(self, x, y):

        elevationPoint = QgsGeometry().fromPoint( QgsPoint(x, y ) )

        featureIds = self._getClosestNodeFeatureIds(x,y)
        values = {featureId: {'height': self.featuresHeights[0][featureId-1] } for featureId in featureIds}

        request = QgsFeatureRequest()
        request.setFilterFids(featureIds)
        nearestFourGridNodes = self.gridLayer.getFeatures( request )

        for gridNode in nearestFourGridNodes:
            values[gridNode.id()]['distance'] = gridNode.geometry().distance(elevationPoint)

        return self._inverseDistanceWeighted(values)
Example #14
0
    def testFilterFids(self):
        req = QgsFeatureRequest().setFilterFids([5, 6])
        self.assertEqual(req.filterType(), QgsFeatureRequest.FilterFids)
        self.assertEqual(req.filterFid(), -1)
        self.assertCountEqual(req.filterFids(), [5, 6])

        # filter rect doesn't affect fids filter
        req.setFilterRect(QgsRectangle(1, 2, 3, 4))
        self.assertEqual(req.filterType(), QgsFeatureRequest.FilterFids)
        self.assertEqual(req.filterFid(), -1)
        self.assertCountEqual(req.filterFids(), [5, 6])
        req.setFilterFids([8, 9])
        self.assertEqual(req.filterType(), QgsFeatureRequest.FilterFids)
        self.assertEqual(req.filterFid(), -1)
        self.assertCountEqual(req.filterFids(), [8, 9])
        self.assertEqual(req.filterRect(), QgsRectangle(1, 2, 3, 4))
Example #15
0
def getChangeSet(fname):
    raw = getChangeSetRaw(fname)

    layer = QgsVectorLayer(fname)

    request = QgsFeatureRequest()
    request.setFilterFids(raw["inserted_fids"])
    features_inserted = layer.getFeatures(request)

    request = QgsFeatureRequest()
    request.setFilterFids(raw["updated_fids"])
    features_updated = list(layer.getFeatures(request))

    origLayer = QgsVectorLayer(fname + "|layername=geogig_updated_rows_orig")
    layerDeletes = QgsVectorLayer(fname+"|layername=geogig_deleted_rows")

    result = []


    deleted_features = getFeaturesFromGeogigIds(raw["deleted_geogigids"],layerDeletes)
    for geogigid in raw["deleted_geogigids"]:
        result.append({"ID": geogigid,
                        "old": deleted_features[geogigid],
                        "new": None,
                        "geogig.changeType": 2})
    for newFeature in features_inserted:
        result.append({"ID": newFeature[GEOGIGID_FIELD],
                        "old": None,
                        "new": newFeature,
                        "geogig.changeType": 0})

    origFeatures = getFeaturesFromGeogigIds([f[GEOGIGID_FIELD] for f in features_updated],origLayer)
    for newFeature in features_updated:
        id = newFeature[GEOGIGID_FIELD]
        result.append({"ID": id,
                        # "old": _getOldFeature(newFeature[GEOGIGID_FIELD], origLayer),
                        "old": origFeatures[id] ,
                        "new": newFeature,
                        "geogig.changeType": 1})
    sip.delete(layer)
    del layer
    sip.delete(origLayer)
    del origLayer
    sip.delete(layerDeletes)
    del layerDeletes
    return result
        def getImagesByCanvas():
            def getSourceDate(feat):
                return {
                    'source': feat[self.nameFieldSource],
                    'date': feat[self.nameFieldDate]
                }

            def getSource(feat):
                return {'source': feat[self.nameFieldSource]}

            images = []

            selectedImage = self.layer.selectedFeatureCount() > 0
            rectLayer = self.layer.extent(
            ) if not selectedImage else self.layer.boundingBoxOfSelected()
            crsLayer = self.layer.crs()

            crsCanvas = self.canvas.mapSettings().destinationCrs()
            ct = QgsCoordinateTransform(crsCanvas, crsLayer)
            rectCanvas = self.canvas.extent(
            ) if crsCanvas == crsLayer else ct.transform(self.canvas.extent())

            if not rectLayer.intersects(rectCanvas):
                return (True, images)

            fr = QgsFeatureRequest()
            if selectedImage:
                fr.setFilterFids(self.layer.selectedFeaturesIds())
            index = QgsSpatialIndex(self.layer.getFeatures(fr))
            fids = index.intersects(rectCanvas)
            del fr
            del index

            fr = QgsFeatureRequest()
            fr.setFilterFids(fids)
            numImages = len(fids)
            del fids[:]
            it = self.layer.getFeatures(fr)
            f = QgsFeature()
            getF = getSourceDate if not self.nameFieldDate is None else getSource
            while it.nextFeature(f):
                if f.geometry().intersects(rectCanvas):
                    images.append(getF(f))

            return (True, images) if len(images) > 0 else (False, numImages)
Example #17
0
    def _useAlgorithm(self, x, y):

        featureIds = self._getClosestNodeFeatureIds(x, y)
        values = {
            featureId: {
                'height': self.featuresHeights[0][featureId - 1]
            }
            for featureId in featureIds
        }

        request = QgsFeatureRequest()
        request.setFilterFids(featureIds)
        nearestFourGridNodes = self.gridLayer.getFeatures(request)

        for gridNode in nearestFourGridNodes:
            values[gridNode.id()]['geometry'] = gridNode.geometry().asPoint()

        return self._bilinearInterpolation(x, y, values)
def get_fk_set(layerName, fkName, skipFirst=1, fids=None, useProvider=False):
    """
        skipFirst: number of initial lines to skip (header lines in excel)
    """
    layer = layer_from_name(layerName)
    freq = QgsFeatureRequest()
    if fids is not None:
        freq.setFilterFids(fids)
    if not useProvider:
        feats = [f for f in layer.getFeatures(freq)]
    else:
        feats = [f for f in layer.dataProvider().getFeatures(freq)]
    fkSet = []
    for f in feats[skipFirst:]:
        fk = f.attribute(fkName)
        if fk:  # Skip NULL ids that may be reported from excel files
            fkSet.append(fk)
    return fkSet
Example #19
0
def copy_layer(source, target):
    """Copy a vector layer to another one.

    :param source: The vector layer to copy.
    :type source: QgsVectorLayer

    :param target: The destination.
    :type source: QgsVectorLayer
    """
    out_feature = QgsFeature()
    target.startEditing()

    request = QgsFeatureRequest()

    aggregation_layer = False
    if source.keywords.get('layer_purpose') == 'aggregation':
        try:
            use_selected_only = source.use_selected_features_only
        except AttributeError:
            use_selected_only = False

        # We need to check if the user wants selected feature only and if there
        # is one minimum selected.
        if use_selected_only and source.selectedFeatureCount() > 0:
            request.setFilterFids(source.selectedFeatureIds())

        aggregation_layer = True

    for i, feature in enumerate(source.getFeatures(request)):
        geom = feature.geometry()
        if aggregation_layer and feature.hasGeometry():
            # See issue https://github.com/inasafe/inasafe/issues/3713
            # and issue https://github.com/inasafe/inasafe/issues/3927
            # Also handle if feature has no geometry.
            was_valid, geom = geometry_checker(geom)
            if not geom:
                LOGGER.info(
                    'One geometry in the aggregation layer is still invalid '
                    'after cleaning.')
        out_feature.setGeometry(geom)
        out_feature.setAttributes(feature.attributes())
        target.addFeature(out_feature)

    target.commitChanges()
Example #20
0
def copy_layer(source, target):
    """Copy a vector layer to another one.

    :param source: The vector layer to copy.
    :type source: QgsVectorLayer

    :param target: The destination.
    :type source: QgsVectorLayer
    """
    out_feature = QgsFeature()
    target.startEditing()

    request = QgsFeatureRequest()

    aggregation_layer = False
    if source.keywords.get('layer_purpose') == 'aggregation':
        try:
            use_selected_only = source.use_selected_features_only
        except AttributeError:
            use_selected_only = False

        # We need to check if the user wants selected feature only and if there
        # is one minimum selected.
        if use_selected_only and source.selectedFeatureCount() > 0:
            request.setFilterFids(source.selectedFeatureIds())

        aggregation_layer = True

    for i, feature in enumerate(source.getFeatures(request)):
        geom = feature.geometry()
        if aggregation_layer and feature.hasGeometry():
            # See issue https://github.com/inasafe/inasafe/issues/3713
            # and issue https://github.com/inasafe/inasafe/issues/3927
            # Also handle if feature has no geometry.
            was_valid, geom = geometry_checker(geom)
            if not geom:
                LOGGER.info(
                    'One geometry in the aggregation layer is still invalid '
                    'after cleaning.')
        out_feature.setGeometry(geom)
        out_feature.setAttributes(feature.attributes())
        target.addFeature(out_feature)

    target.commitChanges()
Example #21
0
def inverser_canalisation(*args):
    id_canalisation = int(args[0])
    id_layer = args[1]

    layer = QgsProject.instance().mapLayer(id_layer)

    # materialized feature in new layer
    request = QgsFeatureRequest()
    request.setFilterFids([id_canalisation])
    mat = layer.materialize(request)

    # run the processing alg "reverse line direction"
    params = {
        'INPUT': mat,
        'OUTPUT': 'memory:test'
    }
    try:
        out = processing.run('native:reverselinedirection', params)
    except QgsProcessingException:
        QgsMessageLog.logMessage('Erreur dans les logs de Processing/PostGIS.', 'RAEPA', Qgis.Critical)
        iface.messageBar().pushMessage(
            'Erreur dans les logs de Processing/PostGIS.', level=Qgis.Critical, duration=2)
        return

    vout = out['OUTPUT']
    for feat in vout.getFeatures():
        if layer.changeGeometry(id_canalisation, feat.geometry()):
            # message
            iface.messageBar().pushMessage(
                "Line direction has been reversed",
                level=Qgis.Success,
                duration=2
            )
            iface.mapCanvas().refresh()
        else:
            iface.messageBar().pushMessage(
                "Line direction has NOT been reversed. Check if the layer is editable",
                level=Qgis.Critical,
                duration=2
            )
def buildTopology(self, axial, unlinks, links):
    index = createIndex(axial)
    axial_links = []
    unlinks_list = []
    links_list = []
    # get unlinks pairs
    if unlinks:
        features = unlinks.getFeatures(QgsFeatureRequest().setSubsetOfAttributes(['line1', 'line2'], unlinks.fields()))
        for feature in features:
            unlinks_list.append((feature.attribute('line1'), feature.attribute('line2')))
    # get links pairs
    if links:
        features = links.getFeatures(QgsFeatureRequest().setSubsetOfAttributes(['line1', 'line2'], links.fields()))
        for feature in features:
            links_list.append((feature.attribute('line1'), feature.attribute('line2')))
    # get axial intersections
    features = axial.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([]))
    for feature in features:
        geom = feature.geometry()
        id = feature.id()
        box = geom.boundingBox()
        request = QgsFeatureRequest()
        if index:
            # should be faster to retrieve from index (if available)
            ints = index.intersects(box)
            request.setFilterFids(ints)
        else:
            # can retrieve objects using bounding box
            request.setFilterRect(box)
        request.setSubsetOfAttributes([])
        targets = axial.getFeatures(request)
        for target in targets:
            geom_b = target.geometry()
            id_b = target.id()
            if not id_b == id and geom.intersects(geom_b):
                # check if in the unlinks
                if (id, id_b) not in unlinks_list and (id, id_b) not in unlinks_list:
                    axial_links.append((id, id_b))
    return axial_links
Example #23
0
    def feature_difference(self, layer):
        # Get the intersects polygons and difference from neihghboor
        start = time.time()

        mem_layer = self.MemoryPolygonLayer(layer)
        index = self.SpatialIndex(mem_layer)

        for f1 in mem_layer.getFeatures():
            geom1 = f1.geometry()
            intersecting_ids = index.intersects(geom1.boundingBox())

            request = QgsFeatureRequest()
            request.setFilterFids(intersecting_ids)
            features = mem_layer.getFeatures(request)

            for f2 in features:
                if f1['id'] != f2['id'] and f2['id'] is not None:
                    geom2 = f2.geometry()
                    new_geom = geom1.difference(geom2)

                    if new_geom.area() != geom1.area():
                        if new_geom.type() == QgsWkbTypes.UnknownGeometry:
                            print("Unknown Geometry Type Detected !",
                                  "in id: ", f1['id'])
                            new_geom = self.GeometryControl(new_geom)
                            new_geom = new_geom if new_geom.isEmpty(
                            ) == False else geom1

                        mem_layer.dataProvider().changeGeometryValues(
                            {f1.id(): new_geom})
                        geom1 = new_geom

        mem_layer.updateFields()
        end = time.time()
        print(round(end - start, 6), " time elapsed for difference")

        return mem_layer
Example #24
0
 def _assignFuel(self, points):
     index = QgsSpatialIndex()
     for feat in self._fuel_layer.getFeatures():
         index.addFeature(feat)
     intersecting_fuels = dict()
     intersecting_points = list()
     for pt in points:
         pt.fuelModel = '1'
         geom = pt.feature.geometry()
         intersects = index.intersects(geom.boundingBox())
         if len(intersects) > 0:
             request = QgsFeatureRequest()
             request.setFilterFids([intersects[0]])
             fuels = [f for f in self._fuel_layer.getFeatures(request)]
             for fuel in fuels:
                 if not fuel.id() in intersecting_fuels:
                     intersecting_fuels[fuel.id()] = fuel
             intersecting_points.append(pt)
     if len(intersecting_fuels) > 0:
         for pt in intersecting_points:
             for k, feat in intersecting_fuels.items():
                 if feat.geometry().contains(pt.feature.geometry()):
                     pt.fuelModel = feat.attributes()[1]
                     break
Example #25
0
	def findAtPoint(self, layer, point, canvas, onlyTheClosestOne=True, onlyIds=False):
		QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

		# recupera il valore del raggio di ricerca
		settings = QgsSettings()
		radius = settings.value( "/Map/searchRadiusMM", Qgis.DEFAULT_SEARCH_RADIUS_MM, type=float)
		if radius <= 0:
			radius = Qgis.DEFAULT_SEARCH_RADIUS_MM
		radius = canvas.extent().width() * radius/100

		# crea il rettangolo da usare per la ricerca
		rect = QgsRectangle()
		rect.setXMinimum(point.x() - radius)
		rect.setXMaximum(point.x() + radius)
		rect.setYMinimum(point.y() - radius)
		rect.setYMaximum(point.y() + radius)
		rect = canvas.mapSettings().mapToLayerCoordinates(layer, rect)

		# recupera le feature che intersecano il rettangolo
		ret = None

		if onlyTheClosestOne:
			request=QgsFeatureRequest()
			request.setFilterRect(rect)

			minDist = -1
			featureId = None
			rect = QgsGeometry.fromRect(rect)
			count = 0

			for f in layer.getFeatures(request):
				if onlyTheClosestOne:
					geom = f.geometry()
					distance = geom.distance(rect)
					if minDist < 0 or distance < minDist:
						minDist = distance
						featureId = f.id()

			if onlyIds:
				ret = featureId
			elif featureId != None:
				f = QgsFeature()
				feats = layer.getFeature( QgsFeatureRequest(featureId) )
				feats.nextFeature(f)
				ret = f

		else:
			IDs = []
			for f in layer.getFeatures():
				IDs.append( f.id() )

			if onlyIds:
				ret = IDs
			else:
				ret = []
				request = QgsFeatureRequest()
				QgsFeatureRequest.setFilterFids(IDs)
				for f in layer.getFeatures( request ):
					ret.append( f )

		QApplication.restoreOverrideCursor()
		return ret
Example #26
0
        def run_checks():
            self.assertEqual([f.name() for f in vl.fields()],
                             ['fid', 'type', 'value'])

            # expression
            req = QgsFeatureRequest()
            req.setFilterExpression("value=16")
            it = vl.getFeatures(req)
            f = QgsFeature()
            self.assertTrue(it.nextFeature(f))
            self.assertEqual(f.id(), 5)
            self.assertEqual(f.attributes(), [5, 2, 16])
            self.assertEqual([field.name() for field in f.fields()],
                             ['fid', 'type', 'value'])
            self.assertEqual(f.geometry().asWkt(), 'Point (5 5)')

            # filter fid
            req = QgsFeatureRequest()
            req.setFilterFid(5)
            it = vl.getFeatures(req)
            f = QgsFeature()
            self.assertTrue(it.nextFeature(f))
            self.assertEqual(f.id(), 5)
            self.assertEqual(f.attributes(), [5, 2, 16])
            self.assertEqual([field.name() for field in f.fields()],
                             ['fid', 'type', 'value'])
            self.assertEqual(f.geometry().asWkt(), 'Point (5 5)')

            # filter fids
            req = QgsFeatureRequest()
            req.setFilterFids([5])
            it = vl.getFeatures(req)
            f = QgsFeature()
            self.assertTrue(it.nextFeature(f))
            self.assertEqual(f.id(), 5)
            self.assertEqual(f.attributes(), [5, 2, 16])
            self.assertEqual([field.name() for field in f.fields()],
                             ['fid', 'type', 'value'])
            self.assertEqual(f.geometry().asWkt(), 'Point (5 5)')

            # check with subset of attributes
            req = QgsFeatureRequest()
            req.setFilterFids([5])
            req.setSubsetOfAttributes([2])
            it = vl.getFeatures(req)
            f = QgsFeature()
            self.assertTrue(it.nextFeature(f))
            self.assertEqual(f.id(), 5)
            self.assertEqual(f.attributes()[2], 16)
            self.assertEqual([field.name() for field in f.fields()],
                             ['fid', 'type', 'value'])
            self.assertEqual(f.geometry().asWkt(), 'Point (5 5)')

            # filter rect and expression
            req = QgsFeatureRequest()
            req.setFilterExpression("value=16 or value=14")
            req.setFilterRect(QgsRectangle(4.5, 4.5, 5.5, 5.5))
            it = vl.getFeatures(req)
            f = QgsFeature()
            self.assertTrue(it.nextFeature(f))
            self.assertEqual(f.id(), 5)
            self.assertEqual(f.attributes(), [5, 2, 16])
            self.assertEqual([field.name() for field in f.fields()],
                             ['fid', 'type', 'value'])
            self.assertEqual(f.geometry().asWkt(), 'Point (5 5)')

            # filter rect and fids
            req = QgsFeatureRequest()
            req.setFilterFids([3, 5])
            req.setFilterRect(QgsRectangle(4.5, 4.5, 5.5, 5.5))
            it = vl.getFeatures(req)
            f = QgsFeature()
            self.assertTrue(it.nextFeature(f))
            self.assertEqual(f.id(), 5)
            self.assertEqual(f.attributes(), [5, 2, 16])
            self.assertEqual([field.name() for field in f.fields()],
                             ['fid', 'type', 'value'])
            self.assertEqual(f.geometry().asWkt(), 'Point (5 5)')

            # Ensure that orig_ogc_fid is still retrieved even if attribute subset is passed
            req = QgsFeatureRequest()
            req.setSubsetOfAttributes([])
            it = vl.getFeatures(req)
            ids = []
            geoms = {}
            while it.nextFeature(f):
                ids.append(f.id())
                geoms[f.id()] = f.geometry().asWkt()
            self.assertCountEqual(ids, [3, 4, 5])
            self.assertEqual(geoms, {
                3: 'Point (3 3)',
                4: 'Point (4 4)',
                5: 'Point (5 5)'
            })
        def run_checks():
            self.assertEqual([f.name() for f in vl.fields()], ['fid', 'type', 'value'])

            # expression
            req = QgsFeatureRequest()
            req.setFilterExpression("value=16")
            it = vl.getFeatures(req)
            f = QgsFeature()
            self.assertTrue(it.nextFeature(f))
            self.assertEqual(f.id(), 5)
            self.assertEqual(f.attributes(), [5, 2, 16])
            self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value'])
            self.assertEqual(f.geometry().asWkt(), 'Point (5 5)')

            # filter fid
            req = QgsFeatureRequest()
            req.setFilterFid(5)
            it = vl.getFeatures(req)
            f = QgsFeature()
            self.assertTrue(it.nextFeature(f))
            self.assertEqual(f.id(), 5)
            self.assertEqual(f.attributes(), [5, 2, 16])
            self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value'])
            self.assertEqual(f.geometry().asWkt(), 'Point (5 5)')

            # filter fids
            req = QgsFeatureRequest()
            req.setFilterFids([5])
            it = vl.getFeatures(req)
            f = QgsFeature()
            self.assertTrue(it.nextFeature(f))
            self.assertEqual(f.id(), 5)
            self.assertEqual(f.attributes(), [5, 2, 16])
            self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value'])
            self.assertEqual(f.geometry().asWkt(), 'Point (5 5)')

            # check with subset of attributes
            req = QgsFeatureRequest()
            req.setFilterFids([5])
            req.setSubsetOfAttributes([2])
            it = vl.getFeatures(req)
            f = QgsFeature()
            self.assertTrue(it.nextFeature(f))
            self.assertEqual(f.id(), 5)
            self.assertEqual(f.attributes()[2], 16)
            self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value'])
            self.assertEqual(f.geometry().asWkt(), 'Point (5 5)')

            # filter rect and expression
            req = QgsFeatureRequest()
            req.setFilterExpression("value=16 or value=14")
            req.setFilterRect(QgsRectangle(4.5, 4.5, 5.5, 5.5))
            it = vl.getFeatures(req)
            f = QgsFeature()
            self.assertTrue(it.nextFeature(f))
            self.assertEqual(f.id(), 5)
            self.assertEqual(f.attributes(), [5, 2, 16])
            self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value'])
            self.assertEqual(f.geometry().asWkt(), 'Point (5 5)')

            # filter rect and fids
            req = QgsFeatureRequest()
            req.setFilterFids([3, 5])
            req.setFilterRect(QgsRectangle(4.5, 4.5, 5.5, 5.5))
            it = vl.getFeatures(req)
            f = QgsFeature()
            self.assertTrue(it.nextFeature(f))
            self.assertEqual(f.id(), 5)
            self.assertEqual(f.attributes(), [5, 2, 16])
            self.assertEqual([field.name() for field in f.fields()], ['fid', 'type', 'value'])
            self.assertEqual(f.geometry().asWkt(), 'Point (5 5)')

            # Ensure that orig_ogc_fid is still retrieved even if attribute subset is passed
            req = QgsFeatureRequest()
            req.setSubsetOfAttributes([])
            it = vl.getFeatures(req)
            ids = []
            geoms = {}
            while it.nextFeature(f):
                ids.append(f.id())
                geoms[f.id()] = f.geometry().asWkt()
            self.assertCountEqual(ids, [3, 4, 5])
            self.assertEqual(geoms, {3: 'Point (3 3)', 4: 'Point (4 4)', 5: 'Point (5 5)'})
    def processAlgorithm(self, parameters, context, feedback):  #pylint: disable=unused-argument,missing-docstring

        layer = self.parameterAsSource(parameters, self.INPUT, context)
        metric_field = self.parameterAsString(parameters, self.METRIC_FIELD,
                                              context)
        ordering_field = self.parameterAsString(parameters,
                                                self.ORDERING_FIELD, context)
        dissolve = self.parameterAsBool(parameters, self.DISSOLVE, context)

        feedback.pushInfo('Create metric sequence...')
        sequence = []

        total = 100.0 / layer.featureCount() if layer.featureCount() else 0

        for current, feature in enumerate(layer.getFeatures()):
            if feedback.isCanceled():
                break

            distance = feature.attribute(ordering_field)
            value = feature.attribute(metric_field)

            if value != NULL:
                sequence.append([distance, value, feature.id()])

            feedback.setProgress(int(current * total))

        sequence = sorted(sequence)

        feedback.pushInfo('Perform Hubert-Kehagias Segmentation ...')

        serie = np.array([float(item[1]) for item in sequence])
        segmentation = HubertKehagiasSegmentation(serie)
        kopt = segmentation.kopt(len(sequence) // 3)

        feedback.pushInfo('Output aggregated features')

        if dissolve:

            layer_fields = layer.fields()
            metric_field_idx = layer_fields.lookupField(metric_field)
            mean_field = layer_fields.at(metric_field_idx)
            std_field = QgsField(mean_field)
            std_field.setName('STD')

            fields = QgsFields()
            fields.append(QgsField('ID_AGO', QVariant.Int, len=10, prec=0))
            fields.append(mean_field)
            fields.append(std_field)

            (sink, dest_id) = self.parameterAsSink(
                parameters,
                self.OUTPUT,
                context,
                fields,
                # QgsWkbTypes.MultiPolygon,
                layer.wkbType(),
                layer.sourceCrs())

            def output_feature(geometry, seg_idx, mean, std):
                """ Emit output feature """

                outfeature = QgsFeature()
                outfeature.setGeometry(geometry)
                outfeature.setAttributes([seg_idx, float(mean), float(std)])

                sink.addFeature(outfeature)

            srclayer = context.getMapLayer(layer.sourceName())

            breakpoints = segmentation.breakpoints(kopt)
            current = 0

            for seg_idx, (start, stop) in enumerate(
                    zip(breakpoints[:-1], breakpoints[1:])):

                geometries = list()
                request = QgsFeatureRequest()
                request.setFilterFids(
                    [item[2] for item in sequence[start:stop]])
                for feature in srclayer.getFeatures(request):
                    geometries.append(feature.geometry())
                    current += 1

                geometry = QgsGeometry.unaryUnion(geometries)
                mean = serie[start:stop].mean()
                std = serie[start:stop].std()

                if QgsWkbTypes.flatType(
                        geometry.wkbType()) == QgsWkbTypes.MultiLineString:

                    for linestring in geometry.mergeLines(
                    ).asGeometryCollection():
                        output_feature(linestring, seg_idx, mean, std)

                elif QgsWkbTypes.flatType(
                        geometry.wkbType()) == QgsWkbTypes.MultiPolygon:

                    for polygon in geometry.asGeometryCollection():
                        output_feature(polygon, seg_idx, mean, std)

                else:

                    output_feature(geometry, seg_idx, mean, std)

                feedback.setProgress(int(current * total))

        else:

            fields = QgsFields(layer.fields())
            fields.append(QgsField('ID_AGO', QVariant.Int, len=10, prec=0))

            (sink, dest_id) = self.parameterAsSink(
                parameters,
                self.OUTPUT,
                context,
                fields,
                layer.wkbType(),  # QgsWkbTypes.MultiPolygon,
                layer.sourceCrs())

            segments = segmentation.segments(kopt)
            feature_segments = {
                sequence[i][2]: int(segment)
                for i, segment in enumerate(segments)
            }

            for current, feature in enumerate(layer.getFeatures()):

                if feedback.isCanceled():
                    break

                outfeature = QgsFeature()
                outfeature.setGeometry(QgsGeometry(feature.geometry()))
                outfeature.setAttributes(
                    feature.attributes() +
                    [feature_segments.get(feature.id(), None)])

                sink.addFeature(outfeature)

                feedback.setProgress(int(current * total))

        return {self.OUTPUT: dest_id}
Example #29
0
 def __init__(self, layer, parent=None):
     """Constructor
     :param layer: QGIS layer with selected entities
     :type layer: QgsVectorLayer
     :param parent: Parent object
     :type parent: QWidget
     """
     super(SOSPlotDialog, self).__init__(parent)
     # Set up the user interface from Designer.
     self.layer = layer
     if type(self.layer) <> type (QgsVectorLayer()) :
         raise TypeError(self.tr("Selector layer isn't a vector layer"))
     if self.layer.selectedFeatureCount() == 0:
         raise ValueError (self.tr("No features selected"))
     
     self.setupUi(self)
     
     map (lambda w: w.setRange(-maxFloat,maxFloat),[self.xMinFloat, self.xMaxFloat, self.yMinFloat, self.yMaxFloat])
     def DateTimeEdit2SpinBox (widget):
         widget.setValue = lambda value: widget.setDateTime(mpdates.num2date(value))
         widget.value = lambda: mpdates.date2num(widget.dateTime().toPyDateTime())
     map(DateTimeEdit2SpinBox, [self.xMinTime, self.xMaxTime, self.yMinTime, self.yMaxTime])
     
     request = QgsFeatureRequest()
     request.setFlags(QgsFeatureRequest.NoGeometry)
     request.setFilterFids(self.layer.selectedFeaturesIds())
     self.foiList = set([f.attribute("foi") for f in layer.getFeatures(request)])
     self.foiList = list(self.foiList)
     self.foiList.sort()
     self.plotWidget.genColorMap (len(self.foiList))
     
     self.xProperty.addItems([str(f.name()) for f in list(layer.pendingFields())[2:]])
     self.yProperty.addItems([str(f.name()) for f in list(layer.pendingFields())[2:]])
     self.xProperty.setCurrentIndex (0)
     self.yProperty.setCurrentIndex (1)
     
     self.draw()
     self.plotWidget.title = self.layer.name()
     self.plotWidget.xLabel = self.xProperty.currentText()
     self.plotWidget.yLabel = self.yProperty.currentText()
     
     self.plotWidget.picked.connect (self.dataSeriePicked)
     self.plotWidget.axisChanged.connect (self.axisLimChanged)
     
     self.title.editingFinished.connect(lambda: self.optionsToPlot(option='title'))
     self.legendChk.stateChanged.connect(lambda v: self.optionsToPlot(option='legend'))
     self.legendPos.currentIndexChanged.connect(lambda v: self.optionsToPlot(option='legend'))
     self.legendCols.valueChanged.connect(lambda v: self.optionsToPlot(option='legend'))
     self.gridChk.stateChanged.connect(lambda v: self.optionsToPlot(option='grid'))
     self.xSorted.toggled.connect(self.optionsToPlot)
     self.ySorted.toggled.connect(self.optionsToPlot)
     self.timeFormat.editingFinished.connect(self.optionsToPlot)
     
     self.xProperty.currentIndexChanged.connect(lambda v: self.optionsToPlot(option='xProperty'))
     self.xLabel.editingFinished.connect(lambda: self.optionsToPlot(option='xLabel'))
     self.xMinFloat.editingFinished.connect(lambda: self.optionsToPlot(option='xRange'))
     self.xMaxFloat.editingFinished.connect(lambda: self.optionsToPlot(option='xRange'))
     self.xMinTime.editingFinished.connect(lambda: self.optionsToPlot(option='xRange'))
     self.xMaxTime.editingFinished.connect(lambda: self.optionsToPlot(option='xRange'))
     
     self.yProperty.currentIndexChanged.connect(lambda v: self.optionsToPlot(option='yProperty'))
     self.yLabel.editingFinished.connect(lambda: self.optionsToPlot(option='yLabel'))
     self.yMinFloat.editingFinished.connect(lambda: self.optionsToPlot(option='yRange'))
     self.yMaxFloat.editingFinished.connect(lambda: self.optionsToPlot(option='yRange'))
     self.yMinTime.editingFinished.connect(lambda: self.optionsToPlot(option='yRange'))
     self.yMaxTime.editingFinished.connect(lambda: self.optionsToPlot(option='yRange'))
     
     map (lambda k: self.lineStyle.addItem(k, self.StylesTable.lineStyles[k]), sorted(self.StylesTable.lineStyles))
     map (lambda k: self.marker.addItem(k, self.StylesTable.markers[k]), sorted(self.StylesTable.markers))
     self.defaultStyle.button(QtGui.QDialogButtonBox.Reset).clicked.connect(self.restoreDefaultStyle)
     self.defaultStyle.button(QtGui.QDialogButtonBox.Apply).clicked.connect(lambda: self.optionsToPlot (option='defaultStyle'))
     map(lambda b: b.setAutoDefault(False), self.defaultStyle.buttons())
     
     self.optionsFromPlot()
     
     self.stylesTable.setItemDelegateForColumn (1, ColorButtonDelegate(self))
     self.stylesTable.setItemDelegateForColumn (2, ComboBoxDelegate(self,self.StylesTable.lineStyles))
     self.stylesTable.setItemDelegateForColumn (3, DoubleSpinBoxDelegate(self, (0,100)))
     self.stylesTable.setItemDelegateForColumn (4, ComboBoxDelegate(self,self.StylesTable.markers))
     self.stylesTable.setItemDelegateForColumn (5, DoubleSpinBoxDelegate(self, (0,100)))
     self.stylesTable.setItemDelegateForColumn (6, SliderDelegate(self, (0.0,1.0)))
def query_layer_for_fids(layerName, fids):
    layer = layer_from_name(layerName)
    freq = QgsFeatureRequest()
    freq.setFilterFids(list(fids))
    return list(layer.getFeatures(freq))
Example #31
0
 def qgisGeometryTopologyTest(self, axial, index, unlinks):
     # this function checks the geometric validity of geometry using QGIS
     length = self.verification_settings['ax_min']
     threshold = self.verification_settings['ax_dist']
     axial_links = []
     unlinks_list = []
     # get unlinks pairs
     if not self.running: return
     if unlinks:
         if lfh.fieldExists(unlinks, 'line1') and lfh.fieldExists(
                 unlinks, 'line2'):
             features = unlinks.getFeatures(
                 QgsFeatureRequest().setSubsetOfAttributes(
                     ['line1', 'line2'], unlinks.fields()))
             for feature in features:
                 unlinks_list.append((feature.attribute('line1'),
                                      feature.attribute('line2')))
     if not self.running: return
     if self.user_id == '':
         features = axial.getFeatures(
             QgsFeatureRequest().setSubsetOfAttributes([]))
     else:
         field = lfh.getFieldIndex(axial, self.user_id)
         features = axial.getFeatures(
             QgsFeatureRequest().setSubsetOfAttributes([field]))
     steps = 85.0 / float(axial.featureCount())
     progress = 5.0
     start_buff = QgsGeometry()
     end_buff = QgsGeometry()
     for i, feature in enumerate(features):
         if not self.running: break
         has_problem = False
         geom = feature.geometry()
         if self.user_id == '':
             fid = feature.id()
         else:
             fid = feature.attribute(self.user_id)
         # has no geometry, skip rest of the checks
         if not feature.hasGeometry():
             self.axial_errors['invalid geometry'].append(fid)
             self.problem_nodes.append(fid)
             progress += steps
             continue
         # geometry is valid (generally), skip rest of the checks
         if not geom.isGeosValid() or geom.isEmpty() or (
                 geom.isMultipart() and len(geom.asMultiPolyline()) > 1):
             has_problem = True
             self.axial_errors['invalid geometry'].append(fid)
             continue
         if geom.isMultipart():
             poly_geom = geom.asMultiPolyline()[0]
         else:
             poly_geom = geom.asPolyline()
         # geometry is polyline
         if len(poly_geom) > 2:
             has_problem = True
             self.axial_errors['polyline'].append(fid)
         # has two coinciding points
         if geom.length() == 0:
             has_problem = True
             self.axial_errors['coinciding points'].append(fid)
         # small lines, with small length
         if geom.length() < length:
             has_problem = True
             self.axial_errors['small line'].append(fid)
         # testing against other lines in the layer
         if threshold > 0:
             start_buff = QgsGeometry.fromPointXY(poly_geom[0]).buffer(
                 threshold, 4)
             end_buff = QgsGeometry.fromPointXY(poly_geom[1]).buffer(
                 threshold, 4)
             buff = geom.buffer(threshold, 4)
             box = buff.boundingBox()
         else:
             box = geom.boundingBox()
         request = QgsFeatureRequest()
         if index:
             # should be faster to retrieve from index (if available)
             ints = index.intersects(box)
             request.setFilterFids(ints)
         else:
             # can retrieve objects using bounding box
             request.setFilterRect(box)
         if self.user_id == '':
             request.setSubsetOfAttributes([])
         else:
             field = lfh.getFieldIndex(axial, self.user_id)
             request.setSubsetOfAttributes([field])
         targets = axial.getFeatures(request)
         for target in targets:
             if not self.running: break
             geom_b = target.geometry()
             if self.user_id == '':
                 id_b = target.id()
             else:
                 id_b = target.attribute(self.user_id)
             if not id_b == fid:
                 # duplicate geometry
                 if geom.isGeosEqual(geom_b):
                     has_problem = True
                     self.axial_errors['duplicate geometry'].append(fid)
                 # geometry overlaps
                 if geom.overlaps(geom_b):
                     has_problem = True
                     self.axial_errors['overlap'].append(fid)
                 # short lines, just about touch without intersecting
                 if (geom_b.intersects(start_buff)
                         or geom_b.intersects(end_buff)
                     ) and not geom_b.intersects(geom):
                     has_problem = True
                     self.axial_errors['short line'].append(fid)
                 if geom.intersects(geom_b):
                     # check if in the unlinks
                     if (fid, id_b) not in unlinks_list and (
                             id_b, fid) not in unlinks_list:
                         # build the topology
                         if has_networkx:
                             axial_links.append((fid, id_b))
         if has_problem:
             self.problem_nodes.append(fid)
         progress += steps
         self.verificationProgress.emit(int(progress))
     return axial_links
Example #32
0
    def __build_data(self):

        req = QgsFeatureRequest()
        req.setFilterFids(self.__feature_ids)

        self.__x_values = []
        self.__y_values = []
        current_data_range = None
        for f in self.__layer.getFeatures(req):
            raw_data = f[self.__y_fieldname]
            if self.__x_start_fieldname is not None:
                x_start = f[self.__x_start_fieldname]
                x_delta = f[self.__x_delta_fieldname]
            else:
                x_start = self.__x_start
                x_delta = self.__x_delta

            if isinstance(raw_data, list):
                # QGIS 3 natively reads array values
                # Null values still have to be filtered out
                # WARNING: extracting list from PostgreSQL's arrays seem very sloowww
                y_values = [
                    None if isinstance(x, QVariant) else x for x in raw_data
                ]
            elif isinstance(raw_data, str):
                # We assume values are separated by a ','
                y_values = [
                    None if value == 'NULL' else float(value)
                    for value in raw_data.split(",")
                ]
            else:
                print("Unsupported data format: {}".format(raw_data.__class__))

            x_values = np.linspace(x_start,
                                   x_start + x_delta * (len(y_values) - 1),
                                   len(y_values)).tolist()

            data_range = (x_start, x_start + x_delta * (len(y_values) - 1))
            if current_data_range is None:
                current_data_range = data_range
                self.__x_values = x_values
                self.__y_values = y_values
            else:
                # look for overlap
                if (current_data_range[0] < data_range[0] < current_data_range[1]) or \
                   (current_data_range[0] < data_range[1] < current_data_range[1]):
                    print("Overlap in data around feature #{}".format(f.id()))
                    continue
                if current_data_range[0] > data_range[1]:
                    # new data are "on the left"
                    self.__x_values = x_values + self.__x_values
                    self.__y_values = y_values + self.__y_values
                else:
                    # new data are "on the right"
                    self.__x_values = self.__x_values + x_values
                    self.__y_values = self.__y_values + y_values
                current_data_range = (self.__x_values[0], self.__x_values[-1])

        self.__x_min, self.__x_max = ((min(
            self.__x_values), max(self.__x_values)) if self.__x_values else
                                      (None, None))
        self.__y_min, self.__y_max = ((min(
            y for y in self.__y_values
            if y is not None), max(y for y in self.__y_values
                                   if y is not None)) if self.__y_values else
                                      (None, None))

        self.data_modified.emit()
Example #33
0
    def findAtPoint(self,
                    layer,
                    point,
                    canvas,
                    onlyTheClosestOne=True,
                    onlyIds=False):
        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

        # recupera il valore del raggio di ricerca
        settings = QgsSettings()
        radius = settings.value("/Map/searchRadiusMM",
                                Qgis.DEFAULT_SEARCH_RADIUS_MM,
                                type=float)
        if radius <= 0:
            radius = Qgis.DEFAULT_SEARCH_RADIUS_MM
        radius = canvas.extent().width() * radius / 100

        # crea il rettangolo da usare per la ricerca
        rect = QgsRectangle()
        rect.setXMinimum(point.x() - radius)
        rect.setXMaximum(point.x() + radius)
        rect.setYMinimum(point.y() - radius)
        rect.setYMaximum(point.y() + radius)
        rect = canvas.mapSettings().mapToLayerCoordinates(layer, rect)

        # recupera le feature che intersecano il rettangolo
        ret = None

        if onlyTheClosestOne:
            request = QgsFeatureRequest()
            request.setFilterRect(rect)

            minDist = -1
            featureId = None
            rect = QgsGeometry.fromRect(rect)
            count = 0

            for f in layer.getFeatures(request):
                if onlyTheClosestOne:
                    geom = f.geometry()
                    distance = geom.distance(rect)
                    if minDist < 0 or distance < minDist:
                        minDist = distance
                        featureId = f.id()

            if onlyIds:
                ret = featureId
            elif featureId != None:
                f = QgsFeature()
                feats = layer.getFeature(QgsFeatureRequest(featureId))
                feats.nextFeature(f)
                ret = f

        else:
            IDs = []
            for f in layer.getFeatures():
                IDs.append(f.id())

            if onlyIds:
                ret = IDs
            else:
                ret = []
                request = QgsFeatureRequest()
                QgsFeatureRequest.setFilterFids(IDs)
                for f in layer.getFeatures(request):
                    ret.append(f)

        QApplication.restoreOverrideCursor()
        return ret
Example #34
0
    def canvasPressEvent(self, event):
        """ handle click event on the canvas when tool is active """
        x = event.pos().x()
        y = event.pos().y()
        pos = self.toMapCoordinates(QPoint(x, y))
        # search for parcel layer
        poly_layers = QgsProject.instance().mapLayersByName(self.main.parcel)
        if len(poly_layers) == 0:
            QMessageBox.warning(
                None, self.tr("Area ratio"),
                self.tr("{} layer not found".format(self.main.parcel)))
            return
        poly_layer = poly_layers[0]
        # remove | layer: 0 tag from the end TODO not always good!
        poly_path = poly_layer.dataProvider().dataSourceUri().split('|')[0]
        # build index for polygon layer
        if self.index is None:
            self.index = QgsSpatialIndex()
            for feat in poly_layer.getFeatures():
                self.index.insertFeature(feat)

        in_poly_layers = self.main.buildings
        # find polygons which MBR cover point
        fids = self.index.nearestNeighbor(pos)
        request = QgsFeatureRequest()
        request.setFilterFids(fids)
        features = poly_layer.getFeatures(request)
        p_geom = QgsGeometry.fromPointXY(pos)
        f = None
        for feat in features:
            if feat.geometry().intersects(p_geom):
                f = feat
                break
        else:
            # No poly found
            QMessageBox.warning(
                None, self.tr("Area ratio"),
                self.tr("Feature not found on layer {} ".format(
                    self.main.parcel)))
            return
        # remove previous selection
        poly_layer.removeSelection()
        # select polygon clicked
        poly_layer.select(f.id())
        area1 = f.geometry().area()  # parcel area
        area2 = 0  # sum area for in_poly_layers
        msg = self.main.parcel + ": {:.1f}\n".format(area1)
        # go through building layers
        for name in in_poly_layers:
            layers = QgsProject.instance().mapLayersByName(name)
            if len(layers) == 0:
                QMessageBox.warning(None, self.tr("Area ratio"),
                                    self.tr("{} layer not found".format(name)))
                continue
            layer = layers[0]
            # remove | layer: 0 tag from the end
            layer_path = layer.dataProvider().dataSourceUri().split('|')[0]
            # select intersecting building
            processing.run(
                "native:selectbylocation", {
                    'INPUT':
                    layer_path,
                    'INTERSECT':
                    QgsProcessingFeatureSourceDefinition(poly_path, True),
                    'METHOD':
                    0,
                    'PREDICATE': [0]
                })
            features = layer.selectedFeatures()
            n = 0
            area3 = 0  # sum area for actual layer
            for feat in features:
                # accept intersecting buildings if an internal point is in the parcel
                p = feat.geometry().pointOnSurface()
                if p.intersects(f.geometry()):
                    warea = feat.geometry().area()
                    n += 1
                    area3 += warea  # total area in this layer
                    area2 += warea  # total area in all layers
            if n > 0:
                msg = msg + "\n{:d} {}: {:.1f}".format(n, name, area3)
            layer.removeSelection()
        msg = msg + "\n\n{:.1f} %".format(area2 / area1 * 100.0)
        QMessageBox.information(None, self.tr("Area ratio"), msg)
    def data( self ):
        if self._dataLoaded:
            return self._x, self._y, self._z
        self._dataLoaded=True
        self._x = None
        self._y = None
        self._z = None
        self._gridShape=None
        self._gridTested=False
        self._dataLoaded=True

        source=self._source
        zField=self._zField
        if source is None or zField is None or zField == '':
            return self._x, self._y, self._z

        discardTolerance=self._discardTolerance
        feedback=self._feedback

        total = source.featureCount()
        percent = 100.0 / total if total > 0 else 0

        count = 0
        x = list()
        y = list()
        z = list()
        try:
            if source.fields().lookupField(zField) >= 0:
                zField='"'+zField.replace('"','""')+'"'
            expression=QgsExpression(zField)
            if expression.hasParserError():
                raise ContourError(tr("Cannot parse")+" "+zField)
            fields=source.fields()
            context=QgsExpressionContext()
            context.setFields(fields)
            if not expression.prepare(context):
                raise ContourError(tr("Cannot evaluate value")+ " "+zField)
            request = QgsFeatureRequest()
            request.setSubsetOfAttributes( expression.referencedColumns(),fields)
            if self._sourceFids is not None:
                request.setFilterFids(self._sourceFids)
            for current,feat in enumerate(source.getFeatures( request )):
                try:
                    if feedback.isCanceled():
                        raise ContourError('Cancelled by user')
                    feedback.setProgress(int(current * percent))
                    context.setFeature(feat)
                    zval=expression.evaluate(context)
                    try:
                        zval=float(zval)
                    except ValueError:
                        raise ContourError(tr("Z value {0} is not number")
                                                   .format(zval))
                    if zval is not None:
                        fgeom = feat.geometry()
                        if QgsWkbTypes.flatType(fgeom.wkbType()) != QgsWkbTypes.Point:
                            raise ContourError(tr("Invalid geometry type for contouring - must be point geometry"))
                        geom=fgeom.asPoint()
                        x.append(geom.x())
                        y.append(geom.y())
                        z.append(zval)
                except Exception as ex:
                    raise
                count = count + 1

            npt=len(x)
            if npt > 0:
                x=np.array(x)
                y=np.array(y)
                z=np.array(z)
                if discardTolerance > 0:
                    index=ContourUtils.discardDuplicatePoints(
                        x,y,discardTolerance,self.crs().isGeographic())
                    npt1=len(index)
                    if npt1 < npt:
                        x=x[index]
                        y=y[index]
                        z=z[index]
                        feedback.pushInfo(tr("{0} near duplicate points discarded - tolerance {1}")
                                          .format(npt-npt1,discardTolerance))
        except ContourError as ce:
            feedback.reportError(ce.message())
            feedback.setProgress(0)
            return self._x,self._y,self._z
        finally:
            feedback.setProgress(0)

        if len(x) < 3:
            feedback.reportError(tr("Too few points to contour"))
            return self._x, self._y, self._z
        self._x=x
        self._y=y
        self._z=z
        return self._x, self._y, self._z
Example #36
0
farmacies = csv.reader(file, delimiter=',')
i = 0

index = QgsSpatialIndex()
for feat in grid:
    index.addFeature(feat)
    groups[feat.id()] = list()

for farmacia in farmacies:
    if i > 0:
        punt = QgsGeometry.fromPointXY(
            QgsPointXY(float(farmacia[16]), float(farmacia[17])))
        intersects = index.intersects(punt.boundingBox())
        if len(intersects) > 0:
            request = QgsFeatureRequest()
            request.setFilterFids(intersects)
            feats = [f for f in layer.getFeatures(request)]
            found = False
            for feat in feats:
                if punt.intersects(feat.geometry()):
                    groups[feat.id()].append(farmacia)
                    found = True
            if not found:
                print('Error')
        else:
            print('Error')

    if i % 100 == 0:
        print(i)
    i += 1
Example #37
0
    def __init__(self, layer, parent=None):
        """Constructor
        :param layer: QGIS layer with selected entities
        :type layer: QgsVectorLayer
        :param parent: Parent object
        :type parent: QWidget
        """
        super(SOSPlotDialog, self).__init__(parent)
        # Set up the user interface from Designer.
        self.layer = layer
        if type(self.layer) <> type(QgsVectorLayer()):
            raise TypeError(self.tr("Selector layer isn't a vector layer"))
        if self.layer.selectedFeatureCount() == 0:
            raise ValueError(self.tr("No features selected"))

        self.setupUi(self)

        map(lambda w: w.setRange(-maxFloat, maxFloat),
            [self.xMinFloat, self.xMaxFloat, self.yMinFloat, self.yMaxFloat])

        def DateTimeEdit2SpinBox(widget):
            widget.setValue = lambda value: widget.setDateTime(
                mpdates.num2date(value))
            widget.value = lambda: mpdates.date2num(widget.dateTime().
                                                    toPyDateTime())

        map(DateTimeEdit2SpinBox,
            [self.xMinTime, self.xMaxTime, self.yMinTime, self.yMaxTime])

        request = QgsFeatureRequest()
        request.setFlags(QgsFeatureRequest.NoGeometry)
        request.setFilterFids(self.layer.selectedFeaturesIds())
        self.foiList = set(
            [f.attribute("foi") for f in layer.getFeatures(request)])
        self.foiList = list(self.foiList)
        self.foiList.sort()
        self.plotWidget.genColorMap(len(self.foiList))

        self.xProperty.addItems(
            [str(f.name()) for f in list(layer.pendingFields())[2:]])
        self.yProperty.addItems(
            [str(f.name()) for f in list(layer.pendingFields())[2:]])
        self.xProperty.setCurrentIndex(0)
        self.yProperty.setCurrentIndex(1)

        self.draw()
        self.plotWidget.title = self.layer.name()
        self.plotWidget.xLabel = self.xProperty.currentText()
        self.plotWidget.yLabel = self.yProperty.currentText()

        self.plotWidget.picked.connect(self.dataSeriePicked)
        self.plotWidget.axisChanged.connect(self.axisLimChanged)

        self.title.editingFinished.connect(
            lambda: self.optionsToPlot(option='title'))
        self.legendChk.stateChanged.connect(
            lambda v: self.optionsToPlot(option='legend'))
        self.legendPos.currentIndexChanged.connect(
            lambda v: self.optionsToPlot(option='legend'))
        self.legendCols.valueChanged.connect(
            lambda v: self.optionsToPlot(option='legend'))
        self.gridChk.stateChanged.connect(
            lambda v: self.optionsToPlot(option='grid'))
        self.xSorted.toggled.connect(self.optionsToPlot)
        self.ySorted.toggled.connect(self.optionsToPlot)
        self.timeFormat.editingFinished.connect(self.optionsToPlot)

        self.xProperty.currentIndexChanged.connect(
            lambda v: self.optionsToPlot(option='xProperty'))
        self.xLabel.editingFinished.connect(
            lambda: self.optionsToPlot(option='xLabel'))
        self.xMinFloat.editingFinished.connect(
            lambda: self.optionsToPlot(option='xRange'))
        self.xMaxFloat.editingFinished.connect(
            lambda: self.optionsToPlot(option='xRange'))
        self.xMinTime.editingFinished.connect(
            lambda: self.optionsToPlot(option='xRange'))
        self.xMaxTime.editingFinished.connect(
            lambda: self.optionsToPlot(option='xRange'))

        self.yProperty.currentIndexChanged.connect(
            lambda v: self.optionsToPlot(option='yProperty'))
        self.yLabel.editingFinished.connect(
            lambda: self.optionsToPlot(option='yLabel'))
        self.yMinFloat.editingFinished.connect(
            lambda: self.optionsToPlot(option='yRange'))
        self.yMaxFloat.editingFinished.connect(
            lambda: self.optionsToPlot(option='yRange'))
        self.yMinTime.editingFinished.connect(
            lambda: self.optionsToPlot(option='yRange'))
        self.yMaxTime.editingFinished.connect(
            lambda: self.optionsToPlot(option='yRange'))

        map(
            lambda k: self.lineStyle.addItem(k, self.StylesTable.lineStyles[k]
                                             ),
            sorted(self.StylesTable.lineStyles))
        map(lambda k: self.marker.addItem(k, self.StylesTable.markers[k]),
            sorted(self.StylesTable.markers))
        self.defaultStyle.button(QtGui.QDialogButtonBox.Reset).clicked.connect(
            self.restoreDefaultStyle)
        self.defaultStyle.button(QtGui.QDialogButtonBox.Apply).clicked.connect(
            lambda: self.optionsToPlot(option='defaultStyle'))
        map(lambda b: b.setAutoDefault(False), self.defaultStyle.buttons())

        self.optionsFromPlot()

        self.stylesTable.setItemDelegateForColumn(1, ColorButtonDelegate(self))
        self.stylesTable.setItemDelegateForColumn(
            2, ComboBoxDelegate(self, self.StylesTable.lineStyles))
        self.stylesTable.setItemDelegateForColumn(
            3, DoubleSpinBoxDelegate(self, (0, 100)))
        self.stylesTable.setItemDelegateForColumn(
            4, ComboBoxDelegate(self, self.StylesTable.markers))
        self.stylesTable.setItemDelegateForColumn(
            5, DoubleSpinBoxDelegate(self, (0, 100)))
        self.stylesTable.setItemDelegateForColumn(
            6, SliderDelegate(self, (0.0, 1.0)))