Example #1
0
    def vertexSnapped(self, snapResult):
        snappedVertex = snapResult[0][0]
        snappedFid = snapResult[2][0]
        layer = self.iface.activeLayer()
        feat = dtutils.dtGetFeatureForId(layer, snappedFid)

        if feat != None:
            geom = feat.geometry()
            rings = dtutils.dtExtractRings(geom)
            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:
                defaultAttributeMap = dtutils.dtGetDefaultAttributeMap(layer)
                layer.beginEditCommand(
                    QtCore.QCoreApplication.translate("editcommand",
                                                      "Fill ring"))

                if self.iface.vectorLayerTools().addFeature(
                        layer,
                        defaultValues=defaultAttributeMap,
                        defaultGeometry=thisRing):
                    layer.endEditCommand()
                    self.canvas.refresh()
                else:
                    layer.destroyEditCommand()

        self.tool.reset()
Example #2
0
    def vertexSnapped(self,  snapResult):
        if not self.doIgnoreTool:
            snappedVertex = snapResult[0][0]
            snappedFid = snapResult[2][0]
            layer = self.iface.activeLayer()
            thisRing = None
            feat = dtutils.dtGetFeatureForId(layer,  snappedFid)

            if feat != None:
                geom = feat.geometry()
                rings = dtutils.dtExtractRings(geom)

                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 ring"))

                    if self.iface.openFeatureForm(layer,  newFeat,  True):
                        # let user edit attributes
                        newFeat.setGeometry(thisRing)
                        layer.addFeature(newFeat)
                        layer.endEditCommand()
                        self.canvas.refresh()
                    else:
                        layer.destroyEditCommand()

        self.tool.clear()
Example #3
0
    def vertexSnapped(self,  snapResult):
        snappedVertex = snapResult[0][0]
        snappedFid = snapResult[2][0]
        layer = self.iface.activeLayer()
        feat = dtutils.dtGetFeatureForId(layer,  snappedFid)

        if feat != None:
            geom = feat.geometry()
            rings = dtutils.dtExtractRings(geom)
            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:
                defaultAttributeMap = dtutils.dtGetDefaultAttributeMap(layer)
                layer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Fill ring"))

                if self.iface.vectorLayerTools().addFeature(layer, defaultValues = defaultAttributeMap, defaultGeometry = thisRing):
                    layer.endEditCommand()
                    self.canvas.refresh()
                else:
                    layer.destroyEditCommand()

        self.tool.reset()
Example #4
0
    def vertexSnapped(self, snapResult):
        snappedVertex = snapResult[0][0]
        snappedFid = snapResult[2][0]
        layer = self.iface.activeLayer()
        feat = dtutils.dtGetFeatureForId(layer, snappedFid)

        if feat != None:
            geom = feat.geometry()
            rings = dtutils.dtExtractRings(geom)
            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):
                    # let user edit attributes
                    layer.beginEditCommand(
                        QtCore.QCoreApplication.translate(
                            "editcommand", "Fill ring"))
                    newFeat.setGeometry(thisRing)
                    layer.addFeature(newFeat)
                    layer.endEditCommand()
                    self.canvas.refresh()

        self.tool.clear()
Example #5
0
    def vertexSnapped(self,  snapResult):
        snappedVertex = snapResult[0][0]
        fid = snapResult[2][0]
        layer = self.iface.mapCanvas().currentLayer()
        feature = dtutils.dtGetFeatureForId(layer,  fid)
        geom = feature.geometry()
        # if feature geometry is multipart start split processing
        if geom.isMultipart():
            # Get parts from original feature
            parts = geom.asGeometryCollection ()
            foundPart = False

            for i in range(len(parts)):
                # find the part that was snapped
                aPart = parts[i]
                points = dtutils.dtExtractPoints(aPart)

                for aPoint in points:
                    if aPoint.x() == snappedVertex.x() and aPoint.y() == snappedVertex.y():
                        foundPart = True
                        break

                if foundPart:
                    break

            if foundPart:
                if geom.deletePart(i):
                    layer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Extract part"))
                    aFeat = dtutils.dtCopyFeature(layer,  feature)
                    aFeat.setGeometry(aPart)
                    layer.addFeature(aFeat)
                    feature.setGeometry(geom)
                    layer.updateFeature(feature)
                    layer.endEditCommand()
                    self.canvas.refresh()

        self.tool.reset()
Example #6
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()
Example #7
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()
Example #8
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 = feat.geometry()

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

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

                        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 = 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()
Example #9
0
    def canvasReleaseEvent(self,event):
        #Get the click
        x = event.pos().x()
        y = event.pos().y()

        layer = self.canvas.currentLayer()

        if layer != None:
            #the clicked point is our starting point
            startingPoint = QtCore.QPoint(x,y)
            found = self.getFeatureForPoint(layer, startingPoint)

            if len(found) > 0:
                feat = found[0]
                snappedPoints = found[1]

                if len(snappedPoints) > 0:
                    snappedVertex = snappedPoints[0]
                else:
                    snappedVertex = None

                geom = QgsGeometry(feat.geometry())

                # if feature geometry is multipart start split processing
                if geom.isMultipart():
                    # Get parts from original feature
                    parts = geom.asGeometryCollection()
                    mapToPixel = self.canvas.getCoordinateTransform()
                    thisQgsPoint = mapToPixel.toMapCoordinates(startingPoint)

                    for i in range(len(parts)):
                        # find the part that was snapped
                        aPart = parts[i]

                        if self.isPolygonLayer(layer):
                            if aPart.contains(thisQgsPoint):
                                self.partSelected.emit([feat.id(), i, aPart])
                                break
                        else:
                            points = dtutils.dtExtractPoints(aPart)

                            for j in range(len(points)):
                                aPoint = points[j]

                                if snappedVertex != None:
                                    if aPoint.x() == snappedVertex.x() and \
                                            aPoint.y() == snappedVertex.y():
                                        self.partSelected.emit([feat.id(), i, aPart])
                                        break
                                else:
                                    try:
                                        nextPoint = points[j + 1]
                                    except:
                                        break

                                    if aPoint.x() == snappedPoints[0].x() and \
                                            aPoint.y() == snappedPoints[0].y() and \
                                            nextPoint.x() == snappedPoints[1].x() and \
                                            nextPoint.y() == snappedPoints[1].y():
                                        self.partSelected.emit([feat.id(), i, aPart])
                                        break
Example #10
0
    def run(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:
            QtGui.QMessageBox.information(None, title,  QtCore.QCoreApplication.translate("digitizingtools", "Please provide a line layer to split with."))
        else:
            passiveLayer = self.iface.activeLayer()
            msgLst = dtutils.dtGetNoSelMessage()
            noSelMsg1 = msgLst[0]
            noSelMsg2 = msgLst[1]

            if splitterLayer.selectedFeatureCount() == 0:

                reply = QtGui.QMessageBox.question(None,  title,
                                                   noSelMsg1 + " " + splitterLayer.name() + "\n" + noSelMsg2,
                                                   QtGui.QMessageBox.Yes | QtGui.QMessageBox.Cancel )

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

            if splitterLayer.selectedFeatureCount() > 0:
                if passiveLayer.selectedFeatureCount() == 0:
                    QtGui.QMessageBox.information(None, 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("digitizingtools", "Split Features"))
                featuresBeingSplit = 0
                featuresToAdd = []

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

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

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

                        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:
                                QtGui.QMessageBox.warning(None,  title,
                                    dtutils.dtGetErrorMessage() + QtCore.QCoreApplication.translate("digitizingtools", "splitting of feature") + " " + str(selFeat.id()))
                                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 = 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()
    def digitizingFinished(self, splitGeom):
        title = QtCore.QCoreApplication.translate("digitizingtools", "Split Features")
        hlColor, hlFillColor, hlBuffer,  hlMinWidth = dtutils.dtGetHighlightSettings()
        selIds = self.editLayer.selectedFeatureIds()
        self.editLayer.removeSelection()

        if self.editLayer.crs().srsid() != QgsProject.instance().crs().srsid():
            splitGeom.transform(QgsCoordinateTransform(
                QgsProject.instance().crs(), self.editLayer.crs(),
                QgsProject.instance()
            ))
        splitterPList = dtutils.dtExtractPoints(splitGeom)
        featuresToAdd = [] # store new features in this array
        featuresToKeep = {} # store geoms that will stay with their id as key
        featuresToSplit = {}
        topoGeoms = [] # store all new geometries in this array

        for aFeat in self.editLayer.getFeatures(QgsFeatureRequest(splitGeom.boundingBox())):
            anId = aFeat.id()

            # work either on selected or all features if no selection exists
            if len(selIds) == 0 or selIds.count(anId) != 0:
                aGeom = aFeat.geometry()

                if splitGeom.intersects(aGeom):
                    featuresToSplit[anId] = aFeat

        if len(featuresToSplit) > 0:
            self.editLayer.beginEditCommand(QtCore.QCoreApplication.translate("editcommand", "Features split"))

        for anId, aFeat in list(featuresToSplit.items()):
            aGeom = aFeat.geometry()
            wasMultipart = aGeom.isMultipart() and len(aGeom.asGeometryCollection()) > 1
            splitResult = []
            geomsToSplit = []

            if wasMultipart:
                keepGeom = None

                for aPart in aGeom.asGeometryCollection():
                    if splitGeom.intersects(aPart):
                        geomsToSplit.append(aPart)
                    else:
                        if keepGeom == None:
                            keepGeom = aPart
                        else:
                            keepGeom = keepGeom.combine(aPart)
            else:
                geomsToSplit.append(aGeom)

            for thisGeom in geomsToSplit:
                try:
                    result,  newGeometries,  topoTestPoints = thisGeom.splitGeometry(splitterPList,  False)
                except:
                    self.iface.messageBar().pushCritical(title,
                        dtutils.dtGetErrorMessage() + QtCore.QCoreApplication.translate(
                            "digitizingtools", "splitting of feature") + " " + str(aFeat.id()))
                    return None

                if result == 0: # success
                    if len(newGeometries) > 0:
                        splitResult = newGeometries

                        if wasMultipart:
                            splitResult.append(thisGeom)

                if wasMultipart and len(splitResult) > 1:
                    takeThisOne = -1

                    while takeThisOne == -1:
                        for i in range(len(splitResult)):
                            aNewGeom = splitResult[i]
                            hl = QgsHighlight(self.iface.mapCanvas(), aNewGeom, self.editLayer)
                            hl.setColor(hlColor)
                            hl.setFillColor(hlFillColor)
                            hl.setBuffer(hlBuffer)
                            hl.setWidth(hlMinWidth)
                            answer = QtWidgets.QMessageBox.question(
                                None, QtCore.QCoreApplication.translate("digitizingtools", "Split Multipart Feature"),
                                QtCore.QCoreApplication.translate("digitizingtools", "Create new feature from this part?"),
                                QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.Cancel | QtWidgets.QMessageBox.NoToAll)

                            if answer == QtWidgets.QMessageBox.Yes:
                                takeThisOne = i
                                break
                            elif answer == QtWidgets.QMessageBox.NoToAll:
                                keepGeom = aGeom
                                newGeoms = []
                                takeThisOne = -2
                                break
                            elif answer == QtWidgets.QMessageBox.Cancel:
                                self.editLayer.destroyEditCommand()
                                return None

                    if takeThisOne == -2:
                        break
                    elif takeThisOne >= 0:
                        newGeoms = [splitResult.pop(takeThisOne)]

                        if len(splitResult) > 0: #should be
                            for aNewGeom in splitResult:
                                if keepGeom == None:
                                    keepGeom = aNewGeom
                                else:
                                    keepGeom = keepGeom.combine(aNewGeom)
                else: # singlePart
                    keepGeom = thisGeom
                    newGeoms = newGeometries

                newFeatures = dtutils.dtMakeFeaturesFromGeometries(self.editLayer,  aFeat,  newGeoms)
                featuresToAdd = featuresToAdd + newFeatures
                topoGeoms = topoGeoms + newGeoms

            aFeat.setGeometry(keepGeom)
            featuresToKeep[anId] = aFeat
            topoGeoms.append(keepGeom)

        for anId,  aFeat in list(featuresToKeep.items()):
            aGeom = aFeat.geometry()
            self.editLayer.updateFeature(aFeat)

        if len(featuresToAdd) > 0:
            if self.editLayer.addFeatures(featuresToAdd):

                if QgsProject.instance().topologicalEditing():
                    for aGeom in topoGeoms:
                        self.editLayer.addTopologicalPoints(aGeom)

                self.editLayer.endEditCommand()
            else:
                self.editLayer.destroyEditCommand()
        else:
            self.editLayer.destroyEditCommand()

        if hasattr(self.editLayer, "selectByIds"): # since QGIS 2.16
            self.editLayer.selectByIds(selIds)
        else:
            self.editLayer.setSelectedFeatures(selIds)
Example #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()
    def digitizingFinished(self, splitGeom):
        title = QtCore.QCoreApplication.translate("digitizingtools",
                                                  "Split Features")
        hlColor, hlFillColor, hlBuffer, hlMinWidth = dtutils.dtGetHighlightSettings(
        )
        selIds = self.editLayer.selectedFeatureIds()
        self.editLayer.removeSelection()

        if self.editLayer.crs().srsid() != QgsProject.instance().crs().srsid():
            splitGeom.transform(
                QgsCoordinateTransform(QgsProject.instance().crs(),
                                       self.editLayer.crs(),
                                       QgsProject.instance()))
        splitterPList = dtutils.dtExtractPoints(splitGeom)
        featuresToAdd = []  # store new features in this array
        featuresToKeep = {}  # store geoms that will stay with their id as key
        featuresToSplit = {}
        topoEditEnabled = QgsProject.instance().topologicalEditing()
        topoTestPointsAll = []  # store all topoTestPoints for all parts

        for aFeat in self.editLayer.getFeatures(
                QgsFeatureRequest(splitGeom.boundingBox())):
            anId = aFeat.id()

            # work either on selected or all features if no selection exists
            if len(selIds) == 0 or selIds.count(anId) != 0:
                aGeom = aFeat.geometry()

                if splitGeom.intersects(aGeom):
                    featuresToSplit[anId] = aFeat

        if len(featuresToSplit) > 0:
            self.editLayer.beginEditCommand(
                QtCore.QCoreApplication.translate("editcommand",
                                                  "Features split"))

        for anId, aFeat in list(featuresToSplit.items()):
            aGeom = aFeat.geometry()
            wasMultipart = aGeom.isMultipart() and len(
                aGeom.asGeometryCollection()) > 1
            splitResult = []
            geomsToSplit = []

            if wasMultipart:
                keepGeom = None

                for aPart in aGeom.asGeometryCollection():
                    if splitGeom.intersects(aPart):
                        geomsToSplit.append(aPart)
                    else:
                        if keepGeom == None:
                            keepGeom = aPart
                        else:
                            keepGeom = keepGeom.combine(aPart)
            else:
                geomsToSplit.append(aGeom)

            for thisGeom in geomsToSplit:
                try:
                    result, newGeometries, topoTestPoints = thisGeom.splitGeometry(
                        splitterPList, topoEditEnabled)
                except:
                    self.iface.messageBar().pushCritical(
                        title,
                        dtutils.dtGetErrorMessage() +
                        QtCore.QCoreApplication.translate(
                            "digitizingtools", "splitting of feature") + " " +
                        str(aFeat.id()))
                    return None

                topoTestPointsAll.append(topoTestPoints)

                if result == 0:  # success
                    if len(newGeometries) > 0:
                        splitResult = newGeometries

                        if wasMultipart:
                            splitResult.append(thisGeom)

                if wasMultipart and len(splitResult) > 1:
                    takeThisOne = -1

                    while takeThisOne == -1:
                        for i in range(len(splitResult)):
                            aNewGeom = splitResult[i]
                            hl = QgsHighlight(self.iface.mapCanvas(), aNewGeom,
                                              self.editLayer)
                            hl.setColor(hlColor)
                            hl.setFillColor(hlFillColor)
                            hl.setBuffer(hlBuffer)
                            hl.setWidth(hlMinWidth)
                            hl.show()
                            answer = QtWidgets.QMessageBox.question(
                                None,
                                QtCore.QCoreApplication.translate(
                                    "digitizingtools",
                                    "Split Multipart Feature"),
                                QtCore.QCoreApplication.translate(
                                    "digitizingtools",
                                    "Create new feature from this part?"),
                                QtWidgets.QMessageBox.Yes
                                | QtWidgets.QMessageBox.No
                                | QtWidgets.QMessageBox.Cancel
                                | QtWidgets.QMessageBox.NoToAll)
                            hl.hide()
                            hl = None
                            if answer == QtWidgets.QMessageBox.Yes:
                                takeThisOne = i
                                break
                            elif answer == QtWidgets.QMessageBox.NoToAll:
                                keepGeom = aGeom
                                newGeoms = []
                                takeThisOne = -2
                                break
                            elif answer == QtWidgets.QMessageBox.Cancel:
                                self.editLayer.destroyEditCommand()
                                return None

                    if takeThisOne == -2:
                        break
                    elif takeThisOne >= 0:
                        newGeoms = [splitResult.pop(takeThisOne)]

                        if len(splitResult) > 0:  #should be
                            for aNewGeom in splitResult:
                                if keepGeom == None:
                                    keepGeom = aNewGeom
                                else:
                                    keepGeom = keepGeom.combine(aNewGeom)
                else:  # singlePart
                    keepGeom = thisGeom
                    newGeoms = newGeometries

                newFeatures = dtutils.dtMakeFeaturesFromGeometries(
                    self.editLayer, aFeat, newGeoms)
                featuresToAdd = featuresToAdd + newFeatures

            aFeat.setGeometry(keepGeom)
            featuresToKeep[anId] = aFeat

        for anId, aFeat in list(featuresToKeep.items()):
            aGeom = aFeat.geometry()
            self.editLayer.updateFeature(aFeat)

        if len(featuresToAdd) > 0:
            if self.editLayer.addFeatures(featuresToAdd):

                for topoTestPoint in topoTestPointsAll:
                    for pt in topoTestPoint:
                        self.editLayer.addTopologicalPoints(pt)

                self.editLayer.endEditCommand()
            else:
                self.editLayer.destroyEditCommand()
        else:
            self.editLayer.destroyEditCommand()

        if hasattr(self.editLayer, "selectByIds"):  # since QGIS 2.16
            self.editLayer.selectByIds(selIds)
        else:
            self.editLayer.setSelectedFeatures(selIds)
Example #14
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()
Example #15
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()