def construct_sql_array_polygons(layer):
    """
    Construct the sql array containing the input vector layer's features geometry.
    """
    # Initialization of the sql array containing the study area's features geometry
    array_polygons = "array["
    # Retrieve the CRS of the layer
    crs = layer.sourceCrs().authid()
    if crs.split(':')[0] != 'EPSG':
        raise QgsProcessingException(
            """Le SCR (système de coordonnées de référence) de votre couche zone d'étude n'est pas de type 'EPSG'.
            Veuillez choisir un SCR adéquat.
            NB : 'EPSG:2154' pour Lambert 93 !""")
    else:
        crs = crs.split(':')[1]
    # For each entity in the study area...
    for feature in layer.getFeatures():
        # Retrieve the geometry
        area = feature.geometry()  # QgsGeometry object
        # Retrieve the geometry type (single or multiple)
        geomSingleType = QgsWkbTypes.isSingleType(area.wkbType())
        # Increment the sql array
        if geomSingleType:
            array_polygons += "ST_transform(ST_PolygonFromText('{}', {}), 2154), ".format(
                area.asWkt(), crs)
        else:
            array_polygons += "ST_transform(ST_MPolyFromText('{}', {}), 2154), ".format(
                area.asWkt(), crs)
    # Remove the last "," in the sql array which is useless, and end the array
    array_polygons = array_polygons[:len(array_polygons) - 2] + "]"
    return array_polygons
Exemplo n.º 2
0
    def startConvert(self, layer: QgsMapLayer):

        layerName = layer.name()
        nodeCoorDict = OrderedDict()
        graph = nx.Graph()
        if layerName:
            features = layer.getFeatures()
            count = 0
            for feature in features:
                if count > 10:
                    break
                geom = feature.geometry()
                geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType())
                if geom.type() == QgsWkbTypes.PolygonGeometry:
                    if geomSingleType:
                        polygon = geom.asPolygon()
                    else:
                        multiPolygon = geom.asMultiPolygon()
                        for polygon in multiPolygon:
                            nodeCoorDict = self.parsePolygon2Network(
                                polygon, nodeCoorDict, graph)
                count = count + 1
        '''
        plt.subplot(121)
        nx.draw(graph, with_labels=True, font_weight='bold')
        plt.show()
        '''
        return nodeCoorDict
Exemplo n.º 3
0
    def startConvert(self,layer:QgsMapLayer):

        layerName = layer.name()
        nodeCoorDict = OrderedDict()
        graph = nx.Graph()

        if layerName:
            features_forCounts = layer.getFeatures()  # type:QgsFeatureIterator
            # 记录当前处理的polygon id编号
            plyId = 0
            count = 0
            feaNums = sum(1 for _ in features_forCounts)  #此时已经迭代过了

            features = layer.getFeatures()  # type:QgsFeatureIterator
            pbar = self.dlg.progressBar  # type:QProgressBar
            pbar.setRange(0, feaNums)
            print(feaNums)
            for feature in features:
                #if count >= 10:
                #    break
                geom = feature.geometry()
                geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType())
                if geom.type() == QgsWkbTypes.PolygonGeometry:
                    if geomSingleType:
                        polygon = geom.asPolygon()
                        nodeCoorDict, graph = self.parsePolygon2Network(polygon, nodeCoorDict, graph, plyId=plyId)
                        plyId = plyId + 1
                    else:
                        multiPolygon = geom.asMultiPolygon()
                        for polygon in multiPolygon:
                            nodeCoorDict,graph = self.parsePolygon2Network(polygon,nodeCoorDict,graph,plyId=plyId)
                            plyId = plyId + 1
                pbar.setValue(count)
                count = count + 1
                #print("complete!")
        #plt.subplot(121)
        #print(nodeCoorDict)
        '''
        # 每个节点坐标,绘制带坐标的图
        pos = list(nodeCoorDict.values())
        #nx.draw(graph,pos, with_labels=True)
        nx.draw(graph, pos,node_size=20)
        nx.fruchterman_reingold_layout(graph)
        plt.show()
        '''
        print('all complete')
        pbar.setValue(feaNums)
        return nodeCoorDict,graph,True
Exemplo n.º 4
0
    def addLinkReverse(self):
        offset = 5
        #Loop over the links """
        try:
            layer = QgsProject.instance().mapLayersByName("Liens")[0]
        except IndexError:
            print("No link layer...")

        with edit(layer):
            features = layer.selectedFeatures()
            for feature in features:
                print("Feature ID: ", feature.id())
                geom = feature.geometry()
                geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType())
                if geom.type()==QgsWkbTypes.LineGeometry:
                    if geomSingleType:
                        print("Dev Notes : maybe useless here but if you see it in the console, this case has to be handled")

                    else:
                        x = geom.asMultiPolyline()
                        newPoints = []
                        # first point
                        X = x[0][0][0] + offset*(x[0][0][1]-x[0][1][1])/((x[0][1][0]-x[0][0][0])**2 + (x[0][1][1]-x[0][0][1])**2)**0.5
                        Y = x[0][0][1] + offset*(x[0][1][0]-x[0][0][0])/((x[0][1][0]-x[0][0][0])**2 + (x[0][1][1]-x[0][0][1])**2)**0.5
                        newPoints.append(QgsPointXY(X,Y))
                        #last point
                        N = len(x[0]) - 1
                        for i in range(1,N):
                            x1 = x[0][i][0] + offset*(x[0][i-1][1]-x[0][i][1])/((x[0][i][0]-x[0][i-1][0])**2 + (x[0][i][1]-x[0][i-1][1])**2)**0.5
                            y1 = x[0][i][1] + offset*(x[0][i][0]-x[0][i-1][0])/((x[0][i][0]-x[0][i-1][0])**2 + (x[0][i][1]-x[0][i-1][1])**2)**0.5
                            x2 = x[0][i][0] + offset*(x[0][i][1]-x[0][i+1][1])/((x[0][i+1][0]-x[0][i][0])**2 + (x[0][i+1][1]-x[0][i][1])**2)**0.5
                            y2 = x[0][i][1] + offset*(x[0][i+1][0]-x[0][i][0])/((x[0][i+1][0]-x[0][i][0])**2 + (x[0][i+1][1]-x[0][i][1])**2)**0.5
                            X = (x1 + x2)/2
                            Y = (y1 + y2)/2
                            # TODO !! Faire quand Etienne sera parti
                            newPoints.append(QgsPointXY(X,Y))
                        #last point
                        X = x[0][N][0] + offset*(x[0][N-1][1]-x[0][N][1])/((x[0][N][0]-x[0][N-1][0])**2 + (x[0][N][1]-x[0][N-1][1])**2)**0.5
                        Y = x[0][N][1] + offset*(x[0][N][0]-x[0][N-1][0])/((x[0][N][0]-x[0][N-1][0])**2 + (x[0][N][1]-x[0][N-1][1])**2)**0.5
                        newPoints.append(QgsPointXY(X,Y))
                        # reverse
                        newPoints.reverse()
                        newgeom = QgsGeometry.fromMultiPolylineXY([newPoints])
                        feat = QgsFeature(layer.fields())
                        feat.setGeometry(newgeom)
                        (res, outFeats) = layer.dataProvider().addFeatures([feat])
Exemplo n.º 5
0
def build_graph(features):
    d = QgsDistanceArea()
    graph = nx.Graph()
    for feature in features:
        geom = feature.geometry()
        geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType())
        if geomSingleType:
            nodes = geom.asPolyline()
            for start, end in postman.pairs(nodes):
                graph.add_edge((start[0], start[1]), (end[0], end[1]),
                               weight=d.measureLine(start, end))
        else:
            lines = geom.asMultiPolyline()
            for line in lines:
                for start, end in postman.pairs(line):
                    graph.add_edge((start[0], start[1]), (end[0], end[1]),
                                   weight=d.measureLine(start, end))

    return graph
Exemplo n.º 6
0
    def reverseSelectedLinks(self):
        try:
            layer = QgsProject.instance().mapLayersByName("Liens")[0]
        except IndexError:
            print("No link layer...")
            return

        with edit(layer):
            features = layer.selectedFeatures()
            for feature in features:
                geom = feature.geometry()
                geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType())
                if geom.type()==QgsWkbTypes.LineGeometry:
                    if geomSingleType:
                        #TODO
                        print("Dev Notes : maybe useless here but if you see it in the console, this case has to be handled")
                    else:
                        x = geom.asMultiPolyline()
                        x[0].reverse()
                        newgeom = QgsGeometry.fromMultiPolylineXY(x)
                        layer.changeGeometry(feature.id(),newgeom)
Exemplo n.º 7
0
    def GeometryControl(self, geom):
        # Check Geometry Type and Return Biggest Polygon
        areas = []
        geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType())

        if geomSingleType:
            return geom

        elif geom.isEmpty():
            print("Geometry Error !")
            return geom
        else:
            for i in geom.asGeometryCollection():
                if i.type() == QgsWkbTypes.PointGeometry:
                    print("Point geometry removed")
                elif i.type() == QgsWkbTypes.LineGeometry:
                    print("Line geometry removed")
                elif i.type() == QgsWkbTypes.PolygonGeometry:
                    areas.append([i.area(), i])
                elif i.type() == QgsWkbTypes.UnknownGeometry:
                    print("Unknown geometry removed")
            print("Biggest area selected")
            return (max(areas)[1])
Exemplo n.º 8
0
    def processAlgorithm(self, parameters, context, feedback):

        try:
            import os, math, string, random
            import processing as st
            import networkx as nx
            import numpy as np
            import plotly.graph_objs as go
            import chart_studio.plotly as py
            import pandas as pd
            from math import ceil

        except Exception as e:
            feedback.reportError(QCoreApplication.translate('Error','%s'%(e)))
            feedback.reportError(QCoreApplication.translate('Error',' '))
            feedback.reportError(QCoreApplication.translate('Error','Error loading modules - please install the necessary dependencies'))
            return {}

        LG = self.parameterAsSource(parameters, self.LG, context)
        Network = self.parameterAsSource(parameters, self.Network, context)
        Norm = parameters[self.Norm]
        Combine = parameters[self.Combine]

        field_check = LG.fields().indexFromName('Sample_No_')

        if field_check == -1:
            editLayer = self.parameterAsLayer(parameters, self.LG, context)
            pr = editLayer.dataProvider()
            pr.addAttributes([QgsField('Sample_No_', QVariant.Int)])
            editLayer.updateFields()
            f_len = len(editLayer.fields()) - 1
            editLayer.startEditing()
            for feature in editLayer.getFeatures():
                pr.changeAttributeValues({feature.id():{f_len:feature.id()}})
            editLayer.commitChanges()

        wF = parameters[self.Weight]
        gF = parameters[self.Group]

        index = QgsSpatialIndex(Network.getFeatures())
        orig_data = {feature.id():feature for feature in Network.getFeatures()}

        infc = parameters[self.LG]
        infc2 = parameters[self.Network]

        P = 100000
        sources,edges,Lengths = {},{},{}
        for feature in LG.getFeatures():
            geom = feature.geometry()
            if QgsWkbTypes.isSingleType(geom.wkbType()):
                geom = geom.asPolyline()
            else:
                geom = geom.asMultiPolyline()[0]
            x,y = geom[0]
            startx,starty=ceil(x*P)/P,ceil(y*P)/P
            sources[feature['Sample_No_']] = (startx,starty)

        feedback.pushInfo(QCoreApplication.translate('TempFiles','Creating Line Frequency Sampling'))
        parameters = {'INPUT':infc,'LINES':infc2,'OUTPUT':'memory:'}
        templines = st.run('native:splitwithlines',parameters,context=context,feedback=feedback)

        for feature in templines['OUTPUT'].getFeatures():
            geom = feature.geometry()
            if QgsWkbTypes.isSingleType(geom.wkbType()):
                geom = geom.asPolyline()
            else:
                geom = geom.asMultiPolyline()[0]
            start,end = geom[0],geom[-1]
            startx,starty=start
            endx,endy=end

            pnts1,pnts2 = [(ceil(startx*P)/P,ceil(starty*P)/P),(ceil(endx*P)/P,ceil(endy*P)/P)]
            Length = feature.geometry().length()
            ID = feature['Sample_No_']

            if ID in edges:
                edges[ID].add_edge(pnts1,pnts2,weight=Length)
            else:
                G = nx.Graph()
                G.add_edge(pnts1,pnts2,weight=Length)
                edges[ID] = G

        SN, SS, D, W = [],[],[],[]
        for feature in templines['OUTPUT'].getFeatures():
            geom = feature.geometry()
            if QgsWkbTypes.isSingleType(geom.wkbType()):
                geom = geom.asPolyline()
            else:
                geom = geom.asMultiPolyline()[0]
            start,end = geom[0],geom[-1]
            startx,starty=start
            endx,endy=end

            startx,starty = (ceil(startx*P)/P,ceil(starty*P)/P)
            endx, endy = (ceil(endx*P)/P,ceil(endy*P)/P)

            ID = feature['Sample_No_']

            if ID not in Lengths:
                G = edges[ID]
                if len(G.nodes()) > 2:
                    source = sources[ID]
                    length,path = nx.single_source_dijkstra(G,source,weight='weight')
                    Lengths[ID] = length

            if ID in Lengths:
                L = Lengths[ID][(endx,endy)]

                if gF != None or wF != None:
                    featFIDs = index.nearestNeighbor(QgsPointXY(endx,endy), 2)

                    for FID in featFIDs:
                        feature2 = orig_data[FID]
                        testGeom = QgsGeometry.fromPointXY(QgsPointXY(endx,endy))
                        wFv = 0
                        gFv = 'Total'
                        if testGeom.buffer(0.001,5).intersects(feature2.geometry()):
                            if wF:
                                wFv = feature2[wF]
                                if type(wFv) == int or type(wFv) == float:
                                    pass
                                else:
                                    feedback.reportError(QCoreApplication.translate('Error','Weight field contains non numeric values - check for null values'))
                                    return {}
                            if gF:
                                gFv = feature2[gF]
                            break

                SN.append(ID)
                D.append(L)
                if gF:
                    SS.append(str(gFv))
                else:
                    SS.append('Total')
                if wF:
                    W.append(float(wFv))
                else:
                    W.append(1)


        del sources,edges,Lengths

        data2 = pd.DataFrame({0:SN, 1:SS, 2:D, 3:W})
        data2.dropna(inplace=True)

        col_labels = ['Sample No','Count','mean','std','min','25%','50%','75%','Max','CoV',r'D+',r'D-','Vf']
        cols = [['<b>%s</b>'%(col)]for col in col_labels]
        ngtPath = 'https://raw.githubusercontent.com/BjornNyberg/NetworkGT/master/Images/NetworkGT_Logo1.png'
        axis=dict(
            showline=True,
            zeroline=False,
            showgrid=True,
            mirror=True,
            ticklen=2,
            gridcolor='#ffffff',
            tickfont=dict(size=10)
        )

        layout= go.Layout(images=[dict(source=ngtPath,xref="paper", yref="paper", x=1.0, y=1.0,sizex=0.2, sizey=0.2, xanchor="right", yanchor="bottom")],
            title= 'Line Frequency Plot',
            margin = dict(t=100),
            xaxis1= dict(
                axis,
                title= 'Distance',
                ticklen= 5,
                gridwidth= 2,
                **dict(domain=[0, 1], anchor='y1')
            ),
            yaxis1=dict(
                axis,
                title= 'Frequency',
                ticklen= 5,
                gridwidth= 2,
                **dict(domain=[0.3, 1], anchor='x1')
            ),

            showlegend= True
        )

        table_vals = [[],[],[],[],[],[],[],[],[],[],[],[],[]]
        data,vf_values = {},{}
        traces = []

        for n,df in data2.groupby(0):
            if len(df) > 1:
                if not Combine:
                    table_vals = [[],[],[],[],[],[],[],[],[],[],[],[],[]]
                    data,vf_values = {},{}
                    traces = []

                max_dist = max(df[2])

                x,y,c = [0],[0],0.0
                values = df.sort_values(2)
                values.iloc[-1, values.columns.get_loc(3)] = 0

                prev = 0
                for x_value,disp in zip(values[2],values[3]):
                    y.append(y[-1])
                    c += disp
                    y.append(c)
                    x.extend([x_value,x_value])
                    spacing = [x_value - prev]
                    prev = x_value

                    if n not in data:
                        data[n] = spacing
                    else:
                        spacing_data = data[n]
                        spacing += spacing_data
                        data[n] = spacing

                m = float(max(y)/max_dist)

                for x_v,y_v in zip(x,y):
                    test_y = x_v*m
                    vf = [y_v/float(y[-1]) - test_y/y[-1]]
                    if n in vf_values:
                        vf_data = vf_values[n]
                        vf_data += vf
                        vf_values[n] = vf_data
                    else:
                        vf_values[n] = vf
                if Norm:
                    xmax = max(x)
                    ymax = max(y)
                    x = [v/xmax for v in x]
                    y = [v/ymax for v in y]

                traces.append(go.Scatter(
                                    x = x,
                                    y = y,
                                    mode = 'lines',
                                    name = n,
                                    xaxis='x1',
                                    yaxis='y1'
                                ))

                for n2V,g in df.groupby(1):
                    n2 = 'Sample %s - %s'%(n,n2V)
                    if n2V == 'Total':
                        continue
                    else:
                        x,y,c = [0],[0],0.0
                        values = g.sort_values(2)

                        prev = 0
                        for x_value,disp in zip(values[2],values[3]):

                            y.append(y[-1])
                            c += disp
                            y.append(c)
                            x.extend([x_value,x_value])
                            spacing = [x_value - prev]

                            prev = x_value

                            if n2 not in data:
                                data[n2] = spacing

                            else:
                                spacing_data = data[n2]
                                spacing += spacing_data
                                data[n2] = spacing


                        x.append(max_dist)
                        y.append(y[-1])

                        spacing_data = data[n2]
                        spacing = [max_dist - prev]
                        spacing += spacing_data
                        data[n2] = spacing

                        m = float(max(y)/max_dist)
                        for x_v,y_v in zip(x,y):
                            test_y = x_v*m
                            vf = [y_v/float(y[-1]) - test_y/float(y[-1])]

                            if n2 in vf_values:
                                vf_data = vf_values[n2]
                                vf_data += vf
                                vf_values[n2] = vf_data
                            else:
                                vf_values[n2] = vf

                        if Norm:
                            xmax = max(x)
                            ymax = max(y)
                            x = [v/xmax for v in x]
                            y = [v/ymax for v in y]

                        traces.append(go.Scatter(
                                    x = x,
                                    y = y,
                                    mode = 'lines',
                                    name = n2,
                                    xaxis='x1',
                                    yaxis='y1'
                                ))
            if not Combine:
                if not data:
                    continue

                for k,v in data.items():
                    table_vals[0].append(str(k))
                    table_vals[1].append(len(v))
                    table_vals[2].append(round(np.mean(v),2))
                    table_vals[3].append(round(np.std(v),2))
                    table_vals[4].append(round(min(v),2))
                    table_vals[5].append(round(np.percentile(v, 25),2))
                    table_vals[6].append(round(np.percentile(v, 50),2))
                    table_vals[7].append(round(np.percentile(v, 75),2))
                    table_vals[8].append(round(max(v),2))
                    table_vals[9].append(round(np.std(v)/np.mean(v),2))

                for k,vf in vf_values.items():
                    table_vals[10].append(round(max(vf),2))
                    table_vals[11].append(round(min(vf),2))
                    table_vals[12].append(round(math.fabs(max(vf))+ math.fabs(min(vf)),2))

                traces.append(go.Table(
                    domain=dict(x=[0.0, 1.0],
                                y=[0.0, 0.2]),
                    columnwidth = [1, 2, 2, 2],
                    columnorder=np.arange(0,13,1),
                    header = dict(height = 25,
                                  values = cols,
                                  line = dict(color='rgb(50, 50, 50)'),
                                  align = ['left'] * 10,
                                  font = dict(color=['rgb(45, 45, 45)'] * 5, size=14),
                                  fill = dict(color='#d562be')),

                    cells = dict(values = table_vals,
                                 line = dict(color='#506784'),
                                 align = ['left'] * 10,
                                 font = dict(color=['rgb(40, 40, 40)'] * 5, size=12),
                                 format = [None]+[".2f"]*12,
                                 height = 50,
                                 fill = dict(color=['rgb(235, 193, 238)', 'rgba(228, 222, 249, 0.65)']))))

                fig = go.Figure(traces, layout=layout)
                try:
                    py.plot(fig, filename='Line Frequency', auto_open=True)
                except Exception:
                    fig.show()

        if Combine:

            for k,v in data.items():
                table_vals[0].append(str(k))
                table_vals[1].append(len(v))
                table_vals[2].append(round(np.mean(v),2))
                table_vals[3].append(round(np.std(v),2))
                table_vals[4].append(round(min(v),2))
                table_vals[5].append(round(np.percentile(v, 25),2))
                table_vals[6].append(round(np.percentile(v, 50),2))
                table_vals[7].append(round(np.percentile(v, 75),2))
                table_vals[8].append(round(max(v),2))
                table_vals[9].append(round(np.std(v)/np.mean(v),2))

            for k,vf in vf_values.items():
                table_vals[10].append(round(max(vf),2))
                table_vals[11].append(round(min(vf),2))
                table_vals[12].append(round(math.fabs(max(vf))+ math.fabs(min(vf)),2))

            traces.append(go.Table(
                domain=dict(x=[0.0, 1.0],
                            y=[0.0, 0.2]),
                columnwidth = [1, 2, 2, 2],
                columnorder=np.arange(0,13,1),
                header = dict(height = 25,
                              values = cols,
                              line = dict(color='rgb(50, 50, 50)'),
                              align = ['left'] * 10,
                              font = dict(color=['rgb(45, 45, 45)'] * 5, size=14),
                              fill = dict(color='#d562be')),

                cells = dict(values = table_vals,
                             line = dict(color='#506784'),
                             align = ['left'] * 10,
                             font = dict(color=['rgb(40, 40, 40)'] * 5, size=12),
                             format = [None]+[".2f"]*12,
                             height = 50,
                             fill = dict(color=['rgb(235, 193, 238)', 'rgba(228, 222, 249, 0.65)']))))

            fig = go.Figure(traces, layout=layout)
            try:
                py.plot(fig, filename='Line Frequency', auto_open=True)
            except Exception:
                fig.show()

        return {}
Exemplo n.º 9
0
    def generateNodes(self):
        # commit all
        self.stopEdition()
        #Loop over the links """
        try:
            linkLayer = QgsProject.instance().mapLayersByName("Liens")[0]
            nodeLayer = QgsProject.instance().mapLayersByName("Noeuds")[0]
        except IndexError:
            print("No link layer...")
            return
        # Delete all nodes
        with edit(nodeLayer):
                    listOfIds = [feat.id() for feat in nodeLayer.getFeatures()]
                    nodeLayer.deleteFeatures( listOfIds )
        # Loop on all the feratures to store the first points
        features = linkLayer.getFeatures()
        coords = np.zeros([2*linkLayer.featureCount() , 4])
        i = 0
        for feature in features:
            coords[i,0] = feature.id()
            coords[i,1] = 0
            geom = feature.geometry()
            geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType())
            if geom.type()==QgsWkbTypes.LineGeometry:
                if geomSingleType:
                    x = geom.asPolyline()
                    coords[i,2] = x[0][0]
                    coords[i,3] = x[0][1]
                else:
                    x = geom.asMultiPolyline()
                    coords[i,2] = x[0][0][0]
                    coords[i,3] = x[0][0][1]
            i+=1
        # Loop on all the features tp store the last points
        features = linkLayer.getFeatures()
        for feature in features:
            coords[i,0] = feature.id()
            coords[i,1] = 2
            geom = feature.geometry()
            geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType())
            if geom.type()==QgsWkbTypes.LineGeometry:
                if geomSingleType:
                    x = geom.asPolyline()
                    coords[i,2] = x[-1][0]
                    coords[i,3] = x[-1][1]
                else:
                    x = geom.asMultiPolyline()
                    coords[i,2] = x[0][-1][0]
                    coords[i,3] = x[0][-1][1]
            i+=1
        # Get the uniques coords to ensure that the nodes are not duplicated
        uniques = np.unique(coords[:,2:4], axis=0)
        # Generate the nodes
        with edit(nodeLayer):
            for i in range(len(uniques)):
                feat = QgsFeature(nodeLayer.fields())
                feat['fid'] = i+1
                feat.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(uniques[i,0], uniques[i,1])))
                (res, outFeats) = nodeLayer.dataProvider().addFeatures([feat])

        # Assign the nodes to the links
        features = nodeLayer.getFeatures()
        with edit(linkLayer):
            # Loop over the nodes
            count = 0
            for feature in features:
                X = feature.geometry().asPoint()[0]
                Y = feature.geometry().asPoint()[1]
                # get the lines in coords where the node appear
                lines = np.unique(np.where(coords[:,2:4]==[X,Y])[0])
                # get fids
                fidsAndPlaces = coords[lines, 0:2]
                fidsAndPlaces = fidsAndPlaces[fidsAndPlaces[:,0].argsort()]
                fids = list(fidsAndPlaces[:,0])
                # get places 0 = upstram / 2 = downstream
                places = list(fidsAndPlaces[:,1])
                # get Features corresponding to the fids
                linkFeats = linkLayer.getFeatures(QgsFeatureRequest().setFilterFids(fids))
                i = 0
                # Loop over the features
                for feat in linkFeats:
                    # if it is an upstream node
                    if places[i] == 0.:
                        linkLayer.dataProvider().changeAttributeValues({feat.id() : {4 : feature.id()}})
                    # if it is a downstream node
                    elif places[i] == 2.:
                        linkLayer.dataProvider().changeAttributeValues({feat.id() : {5 : feature.id()}})
                    else:
                        print('ERROR HERE / Search for E-001')
                    i += 1
        # Assign types
        with edit(nodeLayer):
            nodes = nodeLayer.getFeatures()
            for node in nodes:
                # Test if links has this node as upstream node
                expr = QgsExpression( "\"up_node\"='{}'".format( node.id() ) )
                features = linkLayer.getFeatures( QgsFeatureRequest( expr ) )
                # if it is empty
                if not features.nextFeature(QgsFeature()):
                    nodeLayer.dataProvider().changeAttributeValues({node.id() : {1 : 2}})
                    continue
                # Test if links has this node as downstream node
                expr = QgsExpression( "\"down_node\"='{}'".format( node.id() ) )
                features = linkLayer.getFeatures( QgsFeatureRequest( expr ) )
                # if it is empty
                if not features.nextFeature(QgsFeature()):
                    nodeLayer.dataProvider().changeAttributeValues({node.id() : {1 : 1}})
                    continue
                nodeLayer.dataProvider().changeAttributeValues({node.id() : {1 : 0}})
Exemplo n.º 10
0
    def processAlgorithm(self, parameters, context, feedback):

        layer = self.parameterAsSource(parameters, self.Network, context)
        Sample_Area = self.parameterAsSource(parameters, self.Sample_Area,
                                             context)
        tol = self.parameterAsDouble(parameters, self.tolerance, context)

        field_check = Sample_Area.fields().indexFromName('Sample_No_')

        if field_check == -1:
            editLayer = self.parameterAsLayer(parameters, self.Sample_Area,
                                              context)
            pr = editLayer.dataProvider()
            pr.addAttributes([QgsField('Sample_No_', QVariant.Int)])
            editLayer.updateFields()
            f_len = editLayer.fields().indexFromName('Sample_No_')
            editLayer.startEditing()
            for feature in editLayer.getFeatures():
                pr.changeAttributeValues({feature.id(): {f_len: feature.id()}})
            editLayer.commitChanges()

        infc = parameters[self.Network]
        infc2 = parameters[self.IB]
        infc3 = parameters[self.Sample_Area]

        fields = QgsFields()
        new_fields = ['Class', 'Connection', 'Weight', 'Sample_No_', 'Length']

        fields.append(QgsField("Class", QVariant.String))
        fields.append(QgsField("Connection", QVariant.String))
        fields.append(QgsField("Weight", QVariant.Double))
        fields.append(QgsField("Sample_No_", QVariant.Int))
        fields.append(QgsField("Length", QVariant.Double))

        fields2 = QgsFields()
        fields2.append(QgsField("Class", QVariant.String))
        fields2.append(QgsField("Sample_No_", QVariant.Int))

        (writer2, dest_id2) = self.parameterAsSink(parameters, self.Nodes,
                                                   context, fields2,
                                                   QgsWkbTypes.Point,
                                                   layer.sourceCrs())

        feedback.pushInfo(
            QCoreApplication.translate('TempFiles',
                                       'Creating Temporary Files'))

        params = {'INPUT': infc, 'LINES': infc, 'OUTPUT': 'memory:'}
        templines = st.run('native:splitwithlines',
                           params,
                           context=context,
                           feedback=None)

        if infc2:
            params = {'INPUT': infc2, 'OUTPUT': 'memory:'}
            tempmask = st.run('qgis:polygonstolines',
                              params,
                              context=context,
                              feedback=None)
            params = {
                'INPUT': infc,
                'OVERLAY': infc2,
                'INPUT_FIELDS': '',
                'OVERLAY_FIELDS': '',
                'OUTPUT': 'memory:'
            }
            tempint = st.run('native:intersection',
                             params,
                             context=context,
                             feedback=None)
            params = {'INPUT': tempint['OUTPUT'], 'OUTPUT': 'memory:'}
            templines = st.run("native:multiparttosingleparts",
                               params,
                               context=context,
                               feedback=None)
            cursorm = [
                feature.geometry() for feature in
                tempmask['OUTPUT'].getFeatures(QgsFeatureRequest())
            ]

        field_check = Sample_Area.fields().indexFromName('Radius')

        if field_check != -1:
            params = {'INPUT': infc3, 'ALL_PARTS': False, 'OUTPUT': 'memory:'}
            centroids = st.run('native:centroids',
                               params,
                               context=context,
                               feedback=None)

            params = {
                'INPUT': centroids['OUTPUT'],
                'DISTANCE': QgsProperty.fromField('Radius'),
                'SEGMENTS': 100,
                'END_CAP_STYLE': 0,
                'JOIN_STYLE': 0,
                'MITER_LIMIT': 2,
                'DISSOLVE': False,
                'OUTPUT': 'memory:'
            }
            buff = st.run('native:buffer',
                          params,
                          context=context,
                          feedback=None)

            if infc2:
                params = {
                    'INPUT': buff['OUTPUT'],
                    'OVERLAY': infc2,
                    'INPUT_FIELDS': '',
                    'OVERLAY_FIELDS': '',
                    'OUTPUT': 'memory:'
                }
                samplemask = st.run('native:intersection',
                                    params,
                                    context=context,
                                    feedback=None)
                Sample_Area = samplemask['OUTPUT']
            else:
                Sample_Area = buff['OUTPUT']

        unknown_nodes, point_data = [], []
        c_points = {}
        Graph = {}  #Store all node connections
        P = 100000
        feedback.pushInfo(
            QCoreApplication.translate('Nodes', 'Reading Node Information'))
        extra_fields = []
        for field in templines['OUTPUT'].fields():
            if field.name() not in new_fields:
                fields.append(QgsField(field.name(), field.type()))
                extra_fields.append(field.name())

        (writer, dest_id) = self.parameterAsSink(parameters, self.Branches,
                                                 context, fields,
                                                 QgsWkbTypes.LineString,
                                                 layer.sourceCrs())

        features = templines['OUTPUT'].getFeatures(QgsFeatureRequest())
        total = 0
        for feature in features:
            try:
                total += 1
                geom = feature.geometry()
                if geom.length() < 0.0000001:
                    continue
                geom = geom.asPolyline()
                start, end = geom[0], geom[-1]
                startx, starty = start
                endx, endy = end
                branch = [(ceil(startx * P) / P, ceil(starty * P) / P),
                          (ceil(endx * P) / P, ceil(endy * P) / P)]
                for b in branch:
                    if b in Graph:  #node count
                        Graph[b] += 1
                    else:
                        Graph[b] = 1
            except Exception as e:
                feedback.reportError(
                    QCoreApplication.translate('Interpretation Boundary',
                                               '%s' % (e)))

        if infc2:
            feedback.pushInfo(
                QCoreApplication.translate('Nodes', 'Reading Unknown Nodes'))
            features = layer.getFeatures(QgsFeatureRequest())
            for feature in features:
                try:
                    for m in cursorm:
                        if feature.geometry().intersects(m):
                            geom = feature.geometry().intersection(m)
                            if QgsWkbTypes.isSingleType(geom.wkbType()):
                                x, y = geom.asPoint()
                                unknown_nodes.append(
                                    (ceil(x * P) / P, ceil(y * P) / P))
                            else:
                                for x, y in geom.asMultiPoint(
                                ):  #Check for multipart polyline
                                    unknown_nodes.append(
                                        (ceil(x * P) / P, ceil(y * P) / P))
                except Exception as e:
                    feedback.reportError(
                        QCoreApplication.translate('Interpretation Boundary',
                                                   '%s' % (geom.wkbType())))

        total = 100.0 / total
        index = QgsSpatialIndex(Sample_Area.getFeatures(QgsFeatureRequest()))
        cursormData = {
            feature.id(): (feature.geometry(), feature['Sample_No_'])
            for feature in Sample_Area.getFeatures(QgsFeatureRequest())
        }

        fet = QgsFeature(fields)
        fet2 = QgsFeature(fields)
        eCount = 0
        features = templines['OUTPUT'].getFeatures(QgsFeatureRequest())
        feedback.pushInfo(
            QCoreApplication.translate('BranchesNodes',
                                       'Creating Branches and Nodes'))

        for enum, feature in enumerate(features):
            try:
                feedback.setProgress(int(enum * total))
                geom = feature.geometry().asPolyline()
                start, end = geom[0], geom[-1]
                startx, starty = start
                endx, endy = end
                branch = [(ceil(startx * P) / P, ceil(starty * P) / P),
                          (ceil(endx * P) / P, ceil(endy * P) / P)]
                name, rows = [], []
                for field in extra_fields:
                    rows.append(feature[field])
                for (x, y) in branch:
                    if (x, y) in unknown_nodes:
                        V = 'U'
                    elif (x, y) in Graph:
                        node_count = Graph[(x, y)]
                        if node_count == 1:
                            V = 'I'
                        elif node_count == 3:
                            V = 'Y'
                        elif node_count == 4:
                            V = 'X'
                        else:
                            V = str(node_count)  #'Error'
                            eCount += 1
                            if eCount < 10:
                                feedback.reportError(
                                    QCoreApplication.translate(
                                        'Interpretation Boundary',
                                        'Found intersection with %s nodes at coordinates %s! Please repair fracture network using the repair tool and/or manual reinterpretation(s)'
                                        % (node_count, str((x, y)))))
                            elif eCount == 10:
                                feedback.reportError(
                                    QCoreApplication.translate(
                                        'Interpretation Boundary',
                                        'Reached 10 errors and will stop reporting errors'
                                    ))
                    else:
                        V = 'Error'
                    name.append(V)
                Class = " - ".join(sorted(
                    name[:2]))  #Organize the order of names
                name = Class.replace('X', 'C').replace('Y', 'C')
                name = name.split(" - ")
                Connection = " - ".join(sorted(name))
                geom = feature.geometry()
                cursorm = index.intersects(geom.boundingBox())

                for FID in cursorm:
                    geom = feature.geometry()
                    m = cursormData[FID]
                    if geom.within(m[0]):  #Branches
                        weight = 1
                        for (x, y) in branch:  #Points
                            testPoint = QgsGeometry.fromPointXY(
                                QgsPointXY(x, y))
                            if (x, y) in unknown_nodes:
                                V = 'U'
                                weight -= 0.5
                            elif not testPoint.within(
                                    m[0].buffer(-0.001, 2)
                            ):  #Test if point is on edge of sample area
                                V = 'E'
                                weight -= 0.5
                            else:
                                if (x, y) in Graph:
                                    node_count = Graph[(x, y)]
                                    if node_count == 1:
                                        V = 'I'
                                    elif node_count == 3:
                                        V = 'Y'
                                    elif node_count == 4:
                                        V = 'X'
                                    else:
                                        V = str(node_count)  #'Error'
                                else:
                                    V = 'Error'
                            if m[1] in c_points:
                                if (x, y) not in c_points[m[1]]:
                                    data2 = [V, m[1]]
                                    c_points[m[1]].append((x, y))
                                    fet2.setGeometry(
                                        QgsGeometry.fromPointXY(
                                            QgsPointXY(x, y)))
                                    fet2.setAttributes(data2)
                                    writer2.addFeature(
                                        fet2, QgsFeatureSink.FastInsert)
                            else:
                                data2 = [V, m[1]]
                                c_points[m[1]] = [(x, y)]
                                fet2.setGeometry(
                                    QgsGeometry.fromPointXY(QgsPointXY(x, y)))
                                fet2.setAttributes(data2)
                                writer2.addFeature(fet2,
                                                   QgsFeatureSink.FastInsert)
                        data = [
                            Class, Connection, weight, m[1],
                            feature.geometry().length()
                        ]
                        data.extend(rows)
                        fet.setGeometry(feature.geometry())
                        fet.setAttributes(data)
                        writer.addFeature(fet, QgsFeatureSink.FastInsert)

                    elif geom.intersects(m[0]):

                        geom = geom.intersection(m[0])
                        parts = []

                        if QgsWkbTypes.isSingleType(geom.wkbType()):
                            parts.append(geom)
                        else:
                            for part in geom.parts(
                            ):  #Check for multipart polyline
                                parts.append(QgsGeometry.fromPolyline(
                                    part))  #intersected geometry

                        for inter in parts:
                            if inter.length() != 0.0:  #Branches
                                geom = inter.asPolyline()
                                istart, iend = geom[0], geom[-1]
                                istartx, istarty = istart
                                iendx, iendy = iend
                                inter_branch = [(istartx, istarty),
                                                (iendx, iendy)]
                                weight = 1
                                for (x, y) in inter_branch:  #Points
                                    rx, ry = ceil(x * P) / P, ceil(y * P) / P
                                    V = 'E'
                                    if (rx, ry) in unknown_nodes:
                                        V = 'U'
                                    elif (rx, ry) in Graph:
                                        node_count = Graph[(rx, ry)]
                                        if node_count == 1:
                                            V = 'I'
                                        elif node_count == 3:
                                            V = 'Y'
                                        elif node_count == 4:
                                            V = 'X'
                                        else:
                                            V = str(node_count)  #'Error'

                                    if m[1] in c_points:
                                        if (rx, ry) not in c_points[m[1]]:
                                            data2 = [V, m[1]]
                                            c_points[m[1]].append((rx, ry))
                                            fet2.setGeometry(
                                                QgsGeometry.fromPointXY(
                                                    QgsPointXY(x, y)))
                                            fet2.setAttributes(data2)
                                            writer2.addFeature(
                                                fet2,
                                                QgsFeatureSink.FastInsert)
                                    else:
                                        c_points[m[1]] = [(rx, ry)]
                                        data2 = [V, m[1]]
                                        fet2.setGeometry(
                                            QgsGeometry.fromPointXY(
                                                QgsPointXY(x, y)))
                                        fet2.setAttributes(data2)
                                        writer2.addFeature(
                                            fet2, QgsFeatureSink.FastInsert)
                                    if V == 'E' or V == 'U':
                                        weight -= 0.5

                                data = [
                                    Class, Connection, weight, m[1],
                                    feature.geometry().length()
                                ]
                                data.extend(rows)
                                fet.setGeometry(inter)
                                fet.setAttributes(data)
                                writer.addFeature(fet,
                                                  QgsFeatureSink.FastInsert)

            except Exception as e:
                feedback.reportError(
                    QCoreApplication.translate('Sample Area', '%s' % (e)))

        self.dest_id = dest_id
        self.dest_id2 = dest_id2

        return {self.Branches: dest_id, self.Nodes: dest_id2}
Exemplo n.º 11
0
def SplitMesh(outputdb, meshtable, output_table, SplitFlag, keycolum,
              divcolumn):

    mlayer = meshtable

    if type(meshtable) is str:

        #    入力メッシュレイヤ
        dmesh = outputdb + "|layername=" + meshtable

        mlayer = QgsVectorLayer(dmesh, "mesh", "ogr")

    if mlayer.isValid():
        print("dmesh Layer load OK")
    else:
        print("dmesh Layer load Fail")
        print("dmesh=" + meshtable)
        sys.exit()

    out_tb = outputdb + "|layername=" + output_table

    crsstr = mlayer.crs().authid()

    #   作業結果出力レイヤ

    vectL = 'Polygon?crs=' + crsstr

    vl1 = QgsVectorLayer(vectL, "temporary_mesh", "memory")

    if not vl1:
        print("Virtual Layer failed to load!")
        sys.exit()
    else:
        print(out_tb)

    #vl1.setCrs( mlayer.crs()  )

    pr1 = vl1.dataProvider()

    #  フィールド定義
    pr1.addAttributes([
        QgsField(keycolum, QVariant.String),
        QgsField(divcolumn, QVariant.Int)
    ])

    vl1.updateFields()  #

    vl1.beginEditCommand("Add Polygons")

    features = mlayer.getFeatures()

    for feature in features:

        code = feature[keycolum]
        divide_f = feature[divcolumn]

        #print( 'code =' + code+ ' divide=' + str(divide_f) )
        geom = feature.geometry()
        geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType())

        if divide_f == 0:

            if geom.type() == QgsWkbTypes.PolygonGeometry:

                if geomSingleType:
                    x = geom.asPolygon()

                    #print("Polygon: ", x, "Area: ", geom.area())

                    for xp in x:
                        #print("xp:",xp )

                        #for xxp in xp:
                        #     print("xxp:",xxp)

                        #    座標の場所を判定して位置関係を正規化したほうがいいかも
                        #

                        p0_1 = GetCyuuten(xp[0], xp[1])
                        p1_2 = GetCyuuten(xp[1], xp[2])
                        p2_3 = GetCyuuten(xp[2], xp[3])
                        p3_4 = GetCyuuten(xp[3], xp[4])
                        pC_C = GetCyuuten(p0_1, p2_3)

                        #    新しいキーコード
                        ncode1 = code + '-01'

                        Polygon1 = QgsGeometry.fromPolygonXY([[
                            QgsPointXY(xp[0].x(), xp[0].y()),
                            QgsPointXY(p0_1.x(), p0_1.y()),
                            QgsPointXY(pC_C.x(), pC_C.y()),
                            QgsPointXY(p3_4.x(), p3_4.y())
                        ]])

                        # add a feature
                        fet = QgsFeature(pr1.fields())

                        fet.setGeometry(Polygon1)

                        fet[keycolum] = ncode1
                        fet[divcolumn] = divide_f
                        #  新しい feature を作って別レイヤに格納する
                        retc = pr1.addFeatures([fet])

                        #print("add new")
                        #print( retc )

                        #    新しいキーコード
                        ncode2 = code + '-02'
                        Polygon2 = QgsGeometry.fromPolygonXY([[
                            QgsPointXY(p0_1.x(), p0_1.y()),
                            QgsPointXY(xp[1].x(), xp[1].y()),
                            QgsPointXY(p1_2.x(), p1_2.y()),
                            QgsPointXY(pC_C.x(), pC_C.y())
                        ]])

                        fet2 = QgsFeature(pr1.fields())

                        fet2.setGeometry(Polygon2)

                        fet2[keycolum] = ncode2
                        fet2[divcolumn] = divide_f
                        #  新しい feature を作って別レイヤに格納する
                        retc = pr1.addFeatures([fet2])

                        #    新しいキーコード
                        ncode3 = code + '-03'
                        Polygon3 = QgsGeometry.fromPolygonXY([[
                            QgsPointXY(pC_C.x(), pC_C.y()),
                            QgsPointXY(p1_2.x(), p1_2.y()),
                            QgsPointXY(xp[2].x(), xp[2].y()),
                            QgsPointXY(p2_3.x(), p2_3.y())
                        ]])

                        fet3 = QgsFeature(pr1.fields())

                        fet3.setGeometry(Polygon3)

                        fet3[keycolum] = ncode3
                        fet3[divcolumn] = divide_f
                        #  新しい feature を作って別レイヤに格納する
                        retc = pr1.addFeatures([fet3])

                        #    新しいキーコード
                        ncode4 = code + '-04'
                        Polygon4 = QgsGeometry.fromPolygonXY([[
                            QgsPointXY(p3_4.x(), p3_4.y()),
                            QgsPointXY(pC_C.x(), pC_C.y()),
                            QgsPointXY(p2_3.x(), p2_3.y()),
                            QgsPointXY(xp[3].x(), xp[3].y())
                        ]])

                        fet4 = QgsFeature(pr1.fields())

                        fet4.setGeometry(Polygon4)

                        fet4[keycolum] = ncode4
                        fet4[divcolumn] = divide_f
                        #  新しい feature を作って別レイヤに格納する
                        retc = pr1.addFeatures([fet4])

                    #print(Polygon1)
                    # print(Polygon2)

                    #Poly

                    #feat.setGeometry( QgsGeometry.fromPolygonXY([QgsPointXY(546016, 4760165), p2, p3]))
                    #qPolygon1 = QgsGeometry.fromPolygonXY([ xp[0],p0_1, pC_C,xp[0]])

                    #print( qPolygon1 )

                #   一点目 2点目の中点を求める   2

                else:
                    x = geom.asMultiPolygon()
                #print("MultiPolygon: ", x, "Area: ", geom.area())
            else:
                print("geometry is not polygon!")

        else:  #  分割不要ポリゴンはそのまま書き込む
            retc = pr1.addFeatures([feature])

    vl1.updateExtents()
    vl1.endEditCommand()
    vl1.commitChanges()

    features2 = vl1.getFeatures()

    print("-------------------------- vl1 features ------------------------")
    #for feature2 in features2:

    #          print( feature2 )

    options = QgsVectorFileWriter.SaveVectorOptions()
    options.driverName = 'GPKG'
    options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer
    options.layerName = output_table

    #print( "outputdb ==>"+outputdb )
    #print( "output ==>"+output_table )

    #  結果レイヤ書き込み
    write_result, error = QgsVectorFileWriter.writeAsVectorFormat(
        vl1, outputdb, options)
    #if error == QgsVectorFileWriter.NoError:
    #         print("success again!")

    #print( error )
    #print( write_result )

    return (output_table)
Exemplo n.º 12
0
def SplitMeshLayer(mlayer, keycolum):
    #  InputLayer  メッシュテーブル
    #  output_table  出力メッシュテーブル
    #  SplitFlag     フラグが1のメッシュは分割しない
    #
    #  return new mesh layer
    #
    #outputlayer = QgsVectorLayer("Point?crs=EPSG:4326", "layer name you like", "memory")

    if type(mlayer) is str:

        mlayer = QgsVectorLayer(mlayer, "mesh", "ogr")

    if mlayer.isValid():
        print("dmesh Layer load OK")
    else:
        print("dmesh Layer load Fail")
        print("dmesh=" + mlayer.name())
        sys.exit()

    crsstr = mlayer.crs().authid()

    #   作業結果出力レイヤ

    vectL = 'Polygon?crs=' + crsstr

    vl1 = QgsVectorLayer(vectL, "temporary_mesh", "memory")

    if not vl1:
        print("Virtual Layer failed to load!")
        sys.exit()
    #else:
    #         print( out_tb )

    #vl1.setCrs( mlayer.crs()  )

    pr1 = vl1.dataProvider()

    #  フィールド定義
    pr1.addAttributes([QgsField(keycolum, QVariant.String)])
    #               QgsField(divcolumn,  QVariant.Int)])

    vl1.updateFields()  #

    vl1.beginEditCommand("Add Polygons")

    features = mlayer.getFeatures()

    for feature in features:

        code = feature[keycolum]
        #divide_f = feature[ divcolumn ]

        divide_f = 0

        #print( 'code =' + code+ ' divide=' + str(divide_f) )
        geom = feature.geometry()
        geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType())

        if divide_f == 0:

            if geom.type() == QgsWkbTypes.PolygonGeometry:

                if geomSingleType:
                    x = geom.asPolygon()

                    #print("Polygon: ", x, "Area: ", geom.area())

                    for xp in x:
                        #print("xp:",xp )

                        #for xxp in xp:
                        #     print("xxp:",xxp)

                        #    座標の場所を判定して位置関係を正規化したほうがいいかも
                        #

                        p0_1 = GetCyuuten(xp[0], xp[1])
                        p1_2 = GetCyuuten(xp[1], xp[2])
                        p2_3 = GetCyuuten(xp[2], xp[3])
                        p3_4 = GetCyuuten(xp[3], xp[4])
                        pC_C = GetCyuuten(p0_1, p2_3)

                        #    新しいキーコード
                        ncode1 = code + '-01'

                        Polygon1 = QgsGeometry.fromPolygonXY([[
                            QgsPointXY(xp[0].x(), xp[0].y()),
                            QgsPointXY(p0_1.x(), p0_1.y()),
                            QgsPointXY(pC_C.x(), pC_C.y()),
                            QgsPointXY(p3_4.x(), p3_4.y())
                        ]])

                        # add a feature
                        fet = QgsFeature(pr1.fields())

                        fet.setGeometry(Polygon1)

                        fet[keycolum] = ncode1
                        #    fet[divcolumn] = divide_f
                        #  新しい feature を作って別レイヤに格納する
                        retc = pr1.addFeatures([fet])

                        #print("add new")
                        #print( retc )

                        #    新しいキーコード
                        ncode2 = code + '-02'
                        Polygon2 = QgsGeometry.fromPolygonXY([[
                            QgsPointXY(p0_1.x(), p0_1.y()),
                            QgsPointXY(xp[1].x(), xp[1].y()),
                            QgsPointXY(p1_2.x(), p1_2.y()),
                            QgsPointXY(pC_C.x(), pC_C.y())
                        ]])

                        fet2 = QgsFeature(pr1.fields())

                        fet2.setGeometry(Polygon2)

                        fet2[keycolum] = ncode2
                        #   fet2[divcolumn] = divide_f
                        #  新しい feature を作って別レイヤに格納する
                        retc = pr1.addFeatures([fet2])

                        #    新しいキーコード
                        ncode3 = code + '-03'
                        Polygon3 = QgsGeometry.fromPolygonXY([[
                            QgsPointXY(pC_C.x(), pC_C.y()),
                            QgsPointXY(p1_2.x(), p1_2.y()),
                            QgsPointXY(xp[2].x(), xp[2].y()),
                            QgsPointXY(p2_3.x(), p2_3.y())
                        ]])

                        fet3 = QgsFeature(pr1.fields())

                        fet3.setGeometry(Polygon3)

                        fet3[keycolum] = ncode3
                        #   fet3[divcolumn] = divide_f
                        #  新しい feature を作って別レイヤに格納する
                        retc = pr1.addFeatures([fet3])

                        #    新しいキーコード
                        ncode4 = code + '-04'
                        Polygon4 = QgsGeometry.fromPolygonXY([[
                            QgsPointXY(p3_4.x(), p3_4.y()),
                            QgsPointXY(pC_C.x(), pC_C.y()),
                            QgsPointXY(p2_3.x(), p2_3.y()),
                            QgsPointXY(xp[3].x(), xp[3].y())
                        ]])

                        fet4 = QgsFeature(pr1.fields())

                        fet4.setGeometry(Polygon4)

                        fet4[keycolum] = ncode4
                        #   fet4[divcolumn] = divide_f
                        #  新しい feature を作って別レイヤに格納する
                        retc = pr1.addFeatures([fet4])

                    #print(Polygon1)
                    # print(Polygon2)

                    #Poly

                    #feat.setGeometry( QgsGeometry.fromPolygonXY([QgsPointXY(546016, 4760165), p2, p3]))
                    #qPolygon1 = QgsGeometry.fromPolygonXY([ xp[0],p0_1, pC_C,xp[0]])

                    #print( qPolygon1 )

                #   一点目 2点目の中点を求める   2

                else:
                    x = geom.asMultiPolygon()
                #print("MultiPolygon: ", x, "Area: ", geom.area())
            else:
                print("geometry is not polygon!")

        #else:    #  分割不要ポリゴンはそのまま書き込む
        #    retc = pr1.addFeatures([feature])

    vl1.updateExtents()
    vl1.endEditCommand()
    vl1.commitChanges()

    return vl1
Exemplo n.º 13
0
    def processAlgorithm(self, parameters, context, feedback):
        # get input variables
        source = self.parameterAsSource(parameters, self.INPUT_LINE, context)
        swath_angle_field = self.parameterAsString(parameters,
                                                   self.SWATH_ANGLE_FIELD,
                                                   context)
        swath_angle_fallback = self.parameterAsInt(parameters,
                                                   self.SWATH_ANGLE, context)
        raster_layer = self.parameterAsRasterLayer(parameters,
                                                   self.INPUT_RASTER, context)
        band_number = self.parameterAsInt(parameters, self.BAND, context)

        # copy of the field name for later
        swath_angle_field_name = swath_angle_field

        # set new default values in config
        feedback.pushConsoleInfo(
            self.tr(f'Storing new default settings in config...'))
        self.config.set(self.module, 'swath_angle', swath_angle_fallback)

        # get crs's
        crs_line = source.sourceCrs()
        crs_raster = raster_layer.crs()

        # get project transform_context
        transform_context = context.transformContext()

        # CRS transformation to "WGS84/World Mercator" for MBES coverage operations
        crs_mercator = QgsCoordinateReferenceSystem('EPSG:3395')
        trans_line2merc = QgsCoordinateTransform(crs_line, crs_mercator,
                                                 transform_context)

        # CRS transformation to raster layer CRS for depth sampling
        trans_merc2raster = QgsCoordinateTransform(crs_mercator, crs_raster,
                                                   transform_context)
        trans_line2raster = QgsCoordinateTransform(crs_line, crs_raster,
                                                   transform_context)
        crs_geo = QgsCoordinateReferenceSystem('EPSG:4326')
        trans_line2geo = QgsCoordinateTransform(crs_line, crs_geo,
                                                transform_context)

        # initialize distance tool
        da = QgsDistanceArea()
        da.setSourceCrs(crs_mercator, transform_context)
        da.setEllipsoid(crs_mercator.ellipsoidAcronym())

        # empty lists for unioned buffers
        buffer_union_list = []

        # get (selected) features
        features = source.getFeatures()

        # feedback
        total = 100.0 / source.featureCount() if source.featureCount() else 0

        # loop through features
        feedback.pushConsoleInfo(self.tr(f'Densifying line features...'))
        feedback.pushConsoleInfo(self.tr(f'Extracting vertices...'))
        feedback.pushConsoleInfo(self.tr(f'Sampling values...'))
        feedback.pushConsoleInfo(
            self.tr(f'Computing depth dependent buffers...'))
        feedback.pushConsoleInfo(self.tr(f'Unionizing output features...'))
        for feature_id, feature in enumerate(features):
            # get feature geometry
            feature_geom = feature.geometry()

            # check for LineString geometry
            if QgsWkbTypes.isSingleType(feature_geom.wkbType()):
                # get list of vertices
                vertices_list = feature_geom.asPolyline()
                vertices_list = [vertices_list]

            # check for MultiLineString geometry
            elif QgsWkbTypes.isMultiType(feature_geom.wkbType()):
                # get list of list of vertices per multiline part
                vertices_list = feature_geom.asMultiPolyline()

            for part_id, vertices in enumerate(vertices_list):
                # transform vertices CRS to "WGS 84 / World Mercator"
                vertices_t = []
                for vertex in vertices:
                    vertex_trans = trans_line2merc.transform(vertex)
                    vertices_t.append(vertex_trans)

                # get centroid as point for UTM zone selection
                centroid = feature_geom.centroid()
                centroid_point = centroid.asPoint()

                # check if centroid needs to be transformed to get x/y in lon/lat
                if not crs_line.isGeographic():
                    centroid_point = trans_line2geo.transform(centroid_point)

                # get UTM zone of feature for buffering
                lat, lon = centroid_point.y(), centroid_point.x()
                crs_utm = self.get_UTM_zone(lat, lon)

                # create back and forth transformations for later
                trans_merc2utm = QgsCoordinateTransform(
                    crs_mercator, crs_utm, transform_context)
                trans_utm2line = QgsCoordinateTransform(
                    crs_utm, crs_line, transform_context)

                # split line into segments
                for segment_id in range(len(vertices_t) - 1):
                    # ===== (1) DENSIFY LINE VERTICES =====
                    # create new Polyline geometry for line segment
                    segment_geom = QgsGeometry.fromPolylineXY(
                        [vertices_t[segment_id], vertices_t[segment_id + 1]])

                    # measure ellipsoidal distance between start and end vertex
                    segment_length = da.measureLength(segment_geom)

                    # calculate number of extra vertices to insert
                    extra_vertices = int(segment_length //
                                         self.vertex_distance)

                    # create additional vertices along line segment
                    segment_geom_dense = segment_geom.densifyByCount(
                        extra_vertices - 1)

                    # initialize additional fields
                    feature_id_field = QgsField('feature_id',
                                                QVariant.Int,
                                                'Integer',
                                                len=5,
                                                prec=0)
                    part_id_field = QgsField('part_id',
                                             QVariant.Int,
                                             'Integer',
                                             len=5,
                                             prec=0)
                    segment_id_field = QgsField('segment_id',
                                                QVariant.Int,
                                                'Integer',
                                                len=5,
                                                prec=0)

                    # list for segment buffers
                    buffer_list = []

                    # loop over all vertices of line segment
                    for i, vertex in enumerate(segment_geom_dense.vertices()):
                        # === CREATE POINT FEATURE ===
                        # initialize feature and set geometry
                        fpoint = QgsFeature()
                        fpoint.setGeometry(vertex)

                        # sample bathymetry grid
                        # get point geometry (as QgsPointXY)
                        fpoint_geom = fpoint.geometry()
                        pointXY = fpoint_geom.asPoint()

                        # transform point to raster CRS
                        pointXY_raster = trans_merc2raster.transform(
                            pointXY)  #trans_line2raster.transform(pointXY)

                        # sample raster at point location
                        pointXY_depth, error_check = raster_layer.dataProvider(
                        ).sample(pointXY_raster, 1)

                        # check if valid depth was sampled, otherwise skip point
                        if error_check == False:
                            continue

                        # create depth-dependant buffer:
                        # check if swath_angle field is selected
                        if swath_angle_field != '':
                            # get value from field
                            swath_angle_field_value = feature.attribute(
                                swath_angle_field)
                            # check if value is set (not NOLL)
                            if swath_angle_field_value == None:
                                # if NULL, set fallback
                                swath_angle = swath_angle_fallback
                            else:
                                # othervise take value from field
                                swath_angle = swath_angle_field_value
                        # or if no field was selected use fallback value right away
                        else:
                            swath_angle = swath_angle_fallback

                        # calculate buffer radius (swath width from depth and swath angle)
                        buffer_radius = round(
                            tan(radians(swath_angle / 2)) * abs(pointXY_depth),
                            0)

                        # transform point from mercator zu UTM
                        fpoint_geom.transform(trans_merc2utm)

                        # create buffer
                        buffer = fpoint_geom.buffer(buffer_radius, 10)

                        # transform buffer back to initial input CRS
                        buffer.transform(trans_utm2line)

                        # store buffer in list
                        buffer_list.append(buffer)

                    # check if any points in this segment have been sampled
                    if buffer_list == []:
                        continue

                    # dissolve point buffers of line segment:
                    # dissolve all polygons based on line vertices into single feature
                    buffer_union = QgsGeometry().unaryUnion(buffer_list)

                    # set fields and attributes:
                    # empty fields
                    buffer_fields = QgsFields()

                    # loop through line feature fields
                    for field in feature.fields():
                        # and append all but the 'fid' field (if it exists)
                        if field.name() != 'fid':
                            buffer_fields.append(field)

                    # append extra buffer fields (intial feature id, part id and segment id
                    for buffer_field in [
                            feature_id_field, part_id_field, segment_id_field
                    ]:
                        buffer_fields.append(buffer_field)

                    # if no input swath_angle field was selected on input, create one
                    if swath_angle_field == '':
                        swath_angle_field_name = 'mbes_swath_angle'
                        buffer_fields.append(
                            QgsField(swath_angle_field_name,
                                     QVariant.Int,
                                     'Integer',
                                     len=5,
                                     prec=0))

                    # initialize polygon feature
                    fpoly = QgsFeature(buffer_fields)

                    # set attributes for polygon feature
                    for field in feature.fields():
                        # ignore 'fid' again
                        if field.name() != 'fid':
                            # set attribute from feature to buffer
                            fpoly.setAttribute(field.name(),
                                               feature.attribute(field.name()))

                    # set addtional buffer fields
                    fpoly.setAttribute('feature_id', feature_id)
                    fpoly.setAttribute('part_id', part_id)
                    fpoly.setAttribute('segment_id', segment_id)
                    fpoly.setAttribute(swath_angle_field_name, swath_angle)

                    # set geometry
                    fpoly.setGeometry(buffer_union)

                    # store segment coverage polygon
                    if fpoly.hasGeometry() and fpoly.isValid():
                        buffer_union_list.append(fpoly)

            # set progess
            feedback.setProgress(int(feature_id * total))

        # if buffer_union_list is empty, no buffer features where created
        if buffer_union_list == []:
            raise Exception(
                'No depth values could be sampled from the input raster!')

        # creating feature sink
        feedback.pushConsoleInfo(self.tr(f'Creating feature sink...'))
        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
                                               context, buffer_fields,
                                               QgsWkbTypes.MultiPolygon,
                                               source.sourceCrs())
        if sink is None:
            raise QgsProcessingException(
                self.invalidSinkError(parameters, self.OUTPUT))

        # write coverage features to sink
        feedback.pushConsoleInfo(self.tr(f'Writing features...'))
        sink.addFeatures(buffer_union_list, QgsFeatureSink.FastInsert)

        # make variables accessible for post processing
        self.output = dest_id

        result = {self.OUTPUT: self.output}

        return result
    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
        """
        try:
            if is_remote:
                xml_src = 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_src = open(xml_uri, 'rb')
            src = ComplexFeatureSource(xml_src, attributes, geometry_mapping, logger)

            attr_list = [ (k, v[1]) for k, v in attributes.items() ]

            layers = {}
            features = {}
            layer_geom_type = {}
            for id, fid, qgsgeoms, xml, attrs in src.getFeatures(swap_xy):
                # layer creation
                if qgsgeoms == []:
                    if "" not in layers:
                        layer = self._create_layer('none', None, attr_list, src.title, "nogeom")
                        self._add_properties_to_layer(layer, xml_uri, is_remote, attributes, geometry_mapping)
                        layers["nogeom"] = layer
                else:
                    for (qgsgeom, srid), tag in qgsgeoms:
                        if tag in layers:
                            continue
                        type2d = QgsWkbTypes.flatType(qgsgeom.wkbType())
                        typemap = {QgsWkbTypes.Point: 'point',
                                   QgsWkbTypes.MultiPoint: 'multipoint',
                                   QgsWkbTypes.LineString: 'linestring',
                                   QgsWkbTypes.MultiLineString: 'multilinestring',
                                   QgsWkbTypes.Polygon: 'polygon',
                                   QgsWkbTypes.MultiPolygon: 'multipolygon',
                                   QgsWkbTypes.CompoundCurve: 'compoundcurve',
                                   QgsWkbTypes.CircularString: 'compoundcurve',
                                   QgsWkbTypes.MultiCurve: 'multicurve',
                                   QgsWkbTypes.CurvePolygon: 'curvepolygon',
                                   QgsWkbTypes.MultiSurface: 'multisurface'}
                        if qgsgeom and type2d in typemap:
                            title = "{} ({})".format(src.title, no_prefix(tag))
                            layer = self._create_layer(typemap[QgsWkbTypes.multiType(type2d)], srid, attr_list, title, no_prefix(tag))
                        else:
                            raise RuntimeError("Unsupported geometry type {}".format(qgsgeom.wkbType()))
                        self._add_properties_to_layer(layer, xml_uri, is_remote, attributes, geometry_mapping)                        
                        layers[tag] = layer

                # collect features
                f = QgsFeature(layer.dataProvider().fields(), id)
                f.setAttribute("id", str(id))
                f.setAttribute("fid", fid)
                for k, v in attrs.items():
                    r = f.setAttribute(k, v)
                for g, tag in qgsgeoms:
                    if tag not in features:
                        features[tag] = []
                    fcopy = QgsFeature(f)
                    fcopy.setAttribute("_xml_", ET.tostring(xml).decode('utf8'))
                    if g:
                        qgsgeom, _ = g
                        if QgsWkbTypes.isMultiType(layers[tag].wkbType()) and QgsWkbTypes.isSingleType(qgsgeom.wkbType()):
                            # force multi
                            qgsgeom.convertToMultiType()
                        fcopy.setGeometry(qgsgeom)
                    features[tag].append(fcopy)

            # write features
            for tag, f in features.items():
                if len(f) > 0:
                    layer = layers[tag]
                    layer.startEditing()
                    layer.addFeatures(f)
                    layer.commitChanges()
        finally:
            xml_src.close()

        # Set the styl for polygons coming from boundedBy
        for tag_name, layer in layers.items():
            if tag_name.endswith("boundedBy"):
                layer.loadNamedStyle(os.path.join(os.path.dirname(__file__), "..", "gui", "bounded_by_style.qml"))
        return layers
Exemplo n.º 15
0
    def processAlgorithm(self, parameters, context, feedback):

        try:
            import math
            import numpy as np
        except Exception as e:
            feedback.reportError(QCoreApplication.translate('Error','%s'%(e)))
            feedback.reportError(QCoreApplication.translate('Error',' '))
            feedback.reportError(QCoreApplication.translate('Error','Error loading modules - please install the necessary dependencies'))
            return {}

        layer = self.parameterAsLayer(parameters, self.Network, context)
        bin_v =  parameters[self.Bin_V]
        if bin_v > 0:
            x = np.arange(0,180,bin_v)
            y = np.arange(bin_v,180+bin_v,bin_v)
            y[-1] = 180
            bins = tuple(zip(x,y))
        else:
            bins = list(eval(self.parameterAsString(parameters, self.Sets, context)))

        new_fields = ['Set', 'Orient', 'Length']

        if self.Output in parameters:
            fields = QgsFields()
            for field in layer.fields():
                if field.name() not in new_fields:
                    fields.append(QgsField(field.name(), field.type()))

            for field in new_fields:
                fields.append(QgsField(field, QVariant.Double))

            (writer, dest_id) = self.parameterAsSink(parameters, self.Output, context,
                                                     fields, QgsWkbTypes.LineString, layer.sourceCrs())
            fet = QgsFeature()

        else:
            pr = layer.dataProvider()

            for field in new_fields:
                if layer.fields().indexFromName(field) == -1:
                    pr.addAttributes([QgsField(field, QVariant.Double)])

            layer.updateFields()
            idxs = []
            for field in new_fields:
                idxs.append(layer.fields().indexFromName(field))

            layer.startEditing()

        features = layer.selectedFeatures()
        total = layer.selectedFeatureCount()
        if len(features) == 0:
            features = layer.getFeatures()
            total = layer.featureCount()

        total = 100.0/total

        for enum,feature in enumerate(features):
            if total > 0:
                feedback.setProgress(int(enum*total))
            geom = feature.geometry()
            if QgsWkbTypes.isSingleType(geom.wkbType()):
                geom = [geom.asPolyline()]
            else:
                geom = geom.asMultiPolyline()

            if len(geom) == 0:
                feedback.reportError(QCoreApplication.translate('Error','Warning - skipping null geometry linestring.'))
                continue

            x, y = 0, 0
            for part in geom:
                startx = None
                for point in part:
                    if startx == None:
                        startx, starty = point
                        continue
                    endx, endy = point

                    dx = endx - startx
                    dy = endy - starty

                    l = math.sqrt((dx ** 2) + (dy ** 2))
                    angle = math.degrees(math.atan2(dy, dx))
                    x += math.cos(math.radians(angle)) * l
                    y += math.sin(math.radians(angle)) * l

                    startx, starty = endx, endy

            mean = 90 - np.around(math.degrees(math.atan2(y, x)), decimals=4)
            if mean > 180:
                mean -= 180
            elif mean < 0:
                mean += 180

            value = -1
            for enum, b in enumerate(bins):
                if float(b[0]) > float(b[1]):
                    if mean >= float(b[0]) or mean <= float(b[1]):
                        value = enum
                        break
                elif mean >= float(b[0]) and mean <= float(b[1]):
                    value = enum
                    break

            if self.Output in parameters:
                rows = []
                for field in layer.fields():
                    if field.name() not in new_fields:
                        rows.append(feature[field.name()])
                rows.extend([value,float(mean),float(feature.geometry().length())])

                fet.setGeometry(feature.geometry())
                fet.setAttributes(rows)
                writer.addFeature(fet, QgsFeatureSink.FastInsert)
            else:
                rows = {idxs[0]:value,idxs[1]:float(mean),idxs[2]:float(feature.geometry().length())}
                pr.changeAttributeValues({feature.id():rows})

        if self.Output in parameters:
            return {self.Output: dest_id}
        else:
            layer.commitChanges()
            return {}
Exemplo n.º 16
0
    def processAlgorithm(self, parameters, context, feedback):
        """
        Here is where the processing itself takes place.
        """
        self.progress = 0
        # extent = self.parameterAsExtent(parameters, self.EXTENT, context)
        workspace = self.parameterAsFile(parameters, self.INPUT, context)
        output = self.parameterAsFileOutput(parameters, self.OUTPUT, context)

        # if not extent:
        #     raise_exception('can\'t read extent')

        if not workspace:
            raise_exception('can\'t get wokrspace')

        if not output:
            raise_exception('can\'t get an output')

        feedback.pushInfo(tr('The algorithm is running'))

        dummy = QgsVectorLayer(workspace, "dummy", "ogr")
        sublyrs = dummy.dataProvider().subLayers()

        layers = []
        for sublyr in sublyrs:
            name = sublyr.split('!!::!!')[1]
            uri = "%s|layername=%s" % (workspace, name)
            layer = QgsVectorLayer(uri, name, "ogr")
            layers.append(layer)

        for layer in layers:
            features = list(layer.getFeatures())
            features_count = len(features)
            fields = layer.dataProvider().fields()
            indexes = [fields.indexFromName(field.name()) for field in fields]

            unique_values_per_field = {key: set() for key in indexes}
            points_num = 0
            total_length = 0
            bend_num = 0
            total_bend_area = 0.0
            ave_bend_base_line_len = 0.0
            ave_bend_height = 0.0
            ave_bend_length = 0.0
            total_polygon_area = 0.0
            count = 0.0
            total_intersections = 0

            total = 100.0 / features_count if features_count > 0 else 0

            for current, feature in enumerate(features):
                if feedback.isCanceled():
                    break

                update_unique_values(feature, indexes, unique_values_per_field)
                geom = feature.geometry()
                is_single_type = QgsWkbTypes.isSingleType(geom.wkbType())

                if geom.type() == QgsWkbTypes.LineGeometry:
                    total_length += geom.length()

                    if is_single_type:
                        data_list = [(v.x(), v.y()) for v in geom.vertices()]

                        if len(data_list) < 3:
                            continue

                        result = get(data_list)
                        count = count + 1
                        points_num += result[0]
                        bend_num += result[1]
                        total_bend_area += result[2]
                        ave_bend_base_line_len += result[3]
                        ave_bend_height += result[4]
                        ave_bend_length += result[5]
                    else:
                        for part in geom.parts():
                            data_list = [(v.x(), v.y())
                                         for v in part.vertices()]

                            if len(data_list) < 3:
                                continue

                            result = get(data_list)
                            count = count + 1
                            points_num += result[0]
                            bend_num += result[1]
                            total_bend_area += result[2]
                            ave_bend_base_line_len += result[3]
                            ave_bend_height += result[4]
                            ave_bend_length += result[5]
                elif geom.type() == QgsWkbTypes.PolygonGeometry:
                    total_length += geom.length()

                    if is_single_type:
                        data_list = [(v.x(), v.y()) for v in geom.vertices()]

                        if len(data_list) < 3:
                            continue

                        result = get(data_list)
                        count = count + 1
                        points_num += result[0]
                        bend_num += result[1]
                        total_bend_area += result[2]
                        ave_bend_base_line_len += result[3]
                        ave_bend_height += result[4]
                        ave_bend_length += result[5]
                        total_polygon_area += geom.area()
                    else:
                        for part in geom.parts():
                            data_list = [(v.x(), v.y())
                                         for v in part.vertices()]

                            if len(data_list) < 3:
                                continue

                            result = get(data_list)
                            count = count + 1
                            points_num += result[0]
                            bend_num += result[1]
                            total_bend_area += result[2]
                            ave_bend_base_line_len += result[3]
                            ave_bend_height += result[4]
                            ave_bend_length += result[5]
                        total_polygon_area += geom.area()
                else:
                    break

                self.progress = int(current * total)
                feedback.setProgress(self.progress)

            uniq_values_number = get_unique_values_ratio(
                unique_values_per_field, features_count)
            ave_uniq_values_number = get_ave_unique_values_ratio(
                uniq_values_number, len(fields))

            feedback.pushInfo('Total intersections:')
            filtered_layers = filter_layers([layer])

            if filtered_layers:
                total_intersections = len(
                    get_total_intersection(filtered_layers[0], feedback))

            header = [
                'workspace',
                'layer',
                'field_count',
                'features_count',
                'uniq_values_number',
                'average_uniq_values',
                'total_length',
                'number_of_points',
                'number_of_bends',
                'average_area_of_bends',
                'average_length_of_bends_baseline',
                'average_height_of_bends',
                'average_length_of_the_bends',
                'total_polygons_area',
                'average_polygons_area',
                'average_length',
                'layer_type',
                'total_bends_area',
                'total_intersections',
            ]
            row = [{
                header[0]:
                os.path.basename(os.path.normpath(workspace)),
                header[1]:
                layer.name(),
                header[2]:
                len(fields),
                header[3]:
                features_count,
                header[4]:
                uniq_values_number,
                header[5]:
                ave_uniq_values_number,
                header[6]:
                get_formatted_result(total_length),
                header[7]:
                points_num,
                header[8]:
                bend_num,
                header[9]:
                get_formatted_result(total_bend_area /
                                     bend_num) if bend_num > 0 else 0.0,
                header[10]:
                get_formatted_result(ave_bend_base_line_len /
                                     bend_num) if bend_num > 0 else 0.0,
                header[11]:
                get_formatted_result(ave_bend_height /
                                     bend_num) if bend_num > 0 else 0.0,
                header[12]:
                get_formatted_result(ave_bend_length /
                                     bend_num) if bend_num > 0 else 0.0,
                header[13]:
                get_formatted_result(total_polygon_area),
                header[14]:
                get_formatted_result(total_polygon_area /
                                     count) if count > 0 else 0.0,
                header[15]:
                get_formatted_result(total_length /
                                     count) if count > 0 else 0.0,
                header[16]:
                QgsWkbTypes.geometryDisplayString(int(layer.geometryType())),
                header[17]:
                get_formatted_result(total_bend_area),
                header[18]:
                get_formatted_result(total_intersections),
            }]

            if output:
                feedback.pushInfo(tr('Writing to file'))
                write_to_file(output, header, row, ';')

        return row[0]
Exemplo n.º 17
0
    def processAlgorithm(self, parameters, context, feedback):

        layer = self.parameterAsSource(parameters, self.Network, context)
        Sample_Area = self.parameterAsSource(parameters, self.Sample_Area,
                                             context)

        field_check = Sample_Area.fields().indexFromName('Sample_No_')

        if field_check == -1:
            feedback.reportError(
                QCoreApplication.translate(
                    'Input Error',
                    'Add "Sample_No_" attribute field to Sample Area input file'
                ))
            return {}

        infc = parameters[self.Network]
        infc2 = parameters[self.IB]
        infc3 = parameters[self.Sample_Area]

        fields = QgsFields()
        fields.append(QgsField("Class", QVariant.String))
        fields.append(QgsField("Connection", QVariant.String))
        fields.append(QgsField("Weight", QVariant.Double))
        fields.append(QgsField("Sample_No_", QVariant.Int))

        (writer, dest_id) = self.parameterAsSink(parameters, self.Branches,
                                                 context, fields,
                                                 QgsWkbTypes.LineString,
                                                 layer.sourceCrs())

        fields2 = QgsFields()
        fields2.append(QgsField("Class", QVariant.String))
        fields2.append(QgsField("Sample_No_", QVariant.Int))

        (writer2, dest_id2) = self.parameterAsSink(parameters, self.Nodes,
                                                   context, fields2,
                                                   QgsWkbTypes.Point,
                                                   layer.sourceCrs())

        feedback.pushInfo(
            QCoreApplication.translate('TempFiles',
                                       'Creating Temporary Files'))
        parameters = {'INPUT': infc2, 'OUTPUT': 'memory:'}
        tempmask = st.run('qgis:polygonstolines',
                          parameters,
                          context=context,
                          feedback=feedback)

        parameters = {
            'INPUT': infc,
            'OVERLAY': infc2,
            'INPUT_FIELDS': '',
            'OVERLAY_FIELDS': '',
            'OUTPUT': 'memory:'
        }
        tempint = st.run('native:intersection',
                         parameters,
                         context=context,
                         feedback=feedback)

        parameters = {'INPUT': tempint['OUTPUT'], 'OUTPUT': 'memory:'}
        tempsp = st.run("native:multiparttosingleparts",
                        parameters,
                        context=context,
                        feedback=feedback)

        parameters = {
            'INPUT': tempsp['OUTPUT'],
            'LINES': tempsp['OUTPUT'],
            'OUTPUT': 'memory:'
        }
        templines = st.run('native:splitwithlines',
                           parameters,
                           context=context,
                           feedback=feedback)

        field_check = Sample_Area.fields().indexFromName('Radius')

        if field_check != -1:
            parameters = {
                'INPUT': infc3,
                'ALL_PARTS': False,
                'OUTPUT': 'memory:'
            }
            centroids = st.run('native:centroids',
                               parameters,
                               context=context,
                               feedback=feedback)

            parameters = {
                'INPUT': centroids['OUTPUT'],
                'DISTANCE': QgsProperty.fromField('Radius'),
                'SEGMENTS': 5,
                'END_CAP_STYLE': 0,
                'JOIN_STYLE': 0,
                'MITER_LIMIT': 2,
                'DISSOLVE': False,
                'OUTPUT': 'memory:'
            }
            buffer = st.run('native:buffer',
                            parameters,
                            context=context,
                            feedback=feedback)

            parameters = {
                'INPUT': buffer['OUTPUT'],
                'OVERLAY': infc2,
                'INPUT_FIELDS': '',
                'OVERLAY_FIELDS': '',
                'OUTPUT': 'memory:'
            }
            samplemask = st.run('native:intersection',
                                parameters,
                                context=context,
                                feedback=feedback)

            Sample_Area = samplemask['OUTPUT']

        unknown_nodes, point_data = [], []
        c_points = {}
        Graph = {}  #Store all node connections

        feedback.pushInfo(
            QCoreApplication.translate('Nodes', 'Reading Node Information'))
        cursorm = [
            feature.geometry()
            for feature in tempmask['OUTPUT'].getFeatures(QgsFeatureRequest())
        ]
        features = templines['OUTPUT'].getFeatures(QgsFeatureRequest())
        total = 0
        for feature in features:
            try:
                total += 1
                geom = feature.geometry().asPolyline()
                start, end = geom[0], geom[-1]
                startx, starty = start
                endx, endy = end
                branch = [(round(startx, 8), round(starty, 8)),
                          (round(endx, 8), round(endy, 8))]
                for b in branch:
                    if b in Graph:  #node count
                        Graph[b] += 1
                    else:
                        Graph[b] = 1
                for m in cursorm:
                    geom = feature.geometry().intersection(m)
                    if QgsWkbTypes.isSingleType(geom.wkbType()):
                        x, y = geom.asPoint()
                        unknown_nodes.append((round(x, 8), round(y, 8)))
                    else:
                        for x, y in geom.asMultiPoint(
                        ):  #Check for multipart polyline
                            unknown_nodes.append((round(x, 8), round(y, 8)))

            except Exception as e:
                feedback.reportError(
                    QCoreApplication.translate('Interpretation Boundary',
                                               '%s' % (e)))

        total = 100.0 / total
        cursorm = [(feature.geometry(), feature['Sample_No_'])
                   for feature in Sample_Area.getFeatures(QgsFeatureRequest())]
        fet = QgsFeature(fields)
        fet2 = QgsFeature(fields)
        features = templines['OUTPUT'].getFeatures(QgsFeatureRequest())

        feedback.pushInfo(
            QCoreApplication.translate('BranchesNodes',
                                       'Creating Branches and Nodes'))
        for enum, feature in enumerate(features):
            try:
                feedback.setProgress(int(enum * total))
                geom = feature.geometry().asPolyline()
                start, end = geom[0], geom[-1]
                startx, starty = start
                endx, endy = end
                branch = [(round(startx, 8), round(starty, 8)),
                          (round(endx, 8), round(endy, 8))]
                name = []
                for (x, y) in branch:
                    if (x, y) in unknown_nodes:
                        V = 'U'
                    else:
                        if (x, y) in Graph:
                            node_count = Graph[(x, y)]
                            if node_count == 1:
                                V = 'I'
                            elif node_count == 3:
                                V = 'Y'
                            elif node_count == 4:
                                V = 'X'
                            else:
                                V = 'Error'
                        else:
                            V = 'Error'
                    name.append(V)
                Class = " - ".join(sorted(
                    name[:2]))  #Organize the order of names
                name = Class.replace('X', 'C').replace('Y', 'C')
                name = name.split(" - ")
                Connection = " - ".join(sorted(name))

                for m in cursorm:
                    geom = feature.geometry()
                    if geom.within(m[0]):  #Branches
                        weight = 1
                        for (x, y) in branch:  #Points
                            testPoint = QgsGeometry.fromPointXY(
                                QgsPointXY(x, y))
                            if (x, y) in unknown_nodes:
                                V = 'U'
                                weight -= 0.5
                            elif not testPoint.within(
                                    m[0].buffer(-0.001, 2)
                            ):  #Test if point is on edge of sample area
                                V = 'E'
                                weight -= 0.5
                            else:
                                if (x, y) in Graph:
                                    node_count = Graph[(x, y)]
                                    if node_count == 1:
                                        V = 'I'
                                    elif node_count == 3:
                                        V = 'Y'
                                    elif node_count == 4:
                                        V = 'X'
                                    else:
                                        V = 'Error'
                                else:
                                    V = 'Error'
                            if m[1] in c_points:
                                if (x, y) not in c_points[m[1]]:
                                    data2 = [V, m[1]]
                                    c_points[m[1]].append((x, y))
                                    fet2.setGeometry(
                                        QgsGeometry.fromPointXY(
                                            QgsPointXY(x, y)))
                                    fet2.setAttributes(data2)
                                    writer2.addFeature(
                                        fet2, QgsFeatureSink.FastInsert)
                            else:
                                data2 = [V, m[1]]
                                c_points[m[1]] = [(x, y)]
                                fet2.setGeometry(
                                    QgsGeometry.fromPointXY(QgsPointXY(x, y)))
                                fet2.setAttributes(data2)
                                writer2.addFeature(fet2,
                                                   QgsFeatureSink.FastInsert)
                        data = [Class, Connection, weight, m[1]]
                        fet.setGeometry(feature.geometry())
                        fet.setAttributes(data)
                        writer.addFeature(fet, QgsFeatureSink.FastInsert)

                    elif geom.intersects(m[0]):

                        geom = geom.intersection(m[0])
                        parts = []

                        if QgsWkbTypes.isSingleType(geom.wkbType()):
                            parts.append(geom)

                        else:
                            for part in geom.parts(
                            ):  #Check for multipart polyline
                                parts.append(QgsGeometry.fromPolyline(
                                    part))  #intersected geometry
                        for inter in parts:
                            if inter.length() != 0.0:  #Branches
                                geom = inter.asPolyline()
                                istart, iend = geom[0], geom[-1]
                                istartx, istarty = istart
                                iendx, iendy = iend
                                inter_branch = [(istartx, istarty),
                                                (iendx, iendy)]
                                weight = 1
                                for (x, y) in inter_branch:  #Points
                                    rx, ry = round(x, 8), round(y, 8)
                                    V = 'E'
                                    if (rx, ry) in unknown_nodes:
                                        V = 'U'
                                    elif (rx, ry) in Graph:
                                        node_count = Graph[(rx, ry)]
                                        if node_count == 1:
                                            V = 'I'
                                        elif node_count == 3:
                                            V = 'Y'
                                        elif node_count == 4:
                                            V = 'X'
                                        else:
                                            V = 'Error'

                                    if m[1] in c_points:
                                        if (rx, ry) not in c_points[m[1]]:
                                            data2 = [V, m[1]]
                                            c_points[m[1]].append((rx, ry))
                                            fet2.setGeometry(
                                                QgsGeometry.fromPointXY(
                                                    QgsPointXY(x, y)))
                                            fet2.setAttributes(data2)
                                            writer2.addFeature(
                                                fet2,
                                                QgsFeatureSink.FastInsert)
                                    else:
                                        c_points[m[1]] = [(rx, ry)]
                                        data2 = [V, m[1]]
                                        fet2.setGeometry(
                                            QgsGeometry.fromPointXY(
                                                QgsPointXY(x, y)))
                                        fet2.setAttributes(data2)
                                        writer2.addFeature(
                                            fet2, QgsFeatureSink.FastInsert)
                                    if V == 'E' or V == 'U':
                                        weight -= 0.5

                                data = [Class, Connection, weight, m[1]]
                                fet.setGeometry(inter)
                                fet.setAttributes(data)
                                writer.addFeature(fet,
                                                  QgsFeatureSink.FastInsert)

            except Exception as e:
                feedback.reportError(
                    QCoreApplication.translate('Sample Area', '%s' % (e)))

        return {self.Branches: dest_id, self.Nodes: dest_id2}
    def generate_gcode(self):

        machine_bounds = self.get_current_machine_bounds()

        extent = self.extentGroupBox.outputExtent()
        map_bounds = {
            "lon": (extent.xMinimum(), extent.xMaximum()),
            "lat": (extent.yMinimum(), extent.yMaximum())
        }

        plot_speed = self.plot_speed_spinbox.value()
        rapid_speed = self.rapid_speed_spinbox.value()
        pen_down_height = self.pen_down_height_spinbox.value()
        pen_up_height = self.pen_up_height_spinbox.value()

        gcode = ""

        layer = self.layer_select.currentLayer()
        for feature in layer.getFeatures():
            geom = feature.geometry()

            geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType())
            if geom.type() == QgsWkbTypes.PointGeometry:
                raise Exception("Point geometry not supported")
            elif geom.type() == QgsWkbTypes.LineGeometry:
                if geomSingleType:
                    gcode += geometry2gcode(geom.asPolyline(),
                                            map_bounds,
                                            machine_bounds,
                                            pen_down_height,
                                            pen_up_height,
                                            feed=plot_speed,
                                            link_feed=rapid_speed)
                else:
                    poly_geom = geom.asMultiPolyline()
                    for poly_geom in geom.asMultiPolyline():
                        gcode += geometry2gcode(poly_geom,
                                                map_bounds,
                                                machine_bounds,
                                                pen_down_height,
                                                pen_up_height,
                                                feed=plot_speed,
                                                link_feed=rapid_speed)
            elif geom.type() == QgsWkbTypes.PolygonGeometry:
                if geomSingleType:
                    for poly_geom in geom.asPolygon():
                        gcode += geometry2gcode(poly_geom,
                                                map_bounds,
                                                machine_bounds,
                                                pen_down_height,
                                                pen_up_height,
                                                feed=plot_speed,
                                                link_feed=rapid_speed)
                else:
                    for multi_geom in geom.asMultiPolygon():
                        for poly_geom in multi_geom:
                            gcode += geometry2gcode(poly_geom,
                                                    map_bounds,
                                                    machine_bounds,
                                                    pen_down_height,
                                                    pen_up_height,
                                                    feed=plot_speed,
                                                    link_feed=rapid_speed)
            else:
                raise Exception("Unknown or invalid geometry")

        dialog = QtWidgets.QFileDialog()
        dialog.setAcceptMode(QtWidgets.QFileDialog.AcceptSave)

        if dialog.exec_() == QtWidgets.QDialog.Accepted:
            path = dialog.selectedFiles()[0]
            with open(path, "w") as file:
                file.write(gcode)
Exemplo n.º 19
0
    def run(self):

        #coloco el puntero arriba del todo
        #QgsProject.instance().layerTreeRegistryBridge().setLayerInsertionPoint( QgsProject.instance().layerTreeRoot(), 0 )
        #genero una lista con los campos de la capa selecionada
        layer = iface.activeLayer()
        if layer is None:
            iface.messageBar().pushMessage("ATENCION",
                                           "Selecciona una capa de puntos",
                                           duration=10)
        if layer.wkbType() == 1 or layer.wkbType() == 1001:
            prov = layer.dataProvider()
            field_names = [field.name() for field in prov.fields()]
            self.dlg.mycomboBox.clear()
            for element in field_names:
                self.dlg.mycomboBox.addItem(element)
            """Run method that performs all the real work"""

            # Create the dialog with elements (after translation) and keep reference
            # Only create GUI ONCE in callback, so that it will only load when the plugin is started
            if self.first_start == True:
                self.first_start = False

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

            if result:
                global index_campo_seleccionado
                distanciaminima = int(self.dlg.lineEdit_distancia.text())
                # "layer" is a QgsVectorLayer instance
                layer = iface.activeLayer()
                idx = layer.fields().indexFromName("distanc")
                if idx == -1:
                    print("ya existe")
                    res = layer.dataProvider().addAttributes(
                        [QgsField("distanc", QVariant.String)])
                #layer.addAttribute(QgsField("valido", QVariant.String))
                layer.updateFields()
                features = layer.getFeatures()

                for feature in features:
                    # retrieve every feature with its geometry and attributes
                    #print("Feature ID: ", feature.id())
                    # fetch geometry
                    # show some information about the feature geometry
                    geom = feature.geometry()
                    geomSingleType = QgsWkbTypes.isSingleType(geom.wkbType())
                    if geom.type() == QgsWkbTypes.PointGeometry:
                        punto = geom.asPoint()
                        x = punto.x()
                        y = punto.y()
                        #print("analizo los puntos",x,y)
                        features2 = layer.getFeatures()
                        for feature2 in features2:
                            geom2 = feature2.geometry()
                            punto2 = geom2.asPoint()
                            x3 = punto2.x()
                            y3 = punto2.y()
                            d = ((x3 - x)**2 + (y3 - y)**2)**0.5
                            if d < distanciaminima:
                                if feature2.id() == feature.id():
                                    pass
                                else:
                                    layer.startEditing()
                                    feature.setAttribute("distanc", 'no')
                                    print(feature2.id())
                                    layer.updateFeature(feature)
                                    #Call commit to save the changes
                                    layer.commitChanges()

                categorias = []
                sym = QgsMarkerSymbol.createSimple({
                    'name': 'circle',
                    'color': 'red',
                    'size': '3'
                })
                categoria = QgsRendererCategory("no", sym, "No cumple")
                categorias.append(categoria)
                sym = QgsMarkerSymbol.createSimple({
                    'name': 'circle',
                    'color': 'blue',
                    'size': '2'
                })
                categoria = QgsRendererCategory("", sym, "Cumple")
                categorias.append(categoria)
                renderer = QgsCategorizedSymbolRenderer("distanc", categorias)
                layer.setRenderer(renderer)
                # update layer's extent when new features have been added
                # because change of extent in provider is not propagated to the layer

                #Configure label settings
                settings = QgsPalLayerSettings()
                settings.fieldName = field_names[
                    index_campo_seleccionado]  #'name'
                textFormat = QgsTextFormat()
                textFormat.setSize(10)
                settings.setFormat(textFormat)
                #create and append a new rule
                root = QgsRuleBasedLabeling.Rule(QgsPalLayerSettings())
                rule = QgsRuleBasedLabeling.Rule(settings)
                #rule.setDescription(fieldName)
                rule.setFilterExpression(''' "distanc" = 'no' ''')
                root.appendChild(rule)
                #Apply label configuration
                rules = QgsRuleBasedLabeling(root)
                layer.setLabeling(rules)
                layer.setLabelsEnabled(True)
                layer.triggerRepaint()

        else:
            iface.messageBar().pushMessage("ATENCION",
                                           "Selecciona una capa de puntos",
                                           duration=10)
Exemplo n.º 20
0
    def testWriteShapefileWithSingleConversion(self):
        """Check writing geometries from a POLYGON ESRI shapefile does not
        convert to multi when "forceSinglePartGeometryType" options is TRUE
        also checks failing cases.

        OGR provider always report MULTI for POLYGON and LINESTRING, but if we set
        the import option "forceSinglePartGeometryType" the writer must respect the
        actual single-part type if the features in the data provider are actually single
        and not multi.
        """

        ml = QgsVectorLayer(('Polygon?crs=epsg:4326&field=id:int'), 'test',
                            'memory')

        provider = ml.dataProvider()
        ft = QgsFeature()
        ft.setGeometry(
            QgsGeometry.fromWkt('Polygon ((0 0, 0 1, 1 1, 1 0, 0 0))'))
        ft.setAttributes([1])
        res, features = provider.addFeatures([ft])

        dest_file_name = os.path.join(self.basetestpath, 'multipart.shp')
        write_result, error_message = QgsVectorLayerExporter.exportLayer(
            ml, dest_file_name, 'ogr', ml.crs(), False,
            {"driverName": "ESRI Shapefile"})
        self.assertEqual(write_result, QgsVectorLayerExporter.NoError,
                         error_message)

        # Open the newly created layer
        shapefile_layer = QgsVectorLayer(dest_file_name)

        dest_singlepart_file_name = os.path.join(self.basetestpath,
                                                 'singlepart.gpkg')
        write_result, error_message = QgsVectorLayerExporter.exportLayer(
            shapefile_layer, dest_singlepart_file_name, 'ogr',
            shapefile_layer.crs(), False, {
                "forceSinglePartGeometryType": True,
                "driverName": "GPKG",
            })
        self.assertEqual(write_result, QgsVectorLayerExporter.NoError,
                         error_message)

        # Load result layer and check that it's NOT MULTI
        single_layer = QgsVectorLayer(dest_singlepart_file_name)
        self.assertTrue(single_layer.isValid())
        self.assertTrue(QgsWkbTypes.isSingleType(single_layer.wkbType()))

        # Now save the shapfile layer into a gpkg with no force options
        dest_multipart_file_name = os.path.join(self.basetestpath,
                                                'multipart.gpkg')
        write_result, error_message = QgsVectorLayerExporter.exportLayer(
            shapefile_layer, dest_multipart_file_name, 'ogr',
            shapefile_layer.crs(), False, {
                "forceSinglePartGeometryType": False,
                "driverName": "GPKG",
            })
        self.assertEqual(write_result, QgsVectorLayerExporter.NoError,
                         error_message)
        # Load result layer and check that it's MULTI
        multi_layer = QgsVectorLayer(dest_multipart_file_name)
        self.assertTrue(multi_layer.isValid())
        self.assertTrue(QgsWkbTypes.isMultiType(multi_layer.wkbType()))

        # Failing case: add a real multi to the shapefile and try to force to single
        self.assertTrue(shapefile_layer.startEditing())
        ft = QgsFeature()
        ft.setGeometry(
            QgsGeometry.fromWkt(
                'MultiPolygon (((0 0, 0 1, 1 1, 1 0, 0 0)), ((0 0, 0 1.5, 1 1.5, 1 0, 0 0)))'
            ))
        ft.setAttributes([2])
        self.assertTrue(shapefile_layer.addFeatures([ft]))
        self.assertTrue(shapefile_layer.commitChanges())

        dest_multipart_failure_file_name = os.path.join(
            self.basetestpath, 'multipart_failure.gpkg')
        write_result, error_message = QgsVectorLayerExporter.exportLayer(
            shapefile_layer, dest_multipart_failure_file_name, 'ogr',
            shapefile_layer.crs(), False, {
                "forceSinglePartGeometryType": True,
                "driverName": "GPKG",
            })
        self.assertTrue(QgsWkbTypes.isMultiType(multi_layer.wkbType()))
        self.assertEqual(
            write_result, QgsVectorLayerExporter.ErrFeatureWriteFailed,
            "Failed to transform a feature with ID '1' to single part. Writing stopped."
        )
    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
        """
        try:
            if is_remote:
                xml_src = 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_src = open(xml_uri, 'rb')
            src = ComplexFeatureSource(xml_src, attributes, geometry_mapping,
                                       logger)

            attr_list = [(k, v[1]) for k, v in attributes.items()]

            layers = {}
            features = {}
            layer_geom_type = {}
            for id, fid, qgsgeoms, xml, attrs in src.getFeatures(swap_xy):
                # layer creation
                if qgsgeoms == []:
                    if "" not in layers:
                        layer = self._create_layer('none', None, attr_list,
                                                   src.title, "nogeom")
                        self._add_properties_to_layer(layer, xml_uri,
                                                      is_remote, attributes,
                                                      geometry_mapping)
                        layers["nogeom"] = layer
                else:
                    for (qgsgeom, srid), tag in qgsgeoms:
                        if tag in layers:
                            continue
                        type2d = QgsWkbTypes.flatType(qgsgeom.wkbType())
                        typemap = {
                            QgsWkbTypes.Point: 'point',
                            QgsWkbTypes.MultiPoint: 'multipoint',
                            QgsWkbTypes.LineString: 'linestring',
                            QgsWkbTypes.MultiLineString: 'multilinestring',
                            QgsWkbTypes.Polygon: 'polygon',
                            QgsWkbTypes.MultiPolygon: 'multipolygon',
                            QgsWkbTypes.CompoundCurve: 'compoundcurve',
                            QgsWkbTypes.CircularString: 'compoundcurve',
                            QgsWkbTypes.MultiCurve: 'multicurve',
                            QgsWkbTypes.CurvePolygon: 'curvepolygon',
                            QgsWkbTypes.MultiSurface: 'multisurface'
                        }
                        if qgsgeom and type2d in typemap:
                            title = "{} ({})".format(src.title, no_prefix(tag))
                            layer = self._create_layer(
                                typemap[QgsWkbTypes.multiType(type2d)], srid,
                                attr_list, title, no_prefix(tag))
                        else:
                            raise RuntimeError(
                                "Unsupported geometry type {}".format(
                                    qgsgeom.wkbType()))
                        self._add_properties_to_layer(layer, xml_uri,
                                                      is_remote, attributes,
                                                      geometry_mapping)
                        layers[tag] = layer

                # collect features
                f = QgsFeature(layer.dataProvider().fields(), id)
                f.setAttribute("id", str(id))
                f.setAttribute("fid", fid)
                for k, v in attrs.items():
                    r = f.setAttribute(k, v)
                for g, tag in qgsgeoms:
                    if tag not in features:
                        features[tag] = []
                    fcopy = QgsFeature(f)
                    fcopy.setAttribute("_xml_",
                                       ET.tostring(xml).decode('utf8'))
                    if g:
                        qgsgeom, _ = g
                        if QgsWkbTypes.isMultiType(layers[tag].wkbType(
                        )) and QgsWkbTypes.isSingleType(qgsgeom.wkbType()):
                            # force multi
                            qgsgeom.convertToMultiType()
                        fcopy.setGeometry(qgsgeom)
                    features[tag].append(fcopy)

            # write features
            for tag, f in features.items():
                if len(f) > 0:
                    layer = layers[tag]
                    layer.startEditing()
                    layer.addFeatures(f)
                    layer.commitChanges()
        finally:
            xml_src.close()

        # Set the styl for polygons coming from boundedBy
        for tag_name, layer in layers.items():
            if tag_name.endswith("boundedBy"):
                layer.loadNamedStyle(
                    os.path.join(os.path.dirname(__file__), "..", "gui",
                                 "bounded_by_style.qml"))
        return layers
Exemplo n.º 22
0
    def run(self):
        """Run method that performs all the real work"""

        # Create the dialog with elements (after translation) and keep reference
        # Only create GUI ONCE in callback, so that it will only load when the plugin is started
        
        #Limpa o caminho pra salvar o arquivo
        self.dlg.caminho.clear() 

        # Carrega os Layer que corresponde somente a Shp de polylines
        layers = QgsProject.instance().mapLayers().values()
        self.dlg.select_layer.clear()
        for layer in layers:
            if layer.type() == QgsMapLayer.VectorLayer and layer.geometryType() == QgsWkbTypes.LineGeometry:
                self.dlg.select_layer.addItem( layer.name(), layer )  
        self.set_select_attributes()

        # Carrega as colunas dos shape sempre que seleciona os shape
        self.dlg.select_layer.currentIndexChanged.connect(self.set_select_attributes)
        self.set_select_attributes()

        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:
            # Do something useful here - delete the line containing pass and
            # substitute with your code.

            listcom = []
            
            # Seleciona Somente o Shape que foi escolhido
            for selectlayer in QgsProject.instance().mapLayers().values():
                if selectlayer.name() == self.dlg.select_layer.currentText():
                    coluna = self.dlg.coluna.currentText()
                    lay = selectlayer
                    sRs = lay.crs()
                    provider = lay.dataProvider()
                    n_new_feats = 0
                    for i in lay.getFeatures():
                        geomVerif = i.geometry()
                        print(i.geometry())
                        print(i.attributes())
                        geomSingleType = QgsWkbTypes.isSingleType(geomVerif.wkbType())
                        if not geomSingleType:
                            geomFeature = geomVerif.asGeometryCollection()
                    
                    if not geomSingleType:
                        
                        a_list = []
                        vlayer = QgsVectorLayer("LineString?", "vlayer", "memory" )
                        pr = vlayer.dataProvider()
                        for feature in lay.getFeatures():
                            geomMult = feature.geometry()
                            a_list.append(feature[coluna])

                            if geomMult.isMultipart():                             
                                geom_list = geomMult.asMultiPolyline()

                                listTeste = []
                                for single_geom_list in geom_list:
                                    corrdsList = []
                                    for coords in single_geom_list: 
                                        corrdsList.append(QgsPoint(coords)) 
                                    single_feature = QgsFeature()
                                    single_geom = QgsGeometry.fromPolyline(corrdsList)

                                    single_feature.setGeometry(single_geom)
                                    pr.addFeature(single_feature)
                        vlayer.updateExtents()
                    if geomSingleType:
                        for f in lay.getFeatures():
                            nome = f[coluna]
                            geom = f.geometry()
                            wkb = geom.asWkb()
                            geom_ogr = ogr.CreateGeometryFromWkb(wkb)
                            vertices = geom.asPolyline()
                

                            n = len(vertices) - 1

                            xi = geom_ogr.GetX(0)
                            yi = geom_ogr.GetY(0)
                            zi = geom_ogr.GetZ(0)

                            xf = geom_ogr.GetX(n)
                            yf = geom_ogr.GetY(n)
                            zf = geom_ogr.GetZ(n)
                                
                            if geom_ogr.GetZ(0) == geom_ogr.GetZ(n):
                                list = [xi,yi,zi,nome,'Inicio']
                                listcom.append(list)
                                list2 = [xf,yf,zf,nome,'Fim']
                                listcom.append(list2)

                            elif geom_ogr.GetZ(0) < geom_ogr.GetZ(n): 
                                list3 = [xi,yi,zi,nome,'Fim']
                                listcom.append(list3)
                                list4 = [xf,yf,zf,nome,'Inicio']
                                listcom.append(list4)

                            elif geom_ogr.GetZ(0) > geom_ogr.GetZ(n):
                                list5 = [xi,yi,zi,nome,'Inicio']
                                listcom.append(list5)
                                list6 = [xf,yf,zf,nome,'Fim']
                                listcom.append(list6)
                    else :
                        for f in vlayer.getFeatures():
                            nome = a_list[n_new_feats]
                            geom = f.geometry()
                            wkb = geom.asWkb()
                            geom_ogr = ogr.CreateGeometryFromWkb(wkb)
                            vertices = geom.asPolyline()
                

                            n = len(vertices) - 1

                            xi = geom_ogr.GetX(0)
                            yi = geom_ogr.GetY(0)
                            zi = geom_ogr.GetZ(0)

                            xf = geom_ogr.GetX(n)
                            yf = geom_ogr.GetY(n)
                            zf = geom_ogr.GetZ(n)
                                
                            if geom_ogr.GetZ(0) == geom_ogr.GetZ(n):
                                list = [xi,yi,zi,nome,'Inicio']
                                listcom.append(list)
                                list2 = [xf,yf,zf,nome,'Fim']
                                listcom.append(list2)

                            elif geom_ogr.GetZ(0) < geom_ogr.GetZ(n): 
                                list3 = [xi,yi,zi,nome,'Fim']
                                listcom.append(list3)
                                list4 = [xf,yf,zf,nome,'Inicio']
                                listcom.append(list4)

                            elif geom_ogr.GetZ(0) > geom_ogr.GetZ(n):
                                list5 = [xi,yi,zi,nome,'Inicio']
                                listcom.append(list5)
                                list6 = [xf,yf,zf,nome,'Fim']
                                listcom.append(list6)
                            n_new_feats += 1
            listfinal = []
            listverif = []
            
            v = 0


            for s in listcom:
                valorXY = [listcom[v][0],listcom[v][1]]
                listverif.append(valorXY)
                v += 1
            
            for d in listverif:
                rX1 = d[0]
                rY1 = d[1]
                resultado = 0
                for resp in listverif:
                    rX2 = resp[0]
                    rY2 = resp[1]
                    if rX1 == rX2 and rY1 == rY2:
                        resultado += 1

                tfinal = 0
                for j in listfinal:
                    if j[0] == d[0] and j[1] == d[1]:
                        tfinal = 1
                if tfinal == 0 :
                    if resultado == 1:
                        for verifin in listcom:
                            if verifin[0] == d[0] and verifin[1] == d[1]:
                                listfinal.append(verifin)
                    else :
                    
                        v2 = 0
                        Listrio = []
                        
                        for verif in listcom:
                            if verif[0] == d[0] and verif[1] == d[1]:
                                altitude = verif[2]
                                nome_rio = verif[3]
                                Listrio.append(nome_rio)
                                riofinal = verif[3]

                        riot = 0
                        for rio in Listrio:
                            riot = 0
                            for riofin in Listrio:
                                if rio == riofin :
                                    riot += 1
                            if riot == 2:
                                if rio != '' or rio != None:
                                    riofinal = rio
                        valorfinal = [d[0],d[1],altitude,riofinal,'Confluencia']                        
                        del Listrio
                        listfinal.append(valorfinal)


            self.Fields = QgsFields()
            self.Fields.append(QgsField('id',QVariant.Int))
            self.Fields.append(QgsField('nome',QVariant.String))
            self.Fields.append(QgsField('situacao',QVariant.String))

            global SHPCaminho
            SHPCaminho = self.outFilePath
            self.outputPointsShape = QgsVectorFileWriter(SHPCaminho, self.encoding, self.Fields, QgsWkbTypes.Point, sRs, "ESRI Shapefile")
            idX = 1
            for final in listfinal:
                self.fetf = QgsFeature()
                zPoint = QgsPoint(final[0], final[1], final[2])
                zPoint.z()
                self.fetf.setGeometry( QgsGeometry( zPoint ) )
                self.fetf.setAttributes([idX, final[3], final[4]] )
                self.outputPointsShape.addFeature(self.fetf)
                idX += 1
            
            pegarNome = self.outFilePath
            Nomes = pegarNome.split( '/' )
            contNomes = len(Nomes) - 1
            nomefinalshp = Nomes[contNomes]
            nomefinalshp =  nomefinalshp.replace('.shp','')
            nomefinalshp =  nomefinalshp.replace('.SHP','')
            #self.iface.addVectorLayer(self.outFilePath, nomefinalshp, 'ogr')
            self.layer = QgsVectorLayer(self.outFilePath, nomefinalshp, "ogr")
            if not self.layer.isValid():
                raise ValueError("Failed to open the layer")
            self.canvas = QgsMapCanvas()
            QgsProject.instance().addMapLayer(self.layer)
            self.canvas.setExtent(self.layer.extent())
            self.canvas.setLayers([self.layer])
            del self.outputPointsShape
            QgsProject.instance().removeMapLayer(self.layer)
            self.layer = QgsVectorLayer(self.outFilePath, nomefinalshp, "ogr")
            QgsProject.instance().addMapLayer(self.layer)