def resetSnapping(self):
     self.unlink_mode = False
     # disable previous snapping setting
     proj = QgsProject.instance()
     snapConfig = QgsSnappingConfig()
     if self.settings[0] != '' and self.settings[0]:
         # proj.writeEntry('Digitizing', 'SnappingMode', 'advanced')
         layer = lfh.getLayerByName(self.settings[0])
         if layer:  # layer might have been removed
             snapConfig.setMode(QgsSnappingConfig.AdvancedConfiguration)
             layerSnapConfig = QgsSnappingConfig.IndividualLayerSettings(False, QgsSnappingConfig.Vertex,
                                                                         self.settings[2], QgsTolerance.LayerUnits)
             snapConfig.setIndividualLayerSettings(layer, layerSnapConfig)
             proj.setAvoidIntersectionsLayers([layer])
     if self.settings[1] != 'no unlinks' and self.settings[1]:
         # proj.writeEntry('Digitizing', 'SnappingMode', 'advanced')
         layer = lfh.getLayerByName(self.settings[1])
         if layer:
             snapConfig.setMode(QgsSnappingConfig.AdvancedConfiguration)
             layerSnapConfig = QgsSnappingConfig.IndividualLayerSettings(False, QgsSnappingConfig.Vertex,
                                                                         self.settings[2], QgsTolerance.LayerUnits)
             snapConfig.setIndividualLayerSettings(layer, layerSnapConfig)
             proj.setAvoidIntersectionsLayers([])
     snapConfig.setIntersectionSnapping(False)
     proj.setSnappingConfig(snapConfig)
     return
    def startWorker(self):
        self.dlg.segmentingProgress.reset()
        self.settings = self.dlg.get_settings()
        if self.settings['output_type'] == 'postgis':
            db_settings = self.dlg.get_dbsettings()
            self.settings.update(db_settings)

        if lfh.getLayerByName(self.settings['input']).crs().postgisSrid() == 4326:
            self.giveMessage('Re-project the layer. EPSG:4326 not allowed.', Qgis.Info)
        elif self.settings['output'] != '':
            segmenting = self.Worker(self.settings, self.iface)
            self.dlg.lockGUI(True)
            # start the segmenting in a new thread
            thread = QThread()
            self.thread_error = ''
            segmenting.moveToThread(thread)
            segmenting.finished.connect(self.workerFinished)
            segmenting.error.connect(self.workerError)
            segmenting.warning.connect(self.giveMessage)
            segmenting.segm_progress.connect(self.dlg.segmentingProgress.setValue)

            thread.started.connect(segmenting.run)

            thread.start()

            self.thread = thread
            self.segmenting = segmenting
        else:
            self.giveMessage('Missing user input!', Qgis.Info)
            return
    def workerFinished(self, ret):
        # create the segmenting results layers
        if self.segmenting:
            # clean up the worker and thread
            self.segmenting.finished.disconnect(self.workerFinished)
            self.segmenting.error.disconnect(self.workerError)
            self.segmenting.warning.disconnect(self.giveMessage)
            self.segmenting.segm_progress.disconnect(self.dlg.segmentingProgress.setValue)
            # self.segmenting.my_segmentor.progress.disconnect(self.segm_progress.emit)

        self.thread.deleteLater()
        self.thread.quit()
        self.thread.wait()
        self.thread.deleteLater()

        if ret:
            self.dlg.lockGUI(False)
            # get segmenting settings
            layer_name = self.settings['input']
            output_path, errors_path = self.settings['output']
            output_type = self.settings['output_type']
            #  get settings from layer
            layer = lfh.getLayerByName(layer_name)

            break_lines, break_points = ret

            segmented = uf.to_layer(break_lines, layer.crs(), layer.dataProvider().encoding(),
                                    'Linestring', output_type, output_path)
            QgsProject.instance().addMapLayer(segmented)
            segmented.updateExtents()

            if self.settings['errors']:
                if len(break_points) == 0:
                    self.giveMessage('No points detected!', Qgis.Info)
                else:
                    errors = uf.to_layer(break_points, layer.crs(), layer.dataProvider().encoding(), 'Point',
                                         output_type,
                                         errors_path)
                    errors.loadNamedStyle(os.path.dirname(__file__) + '/errors_style.qml')
                    QgsProject.instance().addMapLayer(errors)
                    node = QgsProject.instance().layerTreeRoot().findLayer(errors.id())
                    self.iface.layerTreeView().layerTreeModel().refreshLayerLegend(node)

            self.giveMessage('Process ended successfully!', Qgis.Info)

        elif self.thread_error != '':
            # notify the user that sth went wrong
            self.giveMessage('Something went wrong! See the message log for more information', Qgis.Critical)
            QgsMessageLog.logMessage("Network segmenter error: %s" % self.thread_error)

        self.thread = None
        self.segmenting = None

        if self.dlg:
            self.dlg.segmentingProgress.reset()
            self.dlg.close()
Beispiel #4
0
    def startWorker(self):
        self.dlg.cleaningProgress.reset()
        self.settings = self.dlg.get_settings()
        if self.settings['output_type'] == 'postgis':
            db_settings = self.dlg.get_dbsettings()
            if 'dbname' not in db_settings:
                self.giveMessage(
                    'Please make sure a database is set for exporting to PostGIS',
                    Qgis.Info)
                return
            if 'schema' not in db_settings:
                self.giveMessage(
                    'Please make sure a schema is set for exporting to PostGIS',
                    Qgis.Info)
                return
            if 'table_name' not in db_settings:
                self.giveMessage(
                    'Please make sure a table is set for exporting to PostGIS',
                    Qgis.Info)
                return
            self.settings.update(db_settings)

        if lfh.getLayerByName(
                self.settings['input']).crs().postgisSrid() == 4326:
            self.giveMessage('Re-project the layer. EPSG:4326 not allowed.',
                             Qgis.Info)
            return
        elif self.settings['output'] != '':

            cleaning = self.Worker(self.settings, self.iface)
            # start the cleaning in a new thread
            self.dlg.lockGUI(True)
            self.dlg.lockSettingsGUI(True)
            thread = QThread()
            self.thread_error = ''
            cleaning.moveToThread(thread)
            cleaning.finished.connect(self.workerFinished)
            cleaning.error.connect(self.workerError)
            cleaning.warning.connect(self.giveMessage)
            cleaning.cl_progress.connect(self.dlg.cleaningProgress.setValue)

            thread.started.connect(cleaning.run)

            thread.start()

            self.thread = thread
            self.cleaning = cleaning

            if is_debug:
                print('started')
        else:
            self.giveMessage('Missing user input!', Qgis.Info)
            return
    def setUnlinkSnapping(self):
        # disable previous snapping setting if segment
        self.resetSnapping()

        # snap to vertex
        if self.settings[1] != 'no unlinks':
            self.resetIcons()
            unlink_icon = QPixmap(os.path.dirname(__file__) + "/custom_icons/unlink.png")
            self.unlinksButton.setIcon(QIcon(unlink_icon))
            self.unlinksButton.setIconSize(QSize(40, 40))
            proj = QgsProject.instance()
            # fix_print_with_import
            # fix_print_with_import
            print(proj, 'un')
            proj.writeEntry('Digitizing', 'SnappingMode', 'advanced')
            layer = lfh.getLayerByName(self.settings[0])
            unlinks_layer = lfh.getLayerByName(self.settings[1])
            # if unlinks_layer.isEditable():
            #    unlinks_layer.commitChanges()
            # else:
            #    unlinks_layer.startEditing()
            self.iface.setActiveLayer(unlinks_layer)
            snapConfig = QgsSnappingConfig()
            snapConfig.setMode(QgsSnappingConfig.AdvancedConfiguration)
            layerSnapConfig = QgsSnappingConfig.IndividualLayerSettings(True, QgsSnappingConfig.Vertex,
                                                                        self.settings[2], QgsTolerance.LayerUnits)
            snapConfig.setIndividualLayerSettings(layer, layerSnapConfig)
            proj.setAvoidIntersectionsLayers([layer])
            snapConfig.setIntersectionSnapping(True)
            snapConfig.setEnabled(True)
            QgsProject.instance().setSnappingConfig(snapConfig)
            proj.setTopologicalEditing(False)
            self.unlink_mode = True
        else:
            self.iface.messageBar().pushMessage("Unlinks layer not specified!", Qgis.Critical, duration=5)
            self.unlink_mode = False
        return
    def setAxialSnapping(self):
        # keep button pressed

        # un press other buttons

        # disable previous snapping setting
        self.resetSnapping()

        # self.axialButton.setCheckable(True)
        self.resetIcons()
        axial_icon = QPixmap(os.path.dirname(__file__) + "/custom_icons/axial.png")
        self.axialButton.setIcon(QIcon(axial_icon))
        self.axialButton.setIconSize(QSize(40, 40))

        # snap to nothing
        if self.settings[0] != '':
            proj = QgsProject.instance()
            # fix_print_with_import
            # fix_print_with_import
            print(proj, 'ax')
            proj.writeEntry('Digitizing', 'SnappingMode', 'advanced')
            layer = lfh.getLayerByName(self.settings[0])
            self.iface.setActiveLayer(layer)
            # if layer.isEditable():
            #    layer.commitChanges()
            # else:
            #    layer.startEditing()
            snapConfig = QgsSnappingConfig()
            snapConfig.setMode(QgsSnappingConfig.AdvancedConfiguration)
            layerSnapConfig = QgsSnappingConfig.IndividualLayerSettings(False, QgsSnappingConfig.Vertex,
                                                                        self.settings[2], QgsTolerance.LayerUnits)
            snapConfig.setIndividualLayerSettings(layer, layerSnapConfig)
            snapConfig.setEnabled(False)
            proj.setAvoidIntersectionsLayers([layer])
            proj.setSnappingConfig(snapConfig)
            proj.setTopologicalEditing(False)
            self.axial_mode = True
        else:
            self.iface.messageBar().pushMessage("Network layer not specified!", Qgis.Critical, duration=5)
            self.axial_mode = False
        return
Beispiel #7
0
        def run(self):
            if has_pydevd and is_debug:
                pydevd_pycharm.settrace('localhost',
                                        port=53100,
                                        stdoutToServer=True,
                                        stderrToServer=True,
                                        suspend=False)
            ret = None
            # if self.settings:
            try:
                # cleaning settings
                layer_name = self.settings['input']
                layer = lfh.getLayerByName(layer_name)
                snap_threshold = self.settings['snap']
                break_at_vertices = self.settings['break']
                merge_type = self.settings['merge']
                collinear_threshold = self.settings['collinear_angle']
                angle_threshold = self.settings['simplification_threshold']
                fix_unlinks = self.settings['fix_unlinks']
                orphans = self.settings['orphans']
                getUnlinks = self.settings['unlinks']
                [
                    load_range, cl1_range, cl2_range, cl3_range, break_range,
                    merge_range, snap_range, unlinks_range, fix_range
                ] = self.settings['progress_ranges']
                QgsMessageLog.logMessage('settings %s' % self.settings,
                                         level=Qgis.Critical)

                self.cl_progress.emit(0)

                if break_at_vertices:

                    self.pseudo_graph.step = load_range / float(
                        layer.featureCount())
                    self.pseudo_graph.progress.connect(self.cl_progress.emit)
                    self.graph = sGraph({}, {})
                    self.graph.total_progress = load_range
                    self.pseudo_graph.load_edges_w_o_topology(
                        utf.clean_features_iter(layer.getFeatures()))
                    QgsMessageLog.logMessage('pseudo_graph edges added %s' %
                                             load_range,
                                             level=Qgis.Critical)
                    self.pseudo_graph.step = break_range / float(
                        len(self.pseudo_graph.sEdges))
                    self.graph.load_edges(
                        self.pseudo_graph.break_features_iter(
                            getUnlinks, angle_threshold, fix_unlinks),
                        angle_threshold)
                    QgsMessageLog.logMessage('pseudo_graph edges broken %s' %
                                             break_range,
                                             level=Qgis.Critical)
                    self.pseudo_graph.progress.disconnect()
                    self.graph.progress.connect(self.cl_progress.emit)
                    self.graph.total_progress = self.pseudo_graph.total_progress

                else:
                    self.graph = sGraph({}, {})
                    self.graph.progress.connect(self.cl_progress.emit)
                    self.graph.step = load_range / float(layer.featureCount())
                    self.graph.load_edges(
                        utf.clean_features_iter(layer.getFeatures()),
                        angle_threshold)
                    QgsMessageLog.logMessage('graph edges added %s' %
                                             load_range,
                                             level=Qgis.Critical)

                self.graph.step = cl1_range / (float(len(self.graph.sEdges)) *
                                               2.0)
                if orphans:
                    self.graph.clean(True, False, snap_threshold, True)
                else:
                    self.graph.clean(True, False, snap_threshold, False)
                QgsMessageLog.logMessage(
                    'graph clean parallel and closed pl %s' % cl1_range,
                    level=Qgis.Critical)

                if fix_unlinks:
                    self.graph.step = fix_range / float(len(self.graph.sEdges))
                    self.graph.fix_unlinks()
                    QgsMessageLog.logMessage('unlinks added  %s' % fix_range,
                                             level=Qgis.Critical)

                # TODO clean iteratively until no error

                if snap_threshold != 0:

                    self.graph.step = snap_range / float(len(
                        self.graph.sNodes))
                    self.graph.snap_endpoints(snap_threshold)
                    QgsMessageLog.logMessage('snap  %s' % snap_range,
                                             level=Qgis.Critical)
                    self.graph.step = cl2_range / (
                        float(len(self.graph.sEdges)) * 2.0)

                    if orphans:
                        self.graph.clean(True, False, snap_threshold, True)
                    else:
                        self.graph.clean(True, False, snap_threshold, False)
                    QgsMessageLog.logMessage('clean   %s' % cl2_range,
                                             level=Qgis.Critical)

                if merge_type == 'intersections':

                    self.graph.step = merge_range / float(
                        len(self.graph.sNodes))
                    self.graph.merge_b_intersections(angle_threshold)
                    QgsMessageLog.logMessage('merge %s %s angle_threshold ' %
                                             (merge_range, angle_threshold),
                                             level=Qgis.Critical)

                elif merge_type == 'collinear':

                    self.graph.step = merge_range / float(
                        len(self.graph.sEdges))
                    self.graph.merge_collinear(collinear_threshold,
                                               angle_threshold)
                    QgsMessageLog.logMessage('merge  %s' % merge_range,
                                             level=Qgis.Critical)

                # cleaned multiparts so that unlinks are generated properly
                if orphans:
                    self.graph.step = cl3_range / (
                        float(len(self.graph.sEdges)) * 2.0)
                    self.graph.clean(True, orphans, snap_threshold, False,
                                     True)
                    QgsMessageLog.logMessage('clean  %s' % cl3_range,
                                             level=Qgis.Critical)
                else:
                    self.graph.step = cl3_range / (
                        float(len(self.graph.sEdges)) * 2.0)
                    self.graph.clean(True, False, snap_threshold, False, True)
                    QgsMessageLog.logMessage('clean %s' % cl3_range,
                                             level=Qgis.Critical)

                if getUnlinks:
                    self.graph.step = unlinks_range / float(
                        len(self.graph.sEdges))
                    self.graph.generate_unlinks()
                    QgsMessageLog.logMessage('unlinks generated %s' %
                                             unlinks_range,
                                             level=Qgis.Critical)
                    unlinks = self.graph.unlinks
                else:
                    unlinks = []

                cleaned_features = [
                    e.feature for e in list(self.graph.sEdges.values())
                ]
                # add to errors multiparts and points
                self.graph.errors += utf.multiparts
                self.graph.errors += utf.points

                if is_debug:
                    print("survived!")
                self.graph.progress.disconnect()
                self.cl_progress.emit(95)
                # return cleaned data, errors and unlinks
                ret = cleaned_features, self.graph.errors, unlinks

            except Exception as e:
                # forward the exception upstream
                self.error.emit(e, traceback.format_exc())

            self.finished.emit(ret)
Beispiel #8
0
    def workerFinished(self, ret):

        if self.cleaning:
            # clean up the worker and thread
            self.cleaning.finished.disconnect(self.workerFinished)
            self.cleaning.error.disconnect(self.workerError)
            self.cleaning.warning.disconnect(self.giveMessage)
            self.cleaning.cl_progress.disconnect(
                self.dlg.cleaningProgress.setValue)

        # clean up the worker and thread
        self.thread.deleteLater()
        self.thread.quit()
        self.thread.wait()
        self.thread.deleteLater()

        if ret:
            self.dlg.lockGUI(False)
            # TODO: only if edit default has been pressed before
            self.dlg.lockSettingsGUI(False)
            # get cleaning settings
            layer_name = self.settings['input']
            path, unlinks_path, errors_path = self.settings[
                'output']  # if postgis: connstring, schema, table_name

            output_type = self.settings['output_type']
            #  get settings from layer
            layer = lfh.getLayerByName(layer_name)

            cleaned_features, errors_features, unlinks_features = ret

            if self.settings['errors']:
                if len(errors_features) > 0:
                    errors = utf.to_layer(errors_features, layer.crs(),
                                          layer.dataProvider().encoding(),
                                          'Point', output_type, errors_path)
                    errors.loadNamedStyle(
                        os.path.dirname(__file__) + '/qgis_styles/errors.qml')
                    QgsProject.instance().addMapLayer(errors)
                    node = QgsProject.instance().layerTreeRoot().findLayer(
                        errors.id())
                    self.iface.layerTreeView().layerTreeModel(
                    ).refreshLayerLegend(node)
                    QgsMessageLog.logMessage('layer name %s' % layer_name,
                                             level=Qgis.Critical)
                else:
                    self.giveMessage('No errors detected!', Qgis.Info)

            if self.settings['unlinks']:
                if len(unlinks_features) > 0:
                    unlinks = utf.to_layer(unlinks_features, layer.crs(),
                                           layer.dataProvider().encoding(),
                                           'Point', output_type, unlinks_path)
                    unlinks.loadNamedStyle(
                        os.path.dirname(__file__) + '/qgis_styles/unlinks.qml')
                    QgsProject.instance().addMapLayer(unlinks)
                    node = QgsProject.instance().layerTreeRoot().findLayer(
                        unlinks.id())
                    self.iface.layerTreeView().layerTreeModel(
                    ).refreshLayerLegend(node)
                else:
                    self.giveMessage('No unlinks detected!', Qgis.Info)

            cleaned = utf.to_layer(cleaned_features, layer.crs(),
                                   layer.dataProvider().encoding(),
                                   'Linestring', output_type, path)
            cleaned.loadNamedStyle(
                os.path.dirname(__file__) + '/qgis_styles/cleaned.qml')
            QgsProject.instance().addMapLayer(cleaned)
            node = QgsProject.instance().layerTreeRoot().findLayer(
                cleaned.id())
            self.iface.layerTreeView().layerTreeModel().refreshLayerLegend(
                node)
            cleaned.updateExtents()

            self.giveMessage('Process ended successfully!', Qgis.Info)
            self.dlg.cleaningProgress.setValue(100)

        elif self.thread_error != '':
            # notify the user that sth went wrong
            self.giveMessage(
                'Something went wrong! See the message log for more information',
                Qgis.Critical)
            QgsMessageLog.logMessage("Cleaning thread error: %s" %
                                     self.thread_error)

        self.thread = None
        self.cleaning = None

        if self.dlg:
            self.dlg.cleaningProgress.reset()
            self.dlg.close()
Beispiel #9
0
import time

from qgis.core import QgsProject

from rcl_cleaner.sGraph.sGraph import sGraph
from rcl_cleaner.sGraph.utilityFunctions import (clean_features_iter, to_layer)
from esstoolkit.utilities import layer_field_helpers as lfh

# parameters
layer_name = 'gb_roadlink_test'
# time with previous version: ~ 16 minutes
# time with new      version: ~ 3 minutes
# reduction: 80%

layer = lfh.getLayerByName(layer_name)
crs = layer.crs()
encoding = layer.dataProvider().encoding()
geom_type = layer.dataProvider().geometryType()
getUnlinks = True
snap_threshold = 1
angle_threshold = 0
merge_type = 'intersections'
# merge_type = 'collinear'
orphans = False
fix_unlinks = True
collinear_threshold = 0
duplicates = True

path = None
        def run(self):
            if has_pydevd and is_debug:
                pydevd.settrace('localhost', port=53100, stdoutToServer=True, stderrToServer=True, suspend=False)
            ret = None
            # if self.settings:
            try:
                # segmenting settings
                layer_name = self.settings['input']
                unlinks_layer_name = self.settings['unlinks']
                layer = lfh.getLayerByName(layer_name)
                unlinks = lfh.getLayerByName(unlinks_layer_name)
                stub_ratio = self.settings['stub_ratio']
                buffer = self.settings['buffer']
                errors = self.settings['errors']

                # print layer, unlinks, stub_ratio, buffer

                self.my_segmentor = segmentor(layer, unlinks, stub_ratio, buffer, errors)

                self.my_segmentor.progress.connect(self.segm_progress.emit)

                break_point_feats, invalid_unlink_point_feats, stubs_point_feats, segmented_feats = [], [], [], []

                # TODO: if postgis - run function
                self.my_segmentor.step = 10 / float(self.my_segmentor.layer.featureCount())
                self.my_segmentor.load_graph()
                # self.step specified in load_graph
                # progress emitted by break_segm & break_feats_iter
                cross_p_list = [self.my_segmentor.break_segm(feat) for feat in
                                self.my_segmentor.list_iter(list(self.my_segmentor.feats.values()))]
                self.my_segmentor.step = 20 / float(len(cross_p_list))
                segmented_feats = [self.my_segmentor.copy_feat(feat_geom_fid[0], feat_geom_fid[1], feat_geom_fid[2]) for
                                   feat_geom_fid in self.my_segmentor.break_feats_iter(cross_p_list)]

                if errors:
                    cross_p_list = set(list(itertools.chain.from_iterable(cross_p_list)))

                    ids1 = [i for i in range(0, len(cross_p_list))]
                    break_point_feats = [
                        self.my_segmentor.copy_feat(self.my_segmentor.break_f, QgsGeometry.fromPointXY(p_fid[0]),
                                                    p_fid[1]) for p_fid in (list(zip(cross_p_list, ids1)))]
                    ids2 = [i for i in range(max(ids1) + 1, max(ids1) + 1 + len(self.my_segmentor.invalid_unlinks))]
                    invalid_unlink_point_feats = [self.my_segmentor.copy_feat(self.my_segmentor.invalid_unlink_f,
                                                                              QgsGeometry.fromPointXY(p_fid1[0]),
                                                                              p_fid1[1]) for p_fid1 in
                                                  (list(zip(self.my_segmentor.invalid_unlinks, ids2)))]
                    ids = [i for i in
                           range(max(ids1 + ids2) + 1, max(ids1 + ids2) + 1 + len(self.my_segmentor.stubs_points))]
                    stubs_point_feats = [
                        self.my_segmentor.copy_feat(self.my_segmentor.stub_f, QgsGeometry.fromPointXY(p_fid2[0]),
                                                    p_fid2[1]) for p_fid2 in
                        (list(zip(self.my_segmentor.stubs_points, ids)))]

                ret = segmented_feats, break_point_feats + invalid_unlink_point_feats + stubs_point_feats

                self.my_segmentor.progress.disconnect()

            except Exception as e:
                print(e)
                self.error.emit(e, traceback.format_exc())

            # print "survived!"

            self.finished.emit(ret)
# INPUT
from qgis.PyQt.QtCore import QVariant
from qgis.analysis import QgsGraphBuilder
from qgis.core import (QgsSpatialIndex, QgsGeometry, QgsFeature, QgsFields, QgsField, QgsWkbTypes)

import catchment_analyser.catchment_analysis as catchment
import catchment_analyser.utility_functions as uf
from catchment_analyser.analysis_tools import CustomCost
from esstoolkit.utilities import layer_field_helpers as lfh

origin_vector = lfh.getLayerByName('2595D_pr_tfl_bus_stops')
network = lfh.getLayerByName('2595D_spm_pr2_seg2')
origin_name_field = None
cost_field = 'length'
tolerance = 0.01
crs = network.crs()
epsg = network.crs().authid()[5:]

# ANALYSIS

# 1. prepare origins
# Loop through origin and get or create points
origins = []
for i, f in enumerate(origin_vector.getFeatures()):
    # Get origin name
    if origin_name_field:
        origin_name = f[origin_name_field]
    else:
        origin_name = i  # "origin_" + "%s" % (i+1)
    origins.append({'name': origin_name, 'geom': f.geometry().centroid()})