def clean_features_iter(feat_iter):
    id = 0
    for f in feat_iter:

        f_geom = f.geometry()  # can be None

        # dropZValue if geometry is 3D
        if f_geom is None or f.geometry().constGet() is None:
            pass
        elif f.geometry().constGet().is3D():
            f.geometry().constGet().dropZValue()
            f_geom = f.geometry()

        if f_geom is None or f_geom is NULL or not f_geom.isGeosValid():
            # empty or invalid geometry
            pass
        elif f_geom.length() <= 0:
            ml_error = QgsFeature(error_feat)
            if f_geom.isMultipart():
                ml_error.setGeometry(
                    QgsGeometry.fromPointXY(f_geom.asMultiPolyline()[0][0]))
            else:
                ml_error.setGeometry(
                    QgsGeometry.fromPointXY(f_geom.asPolyline()[0]))
            ml_error.setAttributes(['point'])
            points.append(ml_error)
        elif f_geom.type() == QgsWkbTypes.LineGeometry:
            if not f_geom.isMultipart():
                f.setId(id)
                id += 1
                yield f
            else:
                # multilinestring
                ml_segms = f_geom.asMultiPolyline()
                for ml in ml_segms:
                    ml_geom = QgsGeometry(QgsGeometry.fromPolylineXY(ml))
                    ml_feat = QgsFeature(f)
                    ml_feat.setId(id)
                    id += 1
                    ml_feat.setGeometry(ml_geom)
                    ml_error = QgsFeature(error_feat)
                    ml_error.setGeometry(
                        QgsGeometry.fromPointXY(ml_geom.asPolyline()[0]))
                    ml_error.setAttributes(['multipart'])
                    multiparts.append(ml_error)
                    ml_error = QgsFeature(error_feat)
                    ml_error.setGeometry(
                        QgsGeometry.fromPointXY(ml_geom.asPolyline()[-1]))
                    ml_error.setAttributes(['multipart'])
                    multiparts.append(ml_error)
                    yield ml_feat
Example #2
0
    def drawOnePath(self, rows, con, args, geomType, canvasItemList, mapCanvas):
        ''' draws  line string on the mapCanvas. '''
        resultPathRubberBand = canvasItemList['path']
        for row in rows:
                cur2 = con.cursor()
                args['result_node_id'] = sql.Literal(row[1])
                args['result_edge_id'] = sql.Literal(row[2])
                args['result_cost'] = row[3]
                if row[2] != -1:
                    query2 = sql.SQL("""
                        SELECT ST_AsText({geom_t} FROM {edge_schema}.{edge_table}
                            WHERE {source} = {result_node_id} AND {id} = {result_edge_id}
                        UNION
                        SELECT ST_AsText(ST_Reverse({geom_t}) FROM {edge_schema}.{edge_table}
                            WHERE {target} = {result_node_id} AND {id} = {result_edge_id};
                    """).format(**args)

                    cur2.execute(query2)
                    row2 = cur2.fetchone()

                    geom = QgsGeometry().fromWkt(str(row2[0]))
                    if geom.wkbType() == QgsWkbTypes.MultiLineString:
                        for line in geom.asMultiPolyline():
                            for pt in line:
                                resultPathRubberBand.addPoint(pt)
                    elif geom.wkbType() == QgsWkbTypes.LineString:
                        for pt in geom.asPolyline():
                            resultPathRubberBand.addPoint(pt)
    def polygon_to_segments(self, geometry):
        # polygons to lines (mutlipart)
        boundary = QgsGeometry(geometry.constGet().boundary())
        boundaries = boundary.asGeometryCollection()

        segments = []

        for boundary in boundaries:
            if boundary.isMultipart():
                lines = boundary.asMultiPolyline()
                for line in lines:
                    for i in range(len(line) - 1):
                        p1 = QgsPoint(line[i])
                        p2 = QgsPoint(line[i + 1])

                        segment = create_normalized_segment(p1, p2)
                        segment_wkt = segment.asWkt()
                        segments.append(segment)
            else:
                line = boundary.asPolyline()
                for i in range(len(line) - 1):
                    p1 = QgsPoint(line[i])
                    p2 = QgsPoint(line[i + 1])

                    segment = create_normalized_segment(p1, p2)
                    segments.append(segment)
        return segments
Example #4
0
def arcsAadjacencyDictionary(layer):
    '''Build arc adjacency dictionary for the input stream network layer.

    This dictionary is a set of adjacency lists compiled for each node in
    th network.
    '''
    arcsPerNode = dict()

    for f in layer.getFeatures():
        geom = QgsGeometry(f.geometry())
        polyline = geom.asPolyline()
        fromNode = polyline[0]
        toNode = polyline[-1]

        if fromNode not in arcsPerNode:
            arcsPerNode[fromNode] = [f]
        else:
            arcsPerNode[fromNode].append(f)

        if toNode not in arcsPerNode:
            arcsPerNode[toNode] = [f]
        else:
            arcsPerNode[toNode].append(f)

    return arcsPerNode
Example #5
0
    def drawOnePath(self, rows, con, args, geomType, canvasItemList,
                    mapCanvas):
        ''' draws  line string on the mapCanvas. '''
        resultPathRubberBand = canvasItemList['path']
        for row in rows:
            cur2 = con.cursor()
            args['result_node_id'] = row[1]
            args['result_edge_id'] = row[2]
            args['result_cost'] = row[3]
            if args['result_edge_id'] != -1:
                query2 = """
                        SELECT ST_AsText(%(transform_s)s%(geometry)s%(transform_e)s) FROM %(edge_table)s
                            WHERE %(source)s = %(result_node_id)d AND %(id)s = %(result_edge_id)d
                        UNION
                        SELECT ST_AsText(%(transform_s)sST_Reverse(%(geometry)s)%(transform_e)s) FROM %(edge_table)s
                            WHERE %(target)s = %(result_node_id)d AND %(id)s = %(result_edge_id)d;
                    """ % args
                ##Utils.logMessage(query2)
                cur2.execute(query2)
                row2 = cur2.fetchone()
                ##Utils.logMessage(str(row2[0]))
                assert row2, "Invalid result geometry. (node_id:%(result_node_id)d, edge_id:%(result_edge_id)d)" % args

                geom = QgsGeometry().fromWkt(str(row2[0]))
                if geom.wkbType() == QgsWkbTypes.MultiLineString:
                    for line in geom.asMultiPolyline():
                        for pt in line:
                            resultPathRubberBand.addPoint(pt)
                elif geom.wkbType() == QgsWkbTypes.LineString:
                    for pt in geom.asPolyline():
                        resultPathRubberBand.addPoint(pt)
Example #6
0
    def draw(self, rows, con, args, geomType, canvasItemList, mapCanvas):
        ''' draw the result '''
        resultPathRubberBand = canvasItemList['path']
        i = 0
        count = len(rows)
        for row in rows:
            query2 = ""
            cur2 = con.cursor()
            args['result_node_id'] = row[1]
            args['result_edge_id'] = row[2]
            args['result_cost'] = row[3]

            if i == 0 and args['result_node_id'] == -1:
                args['result_next_node_id'] = rows[i + 1][1]
                query2 = """
                    SELECT ST_AsText(%(transform_s)sST_Line_Substring(%(geometry)s, %(source_pos)s, 1.0)%(transform_e)s) FROM %(edge_table)s
                        WHERE %(target)s = %(result_next_node_id)s AND %(id)s = %(result_edge_id)s
                    UNION
                    SELECT ST_AsText(%(transform_s)sST_Line_Substring(ST_Reverse(%(geometry)s), 1.0 - %(source_pos)s, 1.0)%(transform_e)s) FROM %(edge_table)s
                        WHERE %(source)s = %(result_next_node_id)s AND %(id)s = %(result_edge_id)s;
                """ % args
            elif i == (count - 1) and ((args['result_edge_id'] == -1) or (str(args['result_edge_id']) == args['target_id'])):
                if args['result_edge_id'] != -1:
                    query2 = """
                        SELECT ST_AsText(%(transform_s)sST_Line_Substring(%(geometry)s, 0.0, %(target_pos)s)%(transform_e)s) FROM %(edge_table)s
                            WHERE %(source)s = %(result_node_id)s AND %(id)s = %(result_edge_id)s
                        UNION
                        SELECT ST_AsText(%(transform_s)sST_Line_Substring(ST_Reverse(%(geometry)s), 0.0, 1.0 - %(target_pos)s)%(transform_e)s) FROM %(edge_table)s
                            WHERE %(target)s = %(result_node_id)s AND %(id)s = %(result_edge_id)s;
                    """ % args
                else:
                    break
            else:
                query2 = """
                    SELECT ST_AsText(%(transform_s)s%(geometry)s%(transform_e)s) FROM %(edge_table)s
                        WHERE %(source)s = %(result_node_id)d AND %(id)s = %(result_edge_id)d
                    UNION
                    SELECT ST_AsText(%(transform_s)sST_Reverse(%(geometry)s)%(transform_e)s) FROM %(edge_table)s
                        WHERE %(target)s = %(result_node_id)d AND %(id)s = %(result_edge_id)d;
                """ % args

            ##Utils.logMessage(query2)
            cur2.execute(query2)
            row2 = cur2.fetchone()
            ##Utils.logMessage(str(row2[0]))
            assert row2, "Invalid result geometry. (node_id:%(result_node_id)d, edge_id:%(result_edge_id)d)" % args

            geom = QgsGeometry().fromWkt(str(row2[0]))
            if geom.wkbType() == QgsWkbTypes.MultiLineString:
                for line in geom.asMultiPolyline():
                    for pt in line:
                        resultPathRubberBand.addPoint(pt)
            elif geom.wkbType() == QgsWkbTypes.LineString:
                for pt in geom.asPolyline():
                    resultPathRubberBand.addPoint(pt)

            i = i + 1
Example #7
0
    def draw(self, rows, con, args, geomType, canvasItemList, mapCanvas):
        ''' draw the result '''
        resultPathsRubberBands = canvasItemList['paths']
        rubberBand = None
        cur_route_id = -1
        for row in rows:
            cur2 = con.cursor()

            if self.version < 2.1:
                args['result_route_id'] = row[1]
                args['result_node_id'] = row[2]
                args['result_edge_id'] = row[3]
                args['result_cost'] = row[4]
            else:
                args['result_route_id'] = row[2]
                args['result_node_id'] = row[4]
                args['result_edge_id'] = row[5]
                args['result_cost'] = row[6]

            if args['result_route_id'] != cur_route_id:
                cur_route_id = args['result_route_id']
                if rubberBand:
                    resultPathsRubberBands.append(rubberBand)
                    rubberBand = None

                rubberBand = QgsRubberBand(mapCanvas,
                                           Utils.getRubberBandType(False))
                rubberBand.setColor(QColor(255, 0, 0, 128))
                rubberBand.setWidth(4)

            if args['result_edge_id'] != -1:
                #if args['result_edge_id'] != 0: # pgRouting <= 2.0.0rc1
                query2 = """
                    SELECT ST_AsText(%(transform_s)s%(geometry)s%(transform_e)s) FROM %(edge_table)s
                        WHERE %(source)s = %(result_node_id)d AND %(id)s = %(result_edge_id)d
                    UNION
                    SELECT ST_AsText(%(transform_s)sST_Reverse(%(geometry)s)%(transform_e)s) FROM %(edge_table)s
                        WHERE %(target)s = %(result_node_id)d AND %(id)s = %(result_edge_id)d;
                """ % args
                ##Utils.logMessage(query2)
                cur2.execute(query2)
                row2 = cur2.fetchone()
                ##Utils.logMessage(str(row2[0]))
                assert row2, "Invalid result geometry. (route_id:%(result_route_id)d, node_id:%(result_node_id)d, edge_id:%(result_edge_id)d)" % args

                geom = QgsGeometry().fromWkt(str(row2[0]))
                if geom.wkbType() == QgsWkbTypes.MultiLineString:
                    for line in geom.asMultiPolyline():
                        for pt in line:
                            rubberBand.addPoint(pt)
                elif geom.wkbType() == QgsWkbTypes.LineString:
                    for pt in geom.asPolyline():
                        rubberBand.addPoint(pt)

        if rubberBand:
            resultPathsRubberBands.append(rubberBand)
            rubberBand = None
Example #8
0
    def drawManyPaths(self, rows, columns, con, args, geomType, canvasItemList, mapCanvas):
        '''
            draws multi line string on the mapCanvas.
        '''
        resultPathsRubberBands = canvasItemList['paths']
        rubberBand = None
        cur_path_id = None
        for row in rows:
            cur2 = con.cursor()
            result_path_id = str(row[columns[0]])
            args['result_node_id'] = sql.Literal(row[columns[1]])
            args['result_edge_id'] = sql.Literal(row[columns[2]])

            if result_path_id != cur_path_id:
                cur_path_id = result_path_id
                if rubberBand:
                    resultPathsRubberBands.append(rubberBand)
                    rubberBand = None

                rubberBand = QgsRubberBand(mapCanvas, Utils.getRubberBandType(False))
                rubberBand.setColor(QColor(255, 0, 0, 128))
                rubberBand.setWidth(4)

            if row[columns[2]] != -1:
                query2 = sql.SQL("""
                    SELECT ST_AsText({transform_s}{geometry}{transform_e})
                    FROM {edge_schema}.{edge_table}
                    WHERE {source} = {result_node_id} AND {id} = {result_edge_id}

                    UNION

                    SELECT ST_AsText({transform_s}ST_Reverse({geometry}){transform_e})
                    FROM {edge_schema}.{edge_table}
                    WHERE {target} = {result_node_id} AND {id} = {result_edge_id}
                    """).format(**args).as_string(con)

                cur2.execute(query2)
                row2 = cur2.fetchone()

                geom = QgsGeometry().fromWkt(str(row2[0]))
                if geom.wkbType() == QgsWkbTypes.MultiLineString:
                    for line in geom.asMultiPolyline():
                        for pt in line:
                            rubberBand.addPoint(pt)
                elif geom.wkbType() == QgsWkbTypes.LineString:
                    for pt in geom.asPolyline():
                        rubberBand.addPoint(pt)

        if rubberBand:
            resultPathsRubberBands.append(rubberBand)
            rubberBand = None
Example #9
0
class GeometryHighlight(QgsMapCanvasItem):

    _mapCanvas = None  # QgsMapCanvas
    _geometry = None  # QgsGeometry()
    _brush = QBrush()
    _pen = QPen()

    def __init__(self, mapCanvas, geometry, layer):
        super(GeometryHighlight, self).__init__(mapCanvas)
        self._mapCanvas = mapCanvas
        if not geometry or not isinstance(geometry, QgsGeometry) or geometry.isEmpty() or not geometry.isGeosValid():
            return
        self._geometry = QgsGeometry(geometry) # Force deep copy
        self.setLineColor(Project.highlightLineColor())
        self.setFillColor(Project.highlightFillColor())
        if (layer and self._mapCanvas.mapSettings().hasCrsTransformEnabled()):
            ct = self._mapCanvas.mapSettings().layerTransform(layer)
            if ct:
                self._geometry.transform(ct)
        self.updateRect()
        self.update()

    def remove(self):
        self._mapCanvas.scene().removeItem(self)

    def setLineWidth(self, width):
        self._pen.setWidth(width)

    def setLineColor(self, color):
        lineColor = QColor(color)
        lineColor.setAlpha(255)
        self._pen.setColor(lineColor)

    def setFillColor(self, fillColor):
        self._brush.setColor(fillColor)
        self._brush.setStyle(Qt.SolidPattern)

    def updatePosition(self):
        pass

    # protected:
    def paint(self, painter, option=None, widget=None): # Override
        if not self._geometry:
            return

        painter.setPen(self._pen)
        painter.setBrush(self._brush)

        wkbType = self._geometry.wkbType()
        if wkbType == QGis.WKBPoint or wkbType == QGis.WKBPoint25D:
            self._paintPoint(painter, self._geometry.asPoint())
        elif wkbType == QGis.WKBMultiPoint or wkbType == QGis.WKBMultiPoint25D:
            for point in self._geometry.asMultiPoint():
                self._paintPoint(painter, point)
        elif wkbType == QGis.WKBLineString or wkbType == QGis.WKBLineString25D:
            self._paintLine(painter, self._geometry.asPolyline())
        elif wkbType == QGis.WKBMultiLineString or wkbType == QGis.WKBMultiLineString25D:
            for line in self._geometry.asMultiPolyline():
                self._paintLine(painter, line)
        elif wkbType == QGis.WKBPolygon or wkbType == QGis.WKBPolygon25D:
            self._paintPolygon(painter, self._geometry.asPolygon())
        elif wkbType == QGis.WKBMultiPolygon or wkbType == QGis.WKBMultiPolygon25D:
            for polygon in self._geometry.asMultiPolygon():
                self._paintPolygon(painter, polygon)

    def updateRect(self):
        if self._geometry:
            r = self._geometry.boundingBox()
            if r.isEmpty():
                d = self._mapCanvas.extent().width() * 0.005
                r.setXMinimum(r.xMinimum() - d)
                r.setYMinimum(r.yMinimum() - d)
                r.setXMaximum(r.xMaximum() + d)
                r.setYMaximum(r.yMaximum() + d)
            self.setRect(r)
            self.setVisible(True)
        else:
            self.setRect(QgsRectangle())

    # private:

    def _paintPoint(self, painter, point):
        painter.drawEllipse(self.toCanvasCoordinates(point) - self.pos(), 2, 2)

    def _paintLine(self, painter, line):
        polyline = QPolygonF()
        for point in line:
            polyline.append(self.toCanvasCoordinates(point) - self.pos())
        painter.drawPolyline(polyline)

    def _paintPolygon(self, painter, polygon):
        path = QPainterPath()
        for line in polygon:
            ring = QPolygonF()
            for point in line:
                cur = self.toCanvasCoordinates(point) - self.pos()
                ring.append(cur)
            ring.append(ring[0])
            path.addPolygon(ring)
        painter.drawPath(path)
Example #10
0
    def canvasReleaseEvent(self, event):

        if not self.mouse_clicked:
            return

        if event.button() == Qt.LeftButton:

            self.mouse_clicked = False

            # Find first available ID for Junctions
            node_eid = NetworkUtils.find_next_id(
                self.params.junctions_vlay, Junction.prefix)  # TODO: softcode

            elev = 0
            if self.elev is None and self.params.dem_rlay is not None:
                self.iface.messageBar().pushMessage(
                    Parameters.plug_in_name,
                    'Elevation value not available: element elevation set to 0.',
                    QgsMessageBar.WARNING, 5)  # TODO: softcode
            else:
                elev = self.elev

            j_demand = float(self.data_dock.txt_junction_demand.text())
            deltaz = float(self.data_dock.txt_junction_deltaz.text())

            pattern = self.data_dock.cbo_junction_pattern.itemData(
                self.data_dock.cbo_junction_pattern.currentIndex())
            if pattern is not None:
                pattern_id = pattern.id
            else:
                pattern_id = None

            emitter_coeff_s = self.data_dock.txt_junction_emit_coeff.text()
            if emitter_coeff_s is None or emitter_coeff_s == '':
                emitter_coeff = float(0)
            else:
                emitter_coeff = float(
                    self.data_dock.txt_junction_emit_coeff.text())

            junction_desc = self.data_dock.txt_junction_desc.text()
            junction_tag = self.data_dock.cbo_junction_tag.currentText()

            # No links snapped: create a new stand-alone node
            if self.snapped_feat_id is None:

                NodeHandler.create_new_junction(self.params, self.mouse_pt,
                                                node_eid, elev, j_demand,
                                                deltaz, pattern_id,
                                                emitter_coeff, junction_desc,
                                                junction_tag)

            # A link has been snapped
            else:

                # Get the snapped pipe
                request = QgsFeatureRequest().setFilterFid(
                    self.snapped_feat_id)
                feats = list(self.params.pipes_vlay.getFeatures(request))
                if len(feats) > 0:
                    snapped_pipe = QgsFeature(feats[0])

                    snapped_ft_pts = QgsGeometry.asPolyline(
                        snapped_pipe.geometry())

                    # The new junction is on the start or end node of the pipe
                    if NetworkUtils.points_overlap(QgsGeometry.fromPoint(self.snapped_vertex), QgsGeometry.fromPoint(snapped_ft_pts[0]), self.params.tolerance) or\
                        NetworkUtils.points_overlap(QgsGeometry.fromPoint(self.snapped_vertex), QgsGeometry.fromPoint(snapped_ft_pts[len(snapped_ft_pts) - 1]), self.params.tolerance):

                        NodeHandler.create_new_junction(
                            self.params, self.snapped_vertex, node_eid,
                            self.elev, j_demand, deltaz, pattern_id,
                            emitter_coeff, junction_desc, junction_tag)

                    else:

                        # Split the pipe
                        (start_node_ft,
                         end_node_ft) = NetworkUtils.find_start_end_nodes(
                             self.params, snapped_pipe.geometry())

                        if start_node_ft is None or end_node_ft is None:
                            self.iface.messageBar().pushMessage(
                                Parameters.plug_in_name,
                                'The pipe is missing the start or end nodes. Cannot add a new junction along the pipe.',
                                QgsMessageBar.WARNING, 5)  # TODO: softcode
                            return

                        # Check that the snapped point on line is distant enough from start/end nodes
                        if start_node_ft.geometry().distance(QgsGeometry.fromPoint(self.snapped_vertex)) > self.params.min_dist and\
                            end_node_ft.geometry().distance(QgsGeometry.fromPoint(self.snapped_vertex)) > self.params.min_dist:

                            NodeHandler.create_new_junction(
                                self.params, self.snapped_vertex, node_eid,
                                self.elev, j_demand, deltaz, pattern_id,
                                emitter_coeff, junction_desc, junction_tag)

                            LinkHandler.split_pipe(self.params, snapped_pipe,
                                                   self.snapped_vertex)
                        else:
                            self.iface.messageBar().pushMessage(
                                Parameters.plug_in_name,
                                'The new junction is too close to either the pipe end or start nodes. Cannot add a new junction along the pipe.',
                                QgsMessageBar.WARNING, 5)  # TODO: softcode
Example #11
0
    def processAlgorithm(self, progress):
        layer = dataobjects.getObjectFromUri(
            self.getParameterValue(self.VECTOR))
        pointCount = float(self.getParameterValue(self.POINT_NUMBER))
        minDistance = float(self.getParameterValue(self.MIN_DISTANCE))

        fields = QgsFields()
        fields.append(QgsField('id', QVariant.Int, '', 10, 0))
        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            fields, QGis.WKBPoint,
            layer.dataProvider().crs())

        nPoints = 0
        nIterations = 0
        maxIterations = pointCount * 200
        featureCount = layer.featureCount()
        total = 100.0 / pointCount

        index = QgsSpatialIndex()
        points = dict()

        da = QgsDistanceArea()
        request = QgsFeatureRequest()

        random.seed()

        while nIterations < maxIterations and nPoints < pointCount:
            # pick random feature
            fid = random.randint(0, featureCount - 1)
            f = layer.getFeatures(request.setFilterFid(fid)).next()
            fGeom = QgsGeometry(f.geometry())

            if fGeom.isMultipart():
                lines = fGeom.asMultiPolyline()
                # pick random line
                lineId = random.randint(0, len(lines) - 1)
                vertices = lines[lineId]
            else:
                vertices = fGeom.asPolyline()

            # pick random segment
            if len(vertices) == 2:
                vid = 0
            else:
                vid = random.randint(0, len(vertices) - 2)
            startPoint = vertices[vid]
            endPoint = vertices[vid + 1]
            length = da.measureLine(startPoint, endPoint)
            dist = length * random.random()

            if dist > minDistance:
                d = dist / (length - dist)
                rx = (startPoint.x() + d * endPoint.x()) / (1 + d)
                ry = (startPoint.y() + d * endPoint.y()) / (1 + d)

                # generate random point
                pnt = QgsPoint(rx, ry)
                geom = QgsGeometry.fromPoint(pnt)
                if vector.checkMinDistance(pnt, index, minDistance, points):
                    f = QgsFeature(nPoints)
                    f.initAttributes(1)
                    f.setFields(fields)
                    f.setAttribute('id', nPoints)
                    f.setGeometry(geom)
                    writer.addFeature(f)
                    index.insertFeature(f)
                    points[nPoints] = pnt
                    nPoints += 1
                    progress.setPercentage(int(nPoints * total))
            nIterations += 1

        if nPoints < pointCount:
            ProcessingLog.addToLog(
                ProcessingLog.LOG_INFO,
                self.tr('Can not generate requested number of random points. '
                        'Maximum number of attempts exceeded.'))

        del writer
Example #12
0
    def draw(self, rows, con, args, geomType, canvasItemList, mapCanvas):
        ''' draw the result '''
        resultPathsRubberBands = canvasItemList['paths']
        rubberBand = None
        cur_path_id = -1
        for row in rows:
            cur2 = con.cursor()
            args['result_path_id'] = row[0]
            args['result_source_id'] = row[1]
            args['result_target_id'] = row[2]
            args['result_cost'] = row[3]
            if args['result_path_id'] != cur_path_id:
                cur_path_id = args['result_path_id']
                if rubberBand:
                    resultPathsRubberBands.append(rubberBand)
                    rubberBand = None

                rubberBand = QgsRubberBand(mapCanvas,
                                           Utils.getRubberBandType(False))
                rubberBand.setColor(QColor(255, 0, 0, 128))
                rubberBand.setWidth(4)
            if args['result_cost'] != -1:
                query2 = """
                    SELECT ST_AsText( ST_MakeLine(
                        (SELECT the_geom FROM  %(edge_table)s_vertices_pgr WHERE id = %(result_source_id)d),
                        (SELECT the_geom FROM  %(edge_table)s_vertices_pgr WHERE id = %(result_target_id)d)
                        ))
                    """ % args
                ##Utils.logMessage(query2)
                cur2.execute(query2)
                row2 = cur2.fetchone()
                ##Utils.logMessage(str(row2[0]))
                assert row2, "Invalid result geometry. (path_id:%(result_path_id)d, saource_id:%(result_source_id)d, target_id:%(result_target_id)d)" % args

                geom = QgsGeometry().fromWkt(str(row2[0]))
                if geom.wkbType() == QgsWkbTypes.MultiLineString:
                    for line in geom.asMultiPolyline():
                        for pt in line:
                            rubberBand.addPoint(pt)
                elif geom.wkbType() == QgsWkbTypes.LineString:
                    for pt in geom.asPolyline():
                        rubberBand.addPoint(pt)

        if rubberBand:
            resultPathsRubberBands.append(rubberBand)
            rubberBand = None
        resultNodesTextAnnotations = canvasItemList['annotations']
        Utils.setStartPoint(geomType, args)
        Utils.setEndPoint(geomType, args)
        for row in rows:
            cur2 = con.cursor()
            args['result_seq'] = row[0]
            args['result_source_id'] = row[1]
            args['result_target_id'] = row[2]
            args['result_cost'] = row[3]
            query2 = """
                SELECT ST_AsText(%(transform_s)s%(startpoint)s%(transform_e)s) FROM %(edge_table)s
                    WHERE %(source)s = %(result_target_id)d
                UNION
                SELECT ST_AsText(%(transform_s)s%(endpoint)s%(transform_e)s) FROM %(edge_table)s
                    WHERE %(target)s = %(result_target_id)d
            """ % args
            cur2.execute(query2)
            row2 = cur2.fetchone()
            assert row2, "Invalid result geometry. (target_id:%(result_target_id)d)" % args

            geom = QgsGeometry().fromWkt(str(row2[0]))
            pt = geom.asPoint()
            textDocument = QTextDocument(
                "%(result_target_id)d:%(result_cost)f" % args)
            textAnnotation = QgsTextAnnotation()
            textAnnotation.setMapPosition(geom.asPoint())
            textAnnotation.setFrameSize(QSizeF(textDocument.idealWidth(), 20))
            textAnnotation.setFrameOffsetFromReferencePoint(QPointF(20, -40))
            textAnnotation.setDocument(textDocument)

            QgsMapCanvasAnnotationItem(textAnnotation, mapCanvas)
            resultNodesTextAnnotations.append(textAnnotation)
Example #13
0
    def drawCostPaths(self, rows, con, args, geomType, canvasItemList, mapCanvas):
        resultPathsRubberBands = canvasItemList['paths']
        rubberBand = None
        cur_path_id = -1
        for row in rows:
            cur2 = con.cursor()
            args['result_path_id'] = row[0]
            args['result_source_id'] = sql.Literal(row[1])
            args['result_target_id'] = sql.Literal(row[2])
            args['result_cost'] = row[3]
            if args['result_path_id'] != cur_path_id:
                cur_path_id = args['result_path_id']
                if rubberBand:
                    resultPathsRubberBands.append(rubberBand)
                    rubberBand = None

                rubberBand = QgsRubberBand(mapCanvas, Utils.getRubberBandType(False))
                rubberBand.setColor(QColor(255, 0, 0, 128))
                rubberBand.setWidth(4)
            if args['result_cost'] != -1:
                query2 = sql.SQL("""
                    SELECT ST_AsText( ST_MakeLine(
                        (SELECT {geometry_vt} FROM  {vertex_schema}.{vertex_table} WHERE id = {result_source_id}),
                        (SELECT {geometry_vt} FROM  {vertex_schema}.{vertex_table} WHERE id = {result_target_id})
                        ))
                    """).format(**args)
                # Utils.logMessage(query2)
                cur2.execute(query2)
                row2 = cur2.fetchone()
                # Utils.logMessage(str(row2[0]))

                geom = QgsGeometry().fromWkt(str(row2[0]))
                if geom.wkbType() == QgsWkbTypes.MultiLineString:
                    for line in geom.asMultiPolyline():
                        for pt in line:
                            rubberBand.addPoint(pt)
                elif geom.wkbType() == QgsWkbTypes.LineString:
                    for pt in geom.asPolyline():
                        rubberBand.addPoint(pt)

        # TODO label the edge instead of labeling the target points
        if rubberBand:
            resultPathsRubberBands.append(rubberBand)
            rubberBand = None
        resultNodesTextAnnotations = canvasItemList['annotations']
        for row in rows:
            cur2 = con.cursor()
            args['result_seq'] = row[0]
            args['result_source_id'] = sql.Literal(row[1])
            result_target_id = row[2]
            args['result_target_id'] = sql.Literal(result_target_id)
            result_cost = row[3]
            query2 = sql.SQL("""
                SELECT ST_AsText( ST_startPoint({geometry}) ) FROM {edge_schema}.{edge_table}
                    WHERE {source} = {result_target_id}
                UNION
                SELECT ST_AsText( ST_endPoint( {geometry} ) ) FROM {edge_schema}.{edge_table}
                    WHERE {target} = {result_target_id}
                """).format(**args)
            cur2.execute(query2)
            row2 = cur2.fetchone()

            geom = QgsGeometry().fromWkt(str(row2[0]))
            pt = geom.asPoint()
            textDocument = QTextDocument("{0!s}:{1}".format(result_target_id, result_cost))
            textAnnotation = QgsTextAnnotation()
            textAnnotation.setMapPosition(geom.asPoint())
            textAnnotation.setFrameSize(QSizeF(textDocument.idealWidth(), 20))
            textAnnotation.setFrameOffsetFromReferencePoint(QPointF(20, -40))
            textAnnotation.setDocument(textDocument)

            QgsMapCanvasAnnotationItem(textAnnotation, mapCanvas)
            resultNodesTextAnnotations.append(textAnnotation)
def split_line_at_points(
    polyline_input,
    point_features,
    point_feature_id_field="id",
    start_node_id=None,
    end_node_id=None,
):
    """Split line at points

    Args:
        polyline (QgsPolyline):
        point_features (iteratable object of QgsFeature or list of dictonaries with id and geometry ('geom'):
        point_feature_id_field (str): fieldname if the id field of the point_features
        start_node_id (str or int): node id of point at begin of polyline
        end_node_id (str or int): node id of point at end of polyline

    Returns:
         (list of dict): Splitted polyline into parts as dictonary with:
                geom: Polyline geometry
                start_node_id: id of node at starting point of line
                end_node_id: id of node at end point of line
                distance at line: is distance of original line at the begin of this line part

    """

    snap_points = []

    source_crs = QgsCoordinateReferenceSystem(4326)
    dest_crs = QgsCoordinateReferenceSystem(3857)

    transform = QgsCoordinateTransform(source_crs, dest_crs,
                                       QgsProject.instance())
    transform_back = QgsCoordinateTransform(dest_crs, source_crs,
                                            QgsProject.instance())

    polyline = QgsGeometry(polyline_input)
    polyline.transform(transform)

    for point in point_features:
        if type(point) == QgsFeature:
            point = {
                point_feature_id_field: point[point_feature_id_field],
                "geom": point.geometry(),
            }

        if hasattr(point["geom"], "asPoint"):
            geom = point["geom"].asPoint()
        else:
            geom = point["geom"]

        geom = QgsGeometry.fromPointXY(geom)
        geom.transform(transform)
        geom = geom.asPoint()

        closest_seg = polyline.closestSegmentWithContext(geom)
        # get nearest point (related to the point) on the line
        point_on_line = closest_seg[1]
        point_geom_on_line = QgsPoint(point_on_line[0], point_on_line[1])

        # get nr of vertex (at the end of the line where the closest point is
        # found
        end_vertex_nr = closest_seg[2]
        start_vertex_nr = end_vertex_nr - 1

        p1 = polyline.asPolyline()[start_vertex_nr]  # first vertex
        p2 = point_geom_on_line

        distance_on_subline = math.hypot(p2.x() - p1.x(), p2.y() - p1.y())

        snap_points.append((
            start_vertex_nr,
            distance_on_subline,
            point_geom_on_line,
            point[point_feature_id_field],
        ))

    # order on vertex nr and if same vertex nr on distance
    snap_points.sort(key=lambda x: x[1])
    snap_points.sort(key=lambda x: x[0])

    # create line parts
    line_parts = []
    line_points = []
    start_point_id = start_node_id
    total_line_distance = 0

    for i, vertex in enumerate(polyline.asPolyline()):
        line_points.append(QgsPoint(vertex[0], vertex[1]))

        # get points after this vertex
        split_points_on_segment = [p for p in snap_points if p[0] == i]
        for point in split_points_on_segment:
            # only add another point if point is not equal to last vertex
            # todo: throw error when at begin or end vertex of original line?
            # todo: what to do of multiple points on same location?
            line_points.append(point[2])
            geom = QgsGeometry.fromPolyline(line_points)

            # length, unit_type = d.convertMeasurement(
            #     d.computeDistance(line_points),
            #     Qgis.Meters, Qgis.Meters, False)  # Qgis.Degrees

            length = geom.length()

            # add line parts
            line_parts.append({
                "geom": geom.transform(transform_back),
                "start_point_id": start_point_id,
                "end_point_id": point[3],
                "distance_at_line": total_line_distance,
                "length": length,
            })
            # create starting point of new line
            line_points = [point[2]]
            start_point_id = point[3]
            total_line_distance += length

    # last part of the line
    geom = QgsGeometry.fromPolyline(line_points)
    length = geom.length()
    # length, something = d.convertMeasurement(
    #     d.computeDistance(line_points),
    #     Qgis.Meters, Qgis.Meters, False)

    line_parts.append({
        "geom": geom,
        "start_point_id": start_point_id,
        "end_point_id": end_node_id,
        "distance_at_line": total_line_distance,
        "length": length,
    })

    return line_parts
    def load_complex_gml(self, xml_uri, is_remote, attributes = {}, geometry_mapping = None, logger = None, swap_xy = False):
        """
        :param xml_uri: the XML URI
        :param is_remote: True if it has to be fetched by http
        :param attributes: { 'attr1' : ( '//xpath/expression', QVariant.Int ) }
        :param geometry_mapping: XPath expression to a gml geometry node
        :param swap_xy: True if X/Y coordinates must be swapped
        :returns: the created layer
        """
        if is_remote:
            xml = remote_open_from_qgis(xml_uri)
        else:
            # Open the file in binary mode, this means returning bytes
            # instead of a string whose encoding would have to be interpreted
            # it is up to the XML parser to determine which encoding it is
            xml = open(xml_uri, 'rb')
        src = ComplexFeatureSource(xml, attributes, geometry_mapping, logger)

        attr_list = [ (k, v[1]) for k, v in attributes.items() ]
        
        # first feature
        id, fid, g, xml, attrs = next(src.getFeatures())
        qgsgeom = None
        if g is None:
            layer = self._create_layer('none', None, attr_list, src.title)
        else:
            wkb, srid = g
            qgsgeom = QgsGeometry()
            qgsgeom.fromWkb(wkb)
            if qgsgeom and qgsgeom.type() == QgsWkbTypes.PointGeometry:
                layer = self._create_layer('point', srid, attr_list, src.title + " (points)")
            elif qgsgeom and qgsgeom.type() == QgsWkbTypes.LineGeometry:
                layer = self._create_layer('linestring', srid, attr_list, src.title + " (lines)")
            elif qgsgeom and qgsgeom.type() == QgsWkbTypes.PolygonGeometry:
                layer = self._create_layer('polygon', srid, attr_list, src.title + " (polygons)")

        # add metadata
        self._add_properties_to_layer(layer, xml_uri, is_remote, attributes, geometry_mapping)

        # collect features
        features = []
        for id, fid, g, xml, attrs in src.getFeatures():
            qgsgeom = None
            wkb, srid = g
            qgsgeom = QgsGeometry()
            qgsgeom.fromWkb(wkb)
            if qgsgeom and qgsgeom.type() == QgsWkbTypes.PointGeometry:
                if swap_xy:
                    p = qgsgeom.asPoint()
                    qgsgeom = QgsGeometry.fromPoint(QgsPointXY(p[1], p[0]))
            elif qgsgeom and qgsgeom.type() == QgsWkbTypes.LineGeometry:
                if swap_xy:
                    pl = qgsgeom.asPolyline()
                    qgsgeom = QgsGeometry.fromPolyline([QgsPointXY(p[1],p[0]) for p in pl])
            elif qgsgeom and qgsgeom.type() == QgsWkbTypes.PolygonGeometry:
                if swap_xy:
                    pl = qgsgeom.asPolygon()
                    qgsgeom = QgsGeometry.fromPolygon([[QgsPointXY(p[1],p[0]) for p in r] for r in pl])

            f = QgsFeature(layer.dataProvider().fields(), id)
            if qgsgeom:
                f.setGeometry(qgsgeom)
            f.setAttribute("id", str(id))
            f.setAttribute("fid", fid)
            f.setAttribute("_xml_", ET.tostring(xml).decode('utf8'))
            for k, v in attrs.items():
                r = f.setAttribute(k, v)
            features.append(f)

        # write features
        if len(features) > 0:
            layer.dataProvider().addFeatures(features)

        return layer
    def processAlgorithm(self, progress):
        layer = dataobjects.getObjectFromUri(
            self.getParameterValue(self.VECTOR))
        pointCount = float(self.getParameterValue(self.POINT_NUMBER))
        minDistance = float(self.getParameterValue(self.MIN_DISTANCE))

        fields = QgsFields()
        fields.append(QgsField('id', QVariant.Int, '', 10, 0))
        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            fields, QGis.WKBPoint, layer.crs())

        nPoints = 0
        nIterations = 0
        maxIterations = pointCount * 200
        featureCount = layer.featureCount()
        total = 100.0 / pointCount if pointCount > 0 else 1

        index = QgsSpatialIndex()
        points = dict()

        da = QgsDistanceArea()
        request = QgsFeatureRequest()

        random.seed()

        while nIterations < maxIterations and nPoints < pointCount:
            # pick random feature
            fid = random.randint(0, featureCount - 1)
            f = layer.getFeatures(request.setFilterFid(fid)).next()
            fGeom = QgsGeometry(f.geometry())

            if fGeom.isMultipart():
                lines = fGeom.asMultiPolyline()
                # pick random line
                lineId = random.randint(0, len(lines) - 1)
                vertices = lines[lineId]
            else:
                vertices = fGeom.asPolyline()

            # pick random segment
            if len(vertices) == 2:
                vid = 0
            else:
                vid = random.randint(0, len(vertices) - 2)
            startPoint = vertices[vid]
            endPoint = vertices[vid + 1]
            length = da.measureLine(startPoint, endPoint)
            dist = length * random.random()

            if dist > minDistance:
                d = dist / (length - dist)
                rx = (startPoint.x() + d * endPoint.x()) / (1 + d)
                ry = (startPoint.y() + d * endPoint.y()) / (1 + d)

                # generate random point
                pnt = QgsPoint(rx, ry)
                geom = QgsGeometry.fromPoint(pnt)
                if vector.checkMinDistance(pnt, index, minDistance, points):
                    f = QgsFeature(nPoints)
                    f.initAttributes(1)
                    f.setFields(fields)
                    f.setAttribute('id', nPoints)
                    f.setGeometry(geom)
                    writer.addFeature(f)
                    index.insertFeature(f)
                    points[nPoints] = pnt
                    nPoints += 1
                    progress.setPercentage(int(nPoints * total))
            nIterations += 1

        if nPoints < pointCount:
            ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
                                   self.tr('Can not generate requested number of random points. '
                                           'Maximum number of attempts exceeded.'))

        del writer
Example #17
0
    def draw(self, rows, con, args, geomType, canvasItemList, mapCanvas):
        ''' draw the result '''
        resultPathsRubberBands = canvasItemList['paths']
        rubberBand = None
        cur_path_id = -1

        i = 0
        count = len(rows)
        ids = args['ids'].split(',')
        args['last_id'] = ids[len(ids) - 1]
        pcts = args['pcts'].split(',')
        pct_idx = 0
        for row in rows:
            cur2 = con.cursor()
            args['result_path_id'] = row[1]
            args['result_node_id'] = row[2]
            args['result_edge_id'] = row[3]
            args['result_cost'] = row[4]

            if args['result_path_id'] != cur_path_id:
                cur_path_id = args['result_path_id']
                if rubberBand:
                    resultPathsRubberBands.append(rubberBand)
                    rubberBand = None

                rubberBand = QgsRubberBand(mapCanvas,
                                           Utils.getRubberBandType(False))
                rubberBand.setColor(QColor(255, 0, 0, 128))
                rubberBand.setWidth(4)

            query2 = ""
            if i < (count - 1):
                args['result_next_path_id'] = rows[i + 1][1]
                args['result_next_node_id'] = rows[i + 1][2]
                if args['result_next_path_id'] != args['result_path_id']:
                    pct_idx += 1
            elif i == (count - 1):
                pct_idx = len(pcts) - 1
            args['current_pct'] = pcts[pct_idx]

            if i == 0 and args['result_node_id'] == -1:
                query2 = """
                    SELECT ST_AsText(%(transform_s)sST_Line_Substring(%(geometry)s, %(current_pct)s, 1.0)%(transform_e)s) FROM %(edge_table)s
                        WHERE %(target)s = %(result_next_node_id)s AND %(id)s = %(result_edge_id)s
                    UNION
                    SELECT ST_AsText(%(transform_s)sST_Line_Substring(ST_Reverse(%(geometry)s), 1.0 - %(current_pct)s, 1.0)%(transform_e)s) FROM %(edge_table)s
                        WHERE %(source)s = %(result_next_node_id)s AND %(id)s = %(result_edge_id)s;
                """ % args
            elif i < (count - 1) and (
                    args['result_path_id'] != args['result_next_path_id']
            ) and (args['result_node_id'] == args['result_next_node_id']):
                # round trip case
                query2 = """
                    SELECT ST_AsText(ST_LineMerge(ST_Collect(ARRAY[
                    (
                        SELECT ST_AsText(%(transform_s)sST_Line_Substring(%(geometry)s, 0.0, %(current_pct)s)%(transform_e)s) FROM %(edge_table)s
                            WHERE %(source)s = %(result_node_id)s AND %(id)s = %(result_edge_id)s
                        UNION
                        SELECT ST_AsText(%(transform_s)sST_Line_Substring(ST_Reverse(%(geometry)s), 0.0, 1.0 - %(current_pct)s)%(transform_e)s) FROM %(edge_table)s
                            WHERE %(target)s = %(result_node_id)s AND %(id)s = %(result_edge_id)s
                    ),
                    (
                        SELECT ST_AsText(%(transform_s)sST_Reverse(ST_Line_Substring(%(geometry)s, 0.0, %(current_pct)s))%(transform_e)s) FROM %(edge_table)s
                            WHERE %(source)s = %(result_node_id)s AND %(id)s = %(result_edge_id)s
                        UNION
                        SELECT ST_AsText(%(transform_s)sST_Reverse(ST_Line_Substring(ST_Reverse(%(geometry)s), 0.0, 1.0 - %(current_pct)s))%(transform_e)s) FROM %(edge_table)s
                            WHERE %(target)s = %(result_node_id)s AND %(id)s = %(result_edge_id)s
                    )])));
                """ % args
            elif i == (count - 1) and (
                (args['result_edge_id'] == -1) or
                (str(args['result_edge_id']) == args['last_id'])):
                if args['result_edge_id'] != -1:
                    query2 = """
                        SELECT ST_AsText(%(transform_s)sST_Line_Substring(%(geometry)s, 0.0, %(current_pct)s)%(transform_e)s) FROM %(edge_table)s
                            WHERE %(source)s = %(result_node_id)s AND %(id)s = %(result_edge_id)s
                        UNION
                        SELECT ST_AsText(%(transform_s)sST_Line_Substring(ST_Reverse(%(geometry)s), 0.0, 1.0 - %(current_pct)s)%(transform_e)s) FROM %(edge_table)s
                            WHERE %(target)s = %(result_node_id)s AND %(id)s = %(result_edge_id)s;
                    """ % args
                else:
                    break
            else:
                query2 = """
                    SELECT ST_AsText(%(transform_s)s%(geometry)s%(transform_e)s) FROM %(edge_table)s
                        WHERE %(source)s = %(result_node_id)d AND %(id)s = %(result_edge_id)d
                    UNION
                    SELECT ST_AsText(%(transform_s)sST_Reverse(%(geometry)s)%(transform_e)s) FROM %(edge_table)s
                        WHERE %(target)s = %(result_node_id)d AND %(id)s = %(result_edge_id)d;
                """ % args

            ##Utils.logMessage(query2)
            cur2.execute(query2)
            row2 = cur2.fetchone()
            ##Utils.logMessage(str(row2[0]))
            assert row2, "Invalid result geometry. (node_id:%(result_node_id)d, edge_id:%(result_edge_id)d)" % args

            geom = QgsGeometry().fromWkt(str(row2[0]))
            if geom.wkbType() == QgsWkbTypes.MultiLineString:
                for line in geom.asMultiPolyline():
                    for pt in line:
                        rubberBand.addPoint(pt)
            elif geom.wkbType() == QgsWkbTypes.LineString:
                for pt in geom.asPolyline():
                    rubberBand.addPoint(pt)

            i = i + 1

        if rubberBand:
            resultPathsRubberBands.append(rubberBand)
            rubberBand = None
Example #18
0
    def __mergeFeaturesSimple(self, provider, origFeats):

        newFeats = []
        QgsMessageLog.logMessage(
            '---- Merge Simple: {0} features'.format(len(origFeats)), 'VoGis')

        if len(origFeats) < 1:
            return []

        prevToPnt = None
        #newGeom = QgsGeometry()
        newGeom = QgsGeometry().fromPolyline([])
        attrMap = None
        #newGeom = QgsGeometry.fromPolyline([QgsPoint(1, 1), QgsPoint(2, 2)])
        #QgsMessageLog.logMessage('newGeom WKB Type {0}'.format(newGeom.wkbType() == QGis.WKBLineString), 'VoGis')
        for feat in origFeats:
            #QgsMessageLog.logMessage('{0}:{1}'.format('ORIG FEAT AttributeMap', self.__printAttribs(feat.attributeMap())), 'VoGis')
            #self.__printAttribs(feat.attributeMap())
            currentGeom = feat.geometry()
            currentPnts = currentGeom.asPolyline()
            if prevToPnt is None:
                #QgsMessageLog.logMessage('combining FIRST {0}'.format(currentGeom.asPolyline()), 'VoGis')
                newGeom = newGeom.combine(currentGeom)
                if QGis.QGIS_VERSION_INT < 10900:
                    attrMap = feat.attributeMap()
                else:
                    attrMap = feat.attributes()
            else:
                if currentPnts[0] == prevToPnt:
                    #QgsMessageLog.logMessage('combining {0}'.format(currentGeom.asPolyline()), 'VoGis')
                    newGeom = newGeom.combine(currentGeom)
                    if QGis.QGIS_VERSION_INT < 10900:
                        attrMap = feat.attributeMap()
                    else:
                        attrMap = feat.attributes()
                else:
                    #QgsMessageLog.logMessage('creating {0}'.format(newGeom.asPolyline()), 'VoGis')
                    featNew = self.createQgLineFeature(newGeom.asPolyline())
                    featNew = self.__transferAttributes(
                        provider, attrMap, featNew)
                    newFeats.append(featNew)
                    #feat = QgsFeature()
                    #newGeom = QgsGeometry()
                    newGeom = QgsGeometry().fromPolyline(currentPnts)
                    if QGis.QGIS_VERSION_INT < 10900:
                        attrMap = feat.attributeMap()
                    else:
                        attrMap = feat.attributes()
                #newGeom = QgsGeometry.fromPolyline([QgsPoint(1, 1), QgsPoint(2, 2)])

            prevToPnt = currentPnts[len(currentPnts) - 1]

        featNew = self.createQgLineFeature(newGeom.asPolyline())
        self.__transferAttributes(provider, attrMap, featNew)
        #newFeats.append(self.createQgLineFeature(newGeom.asPolyline()))
        newFeats.append(featNew)

        tmpFeats = []
        for feat in newFeats:
            if feat.geometry().isGeosEmpty() is True:
                QgsMessageLog.logMessage('dropping empty geometry', 'VoGis')
                continue
            else:
                tmpFeats.append(feat)
        newFeats = tmpFeats

        QgsMessageLog.logMessage(
            '---- {0} features after Merge Simple'.format(len(newFeats)),
            'VoGis')

        #for idx, f in enumerate(newFeats):
        #    QgsMessageLog.logMessage('--------feature {0}---------'.format(idx), 'VoGis')
        #    geo = f.geometry()
        #    pnts = geo.asPolyline()
        #    for i, v in enumerate(pnts):
        #        QgsMessageLog.logMessage('   pnt {0}: {1}/{2}'.format(i, v.x(), v.y()), 'VoGis')

        return newFeats
Example #19
0
    def __mergeFeaturesSimple(self, provider, origFeats):

        newFeats = []
        QgsMessageLog.logMessage('---- Merge Simple: {0} features'.format(len(origFeats)), 'VoGis')

        if len(origFeats) < 1:
            return []

        prevToPnt = None
        #newGeom = QgsGeometry()
        newGeom = QgsGeometry().fromPolyline([])
        attrMap = None
        #newGeom = QgsGeometry.fromPolyline([QgsPoint(1, 1), QgsPoint(2, 2)])
        #QgsMessageLog.logMessage('newGeom WKB Type {0}'.format(newGeom.wkbType() == QGis.WKBLineString), 'VoGis')
        for feat in origFeats:
            #QgsMessageLog.logMessage('{0}:{1}'.format('ORIG FEAT AttributeMap', self.__printAttribs(feat.attributeMap())), 'VoGis')
            #self.__printAttribs(feat.attributeMap())
            currentGeom = feat.geometry()
            currentPnts = currentGeom.asPolyline()
            if prevToPnt is None:
                #QgsMessageLog.logMessage('combining FIRST {0}'.format(currentGeom.asPolyline()), 'VoGis')
                newGeom = newGeom.combine(currentGeom)
                if QGis.QGIS_VERSION_INT < 10900:
                    attrMap = feat.attributeMap()
                else:
                    attrMap = feat.attributes()
            else:
                if currentPnts[0] == prevToPnt:
                    #QgsMessageLog.logMessage('combining {0}'.format(currentGeom.asPolyline()), 'VoGis')
                    newGeom = newGeom.combine(currentGeom)
                    if QGis.QGIS_VERSION_INT < 10900:
                        attrMap = feat.attributeMap()
                    else:
                        attrMap = feat.attributes();
                else:
                    #QgsMessageLog.logMessage('creating {0}'.format(newGeom.asPolyline()), 'VoGis')
                    featNew = self.createQgLineFeature(newGeom.asPolyline())
                    featNew = self.__transferAttributes(provider, attrMap, featNew)
                    newFeats.append(featNew)
                    #feat = QgsFeature()
                    #newGeom = QgsGeometry()
                    newGeom = QgsGeometry().fromPolyline(currentPnts)
                    if QGis.QGIS_VERSION_INT < 10900:
                        attrMap = feat.attributeMap()
                    else:
                        attrMap = feat.attributes()
                #newGeom = QgsGeometry.fromPolyline([QgsPoint(1, 1), QgsPoint(2, 2)])

            prevToPnt = currentPnts[len(currentPnts) - 1]

        featNew = self.createQgLineFeature(newGeom.asPolyline())
        self.__transferAttributes(provider, attrMap, featNew)
        #newFeats.append(self.createQgLineFeature(newGeom.asPolyline()))
        newFeats.append(featNew)

        tmpFeats = []
        for feat in newFeats:
            if feat.geometry().isGeosEmpty() is True:
                QgsMessageLog.logMessage('dropping empty geometry', 'VoGis')
                continue
            else:
                tmpFeats.append(feat)
        newFeats = tmpFeats

        QgsMessageLog.logMessage('---- {0} features after Merge Simple'.format(len(newFeats)), 'VoGis')

        #for idx, f in enumerate(newFeats):
        #    QgsMessageLog.logMessage('--------feature {0}---------'.format(idx), 'VoGis')
        #    geo = f.geometry()
        #    pnts = geo.asPolyline()
        #    for i, v in enumerate(pnts):
        #        QgsMessageLog.logMessage('   pnt {0}: {1}/{2}'.format(i, v.x(), v.y()), 'VoGis')

        return newFeats
Example #20
0
    def __mergeFeaturesSimple(self, provider, origFeats):
        newFeats = []
        QgsMessageLog.logMessage("---- Merge Simple: {0} features".format(len(origFeats)), "VoGis", Qgis.Info)

        if len(origFeats) < 1:
            return []

        prevToPnt = None
        #newGeom = QgsGeometry()
        newGeom = QgsGeometry().fromPolylineXY([])
        attrMap = None
        #newGeom = QgsGeometry.fromPolyline([QgsPoint(1, 1), QgsPoint(2, 2)])
        #QgsMessageLog.logMessage("newGeom WKB Type {0}".format(newGeom.wkbType() == QGis.WKBLineString), "VoGis", Qgis.Info)
        for feat in origFeats:
            #QgsMessageLog.logMessage("{0}:{1}".format("ORIG FEAT AttributeMap", self.__printAttribs(feat.attributeMap())), "VoGis", Qgis.Info)
            #self.__printAttribs(feat.attributeMap())
            currentGeom = feat.geometry()
            currentPnts = currentGeom.asPolyline()
            if prevToPnt is None:
                #QgsMessageLog.logMessage("combining FIRST {0}".format(currentGeom.asPolyline()), "VoGis", Qgis.Info)
                newGeom = newGeom.combine(currentGeom)
                attrMap = feat.attributes()
            else:
                if currentPnts[0] == prevToPnt:
                    #QgsMessageLog.logMessage("combining {0}".format(currentGeom.asPolyline()), "VoGis", Qgis.Info)
                    newGeom = newGeom.combine(currentGeom)
                    attrMap = feat.attributes();
                else:
                    #QgsMessageLog.logMessage("creating {0}".format(newGeom.asPolyline()), "VoGis", Qgis.Info)
                    featNew = self.createQgLineFeature(newGeom.asPolyline())
                    featNew = self.__transferAttributes(provider, attrMap, featNew)
                    newFeats.append(featNew)
                    #feat = QgsFeature()
                    #newGeom = QgsGeometry()
                    newGeom = QgsGeometry().fromPolylineXY(currentPnts)
                    attrMap = feat.attributes()
                #newGeom = QgsGeometry.fromPolyline([QgsPoint(1, 1), QgsPoint(2, 2)])

            prevToPnt = currentPnts[len(currentPnts) - 1]

        featNew = self.createQgLineFeature(newGeom.asPolyline())
        self.__transferAttributes(provider, attrMap, featNew)
        #newFeats.append(self.createQgLineFeature(newGeom.asPolyline()))
        newFeats.append(featNew)

        tmpFeats = []
        for feat in newFeats:
            if feat.geometry().isEmpty() is True:
                QgsMessageLog.logMessage("dropping empty geometry", "VoGis", Qgis.Warning)
                continue
            else:
                tmpFeats.append(feat)
        newFeats = tmpFeats

        QgsMessageLog.logMessage("---- {0} features after Merge Simple".format(len(newFeats)), "VoGis", Qgis.Info)

        #for idx, f in enumerate(newFeats):
        #    QgsMessageLog.logMessage("--------feature {0}---------".format(idx), "VoGis", Qgis.Info)
        #    geo = f.geometry()
        #    pnts = geo.asPolyline()
        #    for i, v in enumerate(pnts):
        #        QgsMessageLog.logMessage("   pnt {0}: {1}/{2}".format(i, v.x(), v.y()), "VoGis", Qgis.Info)

        return newFeats