Пример #1
0
    def process(self):
        layer = self.iface.mapCanvas().currentLayer()
        newFeatures = []

        if layer.selectedFeatureCount() == 1:
            editCommand = QtCore.QCoreApplication.translate("editcommand", "Split feature")
        elif layer.selectedFeatureCount() > 1:
            editCommand = QtCore.QCoreApplication.translate("editcommand", "Split features")

        for feature in layer.selectedFeatures():
            geom = QgsGeometry(feature.geometry())

            if not geom.isGeosValid():
                thisWarning = dtutils.dtGetInvalidGeomWarning(layer)
                dtutils.dtShowWarning(self.iface, thisWarning)
                continue

            # if feature geometry is multipart starts split processing
            if geom.isMultipart():
                if len(newFeatures) == 0:
                    layer.beginEditCommand(editCommand)

                # Get parts from original feature
                parts = geom.asGeometryCollection ()
                # update feature geometry to hold first part single geometry
                # (this way one of the output feature keeps the original Id)
                feature.setGeometry(parts.pop(0))
                layer.updateFeature(feature)
                # create new features from parts and add them to the list of newFeatures
                newFeatures = newFeatures + dtutils.dtMakeFeaturesFromGeometries(layer,  feature,  parts)

        # add new features to layer
        if len(newFeatures) > 0:
            layer.addFeatures(newFeatures, False)
            layer.endEditCommand()
Пример #2
0
    def process(self):
        layer = self.iface.activeLayer()
        layer.featureAdded.connect(self.featureAdded)
        numRingsFilled = 0
        aborted = False

        for featureToFill in layer.selectedFeatures():
            geom = QgsGeometry(featureToFill.geometry())

            if not geom.isGeosValid():
                thisWarning = dtutils.dtGetInvalidGeomWarning(layer)
                dtutils.dtShowWarning(self.iface, thisWarning)
                continue

            rings = dtutils.dtExtractRings(geom)

            for aRing in rings:

                if numRingsFilled == 0:
                    defaultAttributeMap = dtutils.dtGetDefaultAttributeMap(
                        layer)
                    layer.beginEditCommand(
                        QtCore.QCoreApplication.translate(
                            "editcommand", "Fill rings"))

                    if self.iface.vectorLayerTools().addFeature(
                            layer,
                            defaultValues=defaultAttributeMap,
                            defaultGeometry=aRing):
                        layer.featureAdded.disconnect(self.featureAdded)
                    else:
                        layer.featureAdded.disconnect(self.featureAdded)
                        layer.destroyEditCommand()
                        aborted = True
                        break
                else:
                    aFeat = dtutils.dtCopyFeature(layer, srcFid=self.newFid)
                    aFeat.setGeometry(aRing)
                    layer.addFeature(aFeat)

                numRingsFilled += 1

                if aborted:
                    break

        layer.endEditCommand()
        self.canvas.refresh()
Пример #3
0
    def process(self):
        layer = self.iface.activeLayer()
        layer.featureAdded.connect(self.featureAdded)
        numRingsFilled = 0
        aborted = False

        for featureToFill in layer.selectedFeatures():
            geom = QgsGeometry(featureToFill.geometry())

            if not geom.isGeosValid():
                thisWarning = dtutils.dtGetInvalidGeomWarning(layer)
                dtutils.dtShowWarning(self.iface, thisWarning)
                continue

            rings = dtutils.dtExtractRings(geom)

            for aRing in rings:

                if numRingsFilled == 0:
                    defaultAttributeMap = dtutils.dtGetDefaultAttributeMap(layer)
                    layer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Fill rings"))

                    if self.iface.vectorLayerTools().addFeature(layer, defaultValues = defaultAttributeMap, defaultGeometry = aRing):
                        layer.featureAdded.disconnect(self.featureAdded)
                    else:
                        layer.featureAdded.disconnect(self.featureAdded)
                        layer.destroyEditCommand()
                        aborted = True
                        break
                else:
                    aFeat = dtutils.dtCopyFeature(layer,  srcFid = self.newFid)
                    aFeat.setGeometry(aRing)
                    layer.addFeature(aFeat)

                numRingsFilled += 1

                if aborted:
                    break

        layer.endEditCommand()
        self.canvas.refresh()
Пример #4
0
    def process(self):
        layer = self.iface.mapCanvas().currentLayer()
        newFeatures = []

        if layer.selectedFeatureCount() == 1:
            editCommand = QtCore.QCoreApplication.translate(
                "editcommand", "Split feature")
        elif layer.selectedFeatureCount() > 1:
            editCommand = QtCore.QCoreApplication.translate(
                "editcommand", "Split features")

        for feature in layer.selectedFeatures():
            geom = QgsGeometry(feature.geometry())

            if not geom.isGeosValid():
                thisWarning = dtutils.dtGetInvalidGeomWarning(layer)
                dtutils.dtShowWarning(self.iface, thisWarning)
                continue

            # if feature geometry is multipart starts split processing
            if geom.isMultipart():
                if len(newFeatures) == 0:
                    layer.beginEditCommand(editCommand)

                # Get parts from original feature
                parts = geom.asGeometryCollection()
                # update feature geometry to hold first part single geometry
                # (this way one of the output feature keeps the original Id)
                feature.setGeometry(parts.pop(0))
                layer.updateFeature(feature)
                # create new features from parts and add them to the list of newFeatures
                newFeatures = newFeatures + dtutils.dtMakeFeaturesFromGeometries(
                    layer, feature, parts)

        # add new features to layer
        if len(newFeatures) > 0:
            layer.addFeatures(newFeatures)
            layer.endEditCommand()
Пример #5
0
    def fillGaps(self, snappedVertex = None):
        layer = self.iface.activeLayer()
        if layer.selectedFeatureCount() == 0:
            layer.invertSelection()

        multiGeom = None

        for aFeat in layer.selectedFeatures():
            aGeom = aFeat.geometry()

            if not aGeom.isGeosValid():
                QtGui.QMessageBox.warning(None,  self.title,  dtutils.dtGetInvalidGeomWarning())
                return None

            # fill rings contained in the polygon
            if aGeom.isMultipart():
                tempGeom = None

                for poly in aGeom.asMultiPolygon():
                    noRingGeom = self.deleteRings(poly)

                    if tempGeom == None:
                        tempGeom = noRingGeom
                    else:
                        tempGeom = tempGeom.combine(noRingGeom)
            else:
                tempGeom = self.deleteRings(aGeom.asPolygon())

            # make a large polygon from all selected
            if multiGeom == None:
                multiGeom = tempGeom
            else:
                multiGeom = multiGeom.combine(tempGeom)

        rings = dtutils.dtExtractRings(multiGeom)

        if len(rings) == 0:
            QtGui.QMessageBox.warning(None,  self.title,  QtCore.QCoreApplication.translate("digitizingtools",
                "There are no gaps between the polygons.") )
        else:
            if snappedVertex != None:
                thisRing = None

                for aRing in rings:
                    for aPoint in dtutils.dtExtractPoints(aRing):
                        if aPoint.x() == snappedVertex.x() and aPoint.y() == snappedVertex.y():
                            thisRing = aRing
                            break

                if thisRing != None:
                    newFeat = dtutils.dtCreateFeature(layer)
                    layer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Fill gap"))

                    if self.iface.openFeatureForm(layer,  newFeat,  True):
                        newFeat.setGeometry(thisRing)
                        layer.addFeature(newFeat)
                        layer.endEditCommand()

                    else:
                        layer.destroyEditCommand()
                else:
                    QtGui.QMessageBox.warning(None,  self.title,  QtCore.QCoreApplication.translate("digitizingtools",
                        "The selected gap is not closed.") )
            else:
                newFeat = dtutils.dtCreateFeature(layer)
                layer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Fill gaps"))

                if self.iface.openFeatureForm(layer,  newFeat):
                    for aRing in rings:
                        aFeat = dtutils.dtCopyFeature(layer,  newFeat)
                        aFeat.setGeometry(aRing)
                        layer.addFeature(aFeat)

                    layer.endEditCommand()
            self.canvas.refresh()
Пример #6
0
    def process(self):
        '''Function that does all the real work'''
        title = QtCore.QCoreApplication.translate("digitizingtools", "Splitter")
        splitterLayer = dtutils.dtChooseVectorLayer(self.iface,  1,  msg = QtCore.QCoreApplication.translate("digitizingtools", "splitter layer"))

        if splitterLayer == None:
            self.iface.messageBar().pushMessage(title,  QtCore.QCoreApplication.translate("digitizingtools", "Please provide a line layer to split with."))
        else:
            passiveLayer = self.iface.activeLayer()
            msgLst = dtutils.dtGetNoSelMessage()
            noSelMsg1 = msgLst[0]

            if splitterLayer.selectedFeatureCount() == 0:
                self.iface.messageBar().pushMessage(title, noSelMsg1 + " " + splitterLayer.name())
                return None
            elif splitterLayer.selectedFeatureCount() != 1:
                numSelSplitMsg = dtutils.dtGetManySelMessage(splitterLayer)
                self.iface.messageBar().pushMessage(title, numSelSplitMsg  + \
                    QtCore.QCoreApplication.translate("digitizingtools", " Please select only one feature to split with."))
            else:
                if passiveLayer.selectedFeatureCount() == 0:
                    self.iface.messageBar().pushMessage(title,  noSelMsg1  + " " + passiveLayer.name() + ".\n" + \
                        QtCore.QCoreApplication.translate("digitizingtools", " Please select the features to be splitted."))
                    return None

               # determine srs, we work in the project's srs
                splitterCRSSrsid = splitterLayer.crs().srsid()
                passiveCRSSrsid = passiveLayer.crs().srsid()
                mc = self.iface.mapCanvas()
                renderer = mc.mapRenderer()
                projectCRSSrsid = renderer.destinationCrs().srsid()
                passiveLayer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Split features"))
                featuresBeingSplit = 0
                featuresToAdd = []

                for feat in splitterLayer.selectedFeatures():
                    splitterGeom = QgsGeometry(feat.geometry())

                    if not splitterGeom.isGeosValid():
                        thisWarning = dtutils.dtGetInvalidGeomWarning(splitterLayer)
                        dtutils.dtShowWarning(self.iface, thisWarning)
                        continue

                    if splitterCRSSrsid != projectCRSSrsid:
                        splitterGeom.transform(QgsCoordinateTransform(splitterCRSSrsid,  projectCRSSrsid))

                    for selFeat in passiveLayer.selectedFeatures():
                        selGeom = QgsGeometry(selFeat.geometry())

                        if not selGeom.isGeosValid():
                            thisWarning = dtutils.dtGetInvalidGeomWarning(passiveLayer)
                            dtutils.dtShowWarning(self.iface, thisWarning)
                            continue

                        if passiveCRSSrsid != projectCRSSrsid:
                            selGeom.transform(QgsCoordinateTransform(passiveCRSSrsid,  projectCRSSrsid))

                        if splitterGeom.intersects(selGeom): # we have a candidate
                            splitterPList = dtutils.dtExtractPoints(splitterGeom)

                            try:
                                result,  newGeometries,  topoTestPoints = selGeom.splitGeometry(splitterPList,  False) #QgsProject.instance().topologicalEditing())
                            except:
                                self.iface.messageBar().pushMessage(title,
                                    dtutils.dtGetErrorMessage() + QtCore.QCoreApplication.translate("digitizingtools", "splitting of feature") + " " + str(selFeat.id()),
                                    level=QgsMessageBar.CRITICAL)
                                return None

                            if result == 0:
                                selFeat.setGeometry(selGeom)
                                passiveLayer.updateFeature(selFeat)

                                if len(newGeometries) > 0:
                                    featuresBeingSplit += 1
                                    newFeatures = dtutils.dtMakeFeaturesFromGeometries(passiveLayer,  selFeat,  newGeometries)

                                    for newFeat in newFeatures:
                                        newGeom = QgsGeometry(newFeat.geometry())
                                        if passiveCRSSrsid != projectCRSSrsid:
                                            newGeom.transform(QgsCoordinateTransform( projectCRSSrsid,  passiveCRSSrsid))
                                            newFeat.setGeometry(newGeom)

                                        featuresToAdd.append(newFeat)

                if featuresBeingSplit > 0:
                    passiveLayer.addFeatures(featuresToAdd,  False)
                    passiveLayer.endEditCommand()
                    passiveLayer.removeSelection()
                else:
                    passiveLayer.destroyEditCommand()
Пример #7
0
    def process(self):
        '''Function that does all the real work'''
        title = QtCore.QCoreApplication.translate(
            "digitizingtools", "Clipper")

        processLayer = self.iface.activeLayer()
        msgLst = dtutils.dtGetNoSelMessage()
        noSelMsg1 = msgLst[0]

        if processLayer.selectedFeatureCount() == 0:
            self.iface.messageBar().pushMessage(
                title, noSelMsg1 + " " + processLayer.name())
            return None
        else:
            clipperGeoms = []

            for feat in processLayer.selectedFeatures():
                clipperGeom = feat.geometry()

                if not clipperGeom.isGeosValid():
                    thisWarning = dtutils.dtGetInvalidGeomWarning(processLayer)
                    dtutils.dtShowWarning(self.iface, thisWarning)
                    continue
                else:
                    clipperGeoms.append(clipperGeom)

            if len(clipperGeoms) == 0:
                return None # could be only invalid geoms selected

            processLayer.invertSelection()
            idsToProcess = []
            processLayer.beginEditCommand(
                    QtCore.QCoreApplication.translate(
                        "editcommand", "Clip Features"
                    ))
            featuresBeingClipped = 0

            for aFeat in processLayer.selectedFeatures():
                idsToProcess.append(aFeat.id())

            for clipperGeom in clipperGeoms:
                bbox = clipperGeom.boundingBox()
                processLayer.selectByRect(bbox) # make a new selection

                for selFeat in processLayer.selectedFeatures():
                    if idsToProcess.count(selFeat.id()) == 0:
                        continue

                    selGeom = selFeat.geometry()

                    if not selGeom.isGeosValid():
                        thisWarning = dtutils.dtGetInvalidGeomWarning(processLayer)
                        dtutils.dtShowWarning(self.iface, thisWarning)
                        continue

                    if clipperGeom.intersects(selGeom): # we have a candidate
                        newGeom = selGeom.intersection(clipperGeom)

                        if newGeom != None:
                            if not newGeom.isEmpty():
                                if newGeom.area() > 0:
                                    selFeat.setGeometry(newGeom)
                                    processLayer.updateFeature(selFeat)
                                    featuresBeingClipped += 1

            processLayer.removeSelection()
            self.iface.mapCanvas().refresh()

            if featuresBeingClipped == 0:
                processLayer.destroyEditCommand()
            else:
                processLayer.endEditCommand()
Пример #8
0
    def process(self):
        '''Function that does all the real work'''
        title = QtCore.QCoreApplication.translate("digitizingtools", "Cutter")
        showEmptyWarning = True
        choice = None
        fidsToDelete = []
        passiveLayer = self.iface.activeLayer()
        dlg = DtChooseCutterLayer(self.iface, self.isPolygonLayer(passiveLayer), self.lastChoice)
        dlg.show()
        result = dlg.exec_()

        if result != 1:
            self.iface.messageBar().pushMessage(title,
                QtCore.QCoreApplication.translate("digitizingtools", "Please provide a polygon layer to cut with."))
        else:
            cutterLayer = dlg.cutterLayer
            copyPoly = dlg.copyPoly
            self.lastChoice= [cutterLayer, copyPoly]
            isSameLayer = cutterLayer == self.iface.activeLayer()

            if cutterLayer.selectedFeatureCount() == 0:
                msgLst = dtutils.dtGetNoSelMessage()
                noSelMsg1 = msgLst[0]
                noSelMsg2 = msgLst[1]

                if isSameLayer:
                    self.iface.messageBar().pushMessage(title, noSelMsg1 + " " + cutterLayer.name())
                    return None
                else:
                    reply = QtWidgets.QMessageBox.question(None,  title,
                                                       noSelMsg1 + " " + cutterLayer.name() + "\n" + noSelMsg2,
                                                       QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No )

                    if reply == QtWidgets.QMessageBox.Yes:
                        cutterLayer.invertSelection()
                    else:
                        return None

            if passiveLayer.selectedFeatureCount() == 0:
                msgLst = dtutils.dtGetNoSelMessage()
                noSelMsg1 = msgLst[0]
                noSelMsg2 = msgLst[1]
                reply = QtWidgets.QMessageBox.question(None,  title,
                                                   noSelMsg1 + " " + passiveLayer.name() + "\n" + noSelMsg2,
                                                   QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No )

                if reply == QtWidgets.QMessageBox.Yes:
                    passiveLayer.invertSelection()
                else:
                    return None

            idsToProcess = []

            for aFeat in passiveLayer.selectedFeatures():
                idsToProcess.append(aFeat.id())

            if cutterLayer.selectedFeatureCount() > 0:
               # determine srs, we work in the project's srs
                cutterCRSSrsid = cutterLayer.crs().srsid()
                passiveCRSSrsid = passiveLayer.crs().srsid()
                projectCRSSrsid = QgsProject.instance().crs().srsid()
                passiveLayer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Cut Features"))
                featuresBeingCut = 0
                featuresToAdd = []
                tmpCutterLayer = QgsVectorLayer("Polygon?crs=" + cutterLayer.crs().authid(),"cutter","memory")
                tmpCutterLayer.setCrs(cutterLayer.crs())
                tmpCutterLayer.startEditing()
                noMatchWarning = dtutils.dtGetNotMatchingGeomWarning(passiveLayer)

                for feat in cutterLayer.selectedFeatures():
                    cutterGeom = QgsGeometry(feat.geometry())

                    if cutterGeom.wkbType() == 6:
                        cutterGeom = QgsGeometry.fromMultiPolygonXY(cutterGeom.asMultiPolygon())
                    else:
                        cutterGeom = QgsGeometry.fromPolygonXY(cutterGeom.asPolygon())

                    if not cutterGeom.isGeosValid():
                        thisWarning = dtutils.dtGetInvalidGeomWarning(cutterLayer)
                        dtutils.dtShowWarning(self.iface, thisWarning)
                        continue

                    cutterFeat = QgsFeature()
                    cutterFeat.setGeometry(cutterGeom)
                    tmpCutterLayer.addFeature(cutterFeat)

                tmpCutterLayer.commitChanges()
                idsToProcess = []

                if isSameLayer:
                    for aFeat in passiveLayer.getFeatures():
                        idsToProcess.append(aFeat.id())
                else:
                    for aFeat in passiveLayer.selectedFeatures():
                        idsToProcess.append(aFeat.id())

                #tmpCutterLayer.invertSelection()

                for feat in tmpCutterLayer.getFeatures():
                    cutterGeom = QgsGeometry(feat.geometry())

                    if cutterCRSSrsid != projectCRSSrsid:
                        cutterGeom.transform(QgsCoordinateTransform(
                        cutterLayer.crs(),  QgsProject.instance().crs(),
                                QgsProject.instance()))

                    if passiveCRSSrsid != projectCRSSrsid:
                        bboxGeom = QgsGeometry(cutterGeom)
                        bboxGeom.transform(QgsCoordinateTransform(
                            QgsProject.instance().crs(), passiveLayer.crs(),
                            QgsProject.instance()))
                        bbox = bboxGeom.boundingBox()
                    else:
                        bbox = cutterGeom.boundingBox()

                    passiveLayer.selectByRect(bbox) # make a new selection

                    for selFeat in passiveLayer.selectedFeatures():
                        if idsToProcess.count(selFeat.id()) == 0:
                            continue

                        selGeom = QgsGeometry(selFeat.geometry())

                        if isSameLayer:
                            if selGeom.isGeosEqual(cutterGeom):
                                continue # do not cut the same geometry

                        if not selGeom.isGeosValid():
                            thisWarning = dtutils.dtGetInvalidGeomWarning(passiveLayer)
                            dtutils.dtShowWarning(self.iface, thisWarning)
                            continue

                        if passiveCRSSrsid != projectCRSSrsid:
                            selGeom.transform(QgsCoordinateTransform(
                                passiveLayer.crs(),  QgsProject.instance().crs(),
                                QgsProject.instance()
                            ))

                        if cutterGeom.intersects(selGeom): # we have a candidate
                            newGeom = selGeom.difference(cutterGeom)

                            if newGeom != None:
                                if newGeom.isEmpty():
                                    #selGeom is completely contained in cutterGeom
                                    if showEmptyWarning:
                                        choice = QtWidgets.QMessageBox.question(None,  title,
                                            QtCore.QCoreApplication.translate("digitizingtools",
                                            "A feature would be completely removed by cutting. Delete this feature\'s dataset altogether?"),
                                            QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.YesToAll | QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.NoToAll | QtWidgets.QMessageBox.Cancel)

                                        if choice == QtWidgets.QMessageBox.Cancel:
                                            passiveLayer.destroyEditCommand()
                                            return None
                                        else:
                                            showEmptyWarning = (choice == QtWidgets.QMessageBox.Yes or choice == QtWidgets.QMessageBox.No)

                                    if choice == QtWidgets.QMessageBox.Yes or choice == QtWidgets.QMessageBox.YesToAll:
                                        fidsToDelete.append(selFeat.id())
                                else:
                                    if passiveCRSSrsid != projectCRSSrsid:
                                        newGeom.transform(QgsCoordinateTransform(
                                            QgsProject.instance().crs(),  passiveLayer.crs(),
                                            QgsProject.instance()
                                        ))

                                    if not self.geometryTypeMatchesLayer(passiveLayer, newGeom):
                                        newMsg = QtCore.QCoreApplication.translate(
                                            "digitizingtools", "New geometry")
                                        dtutils.dtShowWarning(self.iface, newMsg + ": " + noMatchWarning)

                                    selFeat.setGeometry(newGeom)
                                    passiveLayer.updateFeature(selFeat)
                                    featuresBeingCut += 1

                                    if copyPoly:
                                        copyGeom = selGeom.intersection(cutterGeom)

                                        if copyGeom != None:
                                            if not copyGeom.isEmpty():
                                                if passiveCRSSrsid != projectCRSSrsid:
                                                    copyGeom.transform(QgsCoordinateTransform(
                                                        QgsProject.instance().crs(), passiveLayer.crs(),
                                                        QgsProject.instance()))
                                                if not self.geometryTypeMatchesLayer(passiveLayer, copyGeom):
                                                    copyMsg = QtCore.QCoreApplication.translate(
                                                        "digitizingtools", "Added geometry")
                                                    dtutils.dtShowWarning(self.iface, copyMsg + ": " + noMatchWarning)
                                                newFeatures = dtutils.dtMakeFeaturesFromGeometries(\
                                                    passiveLayer, selFeat, [copyGeom])

                                                for newFeat in newFeatures:
                                                        featuresToAdd.append(newFeat)

                if featuresBeingCut > 0:
                    if copyPoly:
                        if passiveLayer.addFeatures(featuresToAdd):
                            passiveLayer.endEditCommand()
                        else:
                            passiveLayer.destroyEditCommand()
                    else:
                        passiveLayer.endEditCommand()
                else:
                    passiveLayer.destroyEditCommand()

                passiveLayer.removeSelection()

                if len(fidsToDelete) > 0:
                    passiveLayer.beginEditCommand(QtCore.QCoreApplication.translate(\
                        "editcommand", "Delete Features"))
                    for fid in fidsToDelete:
                        if not passiveLayer.deleteFeature(fid):
                            passiveLayer.destroyEditCommand()
                            return None

                    passiveLayer.endEditCommand()

                self.iface.mapCanvas().refresh()
Пример #9
0
    def process(self):
        '''Function that does all the real work'''
        title = QtCore.QCoreApplication.translate(
            "digitizingtools", "Clipper")

        clipperLayer = dtutils.dtChooseVectorLayer(
            self.iface, 2, msg = QtCore.QCoreApplication.translate(
                "digitizingtools", "clipper layer"
            ))

        if clipperLayer == None:
            self.iface.messageBar().pushMessage(
                title, QtCore.QCoreApplication.translate(
                    "digitizingtools", "Please provide a polygon layer to clip with."
                ))
        else:
            passiveLayer = self.iface.activeLayer()
            msgLst = dtutils.dtGetNoSelMessage()
            noSelMsg1 = msgLst[0]
            noSelMsg2 = msgLst[1]

            if clipperLayer.selectedFeatureCount() == 0:
                self.iface.messageBar().pushMessage(
                    title, noSelMsg1 + " " + clipperLayer.name())
                return None
            elif clipperLayer.selectedFeatureCount() != 1:
                numSelSplitMsg = dtutils.dtGetManySelMessage(clipperLayer)
                self.iface.messageBar().pushMessage(title, numSelSplitMsg  + \
                    QtCore.QCoreApplication.translate(
                        "digitizingtools",
                        " Please select only one feature to clip with."
                    ))
            else:
                if passiveLayer.selectedFeatureCount() == 0:
                    msgLst = dtutils.dtGetNoSelMessage()
                    noSelMsg1 = msgLst[0]
                    noSelMsg2 = msgLst[1]
                    reply = QtGui.QMessageBox.question(None,  title,
                        noSelMsg1 + " " + passiveLayer.name() + "\n" + noSelMsg2,
                        QtGui.QMessageBox.Yes | QtGui.QMessageBox.No )

                    if reply == QtGui.QMessageBox.Yes:
                        passiveLayer.invertSelection()
                    else:
                        return None

                idsToProcess = []

                for aFeat in passiveLayer.selectedFeatures():
                    idsToProcess.append(aFeat.id())

                if clipperLayer.selectedFeatureCount() > 0:
                   # determine srs, we work in the project's srs
                    clipperCRSSrsid = clipperLayer.crs().srsid()
                    passiveCRSSrsid = passiveLayer.crs().srsid()
                    mc = self.iface.mapCanvas()
                    renderer = mc.mapRenderer()
                    projectCRSSrsid = renderer.destinationCrs().srsid()
                    passiveLayer.beginEditCommand(
                        QtCore.QCoreApplication.translate(
                            "editcommand", "Clip Features"
                        ))
                    featuresBeingClipped = 0

                    for feat in clipperLayer.selectedFeatures():
                        clipperGeom = QgsGeometry(feat.geometry())

                        if not clipperGeom.isGeosValid():
                            thisWarning = dtutils.dtGetInvalidGeomWarning(clipperLayer)
                            dtutils.dtShowWarning(self.iface, thisWarning)
                            continue

                        if clipperCRSSrsid != projectCRSSrsid:
                            clipperGeom.transform(QgsCoordinateTransform(
                                clipperCRSSrsid, projectCRSSrsid
                            ))

                        bbox = clipperGeom.boundingBox()
                        passiveLayer.select(bbox, False) # make a new selection

                        for selFeat in passiveLayer.selectedFeatures():
                            if idsToProcess.count(selFeat.id()) == 0:
                                continue

                            selGeom = QgsGeometry(selFeat.geometry())

                            if not selGeom.isGeosValid():
                                thisWarning = dtutils.dtGetInvalidGeomWarning(passiveLayer)
                                dtutils.dtShowWarning(self.iface, thisWarning)
                                continue

                            if passiveCRSSrsid != projectCRSSrsid:
                                selGeom.transform(
                                    QgsCoordinateTransform(passiveCRSSrsid,
                                    projectCRSSrsid
                                ))

                            if clipperGeom.intersects(selGeom): # we have a candidate
                                newGeom = selGeom.intersection(clipperGeom)

                                if newGeom != None:
                                    if not newGeom.isGeosEmpty():
                                        if passiveCRSSrsid != projectCRSSrsid:
                                            newGeom.transform(QgsCoordinateTransform(
                                                projectCRSSrsid, passiveCRSSrsid))

                                        selFeat.setGeometry(newGeom)
                                        passiveLayer.updateFeature(selFeat)
                                        featuresBeingClipped += 1

                    if featuresBeingClipped == 0:
                        passiveLayer.destroyEditCommand()
                    else:
                        passiveLayer.endEditCommand()

                    passiveLayer.removeSelection()
                    self.iface.mapCanvas().refresh()
Пример #10
0
    def process(self):
        '''Function that does all the real work'''
        title = QtCore.QCoreApplication.translate("digitizingtools", "Cutter")
        showEmptyWarning = True
        choice = None
        fidsToDelete = []
        cutterLayer = dtutils.dtChooseVectorLayer(self.iface,  2,  msg = QtCore.QCoreApplication.translate("digitizingtools", "cutter layer"))

        if cutterLayer == None:
            self.iface.messageBar().pushMessage(title,  QtCore.QCoreApplication.translate("digitizingtools", "Please provide a polygon layer to cut with."))
        else:
            passiveLayer = self.iface.activeLayer()

            if cutterLayer.selectedFeatureCount() == 0:
                msgLst = dtutils.dtGetNoSelMessage()
                noSelMsg1 = msgLst[0]
                noSelMsg2 = msgLst[1]
                reply = QtGui.QMessageBox.question(None,  title,
                                                   noSelMsg1 + " " + cutterLayer.name() + "\n" + noSelMsg2,
                                                   QtGui.QMessageBox.Yes | QtGui.QMessageBox.No )

                if reply == QtGui.QMessageBox.Yes:
                    cutterLayer.invertSelection()
                else:
                    return None

            if passiveLayer.selectedFeatureCount() == 0:
                msgLst = dtutils.dtGetNoSelMessage()
                noSelMsg1 = msgLst[0]
                noSelMsg2 = msgLst[1]
                reply = QtGui.QMessageBox.question(None,  title,
                                                   noSelMsg1 + " " + passiveLayer.name() + "\n" + noSelMsg2,
                                                   QtGui.QMessageBox.Yes | QtGui.QMessageBox.No )

                if reply == QtGui.QMessageBox.Yes:
                    passiveLayer.invertSelection()
                else:
                    return None

            idsToProcess = []

            for aFeat in passiveLayer.selectedFeatures():
                idsToProcess.append(aFeat.id())

            if cutterLayer.selectedFeatureCount() > 0:
               # determine srs, we work in the project's srs
                cutterCRSSrsid = cutterLayer.crs().srsid()
                passiveCRSSrsid = passiveLayer.crs().srsid()
                mc = self.iface.mapCanvas()
                renderer = mc.mapRenderer()
                projectCRSSrsid = renderer.destinationCrs().srsid()
                passiveLayer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Cut Features"))
                featuresBeingCut = 0

                for feat in cutterLayer.selectedFeatures():
                    cutterGeom = QgsGeometry(feat.geometry())

                    if not cutterGeom.isGeosValid():
                        thisWarning = dtutils.dtGetInvalidGeomWarning(cutterLayer)
                        dtutils.dtShowWarning(self.iface, thisWarning)
                        continue

                    if cutterCRSSrsid != projectCRSSrsid:
                        cutterGeom.transform(QgsCoordinateTransform(cutterCRSSrsid,  projectCRSSrsid))

                    bbox = cutterGeom.boundingBox()
                    passiveLayer.select(bbox, False) # make a new selection

                    for selFeat in passiveLayer.selectedFeatures():
                        if idsToProcess.count(selFeat.id()) == 0:
                            continue

                        selGeom = QgsGeometry(selFeat.geometry())

                        if not selGeom.isGeosValid():
                            thisWarning = dtutils.dtGetInvalidGeomWarning(passiveLayer)
                            dtutils.dtShowWarning(self.iface, thisWarning)
                            continue

                        if passiveCRSSrsid != projectCRSSrsid:
                            selGeom.transform(QgsCoordinateTransform(passiveCRSSrsid,  projectCRSSrsid))

                        if cutterGeom.intersects(selGeom): # we have a candidate
                            newGeom = selGeom.difference(cutterGeom)

                            if newGeom != None:
                                if newGeom.isGeosEmpty():
                                    #selGeom is completely contained in cutterGeom
                                    if showEmptyWarning:
                                        choice = QtGui.QMessageBox.question(None,  title,
                                            QtCore.QCoreApplication.translate("digitizingtools",
                                            "A feature would be completely removed by cutting. Delete this feature\'s dataset altogether?"),
                                            QtGui.QMessageBox.Yes | QtGui.QMessageBox.YesToAll | QtGui.QMessageBox.No | QtGui.QMessageBox.NoToAll | QtGui.QMessageBox.Cancel)

                                        if choice == QtGui.QMessageBox.Cancel:
                                            passiveLayer.destroyEditCommand()
                                            return None
                                        else:
                                            showEmptyWarning = (choice == QtGui.QMessageBox.Yes or choice == QtGui.QMessageBox.No)

                                    if choice == QtGui.QMessageBox.Yes or choice == QtGui.QMessageBox.YesToAll:
                                        fidsToDelete.append(selFeat.id())

                                else:
                                    if passiveCRSSrsid != projectCRSSrsid:
                                        newGeom.transform(QgsCoordinateTransform( projectCRSSrsid,  passiveCRSSrsid))

                                    selFeat.setGeometry(newGeom)
                                    passiveLayer.updateFeature(selFeat)
                                    #if passiveLayer.changeGeometry(selFeat.id(),  newGeom):
                                    featuresBeingCut += 1

                if featuresBeingCut > 0:
                    passiveLayer.endEditCommand()
                else:
                    passiveLayer.destroyEditCommand()

                passiveLayer.removeSelection()

                if len(fidsToDelete) > 0:
                    passiveLayer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Delete Features"))
                    for fid in fidsToDelete:
                        if not passiveLayer.deleteFeature(fid):
                            passiveLayer.destroyEditCommand()
                            return None

                    passiveLayer.endEditCommand()

                self.iface.mapCanvas().refresh()
Пример #11
0
    def fillGaps(self, snappedVertex=None):
        title = QtCore.QCoreApplication.translate("digitizingtools",
                                                  "Fill gap")
        layer = self.iface.activeLayer()
        hasNoSelection = (layer.selectedFeatureCount() == 0)

        if hasNoSelection:
            layer.invertSelection()

        multiGeom = None

        for aFeat in layer.selectedFeatures():
            aGeom = aFeat.geometry()

            if not aGeom.isGeosValid():
                self.iface.messageBar().pushMessage(
                    title,
                    dtutils.dtGetInvalidGeomWarning(layer),
                    level=QgsMessageBar.CRITICAL)
                return None

            # fill rings contained in the polygon
            if aGeom.isMultipart():
                tempGeom = None

                for poly in aGeom.asMultiPolygon():
                    noRingGeom = dtutils.dtDeleteRings(poly)

                    if tempGeom == None:
                        tempGeom = noRingGeom
                    else:
                        tempGeom = tempGeom.combine(noRingGeom)
            else:
                tempGeom = dtutils.dtDeleteRings(aGeom.asPolygon())

            # make a large polygon from all selected
            if multiGeom == None:
                multiGeom = tempGeom
            else:
                multiGeom = multiGeom.combine(tempGeom)

        rings = dtutils.dtExtractRings(multiGeom)

        if len(rings) == 0:
            self.iface.messageBar().pushMessage(
                title,
                QtCore.QCoreApplication.translate(
                    "digitizingtools",
                    "There are no gaps between the polygons."),
                level=QgsMessageBar.CRITICAL)
        else:
            defaultAttributeMap = dtutils.dtGetDefaultAttributeMap(layer)

            if snappedVertex != None:
                thisRing = None

                for aRing in rings:
                    for aPoint in dtutils.dtExtractPoints(aRing):
                        if aPoint.x() == snappedVertex.x() and aPoint.y(
                        ) == snappedVertex.y():
                            thisRing = aRing
                            break

                if thisRing != None:
                    layer.beginEditCommand(
                        QtCore.QCoreApplication.translate(
                            "editcommand", "Fill gap"))

                    if self.iface.vectorLayerTools().addFeature(
                            layer,
                            defaultValues=defaultAttributeMap,
                            defaultGeometry=thisRing):
                        layer.endEditCommand()
                        self.canvas.refresh()
                    else:
                        layer.destroyEditCommand()
                else:
                    self.iface.messageBar().pushMessage(
                        title,
                        QtCore.QCoreApplication.translate(
                            "digitizingtools",
                            "The selected gap is not closed."),
                        level=QgsMessageBar.CRITICAL)
            else:
                layer.featureAdded.connect(self.featureAdded)
                numRingsFilled = 0
                aborted = False

                for aRing in rings:
                    if numRingsFilled == 0:
                        layer.beginEditCommand(
                            QtCore.QCoreApplication.translate(
                                "editcommand", "Fill gaps"))

                        if self.iface.vectorLayerTools().addFeature(
                                layer,
                                defaultValues=defaultAttributeMap,
                                defaultGeometry=aRing):
                            layer.featureAdded.disconnect(self.featureAdded)
                        else:
                            layer.featureAdded.disconnect(self.featureAdded)
                            aborted = True
                            break
                    else:
                        aFeat = dtutils.dtCopyFeature(layer,
                                                      srcFid=self.newFid)
                        aFeat.setGeometry(aRing)
                        layer.addFeature(aFeat)

                    numRingsFilled += 1

                if aborted:
                    layer.destroyEditCommand()
                else:
                    layer.endEditCommand()

            if hasNoSelection:
                layer.removeSelection()

            self.canvas.refresh()
Пример #12
0
    def fillGaps(self, snappedVertex = None):
        title = QtCore.QCoreApplication.translate("digitizingtools", "Fill gap")
        layer = self.iface.activeLayer()
        hasNoSelection = (layer.selectedFeatureCount() == 0)

        if hasNoSelection:
            layer.invertSelection()

        multiGeom = None

        for aFeat in layer.selectedFeatures():
            aGeom = aFeat.geometry()

            if not aGeom.isGeosValid():
                self.iface.messageBar().pushMessage(title,  dtutils.dtGetInvalidGeomWarning(layer), level=QgsMessageBar.CRITICAL)
                return None

            # fill rings contained in the polygon
            if aGeom.isMultipart():
                tempGeom = None

                for poly in aGeom.asMultiPolygon():
                    noRingGeom = dtutils.dtDeleteRings(poly)

                    if tempGeom == None:
                        tempGeom = noRingGeom
                    else:
                        tempGeom = tempGeom.combine(noRingGeom)
            else:
                tempGeom = dtutils.dtDeleteRings(aGeom.asPolygon())

            # make a large polygon from all selected
            if multiGeom == None:
                multiGeom = tempGeom
            else:
                multiGeom = multiGeom.combine(tempGeom)

        rings = dtutils.dtExtractRings(multiGeom)

        if len(rings) == 0:
            self.iface.messageBar().pushMessage(title,  QtCore.QCoreApplication.translate("digitizingtools",
                "There are no gaps between the polygons."), level=QgsMessageBar.CRITICAL)
        else:
            defaultAttributeMap = dtutils.dtGetDefaultAttributeMap(layer)

            if snappedVertex != None:
                thisRing = None

                for aRing in rings:
                    for aPoint in dtutils.dtExtractPoints(aRing):
                        if aPoint.x() == snappedVertex.x() and aPoint.y() == snappedVertex.y():
                            thisRing = aRing
                            break

                if thisRing != None:
                    layer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Fill gap"))

                    if self.iface.vectorLayerTools().addFeature(layer, defaultValues = defaultAttributeMap, defaultGeometry = thisRing):
                        layer.endEditCommand()
                        self.canvas.refresh()
                    else:
                        layer.destroyEditCommand()
                else:
                    self.iface.messageBar().pushMessage(title,  QtCore.QCoreApplication.translate("digitizingtools",
                        "The selected gap is not closed."), level=QgsMessageBar.CRITICAL)
            else:
                layer.featureAdded.connect(self.featureAdded)
                numRingsFilled = 0
                aborted = False

                for aRing in rings:
                    if numRingsFilled == 0:
                        layer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Fill gaps"))

                        if self.iface.vectorLayerTools().addFeature(layer, defaultValues = defaultAttributeMap, defaultGeometry = aRing):
                            layer.featureAdded.disconnect(self.featureAdded)
                        else:
                            layer.featureAdded.disconnect(self.featureAdded)
                            aborted = True
                            break
                    else:
                        aFeat = dtutils.dtCopyFeature(layer,  srcFid = self.newFid)
                        aFeat.setGeometry(aRing)
                        layer.addFeature(aFeat)

                    numRingsFilled += 1

                if aborted:
                    layer.destroyEditCommand()
                else:
                    layer.endEditCommand()

            if hasNoSelection:
                layer.removeSelection()

            self.canvas.refresh()
Пример #13
0
    def fillGaps(self, snappedVertex=None):
        title = QtCore.QCoreApplication.translate("digitizingtools",
                                                  "Fill gap")
        layer = self.iface.activeLayer()
        hasNoSelection = (layer.selectedFeatureCount() == 0)

        if hasNoSelection:
            layer.invertSelection()

        multiGeom = None

        for aFeat in layer.selectedFeatures():
            aGeom = aFeat.geometry()

            if not aGeom.isGeosValid():
                self.iface.messageBar().pushMessage(
                    title,
                    dtutils.dtGetInvalidGeomWarning(layer),
                    level=QgsMessageBar.CRITICAL)
                return None

            # fill rings contained in the polygon
            if aGeom.isMultipart():
                tempGeom = None

                for poly in aGeom.asMultiPolygon():
                    noRingGeom = dtutils.dtDeleteRings(poly)

                    if tempGeom == None:
                        tempGeom = noRingGeom
                    else:
                        tempGeom = tempGeom.combine(noRingGeom)
            else:
                tempGeom = dtutils.dtDeleteRings(aGeom.asPolygon())

            # make a large polygon from all selected
            if multiGeom == None:
                multiGeom = tempGeom
            else:
                multiGeom = multiGeom.combine(tempGeom)

        rings = dtutils.dtExtractRings(multiGeom)

        if len(rings) == 0:
            self.iface.messageBar().pushMessage(
                title,
                QtCore.QCoreApplication.translate(
                    "digitizingtools",
                    "There are no gaps between the polygons."),
                level=QgsMessageBar.CRITICAL)
        else:
            if snappedVertex != None:
                thisRing = None

                for aRing in rings:
                    for aPoint in dtutils.dtExtractPoints(aRing):
                        if aPoint.x() == snappedVertex.x() and aPoint.y(
                        ) == snappedVertex.y():
                            thisRing = aRing
                            break

                if thisRing != None:
                    newFeat = dtutils.dtCreateFeature(layer)

                    if self.iface.openFeatureForm(layer, newFeat, True):
                        layer.beginEditCommand(
                            QtCore.QCoreApplication.translate(
                                "editcommand", "Fill gap"))
                        newFeat.setGeometry(thisRing)
                        layer.addFeature(newFeat)
                        layer.endEditCommand()
                else:
                    self.iface.messageBar().pushMessage(
                        title,
                        QtCore.QCoreApplication.translate(
                            "digitizingtools",
                            "The selected gap is not closed."),
                        level=QgsMessageBar.CRITICAL)
            else:
                newFeat = dtutils.dtCreateFeature(layer)

                if self.iface.openFeatureForm(layer, newFeat):
                    layer.beginEditCommand(
                        QtCore.QCoreApplication.translate(
                            "editcommand", "Fill gaps"))

                    for aRing in rings:
                        aFeat = dtutils.dtCopyFeature(layer, newFeat)
                        aFeat.setGeometry(aRing)
                        layer.addFeature(aFeat)

                    layer.endEditCommand()

            if hasNoSelection:
                layer.removeSelection()

            self.canvas.refresh()
Пример #14
0
    def process(self):
        '''Function that does all the real work'''
        title = QtCore.QCoreApplication.translate("digitizingtools", "Cutter")
        showEmptyWarning = True
        choice = None
        fidsToDelete = []
        processLayer = self.iface.activeLayer()

        if processLayer.selectedFeatureCount() == 0:
            msgLst = dtutils.dtGetNoSelMessage()
            noSelMsg1 = msgLst[0]
            noSelMsg2 = msgLst[1]
        else:
            cutterGeoms = []

            for feat in processLayer.selectedFeatures():
                cutterGeom = feat.geometry()

                if not cutterGeom.isGeosValid():
                    thisWarning = dtutils.dtGetInvalidGeomWarning(processLayer)
                    dtutils.dtShowWarning(self.iface, thisWarning)
                    continue
                else:
                    cutterGeoms.append(cutterGeom)

            if len(cutterGeoms) == 0:
                return None # could be only invalid geoms selected

        processLayer.invertSelection()
        idsToProcess = []

        for aFeat in processLayer.selectedFeatures():
            # was:  if isSameLayer:
            #    for aFeat in processLayer.getFeatures()
            idsToProcess.append(aFeat.id())

        processLayer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Cut Features"))
        featuresBeingCut = 0
        noMatchWarning = dtutils.dtGetNotMatchingGeomWarning(processLayer)

        for cutterGeom in cutterGeoms:
            if cutterGeom.wkbType() == 6:
                cutterGeom = QgsGeometry.fromMultiPolygonXY(cutterGeom.asMultiPolygon())
            else:
                cutterGeom = QgsGeometry.fromPolygonXY(cutterGeom.asPolygon())

            bbox = cutterGeom.boundingBox()

            processLayer.selectByRect(bbox) # make a new selection

            for selFeat in processLayer.selectedFeatures():
                if idsToProcess.count(selFeat.id()) == 0:
                    continue

                selGeom = selFeat.geometry()

                if selGeom.isGeosEqual(cutterGeom):
                    continue # do not cut the same geometry

                if not selGeom.isGeosValid():
                    thisWarning = dtutils.dtGetInvalidGeomWarning(processLayer)
                    dtutils.dtShowWarning(self.iface, thisWarning)
                    continue

                if cutterGeom.intersects(selGeom): # we have a candidate
                    newGeom = selGeom.difference(cutterGeom)

                    if newGeom != None:
                        if newGeom.isEmpty() or newGeom.area() == 0:
                            #selGeom is completely contained in cutterGeom
                            if showEmptyWarning:
                                choice = QtWidgets.QMessageBox.question(None,  title,
                                    QtCore.QCoreApplication.translate("digitizingtools",
                                    "A feature would be completely removed by cutting. Delete this feature\'s dataset altogether?"),
                                    QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.YesToAll |
                                    QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.NoToAll |
                                    QtWidgets.QMessageBox.Cancel)

                                if choice == QtWidgets.QMessageBox.Cancel:
                                    processLayer.destroyEditCommand()
                                    processLayer.removeSelection()
                                    return None
                                else:
                                    showEmptyWarning = (choice == QtWidgets.QMessageBox.Yes or choice == QtWidgets.QMessageBox.No)

                            if choice == QtWidgets.QMessageBox.Yes or choice == QtWidgets.QMessageBox.YesToAll:
                                fidsToDelete.append(selFeat.id())
                        else:
                            if not self.geometryTypeMatchesLayer(processLayer, newGeom):
                                newMsg = QtCore.QCoreApplication.translate(
                                    "digitizingtools", "New geometry")
                                dtutils.dtShowWarning(self.iface, newMsg + ": " + noMatchWarning)

                            selFeat.setGeometry(newGeom)
                            processLayer.updateFeature(selFeat)
                            featuresBeingCut += 1

        if len(fidsToDelete) > 0:
            for fid in fidsToDelete:
                if not processLayer.deleteFeature(fid):
                    processLayer.destroyEditCommand()
                    return None

        if featuresBeingCut > 0 or len(fidsToDelete) > 0:
            processLayer.endEditCommand()
        else: # nothing happened
            processLayer.destroyEditCommand()

        processLayer.removeSelection()
        self.iface.mapCanvas().refresh()