Ejemplo n.º 1
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)
Ejemplo n.º 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
Ejemplo n.º 4
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
Ejemplo n.º 5
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
Ejemplo n.º 6
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
Ejemplo n.º 7
0
def qGeometry(feature):
    try:
        geom = QgsGeometry(feature.geometry())
        fid = feature.id()
        if not geom.isMultipart():
            if not geom.convertToMultiType():
                raise Exception("unable to extract feature geometry (invalid geometry type)")
        if geom.type() == 0:
            return qPoints(geom.asMultiPoint())
        elif geom.type() == 1:
            return qLines(geom.asMultiPolyline(), fid)
        elif geom.type() == 2:
            return qPolygons(geom.asMultiPolygon(), fid)
        else:
            raise Exception("unable to extract feature geometry (unknown geometry type)")
    except Exception, e:
        raise Exception("unable to extract feature geometry: %s" % unicode(e))
    def getSchnittpunkteAusLinien(self, overlapFeats, featureCrs, laengsProfil,
                                  feedback):
        schnittpunktFeatures = []
        ioFeat = 0
        countPoints = 0
        try:
            for feat in overlapFeats:
                #Feature bekommt neues Attribut Station
                if ioFeat == 0:
                    fields = feat.fields()
                    fields.append(QgsField("station", QVariant.Double))

                schnittpunktFeaturesOfThisLine = []
                #check if Multipolygon
                iMulti = 0
                tempGeom = QgsGeometry()
                tempGeom.fromWkb(feat.geometry().asWkb())
                #transform geom to Project.crs() if crs a different
                if not featureCrs.authid() == QgsProject.instance().crs(
                ).authid():
                    trafo = QgsCoordinateTransform(featureCrs,
                                                   QgsProject.instance().crs(),
                                                   QgsProject.instance())
                    #transform Geom to Project.crs()
                    tempGeom.transform(trafo,
                                       QgsCoordinateTransform.ForwardTransform,
                                       False)

                if tempGeom.isMultipart:
                    multiGeom = tempGeom.asMultiPolyline()
                    #for singleLine in tempGeom.parts(): #ab QGIS 3.6
                    for singleLineVertices in multiGeom:  ############## Achtung normalerweise wird diese Schleife zum Auflösen des Multiparts benoetigt
                        points = []
                        for pxy in singleLineVertices:
                            points.append(QgsPoint(pxy.x(), pxy.y()))
                        singleLine = QgsGeometry().fromPolyline(points)

                        #feedback.pushInfo(str(iMulti) + " MultiGeom: " + str(type(feat.geometry())))
                        #feedback.pushInfo( str( singleLine.asWkt() ) +"\n"+ str(singleLineVertices))

                        schnittpunktFeaturesOfThisLinePart = self.makeIntersectionFeatures(
                            feat, singleLine, laengsProfil, fields, feedback)
                        #feedback.pushInfo("Multi-Schnittpunkte: " + str( schnittpunktFeaturesOfThisLinePart ) )
                        for item in schnittpunktFeaturesOfThisLinePart:
                            schnittpunktFeaturesOfThisLine.append(item)
                        iMulti = iMulti + 1

                else:  # single Geometry
                    #feedback.pushInfo("singleGeom: " + str(type(feat.geometry())))
                    schnittpunktFeaturesOfThisLine = self.makeIntersectionFeatures(
                        feat, tempGeom, laengsProfil, fields, feedback)

                #add to list
                for schnittFeat in schnittpunktFeaturesOfThisLine:  #Intersection Feature in project.crs()
                    schnittpunktFeatures.append(schnittFeat)
                    #feedback.pushInfo(str(schnittFeat.attributes()))
                ioFeat = ioFeat + 1
                #count Intersections
                countPoints = countPoints + len(schnittpunktFeaturesOfThisLine)

        except:
            msg = self.tr(
                "Error: Creating Intesections Geometry {0} Feature {1}"
            ).format(str(type(feat.geometry())), str(feat.attributes()))
            feedback.reportError(msg)
            raise QgsProcessingException(msg)
        msgInfo = self.tr("Intersected Lines: {0} Intersections: {1}").format(
            ioFeat, countPoints)
        feedback.pushInfo(msgInfo)
        return schnittpunktFeatures
Ejemplo n.º 9
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
Ejemplo n.º 10
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)
Ejemplo n.º 11
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 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
Ejemplo n.º 13
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)
Ejemplo n.º 14
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