Beispiel #1
0
    def __init__(self, table, parent=None):
        TableDataModel.__init__(self, table, parent)

        self.layer = None

        if isinstance(table, LVectorTable):
            self.layer = VLayerRegistry.instance().getLayer(table.name)
        else:
            self.layer = VLayerRegistry.instance().getLayer(table)

        if not self.layer:
            return
        # populate self.resdata
        self.resdata = []
        for f in self.layer.getFeatures():
            a = f.attributes()
            # add the geometry type
            if f.geometry():
                a.append(QgsWKBTypes.displayString(QGis.fromOldWkbType(f.geometry().wkbType())))
            else:
                a.append('None')
            self.resdata.append(a)

        self.fetchedFrom = 0
        self.fetchedCount = len(self.resdata)
    def testWriteShapefileWithZ(self):
        """Check writing geometries with Z dimension to an ESRI shapefile."""

        #start by saving a memory layer and forcing z
        ml = QgsVectorLayer(
            ('Point?crs=epsg:4326&field=id:int'),
            'test',
            'memory')

        assert ml is not None, 'Provider not initialized'
        assert ml.isValid(), 'Source layer not valid'
        provider = ml.dataProvider()
        assert provider is not None

        ft = QgsFeature()
        ft.setGeometry(QgsGeometry.fromWkt('PointZ (1 2 3)'))
        ft.setAttributes([1])
        res, features = provider.addFeatures([ft])
        assert res
        assert len(features) > 0

        # check with both a standard PointZ and 25d style Point25D type
        for t in [QgsWKBTypes.PointZ, QgsWKBTypes.Point25D]:
            dest_file_name = os.path.join(str(QDir.tempPath()), 'point_{}.shp'.format(QgsWKBTypes.displayString(t)))
            print(dest_file_name)
            crs = QgsCoordinateReferenceSystem()
            crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
            write_result = QgsVectorFileWriter.writeAsVectorFormat(
                ml,
                dest_file_name,
                'utf-8',
                crs,
                'ESRI Shapefile',
                overrideGeometryType=t)
            self.assertEqual(write_result, QgsVectorFileWriter.NoError)

            # Open result and check
            created_layer = QgsVectorLayer(u'{}|layerid=0'.format(dest_file_name), u'test', u'ogr')
            f = created_layer.getFeatures(QgsFeatureRequest()).next()
            g = f.geometry()
            wkt = g.exportToWkt()
            expWkt = 'PointZ (1 2 3)'
            assert compareWkt(expWkt, wkt), "saving geometry with Z failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt)

            #also try saving out the shapefile version again, as an extra test
            #this tests that saving a layer with z WITHOUT explicitly telling the writer to keep z values,
            #will stay retain the z values
            dest_file_name = os.path.join(str(QDir.tempPath()), 'point_{}_copy.shp'.format(QgsWKBTypes.displayString(t)))
            print(dest_file_name)
            crs = QgsCoordinateReferenceSystem()
            crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
            write_result = QgsVectorFileWriter.writeAsVectorFormat(
                created_layer,
                dest_file_name,
                'utf-8',
                crs,
                'ESRI Shapefile')
            self.assertEqual(write_result, QgsVectorFileWriter.NoError)

            # Open result and check
            created_layer_from_shp = QgsVectorLayer(u'{}|layerid=0'.format(dest_file_name), u'test', u'ogr')
            f = created_layer_from_shp.getFeatures(QgsFeatureRequest()).next()
            g = f.geometry()
            wkt = g.exportToWkt()
            assert compareWkt(expWkt, wkt), "saving geometry with Z failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt)
Beispiel #3
0
    def testWriteShapefileWithZ(self):
        """Check writing geometries with Z dimension to an ESRI shapefile."""

        #start by saving a memory layer and forcing z
        ml = QgsVectorLayer(
            ('Point?crs=epsg:4326&field=id:int'),
            'test',
            'memory')

        assert ml is not None, 'Provider not initialized'
        assert ml.isValid(), 'Source layer not valid'
        provider = ml.dataProvider()
        assert provider is not None

        ft = QgsFeature()
        ft.setGeometry(QgsGeometry.fromWkt('PointZ (1 2 3)'))
        ft.setAttributes([1])
        res, features = provider.addFeatures([ft])
        assert res
        assert len(features) > 0

        # check with both a standard PointZ and 25d style Point25D type
        for t in [QgsWKBTypes.PointZ, QgsWKBTypes.Point25D]:
            dest_file_name = os.path.join(str(QDir.tempPath()), 'point_{}.shp'.format(QgsWKBTypes.displayString(t)))
            crs = QgsCoordinateReferenceSystem()
            crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
            write_result = QgsVectorFileWriter.writeAsVectorFormat(
                ml,
                dest_file_name,
                'utf-8',
                crs,
                'ESRI Shapefile',
                overrideGeometryType=t)
            self.assertEqual(write_result, QgsVectorFileWriter.NoError)

            # Open result and check
            created_layer = QgsVectorLayer(u'{}|layerid=0'.format(dest_file_name), u'test', u'ogr')
            f = next(created_layer.getFeatures(QgsFeatureRequest()))
            g = f.geometry()
            wkt = g.exportToWkt()
            expWkt = 'PointZ (1 2 3)'
            assert compareWkt(expWkt, wkt), "saving geometry with Z failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt)

            #also try saving out the shapefile version again, as an extra test
            #this tests that saving a layer with z WITHOUT explicitly telling the writer to keep z values,
            #will stay retain the z values
            dest_file_name = os.path.join(str(QDir.tempPath()), 'point_{}_copy.shp'.format(QgsWKBTypes.displayString(t)))
            crs = QgsCoordinateReferenceSystem()
            crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
            write_result = QgsVectorFileWriter.writeAsVectorFormat(
                created_layer,
                dest_file_name,
                'utf-8',
                crs,
                'ESRI Shapefile')
            self.assertEqual(write_result, QgsVectorFileWriter.NoError)

            # Open result and check
            created_layer_from_shp = QgsVectorLayer(u'{}|layerid=0'.format(dest_file_name), u'test', u'ogr')
            f = next(created_layer_from_shp.getFeatures(QgsFeatureRequest()))
            g = f.geometry()
            wkt = g.exportToWkt()
            assert compareWkt(expWkt, wkt), "saving geometry with Z failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt)
    def run(self):
        """Run method that performs all the real work"""

        self.remove_result_layers(remove_all=True, delete_source=True)

        layers = self.iface.legendInterface().layers()
        if not layers:
            print_log(
                "Tool afgebroken! Geen layers gevonden. Voeg eerst layers toe",
                "e", self.iface)
            return
        layer_points, layer_lines, layer_polygons = [], [], []

        if b_QgsWKBTypes:
            for i, layer in enumerate(layers):
                if hasattr(layer, "wkbType"):
                    # qgis.core.QgsWKBTypes.displayString(int(vl.wkbType()))
                    if "point" in QgsWKBTypes.displayString(
                            int(layer.wkbType())).lower():  ## QGis.WKBPoint:
                        layer_points.append(layer)
                    elif "line" in QgsWKBTypes.displayString(
                            int(layer.wkbType())).lower(
                            ):  ##QGis.WKBLineString:
                        layer_lines.append(layer)
                    elif "polygon" in QgsWKBTypes.displayString(
                            int(layer.wkbType())).lower():  ##QGis.WKBPolygon:
                        layer_polygons.append(layer)
                    else:
                        pass
            layer_1 = layer_points[:]  # more on slicing: https://www.afternerd.com/blog/python-copy-list/
            layer_2 = layer_lines[:]
            layer_3 = layer_points[:]
            layer_4 = layer_points[:]
            layer_5 = layer_polygons[:]
            layer_6 = layer_polygons[:]
            layer_7 = layer_polygons[:]

        else:
            print_log(
                "ImportError for QgsWKBTypes. Kan geen geometrie herkennen voor layer inputs. \
                        Controleer of juiste layers zijn geselecteerd of upgrade QGIS.",
                "w", self.iface)
            layer_points = layer_lines = layer_polygons = layers
            layer_1 = layers[:]
            layer_2 = layers[:]
            layer_3 = layers[:]
            layer_4 = layers[:]
            layer_5 = layers[:]
            layer_6 = layers[:]
            layer_7 = layers[:]

        layer_1 = self.move_to_front(layer_1, keyword_1)
        layer_2 = self.move_to_front(layer_2, keyword_2)
        layer_3 = self.move_to_front(layer_3, keyword_3)
        layer_4 = self.move_to_front(layer_4, keyword_4)
        layer_5 = self.move_to_front(layer_5, keyword_5)
        layer_6 = self.move_to_front(layer_6, keyword_6)
        layer_7 = self.move_to_front(layer_7, keyword_7)

        self.dlg.comboBox_1.clear()
        self.dlg.comboBox_2.clear()
        self.dlg.comboBox_3.clear()
        self.dlg.comboBox_4.clear()
        self.dlg.comboBox_5.clear()
        self.dlg.comboBox_6.clear()
        self.dlg.comboBox_7.clear()
        self.dlg.comboBox_1.addItems([i.name() for i in layer_1])  # knooppunt
        self.dlg.comboBox_2.addItems([i.name()
                                      for i in layer_2])  # afvoerrelatie
        self.dlg.comboBox_3.addItems([i.name()
                                      for i in layer_3])  # drinkwater BAG
        self.dlg.comboBox_4.addItems([i.name() for i in layer_4])  # VE's
        self.dlg.comboBox_5.addItems([i.name() for i in layer_5])  # plancap
        self.dlg.comboBox_6.addItems([i.name()
                                      for i in layer_6])  # verhard opp
        self.dlg.comboBox_7.addItems([i.name()
                                      for i in layer_7])  # bemalingsgebieden
        msg_tooltip = "Kaartlagen met '{}' in naam komen bovenaan de keuzelijst te staan.\
            \nVoor het instellen van een eigen zoekterm: ga naar local_settings.py in de app directory van de plugin."

        self.dlg.comboBox_1.setToolTip(msg_tooltip.format(keyword_1))
        self.dlg.comboBox_2.setToolTip(msg_tooltip.format(keyword_2))
        self.dlg.comboBox_3.setToolTip(msg_tooltip.format(keyword_3))
        self.dlg.comboBox_4.setToolTip(msg_tooltip.format(keyword_4))
        self.dlg.comboBox_5.setToolTip(msg_tooltip.format(keyword_5))
        self.dlg.comboBox_6.setToolTip(msg_tooltip.format(keyword_6))
        self.dlg.comboBox_7.setToolTip(msg_tooltip.format(keyword_7))

        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:

            ##QgsMessageLog.logMessage("sel_index = {}".format(sel_index, level=QgsMessageLog.INFO))
            ##QgsMessageLog.logMessage("layer_index 4 = {}".format(self.move_to_front(layer_points, "VE")[self.dlg.comboBox_4.currentIndex()].name()), level=QgsMessageLog.INFO)
            ##QgsMessageLog.logMessage("layer4 = {}".format([i.name() for i in l4]), level=QgsMessageLog.INFO)

            sel_layers = [
                layer_1[self.dlg.comboBox_1.currentIndex()],
                layer_2[self.dlg.comboBox_2.currentIndex()],
                layer_3[self.dlg.comboBox_3.currentIndex()],
                layer_4[self.dlg.comboBox_4.currentIndex()],
                layer_5[self.dlg.comboBox_5.currentIndex()],
                layer_6[self.dlg.comboBox_6.currentIndex()],
                layer_7[self.dlg.comboBox_7.currentIndex()],
            ]

            for i, layer in enumerate(sel_layers):
                print_log("input {}:\t{}".format(i + 1, layer.name()), "i")

            gdb = self.dlg.lineEdit.text()  #
            if not gdb or not os.path.exists(gdb):
                print_log(
                    "Script afgebroken! Geen geldige output map opgegeven ({}...)"
                    .format(gdb), "e", self.iface)
                return

            qgis_warnings_log = settings.qgis_warnings_log
            with open(qgis_warnings_log, 'w') as logfile:
                import time
                logfile.write('{level}: date {time}'.format(
                    level="INFO", time=time.asctime()))

            blokje_log("Veld-info ophalen...", "i")
            INP_FIELDS_XLS = settings.INP_FIELDS_XLS
            INP_FIELDS_CSV = settings.INP_FIELDS_CSV
            try:
                if settings.b_raise_xlrd_import_error:
                    print_log(
                        "b_raise_xlrd_import_error = True (zie local_settings.py)",
                        "w", self.iface)
                    raise ImportError  # for testing csv
                from xlrd import open_workbook
                d_velden = get_d_velden(INP_FIELDS_XLS, 0, open_workbook)
            except ImportError:  # for compatibility with iMac
                print_log(
                    "import error 'xlrd': inp_fields.csv wordt gebruikt als input in plaats van inp_fields.xls",
                    "w", self.iface)
                d_velden = get_d_velden_csv(INP_FIELDS_CSV)
            for fld in d_velden:
                print_log("{}\n{}".format(fld, d_velden[fld]), "d")

            # check for required fields
            vl = sel_layers[0]  # knooppunt
            if vl.fieldNameIndex('VAN_KNOOPN') == -1:
                print_log(
                    "Script afgebroken! Verplicht veld 'VAN_KNOOPN' niet gevonden in kaartlaag '{}'"
                    .format(vl.name()), "e", self.iface)
                return
            vl = sel_layers[1]  # afvoerrelatie
            if vl.fieldNameIndex('VAN_KNOOPN') == -1:
                print_log(
                    "Script afgebroken! Verplicht veld 'VAN_KNOOPN' niet gevonden in kaartlaag '{}'"
                    .format(vl.name()), "e", self.iface)
                return

            # run module 1
            l_K_ONTV_VAN, inp_polygon_layer = m1.main(self.iface, sel_layers,
                                                      gdb, d_velden)

            # run module 2
            m2.main(self.iface, sel_layers, gdb, d_velden, l_K_ONTV_VAN,
                    inp_polygon_layer)

            if settings.b_remove_results_after_run:
                self.remove_result_layers(remove_all=False,
                                          delete_source=False)

            ##self.iface.mainWindow().statusBar().showMessage("dit is de mainWindow")
            warnings = []
            with open(qgis_warnings_log, 'r') as log_file:
                for line in log_file.readlines():
                    if "WARNING" in line:
                        warnings.append(line)

            msg = QMessageBox()
            if len(warnings) > 0:
                msg.setIcon(QMessageBox.Warning)
                msg.setWindowTitle("Script completed")
                msg.setText(
                    "{} warnings were encountered when running script".format(
                        len(warnings)))
                msg.setInformativeText(
                    "For more information see details below or view log panel")
                detailedText = "The details are as follows:"
                detailedText += "\n" + "".join(warnings)
                detailedText += "\nlogfile: {}".format(settings.logFile)
                msg.setDetailedText(detailedText)
                msg.setStyleSheet("QLabel{min-width: 300px;}")
            else:
                msg.setIcon(QMessageBox.Information)
                msg.setWindowTitle("Script completed")
                msg.setText(
                    "No problems were encountered when running script!")
            retval = msg.exec_()
            ##QMessageBox.information(msg, "Info", "Script completed!")
            QgsMessageLog.logMessage("Script completed!",
                                     level=QgsMessageLog.INFO)
    def run(self):
        """Run method that performs all the real work"""

        self.remove_result_layers(remove_all=True, delete_source=True)

        layers = self.iface.legendInterface().layers()
        if not layers:
            print_log(
                "Tool afgebroken! Geen layers gevonden. Voeg eerst layers toe",
                "e", self.iface)
            return
        layer_points, layer_lines, layer_polygons = [], [], []
        if b_QgsWKBTypes:
            for i, layer in enumerate(layers):
                if hasattr(layer, "wkbType"):
                    # qgis.core.QgsWKBTypes.displayString(int(vl.wkbType()))
                    if "point" in QgsWKBTypes.displayString(
                            int(layer.wkbType())).lower():  ## QGis.WKBPoint:
                        layer_points.append(layer)
                    elif "line" in QgsWKBTypes.displayString(
                            int(layer.wkbType())).lower(
                            ):  ##QGis.WKBLineString:
                        layer_lines.append(layer)
                    elif "polygon" in QgsWKBTypes.displayString(
                            int(layer.wkbType())).lower():  ##QGis.WKBPolygon:
                        layer_polygons.append(layer)
                    else:
                        pass

        else:
            print_log(
                "ImportError for QgsWKBTypes. Kan geen geometrie herkennen voor layer inputs. \
                        Controleer of juiste layers zijn geselecteerd of upgrade QGIS.",
                "w", self.iface)
            layer_points = layer_lines = layer_polygons = layers

        self.dlg.comboBox_1.clear()
        self.dlg.comboBox_2.clear()
        self.dlg.comboBox_3.clear()
        self.dlg.comboBox_4.clear()
        self.dlg.comboBox_5.clear()
        self.dlg.comboBox_6.clear()
        self.dlg.comboBox_7.clear()
        self.dlg.comboBox_1.addItems([
            i.name() for i in self.move_to_front(layer_points, "punt")
        ])  # knooppunt
        self.dlg.comboBox_2.addItems([
            i.name() for i in self.move_to_front(layer_lines, "lijn")
        ])  # afvoerrelatie
        self.dlg.comboBox_3.addItems([
            i.name() for i in self.move_to_front(layer_points, "BAG")
        ])  # drinkwater BAG
        self.dlg.comboBox_4.addItems(
            [i.name() for i in self.move_to_front(layer_points, "VE")])  # VE's
        self.dlg.comboBox_5.addItems([
            i.name() for i in self.move_to_front(layer_polygons, "RIGO")
        ])  # plancap
        self.dlg.comboBox_6.addItems([
            i.name() for i in self.move_to_front(layer_polygons, "opp")
        ])  # verhard opp
        self.dlg.comboBox_7.addItems([
            i.name() for i in self.move_to_front(layer_polygons, "bemaling")
        ])  # bemalingsgebieden

        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:

            ##QgsMessageLog.logMessage("sel_index = {}".format(sel_index, level=QgsMessageLog.INFO))
            ##QgsMessageLog.logMessage("layer_index 4 = {}".format(self.move_to_front(layer_points, "VE")[self.dlg.comboBox_4.currentIndex()].name()), level=QgsMessageLog.INFO)
            ##QgsMessageLog.logMessage("layer4 = {}".format([i.name() for i in l4]), level=QgsMessageLog.INFO)

            sel_layers = [
                self.move_to_front(layer_points,
                                   "punt")[self.dlg.comboBox_1.currentIndex()],
                self.move_to_front(layer_lines,
                                   "lijn")[self.dlg.comboBox_2.currentIndex()],
                self.move_to_front(layer_points,
                                   "BAG")[self.dlg.comboBox_3.currentIndex()],
                self.move_to_front(layer_points,
                                   "VE")[self.dlg.comboBox_4.currentIndex()],
                self.move_to_front(layer_polygons,
                                   "RIGO")[self.dlg.comboBox_5.currentIndex()],
                self.move_to_front(layer_polygons,
                                   "opp")[self.dlg.comboBox_6.currentIndex()],
                self.move_to_front(
                    layer_polygons,
                    "bemaling")[self.dlg.comboBox_7.currentIndex()],
            ]

            # refresh input layers, werkt niet... voorlopig dan maar handmatig weggooien.
            ##sel_layernames = [layer.name() for layer in sel_layers]
            ##self.remove_result_layers(settings.l_result_layers_all)
            ##sel_layers = []
            ##layers = self.iface.legendInterface().layers()
            ##for layer in layers:
            ##    if layer.name() in sel_layernames:
            ##        sel_layers.append(layer)

            gdb = self.dlg.lineEdit.text()
            if not gdb or not os.path.exists(gdb):
                print_log(
                    "Script afgebroken! Geen geldige output map opgegeven ({}...)"
                    .format(gdb), "e", self.iface)
                return

            qgis_warnings_log = settings.qgis_warnings_log
            with open(qgis_warnings_log, 'w') as logfile:
                import time
                logfile.write('{level}: date {time}'.format(
                    level="INFO", time=time.asctime()))

            blokje_log("Veld-info ophalen...", "i")
            INP_FIELDS_XLS = settings.INP_FIELDS_XLS
            INP_FIELDS_CSV = settings.INP_FIELDS_CSV
            try:
                from xlrd import open_workbook
                d_velden = get_d_velden(INP_FIELDS_XLS, 0, open_workbook)
            except ImportError:  # for compatibility with iMac
                print_log(
                    "import error 'xlrd': inp_fields.csv wordt gebruikt als input in plaats van inp_fields.xls!",
                    "w", self.iface)
                d_velden = get_d_velden_csv(INP_FIELDS_CSV)
            for fld in d_velden:
                print_log("{}\n{}".format(fld, d_velden[fld]), "d")

            ##self.iface.messageBar().pushMessage("titel", "Start module 1", QgsMessageBar.INFO, duration=5)
            m1.main(self.iface, sel_layers, gdb, d_velden)
            ##self.iface.messageBar().pushMessage("titel", "Start module 2", QgsMessageBar.INFO, duration=5)
            m2.main(self.iface, sel_layers, gdb, d_velden)

            self.remove_result_layers(remove_all=False, delete_source=False)

            ##self.iface.mainWindow().statusBar().showMessage("dit is de mainWindow")
            warnings = []
            with open(qgis_warnings_log, 'r') as log_file:
                for line in log_file.readlines():
                    if "WARNING" in line:
                        warnings.append(line)

            msg = QMessageBox()
            if len(warnings) > 0:
                msg.setIcon(QMessageBox.Warning)
                msg.setWindowTitle("Script completed")
                msg.setText(
                    "{} warnings were encountered when running script".format(
                        len(warnings)))
                msg.setInformativeText(
                    "For more information see details below or view log panel")
                msg.setDetailedText("The details are as follows:")
                msg.setDetailedText("\n".join(warnings))
                # for line in warnings:
                #     msg.setDetailedText(line)
            else:
                msg.setIcon(QMessageBox.Information)
                msg.setWindowTitle("Script completed")
                msg.setText(
                    "No problems were encountered when running script!")
            retval = msg.exec_()
            ##QMessageBox.information(msg, "Info", "Script completed!")
            QgsMessageLog.logMessage("Script completed!",
                                     level=QgsMessageLog.INFO)
Beispiel #6
0
    def processAlgorithm(self, progress):
        vlayerA = dataobjects.getObjectFromUri(
            self.getParameterValue(self.INPUT))
        vlayerB = dataobjects.getObjectFromUri(
            self.getParameterValue(self.INPUT2))
        vproviderA = vlayerA.dataProvider()

        geomType = vproviderA.geometryType()
        if geomType in GEOM_25D:
            raise GeoAlgorithmExecutionException(
                self.tr('Input layer does not support 2.5D type geometry ({}).'
                        ).format(QgsWKBTypes.displayString(geomType)))

        fields = vector.combineVectorFields(vlayerA, vlayerB)
        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            fields, geomType, vproviderA.crs())
        outFeat = QgsFeature()
        index = vector.spatialindex(vlayerB)
        selectionA = vector.features(vlayerA)
        total = 100.0 / len(selectionA)
        for current, inFeatA in enumerate(selectionA):
            progress.setPercentage(int(current * total))
            geom = QgsGeometry(inFeatA.geometry())
            atMapA = inFeatA.attributes()
            intersects = index.intersects(geom.boundingBox())
            for i in intersects:
                request = QgsFeatureRequest().setFilterFid(i)
                inFeatB = vlayerB.getFeatures(request).next()
                tmpGeom = QgsGeometry(inFeatB.geometry())
                if geom.intersects(tmpGeom):
                    atMapB = inFeatB.attributes()
                    int_geom = QgsGeometry(geom.intersection(tmpGeom))
                    if int_geom.wkbType(
                    ) == QGis.WKBUnknown or QgsWKBTypes.flatType(
                            int_geom.geometry().wkbType(
                            )) == QgsWKBTypes.GeometryCollection:
                        int_com = geom.combine(tmpGeom)
                        int_sym = geom.symDifference(tmpGeom)
                        int_geom = QgsGeometry(int_com.difference(int_sym))
                    if int_geom.isGeosEmpty() or not int_geom.isGeosValid():
                        ProcessingLog.addToLog(
                            ProcessingLog.LOG_ERROR,
                            self.tr('GEOS geoprocessing error: One or '
                                    'more input features have invalid '
                                    'geometry.'))
                    try:
                        if int_geom.wkbType() in wkbTypeGroups[wkbTypeGroups[
                                int_geom.wkbType()]]:
                            outFeat.setGeometry(int_geom)
                            attrs = []
                            attrs.extend(atMapA)
                            attrs.extend(atMapB)
                            outFeat.setAttributes(attrs)
                            writer.addFeature(outFeat)
                    except:
                        ProcessingLog.addToLog(
                            ProcessingLog.LOG_INFO,
                            self.
                            tr('Feature geometry error: One or more output features ignored due to invalid geometry.'
                               ))
                        continue

        del writer
Beispiel #7
0
    def processAlgorithm(self, progress):
        layerA = dataobjects.getObjectFromUri(
            self.getParameterValue(Clip.INPUT))
        layerB = dataobjects.getObjectFromUri(
            self.getParameterValue(Clip.OVERLAY))

        geomType = layerA.dataProvider().geometryType()
        if geomType in GEOM_25D:
            raise GeoAlgorithmExecutionException(
                self.tr('Input layer does not support 2.5D type geometry ({}).'
                        ).format(QgsWKBTypes.displayString(geomType)))

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            layerA.pendingFields(),
            layerA.dataProvider().geometryType(),
            layerA.dataProvider().crs())

        inFeatA = QgsFeature()
        inFeatB = QgsFeature()
        outFeat = QgsFeature()

        index = vector.spatialindex(layerB)

        selectionA = vector.features(layerA)

        total = 100.0 / len(selectionA)

        for current, inFeatA in enumerate(selectionA):
            geom = QgsGeometry(inFeatA.geometry())
            attrs = inFeatA.attributes()
            intersects = index.intersects(geom.boundingBox())
            first = True
            found = False
            if len(intersects) > 0:
                for i in intersects:
                    layerB.getFeatures(QgsFeatureRequest().setFilterFid(
                        i)).nextFeature(inFeatB)
                    tmpGeom = QgsGeometry(inFeatB.geometry())
                    if tmpGeom.intersects(geom):
                        found = True
                        if first:
                            outFeat.setGeometry(QgsGeometry(tmpGeom))
                            first = False
                        else:
                            cur_geom = QgsGeometry(outFeat.geometry())
                            new_geom = QgsGeometry(cur_geom.combine(tmpGeom))
                            if new_geom.isGeosEmpty(
                            ) or not new_geom.isGeosValid():
                                ProcessingLog.addToLog(
                                    ProcessingLog.LOG_ERROR,
                                    self.tr('GEOS geoprocessing error: One or '
                                            'more input features have invalid '
                                            'geometry.'))
                                break

                            outFeat.setGeometry(QgsGeometry(new_geom))
                if found:
                    cur_geom = QgsGeometry(outFeat.geometry())
                    new_geom = QgsGeometry(geom.intersection(cur_geom))
                    if new_geom.wkbType(
                    ) == QGis.WKBUnknown or QgsWKBTypes.flatType(
                            new_geom.geometry().wkbType(
                            )) == QgsWKBTypes.GeometryCollection:
                        int_com = QgsGeometry(geom.combine(cur_geom))
                        int_sym = QgsGeometry(geom.symDifference(cur_geom))
                        new_geom = QgsGeometry(int_com.difference(int_sym))
                        if new_geom.isGeosEmpty(
                        ) or not new_geom.isGeosValid():
                            ProcessingLog.addToLog(
                                ProcessingLog.LOG_ERROR,
                                self.tr(
                                    'GEOS geoprocessing error: One or more '
                                    'input features have invalid geometry.'))
                            continue
                    try:
                        outFeat.setGeometry(new_geom)
                        outFeat.setAttributes(attrs)
                        writer.addFeature(outFeat)
                    except:
                        ProcessingLog.addToLog(
                            ProcessingLog.LOG_ERROR,
                            self.tr('Feature geometry error: One or more '
                                    'output features ignored due to '
                                    'invalid geometry.'))
                        continue

            progress.setPercentage(int(current * total))

        del writer
Beispiel #8
0
    def processAlgorithm(self, progress):
        layerA = dataobjects.getObjectFromUri(
            self.getParameterValue(Clip.INPUT))
        layerB = dataobjects.getObjectFromUri(
            self.getParameterValue(Clip.OVERLAY))

        geomType = layerA.dataProvider().geometryType()
        if geomType in GEOM_25D:
            raise GeoAlgorithmExecutionException(
                self.tr('Input layer does not support 2.5D type geometry ({}).').format(QgsWKBTypes.displayString(geomType)))

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            layerA.pendingFields(),
            layerA.dataProvider().geometryType(),
            layerA.dataProvider().crs())

        inFeatA = QgsFeature()
        inFeatB = QgsFeature()
        outFeat = QgsFeature()

        index = vector.spatialindex(layerB)

        selectionA = vector.features(layerA)

        total = 100.0 / len(selectionA)

        for current, inFeatA in enumerate(selectionA):
            geom = QgsGeometry(inFeatA.geometry())
            attrs = inFeatA.attributes()
            intersects = index.intersects(geom.boundingBox())
            first = True
            found = False
            if len(intersects) > 0:
                for i in intersects:
                    layerB.getFeatures(
                        QgsFeatureRequest().setFilterFid(i)).nextFeature(
                            inFeatB)
                    tmpGeom = QgsGeometry(inFeatB.geometry())
                    if tmpGeom.intersects(geom):
                        found = True
                        if first:
                            outFeat.setGeometry(QgsGeometry(tmpGeom))
                            first = False
                        else:
                            cur_geom = QgsGeometry(outFeat.geometry())
                            new_geom = QgsGeometry(cur_geom.combine(tmpGeom))
                            if new_geom.isGeosEmpty() or not new_geom.isGeosValid():
                                ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
                                                       self.tr('GEOS geoprocessing error: One or '
                                                               'more input features have invalid '
                                                               'geometry.'))
                                break

                            outFeat.setGeometry(QgsGeometry(new_geom))
                if found:
                    cur_geom = QgsGeometry(outFeat.geometry())
                    new_geom = QgsGeometry(geom.intersection(cur_geom))
                    if new_geom.wkbType() == QGis.WKBUnknown or QgsWKBTypes.flatType(new_geom.geometry().wkbType()) == QgsWKBTypes.GeometryCollection:
                        int_com = QgsGeometry(geom.combine(cur_geom))
                        int_sym = QgsGeometry(geom.symDifference(cur_geom))
                        new_geom = QgsGeometry(int_com.difference(int_sym))
                        if new_geom.isGeosEmpty() or not new_geom.isGeosValid():
                            ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
                                                   self.tr('GEOS geoprocessing error: One or more '
                                                           'input features have invalid geometry.'))
                            continue
                    try:
                        outFeat.setGeometry(new_geom)
                        outFeat.setAttributes(attrs)
                        writer.addFeature(outFeat)
                    except:
                        ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,
                                               self.tr('Feature geometry error: One or more '
                                                       'output features ignored due to '
                                                       'invalid geometry.'))
                        continue

            progress.setPercentage(int(current * total))

        del writer
Beispiel #9
0
    def processAlgorithm(self, progress):
        vlayerA = dataobjects.getObjectFromUri(
            self.getParameterValue(Union.INPUT))
        vlayerB = dataobjects.getObjectFromUri(
            self.getParameterValue(Union.INPUT2))

        vproviderA = vlayerA.dataProvider()

        geomType = vproviderA.geometryType()
        if geomType in GEOM_25D:
            raise GeoAlgorithmExecutionException(
                self.tr('Input layer does not support 2.5D type geometry ({}).'
                        ).format(QgsWKBTypes.displayString(geomType)))

        fields = vector.combineVectorFields(vlayerA, vlayerB)
        writer = self.getOutputFromName(Union.OUTPUT).getVectorWriter(
            fields, geomType, vproviderA.crs())
        inFeatA = QgsFeature()
        inFeatB = QgsFeature()
        outFeat = QgsFeature()
        indexA = vector.spatialindex(vlayerB)
        indexB = vector.spatialindex(vlayerA)

        count = 0
        nElement = 0
        featuresA = vector.features(vlayerA)
        nFeat = len(featuresA)
        for inFeatA in featuresA:
            progress.setPercentage(nElement / float(nFeat) * 50)
            nElement += 1
            lstIntersectingB = []
            geom = QgsGeometry(inFeatA.geometry())
            atMapA = inFeatA.attributes()
            intersects = indexA.intersects(geom.boundingBox())
            if len(intersects) < 1:
                try:
                    outFeat.setGeometry(geom)
                    outFeat.setAttributes(atMapA)
                    writer.addFeature(outFeat)
                except:
                    # This really shouldn't happen, as we haven't
                    # edited the input geom at all
                    ProcessingLog.addToLog(
                        ProcessingLog.LOG_INFO,
                        self.
                        tr('Feature geometry error: One or more output features ignored due to invalid geometry.'
                           ))
            else:
                for id in intersects:
                    count += 1
                    request = QgsFeatureRequest().setFilterFid(id)
                    inFeatB = vlayerB.getFeatures(request).next()
                    atMapB = inFeatB.attributes()
                    tmpGeom = QgsGeometry(inFeatB.geometry())

                    if geom.intersects(tmpGeom):
                        int_geom = geom.intersection(tmpGeom)
                        lstIntersectingB.append(tmpGeom)

                        if int_geom is None:
                            # There was a problem creating the intersection
                            ProcessingLog.addToLog(
                                ProcessingLog.LOG_INFO,
                                self.
                                tr('GEOS geoprocessing error: One or more input features have invalid geometry.'
                                   ))
                            int_geom = QgsGeometry()
                        else:
                            int_geom = QgsGeometry(int_geom)

                        if int_geom.wkbType(
                        ) == QGis.WKBUnknown or QgsWKBTypes.flatType(
                                int_geom.geometry().wkbType(
                                )) == QgsWKBTypes.GeometryCollection:
                            # Intersection produced different geomety types
                            temp_list = int_geom.asGeometryCollection()
                            for i in temp_list:
                                if i.type() == geom.type():
                                    int_geom = QgsGeometry(i)
                                    try:
                                        outFeat.setGeometry(int_geom)
                                        outFeat.setAttributes(atMapA + atMapB)
                                        writer.addFeature(outFeat)
                                    except:
                                        ProcessingLog.addToLog(
                                            ProcessingLog.LOG_INFO,
                                            self.
                                            tr('Feature geometry error: One or more output features ignored due to invalid geometry.'
                                               ))
                        else:
                            # Geometry list: prevents writing error
                            # in geometries of different types
                            # produced by the intersection
                            # fix #3549
                            if int_geom.wkbType() in wkbTypeGroups[
                                    wkbTypeGroups[int_geom.wkbType()]]:
                                try:
                                    outFeat.setGeometry(int_geom)
                                    outFeat.setAttributes(atMapA + atMapB)
                                    writer.addFeature(outFeat)
                                except:
                                    ProcessingLog.addToLog(
                                        ProcessingLog.LOG_INFO,
                                        self.
                                        tr('Feature geometry error: One or more output features ignored due to invalid geometry.'
                                           ))

                # the remaining bit of inFeatA's geometry
                # if there is nothing left, this will just silently fail and we're good
                diff_geom = QgsGeometry(geom)
                if len(lstIntersectingB) != 0:
                    intB = QgsGeometry.unaryUnion(lstIntersectingB)
                    diff_geom = diff_geom.difference(intB)
                    if diff_geom.isGeosEmpty() or not diff_geom.isGeosValid():
                        ProcessingLog.addToLog(
                            ProcessingLog.LOG_ERROR,
                            self.
                            tr('GEOS geoprocessing error: One or more input features have invalid geometry.'
                               ))

                if diff_geom.wkbType() == 0 or QgsWKBTypes.flatType(
                        diff_geom.geometry().wkbType(
                        )) == QgsWKBTypes.GeometryCollection:
                    temp_list = diff_geom.asGeometryCollection()
                    for i in temp_list:
                        if i.type() == geom.type():
                            diff_geom = QgsGeometry(i)
                try:
                    outFeat.setGeometry(diff_geom)
                    outFeat.setAttributes(atMapA)
                    writer.addFeature(outFeat)
                except:
                    ProcessingLog.addToLog(
                        ProcessingLog.LOG_INFO,
                        self.
                        tr('Feature geometry error: One or more output features ignored due to invalid geometry.'
                           ))

        length = len(vproviderA.fields())
        atMapA = [None] * length

        featuresA = vector.features(vlayerB)
        nFeat = len(featuresA)
        for inFeatA in featuresA:
            progress.setPercentage(nElement / float(nFeat) * 100)
            add = False
            geom = QgsGeometry(inFeatA.geometry())
            diff_geom = QgsGeometry(geom)
            atMap = [None] * length
            atMap.extend(inFeatA.attributes())
            intersects = indexB.intersects(geom.boundingBox())

            if len(intersects) < 1:
                try:
                    outFeat.setGeometry(geom)
                    outFeat.setAttributes(atMap)
                    writer.addFeature(outFeat)
                except:
                    ProcessingLog.addToLog(
                        ProcessingLog.LOG_INFO,
                        self.
                        tr('Feature geometry error: One or more output features ignored due to invalid geometry.'
                           ))
            else:
                for id in intersects:
                    request = QgsFeatureRequest().setFilterFid(id)
                    inFeatB = vlayerA.getFeatures(request).next()
                    atMapB = inFeatB.attributes()
                    tmpGeom = QgsGeometry(inFeatB.geometry())

                    if diff_geom.intersects(tmpGeom):
                        add = True
                        diff_geom = QgsGeometry(diff_geom.difference(tmpGeom))
                        if diff_geom.isGeosEmpty(
                        ) or not diff_geom.isGeosValid():
                            ProcessingLog.addToLog(
                                ProcessingLog.LOG_ERROR,
                                self.
                                tr('GEOS geoprocessing error: One or more input features have invalid geometry.'
                                   ))
                    else:
                        try:
                            # Ihis only happends if the bounding box
                            # intersects, but the geometry doesn't
                            outFeat.setGeometry(diff_geom)
                            outFeat.setAttributes(atMap)
                            writer.addFeature(outFeat)
                        except:
                            ProcessingLog.addToLog(
                                ProcessingLog.LOG_INFO,
                                self.
                                tr('Feature geometry error: One or more output features ignored due to invalid geometry.'
                                   ))

            if add:
                try:
                    outFeat.setGeometry(diff_geom)
                    outFeat.setAttributes(atMap)
                    writer.addFeature(outFeat)
                except:
                    ProcessingLog.addToLog(
                        ProcessingLog.LOG_INFO,
                        self.
                        tr('Feature geometry error: One or more output features ignored due to invalid geometry.'
                           ))
            nElement += 1

        del writer