Ejemplo n.º 1
0
    def decimetritzar_lines(self):
        """ Edit the lines' geometry in order to round the endpoint's coordinates decimals """
        with edit(self.line_layer):
            for line in self.line_layer.getFeatures():
                tram = line.geometry().asMultiPolyline()
                verts = tram[0]
                # Comprovar si el primer i últim vertex del tram ja estan decimetritzats i per tant no s'han
                # de decimetritzar
                first_vert_decim, last_vert_decim = self.check_tram_decimals(
                    verts)
                if first_vert_decim and last_vert_decim:
                    continue
                first_vertex = verts[0]
                last_vertex = verts[-1]
                if len(verts) > 2:
                    if first_vert_decim and not last_vert_decim:
                        tram_vertex = verts[:-1]
                    elif not first_vert_decim and last_vert_decim:
                        tram_vertex = verts[1:]
                    else:
                        tram_vertex = verts[1:-1]
                # Round first and last vertex
                # First
                if not first_vert_decim:
                    first_coord_x = first_vertex.x()
                    first_coord_y = first_vertex.y()
                    first_x, first_y = round_coordinates(
                        first_coord_x, first_coord_y)
                    rounded_first_vert = QgsPointXY(first_x, first_y)
                # Last
                if not last_vert_decim:
                    last_coord_x = last_vertex.x()
                    last_coord_y = last_vertex.y()
                    last_x, last_y = round_coordinates(last_coord_x,
                                                       last_coord_y)
                    rounded_last_vert = QgsPointXY(last_x, last_y)
                # Create new geometry
                if len(verts) > 2:
                    if not first_vert_decim:
                        tram_vertex.insert(0, rounded_first_vert)
                    if not last_vert_decim:
                        tram_vertex.insert(len(tram_vertex), rounded_last_vert)
                    rounded_geom = QgsGeometry.fromMultiPolylineXY(
                        [tram_vertex])
                else:
                    pairs_vertex = [rounded_first_vert, rounded_last_vert]
                    rounded_geom = QgsGeometry.fromMultiPolylineXY(
                        [pairs_vertex])

                # Set new geometry
                self.line_layer.changeGeometry(line.id(), rounded_geom)
Ejemplo n.º 2
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.PrmInputLayer,
                                        context)
        srcCRS = source.sourceCrs()

        (sink, dest_id) = self.parameterAsSink(parameters, self.PrmOutputLayer,
                                               context, source.fields(),
                                               QgsWkbTypes.MultiLineString,
                                               srcCRS)

        # Set up CRS transformations
        if srcCRS != epsg4326:
            geomTo4326 = QgsCoordinateTransform(srcCRS, epsg4326,
                                                QgsProject.instance())
            toSinkCrs = QgsCoordinateTransform(epsg4326, srcCRS,
                                               QgsProject.instance())

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

        iterator = source.getFeatures()
        for cnt, feature in enumerate(iterator):
            if feedback.isCanceled():
                break
            try:
                if feature.geometry().isMultipart():
                    seg = feature.geometry().asMultiPolyline()
                else:
                    seg = [feature.geometry().asPolyline()]
                numseg = len(seg)
                if numseg < 1 or len(seg[0]) < 2:
                    continue

                outseg = []
                for pts in seg:
                    if srcCRS != epsg4326:
                        for x, pt in enumerate(pts):
                            pts[x] = geomTo4326.transform(pt)
                    normalizeLongitude(pts)
                    newseg = checkIdlCrossings(pts)
                    outseg.extend(newseg)
                if srcCRS != epsg4326:  # Convert each point to the output CRS
                    for y in range(len(outseg)):
                        for x, pt in enumerate(outseg[y]):
                            outseg[y][x] = toSinkCrs.transform(pt)

                f = QgsFeature()
                f.setGeometry(QgsGeometry.fromMultiPolylineXY(outseg))
                f.setAttributes(feature.attributes())
                sink.addFeature(f)

            except Exception:
                '''s = traceback.format_exc()
                feedback.pushInfo(s)'''
                pass

            if cnt % 100 == 0:
                feedback.setProgress(int(cnt * total))

        return {self.PrmOutputLayer: dest_id}
def _swap_qgs_geometry(qgsgeom):
    if qgsgeom.wkbType() == QgsWkbTypes.Point:
        p = qgsgeom.asPoint()
        qgsgeom = QgsGeometry.fromPointXY(QgsPointXY(p[1], p[0]))
    elif qgsgeom.wkbType() == QgsWkbTypes.MultiPoint:
        mp = qgsgeom.asMultiPoint()
        qgsgeom = QgsGeometry.fromMultiPointXY(
            [QgsPointXY(p[1], p[0]) for p in mp])
    elif qgsgeom.wkbType() == QgsWkbTypes.LineString:
        pl = qgsgeom.asPolyline()
        qgsgeom = QgsGeometry.fromPolylineXY(
            [QgsPointXY(p[1], p[0]) for p in pl])
    elif qgsgeom.wkbType() == QgsWkbTypes.MultiLineString:
        mls = qgsgeom.asMultiPolyline()
        qgsgeom = QgsGeometry.fromMultiPolylineXY(
            [[QgsPointXY(p[1], p[0]) for p in pl] for pl in mls])
    elif qgsgeom.wkbType() == QgsWkbTypes.Polygon:
        pl = qgsgeom.asPolygon()
        qgsgeom = QgsGeometry.fromPolygonXY(
            [[QgsPointXY(p[1], p[0]) for p in r] for r in pl])
    elif qgsgeom.wkbType() == QgsWkbTypes.MultiPolygon:
        mp = qgsgeom.asMultiPolygon()
        qgsgeom = QgsGeometry.fromMultiPolygonXY(
            [[[QgsPointXY(p[1], p[0]) for p in r] for r in pl] for pl in mp])
    return qgsgeom
Ejemplo n.º 4
0
 def testQgsMultilineStringRepr(self):
     ml = QgsGeometry.fromMultiPolylineXY(
         [
             [QgsPointXY(0, 0), QgsPointXY(1, 0), QgsPointXY(1, 1), QgsPointXY(2, 1), QgsPointXY(2, 0), ],
             [QgsPointXY(3, 0), QgsPointXY(3, 1), QgsPointXY(5, 1), QgsPointXY(5, 0), QgsPointXY(6, 0), ]
         ]
     )
     self.assertEqual(ml.constGet().__repr__(), '<QgsMultiLineString: MultiLineString ((0 0, 1 0, 1 1, 2 1, 2 0),(3 0, 3 1, 5 1, 5 0, 6 0))>')
Ejemplo n.º 5
0
 def TestQgsMultilineStringRepr(self):
     ml = QgsGeometry.fromMultiPolylineXY(
         [
             [QgsPointXY(0, 0), QgsPointXY(1, 0), QgsPointXY(1, 1), QgsPointXY(2, 1), QgsPointXY(2, 0), ],
             [QgsPointXY(3, 0), QgsPointXY(3, 1), QgsPointXY(5, 1), QgsPointXY(5, 0), QgsPointXY(6, 0), ]
         ]
     )
     self.assertEqual(ml.constGet().__repr__(), '<QgsMultiLineString: MultiLineString ((0 0, 1 0, 1 1, 2 1, 2 0),(3 0, 3 1, 5 1, 5 0, 6 0))>')
Ejemplo n.º 6
0
 def reprojectPoints(self, geom, xform):
     if geom.type() == 0:  #Point
         if geom.isMultipart():
             pnts = geom.asMultiPoint()
             newPnts = []
             for pnt in pnts:
                 newPnts += [xform.transform(pnt)]
             newGeom = QgsGeometry.fromMultiPointXY(newPnts)
             return newGeom
         else:
             pnt = geom.asPoint()
             newPnt = xform.transform(pnt)
             newGeom = QgsGeometry.fromPointXY(newPnt)
             return newGeom
     elif geom.type() == 1:  #Line
         if geom.isMultipart():
             linhas = geom.asMultiPolyline()
             newLines = []
             for linha in linhas:
                 newLine = []
                 for pnt in linha:
                     newLine += [xform.transform(pnt)]
                 newLines += [newLine]
             newGeom = QgsGeometry.fromMultiPolylineXY(newLines)
             return newGeom
         else:
             linha = geom.asPolyline()
             newLine = []
             for pnt in linha:
                 newLine += [xform.transform(pnt)]
             newGeom = QgsGeometry.fromPolylineXY(newLine)
             return newGeom
     elif geom.type() == 2:  #Polygon
         if geom.isMultipart():
             poligonos = geom.asMultiPolygon()
             newPolygons = []
             for pol in poligonos:
                 newPol = []
                 for anel in pol:
                     newAnel = []
                     for pnt in anel:
                         newAnel += [xform.transform(pnt)]
                     newPol += [newAnel]
                 newPolygons += [newPol]
             newGeom = QgsGeometry.fromMultiPolygonXY(newPolygons)
             return newGeom
         else:
             pol = geom.asPolygon()
             newPol = []
             for anel in pol:
                 newAnel = []
                 for pnt in anel:
                     newAnel += [xform.transform(pnt)]
                 newPol += [newAnel]
             newGeom = QgsGeometry.fromPolygonXY(newPol)
             return newGeom
     else:
         return None
Ejemplo n.º 7
0
 def flipFeature(self, layer, feature, geomType=None, refreshCanvas=False):
     """
     Inverts the flow from a given feature. THE GIVEN FEATURE IS ALTERED. Standard behaviour is to not
     refresh canvas map.
     :param layer: layer containing the target feature for flipping.
     :param feature: feature to be flipped.
     :param geomType: if layer geometry type is not given, it'll calculate it (0,1 or 2)
     :param refreshCanvas: indicates whether the canvas should be refreshed after flipping feature.
     :returns: flipped feature as of [layer, feature, geometry_type].
     """
     if not geomType:
         geomType = layer.geometryType()
     # getting whether geometry is multipart or not
     # features not yet commited to layer always have SINGLE geometry
     isMulti = QgsWkbTypes.isMultiType(int(
         layer.wkbType())) and feature.id() > 0
     geom = feature.geometry()
     if geomType == 0:
         if isMulti:
             nodes = geom.asMultiPoint()
             # inverting the point list by parts
             for idx, part in enumerate(nodes):
                 nodes[idx] = part[::-1]
             # setting flipped geometry
             flippedFeatureGeom = QgsGeometry.fromMultiPointXY(nodes)
         else:
             # inverting the point list
             nodes = geom.asPoint()
             nodes = nodes[::-1]
             flippedFeatureGeom = QgsGeometry.fromPoint(nodes)
     elif geomType == 1:
         if isMulti:
             nodes = geom.asMultiPolyline()
             for idx, part in enumerate(nodes):
                 nodes[idx] = part[::-1]
             flippedFeatureGeom = QgsGeometry.fromMultiPolylineXY(nodes)
         else:
             nodes = geom.asPolyline()
             nodes = nodes[::-1]
             flippedFeatureGeom = QgsGeometry.fromPolylineXY(nodes)
     elif geomType == 2:
         if isMulti:
             nodes = geom.asMultiPolygon()
             for idx, part in enumerate(nodes):
                 nodes[idx] = part[::-1]
             flippedFeatureGeom = QgsGeometry.fromMultiPolygonXY(nodes)
         else:
             nodes = geom.asPolygon()
             nodes = nodes[::-1]
             flippedFeatureGeom = QgsGeometry.fromPolygonXY(nodes)
     # setting feature geometry to the flipped one
     # feature.setGeometry(flippedFeatureGeom)
     # layer.updateFeature(feature)
     layer.changeGeometry(feature.id(), flippedFeatureGeom)
     if refreshCanvas:
         self.iface.mapCanvas().refresh()
     return [layer, feature, geomType]
Ejemplo n.º 8
0
    def testAddFeatures(self):
        # test adding features to an edit buffer
        layer = createEmptyLayer()
        self.assertTrue(layer.startEditing())

        self.assertEqual(layer.editBuffer().addedFeatures(), {})
        self.assertEqual(layer.editBuffer().allAddedOrEditedFeatures(), [])
        self.assertFalse(layer.editBuffer().isFeatureAdded(1))
        self.assertFalse(layer.editBuffer().isFeatureAdded(3))

        # add two features
        f1 = QgsFeature(layer.fields(), 1)
        f1.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(1, 2)))
        f1.setAttributes(["test", 123])
        self.assertTrue(layer.addFeature(f1))

        f2 = QgsFeature(layer.fields(), 2)
        f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(2, 4)))
        f2.setAttributes(["test2", 246])

        self.assertTrue(layer.addFeature(f2))

        # test contents of buffer
        added = layer.editBuffer().addedFeatures()
        new_feature_ids = list(added.keys())
        self.assertEqual(added[new_feature_ids[0]]['fldtxt'], 'test2')
        self.assertEqual(added[new_feature_ids[0]]['fldint'], 246)
        self.assertEqual(added[new_feature_ids[1]]['fldtxt'], 'test')
        self.assertEqual(added[new_feature_ids[1]]['fldint'], 123)

        self.assertTrue(layer.editBuffer().isFeatureAdded(new_feature_ids[0]))
        self.assertTrue(layer.editBuffer().isFeatureAdded(new_feature_ids[1]))
        self.assertCountEqual(layer.editBuffer().allAddedOrEditedFeatures(),
                              [new_feature_ids[0], new_feature_ids[1]])

        # check if error in case adding not adaptable geometry
        # eg. a Multiline in a Line
        layer = createEmptyLinestringLayer()
        self.assertTrue(layer.startEditing())

        self.assertEqual(layer.editBuffer().addedFeatures(), {})
        self.assertFalse(layer.editBuffer().isFeatureAdded(1))
        self.assertFalse(layer.editBuffer().isFeatureAdded(3))
        self.assertEqual(layer.editBuffer().allAddedOrEditedFeatures(), [])

        # add a features with a multi line geometry of not touched lines =>
        # cannot be forced to be linestring
        multiline = [
            [QgsPointXY(1, 1), QgsPointXY(2, 2)],
            [QgsPointXY(3, 3), QgsPointXY(4, 4)],
        ]
        f1 = QgsFeature(layer.fields(), 1)
        f1.setGeometry(QgsGeometry.fromMultiPolylineXY(multiline))
        f1.setAttributes(["test", 123])
        self.assertTrue(layer.addFeatures([f1]))
        self.assertFalse(layer.commitChanges())
Ejemplo n.º 9
0
    def toQgsGeometry(self):
        count = len(self.lines)
        if count > 1:
            lines = [lineToQgsPolyline(line) for line in self.lines]
            return QgsGeometry.fromMultiPolylineXY(lines)

        if count == 1:
            return QgsGeometry.fromPolylineXY(lineToQgsPolyline(self.lines[0]))

        return QgsGeometry()
Ejemplo n.º 10
0
    def accept(self):
        try:
            distance = float(self.distLineEdit.text())
            azimuth = float(self.azimuthLineEdit.text())
            units = self.unitsComboBox.currentIndex()  # 0 km, 1 m, 2 nm, 3 miles, 4 yards, 5 ft, 6 inches, 7 cm
            start = self.checkBox.isChecked()
        except Exception:
            self.iface.messageBar().pushMessage("", tr("Either distance or azimuth were invalid"), level=Qgis.Warning, duration=4)
            return
        layer = self.iface.activeLayer()
        if layer is None:
            self.iface.messageBar().pushMessage("", tr("No point or line layer selected"), level=Qgis.Warning, duration=4)
            return

        measureFactor = conversionToMeters(units)

        distance = distance * measureFactor
        pt = self.pt
        destCRS = layer.crs()
        transform = QgsCoordinateTransform(epsg4326, destCRS, QgsProject.instance())
        if layer.wkbType() == QgsWkbTypes.Point:
            g = geod.Direct(pt.y(), pt.x(), azimuth, distance, Geodesic.LATITUDE | Geodesic.LONGITUDE)
            if start:
                ptStart = transform.transform(self.pt.x(), self.pt.y())
                feat = QgsFeature(layer.fields())
                feat.setGeometry(QgsGeometry.fromPointXY(ptStart))
                layer.addFeature(feat)
            pt = transform.transform(g['lon2'], g['lat2'])
            feat = QgsFeature(layer.fields())
            feat.setGeometry(QgsGeometry.fromPointXY(pt))
            layer.addFeature(feat)
        else:  # It will either be a LineString or MultiLineString
            maxseglen = settings.maxSegLength * 1000.0  # Needs to be in meters
            maxSegments = settings.maxSegments
            gline = geod.Line(pt.y(), pt.x(), azimuth)
            n = int(math.ceil(distance / maxseglen))
            if n > maxSegments:
                n = maxSegments
            seglen = distance / n
            pts = []
            for i in range(0, n + 1):
                s = seglen * i
                g = gline.Position(s, Geodesic.LATITUDE | Geodesic.LONGITUDE | Geodesic.LONG_UNROLL)
                ptc = transform.transform(g['lon2'], g['lat2'])
                pts.append(ptc)
            feat = QgsFeature(layer.fields())
            if layer.wkbType() == QgsWkbTypes.LineString:
                feat.setGeometry(QgsGeometry.fromPolylineXY(pts))
            else:
                feat.setGeometry(QgsGeometry.fromMultiPolylineXY([pts]))
            layer.addFeatures([feat])

        layer.updateExtents()
        self.iface.mapCanvas().refresh()
        self.close()
Ejemplo n.º 11
0
    def toQgsGeometry(self):
        count = len(self.lines)
        if count > 1:
            lines = [[QgsPointXY(x, y) for x, y, z in line] for line in self.lines]
            return QgsGeometry.fromMultiPolylineXY(lines)

        if count == 1:
            pts = [QgsPointXY(x, y) for x, y, z in self.lines[0]]
            return QgsGeometry.fromPolylineXY(pts)

        return QgsGeometry()
Ejemplo n.º 12
0
    def testAddFeatures(self):
        # test adding features to an edit buffer
        layer = createEmptyLayer()
        self.assertTrue(layer.startEditing())

        self.assertEqual(layer.editBuffer().addedFeatures(), {})
        self.assertFalse(layer.editBuffer().isFeatureAdded(1))
        self.assertFalse(layer.editBuffer().isFeatureAdded(3))

        # add two features
        f1 = QgsFeature(layer.fields(), 1)
        f1.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(1, 2)))
        f1.setAttributes(["test", 123])
        self.assertTrue(layer.addFeature(f1))

        f2 = QgsFeature(layer.fields(), 2)
        f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(2, 4)))
        f2.setAttributes(["test2", 246])

        self.assertTrue(layer.addFeature(f2))

        # test contents of buffer
        added = layer.editBuffer().addedFeatures()
        new_feature_ids = list(added.keys())
        self.assertEqual(added[new_feature_ids[0]]['fldtxt'], 'test2')
        self.assertEqual(added[new_feature_ids[0]]['fldint'], 246)
        self.assertEqual(added[new_feature_ids[1]]['fldtxt'], 'test')
        self.assertEqual(added[new_feature_ids[1]]['fldint'], 123)

        self.assertTrue(layer.editBuffer().isFeatureAdded(new_feature_ids[0]))
        self.assertTrue(layer.editBuffer().isFeatureAdded(new_feature_ids[1]))

        # check if error in case adding not adaptable geometry
        # eg. a Multiline in a Line
        layer = createEmptyLinestringLayer()
        self.assertTrue(layer.startEditing())

        self.assertEqual(layer.editBuffer().addedFeatures(), {})
        self.assertFalse(layer.editBuffer().isFeatureAdded(1))
        self.assertFalse(layer.editBuffer().isFeatureAdded(3))

        # add a features with a multi line geometry of not touched lines =>
        # cannot be forced to be linestring
        multiline = [
            [QgsPointXY(1, 1), QgsPointXY(2, 2)],
            [QgsPointXY(3, 3), QgsPointXY(4, 4)],
        ]
        f1 = QgsFeature(layer.fields(), 1)
        f1.setGeometry(QgsGeometry.fromMultiPolylineXY(multiline))
        f1.setAttributes(["test", 123])
        self.assertTrue(layer.addFeatures([f1]))
        self.assertFalse(layer.commitChanges())
Ejemplo n.º 13
0
 def testMeasureMultiLine(self):
     #   +-+ +-+-+
     #   | | |   |
     # +-+ + +   +-+
     linestring = QgsGeometry.fromMultiPolylineXY(
         [
             [QgsPointXY(0, 0), QgsPointXY(1, 0), QgsPointXY(1, 1), QgsPointXY(2, 1), QgsPointXY(2, 0), ],
             [QgsPointXY(3, 0), QgsPointXY(3, 1), QgsPointXY(5, 1), QgsPointXY(5, 0), QgsPointXY(6, 0), ]
         ]
     )
     da = QgsDistanceArea()
     length = da.measureLength(linestring)
     myMessage = ('Expected:\n%f\nGot:\n%f\n' %
                  (9, length))
     assert length == 9, myMessage
Ejemplo n.º 14
0
 def create_path_feature_from_Multipolyline(MultipolyLine, ID, flux,
                                            roadType, fields):
     # We create the geometry of the polyline
     polyline = QgsGeometry.fromMultiPolylineXY(MultipolyLine)
     # We retrieve the fields and add them to the feature
     feature = QgsFeature(fields)
     id_index = feature.fieldNameIndex("id")
     feature.setAttribute(id_index, ID)
     flux_index = feature.fieldNameIndex("flux")
     feature.setAttribute(flux_index, flux)
     road_type_index = feature.fieldNameIndex("road_type")
     feature.setAttribute(road_type_index, roadType)
     # We add the geometry to the feature
     feature.setGeometry(polyline)
     return feature
Ejemplo n.º 15
0
 def testMeasureMultiLine(self):
     #   +-+ +-+-+
     #   | | |   |
     # +-+ + +   +-+
     linestring = QgsGeometry.fromMultiPolylineXY(
         [
             [QgsPointXY(0, 0), QgsPointXY(1, 0), QgsPointXY(1, 1), QgsPointXY(2, 1), QgsPointXY(2, 0), ],
             [QgsPointXY(3, 0), QgsPointXY(3, 1), QgsPointXY(5, 1), QgsPointXY(5, 0), QgsPointXY(6, 0), ]
         ]
     )
     da = QgsDistanceArea()
     length = da.measureLength(linestring)
     myMessage = ('Expected:\n%f\nGot:\n%f\n' %
                  (9, length))
     assert length == 9, myMessage
Ejemplo n.º 16
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])
Ejemplo n.º 17
0
 def contours_ind(self, grille, p, q, s, novalue, mini, maxi, ll,
                  pixel_size_x, pixel_size_y, nx, ny, poles_dict):
     p1 = ll[0] + (p) * pixel_size_x
     p2 = ll[0] + (p + 1) * pixel_size_x
     q1 = ll[1] + (q) * pixel_size_y
     q2 = ll[1] + (q + 1) * pixel_size_y
     ligne1 = QgsGeometry.fromMultiPolylineXY([[
         QgsPointXY(p1, q1),
         QgsPointXY(p2, q1),
         QgsPointXY(p2, q2),
         QgsPointXY(p1, q2),
         QgsPointXY(p1, q1)
     ]])
     f1 = QgsFeature()
     f1.setAttributes([poles_dict[str(int(grille[p][q]))]])
     f1.setGeometry(ligne1)
     self.polys[poles_dict[str(int(grille[p][q]))], p,
                q] = [f1.geometry().asMultiPolyline()]
Ejemplo n.º 18
0
 def find_geometry(self, g):
     if self.output_type == "Poly":
         stat = g.area()
         if g.isMultipart():
             geometry = QgsGeometry.fromMultiPolygonXY(g.asMultiPolygon())
         else:
             geometry = QgsGeometry.fromPolygonXY(g.asPolygon())
     elif self.output_type == "Line":
         stat = g.length()
         if g.isMultipart():
             geometry = QgsGeometry.fromMultiPolylineXY(g.asMultiPolyLine())
         else:
             geometry = QgsGeometry.fromPolyline(g.asPoly())
     else:
         stat = 1
         if g.isMultipart():
             geometry = QgsGeometry.fromMultiPointXY(g.asMultiPoint())
         else:
             geometry = QgsGeometry.fromPointXY(g.asPoint())
     return geometry, stat
def _swap_qgs_geometry(qgsgeom):
    if qgsgeom.wkbType() == QgsWkbTypes.Point:
        p = qgsgeom.asPoint()
        qgsgeom = QgsGeometry.fromPointXY(QgsPointXY(p[1], p[0]))
    elif qgsgeom.wkbType() == QgsWkbTypes.MultiPoint:
        mp = qgsgeom.asMultiPoint()
        qgsgeom = QgsGeometry.fromMultiPointXY([QgsPointXY(p[1], p[0]) for p in mp])
    elif qgsgeom.wkbType() == QgsWkbTypes.LineString:
        pl = qgsgeom.asPolyline()
        qgsgeom = QgsGeometry.fromPolylineXY([QgsPointXY(p[1],p[0]) for p in pl])
    elif qgsgeom.wkbType() == QgsWkbTypes.MultiLineString:
        mls = qgsgeom.asMultiPolyline()
        qgsgeom = QgsGeometry.fromMultiPolylineXY([[QgsPointXY(p[1],p[0]) for p in pl] for pl in mls])
    elif qgsgeom.wkbType() == QgsWkbTypes.Polygon:
        pl = qgsgeom.asPolygon()
        qgsgeom = QgsGeometry.fromPolygonXY([[QgsPointXY(p[1],p[0]) for p in r] for r in pl])
    elif qgsgeom.wkbType() == QgsWkbTypes.MultiPolygon:
        mp = qgsgeom.asMultiPolygon()
        qgsgeom = QgsGeometry.fromMultiPolygonXY([[[QgsPointXY(p[1],p[0]) for p in r] for r in pl] for pl in mp])
    return qgsgeom
Ejemplo n.º 20
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)
Ejemplo n.º 21
0
 def paint_model_division(self):
     if self.rect_Params is None:
         return
     if self.divisions:
         self.canvas.scene().removeItem(self.divisions)
         self.divisions = []
     x_models = int(self.ui.ColPartsSpinBox.value())
     y_models = int(self.ui.RowPartsSpinBox.value())
     points = getPointsFromRectangleParams(self.rect_Params)
     lines = []
     if y_models > 1:
         model_height = self.rect_Params["height"] / y_models
         custRot = self.rect_Params['rotation'] - math.pi * 0.5
         for i in range(1, y_models):
             p1 = getPolarPoint(points[0][0], points[0][1], custRot,
                                model_height * i)
             p2 = getPolarPoint(points[1][0], points[1][1], custRot,
                                model_height * i)
             lines.append(
                 [QgsPointXY(p1[0], p1[1]),
                  QgsPointXY(p2[0], p2[1])])
     if x_models > 1:
         model_width = self.rect_Params["width"] / x_models
         for i in range(1, x_models):
             p1 = getPolarPoint(points[3][0], points[3][1],
                                self.rect_Params['rotation'],
                                model_width * i)
             p2 = getPolarPoint(points[0][0], points[0][1],
                                self.rect_Params['rotation'],
                                model_width * i)
             lines.append(
                 [QgsPointXY(p1[0], p1[1]),
                  QgsPointXY(p2[0], p2[1])])
     if lines:
         self.divisions = QgsRubberBand(self.canvas, False)
         self.divisions.setColor(QColor(227, 26, 28, 255))
         self.divisions.setWidth(3)
         self.divisions.setLineStyle(Qt.PenStyle(Qt.DashDotLine))
         self.divisions.setToGeometry(
             QgsGeometry.fromMultiPolylineXY(lines), None)
Ejemplo n.º 22
0
 def getSegmentDict(self, lineLyr):
     segmentDict = dict()
     geomList = []
     if lineLyr.featureCount() > 0:
         toLineAlias = lambda geom : geom.asMultiPolyline()[0] if next(lineLyr.getFeatures()).geometry().isMultipart() \
                         else geom.asPolyline()
         fromLineAlias = lambda x : QgsGeometry.fromMultiPolylineXY([x]) if next(lineLyr.getFeatures()).geometry().isMultipart() \
                         else QgsGeometry.fromPolyline(x[0], x[1])
     for feat in lineLyr.getFeatures():
         geom = feat.geometry()
         if geom not in geomList:
             geomList.append(geom)
             lineList = toLineAlias(geom)
             if lineList[0] not in segmentDict:
                 segmentDict[lineList[0]] = []
             segmentDict[lineList[0]].append(
                 fromLineAlias([lineList[0], lineList[1]]))
             if lineList[-1] not in segmentDict:
                 segmentDict[lineList[-1]] = []
             segmentDict[lineList[-1]].append(
                 fromLineAlias([lineList[-1], lineList[-2]]))
     return segmentDict
Ejemplo n.º 23
0
    def getTree(self, node_id: str):
        """
        Does the work. Tracks the graph up- or downstream.
        :param node_id: The node from which the tracking should be started
        """
        QApplication.setOverrideCursor(Qt.WaitCursor)
        upstream = self.direction == "upstream"

        self.rubberBand.reset()

        nodes, edges = self.network_analyzer.getTree(node_id, upstream)
        polylines = self.network_analyzer.getEdgeGeometry([edge[2]['feature'] for edge in edges])

        # Fix for QGIS < 2.0
        filtered_polylines = [pl for pl in polylines if pl]

        self.rubberBand.addGeometry(QgsGeometry.fromMultiPolylineXY(filtered_polylines),
                                    self.network_analyzer.getNodeLayer())

        self.treeChanged.emit(nodes, edges)

        QApplication.restoreOverrideCursor()
Ejemplo n.º 24
0
 def inv_vertex_order(self, geom):
     if geom.type() == 1:  #Line
         if geom.isMultipart():
             linhas = geom.asMultiPolyline()
             newLines = []
             for linha in linhas:
                 newLine = linha[::-1]
                 newLines += [newLine]
             newGeom = QgsGeometry.fromMultiPolylineXY(newLines)
             return newGeom
         else:
             linha = geom.asPolyline()
             newLine = linha[::-1]
             newGeom = QgsGeometry.fromPolylineXY(newLine)
             return newGeom
     elif geom.type() == 2:  #Polygon
         if geom.isMultipart():
             poligonos = geom.asMultiPolygon()
             newPolygons = []
             for pol in poligonos:
                 newPol = []
                 for anel in pol:
                     newAnel = anel[::-1]
                     newPol += [newAnel]
                 newPolygons += [newPol]
             newGeom = QgsGeometry.fromMultiPolygonXY(newPolygons)
             return newGeom
         else:
             pol = geom.asPolygon()
             newPol = []
             for anel in pol:
                 newAnel = anel[::-1]
                 newPol += [newAnel]
             newGeom = QgsGeometry.fromPolygonXY(newPol)
             return newGeom
     else:
         return None
Ejemplo n.º 25
0
    def lineContourFeatures(self):
        x,y,z=self.data()
        levels = self.levels()
        usegrid=self.isGridded() and self._useGrid
        try:
            if usegrid:
                gx,gy,gz=self.gridContourData()
                cs = contour(gx, gy, gz, levels )
            else:
                trig,z=self.trigContourData()
                cs = tricontour(trig, z, levels )
        except:
            raise ContourGenerationError.fromException(sys.exc_info())

        fields = self.fields()
        zfield=self.zFieldName()
        dx,dy=self._origin
        for i, line in enumerate(cs.collections):
            level=float(cs.levels[i])
            glines = []
            try:
                for path in line.get_paths():
                    if len(path.vertices) > 1:
                        points=[QgsPointXY(x,y) for x,y in path.vertices]
                        glines.append(points)
                geom=QgsGeometry.fromMultiPolylineXY(glines)
                geom.translate(dx,dy)
                feat = QgsFeature(fields)
                feat.setGeometry(geom)
                feat['index']=i
                feat[zfield]=level
                feat['label']=self._levelLabel(level)
                yield feat
            except:
                message=sys.exc_info()[1]
                self._feedback.reportError(message)
Ejemplo n.º 26
0
    def lineContourFeatures(self):
        x,y,z=self.data()
        levels = self.levels()
        usegrid=self.isGridded() and self._useGrid
        try:
            if usegrid:
                gx,gy,gz=self.gridContourData()
                cs = contour(gx, gy, gz, levels )
            else:
                trig,z=self.trigContourData()
                cs = tricontour(trig, z, levels )
        except:
            raise ContourGenerationError.fromException(sys.exc_info())

        fields = self.fields()
        zfield=self.zFieldName()
        dx,dy=self._origin
        for i, line in enumerate(cs.collections):
            level=float(cs.levels[i])
            glines = []
            try:
                for path in line.get_paths():
                    if len(path.vertices) > 1:
                        points=[QgsPointXY(x,y) for x,y in path.vertices]
                        glines.append(points)
                geom=QgsGeometry.fromMultiPolylineXY(glines)
                geom.translate(dx,dy)
                feat = QgsFeature(fields)
                feat.setGeometry(geom)
                feat['index']=i
                feat[zfield]=level
                feat['label']=self._levelLabel(level)
                yield feat
            except:
                message=sys.exc_info()[1]
                self._feedback.reportError(message)
Ejemplo n.º 27
0
    def processAlgorithm(self, parameters, context, feedback):
        source = self.parameterAsSource(parameters, self.PrmInputLayer,
                                        context)
        shape_type = self.parameterAsInt(parameters, self.PrmShapeType,
                                         context)
        outer_col = self.parameterAsString(parameters,
                                           self.PrmOuterRadiusField, context)
        inner_col = self.parameterAsString(parameters,
                                           self.PrmInnerRadiusField, context)
        def_outer_radius = self.parameterAsDouble(parameters,
                                                  self.PrmDefaultOuterRadius,
                                                  context)
        def_inner_radius = self.parameterAsDouble(parameters,
                                                  self.PrmDefaultInnerRadius,
                                                  context)
        segments = self.parameterAsInt(parameters, self.PrmDrawingSegments,
                                       context)
        units = self.parameterAsInt(parameters, self.PrmUnitsOfMeasure,
                                    context)
        export_geom = self.parameterAsBool(parameters,
                                           self.PrmExportInputGeometry,
                                           context)

        measure_factor = conversionToMeters(units)

        def_inner_radius *= measure_factor
        def_outer_radius *= measure_factor

        pt_spacing = 360.0 / segments
        src_crs = source.sourceCrs()
        fields = source.fields()
        if export_geom:
            names = fields.names()
            name_x, name_y = settings.getGeomNames(names)
            fields.append(QgsField(name_x, QVariant.Double))
            fields.append(QgsField(name_y, QVariant.Double))
        if shape_type == 0:
            (sink,
             dest_id) = self.parameterAsSink(parameters, self.PrmOutputLayer,
                                             context, fields,
                                             QgsWkbTypes.Polygon, src_crs)
        else:
            (sink, dest_id) = self.parameterAsSink(parameters,
                                                   self.PrmOutputLayer,
                                                   context, fields,
                                                   QgsWkbTypes.MultiLineString,
                                                   src_crs)

        if src_crs != epsg4326:
            geom_to_4326 = QgsCoordinateTransform(src_crs, epsg4326,
                                                  QgsProject.instance())
            to_sink_crs = QgsCoordinateTransform(epsg4326, src_crs,
                                                 QgsProject.instance())

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

        iterator = source.getFeatures()
        num_bad = 0
        for cnt, feature in enumerate(iterator):
            if feedback.isCanceled():
                break
            try:
                pts_in = []
                pts_out = []
                pt = feature.geometry().asPoint()
                pt_orig_x = pt.x()
                pt_orig_y = pt.y()
                # make sure the coordinates are in EPSG:4326
                if src_crs != epsg4326:
                    pt = geom_to_4326.transform(pt.x(), pt.y())
                lat = pt.y()
                lon = pt.x()
                if inner_col:
                    inner_radius = float(feature[inner_col]) * measure_factor
                else:
                    inner_radius = def_inner_radius
                if outer_col:
                    outer_radius = float(feature[outer_col]) * measure_factor
                else:
                    outer_radius = def_outer_radius
                angle = 0
                while angle < 360:
                    if inner_radius != 0:
                        g = geod.Direct(lat, lon, angle, inner_radius,
                                        Geodesic.LATITUDE | Geodesic.LONGITUDE)
                        pts_in.append(QgsPointXY(g['lon2'], g['lat2']))
                    g = geod.Direct(lat, lon, angle, outer_radius,
                                    Geodesic.LATITUDE | Geodesic.LONGITUDE)
                    pts_out.append(QgsPointXY(g['lon2'], g['lat2']))
                    angle += pt_spacing
                if inner_radius != 0:
                    pts_in.append(pts_in[0])
                pts_out.append(pts_out[0])
                crosses_idl = hasIdlCrossing(pts_out)
                if crosses_idl:
                    if inner_radius != 0:
                        makeIdlCrossingsPositive(pts_in, True)
                    makeIdlCrossingsPositive(pts_out, True)

                # If the Output crs is not 4326 transform the points to the proper crs
                if src_crs != epsg4326:
                    if inner_radius != 0:
                        for x, pt_out in enumerate(pts_in):
                            pts_in[x] = to_sink_crs.transform(pt_out)
                    for x, pt_out in enumerate(pts_out):
                        pts_out[x] = to_sink_crs.transform(pt_out)

                f = QgsFeature()
                if shape_type == 0:
                    if inner_radius == 0:
                        f.setGeometry(QgsGeometry.fromPolygonXY([pts_out]))
                    else:
                        f.setGeometry(
                            QgsGeometry.fromPolygonXY([pts_out, pts_in]))
                else:
                    if inner_radius == 0:
                        f.setGeometry(
                            QgsGeometry.fromMultiPolylineXY([pts_out]))
                    else:
                        f.setGeometry(
                            QgsGeometry.fromMultiPolylineXY([pts_out, pts_in]))
                attr = feature.attributes()
                if export_geom:
                    attr.append(pt_orig_x)
                    attr.append(pt_orig_y)
                f.setAttributes(attr)
                sink.addFeature(f)
            except Exception:
                num_bad += 1

            feedback.setProgress(int(cnt * total))

        if num_bad > 0:
            feedback.pushInfo(
                tr("{} out of {} features had invalid parameters and were ignored."
                   .format(num_bad, feature_count)))

        return {self.PrmOutputLayer: dest_id}
Ejemplo n.º 28
0
    def updateRubberGeom(self):
        if self.pA is None:
            return

        self.zoneWidth = self.pA.distance(self.pB)
        self.zoneDepth = self.pA.distance(self.pD)
        self.pM = QgsPointXY((self.pC.x() + self.pD.x()) / 2,
                             (self.pC.y() + self.pD.y()) / 2)
        self.d0 = self.pM.distance(self.pY)
        # self.widget.updateZ(self.pY)

        self.rb.setToGeometry(
            QgsGeometry.fromPolygonXY(
                [[self.pD, self.pA, self.pB, self.pC, self.pD]]))
        self.rbFoc.setToGeometry(
            QgsGeometry.fromPolylineXY([self.pD, self.pY, self.pC]))

        for p, rb in [
            [self.pA, self.rbPA],
            [self.pB, self.rbPB],
            [self.pC, self.rbPC],
            [self.pD, self.rbPD],
            [self.pY, self.rbPY],
            [self.pH, self.rbPH],
            [self.pL, self.rbPL],
        ]:
            rb.setToGeometry(QgsGeometry.fromPointXY(p))

        leftEdge = (QgsGeometry.fromPolylineXY([
            self.pA, self.pD
        ]).densifyByCount(self.widget.rowCount.value() - 1).asPolyline())
        rightEdge = (QgsGeometry.fromPolylineXY([
            self.pB, self.pC
        ]).densifyByCount(self.widget.rowCount.value() - 1).asPolyline())

        # Plot edges lines
        polyline = list(zip(leftEdge, rightEdge))

        backSide = (QgsGeometry.fromPolylineXY([
            self.pA, self.pB
        ]).densifyByCount(self.widget.columnCount.value() - 1).asPolyline())
        frontSide = (QgsGeometry.fromPolylineXY([
            self.pD, self.pC
        ]).densifyByCount(self.widget.columnCount.value() - 1).asPolyline())
        polylineX = list(zip(frontSide[:], backSide[:]))

        self.finalWidth = self.zoneWidth

        self.rowLines = polyline
        self.columnLines = polylineX
        self.allLines = polyline + polylineX
        self.rbLines.setToGeometry(
            QgsGeometry.fromMultiPolylineXY(
                polylineX + polyline + polyline[::max(1, 1 + len(polyline))]))
        if self.widget.cbReverseRows.isChecked():
            if self.widget.cbReverseColumns.isChecked():
                self.rbPC.setColor(Qt.red)
                self.rbPD.setColor(Qt.red)
                self.rbPA.setColor(Qt.red)
                self.rbPB.setColor(QColor(0, 200, 150, 255))
            else:
                self.rbPC.setColor(Qt.red)
                self.rbPD.setColor(Qt.red)
                self.rbPB.setColor(Qt.red)
                self.rbPA.setColor(QColor(0, 200, 150, 255))
        else:
            if self.widget.cbReverseColumns.isChecked():
                self.rbPA.setColor(Qt.red)
                self.rbPB.setColor(Qt.red)
                self.rbPD.setColor(Qt.red)
                self.rbPC.setColor(QColor(0, 200, 150, 255))
            else:
                self.rbPA.setColor(Qt.red)
                self.rbPB.setColor(Qt.red)
                self.rbPC.setColor(Qt.red)
                self.rbPD.setColor(QColor(0, 200, 150, 255))

        self.widget.alert.setText("Total plots: {}".format(
            self.widget.columnCount.value() * self.widget.rowCount.value()))
Ejemplo n.º 29
0
    def on_btnSave_released(self):
        layer = QgsVectorLayer(
            "MultiLineString?crs={}".format(
                QgsProject.instance().crs().authid()),
            "Lines",
            "memory",
        )

        #QgsProject.instance().addMapLayer(layer)
        layer.startEditing()
        layer.dataProvider().addAttributes([QgsField("num", QVariant.Int)])
        layer.dataProvider().addAttributes([QgsField("row", QVariant.Int)])
        layer.dataProvider().addAttributes([QgsField("column", QVariant.Int)])
        layer.updateFields()
        feats = []

        columnGap = self.columnGap.value()
        rowGap = self.rowGap.value()
        fid = 0
        lin = QgsGeometry.fromMultiPolylineXY(self.mt.rowLines)
        feature = QgsFeature(fid)
        feature.setAttributes([str(fid)])
        feature.setGeometry(lin)
        feats.append(feature)
        g = feature.geometry()
        rowBuffer = g.buffer(rowGap / 2, 5)

        fid = 1
        lin = QgsGeometry.fromMultiPolylineXY(self.mt.columnLines)
        feature = QgsFeature(fid)
        feature.setAttributes([str(fid)])
        feature.setGeometry(lin)
        feats.append(feature)
        columnBuffer = lin.buffer(columnGap / 2, 5)

        layer.dataProvider().addFeatures(feats)

        # layer.loadNamedStyle(self.plugin_dir + "/lines.qml")
        layer.commitChanges()

        # Generate index lines

        if self.cbReverseRows.isChecked():
            leftEdge = (QgsGeometry.fromPolylineXY([
                self.mt.pA, self.mt.pD
            ]).densifyByCount(self.rowCount.value() * 2 - 1).asPolyline())
            rightEdge = (QgsGeometry.fromPolylineXY([
                self.mt.pB, self.mt.pC
            ]).densifyByCount(self.rowCount.value() * 2 - 1).asPolyline())
        else:
            leftEdge = (QgsGeometry.fromPolylineXY([
                self.mt.pD, self.mt.pA
            ]).densifyByCount(self.rowCount.value() * 2 - 1).asPolyline())
            rightEdge = (QgsGeometry.fromPolylineXY([
                self.mt.pC, self.mt.pB
            ]).densifyByCount(self.rowCount.value() * 2 - 1).asPolyline())

        # Plot edges lines
        polyline_rows = list(zip(leftEdge[1::2], rightEdge[1::2]))
        if self.cbReverseColumns.isChecked():
            backSide = (QgsGeometry.fromPolylineXY([
                self.mt.pB, self.mt.pA
            ]).densifyByCount(self.columnCount.value() * 2 - 1).asPolyline())
            frontSide = (QgsGeometry.fromPolylineXY([
                self.mt.pC, self.mt.pD
            ]).densifyByCount(self.columnCount.value() * 2 - 1).asPolyline())
        else:
            backSide = (QgsGeometry.fromPolylineXY([
                self.mt.pA, self.mt.pB
            ]).densifyByCount(self.columnCount.value() * 2 - 1).asPolyline())
            frontSide = (QgsGeometry.fromPolylineXY([
                self.mt.pD, self.mt.pC
            ]).densifyByCount(self.columnCount.value() * 2 - 1).asPolyline())
        polyline_columns = list(zip(backSide[1::2], frontSide[1::2]))

        # Generate Row lines
        iRowLayer = QgsVectorLayer(
            "MultiLineString?crs={}".format(
                QgsProject.instance().crs().authid()),
            "Index Rows",
            "memory",
        )

        #QgsProject.instance().addMapLayer(iRowLayer)
        iRowLayer.startEditing()
        iRowLayer.dataProvider().addAttributes([QgsField("row", QVariant.Int)])
        iRowLayer.updateFields()
        feats = []

        row = 1
        lines_rows = QgsGeometry.fromMultiPolylineXY(polyline_rows)
        for p in lines_rows.asGeometryCollection():
            feature = QgsFeature(fid)
            feature.setAttributes([row])
            feature.setGeometry(p)
            feats.append(feature)
            row += 1

        iRowLayer.dataProvider().addFeatures(feats)
        iRowLayer.commitChanges()

        # Generate Column lines
        iColLayer = QgsVectorLayer(
            "MultiLineString?crs={}".format(
                QgsProject.instance().crs().authid()),
            "Index Columns",
            "memory",
        )

        #QgsProject.instance().addMapLayer(iColLayer)
        iColLayer.startEditing()
        iColLayer.dataProvider().addAttributes(
            [QgsField("column", QVariant.Int)])
        iColLayer.updateFields()
        feats = []

        column = 1
        lines_columns = QgsGeometry.fromMultiPolylineXY(polyline_columns)
        for p in lines_columns.asGeometryCollection():
            feature = QgsFeature(fid)
            feature.setAttributes([column])
            feature.setGeometry(p)
            feats.append(feature)
            column += 1
        iColLayer.dataProvider().addFeatures(feats)
        iColLayer.commitChanges()

        pLayer = QgsVectorLayer(
            "Polygon?crs={}".format(QgsProject.instance().crs().authid()),
            "Polygons",
            "memory",
        )
        #QgsProject.instance().addMapLayer(pLayer)
        pLayer.dataProvider().addAttributes([QgsField("num", QVariant.Int)])
        pLayer.dataProvider().addAttributes([QgsField("row", QVariant.Int)])
        pLayer.dataProvider().addAttributes([QgsField("column", QVariant.Int)])
        pLayer.startEditing()
        pLayer.updateFields()
        feats = []
        feature = QgsFeature(0)
        feature.setAttributes([str(fid), 0, 0])

        line_list = [f.geometry() for f in layer.getFeatures()]
        lines = QgsGeometry.unaryUnion(line_list)
        polygons = QgsGeometry.polygonize([lines])
        fid = 0
        for p in polygons.asGeometryCollection():
            feature = QgsFeature(fid)
            feature.setAttributes([str(fid), 0, 0])
            feature.setGeometry(p)
            feats.append(feature)
            fid += 1

        pLayer.dataProvider().addFeatures(feats)
        pLayer.commitChanges()

        pcLayer = QgsVectorLayer(
            "Polygon?crs={}".format(QgsProject.instance().crs().authid()),
            "Plots",
            "memory",
        )
        QgsProject.instance().addMapLayer(pcLayer)
        pcLayer.dataProvider().addAttributes(pLayer.fields())
        pcLayer.startEditing()
        pcLayer.updateFields()
        pcLayer.dataProvider().addFeatures(
            self.clip_polygons(pLayer, rowBuffer, columnBuffer, iRowLayer,
                               iColLayer))
        pcLayer.commitChanges()

        ptLayer = QgsVectorLayer(
            "Point?crs={}".format(QgsProject.instance().crs().authid()),
            "Points", "memory")
        QgsProject.instance().addMapLayer(ptLayer)
        ptLayer.startEditing()
        ptLayer.dataProvider().addAttributes([QgsField("num", QVariant.Int)])
        ptLayer.updateFields()
        feats = []
        fid = 0
        lin = QgsGeometry.fromMultiPolylineXY(self.mt.rowLines)

        for line in lin.asGeometryCollection():
            poly = line.densifyByCount(self.rowCount.value() * 2).asPolyline()
            for part in poly:
                feature = QgsFeature(fid)
                feature.setAttributes([str(fid)])
                feature.setGeometry(QgsPoint(part))
                feats.append(feature)
                fid += 1
        # ptLayer.dataProvider().addFeatures(sorted(feats, key=lambda f: f['num']))
        ptLayer.dataProvider().addFeatures(feats)
        ptLayer.commitChanges()
Ejemplo n.º 30
0
 def getLines(self):
     return QgsGeometry.fromMultiPolylineXY(self.rowLines)
Ejemplo n.º 31
0
    def processAlgorithm(self, parameters, context, feedback):
        """
        Here is where the processing itself takes place.
        """

        # Retrieve the feature source and sink. The 'dest_id' variable is used
        # to uniquely identify the feature sink, and must be included in the
        # dictionary returned by the processAlgorithm function.
        raster = self.parameterAsRasterLayer(parameters, self.RASTER, context)
        bande = self.parameterAsInt(parameters, self.BANDE, context)
        mini = self.parameterAsDouble(parameters, self.MINI, context)
        maxi = self.parameterAsDouble(parameters, self.MAXI, context)
        intervalle = self.parameterAsDouble(parameters, self.INTERVALLE,
                                            context)
        novalue = self.parameterAsDouble(parameters, self.NOVALUE, context)
        polygones = self.parameterAsBool(parameters, self.POLYGONS, context)
        # get features from source

        novalue = novalue
        layer = raster
        #fichier_resultat=resultat
        if not layer == None:
            if layer.type() == QgsMapLayer.RasterLayer:
                provider = layer.dataProvider()
                filePath = str(provider.dataSourceUri())
                raster_or = gdal.Open(filePath)
                nb_bands = layer.bandCount()
                champs2 = QgsFields()
                champs2.append(QgsField("id", QVariant.Double))
                if polygones == True:
                    (resultat, dest_id) = self.parameterAsSink(
                        parameters, self.CONTOURS, context, champs2,
                        QgsWkbTypes.Polygon, raster.crs()
                    )  # Compute the number of steps to display within the progress bar and
                else:
                    (resultat, dest_id) = self.parameterAsSink(
                        parameters, self.CONTOURS, context, champs2,
                        QgsWkbTypes.LineString, raster.crs()
                    )  # Compute the number of steps to display within the progress bar and
                sortie = os.path.splitext(dest_id)
                nom_sortie = os.path.basename(sortie[0])
                rep_sortie = os.path.dirname(sortie[0])
                grille = raster_or.GetRasterBand(nb_bands).ReadAsArray()
                grille = numpy.rot90(grille, 3)
                self.polys = {}
                #if polygones==True:
                #    table_lignes=QgsVectorFileWriter(resultat,"UTF-8",champs2,QGis.WKBMultiPolygon,iface.activeLayer().crs(),"ESRI Shapefile")
                #else:
                #    table_lignes=QgsVectorFileWriter(resultat,"UTF-8",champs2,QGis.WKBMultiLineString,iface.activeLayer().crs(),"ESRI Shapefile")

                fenetre = layer.extent()
                a = fenetre.toString().split(":")
                p1 = a[0].split(',')
                p2 = a[1].split(',')
                ll = (float(p1[0]), float(p1[1]))
                hauteur = float(p2[1]) - float(p1[1])
                largeur = float(p2[0]) - float(p1[0])
                nx = int(layer.width())
                ny = int(layer.height())
                pixel_size_x = round(largeur / nx, 2)
                pixel_size_y = round(hauteur / ny, 2)
                feedback.setProgressText(self.tr('Grid interpolation...'))
                for p in range(nx - 1):
                    feedback.setProgress(50 * p / nx)
                    for q in range(ny - 1):
                        self.contours(grille, p, q, intervalle, novalue, mini,
                                      maxi, ll, pixel_size_x, pixel_size_y, nx,
                                      ny)
                conn = db.connect(':memory:')
                conn.enable_load_extension(True)
                conn.execute("select load_extension('mod_spatialite')")
                c = conn.cursor()
                texte = 'drop table if exists "' + nom_sortie + '_polys"'
                rs = c.execute(texte)
                conn.commit()
                texte = 'drop table if exists "' + nom_sortie + '_polys2"'
                rs = c.execute(texte)
                conn.commit()
                texte = 'drop table if exists "' + nom_sortie + '"'
                rs = c.execute(texte)
                conn.commit()
                texte = 'drop table if exists "' + nom_sortie + '_2"'
                rs = c.execute(texte)
                conn.commit()
                texte = 'create table ' + nom_sortie + ' (id double,p integer,q integer, geom geometry)'
                rs = c.execute(texte)
                conn.commit()
                texte = 'SELECT RecoverGeometryColumn(\'' + nom_sortie + '\',\'geom\',' + str(
                    layer.crs().postgisSrid(
                    )) + ', \'MULTILINESTRING\', \'XY\')'
                rs = c.execute(texte)
                conn.commit()

                for k, ff in enumerate(self.polys):
                    feedback.setProgress(51 + (k * 50 / len(self.polys)))
                    li = self.polys[ff]
                    liste1 = [QgsGeometry.fromMultiPolylineXY(l1) for l1 in li]
                    for j, i in enumerate(liste1):

                        texte = 'insert into ' + nom_sortie + ' values(' + str(
                            float(ff[0])) + ',' + str(ff[1]) + ',' + str(
                                ff[2]) + ',st_geomfromtext(\'' + i.asWkt(
                                ) + '\',2154))'
                        rs = c.execute(texte)
                        conn.commit()
                        tlignes = NULL
                db_filename = rep_sortie + "/" + nom_sortie + ".sqlite"
                feedback.setProgressText(
                    self.tr("Generating isovalue polygons..."))
                feedback.setProgress(0)
                if polygones == True:
                    texte = 'create table \"' + nom_sortie + "_polys\" as SELECT id, casttomultipolygon(polygonize(" + nom_sortie + '.geom)) AS geom FROM \"' + nom_sortie + '\" GROUP BY id,p,q;'
                    rs = c.execute(texte)
                    conn.commit()
                    feedback.setProgress(20)
                    texte = 'create table \"' + nom_sortie + '_polys2" as SELECT id,st_union(geom) AS geom FROM \"' + nom_sortie + '_polys\" GROUP BY id;'
                    rs = c.execute(texte)
                    conn.commit()
                    feedback.setProgress(60)
                    texte = 'SELECT RecoverGeometryColumn(\"' + nom_sortie + "_polys2\"," + '\'geom\',' + str(
                        layer.crs().postgisSrid(
                        )) + ', \'MULTIPOLYGON\', \'XY\')'
                    rs = c.execute(texte)
                    conn.commit()
                else:
                    texte = 'create table \"' + nom_sortie + "_polys2" + '\" as SELECT "' + nom_sortie + '_2".\'id\' as Id, casttomultilinestring(st_union("' + nom_sortie + '_2".\'GEOMETRY\')) AS Geometry FROM \"' + nom_sortie + '_2\" GROUP BY  "' + nom_sortie + '_2".\'id\' ;'
                    rs = c.execute(texte)
                    conn.commit()
                    feedback.setProgress(20)
                    texte = 'SELECT RecoverGeometryColumn(\"' + nom_sortie + "_polys2\"," + '\'geom\',' + str(
                        layer.crs().postgisSrid(
                        )) + ', \'MULTILINESTRING\', \'XY\')'
                    rs = c.execute(texte)
                    conn.commit()
                    feedback.setProgress(60)

                texte = 'select id, asWkt(geom) from ' + nom_sortie + "_polys2"
                rs = c.execute(texte)
                feedback.setProgress(80)
                resultat2 = c.fetchall()
                conn.commit()
                for r0, r in enumerate(resultat2):
                    f1 = QgsFeature(champs2)
                    geom = QgsGeometry.fromWkt(r[1])
                    f1.setGeometry(geom)
                    f1.setAttributes([float(r[0])])
                    resultat.addFeature(f1)
                    feedback.setProgress(80 + (r0 * 20 / len(resultat2)))
                conn.close()
                del c

                del conn
        return {self.CONTOURS: dest_id}
Ejemplo n.º 32
0
    def contours(self, grille, p, q, s, novalue, mini, maxi, ll, pixel_size_x,
                 pixel_size_y, nx, ny):
        lignes = {}
        points = {}
        bords = {}
        cadreu = {}
        cadred = {}
        cadrel = {}
        cadrer = {}
        cadre = {}
        bordu = {}
        bordd = {}
        bordl = {}
        bordr = {}
        lu = grille[p, q]
        ld = grille[p, q + 1]
        ru = grille[p + 1, q]
        rd = grille[p + 1, q + 1]
        if lu > novalue:
            ilu = int(math.floor(lu / s))
        else:
            ilu = novalue
        if ld > novalue:
            ild = int(math.floor(ld / s))
        else:
            ild = novalue
        if ru > novalue:
            iru = int(math.floor(ru / s))
        else:
            iru = novalue
        if rd > novalue:
            ird = int(math.floor(rd / s))
        else:
            ird = novalue
        if ilu > novalue:
            ilu = min(max(ilu, int(math.floor(mini / s))),
                      int(math.floor(maxi / s)))
        if ild > novalue:
            ild = min(max(ild, int(math.floor(mini / s))),
                      int(math.floor(maxi / s)))
        if iru > novalue:
            iru = min(max(iru, int(math.floor(mini / s))),
                      int(math.floor(maxi / s)))
        if ird > novalue:
            ird = min(max(ird, int(math.floor(mini / s))),
                      int(math.floor(maxi / s)))
        if ilu == ild and ilu != novalue:
            if ilu not in bordl:
                bordl[ilu] = []
            bordl[ilu].append([p, q])
            if ilu + 1 not in bordl:
                bordl[ilu + 1] = []
            bordl[ilu + 1].append([p, q + 1])
        if ild == ird and ild != novalue:
            if ild not in bordd:
                bordd[ild] = []
            bordd[ild].append([p, q + 1])
            if ild + 1 not in bordd:
                bordd[ild + 1] = []
            bordd[ild + 1].append([p + 1, q + 1])
        if iru == ird and iru != novalue:
            if ird not in bordr:
                bordr[ird] = []
            bordr[ird].append([p + 1, q])
            if ird + 1 not in bordr:
                bordr[ird + 1] = []
            bordr[ird + 1].append([p + 1, q + 1])
        if ilu == iru and ilu != novalue:
            if ilu not in bordu:
                bordu[ilu] = []
            bordu[ilu].append([p, q])
            if ilu + 1 not in bordu:
                bordu[ilu + 1] = []
            bordu[ilu + 1].append([p + 1, q])
        if ilu < ild:
            if lu == novalue:
                if ild not in bordl:
                    bordl[ild] = []
                bordl[ild].append([p, q])
                bordl[ild].append([p, q + 1])
            else:
                for i in range(ilu, ild):
                    if i not in points:
                        points[i] = []
                    points[i].append([p, q + ((i + 1) * s - lu) / (ld - lu)])
                    if i == ilu:
                        if i not in bordl:
                            bordl[i] = []
                        bordl[i].append([p, q])
                    if i + 1 not in bordl:
                        bordl[i + 1] = []
                    bordl[i + 1].append(
                        [p, q + ((i + 1) * s - lu) / (ld - lu)])
                    if i == ild - 1:
                        if i + 2 not in bordl:
                            bordl[i + 2] = []
                        bordl[i + 2].append([p, q + 1])
        if ilu > ild:
            if ld == novalue:
                if ilu not in bordl:
                    bordl[ilu] = []
                bordl[ilu].append([p, q])
                bordl[ilu].append([p, q + 1])
            else:
                for i in range(ild, ilu):
                    if i not in points:
                        points[i] = []
                    points[i].append([p, q + (lu - (i + 1) * s) / (lu - ld)])
                    if i == ild:
                        if i - 1 not in bordl:
                            bordl[i - 1] = []
                        bordl[i - 1].append([p, q + 1])
                    if i not in bordl:
                        bordl[i] = []
                    bordl[i].append([p, q + (lu - (i + 1) * s) / (lu - ld)])
                    if i == ilu - 1:
                        if i + 1 not in bordl:
                            bordl[i + 1] = []
                        bordl[i + 1].append([p, q])
        if ild < ird:
            if ld == novalue:
                if ird not in bordd:
                    bordd[ird] = []
                bordd[ird].append([p, q + 1])
                bordd[ird].append([p + 1, q + 1])
            else:
                for i in range(ild, ird):
                    if i not in points:
                        points[i] = []
                    points[i].append(
                        [p + ((i + 1) * s - ld) / (rd - ld), q + 1])
                    if i == ild:
                        if i not in bordd:
                            bordd[i] = []
                        bordd[i].append([p, q + 1])
                    if i + 1 not in bordd:
                        bordd[i + 1] = []
                    bordd[i + 1].append(
                        [p + ((i + 1) * s - ld) / (rd - ld), q + 1])
                    if i == ird - 1:
                        if i + 2 not in bordd:
                            bordd[i + 2] = []
                        bordd[i + 2].append([p + 1, q + 1])
        if ild > ird:
            if rd == novalue:
                if ild not in bordd:
                    bordd[ild] = []
                bordd[ild].append([p, q + 1])
                bordd[ild].append([p + 1, q + 1])
            else:
                for i in range(ird, ild):
                    if i not in points:
                        points[i] = []
                    points[i].append(
                        [p + (ld - (i + 1) * s) / (ld - rd), q + 1])
                    if i == ird:
                        if i - 1 not in bordd:
                            bordd[i - 1] = []
                        bordd[i - 1].append([p + 1, q + 1])
                    if i not in bordd:
                        bordd[i] = []
                    bordd[i].append(
                        [p + (ld - (i + 1) * s) / (ld - rd), q + 1])
                    if i == ild - 1:
                        if i + 1 not in bordd:
                            bordd[i + 1] = []
                        bordd[i + 1].append([p, q + 1])
        if ird < iru:
            if rd == novalue:
                if iru not in bordr:
                    bordr[iru] = []
                bordr[iru].append([p + 1, q])
                bordr[iru].append([p + 1, q + 1])
            else:
                for i in range(ird, iru):
                    if i not in points:
                        points[i] = []
                    points[i].append(
                        [p + 1, q + (ru - (i + 1) * s) / (ru - rd)])
                    if i == iru - 1:
                        if i + 1 not in bordr:
                            bordr[i + 1] = []
                        bordr[i + 1].append([p + 1, q])
                    if i == ird:
                        if i - 1 not in bordr:
                            bordr[i - 1] = []
                        bordr[i - 1].append([p + 1, q + 1])
                    if i not in bordr:
                        bordr[i] = []
                    bordr[i].append(
                        [p + 1, q + (ru - (i + 1) * s) / (ru - rd)])
        if ird > iru:
            if ru == novalue:
                if ird not in bordr:
                    bordr[ird] = []
                bordr[ird].append([p + 1, q])
                bordr[ird].append([p + 1, q + 1])
            else:
                for i in range(iru, ird):
                    if i not in points:
                        points[i] = []
                    points[i].append(
                        [p + 1, q + ((i + 1) * s - ru) / (rd - ru)])
                    if i == iru:
                        if i not in bordr:
                            bordr[i] = []
                        bordr[i].append([p + 1, q])
                    if i + 1 not in bordr:
                        bordr[i + 1] = []
                    bordr[i + 1].append(
                        [p + 1, q + ((i + 1) * s - ru) / (rd - ru)])
                    if i == ird - 1:
                        if i + 2 not in bordr:
                            bordr[i + 2] = []
                        bordr[i + 2].append([p + 1, q + 1])
        if iru < ilu:
            if ru == novalue:
                if ilu not in bordu:
                    bordu[ilu] = []
                bordu[ilu].append([p, q])
                bordu[ilu].append([p + 1, q])
            else:
                for i in range(iru, ilu):
                    if i not in points:
                        points[i] = []
                    points[i].append([p + (lu - (i + 1) * s) / (lu - ru), q])
                    if i == iru:
                        if i - 1 not in bordu:
                            bordu[i - 1] = []
                        bordu[i - 1].append([p + 1, q])
                    if i == ilu - 1:
                        if i + 1 not in bordu:
                            bordu[i + 1] = []
                        bordu[i + 1].append([p, q])
                    if i not in bordu:
                        bordu[i] = []
                    bordu[i].append([p + (lu - (i + 1) * s) / (lu - ru), q])
        if iru > ilu:
            if lu == novalue:
                if iru not in bordu:
                    bordu[iru] = []
                bordu[iru].append([p, q])
                bordu[iru].append([p + 1, q])
            else:
                for i in range(ilu, iru):
                    if i not in points:
                        points[i] = []
                    points[i].append([p + ((i + 1) * s - lu) / (ru - lu), q])
                    if i == ilu:
                        if i not in bordu:
                            bordu[i] = []
                        bordu[i].append([p, q])
                    if i + 1 not in bordu:
                        bordu[i + 1] = []
                    bordu[i + 1].append(
                        [p + ((i + 1) * s - lu) / (ru - lu), q])
                    if i == iru - 1:
                        if i + 2 not in bordu:
                            bordu[i + 2] = []
                        bordu[i + 2].append([p + 1, q])
        for pt in points:
            mx = sum(float(points[pt][j][0])
                     for j in range(len(points[pt]))) / len(points[pt])
            my = sum(float(points[pt][j][1])
                     for j in range(len(points[pt]))) / len(points[pt])
            for j in range(len(points[pt])):
                n = len(points[pt])
                if n > 2:
                    p1x = ll[0] + (p + 1 - 0.02 *
                                   ((-1)**(int(j / 2)))) * pixel_size_x
                    p2x = ll[0] + (points[pt][j][0] + 0.5) * pixel_size_x
                    q1y = ll[1] + (q + 1 - 0.02 *
                                   ((-1)**(int(j / 2)))) * pixel_size_y
                    q2y = ll[1] + (points[pt][j][1] + 0.5) * pixel_size_y
                    ligne1 = QgsGeometry.fromMultiPolylineXY(
                        [[QgsPointXY(p1x, q1y),
                          QgsPointXY(p2x, q2y)]])
                else:
                    p1x = ll[0] + (mx + 0.5) * pixel_size_x
                    p2x = ll[0] + (points[pt][j][0] + 0.5) * pixel_size_x
                    q1y = ll[1] + (my + 0.5) * pixel_size_y
                    q2y = ll[1] + (points[pt][j][1] + 0.5) * pixel_size_y
                    ligne1 = QgsGeometry.fromMultiPolylineXY(
                        [[QgsPointXY(p1x, q1y),
                          QgsPointXY(p2x, q2y)]])

                f1 = QgsFeature()
                f1.setAttributes([pt * s])
                f1.setGeometry(ligne1)
                f2 = QgsFeature()
                f2.setAttributes([(pt + 1) * s])
                f2.setGeometry(ligne1)
                if min(lu, ld, ru, rd) > novalue:
                    if (pt * s, p, q) not in self.polys:
                        self.polys[pt * s, p, q] = []
                    self.polys[pt * s, p,
                               q].append(f1.geometry().asMultiPolyline())
                    if ((pt + 1) * s, p, q) not in self.polys:
                        self.polys[(pt + 1) * s, p, q] = []
                    self.polys[(pt + 1) * s, p,
                               q].append(f2.geometry().asMultiPolyline())

        if len(bordu) > 0:
            bords = sorted(bordu.items(), key=lambda x: x[1][0])
            for pt in range(len(bords) - 1):
                p1 = ll[0] + (bords[pt][1][0][0] + 0.5) * pixel_size_x
                p2 = ll[0] + (bords[pt + 1][1][0][0] + 0.5) * pixel_size_x
                q1 = ll[1] + (bords[pt][1][0][1] + 0.5) * pixel_size_y
                q2 = ll[1] + (bords[pt + 1][1][0][1] + 0.5) * pixel_size_y
                ligne1 = QgsGeometry.fromMultiPolylineXY(
                    [[QgsPointXY(p1, q1),
                      QgsPointXY(p2, q2)]])
                f1 = QgsFeature()
                f1.setAttributes([bords[pt][0] * s])
                f1.setGeometry(ligne1)
                if q > 0:
                    if q < ny - 1:
                        if (bords[pt][0] * s, p, q) not in self.polys:
                            self.polys[bords[pt][0] * s, p, q] = []
                        self.polys[bords[pt][0] * s, p,
                                   q].append(f1.geometry().asMultiPolyline())
                else:
                    if (bords[pt][0] * s, p, q) not in self.polys:
                        self.polys[bords[pt][0] * s, p, q] = []
                    self.polys[bords[pt][0] * s, p,
                               q].append(f1.geometry().asMultiPolyline())
        if len(bordl) > 0:
            bords = sorted(bordl.items(), key=lambda x: x[1][0][1])
            for pt in range(len(bords) - 1):
                p1 = ll[0] + (bords[pt][1][0][0] + 0.5) * pixel_size_x
                p2 = ll[0] + (bords[pt + 1][1][0][0] + 0.5) * pixel_size_x
                q1 = ll[1] + (bords[pt][1][0][1] + 0.5) * pixel_size_y
                q2 = ll[1] + (bords[pt + 1][1][0][1] + 0.5) * pixel_size_y
                ligne1 = QgsGeometry.fromMultiPolylineXY(
                    [[QgsPointXY(p1, q1),
                      QgsPointXY(p2, q2)]])
                f1 = QgsFeature()
                f1.setAttributes([bords[pt][0] * s])
                f1.setGeometry(ligne1)
                if p > 0:
                    if p < nx - 1:
                        if (bords[pt][0] * s, p, q) not in self.polys:
                            self.polys[bords[pt][0] * s, p, q] = []
                        self.polys[bords[pt][0] * s, p,
                                   q].append(f1.geometry().asMultiPolyline())
                else:
                    if (bords[pt][0] * s, p, q) not in self.polys:
                        self.polys[bords[pt][0] * s, p, q] = []
                    self.polys[bords[pt][0] * s, p,
                               q].append(f1.geometry().asMultiPolyline())

        if len(bordr) > 0:
            bords = sorted(bordr.items(), key=lambda x: x[1][0][1])
            for pt in range(len(bords) - 1):

                p1 = ll[0] + (bords[pt][1][0][0] + 0.5) * pixel_size_x
                p2 = ll[0] + (bords[pt + 1][1][0][0] + 0.5) * pixel_size_x
                q1 = ll[1] + (bords[pt][1][0][1] + 0.5) * pixel_size_y
                q2 = ll[1] + (bords[pt + 1][1][0][1] + 0.5) * pixel_size_y
                ligne1 = QgsGeometry.fromMultiPolylineXY(
                    [[QgsPointXY(p1, q1),
                      QgsPointXY(p2, q2)]])
                f1 = QgsFeature()
                f1.setAttributes([bords[pt][0] * s])
                f1.setGeometry(ligne1)
                if p < nx - 2:
                    if q > -1:
                        if (bords[pt][0] * s, p, q) not in self.polys:
                            self.polys[bords[pt][0] * s, p, q] = []
                        self.polys[bords[pt][0] * s, p,
                                   q].append(f1.geometry().asMultiPolyline())
                else:
                    if (bords[pt][0] * s, p, q) not in self.polys:
                        self.polys[bords[pt][0] * s, p, q] = []
                    self.polys[bords[pt][0] * s, p,
                               q].append(f1.geometry().asMultiPolyline())
        if len(bordd) > 0:
            bords = sorted(bordd.items(), key=lambda x: x[1][0])
            for pt in range(len(bords) - 1):
                p1 = ll[0] + (bords[pt][1][0][0] + 0.5) * pixel_size_x
                p2 = ll[0] + (bords[pt + 1][1][0][0] + 0.5) * pixel_size_x
                q1 = ll[1] + (bords[pt][1][0][1] + 0.5) * pixel_size_y
                q2 = ll[1] + (bords[pt + 1][1][0][1] + 0.5) * pixel_size_y
                ligne1 = QgsGeometry.fromMultiPolylineXY(
                    [[QgsPointXY(p1, q1),
                      QgsPointXY(p2, q2)]])
                f1 = QgsFeature()
                f1.setAttributes([bords[pt][0] * s])
                f1.setGeometry(ligne1)
                if q < ny - 2:
                    if q > -1:
                        if (bords[pt][0] * s, p, q) not in self.polys:
                            self.polys[bords[pt][0] * s, p, q] = []
                        self.polys[bords[pt][0] * s, p,
                                   q].append(f1.geometry().asMultiPolyline())
                else:
                    if (bords[pt][0] * s, p, q) not in self.polys:
                        self.polys[bords[pt][0] * s, p, q] = []
                    self.polys[bords[pt][0] * s, p,
                               q].append(f1.geometry().asMultiPolyline())
Ejemplo n.º 33
0
    def processAlgorithm(self, parameters, context, feedback):
        network = self.parameterAsSource(parameters, self.INPUT, context)
        if network is None:
            raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))

        startPoints = self.parameterAsSource(parameters, self.START_POINTS, context)
        if startPoints is None:
            raise QgsProcessingException(self.invalidSourceError(parameters, self.START_POINTS))

        strategy = self.parameterAsEnum(parameters, self.STRATEGY, context)
        travelCost = self.parameterAsDouble(parameters, self.TRAVEL_COST, context)

        directionFieldName = self.parameterAsString(parameters, self.DIRECTION_FIELD, context)
        forwardValue = self.parameterAsString(parameters, self.VALUE_FORWARD, context)
        backwardValue = self.parameterAsString(parameters, self.VALUE_BACKWARD, context)
        bothValue = self.parameterAsString(parameters, self.VALUE_BOTH, context)
        defaultDirection = self.parameterAsEnum(parameters, self.DEFAULT_DIRECTION, context)
        speedFieldName = self.parameterAsString(parameters, self.SPEED_FIELD, context)
        defaultSpeed = self.parameterAsDouble(parameters, self.DEFAULT_SPEED, context)
        tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context)

        include_bounds = True # default to true to maintain 3.0 API
        if self.INCLUDE_BOUNDS in parameters:
            include_bounds = self.parameterAsBoolean(parameters, self.INCLUDE_BOUNDS, context)

        fields = startPoints.fields()
        fields.append(QgsField('type', QVariant.String, '', 254, 0))
        fields.append(QgsField('start', QVariant.String, '', 254, 0))

        feat = QgsFeature()
        feat.setFields(fields)

        directionField = -1
        if directionFieldName:
            directionField = network.fields().lookupField(directionFieldName)
        speedField = -1
        if speedFieldName:
            speedField = network.fields().lookupField(speedFieldName)

        director = QgsVectorLayerDirector(network,
                                          directionField,
                                          forwardValue,
                                          backwardValue,
                                          bothValue,
                                          defaultDirection)

        distUnit = context.project().crs().mapUnits()
        multiplier = QgsUnitTypes.fromUnitToUnitFactor(distUnit, QgsUnitTypes.DistanceMeters)
        if strategy == 0:
            strategy = QgsNetworkDistanceStrategy()
        else:
            strategy = QgsNetworkSpeedStrategy(speedField,
                                               defaultSpeed,
                                               multiplier * 1000.0 / 3600.0)

        director.addStrategy(strategy)
        builder = QgsGraphBuilder(network.sourceCrs(),
                                  True,
                                  tolerance)

        feedback.pushInfo(QCoreApplication.translate('ServiceAreaFromLayer', 'Loading start points…'))
        request = QgsFeatureRequest()
        request.setDestinationCrs(network.sourceCrs(), context.transformContext())
        features = startPoints.getFeatures(request)
        total = 100.0 / startPoints.featureCount() if startPoints.featureCount() else 0

        points = []
        source_attributes = {}
        i = 0
        for current, f in enumerate(features):
            if feedback.isCanceled():
                break

            if not f.hasGeometry():
                continue

            for p in f.geometry().vertices():
                points.append(QgsPointXY(p))
                source_attributes[i] = f.attributes()
                i += 1

            feedback.setProgress(int(current * total))

        feedback.pushInfo(QCoreApplication.translate('ServiceAreaFromLayer', 'Building graph…'))
        snappedPoints = director.makeGraph(builder, points, feedback)

        feedback.pushInfo(QCoreApplication.translate('ServiceAreaFromLayer', 'Calculating service areas…'))
        graph = builder.graph()

        (point_sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
                                                     fields, QgsWkbTypes.MultiPoint, network.sourceCrs())
        (line_sink, line_dest_id) = self.parameterAsSink(parameters, self.OUTPUT_LINES, context,
                                                         fields, QgsWkbTypes.MultiLineString, network.sourceCrs())

        total = 100.0 / len(snappedPoints) if snappedPoints else 1
        for i, p in enumerate(snappedPoints):
            if feedback.isCanceled():
                break

            idxStart = graph.findVertex(snappedPoints[i])
            origPoint = points[i].toString()

            tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 0)

            vertices = set()
            area_points = []
            lines = []
            for vertex, start_vertex_cost in enumerate(cost):
                inbound_edge_index = tree[vertex]
                if inbound_edge_index == -1 and vertex != idxStart:
                    # unreachable vertex
                    continue

                if start_vertex_cost > travelCost:
                    # vertex is too expensive, discard
                    continue

                vertices.add(vertex)
                start_point = graph.vertex(vertex).point()

                # find all edges coming from this vertex
                for edge_id in graph.vertex(vertex).outgoingEdges():
                    edge = graph.edge(edge_id)
                    end_vertex_cost = start_vertex_cost + edge.cost(0)
                    end_point = graph.vertex(edge.toVertex()).point()
                    if end_vertex_cost <= travelCost:
                        # end vertex is cheap enough to include
                        vertices.add(edge.toVertex())
                        lines.append([start_point, end_point])
                    else:
                        # travelCost sits somewhere on this edge, interpolate position
                        interpolated_end_point = QgsGeometryUtils.interpolatePointOnLineByValue(start_point.x(), start_point.y(), start_vertex_cost,
                                                                                                end_point.x(), end_point.y(), end_vertex_cost, travelCost)
                        area_points.append(interpolated_end_point)
                        lines.append([start_point, interpolated_end_point])

            for v in vertices:
                area_points.append(graph.vertex(v).point())

            feat = QgsFeature()
            if point_sink is not None:
                geomPoints = QgsGeometry.fromMultiPointXY(area_points)
                feat.setGeometry(geomPoints)
                attrs = source_attributes[i]
                attrs.extend(['within', origPoint])
                feat.setAttributes(attrs)
                point_sink.addFeature(feat, QgsFeatureSink.FastInsert)

                if include_bounds:
                    upperBoundary = []
                    lowerBoundary = []

                    vertices = []
                    for vertex, c in enumerate(cost):
                        if c > travelCost and tree[vertex] != -1:
                            vertexId = graph.edge(tree[vertex]).fromVertex()
                            if cost[vertexId] <= travelCost:
                                vertices.append(vertex)

                    for v in vertices:
                        upperBoundary.append(graph.vertex(graph.edge(tree[v]).toVertex()).point())
                        lowerBoundary.append(graph.vertex(graph.edge(tree[v]).fromVertex()).point())

                    geomUpper = QgsGeometry.fromMultiPointXY(upperBoundary)
                    geomLower = QgsGeometry.fromMultiPointXY(lowerBoundary)

                    feat.setGeometry(geomUpper)
                    attrs[-2] = 'upper'
                    feat.setAttributes(attrs)
                    point_sink.addFeature(feat, QgsFeatureSink.FastInsert)

                    feat.setGeometry(geomLower)
                    attrs[-2] = 'lower'
                    feat.setAttributes(attrs)
                    point_sink.addFeature(feat, QgsFeatureSink.FastInsert)

            if line_sink is not None:
                geom_lines = QgsGeometry.fromMultiPolylineXY(lines)
                feat.setGeometry(geom_lines)
                attrs = source_attributes[i]
                attrs.extend(['lines', origPoint])
                feat.setAttributes(attrs)
                line_sink.addFeature(feat, QgsFeatureSink.FastInsert)

            feedback.setProgress(int(i * total))

        results = {}
        if point_sink is not None:
            results[self.OUTPUT] = dest_id
        if line_sink is not None:
            results[self.OUTPUT_LINES] = line_dest_id
        return results
Ejemplo n.º 34
0
    def processAlgorithm(self, parameters, context, feedback):
        """
        Here is where the processing itself takes place.
        """

        # Retrieve the feature source and sink. The 'dest_id' variable is used
        # to uniquely identify the feature sink, and must be included in the
        # dictionary returned by the processAlgorithm function.
        source = self.parameterAsSource(parameters, self.INPUT, context)
        (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT,
                                               context, source.fields(),
                                               source.wkbType(),
                                               source.sourceCrs())

        # Compute the number of steps to display within the progress bar and
        # get features from source
        total = 100.0 / source.featureCount() if source.featureCount() else 0
        features = source.getFeatures()
        print(features)

        for current, feature in enumerate(features):
            # Stop the algorithm if cancel button has been clicked
            if feedback.isCanceled():
                break
            # sshuair begin
            geom = feature.geometry()
            attrs = feature.attributes()
            geom_type = geom.wkbType()

            feature_new = QgsFeature()

            # Point
            if geom_type == 1:
                vertices = geom.asPoint()
                vert_new = bd2gcj(vertices[0], vertices[1])
                feature_new.setGeometry(
                    QgsGeometry.fromPointXY(
                        QgsPointXY(vert_new[0], vert_new[1])))

            # LineString
            elif geom_type == 2:
                vert_new = []
                vertices = geom.asPolyline()
                for pt in vertices:
                    pt_new = bd2gcj(pt[0], pt[1])
                    vert_new.append(QgsPointXY(pt_new[0], pt_new[1]))
                feature_new.setGeometry(QgsGeometry.fromPolylineXY(vert_new))

            # Polygon
            elif geom_type == 3:
                vertices = geom.asPolygon()
                vert_new = []
                for ring in vertices:
                    ring_vert = []
                    for pt in ring:
                        pt_new = bd2gcj(pt[0], pt[1])
                        ring_vert.append(QgsPointXY(pt_new[0], pt_new[1]))
                    vert_new.append(ring_vert)
                feature_new.setGeometry(QgsGeometry.fromPolygonXY(vert_new))

            # MultiPoint
            elif geom_type == 4:
                vert_new = []
                vertices = geom.asMultiPoint()
                for pt in vertices:
                    pt_new = bd2gcj(pt[0], pt[1])
                    vert_new.append(QgsPointXY(pt_new[0], pt_new[1]))
                feature_new.setGeometry(QgsGeometry.fromMultiPointXY(vert_new))

            # MultiLineString
            elif geom_type == 5:
                vertices = geom.asMultiPolyline()
                vert_new = []
                for part in vertices:
                    linestring = []
                    for pt in part:
                        pt_new = bd2gcj(pt[0], pt[1])
                        linestring.append(QgsPointXY(pt_new[0], pt_new[1]))
                    vert_new.append(linestring)
                feature_new.setGeometry(
                    QgsGeometry.fromMultiPolylineXY(vert_new))

            # MultiPolygon
            elif geom_type == 6:
                vertices = geom.asMultiPolygon()
                vert_new = []
                for part in vertices:
                    poly = []
                    for ring in part:
                        ring_vert = []
                        for pt in ring:
                            pt_new = bd2gcj(pt[0], pt[1])
                            ring_vert.append(QgsPointXY(pt_new[0], pt_new[1]))
                        poly.append(ring_vert)
                    vert_new.append(poly)
                feature_new.setGeometry(
                    QgsGeometry.fromMultiPolygonXY(vert_new))
            else:
                continue

            feature_new.setAttributes(attrs)
            # sshuair end

            # feature = feature+0.1
            # Add a feature in the sink
            sink.addFeature(feature_new, QgsFeatureSink.FastInsert)

            # Update the progress bar
            feedback.setProgress(int(current * total))
            print(feature)

        # Return the results of the algorithm. In this case our only result is
        # the feature sink which contains the processed features, but some
        # algorithms may return multiple feature sinks, calculated numeric
        # statistics, etc. These should all be included in the returned
        # dictionary, with keys matching the feature corresponding parameter
        # or output names.
        return {self.OUTPUT: dest_id}
Ejemplo n.º 35
0
    def processAlgorithm(self, parameters, context, feedback):
        network = self.parameterAsSource(parameters, self.INPUT, context)
        if network is None:
            raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))

        startPoint = self.parameterAsPoint(parameters, self.START_POINT, context, network.sourceCrs())
        strategy = self.parameterAsEnum(parameters, self.STRATEGY, context)
        travelCost = self.parameterAsDouble(parameters, self.TRAVEL_COST, context)

        directionFieldName = self.parameterAsString(parameters, self.DIRECTION_FIELD, context)
        forwardValue = self.parameterAsString(parameters, self.VALUE_FORWARD, context)
        backwardValue = self.parameterAsString(parameters, self.VALUE_BACKWARD, context)
        bothValue = self.parameterAsString(parameters, self.VALUE_BOTH, context)
        defaultDirection = self.parameterAsEnum(parameters, self.DEFAULT_DIRECTION, context)
        speedFieldName = self.parameterAsString(parameters, self.SPEED_FIELD, context)
        defaultSpeed = self.parameterAsDouble(parameters, self.DEFAULT_SPEED, context)
        tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context)

        include_bounds = True # default to true to maintain 3.0 API
        if self.INCLUDE_BOUNDS in parameters:
            include_bounds = self.parameterAsBool(parameters, self.INCLUDE_BOUNDS, context)

        directionField = -1
        if directionFieldName:
            directionField = network.fields().lookupField(directionFieldName)
        speedField = -1
        if speedFieldName:
            speedField = network.fields().lookupField(speedFieldName)

        director = QgsVectorLayerDirector(network,
                                          directionField,
                                          forwardValue,
                                          backwardValue,
                                          bothValue,
                                          defaultDirection)

        distUnit = context.project().crs().mapUnits()
        multiplier = QgsUnitTypes.fromUnitToUnitFactor(distUnit, QgsUnitTypes.DistanceMeters)
        if strategy == 0:
            strategy = QgsNetworkDistanceStrategy()
        else:
            strategy = QgsNetworkSpeedStrategy(speedField,
                                               defaultSpeed,
                                               multiplier * 1000.0 / 3600.0)

        director.addStrategy(strategy)
        builder = QgsGraphBuilder(network.sourceCrs(),
                                  True,
                                  tolerance)
        feedback.pushInfo(QCoreApplication.translate('ServiceAreaFromPoint', 'Building graph…'))
        snappedPoints = director.makeGraph(builder, [startPoint], feedback)

        feedback.pushInfo(QCoreApplication.translate('ServiceAreaFromPoint', 'Calculating service area…'))
        graph = builder.graph()
        idxStart = graph.findVertex(snappedPoints[0])

        tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 0)
        vertices = set()
        points = []
        lines = []

        for vertex, start_vertex_cost in enumerate(cost):
            inbound_edge_index = tree[vertex]
            if inbound_edge_index == -1 and vertex != idxStart:
                # unreachable vertex
                continue

            if start_vertex_cost > travelCost:
                # vertex is too expensive, discard
                continue

            vertices.add(vertex)
            start_point = graph.vertex(vertex).point()

            # find all edges coming from this vertex
            for edge_id in graph.vertex(vertex).outgoingEdges():
                edge = graph.edge(edge_id)
                end_vertex_cost = start_vertex_cost + edge.cost(0)
                end_point = graph.vertex(edge.toVertex()).point()
                if end_vertex_cost <= travelCost:
                    # end vertex is cheap enough to include
                    vertices.add(edge.toVertex())
                    lines.append([start_point, end_point])
                else:
                    # travelCost sits somewhere on this edge, interpolate position
                    interpolated_end_point = QgsGeometryUtils.interpolatePointOnLineByValue(start_point.x(), start_point.y(), start_vertex_cost,
                                                                                            end_point.x(), end_point.y(), end_vertex_cost, travelCost)
                    points.append(interpolated_end_point)
                    lines.append([start_point, interpolated_end_point])

        for i in vertices:
            points.append(graph.vertex(i).point())

        feedback.pushInfo(QCoreApplication.translate('ServiceAreaFromPoint', 'Writing results…'))

        fields = QgsFields()
        fields.append(QgsField('type', QVariant.String, '', 254, 0))
        fields.append(QgsField('start', QVariant.String, '', 254, 0))

        feat = QgsFeature()
        feat.setFields(fields)

        (point_sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
                                                     fields, QgsWkbTypes.MultiPoint, network.sourceCrs())

        results = {}

        if point_sink is not None:
            results[self.OUTPUT] = dest_id
            geomPoints = QgsGeometry.fromMultiPointXY(points)
            feat.setGeometry(geomPoints)
            feat['type'] = 'within'
            feat['start'] = startPoint.toString()
            point_sink.addFeature(feat, QgsFeatureSink.FastInsert)

            if include_bounds:
                upperBoundary = []
                lowerBoundary = []

                vertices = []
                for i, v in enumerate(cost):
                    if v > travelCost and tree[i] != -1:
                        vertexId = graph.edge(tree[i]).fromVertex()
                        if cost[vertexId] <= travelCost:
                            vertices.append(i)

                for i in vertices:
                    upperBoundary.append(graph.vertex(graph.edge(tree[i]).toVertex()).point())
                    lowerBoundary.append(graph.vertex(graph.edge(tree[i]).fromVertex()).point())

                geomUpper = QgsGeometry.fromMultiPointXY(upperBoundary)
                geomLower = QgsGeometry.fromMultiPointXY(lowerBoundary)

                feat.setGeometry(geomUpper)
                feat['type'] = 'upper'
                feat['start'] = startPoint.toString()
                point_sink.addFeature(feat, QgsFeatureSink.FastInsert)

                feat.setGeometry(geomLower)
                feat['type'] = 'lower'
                feat['start'] = startPoint.toString()
                point_sink.addFeature(feat, QgsFeatureSink.FastInsert)

        (line_sink, line_dest_id) = self.parameterAsSink(parameters, self.OUTPUT_LINES, context,
                                                         fields, QgsWkbTypes.MultiLineString, network.sourceCrs())
        if line_sink is not None:
            results[self.OUTPUT_LINES] = line_dest_id
            geom_lines = QgsGeometry.fromMultiPolylineXY(lines)
            feat.setGeometry(geom_lines)
            feat['type'] = 'lines'
            feat['start'] = startPoint.toString()
            line_sink.addFeature(feat, QgsFeatureSink.FastInsert)

        return results
Ejemplo n.º 36
0
    def getLinesSelectionModeLines(self, selectBehaviour: SelectBehaviour,
                                   rect: QgsRectangle) -> typing.Tuple:
        assert self.simplifiedSegmentsLayer

        rect = self.__getCoordinateTransform(
            self.simplifiedSegmentsLayer).transform(rect)

        self.simplifiedSegmentsLayer.selectByRect(rect, selectBehaviour)

        if self.simplifiedSegmentsLayer.selectedFeatureCount() == 0:
            return ()

        selectedLinesLayer = utils.selected_features_to_layer(
            self.simplifiedSegmentsLayer)
        dissolvedLinesLayer = utils.dissolve_layer(selectedLinesLayer)
        mergedLinesLayer = utils.merge_lines_layer(dissolvedLinesLayer)
        singlepartsLayer = utils.multipart_to_singleparts(mergedLinesLayer)

        # INFO: this is disabled, it causes the selecteBehaviour to be ignored.
        # Could be written in much more clever way, but does not worth it
        # self.simplifiedSegmentsLayer.deselect(list(self.simplifiedSegmentsLayer.selectedFeatureIds()))

        enclosingLineFeatures = list(dissolvedLinesLayer.getFeatures())
        points_dict = dict()

        for f in singlepartsLayer.getFeatures():
            points_dict[f.id()] = utils.lines_unique_vertices(
                singlepartsLayer, [f.id()])

        points = list(points_dict.values())

        if len(points) == 1 and len(points[0]) == 2:
            pointX1 = points[0][0]
            pointY1 = points[0][0]
            pointX2 = points[0][1]
            pointY2 = points[0][1]
        elif len(points) == 2 and len(points[0]) == 2 and len(points[1]) == 2:
            pointX1 = points[0][0]
            pointY1 = points[0][1]
            pointX2 = points[1][0]
            pointY2 = points[1][1]
        else:
            show_info(
                __('Selected lines can have exactly two or four unconnected endpoints'
                   ))
            return tuple(enclosingLineFeatures)

        selectedLinesLayer.startEditing()

        f1 = QgsFeature(selectedLinesLayer.fields())
        f2 = QgsFeature(selectedLinesLayer.fields())

        if pointX1.distance(pointX2) + pointY1.distance(
                pointY2) < pointX1.distance(pointY2) + pointY1.distance(
                    pointX2):
            # x1->x2 y1->y2
            f1.setGeometry(
                QgsGeometry.fromMultiPolylineXY([[pointX1, pointX2]]))
            f2.setGeometry(
                QgsGeometry.fromMultiPolylineXY([[pointY1, pointY2]]))
        else:
            # x1->y2 y1->x
            f1.setGeometry(
                QgsGeometry.fromMultiPolylineXY([[pointX1, pointY2]]))
            f2.setGeometry(
                QgsGeometry.fromMultiPolylineXY([[pointY1, pointX2]]))

        selectedLinesLayer.addFeatures([f1, f2])

        selectedLinesLayer.commitChanges()

        dissolvedLinesLayer2 = utils.dissolve_layer(selectedLinesLayer)

        return tuple(dissolvedLinesLayer2.getFeatures())