def layerData(self, layer, request={}, offset=0):
        # Retrieve the data for a layer
        first = True
        data = {}
        fields = []
        fieldTypes = []
        fr = QgsFeatureRequest()
        if request:
            if 'exact' in request and request['exact']:
                fr.setFlags(QgsFeatureRequest.ExactIntersect)
            if 'nogeom' in request and request['nogeom']:
                fr.setFlags(QgsFeatureRequest.NoGeometry)
            if 'fid' in request:
                fr.setFilterFid(request['fid'])
            elif 'extents' in request:
                fr.setFilterRect(QgsRectangle(*request['extents']))
            if 'attributes' in request:
                fr.setSubsetOfAttributes(request['attributes'])

        # IMPORTANT - we do not use `for f in layer.getFeatures(fr):` as we need
        # to verify that existing attributes and geometry are correctly cleared
        # from the feature when calling nextFeature()
        it = layer.getFeatures(fr)
        f = QgsFeature()
        while it.nextFeature(f):
            if first:
                first = False
                for field in f.fields():
                    fields.append(str(field.name()))
                    fieldTypes.append(str(field.typeName()))
            if sys.version_info.major == 2:
                fielddata = dict((name, str(f[name])) for name in fields)
            else:
                fielddata = dict((name, str(f[name])) for name in fields)
            g = f.geometry()
            if not g.isEmpty():
                fielddata[geomkey] = str(g.exportToWkt())
            else:
                fielddata[geomkey] = "None"

            fielddata[fidkey] = f.id()
            id = fielddata[fields[0]]
            description = fielddata[fields[1]]
            fielddata['id'] = id
            fielddata['description'] = description
            data[f.id() + offset] = fielddata

        if 'id' not in fields:
            fields.insert(0, 'id')
        if 'description' not in fields:
            fields.insert(1, 'description')
        fields.append(fidkey)
        fields.append(geomkey)
        return fields, fieldTypes, data
    def testMinMaxAfterChanges(self):
        """
        Tests retrieving field min and max value after making changes to the provider's features
        """
        if not getattr(self, 'getEditableLayer', None):
            return

        vl = self.getEditableLayer()
        self.assertTrue(vl.isValid())

        self.assertEqual(vl.dataProvider().minimumValue(0), 1)
        self.assertEqual(vl.dataProvider().minimumValue(1), -200)
        self.assertEqual(vl.dataProvider().maximumValue(0), 5)
        self.assertEqual(vl.dataProvider().maximumValue(1), 400)

        # add feature
        f6 = QgsFeature()
        f6.setAttributes([15, 1400])
        res, [f6] = vl.dataProvider().addFeatures([f6])
        self.assertTrue(res)
        self.assertEqual(vl.dataProvider().minimumValue(0), 1)
        self.assertEqual(vl.dataProvider().minimumValue(1), -200)
        self.assertEqual(vl.dataProvider().maximumValue(0), 15)
        self.assertEqual(vl.dataProvider().maximumValue(1), 1400)
        f7 = QgsFeature()
        f7.setAttributes([0, -1400])
        res, [f7] = vl.dataProvider().addFeatures([f7])
        self.assertTrue(res)
        self.assertEqual(vl.dataProvider().minimumValue(0), 0)
        self.assertEqual(vl.dataProvider().minimumValue(1), -1400)
        self.assertEqual(vl.dataProvider().maximumValue(0), 15)
        self.assertEqual(vl.dataProvider().maximumValue(1), 1400)

        # change attribute values
        self.assertTrue(vl.dataProvider().changeAttributeValues({f6.id(): {1: 150}, f7.id(): {1: -100}}))
        self.assertEqual(vl.dataProvider().minimumValue(1), -200)
        self.assertEqual(vl.dataProvider().maximumValue(1), 400)

        # delete features
        f1 = [f for f in vl.getFeatures() if f['pk'] == 5][0]
        f3 = [f for f in vl.getFeatures() if f['pk'] == 3][0]
        self.assertTrue(vl.dataProvider().deleteFeatures([f6.id(), f7.id()]))
        self.assertEqual(vl.dataProvider().minimumValue(0), 1)
        self.assertEqual(vl.dataProvider().minimumValue(1), -200)
        self.assertEqual(vl.dataProvider().maximumValue(0), 5)
        self.assertEqual(vl.dataProvider().maximumValue(1), 400)

        if vl.dataProvider().capabilities() & QgsVectorDataProvider.DeleteAttributes:
            # delete attributes
            if vl.dataProvider().deleteAttributes([0]):
                # may not be possible, e.g. if it's a primary key
                self.assertEqual(vl.dataProvider().minimumValue(0), -200)
                self.assertEqual(vl.dataProvider().maximumValue(0), 400)
    def testGetFeaturesFidsTests(self):
        fids = [f.id() for f in self.source.getFeatures()]
        self.assertEqual(len(fids), 5)

        # empty list = no features
        request = QgsFeatureRequest().setFilterFids([])
        result = set([f.id() for f in self.source.getFeatures(request)])
        self.assertFalse(result)

        request = QgsFeatureRequest().setFilterFids([fids[0], fids[2]])
        result = set([f.id() for f in self.source.getFeatures(request)])
        all_valid = (all(f.isValid() for f in self.source.getFeatures(request)))
        expected = set([fids[0], fids[2]])
        assert result == expected, 'Expected {} and got {} when testing for feature IDs filter'.format(expected, result)
        self.assertTrue(all_valid)

        # test that results match QgsFeatureRequest.acceptFeature
        for f in self.source.getFeatures():
            self.assertEqual(request.acceptFeature(f), f.id() in expected)

        result = set([f.id() for f in self.source.getFeatures(QgsFeatureRequest().setFilterFids([fids[1], fids[3], fids[4]]))])
        expected = set([fids[1], fids[3], fids[4]])
        assert result == expected, 'Expected {} and got {} when testing for feature IDs filter'.format(expected, result)

        #sources should ignore non-existent fids
        result = set([f.id() for f in self.source.getFeatures(QgsFeatureRequest().setFilterFids([-101, fids[1], -102, fids[3], -103, fids[4], -104]))])
        expected = set([fids[1], fids[3], fids[4]])
        assert result == expected, 'Expected {} and got {} when testing for feature IDs filter'.format(expected, result)

        result = set([f.id() for f in self.source.getFeatures(QgsFeatureRequest().setFilterFids([]))])
        expected = set([])
        assert result == expected, 'Expected {} and got {} when testing for feature IDs filter'.format(expected, result)

        # Rewind mid-way
        request = QgsFeatureRequest().setFilterFids([fids[1], fids[3], fids[4]])
        feature_it = self.source.getFeatures(request)
        feature = QgsFeature()
        feature.setValid(True)
        self.assertTrue(feature_it.nextFeature(feature))
        self.assertIn(feature.id(), [fids[1], fids[3], fids[4]])
        first_feature = feature
        self.assertTrue(feature.isValid())
        # rewind
        self.assertTrue(feature_it.rewind())
        self.assertTrue(feature_it.nextFeature(feature))
        self.assertEqual(feature.id(), first_feature.id())
        self.assertTrue(feature.isValid())
        # grab all features
        self.assertTrue(feature_it.nextFeature(feature))
        self.assertTrue(feature_it.nextFeature(feature))
        # none left
        self.assertFalse(feature_it.nextFeature(feature))
        self.assertFalse(feature.isValid())
Example #4
0
    def testGetFeaturesFidsTests(self):
        fids = [f.id() for f in self.provider.getFeatures()]
        self.assertEqual(len(fids), 5)

        request = QgsFeatureRequest().setFilterFids([fids[0], fids[2]])
        result = set([f.id() for f in self.provider.getFeatures(request)])
        all_valid = all(f.isValid() for f in self.provider.getFeatures(request))
        expected = set([fids[0], fids[2]])
        assert result == expected, "Expected {} and got {} when testing for feature IDs filter".format(expected, result)
        self.assertTrue(all_valid)

        result = set(
            [f.id() for f in self.provider.getFeatures(QgsFeatureRequest().setFilterFids([fids[1], fids[3], fids[4]]))]
        )
        expected = set([fids[1], fids[3], fids[4]])
        assert result == expected, "Expected {} and got {} when testing for feature IDs filter".format(expected, result)

        # providers should ignore non-existant fids
        result = set(
            [
                f.id()
                for f in self.provider.getFeatures(
                    QgsFeatureRequest().setFilterFids([-101, fids[1], -102, fids[3], -103, fids[4], -104])
                )
            ]
        )
        expected = set([fids[1], fids[3], fids[4]])
        assert result == expected, "Expected {} and got {} when testing for feature IDs filter".format(expected, result)

        result = set([f.id() for f in self.provider.getFeatures(QgsFeatureRequest().setFilterFids([]))])
        expected = set([])
        assert result == expected, "Expected {} and got {} when testing for feature IDs filter".format(expected, result)

        # Rewind mid-way
        request = QgsFeatureRequest().setFilterFids([fids[1], fids[3], fids[4]])
        feature_it = self.provider.getFeatures(request)
        feature = QgsFeature()
        feature.setValid(True)
        self.assertTrue(feature_it.nextFeature(feature))
        self.assertIn(feature.id(), [fids[1], fids[3], fids[4]])
        first_feature = feature
        self.assertTrue(feature.isValid())
        # rewind
        self.assertTrue(feature_it.rewind())
        self.assertTrue(feature_it.nextFeature(feature))
        self.assertEqual(feature.id(), first_feature.id())
        self.assertTrue(feature.isValid())
        # grab all features
        self.assertTrue(feature_it.nextFeature(feature))
        self.assertTrue(feature_it.nextFeature(feature))
        # none left
        self.assertFalse(feature_it.nextFeature(feature))
        self.assertFalse(feature.isValid())
 def select_feature(self, point):
     '''Method to select feature from map canvas based on point location.'''
     # Select Features function from 
     # http://www.qgisworkshop.org/html/workshop/plugins_tutorial.html
     # setup the provider select to filter results based on a rectangle
     pntGeom = QgsGeometry.fromPoint(point)
     # scale-dependent buffer of 3 pixels-worth of map units
     pntBuff = pntGeom.buffer( (self.canvas.mapUnitsPerPixel() * 3), 0)
     rect = pntBuff.boundingBox()
     layers = qgis.utils.iface.mapCanvas().layers()
     nodes = str(self.ui.comboBoxInputNodes.currentText())
     for layer in layers:
         if layer.name() == nodes:
             provider = layer.dataProvider()
             if layer.geometryType() == QGis.Point:
                 feat = QgsFeature()
                 # create the select statement
                 provider.select([], rect) 
                 # the arguments mean no attributes returned and do a bbox 
                 # filter with our buffered rectangle to limit the amount 
                 #of features.
                 while provider.nextFeature(feat):
                     # if the feat geom returned from the selection 
                     #intersects our point then put it in selection list.
                     if feat.geometry().intersects(rect):
                         self.selected_nodes[self.nodetype] = feat.id()
                         self.output.clear()
                         self.output.insert(
                         str(feat.geometry().asPoint().x())+','
                                +str(feat.geometry().asPoint().y()))
                         layer.removeSelection()
                         for featid in self.selected_nodes.itervalues():
                             if featid is not None:
                                 layer.select(featid)
                     break # stop here to select one point only. 
Example #6
0
 def gotFeatureForIdentification(self, pos):
     """Show a dialog with road information """
     #pos is a rectangle
     self.mem_layer_obj.select()
     ftr = QgsFeature()
     ftr_ids = []
     while self.mem_layer_obj.nextFeature(ftr):
         if ftr.geometry().intersects(pos):
             ftr_ids.append(ftr.id())
     self.chosenFOIGeoms = []
     self.info = QgsMessageViewer()
     if ftr_ids != []:
         f = QgsFeature()
         foi_type = self.foi_type.lower()
         if foi_type == 'areaofinterestdefiner':
             ftrData = "You have selected the following feature(s) for use as an Area of Interest:\n\n"
         if foi_type == 'lineofinterestdefiner':
             ftrData = "You have selected the following feature(s) for use as a Line of Interest:\n\n"
         if foi_type == 'pointofinterestdefiner':
             ftrData = "You have selected the following feature(s) for use as a Point of Interest:\n\n"
         for fid in ftr_ids:
             self.mem_layer_obj.dataProvider().featureAtId(fid, f,  True)
             ftrData += f.attributeMap()[0].toString()
             ftrData += "\n_____________________________\n"
             self.chosenFOIGeoms.append(f.geometry())
             id_fid = self.addGeomToMemoryLayer(f.geometry())
         self.info.setMessageAsPlainText(ftrData)
     else:
         self.info.setMessageAsPlainText("no data to show")
     self.info.show()
     return
Example #7
0
    def testClear(self):
        s = QgsAuxiliaryStorage()
        self.assertTrue(s.isValid())

        # Create a new auxiliary layer with 'pk' as key
        vl = createLayer()
        pkf = vl.fields().field(vl.fields().indexOf('pk'))
        al = s.createAuxiliaryLayer(pkf, vl)
        self.assertTrue(al.isValid())
        vl.setAuxiliaryLayer(al)

        # Add a field in auxiliary layer
        p = QgsPropertyDefinition('myprop', QgsPropertyDefinition.DataTypeNumeric, '', '', 'me')
        self.assertFalse(al.exists(p))
        self.assertTrue(al.addAuxiliaryField(p))
        self.assertTrue(al.exists(p))

        # Count auxiliary features
        self.assertEqual(al.featureCount(), 0)

        # Set value for auxiliary fields
        req = QgsFeatureRequest().setFilterExpression("name = 'Honey'")
        f = QgsFeature()
        vl.getFeatures(req).nextFeature(f)
        self.assertTrue(f.isValid())
        afName = QgsAuxiliaryLayer.nameFromProperty(p, True)
        index = vl.fields().indexOf(afName)
        vl.changeAttributeValue(f.id(), index, 333)

        # Count auxiliary features
        self.assertEqual(al.featureCount(), 1)

        # Clear and count
        al.clear()
        self.assertEqual(al.featureCount(), 0)
Example #8
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)
Example #9
0
    def processAlgorithm(self, progress):
        layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT))

        buf = self.getParameterValue(self.BUFFER)

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            layer.pendingFields().toList(), QGis.WKBPolygon, layer.crs())

        inFeat = QgsFeature()
        outFeat = QgsFeature()
        extent = layer.extent()
        extraX = extent.height() * (buf / 100.0)
        extraY = extent.width() * (buf / 100.0)
        height = extent.height()
        width = extent.width()
        c = voronoi.Context()
        pts = []
        ptDict = {}
        ptNdx = -1

        features = vector.features(layer)
        for inFeat in features:
            geom = QgsGeometry(inFeat.geometry())
            point = geom.asPoint()
            x = point.x() - extent.xMinimum()
            y = point.y() - extent.yMinimum()
            pts.append((x, y))
            ptNdx += 1
            ptDict[ptNdx] = inFeat.id()

        if len(pts) < 3:
            raise GeoAlgorithmExecutionException(
                self.tr('Input file should contain at least 3 points. Choose '
                        'another file and try again.'))

        uniqueSet = Set(item for item in pts)
        ids = [pts.index(item) for item in uniqueSet]
        sl = voronoi.SiteList([voronoi.Site(i[0], i[1], sitenum=j) for (j,
                              i) in enumerate(uniqueSet)])
        voronoi.voronoi(sl, c)
        inFeat = QgsFeature()

        current = 0
        total = 100.0 / float(len(c.polygons))

        for (site, edges) in c.polygons.iteritems():
            request = QgsFeatureRequest().setFilterFid(ptDict[ids[site]])
            inFeat = layer.getFeatures(request).next()
            lines = self.clip_voronoi(edges, c, width, height, extent, extraX, extraY)

            geom = QgsGeometry.fromMultiPoint(lines)
            geom = QgsGeometry(geom.convexHull())
            outFeat.setGeometry(geom)
            outFeat.setAttributes(inFeat.attributes())
            writer.addFeature(outFeat)

            current += 1
            progress.setPercentage(int(current * total))

        del writer
Example #10
0
    def poly2nb(self):
        lst = []

        index = QgsSpatialIndex()
        featsA = self.lyr.getFeatures()
        featsB = self.lyr.getFeatures()
        for ft in featsA:
            index.insertFeature(ft)

        featB = QgsFeature()
        prv = self.lyr.dataProvider()
        while featsB.nextFeature(featB):
            geomB = featB.constGeometry()
            idb = featB.id()
            idxs = index.intersects(geomB.boundingBox())
            sor = []
            for idx in idxs:
                rqst = QgsFeatureRequest().setFilterFid(idx)
                featA = prv.getFeatures(rqst).next()
                ida = featA.id()
                geomA = QgsGeometry(featA.geometry())
                if idb!=ida:
                    if geomB.touches(geomA)==True:
                        sor.append(ida)

            lst.append(sor)

        return lst
Example #11
0
    def control(self):
        self.ids = []
        self.polynum = self.ml.featureCount()
        feat = QgsFeature()
        provider = self.ml.dataProvider()
        feats = provider.getFeatures()
        self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
        self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, self.polynum))
        ne = 0
        while feats.nextFeature(feat):
            ne += 1
            self.emit(SIGNAL("runStatus(PyQt_PyObject)"), ne)
            geom = QgsGeometry(feat.geometry())
            if geom.isMultipart():
                multi_polygon = geom.asMultiPolygon()
                for polygon in multi_polygon:
                    for ring in polygon:
                        for v in ring:
                            self.cintlen(str(v.x()))
                            self.cintlen(str(v.y()))
            else:
                polygon = geom.asPolygon()
                for ring in polygon:
                    for v in ring:
                        self.cintlen(str(v.x()))
                        self.cintlen(str(v.y()))

            self.ids.append(feat.id())
Example #12
0
 def compute(self, inVect, inField, value, perc, progressBar):
     mlayer = ftools_utils.getMapLayerByName(inVect)
     mlayer.removeSelection()
     vlayer = ftools_utils.getVectorLayerByName(inVect)
     vprovider = vlayer.dataProvider()
     index = vprovider.fieldNameIndex(inField)
     unique = ftools_utils.getUniqueValues(vprovider, int(index))
     inFeat = QgsFeature()
     selran = []
     nFeat = vprovider.featureCount() * len(unique)
     nElement = 0
     self.progressBar.setValue(0)
     self.progressBar.setRange(0, nFeat)
     if not len(unique) == mlayer.featureCount():
         for i in unique:
             fit = vprovider.getFeatures()
             FIDs= []
             while fit.nextFeature(inFeat):
                 atMap = inFeat.attributes()
                 if atMap[index] == i:
                     FID = inFeat.id()
                     FIDs.append(FID)
                 nElement += 1
                 self.progressBar.setValue(nElement)
             if perc: selVal = int(round((value / 100.0000) * len(FIDs), 0))
             else: selVal = value
             if selVal >= len(FIDs): selFeat = FIDs
             else: selFeat = random.sample(FIDs, selVal)
             selran.extend(selFeat)
         mlayer.setSelectedFeatures(selran)
     else:
         mlayer.setSelectedFeatures(range(0, mlayer.featureCount()))
Example #13
0
    def nbWithinDist(self):
        dlg = xdist.Dialog()
        dlg.setModal(True)
        dlg.setWindowTitle("Between two objects")
                
        if dlg.exec_() == QDialog.Accepted:
            lDist = float(dlg.lineEdit.text())
            if lDist==0:
                return

            feat = QgsFeature()
            provider = self.ml.dataProvider()
            e = provider.featureCount()

            self.settings()

            for ne in range(self.mod, e + self.mod):
                feat = QgsFeature()
                geom = QgsGeometry()
                fiter = self.ml.getFeatures(QgsFeatureRequest(ne))
                if fiter.nextFeature(feat):
                    geom = QgsGeometry(feat.geometry())

                neighbours = self.hdist(feat, lDist)
                row = feat.id()-self.mod
                self.model.setData(self.model.index(row, 0, QModelIndex()), neighbours)
                self.progressBar.setValue(100*ne/e)
    def processAlgorithm(self, parameters, context, feedback):
        filename = self.getParameterValue(self.INPUT)

        layer = QgsProcessingUtils.mapLayerFromString(filename, context)
        field = self.getParameterValue(self.FIELD)
        method = self.getParameterValue(self.METHOD)

        layer.removeSelection()
        index = layer.fields().lookupField(field)

        unique = QgsProcessingUtils.uniqueValues(layer, index, context)
        featureCount = layer.featureCount()

        value = int(self.getParameterValue(self.NUMBER))
        if method == 0:
            if value > featureCount:
                raise GeoAlgorithmExecutionException(
                    self.tr('Selected number is greater that feature count. '
                            'Choose lesser value and try again.'))
        else:
            if value > 100:
                raise GeoAlgorithmExecutionException(
                    self.tr("Percentage can't be greater than 100. Set a "
                            "different value and try again."))
            value = value / 100.0

        selran = []
        inFeat = QgsFeature()

        current = 0
        total = 100.0 / (featureCount * len(unique))

        if not len(unique) == featureCount:
            for i in unique:
                features = QgsProcessingUtils.getFeatures(layer, context)
                FIDs = []
                for inFeat in features:
                    attrs = inFeat.attributes()
                    if attrs[index] == i:
                        FIDs.append(inFeat.id())
                    current += 1
                    feedback.setProgress(int(current * total))

                if method == 1:
                    selValue = int(round(value * len(FIDs), 0))
                else:
                    selValue = value

                if selValue >= len(FIDs):
                    selFeat = FIDs
                else:
                    selFeat = random.sample(FIDs, selValue)

                selran.extend(selFeat)
            layer.selectByIds(selran)
        else:
            layer.selectByIds(list(range(featureCount)))  # FIXME: implies continuous feature ids

        self.setOutputValue(self.OUTPUT, filename)
    def processAlgorithm(self, progress):
        filename = self.getParameterValue(self.INPUT)

        layer = dataobjects.getObjectFromUri(filename)
        field = self.getParameterValue(self.FIELD)
        method = self.getParameterValue(self.METHOD)

        layer.removeSelection()
        index = layer.fieldNameIndex(field)

        unique = vector.getUniqueValues(layer, index)
        featureCount = layer.featureCount()

        value = int(self.getParameterValue(self.NUMBER))
        if method == 0:
            if value > featureCount:
                raise GeoAlgorithmExecutionException(
                    self.tr('Selected number is greater that feature count. '
                            'Choose lesser value and try again.'))
        else:
            if value > 100:
                raise GeoAlgorithmExecutionException(
                    self.tr("Percentage can't be greater than 100. Set a "
                            "different value and try again."))
            value = value / 100.0

        selran = []
        inFeat = QgsFeature()

        current = 0
        total = 100.0 / float(featureCount * len(unique))

        if not len(unique) == featureCount:
            for i in unique:
                features = vector.features(layer)
                FIDs = []
                for inFeat in features:
                    attrs = inFeat.attributes()
                    if attrs[index] == i:
                        FIDs.append(inFeat.id())
                    current += 1
                    progress.setPercentage(int(current * total))

                if method == 1:
                    selValue = int(round(value * len(FIDs), 0))
                else:
                    selValue = value

                if selValue >= len(FIDs):
                    selFeat = FIDs
                else:
                    selFeat = random.sample(FIDs, selValue)

                selran.extend(selFeat)
            layer.setSelectedFeatures(selran)
        else:
            layer.setSelectedFeatures(range(0, featureCount))

        self.setOutputValue(self.OUTPUT, filename)
Example #16
0
 def test_CreateFeature(self):
     feat = QgsFeature()
     feat.addAttribute(1, "text")
     feat.setGeometry(QgsGeometry.fromPoint(QgsPoint(123,456)))
     myId = feat.id()
     myExpectedId = 0
     myMessage = '\nExpected: %s\nGot: %s' % (myExpectedId, myId)
     assert myId == myExpectedId, myMessage
Example #17
0
 def hintersect(self, feata):
     geoma = QgsGeometry(feata.geometry())  
     feat = QgsFeature()
     provider = self.ml.dataProvider()
     feats = provider.getFeatures()
     self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0)
     self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, provider.featureCount())) 
     ne = 0              
     neighbours = ""
     while feats.nextFeature(feat):
         ne += 1
         self.emit(SIGNAL("runStatus(PyQt_PyObject)"), ne)                       
         geomb = QgsGeometry(feat.geometry())
         if feata.id()!=feat.id():
             if geoma.intersects(geomb)==True:
                 neighbours = neighbours + '%s,' % (feat.id()+self.p)
     return neighbours[:-1]
Example #18
0
    def accept(self):
        def updatefeautrefields(feature):
            for key, value in values.iteritems():
                try:
                    feature[key] = value
                except KeyError:
                    continue
            return feature

        if not self.featureform.allpassing:
            self.bar.pushMessage("Missing fields", "Some fields are still required.",
                                 QgsMessageBar.WARNING, duration=2)
            return

        if not self.featureform:
            return

        if not self.featureform.accept():
            return

        layer = self.featureform.form.QGISLayer
        before = QgsFeature(self.feature)
        before.setFields(self.fields, initAttributes=False)

        values, savedvalues = self.featureform.getvalues()

        after = QgsFeature(self.feature)
        after.setFields(self.fields, initAttributes=False)
        after = updatefeautrefields(after)

        layer.startEditing()
        if after.id() > 0:
            if self.project.historyenabled(layer):
                # Mark the old one as history
                before['status'] = 'H'
                after['status'] = 'C'
                after['dateedited'] = QDateTime.currentDateTime()
                after['editedby'] = getpass.getuser()
                layer.addFeature(after)
                layer.updateFeature(before)
            else:
                layer.updateFeature(after)
        else:
            layer.addFeature(after)
            featureform.savevalues(layer, savedvalues)

        saved = layer.commitChanges()

        if not saved:
            self.failedsave.emit(layer.commitErrors())
            map(error, layer.commitErrors())
        else:
            self.featureform.featuresaved(after, values)
            self.featuresaved.emit()

        self.accepted.emit()
        self.featureform = None
Example #19
0
 def checkAfter():
     # check select+nextFeature
     f = QgsFeature()
     layer.select([])
     assert layer.nextFeature(f)
     assert f.geometry().asPoint() == QgsPoint(300,400)
     # check feature at id
     f2 = QgsFeature()
     assert layer.featureAtId(f.id(), f2)
     assert f2.geometry().asPoint() == QgsPoint(300,400)
Example #20
0
 def checkAfter():
     # check select+nextFeature
     f = QgsFeature()
     layer.select([0,1])
     assert layer.nextFeature(f)
     assert f.attributes()[0].toString() == "good"
     
     # check feature at id
     f2 = QgsFeature()
     assert layer.featureAtId(f.id(), f2)
     assert f2.attributes()[0].toString() == "good"
Example #21
0
 def checkAfter():
     assert len(layer.pendingFields()) == 2
     # check feature
     f = QgsFeature()
     layer.select(layer.pendingAllAttributesList())
     assert layer.nextFeature(f)
     assert f.geometry().asPoint() == QgsPoint(2,2)
     # check feature at id
     f2 = QgsFeature()
     assert layer.featureAtId(f.id(), f2)
     assert f2.geometry().asPoint() == QgsPoint(2,2)
Example #22
0
    def test_join(self):

        joinLayer = createJoinLayer()
        joinLayer2 = createJoinLayer()
        QgsMapLayerRegistry.instance().addMapLayers([joinLayer, joinLayer2])

        layer = createLayerWithOnePoint()

        join = QgsVectorJoinInfo()
        join.targetFieldName = "fldint"
        join.joinLayerId = joinLayer.id()
        join.joinFieldName = "y"
        join.memoryCache = True

        layer.addJoin(join)

        join2 = QgsVectorJoinInfo()
        join2.targetFieldName = "fldint"
        join2.joinLayerId = joinLayer2.id()
        join2.joinFieldName = "y"
        join2.memoryCache = True
        join2.prefix = "custom-prefix_"

        layer.addJoin(join2)

        flds = layer.pendingFields()
        assert len(flds) == 6
        assert flds[2].name() == "joinlayer_x"
        assert flds[3].name() == "joinlayer_z"
        assert flds[4].name() == "custom-prefix_x"
        assert flds[5].name() == "custom-prefix_z"
        assert flds.fieldOrigin(0) == QgsFields.OriginProvider
        assert flds.fieldOrigin(2) == QgsFields.OriginJoin
        assert flds.fieldOrigin(3) == QgsFields.OriginJoin
        assert flds.fieldOriginIndex(0) == 0
        assert flds.fieldOriginIndex(2) == 0
        assert flds.fieldOriginIndex(3) == 2

        f = QgsFeature()
        fi = layer.getFeatures()
        assert fi.nextFeature(f)
        attrs = f.attributes()
        assert len(attrs) == 6
        assert attrs[0] == "test"
        assert attrs[1] == 123
        assert attrs[2] == "foo"
        assert attrs[3] == 321
        assert not fi.nextFeature(f)

        f2 = layer.getFeatures(QgsFeatureRequest(f.id())).next()
        assert len(f2.attributes()) == 6
        assert f2[2] == "foo"
        assert f2[3] == 321
Example #23
0
    def test_join(self):

        joinLayer = createJoinLayer()
        joinLayer2 = createJoinLayer()
        QgsMapLayerRegistry.instance().addMapLayers([joinLayer, joinLayer2])

        layer = createLayerWithOnePoint()

        join = QgsVectorJoinInfo()
        join.targetFieldName = "fldint"
        join.joinLayerId = joinLayer.id()
        join.joinFieldName = "y"
        join.memoryCache = True

        layer.addJoin(join)

        join2 = QgsVectorJoinInfo()
        join2.targetFieldName = "fldint"
        join2.joinLayerId = joinLayer2.id()
        join2.joinFieldName = "y"
        join2.memoryCache = True
        join2.prefix = "custom-prefix_"

        layer.addJoin(join2)

        flds = layer.pendingFields()
        self.assertEquals(len(flds), 6)
        self.assertEquals(flds[2].name(), "joinlayer_x")
        self.assertEquals(flds[3].name(), "joinlayer_z")
        self.assertEquals(flds[4].name(), "custom-prefix_x")
        self.assertEquals(flds[5].name(), "custom-prefix_z")
        self.assertEquals(flds.fieldOrigin(0), QgsFields.OriginProvider)
        self.assertEquals(flds.fieldOrigin(2), QgsFields.OriginJoin)
        self.assertEquals(flds.fieldOrigin(3), QgsFields.OriginJoin)
        self.assertEquals(flds.fieldOriginIndex(0), 0)
        self.assertEquals(flds.fieldOriginIndex(2), 0)
        self.assertEquals(flds.fieldOriginIndex(3), 2)

        f = QgsFeature()
        fi = layer.getFeatures()
        self.assertTrue(fi.nextFeature(f))
        attrs = f.attributes()
        self.assertEquals(len(attrs), 6)
        self.assertEquals(attrs[0], "test")
        self.assertEquals(attrs[1], 123)
        self.assertEquals(attrs[2], "foo")
        self.assertEquals(attrs[3], 321)
        self.assertFalse(fi.nextFeature(f))

        f2 = layer.getFeatures(QgsFeatureRequest(f.id())).next()
        self.assertEquals(len(f2.attributes()), 6)
        self.assertEquals(f2[2], "foo")
        self.assertEquals(f2[3], 321)
Example #24
0
 def addGeomToLayer(self,geom,layer):
     """
     Add a geometry to a layer as a new feature
     No attributes are set
     """
     fet = QgsFeature()
     fet.setGeometry(geom)
     area=geom.area()#/1000000
     if self.debug: print "Area of geom added to layer:", str(area)
     layer.dataProvider().addFeatures([fet])
     layer.dataProvider().changeAttributeValues({fet.id(): { 0: area}});
     layer.updateExtents()
Example #25
0
def cloneAsMemoryLayer(layer, name, styleURI=None, symbology=None):
    if (layer is not None and layer.isValid() and layer.type() == QgsMapLayer.VectorLayer):
        if styleURI is None and symbology is None:
            symbology = getSymbology(layer)
        mem = createMemoryLayer(name, layer.wkbType(), layer.crs(), layer.dataProvider().fields(), styleURI, symbology)
        # Hack required to keep fields defined!
        mem.startEditing()
        ft = QgsFeature(layer.dataProvider().fields())
        mem.addFeature(ft)
        mem.deleteFeature(ft.id())
        mem.commitChanges()
        return mem
    return QgsVectorLayer()
Example #26
0
        def checkAfter():
            assert layer.pendingFeatureCount() == 1

            # check select+nextFeature
            layer.select([])
            f = QgsFeature()
            assert layer.nextFeature(f)
            assert f.geometry().asPoint() == QgsPoint(1,2)
            
            # check feature at id
            f2 = QgsFeature()
            assert layer.featureAtId(f.id(), f2)
            assert f2.geometry().asPoint() == QgsPoint(1,2)
Example #27
0
    def test_ChangeAttributeAfterAddFeature(self):
        layer = createLayerWithOnePoint()
        layer.dataProvider().deleteFeatures([1]) # no need for this feature
        
        newF = QgsFeature()
        newF.setGeometry( QgsGeometry.fromPoint(QgsPoint(1,1)) )
        newF.setAttributes( [ QVariant("hello"), QVariant(42) ] )
        
        def checkAfter():
            assert len(layer.pendingFields()) == 2
            # check feature
            f = QgsFeature()
            layer.select(layer.pendingAllAttributesList())
            assert layer.nextFeature(f)
            attrs = f.attributes()
            assert len(attrs) == 2
            assert attrs[0].toString() == "hello"
            assert attrs[1].toInt()[0] == 12

            assert not layer.nextFeature(f)
            
            # check feature at id
            f2 = QgsFeature()
            assert layer.featureAtId(f.id(), f2)
            assert f2[0].toString() == "hello"
            assert f2[1].toInt()[0] == 12
            
        def checkBefore():
            # check feature
            f = QgsFeature()
            layer.select(layer.pendingAllAttributesList())
            assert not layer.nextFeature(f)

        checkBefore()

        layer.startEditing()
        layer.beginEditCommand("AddFeature + ChangeAttribute")
        assert layer.addFeature(newF)
        assert layer.changeAttributeValue(newF.id(), 1, QVariant(12))
        layer.endEditCommand()
        
        checkAfter()

        # now try undo/redo
        layer.undoStack().undo()
        checkBefore()
        layer.undoStack().redo()
        checkAfter()

        assert layer.commitChanges()
        checkAfter()
    def search(self):
        project = QgsProject.instance()
        layerId, ok = project.readEntry(self.pluginName, 'layerId')
        fieldName, ok = project.readEntry(self.pluginName, 'fieldName')
        pattern = self.searchText.text()

        self.layer = QgsMapLayerRegistry.instance().mapLayer(layerId)
        if self.layer is None:
            self.iface.messageBar().pushMessage(self.name,
                self.tr("Choose a layer first in settings dialog."),
                QgsMessageBar.WARNING, 3)
            self.showSettings()
            return

        if fieldName == "":
            self.iface.messageBar().pushMessage(self.name,
                self.tr("Choose a field first in settings dialog."),
                QgsMessageBar.WARNING, 3)
            self.showSettings()
            return
        fields = self.layer.dataProvider().fields()
        fieldIndex = fields.indexFromName(fieldName)

        # create feature request
        featReq = QgsFeatureRequest()
        featReq.setFlags(QgsFeatureRequest.NoGeometry)
        featReq.setSubsetOfAttributes([fieldIndex])
        iterator = self.layer.getFeatures(featReq)

        # process search
        f = QgsFeature()
        results = []
        self.continueSearch = True
        while iterator.nextFeature(f) and self.continueSearch:
            if self.evaluate(f[fieldName], pattern):
                results.append(f.id())
            QCoreApplication.processEvents()

        # process results
        if self.continueSearch:
            msg = self.tr("{} features found").format(len(results))

            legend = self.iface.legendInterface()
            if (not legend.isLayerVisible(self.layer)):
                msg += self.tr(' - The layer named {} is not visible').format(self.layer.name())

            self.iface.messageBar().pushMessage(self.name,
                msg,
                QgsMessageBar.INFO, 2)

            self.processResults(results)
Example #29
0
    def testFiltersWithoutUid(self):
        ml = QgsVectorLayer("Point?srid=EPSG:4326&field=a:int", "mem_no_uid", "memory")
        self.assertEqual(ml.isValid(), True)
        QgsProject.instance().addMapLayer(ml)

        # a memory layer with 10 features
        ml.startEditing()
        for i in range(10):
            f = QgsFeature(ml.fields())
            f.setGeometry(QgsGeometry.fromWkt('POINT({} 0)'.format(i)))
            f.setAttributes([i])
            ml.addFeatures([f])
        ml.commitChanges()

        df = QgsVirtualLayerDefinition()
        df.setQuery('select * from mem_no_uid')
        vl = QgsVectorLayer(df.toString(), "vl", "virtual")
        self.assertEqual(vl.isValid(), True)

        # make sure the returned id with a filter is the same as
        # if there is no filter
        req = QgsFeatureRequest().setFilterRect(QgsRectangle(4.5, -1, 5.5, 1))
        fids = [f.id() for f in vl.getFeatures(req)]
        self.assertEqual(fids, [5])

        req = QgsFeatureRequest().setFilterExpression("a = 5")
        fids = [f.id() for f in vl.getFeatures(req)]
        self.assertEqual(fids, [5])

        req = QgsFeatureRequest().setFilterFid(5)
        a = [(f.id(), f['a']) for f in vl.getFeatures(req)]
        self.assertEqual(a, [(5, 5)])

        req = QgsFeatureRequest().setFilterFids([5, 6, 8])
        a = [(f.id(), f['a']) for f in vl.getFeatures(req)]
        self.assertEqual(a, [(5, 5), (6, 6), (8, 8)])

        QgsProject.instance().removeMapLayer(ml)
Example #30
0
    def test_getFeatures(self):

        layer = createLayerWithOnePoint()

        f = QgsFeature()
        fi = layer.getFeatures()
        assert fi.nextFeature(f) == True
        assert f.isValid() == True
        assert f.id() == 1
        assert f.geometry().asPoint() == QgsPoint(100,200)
        assert f["fldtxt"] == "test"
        assert f["fldint"] == 123

        assert fi.nextFeature(f) == False
class NEDOriginDrawer:
    def __init__(self, proj, vehicle_info):
        self.proj = proj
        self.vehicle_info = vehicle_info
        self.ned_origin_layer = QgsVectorLayer("Point?crs=epsg:4326",
                                               "NED Origin", "memory")
        self.feat = QgsFeature()
        self.ned_origin_layer.dataProvider().addFeature(self.feat)
        self.ned_origin_layer.setRenderer(self.ned_origin_renderer())
        self.ned_origin_layer.setCustomProperty("ned_origin", "NED Origin")

        self.ned_lat = None
        self.ned_lon = None

    def ned_origin_renderer(self):
        symbol = QgsSymbol.defaultSymbol(self.ned_origin_layer.geometryType())
        svg_style = {
            'fill': '# 0000ff',
            'name': ':/resources/Star2.svg',
            'outline': '#000000',
            'outline - width': '6.8',
            'size': '6'
        }
        # create svg symbol layer
        sym_lyr1 = QgsSvgMarkerSymbolLayer.create(svg_style)
        # Replace the default layer with our custom layer
        symbol.deleteSymbolLayer(0)
        symbol.appendSymbolLayer(sym_lyr1)
        # Replace the renderer of the current layer
        renderer = QgsSingleSymbolRenderer(symbol)
        return renderer

    def update_ned_point(self):
        try:
            self.ned_lat = float(
                cola2_interface.get_ros_param(
                    self.vehicle_info.get_vehicle_ip(), 9091,
                    self.vehicle_info.get_vehicle_namespace() +
                    '/navigator/ned_latitude')['value'])
            self.ned_lon = float(
                cola2_interface.get_ros_param(
                    self.vehicle_info.get_vehicle_ip(), 9091,
                    self.vehicle_info.get_vehicle_namespace() +
                    '/navigator/ned_longitude')['value'])

            # layer is not yet in the project, add it
            if len(self.proj.mapLayersByName('NED Origin')) == 0:
                self.feat.setGeometry(
                    QgsGeometry.fromPointXY(
                        QgsPointXY(self.ned_lon, self.ned_lat)))
                self.ned_origin_layer.dataProvider().addFeatures([self.feat])
                self.proj.addMapLayer(self.ned_origin_layer, True)
            else:
                self.ned_origin_layer.startEditing()
                self.ned_origin_layer.moveVertex(self.ned_lon, self.ned_lat,
                                                 self.feat.id() + 1, 0)
                self.ned_origin_layer.commitChanges()

        except:
            QMessageBox.warning(None, "NED Origin update",
                                "Could not read NED origin topic.",
                                QMessageBox.Close)
Example #32
0
    def test_invalidGeometryFilter(self):
        layer = QgsVectorLayer("Polygon?field=x:string", "joinlayer", "memory")

        # add some features, one has invalid geometry
        pr = layer.dataProvider()
        f1 = QgsFeature(1)
        f1.setAttributes(["a"])
        f1.setGeometry(
            QgsGeometry.fromWkt('Polygon((0 0, 1 0, 1 1, 0 1, 0 0))'))  # valid
        f2 = QgsFeature(2)
        f2.setAttributes(["b"])
        f2.setGeometry(
            QgsGeometry.fromWkt(
                'Polygon((0 0, 1 0, 0 1, 1 1, 0 0))'))  # invalid
        f3 = QgsFeature(3)
        f3.setAttributes(["c"])
        f3.setGeometry(
            QgsGeometry.fromWkt('Polygon((0 0, 1 0, 1 1, 0 1, 0 0))'))  # valid
        self.assertTrue(pr.addFeatures([f1, f2, f3]))

        res = [
            f['x'] for f in layer.getFeatures(QgsFeatureRequest(
            ).setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck))
        ]
        self.assertEqual(res, ['a', 'b', 'c'])
        res = [
            f['x'] for f in layer.getFeatures(QgsFeatureRequest(
            ).setInvalidGeometryCheck(QgsFeatureRequest.GeometrySkipInvalid))
        ]
        self.assertEqual(res, ['a', 'c'])
        res = [
            f['x'] for f in layer.getFeatures(
                QgsFeatureRequest().setInvalidGeometryCheck(
                    QgsFeatureRequest.GeometryAbortOnInvalid))
        ]
        self.assertEqual(res, ['a'])

        # with callback
        self.callback_feature_val = None

        def callback(feature):
            self.callback_feature_val = feature['x']

        res = [
            f['x'] for f in layer.getFeatures(QgsFeatureRequest(
            ).setInvalidGeometryCheck(QgsFeatureRequest.GeometryAbortOnInvalid
                                      ).setInvalidGeometryCallback(callback))
        ]
        self.assertEqual(res, ['a'])
        self.assertEqual(self.callback_feature_val, 'b')
        # clear callback
        res = [
            f['x'] for f in layer.getFeatures(QgsFeatureRequest(
            ).setInvalidGeometryCheck(QgsFeatureRequest.GeometryAbortOnInvalid
                                      ).setInvalidGeometryCallback(None))
        ]
        self.assertEqual(res, ['a'])

        # check with filter fids
        res = [
            f['x']
            for f in layer.getFeatures(QgsFeatureRequest().setFilterFid(f2.id(
            )).setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck))
        ]
        self.assertEqual(res, ['b'])
        res = [
            f['x']
            for f in layer.getFeatures(QgsFeatureRequest().setFilterFid(f2.id(
            )).setInvalidGeometryCheck(QgsFeatureRequest.GeometrySkipInvalid))
        ]
        self.assertEqual(res, [])
        res = [
            f['x'] for f in layer.getFeatures(QgsFeatureRequest().setFilterFid(
                f2.id()).setInvalidGeometryCheck(
                    QgsFeatureRequest.GeometryAbortOnInvalid))
        ]
        self.assertEqual(res, [])

        f4 = QgsFeature(4)
        f4.setAttributes(["d"])
        f4.setGeometry(
            QgsGeometry.fromWkt(
                'Polygon((0 0, 1 0, 0 1, 1 1, 0 0))'))  # invalid

        # check with added features
        layer.startEditing()
        self.assertTrue(layer.addFeatures([f4]))
        res = [
            f['x'] for f in layer.getFeatures(QgsFeatureRequest(
            ).setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck))
        ]
        self.assertEqual(set(res), {'a', 'b', 'c', 'd'})
        res = [
            f['x'] for f in layer.getFeatures(QgsFeatureRequest(
            ).setInvalidGeometryCheck(QgsFeatureRequest.GeometrySkipInvalid))
        ]
        self.assertEqual(set(res), {'a', 'c'})
        res = [
            f['x'] for f in layer.getFeatures(
                QgsFeatureRequest().setInvalidGeometryCheck(
                    QgsFeatureRequest.GeometryAbortOnInvalid))
        ]
        self.assertEqual(res, ['a'])

        # check with features with changed geometry
        layer.rollBack()
        layer.startEditing()
        layer.changeGeometry(
            2,
            QgsGeometry.fromWkt('Polygon((0 0, 1 0, 1 1, 0 1, 0 0))'))  # valid
        layer.changeGeometry(
            3, QgsGeometry.fromWkt(
                'Polygon((0 0, 1 0, 0 1, 1 1, 0 0))'))  # invalid
        res = [
            f['x'] for f in layer.getFeatures(QgsFeatureRequest(
            ).setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck))
        ]
        self.assertEqual(set(res), {'a', 'b', 'c'})
        res = [
            f['x'] for f in layer.getFeatures(QgsFeatureRequest(
            ).setInvalidGeometryCheck(QgsFeatureRequest.GeometrySkipInvalid))
        ]
        self.assertEqual(set(res), {'a', 'b'})
        res = [
            f['x'] for f in layer.getFeatures(
                QgsFeatureRequest().setInvalidGeometryCheck(
                    QgsFeatureRequest.GeometryAbortOnInvalid))
        ]
        self.assertEqual(res, ['a', 'b'])
        layer.rollBack()
Example #33
0
    def processAlgorithm(self, parameters, context, feedback):
        inLayer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
        boundary = self.parameterAsEnum(parameters, self.MODE, context) == self.MODE_BOUNDARY
        smallestArea = self.parameterAsEnum(parameters, self.MODE, context) == self.MODE_SMALLEST_AREA

        if inLayer.selectedFeatureCount() == 0:
            feedback.reportError(self.tr('{0}: (No selection in input layer "{1}")').format(self.displayName(), parameters[self.INPUT]))

        featToEliminate = []
        selFeatIds = inLayer.selectedFeatureIds()

        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
                                               inLayer.fields(), inLayer.wkbType(), inLayer.sourceCrs())
        if sink is None:
            raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))

        for aFeat in inLayer.getFeatures():
            if feedback.isCanceled():
                break

            if aFeat.id() in selFeatIds:
                # Keep references to the features to eliminate
                featToEliminate.append(aFeat)
            else:
                # write the others to output
                sink.addFeature(aFeat, QgsFeatureSink.FastInsert)

        # Delete all features to eliminate in processLayer
        processLayer = QgsProcessingUtils.mapLayerFromString(dest_id, context)
        processLayer.startEditing()

        # ANALYZE
        if len(featToEliminate) > 0:  # Prevent zero division
            start = 20.00
            add = 80.00 / len(featToEliminate)
        else:
            start = 100

        feedback.setProgress(start)
        madeProgress = True

        # We go through the list and see if we find any polygons we can
        # merge the selected with. If we have no success with some we
        # merge and then restart the whole story.
        while madeProgress:  # Check if we made any progress
            madeProgress = False
            featNotEliminated = []

            # Iterate over the polygons to eliminate
            for i in range(len(featToEliminate)):
                if feedback.isCanceled():
                    break

                feat = featToEliminate.pop()
                geom2Eliminate = feat.geometry()
                bbox = geom2Eliminate.boundingBox()
                fit = processLayer.getFeatures(
                    QgsFeatureRequest().setFilterRect(bbox).setSubsetOfAttributes([]))
                mergeWithFid = None
                mergeWithGeom = None
                max = 0
                min = -1
                selFeat = QgsFeature()

                # use prepared geometries for faster intersection tests
                engine = QgsGeometry.createGeometryEngine(geom2Eliminate.constGet())
                engine.prepareGeometry()

                while fit.nextFeature(selFeat):
                    if feedback.isCanceled():
                        break

                    selGeom = selFeat.geometry()

                    if engine.intersects(selGeom.constGet()):
                        # We have a candidate
                        iGeom = geom2Eliminate.intersection(selGeom)

                        if not iGeom:
                            continue

                        if boundary:
                            selValue = iGeom.length()
                        else:
                            # area. We need a common boundary in
                            # order to merge
                            if 0 < iGeom.length():
                                selValue = selGeom.area()
                            else:
                                selValue = -1

                        if -1 != selValue:
                            useThis = True

                            if smallestArea:
                                if -1 == min:
                                    min = selValue
                                else:
                                    if selValue < min:
                                        min = selValue
                                    else:
                                        useThis = False
                            else:
                                if selValue > max:
                                    max = selValue
                                else:
                                    useThis = False

                            if useThis:
                                mergeWithFid = selFeat.id()
                                mergeWithGeom = QgsGeometry(selGeom)
                # End while fit

                if mergeWithFid is not None:
                    # A successful candidate
                    newGeom = mergeWithGeom.combine(geom2Eliminate)

                    if processLayer.changeGeometry(mergeWithFid, newGeom):
                        madeProgress = True
                    else:
                        raise QgsProcessingException(
                            self.tr('Could not replace geometry of feature with id {0}').format(mergeWithFid))

                    start = start + add
                    feedback.setProgress(start)
                else:
                    featNotEliminated.append(feat)

            # End for featToEliminate

            featToEliminate = featNotEliminated

        # End while
        if not processLayer.commitChanges():
            raise QgsProcessingException(self.tr('Could not commit changes'))

        for feature in featNotEliminated:
            if feedback.isCanceled():
                break

            sink.addFeature(feature, QgsFeatureSink.FastInsert)

        return {self.OUTPUT: dest_id}
Example #34
0
    def evaluate(self):

        #Write parameters to GIS
        bfeat = QgsFeature()
        featreq = QgsFeatureRequest()
        i = 0
        attr = {}
        for featid in self.bfeatids:
            i += 1
            attr.clear()
            bfeat = next(
                self.sim.blayer.getFeatures(featreq.setFilterFid(featid)))
            for key in sorted(self.ofile.OptAttributes.keys()):
                bfindx = self.sim.bprovider.fieldNameIndex(
                    self.ofile.OptAttributes[key][0])
                ftype = str(self.sim.bprovider.fields()[bfindx].typeName())
                if ftype in ['Integer', 'Integer64']:
                    value = int(self.current.x[key])
                elif ftype in ['Real', 'Double']:
                    value = float(self.current.x[key])
                if int(self.ofile.OptAttributes[key][4]) in [0, i]:
                    attr.update({bfindx: value})
            result = self.sim.bprovider.changeAttributeValues(
                {bfeat.id(): attr})
            if not result:
                self.setCursor(Qt.ArrowCursor)
                QMessageBox.critical(self, 'Simulation Optimizer',
                                     'Could not change attribute value1.')
                return

        #Can't get attribute table repainting to work for all conditions.
        self.sim.blayer.selectByIds(self.bfeatids)
        QApplication.processEvents()

        #Run simulations
        for featid in self.bfeatids:
            self.sim.ui.cbxOnlySelected.setChecked(1)
            self.sim.blayer.selectByIds([featid])
            self.sim.on_btnRun_clicked()
            self.ui.textSimulation.append(self.sim.p.stdout)
            self.ui.textSimulation.append(self.sim.p.stderr)

        #Calculate error
        sqrerr = []
        for featid in self.bfeatids:
            bfeat = next(
                self.sim.blayer.getFeatures(featreq.setFilterFid(featid)))
            for key in sorted(self.ofile.ObjAttributes.keys()):
                measured = float(
                    bfeat.attribute(self.ofile.ObjAttributes[key][0]))
                simulated = float(
                    bfeat.attribute(self.ofile.ObjAttributes[key][1]))
                factor = float(self.ofile.ObjAttributes[key][2])
                error = (simulated - measured) * factor
                #error = (simulated - measured) / measured
                #error = (simulated - measured)
                sqrerr.append(error * error)

        sumsq = sum(sqrerr) / len(sqrerr)
        rmse = math.sqrt(sumsq)

        #Output
        string = '%4d ' % self.iterat
        string += '%11.5f ' % self.T
        string += '%5d ' % self.feval
        string += '%5.3f ' % self.p
        string += '%4d ' % self.accepted
        string += '%4d ' % self.declined
        if self.best.cost:
            string += ('%10.4f ' % self.best.cost)
        else:
            string += ('%10.4f ' % rmse)
        string += ('%10.4f ' % rmse)
        for i in self.best.x:
            string += '%10.4f ' % i
        for i in self.current.x:
            string += '%10.4f ' % i
        self.ui.textOptimization.append(string)
        f = open(self.logfile, 'a')
        f.write(string + '\n')
        f.close()

        return rmse
Example #35
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)'
            })
Example #36
0
    def testGetFeaturesFidsTests(self):
        fids = [f.id() for f in self.source.getFeatures()]
        self.assertEqual(len(fids), 5)

        # empty list = no features
        request = QgsFeatureRequest().setFilterFids([])
        result = set([f.id() for f in self.source.getFeatures(request)])
        self.assertFalse(result)

        request = QgsFeatureRequest().setFilterFids([fids[0], fids[2]])
        result = set([f.id() for f in self.source.getFeatures(request)])
        all_valid = (all(f.isValid()
                         for f in self.source.getFeatures(request)))
        expected = set([fids[0], fids[2]])
        assert result == expected, 'Expected {} and got {} when testing for feature IDs filter'.format(
            expected, result)
        self.assertTrue(all_valid)

        # test that results match QgsFeatureRequest.acceptFeature
        for f in self.source.getFeatures():
            self.assertEqual(request.acceptFeature(f), f.id() in expected)

        result = set([
            f.id() for f in self.source.getFeatures(
                QgsFeatureRequest().setFilterFids([fids[1], fids[3], fids[4]]))
        ])
        expected = set([fids[1], fids[3], fids[4]])
        assert result == expected, 'Expected {} and got {} when testing for feature IDs filter'.format(
            expected, result)

        #sources should ignore non-existent fids
        result = set([
            f.id()
            for f in self.source.getFeatures(QgsFeatureRequest().setFilterFids(
                [-101, fids[1], -102, fids[3], -103, fids[4], -104]))
        ])
        expected = set([fids[1], fids[3], fids[4]])
        assert result == expected, 'Expected {} and got {} when testing for feature IDs filter'.format(
            expected, result)

        result = set([
            f.id() for f in self.source.getFeatures(
                QgsFeatureRequest().setFilterFids([]))
        ])
        expected = set([])
        assert result == expected, 'Expected {} and got {} when testing for feature IDs filter'.format(
            expected, result)

        # Rewind mid-way
        request = QgsFeatureRequest().setFilterFids(
            [fids[1], fids[3], fids[4]])
        feature_it = self.source.getFeatures(request)
        feature = QgsFeature()
        feature.setValid(True)
        self.assertTrue(feature_it.nextFeature(feature))
        self.assertIn(feature.id(), [fids[1], fids[3], fids[4]])
        first_feature = feature
        self.assertTrue(feature.isValid())
        # rewind
        self.assertTrue(feature_it.rewind())
        self.assertTrue(feature_it.nextFeature(feature))
        self.assertEqual(feature.id(), first_feature.id())
        self.assertTrue(feature.isValid())
        # grab all features
        self.assertTrue(feature_it.nextFeature(feature))
        self.assertTrue(feature_it.nextFeature(feature))
        # none left
        self.assertFalse(feature_it.nextFeature(feature))
        self.assertFalse(feature.isValid())
Example #37
0
    def run(self):

        # Converter escala textual para numérica (denominador)
        escala = self.escalaAvaliacao.currentText() # '1:100.000'
        escalaAval = escala.split(':')[1].replace('.','')    
        escalaAval = int(escalaAval)
        
        self.canvas.zoomScale(escalaAval)

        listaHomologosXY = {} # dicionario yx.
        listaHomologosZ = {} # dicionario z.    
       
        # Raio definido
        raio = self.spinBox.value()

        # Layers selecionados
        layer1 = self.referenciaComboBox.currentLayer()
        layer2 = self.avaliacaoComboBox.currentLayer()

        # Teste para identificar se esta setado.
        XY = False 
        Z = False

        if self.xy.isChecked():
            XY = True 
        if self.z.isChecked(): 
            Z = True

        # Troca de referência CRS para uma que utiliza medição em metros (3857).
        source1 = layer1.crs()
        source2 = layer2.crs()
        dest = QgsCoordinateReferenceSystem(3857)

        tr1 = QgsCoordinateTransform(source1, dest)
        tr2 = QgsCoordinateTransform(source2, dest)

        lista1 = [feat1 for feat1 in layer1.getFeatures()]
        lista2 = [feat2 for feat2 in layer2.getFeatures()]
        lista3 = []
         
        spIndex1 = QgsSpatialIndex()
        neighbour = QgsFeature()
        
        for feat1 in lista1: 

            spIndex1.insertFeature(feat1)  # transforma features em indices espaciais
            geom1 = QgsGeometry(feat1.geometry()) 
            geom1.transform(tr1)        
            raioTeste = raio 
            neighbour = None
            encontrado =  False
                        
            for feat2 in lista2:

                pt = feat2.geometry().asPoint()
                nearestid = spIndex1.nearestNeighbor(pt, 2)[0] # realiza a analise do vizinho mais próximo, numero de vizinhos é definido no segundo argumento.
                #print nearestid
                request = QgsFeatureRequest().setFilterFid(nearestid)
                geom2 = QgsGeometry(feat2.geometry()) 
                geom2.transform(tr2) 

                if geom1.buffer (raioTeste, 20 ) .contains (geom2):
                     raioTeste = sqrt (geom1.asPoint (). sqrDist (geom2.asPoint ()))
                     neighbour = feat2  
                     encontrado = True
                  
            # apenas pra descobrir se não foi encontrado.
            if encontrado == False: 
                #print u'\nHouve pontos nao encontrados dentro do raio definido.'
                frase = ("<span style='color:purple'>HOUVE PONTOS NAO ENCONTRADOS.</span>")
                lista3.append(frase)
            
            else:
                if XY:
                    listaHomologosXY[int(feat1.id()), int(neighbour.id())] = (raioTeste)
                
                if Z:
                    listaHomologosZ[int(feat1.id()), int(neighbour.id())]  = feat1.geometry().geometry().z() - neighbour.geometry().geometry().z()
                lista2.remove(neighbour)     

        if XY or Z:   
            #print '\nHomologos: \n', listaHomologosXY.keys()
            distAcum = 0
             
            resultado2 = "<span style='color:orange'>DISTANCIA ENTRE PONTOS: </span>",[ round(v, 2) for v in listaHomologosXY.values()]
            resultado1 = "<span style='color:orange'>PONTOS HOMOLOGOS: </span>",listaHomologosXY.keys()
            #print '\nDistancia entre pontos Homologados:\n',resultado2
            lista3.append(resultado1)
            lista3.append(resultado2)      
        
        if XY: 
            distAcum = 0
            for valorXY in listaHomologosXY.values():
                distAcum += valorXY    

            resultado = int(distAcum / len(listaHomologosXY))
            #print '\nDistancia media:\n', round(resultado,2)  
            b = "<span style='color:orange'>DISTANCIA MEDIA: </span>", round(resultado,2)
            lista3.append(b)
        
        if Z:
            zAcum = 0     
            for valorZ in listaHomologosZ.values(): 
                zAcum += valorZ

            resultado = int(zAcum / len(listaHomologosZ)) 
            #print '\nDiferenca media de elevacao: \n', round(resultado,3)
            a = "<span style='color:orange'>DISTANCIA MEDIA DE ELEVACAO: </span>", round(resultado,3)
            lista3.append(a)

        # Formatação para apresentar QmessageBox de forma bem distribuida.
        message = u""
        one_data = u"<p>{0}</p>"
        two_data = u"<p>{0} {1}</p>"
        for data in lista3:
            message += one_data.format(data) if type(data) == str else two_data.format(data[0], data[1])
  
        QMessageBox.about(self, "RESULTADO: ", message )  
    def testProjectStorage(self):
        # New project without fileName
        p0 = QgsProject()
        self.assertTrue(p0.auxiliaryStorage().isValid())

        # Create new layers with key otherwise auxiliary layers are not
        # automacially created when added in project
        vl0 = createLayer()
        vl0Shp = writeShape(vl0, 'vl0.shp')

        vl1 = createLayer()
        vl1Shp = writeShape(vl1, 'vl1.shp')

        vl0 = QgsVectorLayer(vl0Shp, 'points', 'ogr')
        self.assertTrue(vl0.isValid())

        vl1 = QgsVectorLayer(vl1Shp, 'points', 'ogr')
        self.assertTrue(vl1.isValid())

        # Add layers to project and check underlying auxiliary layers
        p0.addMapLayers([vl0, vl1])

        self.assertTrue(vl0.loadAuxiliaryLayer(p0.auxiliaryStorage(), 'pk'))
        self.assertTrue(vl1.loadAuxiliaryLayer(p0.auxiliaryStorage(), 'num_char'))

        al0 = vl0.auxiliaryLayer()
        al1 = vl1.auxiliaryLayer()

        self.assertEqual(al0.joinInfo().targetFieldName(), 'pk')
        self.assertEqual(al1.joinInfo().targetFieldName(), 'num_char')

        # Add a field in auxiliary layers
        pdef0 = QgsPropertyDefinition('propname', QgsPropertyDefinition.DataTypeNumeric, '', '', 'ut')
        self.assertTrue(al0.addAuxiliaryField(pdef0))

        pdef1 = QgsPropertyDefinition('propname1', QgsPropertyDefinition.DataTypeString, '', '', 'ut')
        self.assertTrue(al1.addAuxiliaryField(pdef1))

        # Check auxiliary fields names
        af0Name = QgsAuxiliaryLayer.nameFromProperty(pdef0, False)
        self.assertEqual(af0Name, 'ut_propname')
        af1Name = QgsAuxiliaryLayer.nameFromProperty(pdef1, False)
        self.assertEqual(af1Name, 'ut_propname1')

        # Set value for auxiliary fields
        req = QgsFeatureRequest().setFilterExpression("name = 'Honey'")
        f = QgsFeature()
        vl0.getFeatures(req).nextFeature(f)
        self.assertTrue(f.isValid())
        af0Name = QgsAuxiliaryLayer.nameFromProperty(pdef0, True)
        index0 = vl0.fields().indexOf(af0Name)
        vl0.changeAttributeValue(f.id(), index0, 333)

        req = QgsFeatureRequest().setFilterExpression("name = 'Apple'")
        f = QgsFeature()
        vl1.getFeatures(req).nextFeature(f)
        self.assertTrue(f.isValid())
        af1Name = QgsAuxiliaryLayer.nameFromProperty(pdef1, True)
        index1 = vl1.fields().indexOf(af1Name)
        vl1.changeAttributeValue(f.id(), index0, 'myvalue')

        req = QgsFeatureRequest().setFilterExpression("name = 'Orange'")
        f = QgsFeature()
        vl1.getFeatures(req).nextFeature(f)
        self.assertTrue(f.isValid())
        vl1.changeAttributeValue(f.id(), index0, 'myvalue1')

        # Save the project in a zip file
        f = tmpPath() + '.qgz'
        p0.write(f)

        # Open the zip file with embedded auxiliary storage
        p1 = QgsProject()
        p1.read(f)

        # Check that auxiliary fields are well loaded in layers
        self.assertEqual(len(p1.mapLayers().values()), 2)

        for vl in p1.mapLayers().values():
            al = vl.auxiliaryLayer()
            self.assertEqual(len(al.auxiliaryFields()), 1)

            af = al.auxiliaryFields()[0]
            afPropDef = QgsAuxiliaryLayer.propertyDefinitionFromField(af)
            self.assertEqual(afPropDef.origin(), 'ut')

            if vl.auxiliaryLayer().joinInfo().targetFieldName() == 'pk':
                self.assertEqual(afPropDef.name(), 'propname')
                self.assertEqual(al.featureCount(), 1)

                req = QgsFeatureRequest().setFilterExpression("name = 'Honey'")
                f = QgsFeature()
                vl.getFeatures(req).nextFeature(f)
                self.assertTrue(f.isValid())
                self.assertEqual(f.attributes()[index0], 333.0)
            else: # num_char
                self.assertEqual(al.featureCount(), 2)
                self.assertEqual(afPropDef.name(), 'propname1')

                req = QgsFeatureRequest().setFilterExpression("name = 'Apple'")
                f = QgsFeature()
                vl.getFeatures(req).nextFeature(f)
                self.assertTrue(f.isValid())
                self.assertEqual(f.attributes()[index1], 'myvalue')

                req = QgsFeatureRequest().setFilterExpression("name = 'Orange'")
                f = QgsFeature()
                vl.getFeatures(req).nextFeature(f)
                self.assertTrue(f.isValid())
                self.assertEqual(f.attributes()[index1], 'myvalue1')
Example #39
0
def buffering(progress, writer, distance, field, useField, layer, dissolve,
              segments):

    if useField:
        field = layer.fieldNameIndex(field)

    outFeat = QgsFeature()
    inFeat = QgsFeature()
    inGeom = QgsGeometry()
    outGeom = QgsGeometry()

    current = 0
    features = vector.features(layer)
    total = 100.0 / len(features) if len(features) > 0 else 1

    # With dissolve
    if dissolve:
        first = True
        for inFeat in features:
            attrs = inFeat.attributes()
            if useField:
                value = attrs[field]
            else:
                value = distance

            inGeom = QgsGeometry(inFeat.geometry())
            if inGeom.isGeosEmpty():
                ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, 'Feature {} has empty geometry. Skipping...'.format(inFeat.id()))
                continue
            if not inGeom.isGeosValid():
                ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, 'Feature {} has invalid geometry. Skipping...'.format(inFeat.id()))
                continue
            outGeom = inGeom.buffer(float(value), segments)
            if first:
                tempGeom = QgsGeometry(outGeom)
                first = False
            else:
                tempGeom = tempGeom.combine(outGeom)

            current += 1
            progress.setPercentage(int(current * total))

        outFeat.setGeometry(tempGeom)
        outFeat.setAttributes(attrs)
        writer.addFeature(outFeat)
    else:
        # Without dissolve
        for inFeat in features:
            attrs = inFeat.attributes()
            if useField:
                value = attrs[field]
            else:
                value = distance
            inGeom = QgsGeometry(inFeat.geometry())
            if inGeom.isGeosEmpty():
                ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, 'Feature {} has empty geometry. Skipping...'.format(inFeat.id()))
                continue
            if not inGeom.isGeosValid():
                ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, 'Feature {} has invalid geometry. Skipping...'.format(inFeat.id()))
                continue

            outGeom = inGeom.buffer(float(value), segments)
            outFeat.setGeometry(outGeom)
            outFeat.setAttributes(attrs)
            writer.addFeature(outFeat)
            current += 1
            progress.setPercentage(int(current * total))

    del writer
Example #40
0
    def processAlgorithm(self, progress):
        inLayer = dataobjects.getObjectFromUri(
            self.getParameterValue(self.INPUT))
        boundary = self.getParameterValue(self.MODE) == self.MODE_BOUNDARY
        smallestArea = self.getParameterValue(
            self.MODE) == self.MODE_SMALLEST_AREA
        keepSelection = self.getParameterValue(self.KEEPSELECTION)
        processLayer = vector.duplicateInMemory(inLayer)

        if not keepSelection:
            # Make a selection with the values provided
            attribute = self.getParameterValue(self.ATTRIBUTE)
            comparison = self.comparisons[self.getParameterValue(
                self.COMPARISON)]
            comparisonvalue = self.getParameterValue(self.COMPARISONVALUE)

            selectindex = vector.resolveFieldIndex(processLayer, attribute)
            selectType = processLayer.fields()[selectindex].type()
            selectionError = False

            if selectType in [
                    QVariant.Int, QVariant.LongLong, QVariant.UInt,
                    QVariant.ULongLong
            ]:
                try:
                    y = int(comparisonvalue)
                except ValueError:
                    selectionError = True
                    msg = self.tr('Cannot convert "%s" to integer' %
                                  str(comparisonvalue))
            elif selectType == QVariant.Double:
                try:
                    y = float(comparisonvalue)
                except ValueError:
                    selectionError = True
                    msg = self.tr('Cannot convert "%s" to float' %
                                  str(comparisonvalue))
            elif selectType == QVariant.String:
                # 10: string, boolean
                try:
                    y = str(comparisonvalue)
                except ValueError:
                    selectionError = True
                    msg = self.tr('Cannot convert "%s" to unicode' %
                                  str(comparisonvalue))
            elif selectType == QVariant.Date:
                # date
                dateAndFormat = comparisonvalue.split(' ')

                if len(dateAndFormat) == 1:
                    # QDate object
                    y = QLocale.system().toDate(dateAndFormat[0])

                    if y.isNull():
                        msg = self.tr(
                            'Cannot convert "%s" to date with system date format %s'
                            % (str(dateAndFormat),
                               QLocale.system().dateFormat()))
                elif len(dateAndFormat) == 2:
                    y = QDate.fromString(dateAndFormat[0], dateAndFormat[1])

                    if y.isNull():
                        msg = self.tr(
                            'Cannot convert "%s" to date with format string "%s"'
                            % (str(dateAndFormat[0]), dateAndFormat[1]))
                else:
                    y = QDate()
                    msg = ''

                if y.isNull():
                    # Conversion was unsuccessfull
                    selectionError = True
                    msg += self.tr(
                        'Enter the date and the date format, e.g. "07.26.2011" "MM.dd.yyyy".'
                    )

            if (comparison == 'begins with' or comparison == 'contains') \
               and selectType != QVariant.String:
                selectionError = True
                msg = self.tr('"%s" can only be used with string fields' %
                              comparison)

            selected = []

            if selectionError:
                raise GeoAlgorithmExecutionException(
                    self.tr('Error in selection input: %s' % msg))
            else:
                for feature in processLayer.getFeatures():
                    aValue = feature.attributes()[selectindex]

                    if aValue is None:
                        continue

                    if selectType in [
                            QVariant.Int, QVariant.LongLong, QVariant.UInt,
                            QVariant.ULongLong
                    ]:
                        x = int(aValue)
                    elif selectType == QVariant.Double:
                        x = float(aValue)
                    elif selectType == QVariant.String:
                        # 10: string, boolean
                        x = str(aValue)
                    elif selectType == QVariant.Date:
                        # date
                        x = aValue  # should be date

                    match = False

                    if comparison == '==':
                        match = x == y
                    elif comparison == '!=':
                        match = x != y
                    elif comparison == '>':
                        match = x > y
                    elif comparison == '>=':
                        match = x >= y
                    elif comparison == '<':
                        match = x < y
                    elif comparison == '<=':
                        match = x <= y
                    elif comparison == 'begins with':
                        match = x.startswith(y)
                    elif comparison == 'contains':
                        match = x.find(y) >= 0

                    if match:
                        selected.append(feature.id())

            processLayer.selectByIds(selected)

        if processLayer.selectedFeatureCount() == 0:
            ProcessingLog.addToLog(
                ProcessingLog.LOG_WARNING,
                self.tr('%s: (No selection in input layer "%s")' %
                        (self.commandLineName(),
                         self.getParameterValue(self.INPUT))))

        # Keep references to the features to eliminate
        featToEliminate = []
        for aFeat in processLayer.selectedFeatures():
            featToEliminate.append(aFeat)

        # Delete all features to eliminate in processLayer (we won't save this)
        processLayer.startEditing()
        processLayer.deleteSelectedFeatures()

        # ANALYZE
        if len(featToEliminate) > 0:  # Prevent zero division
            start = 20.00
            add = 80.00 / len(featToEliminate)
        else:
            start = 100

        progress.setPercentage(start)
        madeProgress = True

        # We go through the list and see if we find any polygons we can
        # merge the selected with. If we have no success with some we
        # merge and then restart the whole story.
        while madeProgress:  # Check if we made any progress
            madeProgress = False
            featNotEliminated = []

            # Iterate over the polygons to eliminate
            for i in range(len(featToEliminate)):
                feat = featToEliminate.pop()
                geom2Eliminate = feat.geometry()
                bbox = geom2Eliminate.boundingBox()
                fit = processLayer.getFeatures(
                    QgsFeatureRequest().setFilterRect(
                        bbox).setSubsetOfAttributes([]))
                mergeWithFid = None
                mergeWithGeom = None
                max = 0
                min = -1
                selFeat = QgsFeature()

                # use prepared geometries for faster intersection tests
                engine = QgsGeometry.createGeometryEngine(
                    geom2Eliminate.geometry())
                engine.prepareGeometry()

                while fit.nextFeature(selFeat):
                    selGeom = selFeat.geometry()

                    if engine.intersects(selGeom.geometry()):
                        # We have a candidate
                        iGeom = geom2Eliminate.intersection(selGeom)

                        if not iGeom:
                            continue

                        if boundary:
                            selValue = iGeom.length()
                        else:
                            # area. We need a common boundary in
                            # order to merge
                            if 0 < iGeom.length():
                                selValue = selGeom.area()
                            else:
                                selValue = -1

                        if -1 != selValue:
                            useThis = True

                            if smallestArea:
                                if -1 == min:
                                    min = selValue
                                else:
                                    if selValue < min:
                                        min = selValue
                                    else:
                                        useThis = False
                            else:
                                if selValue > max:
                                    max = selValue
                                else:
                                    useThis = False

                            if useThis:
                                mergeWithFid = selFeat.id()
                                mergeWithGeom = QgsGeometry(selGeom)
                # End while fit

                if mergeWithFid is not None:
                    # A successful candidate
                    newGeom = mergeWithGeom.combine(geom2Eliminate)

                    if processLayer.changeGeometry(mergeWithFid, newGeom):
                        madeProgress = True
                    else:
                        raise GeoAlgorithmExecutionException(
                            self.
                            tr('Could not replace geometry of feature with id %s'
                               % mergeWithFid))

                    start = start + add
                    progress.setPercentage(start)
                else:
                    featNotEliminated.append(feat)

            # End for featToEliminate

            featToEliminate = featNotEliminated

        # End while

        # Create output
        output = self.getOutputFromName(self.OUTPUT)
        writer = output.getVectorWriter(processLayer.fields(),
                                        processLayer.wkbType(),
                                        processLayer.crs())

        # Write all features that are left over to output layer
        iterator = processLayer.getFeatures()
        for feature in iterator:
            writer.addFeature(feature)

        # Leave processLayer untouched
        processLayer.rollBack()

        for feature in featNotEliminated:
            writer.addFeature(feature)
Example #41
0
    def testMinMaxAfterChanges(self):
        """
        Tests retrieving field min and max value after making changes to the provider's features
        """
        if not getattr(self, 'getEditableLayer', None):
            return

        vl = self.getEditableLayer()
        self.assertTrue(vl.isValid())

        self.assertEqual(vl.dataProvider().minimumValue(0), 1)
        self.assertEqual(vl.dataProvider().minimumValue(1), -200)
        self.assertEqual(vl.dataProvider().maximumValue(0), 5)
        self.assertEqual(vl.dataProvider().maximumValue(1), 400)

        # add feature
        f6 = QgsFeature()
        f6.setAttributes([15, 1400])
        res, [f6] = vl.dataProvider().addFeatures([f6])
        self.assertTrue(res)
        self.assertEqual(vl.dataProvider().minimumValue(0), 1)
        self.assertEqual(vl.dataProvider().minimumValue(1), -200)
        self.assertEqual(vl.dataProvider().maximumValue(0), 15)
        self.assertEqual(vl.dataProvider().maximumValue(1), 1400)
        f7 = QgsFeature()
        f7.setAttributes([0, -1400])
        res, [f7] = vl.dataProvider().addFeatures([f7])
        self.assertTrue(res)
        self.assertEqual(vl.dataProvider().minimumValue(0), 0)
        self.assertEqual(vl.dataProvider().minimumValue(1), -1400)
        self.assertEqual(vl.dataProvider().maximumValue(0), 15)
        self.assertEqual(vl.dataProvider().maximumValue(1), 1400)

        # change attribute values
        self.assertTrue(vl.dataProvider().changeAttributeValues({
            f6.id(): {
                1: 150
            },
            f7.id(): {
                1: -100
            }
        }))
        self.assertEqual(vl.dataProvider().minimumValue(1), -200)
        self.assertEqual(vl.dataProvider().maximumValue(1), 400)

        # delete features
        f1 = [f for f in vl.getFeatures() if f['pk'] == 5][0]
        f3 = [f for f in vl.getFeatures() if f['pk'] == 3][0]
        self.assertTrue(vl.dataProvider().deleteFeatures([f6.id(), f7.id()]))
        self.assertEqual(vl.dataProvider().minimumValue(0), 1)
        self.assertEqual(vl.dataProvider().minimumValue(1), -200)
        self.assertEqual(vl.dataProvider().maximumValue(0), 5)
        self.assertEqual(vl.dataProvider().maximumValue(1), 400)

        if vl.dataProvider().capabilities(
        ) & QgsVectorDataProvider.DeleteAttributes:
            # delete attributes
            if vl.dataProvider().deleteAttributes([0]):
                # may not be possible, e.g. if it's a primary key
                self.assertEqual(vl.dataProvider().minimumValue(0), -200)
                self.assertEqual(vl.dataProvider().maximumValue(0), 400)
Example #42
0
    def eliminate(self, inLayer, boundary, progressBar, outFileName):
        # keep references to the features to eliminate
        fidsToEliminate = inLayer.selectedFeaturesIds()

        if outFileName:  # user wants a new shape file to be created as result
            provider = inLayer.dataProvider()
            error = QgsVectorFileWriter.writeAsVectorFormat(
                inLayer, outFileName, provider.encoding(), inLayer.crs(),
                "ESRI Shapefile")

            if error != QgsVectorFileWriter.NoError:
                QMessageBox.warning(self, self.tr("Eliminate"),
                                    self.tr("Error creating output file"))
                return None

            outLayer = QgsVectorLayer(
                outFileName,
                QFileInfo(outFileName).completeBaseName(), "ogr")

        else:
            QMessageBox.information(self, self.tr("Eliminate"),
                                    self.tr("Please specify output shapefile"))
            return None

        # delete features to be eliminated in outLayer
        outLayer.setSelectedFeatures(fidsToEliminate)
        outLayer.startEditing()

        if outLayer.deleteSelectedFeatures():
            if self.saveChanges(outLayer):
                outLayer.startEditing()
        else:
            QMessageBox.warning(self, self.tr("Eliminate"),
                                self.tr("Could not delete features"))
            return None

        # ANALYZE
        start = 20.00
        progressBar.setValue(start)
        add = 80.00 / len(fidsToEliminate)

        lastLen = 0

        # we go through the list and see if we find any polygons we can merge the selected with
        # if we have no success with some we merge and then restart the whole story
        while (lastLen != inLayer.selectedFeatureCount()
               ):  # check if we made any progress
            lastLen = inLayer.selectedFeatureCount()
            fidsToDeselect = []

            #iterate over the polygons to eliminate
            for fid2Eliminate in inLayer.selectedFeaturesIds():
                feat = QgsFeature()

                if inLayer.getFeatures(QgsFeatureRequest().setFilterFid(
                        fid2Eliminate).setSubsetOfAttributes(
                            [])).nextFeature(feat):
                    geom2Eliminate = feat.geometry()
                    bbox = geom2Eliminate.boundingBox()
                    fit = outLayer.getFeatures(
                        QgsFeatureRequest().setFilterRect(bbox))
                    mergeWithFid = None
                    mergeWithGeom = None
                    max = 0

                    selFeat = QgsFeature()
                    while fit.nextFeature(selFeat):
                        selGeom = selFeat.geometry()

                        if geom2Eliminate.intersects(
                                selGeom):  # we have a candidate
                            iGeom = geom2Eliminate.intersection(selGeom)

                            if boundary:
                                selValue = iGeom.length()
                            else:
                                # we need a common boundary
                                if 0 < iGeom.length():
                                    selValue = selGeom.area()
                                else:
                                    selValue = 0

                            if selValue > max:
                                max = selValue
                                mergeWithFid = selFeat.id()
                                mergeWithGeom = QgsGeometry(
                                    selGeom)  # deep copy of the geometry

                    if mergeWithFid is not None:  # a successful candidate
                        newGeom = mergeWithGeom.combine(geom2Eliminate)

                        if outLayer.changeGeometry(mergeWithFid, newGeom):
                            # write change back to disc
                            if self.saveChanges(outLayer):
                                outLayer.startEditing()
                            else:
                                return None

                            # mark feature as eliminated in inLayer
                            fidsToDeselect.append(fid2Eliminate)
                        else:
                            QMessageBox.warning(
                                self, self.tr("Eliminate"),
                                self.
                                tr("Could not replace geometry of feature with id %s"
                                   ) % (mergeWithFid))
                            return None

                        start = start + add
                        progressBar.setValue(start)
            # end for fid2Eliminate

            # deselect features that are already eliminated in inLayer
            inLayer.deselect(fidsToDeselect)

        #end while

        if inLayer.selectedFeatureCount() > 0:
            # copy all features that could not be eliminated to outLayer
            if outLayer.addFeatures(inLayer.selectedFeatures()):
                # inform user
                fidList = ""

                for fid in inLayer.selectedFeaturesIds():
                    if not fidList == "":
                        fidList += ", "

                    fidList += unicode(fid)

                QErrorMessage(self).showMessage(
                    self.tr("Could not eliminate features with these ids:\n%s")
                    % (fidList))
            else:
                QMessageBox.warning(self, self.tr("Eliminate"),
                                    self.tr("Could not add features"))

        # stop editing outLayer and commit any pending changes
        if not self.saveChanges(outLayer):
            return None

        if outFileName:
            if self.addToCanvasCheck.isChecked():
                ftools_utils.addShapeToCanvas(outFileName)
            else:
                QMessageBox.information(
                    self, self.tr("Eliminate"),
                    self.tr("Created output shapefile:\n%s") % (outFileName))

        self.iface.mapCanvas().refresh()
Example #43
0
    def runDensify(self):
        self.mutex.lock()
        self.stopMe = 0
        self.mutex.unlock()

        interrupted = False

        shapeFileWriter = None

        isPolygon = self.inputLayer.geometryType() == QGis.Polygon

        if self.writeShape:
            # prepare writer
            vProvider = self.inputLayer.dataProvider()
            shapeFields = vProvider.fields()
            crs = vProvider.crs()
            wkbType = self.inputLayer.wkbType()
            if not crs.isValid():
                crs = None
            shapeFileWriter = QgsVectorFileWriter(self.outputFileName,
                                                  self.outputEncoding,
                                                  shapeFields, wkbType, crs)
            featureId = 0

            if self.useSelection:
                selection = self.inputLayer.selectedFeatures()
                self.emit(SIGNAL("rangeCalculated( PyQt_PyObject )"),
                          len(selection))
                for f in selection:
                    featGeometry = QgsGeometry(f.geometry())
                    attrMap = f.attributes()
                    newGeometry = densifyGeometry(featGeometry,
                                                  int(self.tolerance),
                                                  isPolygon)

                    feature = QgsFeature()
                    feature.setGeometry(newGeometry)
                    feature.setAttributes(attrMap)
                    shapeFileWriter.addFeature(feature)
                    featureId += 1
                    self.emit(SIGNAL("featureProcessed()"))

                    self.mutex.lock()
                    s = self.stopMe
                    self.mutex.unlock()
                    if s == 1:
                        interrupted = True
                        break
            else:
                self.emit(SIGNAL("rangeCalculated( PyQt_PyObject )"),
                          vProvider.featureCount())
                f = QgsFeature()
                fit = vProvider.getFeatures()
                while fit.nextFeature(f):
                    featGeometry = QgsGeometry(f.geometry())
                    attrMap = f.attributes()
                    newGeometry = densifyGeometry(featGeometry,
                                                  int(self.tolerance),
                                                  isPolygon)

                    feature = QgsFeature()
                    feature.setGeometry(newGeometry)
                    feature.setAttributes(attrMap)
                    shapeFileWriter.addFeature(feature)
                    featureId += 1
                    self.emit(SIGNAL("featureProcessed()"))

                    self.mutex.lock()
                    s = self.stopMe
                    self.mutex.unlock()
                    if s == 1:
                        interrupted = True
                        break
        else:  # modify existing shapefile
            if not self.inputLayer.isEditable():
                self.inputLayer.startEditing()

            self.inputLayer.beginEditCommand("Densify line(s)")

            if self.useSelection:
                selection = self.inputLayer.selectedFeatures()
                self.emit(SIGNAL("rangeCalculated( PyQt_PyObject )"),
                          len(selection))
                for f in selection:
                    featureId = f.id()
                    featGeometry = QgsGeometry(f.geometry())
                    newGeometry = densifyGeometry(featGeometry,
                                                  int(self.tolerance),
                                                  isPolygon)

                    self.inputLayer.changeGeometry(featureId, newGeometry)
                    self.emit(SIGNAL("featureProcessed()"))

                    self.mutex.lock()
                    s = self.stopMe
                    self.mutex.unlock()
                    if s == 1:
                        interrupted = True
                        break
            else:
                vProvider = self.inputLayer.dataProvider()
                self.emit(SIGNAL("rangeCalculated( PyQt_PyObject )"),
                          vProvider.featureCount())
                f = QgsFeature()
                fit = vProvider.getFeatures()
                while fit.nextFeature(f):
                    featureId = f.id()
                    featGeometry = QgsGeometry(f.geometry())
                    newGeometry = densifyGeometry(featGeometry,
                                                  int(self.tolerance),
                                                  isPolygon)

                    self.inputLayer.changeGeometry(featureId, newGeometry)
                    self.emit(SIGNAL("featureProcessed()"))

                    self.mutex.lock()
                    s = self.stopMe
                    self.mutex.unlock()
                    if s == 1:
                        interrupted = True
                        break

        # cleanup
        if self.inputLayer.isEditable():
            self.inputLayer.endEditCommand()

        if shapeFileWriter is not None:
            del shapeFileWriter

        if not interrupted:
            self.emit(SIGNAL("processingFinished( PyQt_PyObject )"), None)
        else:
            self.emit(SIGNAL("processingInterrupted()"))
Example #44
0
    def testMinMaxCache(self):
        """
        Test that min/max cache is appropriately cleared
        :return:
        """
        vl = QgsVectorLayer(
            'Point?crs=epsg:4326&field=f1:integer&field=f2:integer', 'test',
            'memory')
        self.assertTrue(vl.isValid())

        f1 = QgsFeature()
        f1.setAttributes([5, -200])
        f2 = QgsFeature()
        f2.setAttributes([3, 300])
        f3 = QgsFeature()
        f3.setAttributes([1, 100])
        f4 = QgsFeature()
        f4.setAttributes([2, 200])
        f5 = QgsFeature()
        f5.setAttributes([4, 400])
        res, [f1, f2, f3, f4,
              f5] = vl.dataProvider().addFeatures([f1, f2, f3, f4, f5])
        self.assertTrue(res)

        self.assertEqual(vl.dataProvider().minimumValue(0), 1)
        self.assertEqual(vl.dataProvider().minimumValue(1), -200)
        self.assertEqual(vl.dataProvider().maximumValue(0), 5)
        self.assertEqual(vl.dataProvider().maximumValue(1), 400)

        # add feature
        f6 = QgsFeature()
        f6.setAttributes([15, 1400])
        res, [f6] = vl.dataProvider().addFeatures([f6])
        self.assertTrue(res)
        self.assertEqual(vl.dataProvider().minimumValue(0), 1)
        self.assertEqual(vl.dataProvider().minimumValue(1), -200)
        self.assertEqual(vl.dataProvider().maximumValue(0), 15)
        self.assertEqual(vl.dataProvider().maximumValue(1), 1400)
        f7 = QgsFeature()
        f7.setAttributes([-1, -1400])
        res, [f7] = vl.dataProvider().addFeatures([f7])
        self.assertTrue(res)
        self.assertEqual(vl.dataProvider().minimumValue(0), -1)
        self.assertEqual(vl.dataProvider().minimumValue(1), -1400)
        self.assertEqual(vl.dataProvider().maximumValue(0), 15)
        self.assertEqual(vl.dataProvider().maximumValue(1), 1400)

        # change attribute values
        self.assertTrue(vl.dataProvider().changeAttributeValues({
            f6.id(): {
                0: 3,
                1: 150
            },
            f7.id(): {
                0: 4,
                1: -100
            }
        }))
        self.assertEqual(vl.dataProvider().minimumValue(0), 1)
        self.assertEqual(vl.dataProvider().minimumValue(1), -200)
        self.assertEqual(vl.dataProvider().maximumValue(0), 5)
        self.assertEqual(vl.dataProvider().maximumValue(1), 400)

        # delete features
        self.assertTrue(vl.dataProvider().deleteFeatures([f4.id(), f1.id()]))
        self.assertEqual(vl.dataProvider().minimumValue(0), 1)
        self.assertEqual(vl.dataProvider().minimumValue(1), -100)
        self.assertEqual(vl.dataProvider().maximumValue(0), 4)
        self.assertEqual(vl.dataProvider().maximumValue(1), 400)

        # delete attributes
        self.assertTrue(vl.dataProvider().deleteAttributes([0]))
        self.assertEqual(vl.dataProvider().minimumValue(0), -100)
        self.assertEqual(vl.dataProvider().maximumValue(0), 400)
Example #45
0
    def testSubsetStringFids(self):
        """
          - tests that feature ids are stable even if a subset string is set
          - tests that the subset string is correctly set on the ogr layer event when reloading the data source (issue #17122)
        """

        tmpfile = os.path.join(self.basetestpath, 'subsetStringFids.sqlite')
        ds = ogr.GetDriverByName('SQLite').CreateDataSource(tmpfile)
        lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint, options=['FID=fid'])
        lyr.CreateField(ogr.FieldDefn('type', ogr.OFTInteger))
        lyr.CreateField(ogr.FieldDefn('value', ogr.OFTInteger))
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetFID(0)
        f.SetField(0, 1)
        f.SetField(1, 11)
        lyr.CreateFeature(f)
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetFID(1)
        f.SetField(0, 1)
        f.SetField(1, 12)
        lyr.CreateFeature(f)
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetFID(2)
        f.SetField(0, 1)
        f.SetField(1, 13)
        lyr.CreateFeature(f)
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetFID(3)
        f.SetField(0, 2)
        f.SetField(1, 14)
        lyr.CreateFeature(f)
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetFID(4)
        f.SetField(0, 2)
        f.SetField(1, 15)
        lyr.CreateFeature(f)
        f = ogr.Feature(lyr.GetLayerDefn())
        f.SetFID(5)
        f.SetField(0, 2)
        f.SetField(1, 16)
        lyr.CreateFeature(f)
        f = None
        ds = None

        vl = QgsVectorLayer(tmpfile + "|subset=type=2", 'test', 'ogr')
        self.assertTrue(vl.isValid())
        self.assertTrue(vl.fields().at(vl.fields().count() - 1).name() == "orig_ogc_fid")

        req = QgsFeatureRequest()
        req.setFilterExpression("value=16")
        it = vl.getFeatures(req)
        f = QgsFeature()
        self.assertTrue(it.nextFeature(f))
        self.assertTrue(f.id() == 5)

        # Ensure that orig_ogc_fid is still retrieved even if attribute subset is passed
        req = QgsFeatureRequest()
        req.setSubsetOfAttributes([])
        it = vl.getFeatures(req)
        ids = []
        while it.nextFeature(f):
            ids.append(f.id())
        self.assertTrue(len(ids) == 3)
        self.assertTrue(3 in ids)
        self.assertTrue(4 in ids)
        self.assertTrue(5 in ids)

        # Check that subset string is correctly set on reload
        vl.reload()
        self.assertTrue(vl.fields().at(vl.fields().count() - 1).name() == "orig_ogc_fid")
Example #46
0
def setSelectFeatures(canvas,
                      selectGeometry,
                      doContains,
                      doDifference,
                      singleSelect=None):
    """
    QgsMapCanvas* canvas,
    QgsGeometry* selectGeometry,
    bool doContains,
    bool doDifference,
    bool singleSelect 
    """
    if selectGeometry.type() != QGis.Polygon:
        return

    vlayer = getCurrentVectorLayer(canvas)

    if vlayer == None:
        return

    #toLayerCoordinates will throw an exception for any 'invalid' points in
    #the rubber band.
    #For example, if you project a world map onto a globe using EPSG 2163
    #and then click somewhere off the globe, an exception will be thrown.
    selectGeomTrans = QgsGeometry(selectGeometry)

    if canvas.mapSettings().hasCrsTransformEnabled():
        try:
            ct = QgsCoordinateTransform(canvas.mapSettings().destinationCrs(),
                                        vlayer.crs())
            selectGeomTrans.transform(ct)
        except QgsCsException as cse:
            Q_UNUSED(cse)
            #catch exception for 'invalid' point and leave existing selection unchanged
            """
            QgsLogger::warning( "Caught CRS exception " + QString( __FILE__ ) + ": " + QString::number( __LINE__ ) );
            QgisApp::instance()->messageBar()->pushMessage(
            QObject::tr( "CRS Exception" ),
            QObject::tr( "Selection extends beyond layer's coordinate system" ),
            QgsMessageBar::WARNING,
            QgisApp::instance()->messageTimeout() );
            """
            return

    QApplication.setOverrideCursor(Qt.WaitCursor)
    """
    QgsDebugMsg( "Selection layer: " + vlayer->name() );
    QgsDebugMsg( "Selection polygon: " + selectGeomTrans.exportToWkt() );
    QgsDebugMsg( "doContains: " + QString( doContains ? "T" : "F" ) );
    QgsDebugMsg( "doDifference: " + QString( doDifference ? "T" : "F" ) );
    """

    context = QgsRenderContext().fromMapSettings(canvas.mapSettings())
    r = vlayer.rendererV2()

    if r:
        r.startRender(context, vlayer.pendingFields())

    request = QgsFeatureRequest()
    request.setFilterRect(selectGeomTrans.boundingBox())
    request.setFlags(QgsFeatureRequest.ExactIntersect)

    if r:
        request.setSubsetOfAttributes(r.usedAttributes(),
                                      vlayer.pendingFields())
    else:
        request.setSubsetOfAttributes(QgsAttributeList)

    fit = vlayer.getFeatures(request)

    newSelectedFeatures = []  #QgsFeatureIds
    f = QgsFeature()
    closestFeatureId = 0  #QgsFeatureId
    foundSingleFeature = False
    #double closestFeatureDist = std::numeric_limits<double>::max();
    closestFeatureDist = sys.float_info.max

    while fit.nextFeature(f):
        # make sure to only use features that are visible
        if r and not r.willRenderFeature(f):
            continue
        g = QgsGeometry(f.geometry())
        if doContains:
            if not selectGeomTrans.contains(g):
                continue
        else:
            if not selectGeomTrans.intersects(g):
                continue
        if singleSelect:
            foundSingleFeature = True
            distance = float(g.distance(selectGeomTrans))
            if (distance <= closestFeatureDist):
                closestFeatureDist = distance
                closestFeatureId = f.id()
        else:
            newSelectedFeatures.insert(0, f.id())

    if singleSelect and foundSingleFeature:
        newSelectedFeatures.insert(0, closestFeatureId)
    if r:
        r.stopRender(context)
    #QgsDebugMsg( "Number of new selected features: " + QString::number( newSelectedFeatures.size() )

    if doDifference:
        layerSelectedFeatures = vlayer.selectedFeaturesIds()

        selectedFeatures = []  #QgsFeatureIds
        deselectedFeatures = []  # QgsFeatureIds

        # i = QgsFeatureIds.const_iterator(newSelectedFeatures.constEnd())
        # while i != newSelectedFeatures.constBegin():
        #     i = i - 1
        #     if layerSelectedFeatures.contains(i):
        #         deselectedFeatures.insert(0, i)
        #     else:
        #         selectedFeatures.insert(0, i)

        for item in newSelectedFeatures:
            if item in layerSelectedFeatures:
                deselectedFeatures.insert(0, item)
            else:
                selectedFeatures.insert(0, item)

        vlayer.modifySelection(selectedFeatures, deselectedFeatures)
    else:
        vlayer.setSelectedFeatures(newSelectedFeatures)

    QApplication.restoreOverrideCursor()
    """
Example #47
0
    def processAlgorithm(self, feedback):
        inLayer = dataobjects.getObjectFromUri(
            self.getParameterValue(self.INPUT))
        boundary = self.getParameterValue(self.MODE) == self.MODE_BOUNDARY
        smallestArea = self.getParameterValue(
            self.MODE) == self.MODE_SMALLEST_AREA

        if inLayer.selectedFeatureCount() == 0:
            ProcessingLog.addToLog(
                ProcessingLog.LOG_WARNING,
                self.tr('%s: (No selection in input layer "%s")' %
                        (self.commandLineName(),
                         self.getParameterValue(self.INPUT))))

        featToEliminate = []
        selFeatIds = inLayer.selectedFeatureIds()
        output = self.getOutputFromName(self.OUTPUT)
        writer = output.getVectorWriter(inLayer.fields(), inLayer.wkbType(),
                                        inLayer.crs())

        for aFeat in inLayer.getFeatures():
            if aFeat.id() in selFeatIds:
                # Keep references to the features to eliminate
                featToEliminate.append(aFeat)
            else:
                # write the others to output
                writer.addFeature(aFeat)

        # Delete all features to eliminate in processLayer
        processLayer = output.layer
        processLayer.startEditing()

        # ANALYZE
        if len(featToEliminate) > 0:  # Prevent zero division
            start = 20.00
            add = 80.00 / len(featToEliminate)
        else:
            start = 100

        feedback.setProgress(start)
        madeProgress = True

        # We go through the list and see if we find any polygons we can
        # merge the selected with. If we have no success with some we
        # merge and then restart the whole story.
        while madeProgress:  # Check if we made any progress
            madeProgress = False
            featNotEliminated = []

            # Iterate over the polygons to eliminate
            for i in range(len(featToEliminate)):
                feat = featToEliminate.pop()
                geom2Eliminate = feat.geometry()
                bbox = geom2Eliminate.boundingBox()
                fit = processLayer.getFeatures(
                    QgsFeatureRequest().setFilterRect(
                        bbox).setSubsetOfAttributes([]))
                mergeWithFid = None
                mergeWithGeom = None
                max = 0
                min = -1
                selFeat = QgsFeature()

                # use prepared geometries for faster intersection tests
                engine = QgsGeometry.createGeometryEngine(
                    geom2Eliminate.geometry())
                engine.prepareGeometry()

                while fit.nextFeature(selFeat):
                    selGeom = selFeat.geometry()

                    if engine.intersects(selGeom.geometry()):
                        # We have a candidate
                        iGeom = geom2Eliminate.intersection(selGeom)

                        if not iGeom:
                            continue

                        if boundary:
                            selValue = iGeom.length()
                        else:
                            # area. We need a common boundary in
                            # order to merge
                            if 0 < iGeom.length():
                                selValue = selGeom.area()
                            else:
                                selValue = -1

                        if -1 != selValue:
                            useThis = True

                            if smallestArea:
                                if -1 == min:
                                    min = selValue
                                else:
                                    if selValue < min:
                                        min = selValue
                                    else:
                                        useThis = False
                            else:
                                if selValue > max:
                                    max = selValue
                                else:
                                    useThis = False

                            if useThis:
                                mergeWithFid = selFeat.id()
                                mergeWithGeom = QgsGeometry(selGeom)
                # End while fit

                if mergeWithFid is not None:
                    # A successful candidate
                    newGeom = mergeWithGeom.combine(geom2Eliminate)

                    if processLayer.changeGeometry(mergeWithFid, newGeom):
                        madeProgress = True
                    else:
                        raise GeoAlgorithmExecutionException(
                            self.
                            tr('Could not replace geometry of feature with id %s'
                               % mergeWithFid))

                    start = start + add
                    feedback.setProgress(start)
                else:
                    featNotEliminated.append(feat)

            # End for featToEliminate

            featToEliminate = featNotEliminated

        # End while
        if not processLayer.commitChanges():
            raise GeoAlgorithmExecutionException(
                self.tr('Could not commit changes'))

        for feature in featNotEliminated:
            writer.addFeature(feature)