def addPart(self, list_part, layer):

        list_1 = []
        list_1.append(list_part)

        geom_part_1 = QgsGeometry.fromMultiPolyline(list_1)

        num_attr = len(layer.attributeList())

        layer.startEditing()

        newgeom = QgsFeature()
        newgeom.setGeometry(QgsGeometry.fromMultiPolyline(list_1))

        #Cargo todos los atributos vacios
        attr_vacio = []
        attr_vacio.append("nextval('cloacas.cl_tramos_gid_seq'::regclass)")
        #recorro un for para setear los atributos
        for i in range(num_attr - 1):
            attr_vacio.append("")

        #agrego la parte al layer
        newgeom.setAttributes(attr_vacio)
        layer.addFeature(newgeom, True)
        layer.commitChanges()
    def changePart(self, list_part, layer, layer_sel):

        list_1 = []
        list_1.append(list_part)

        geom_part_1 = QgsGeometry.fromMultiPolyline(list_1)

        layer.startEditing()

        newgeom = QgsGeometry.fromMultiPolyline(list_1)

        layer.changeGeometry(layer_sel.id(), newgeom)
        layer.commitChanges()
Exemple #3
0
def densifyGeometry(geometry, pointsNumber, isPolygon):
    output = []
    if isPolygon:
        if geometry.isMultipart():
            polygons = geometry.asMultiPolygon()
            for poly in polygons:
                p = []
                for ring in poly:
                    p.append(densify(ring, pointsNumber))
                output.append(p)
            return QgsGeometry.fromMultiPolygon(output)
        else:
            rings = geometry.asPolygon()
            for ring in rings:
                output.append(densify(ring, pointsNumber))
            return QgsGeometry.fromPolygon(output)
    else:
        if geometry.isMultipart():
            lines = geometry.asMultiPolyline()
            for points in lines:
                output.append(densify(points, pointsNumber))
            return QgsGeometry.fromMultiPolyline(output)
        else:
            points = geometry.asPolyline()
            output = densify(points, pointsNumber)
            return QgsGeometry.fromPolyline(output)
 def testFromMultiLine(self):
     myMultiPolyline = QgsGeometry.fromMultiPolyline(
         [[QgsPoint(0, 0), QgsPoint(1, 1)],
          [QgsPoint(0, 1), QgsPoint(2, 1)]])
     myMessage = ('Expected:\n%s\nGot:\n%s\n' %
                  (QGis.WKBMultiLineString, myMultiPolyline.type()))
     assert myMultiPolyline.wkbType() == QGis.WKBMultiLineString, myMessage
Exemple #5
0
    def getTree(self, point):
        """
        Does the work. Tracks the graph up- or downstream.
        :param point: The node from which the tracking should be started
        """
        QApplication.setOverrideCursor(Qt.WaitCursor)
        upstream = False
        if self.direction == "upstream":
            upstream = True

        self.rubberBand.reset()

        nodes, edges = self.networkAnalyzer.getTree(point, upstream)
        polylines = self.networkAnalyzer.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.fromMultiPolyline(filtered_polylines),
                                    self.networkAnalyzer.getNodeLayer())

        self.treeChanged.emit(nodes, edges)

        QApplication.restoreOverrideCursor()
Exemple #6
0
 def densifyGeometry(self, geometry, pointsNumber, isPolygon):
     output = []
     if isPolygon:
         if geometry.isMultipart():
             polygons = geometry.asMultiPolygon()
             for poly in polygons:
                 p = []
                 for ring in poly:
                     p.append(self.densify(ring, pointsNumber))
                 output.append(p)
             return QgsGeometry.fromMultiPolygon(output)
         else:
             rings = geometry.asPolygon()
             for ring in rings:
                 output.append(self.densify(ring, pointsNumber))
             return QgsGeometry.fromPolygon(output)
     else:
         if geometry.isMultipart():
             lines = geometry.asMultiPolyline()
             for points in lines:
                 output.append(self.densify(points, pointsNumber))
             return QgsGeometry.fromMultiPolyline(output)
         else:
             points = geometry.asPolyline()
             output = self.densify(points, pointsNumber)
             return QgsGeometry.fromPolyline(output)
Exemple #7
0
 def densifyGeometry(self, geometry, interval, isPolygon):
     output = []
     if isPolygon:
         if geometry.isMultipart():
             polygons = geometry.asMultiPolygon()
             for poly in polygons:
                 p = []
                 for ring in poly:
                     p.append(self.densify(ring, interval))
                 output.append(p)
             return QgsGeometry.fromMultiPolygon(output)
         else:
             rings = geometry.asPolygon()
             for ring in rings:
                 output.append(self.densify(ring, interval))
             return QgsGeometry.fromPolygon(output)
     else:
         if geometry.isMultipart():
             lines = geometry.asMultiPolyline()
             for points in lines:
                 output.append(self.densify(points, interval))
             return QgsGeometry.fromMultiPolyline(output)
         else:
             points = geometry.asPolyline()
             output = self.densify(points, interval)
             return QgsGeometry.fromPolyline(output)
Exemple #8
0
    def toQgsGeometry(self):
        count = len(self.lines)
        if count > 1:
            lines = [lineToQgsPolyline(line) for line in self.lines]
            return QgsGeometry.fromMultiPolyline(lines)

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

        return QgsGeometry()
Exemple #9
0
  def toQgsGeometry(self):
    count = len(self.lines)
    if count > 1:
      lines = map(lineToQgsPolyline, self.lines)
      return QgsGeometry.fromMultiPolyline(lines)

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

    return QgsGeometry()
Exemple #10
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
     isMulti = QgsWKBTypes.isMultiType(int(layer.wkbType()))
     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.fromMultiPoint(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.fromMultiPolyline(nodes)
         else:
             nodes = geom.asPolyline()
             nodes = nodes[::-1]
             flippedFeatureGeom = QgsGeometry.fromPolyline(nodes)
     elif geomType == 2:
         if isMulti:
             nodes = geom.asMultiPolygon()
             for idx, part in enumerate(nodes):
                 nodes[idx] = part[::-1]
             flippedFeatureGeom = QgsGeometry.fromMultiPolygon(nodes)
         else:
             nodes = geom.asPolygon()
             nodes = nodes[::-1]
             flippedFeatureGeom = QgsGeometry.fromPolygon(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]
 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
     isMulti = QgsWKBTypes.isMultiType(int(layer.wkbType()))
     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.fromMultiPoint(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.fromMultiPolyline(nodes)
         else:
             nodes = geom.asPolyline()
             nodes = nodes[::-1]
             flippedFeatureGeom = QgsGeometry.fromPolyline(nodes)         
     elif geomType == 2:
         if isMulti:
             nodes = geom.asMultiPolygon()                
             for idx, part in enumerate(nodes):
                 nodes[idx] = part[::-1]
             flippedFeatureGeom = QgsGeometry.fromMultiPolygon(nodes)                
         else:
             nodes = geom.asPolygon()
             nodes = nodes[::-1]
             flippedFeatureGeom = QgsGeometry.fromPolygon(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]
 def merge_geoms(self, group):
     geoms = [self.edge_geoms[line]['wkt'] for line in group]
     line_segms = []
     for line_wkt in geoms:
         line = QgsGeometry.fromWkt(line_wkt)
         if line.wkbType() == 2:
             line_segms.append([QgsPoint(i[0], i[1]) for i in line.asPolyline()])
         elif line.wkbType() == 5:
             for segm in line.asGeometryCollection():
                 line_segms.append([QgsPoint(i[0], i[1]) for i in segm.asPolyline()])
     ml_geom = QgsGeometry.fromMultiPolyline(line_segms)
     return ml_geom.exportToWkt()
    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.fromPoint(QgsPointXY(1, 2)))
        f1.setAttributes(["test", 123])
        self.assertTrue(layer.addFeature(f1))

        f2 = QgsFeature(layer.fields(), 2)
        f2.setGeometry(QgsGeometry.fromPoint(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.fromMultiPolyline(multiline))
        f1.setAttributes(["test", 123])
        self.assertTrue(layer.addFeatures([f1]))
        self.assertFalse(layer.commitChanges())
    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.fromPoint(QgsPointXY(1, 2)))
        f1.setAttributes(["test", 123])
        self.assertTrue(layer.addFeature(f1))

        f2 = QgsFeature(layer.fields(), 2)
        f2.setGeometry(QgsGeometry.fromPoint(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.fromMultiPolyline(multiline))
        f1.setAttributes(["test", 123])
        self.assertTrue(layer.addFeatures([f1]))
        self.assertFalse(layer.commitChanges())
Exemple #15
0
 def testMeasureMultiLine(self):
     #   +-+ +-+-+
     #   | | |   |
     # +-+ + +   +-+
     linestring = QgsGeometry.fromMultiPolyline(
         [
             [QgsPoint(0, 0), QgsPoint(1, 0), QgsPoint(1, 1), QgsPoint(2, 1), QgsPoint(2, 0)],
             [QgsPoint(3, 0), QgsPoint(3, 1), QgsPoint(5, 1), QgsPoint(5, 0), QgsPoint(6, 0)],
         ]
     )
     da = QgsDistanceArea()
     length = da.measure(linestring)
     myMessage = "Expected:\n%f\nGot:\n%f\n" % (9, length)
     assert length == 9, myMessage
 def merge_geoms(self, group):
     geoms = [self.edge_geoms[line]['wkt'] for line in group]
     line_segms = []
     for line_wkt in geoms:
         line = QgsGeometry.fromWkt(line_wkt)
         if line.wkbType() == 2:
             line_segms.append(
                 [QgsPoint(i[0], i[1]) for i in line.asPolyline()])
         elif line.wkbType() == 5:
             for segm in line.asGeometryCollection():
                 line_segms.append(
                     [QgsPoint(i[0], i[1]) for i in segm.asPolyline()])
     ml_geom = QgsGeometry.fromMultiPolyline(line_segms)
     return ml_geom.exportToWkt()
 def testMeasureMultiLine(self):
     #   +-+ +-+-+
     #   | | |   |
     # +-+ + +   +-+
     linestring = QgsGeometry.fromMultiPolyline(
         [
             [QgsPoint(0, 0), QgsPoint(1, 0), QgsPoint(1, 1), QgsPoint(2, 1), QgsPoint(2, 0), ],
             [QgsPoint(3, 0), QgsPoint(3, 1), QgsPoint(5, 1), QgsPoint(5, 0), QgsPoint(6, 0), ]
         ]
     )
     da = QgsDistanceArea()
     length = da.measureLength(linestring)
     myMessage = ('Expected:\n%f\nGot:\n%f\n' %
                  (9, length))
     assert length == 9, myMessage
Exemple #18
0
    def parse_geometry(gr):
        """node s ISLH grafikou"""

        g = gr[0] #obraz ma jen jeden prvek

        geom = (
                QgsGeometry.fromPoint(islh_parser.parse_point(g)) if g.tag == 'B'
                else QgsGeometry.fromPolyline(islh_parser.parse_line(g)) if g.tag == 'L'
                else QgsGeometry.fromMultiPoint(islh_parser.parse_multipoint(g)) if g.tag == 'MB'
                else QgsGeometry.fromMultiPolyline(islh_parser.parse_multiline(g)) if g.tag == 'ML'
                else QgsGeometry.fromPolygon(islh_parser.parse_polygon(g)) if g.tag == 'P'
                else QgsGeometry.fromMultiPolygon(islh_parser.parse_multipolygon(g)) if g.tag == 'MP' 
                else None) 

        return(geom)
Exemple #19
0
 def testMeasureMultiLine(self):
     #   +-+ +-+-+
     #   | | |   |
     # +-+ + +   +-+
     linestring = QgsGeometry.fromMultiPolyline(
         [
             [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
def extractlinestrings(f):
    """If input is a geometrycollection returns a linestring or multilinestring built from the the input"""
    g = togeometry(f)

    # Short circuit
    if g.type() == QGis.Line:
        return g

    singlegeoms = extractassingle(f)
    lines = [g for g in singlegeoms if g.type() == QGis.Line ]
    if lines:
        if len(lines) > 1:
            return QgsGeometry.fromMultiPolyline([g.asPolyline() for g in lines])
        else:
            return lines[0]
    return None
def create_geom_line(coordinates, maincall=True):
    """recursive function to make QgsPoints from coordinates (point, linestring, multilinestring)"""
    if len(coordinates) > 0 and type(coordinates[0]) == list:
        list_of_geoms = [
            create_geom_line(coord, False) for coord in coordinates
        ]

        if maincall:
            if type(list_of_geoms[0]) == QgsPoint:
                return QgsGeometry.fromPolyline(list_of_geoms)
            else:
                return QgsGeometry.fromMultiPolyline(list_of_geoms)
        else:
            return list_of_geoms
    else:
        return QgsPoint(coordinates[0], coordinates[1])
Exemple #22
0
def extractlinestrings(f):
    """If input is a geometrycollection returns a linestring or multilinestring built from the the input"""
    g = togeometry(f)

    # Short circuit
    if g.type() == QGis.Line:
        return g

    singlegeoms = extractassingle(f)
    lines = [g for g in singlegeoms if g.type() == QGis.Line]
    if lines:
        if len(lines) > 1:
            return QgsGeometry.fromMultiPolyline(
                [g.asPolyline() for g in lines])
        else:
            return lines[0]
    return None
Exemple #23
0
 def getTree(self,point):
     backupCursor = self.canvas.cursor()
     self.canvas.setCursor(Qt.WaitCursor)
     upstream = False
     if self.direction == "upstream":
         upstream = True
     
     self.rubberBand.reset()
     
     edges = self.networkAnalyzer.getTree(point,upstream)
     polylines = self.networkAnalyzer.getEdgeGeometry( [edge[2]['feature'] for edge in edges] )
     
     # Fix for QGIS < 2.0
     filteredPolylines = [pl for pl in polylines if len(pl) > 0]
     
     self.rubberBand.addGeometry( QgsGeometry.fromMultiPolyline( filteredPolylines ), self.networkAnalyzer.getNodeLayer() )
     
     self.canvas.setCursor(backupCursor)
Exemple #24
0
    def __line_grid(self, feature, wkb_type):

        if feature.geometry().isMultipart():
            polylines = feature.geometry().asMultiPolyline()
            cleaned_polylines = list()
            for polyline in polylines:
                snapped_points = self.__points_to_grid(polyline)
                if len(snapped_points) < 2:
                    continue
                cleaned_polyline = snapped_points
                cleaned_polylines.append(cleaned_polyline)
            geom = QgsGeometry.fromMultiPolyline([x for x in cleaned_polylines])
        else:
            points = feature.geometry().asPolyline()
            snapped_points = self.__points_to_grid(points)
            geom = QgsGeometry.fromPolyline(snapped_points)

        return geom
Exemple #25
0
def spGeometry(geom, type):
    def split(L):
        n = len(L)/2
        return [L[:n], L[n:]]
    if type == "Polygon":
        coords = [map(lambda p: QgsPoint(*p), zip(*split(list(po.do_slot('coords')))))
                 for po in geom.do_slot('Polygons')]
        coords = QgsGeometry.fromMultiPolygon([coords])
    elif type == "LineString":
        coords = [map(lambda p: QgsPoint(*p), zip(*split(list(line.do_slot('coords')))))
                 for line in geom.do_slot('Lines')]
        coords = QgsGeometry.fromMultiPolyline(coords)
    elif type == "Point":
        coords = [QgsPoint(*geom)]
        coords = QgsGeometry.fromMultiPoint(coords)
    else:
        raise Exception("unable to convert geometries")
    return coords
Exemple #26
0
    def build_qgis_feature(self, vector_item):
        """
        Constructs a QGIS feature for rendering
        :param vector_item: The item returned
        :return a VectorFeature that can be rendered by QGIS
        """

        feature = VectorFeature()
        geometry = vector_item[KEY_JSON_GEOMETRY]
        coordinates = geometry[KEY_JSON_GEOMETRY_COORDINATES]
        geometry_type = geometry[KEY_JSON_GEOMETRY_TYPE]
        if geometry_type == u'Point':
            feature.setGeometry(QgsGeometry.fromPoint(self.get_point_from_json(coordinates)))
        elif geometry_type == u'LineString':
            feature.setGeometry(QgsGeometry.fromPolyline(self.get_linestring_from_json(coordinates)))
        elif geometry_type == u'MultiPoint':
            feature.setGeometry(QgsGeometry.fromMultiPoint(self.get_linestring_from_json(coordinates)))
        elif geometry_type == u'Polygon':
            feature.setGeometry(QgsGeometry.fromPolygon(self.get_polygon_from_json(coordinates)))
        elif geometry_type == u'MultiLineString':
            feature.setGeometry(QgsGeometry.fromMultiPolyline(self.get_polygon_from_json(coordinates)))
        elif geometry_type == u'MultiPolygon':
            feature.setGeometry(QgsGeometry.fromMultiPolygon(self.get_multipolygon_from_json(coordinates)))
        else:
            QgsMessageLog.instance().logMessage(u"Encountered odd geometry type: " + geometry_type, TAG_NAME,
                                                level=QgsMessageLog.CRITICAL)
        feature.geometry_type = geometry_type
        attributes = self.get_attributes_from_json(vector_item[KEY_JSON_PROPERTIES])
        fields = QgsFields()
        values = []
        for key, value in attributes.iteritems():
            type_value = None
            if key.endswith(u'int'):
                type_value = QVariant.Int
            elif key.endswith(u'dbl'):
                type_value = QVariant.Double
            else:
                type_value = QVariant.String
            fields.append(QgsField(key, type_value))
            values.append(value)
        feature.setFields(fields)
        feature.setAttributes(values)
        return feature
Exemple #27
0
    def getTree(self, point):
        backupCursor = self.canvas.cursor()
        self.canvas.setCursor(Qt.WaitCursor)
        upstream = False
        if self.direction == "upstream":
            upstream = True

        self.rubberBand.reset()

        edges = self.networkAnalyzer.getTree(point, upstream)
        polylines = self.networkAnalyzer.getEdgeGeometry(
            [edge[2]['feature'] for edge in edges])

        # Fix for QGIS < 2.0
        filteredPolylines = [pl for pl in polylines if len(pl) > 0]

        self.rubberBand.addGeometry(
            QgsGeometry.fromMultiPolyline(filteredPolylines),
            self.networkAnalyzer.getNodeLayer())

        self.canvas.setCursor(backupCursor)
Exemple #28
0
    def getTree(self, point):
        """
        Does the work. Tracks the graph up- or downstream.
        :param point: The node from which the tracking should be started
        """
        QApplication.setOverrideCursor(Qt.WaitCursor)
        upstream = False
        if self.direction == "upstream":
            upstream = True

        self.rubberBand.reset()

        edges = self.networkAnalyzer.getTree(point, upstream)
        polylines = self.networkAnalyzer.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.fromMultiPolyline(filtered_polylines),
                                    self.networkAnalyzer.getNodeLayer())

        QApplication.restoreOverrideCursor()
Exemple #29
0
    def testAdjacentVertex(self):
        # 2-+-+-+-+-3
        # |         |
        # + 6-+-+-7 +
        # | |     | |
        # + + 9-+-8 +
        # | |       |
        # ! 5-+-+-+-4 !
        # |
        # 1-+-+-+-+-0 !
        polyline = QgsGeometry.fromPolyline(
          [ QgsPoint(5,0), QgsPoint(0,0), QgsPoint(0,4), QgsPoint(5,4), QgsPoint(5,1), QgsPoint(1,1), QgsPoint(1,3), QgsPoint(4,3), QgsPoint(4,2), QgsPoint(2,2) ]
        )

        # don't crash
        (before,after) = polyline.adjacentVertices(-100)
        if TestQgsGeometry.wkbPtr:
          # CHANGE previous implementation returned (-101,-99) here
          assert before==-1 and after==-1, "Expected (-1,-1), Got:(%d,%d)" % (before,after)

        for i in range(0, 10):
                (before,after) = polyline.adjacentVertices(i)
                if i==0:
                        assert before==-1 and after==1, "Expected (0,1), Got:(%d,%d)" % (before,after)
                elif i==9:
                        assert before==i-1 and after==-1, "Expected (0,1), Got:(%d,%d)" % (before,after)
                else:
                        assert before==i-1 and after==i+1, "Expected (0,1), Got:(%d,%d)" % (before,after)

        (before,after) = polyline.adjacentVertices(100)
        if TestQgsGeometry.wkbPtr:
          # CHANGE previous implementation returned (99,101) here
          assert before==-1 and after==-1, "Expected (-1,-1), Got:(%d,%d)" % (before,after)

        #   2-3 6-+-7
        #   | | |   |
        # 0-1 4 5   8-9
        polyline = QgsGeometry.fromMultiPolyline(
          [
            [ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,0), ],
            [ QgsPoint(3,0), QgsPoint(3,1), QgsPoint(5,1), QgsPoint(5,0), QgsPoint(6,0), ]
          ]
        )

        (before,after) = polyline.adjacentVertices(-100)
        assert before==-1 and after==-1, "Expected (-1,-1), Got:(%d,%d)" % (before,after)

        for i in range(0,10):
                (before,after) = polyline.adjacentVertices(i)

                if i==0 or i==5:
                        assert before==-1 and after==i+1, "Expected (-1,%d), Got:(%d,%d)" % (i+1,before,after)
                elif i==4 or i==9:
                        assert before==i-1 and after==-1, "Expected (%d,-1), Got:(%d,%d)" % (i-1,before,after)
                else:
                        assert before==i-1 and after==i+1, "Expected (%d,%d), Got:(%d,%d)" % (i-1,i+1,before,after)

        (before,after) = polyline.adjacentVertices(100)
        assert before==-1 and after==-1, "Expected (-1,-1), Got:(%d,%d)" % (before,after)

        # 5---4
        # |   |
        # | 2-3
        # | |
        # 0-1
        polygon = QgsGeometry.fromPolygon(
          [[
            QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(0,2), QgsPoint(0,0),
          ]]
        )

        (before,after) = polygon.adjacentVertices(-100)
        assert before==-1 and after==-1, "Expected (-1,-1), Got:(%d,%d)" % (before,after)

        for i in range(0,7):
                (before,after) = polygon.adjacentVertices(i)

                if i==0 or i==6:
                        assert before==5 and after==1, "Expected (5,1), Got:(%d,%d)" % (before,after)
                else:
                        assert before==i-1 and after==i+1, "Expected (%d,%d), Got:(%d,%d)" % (i-1,i+1,before,after)

        (before,after) = polygon.adjacentVertices(100)
        assert before==-1 and after==-1, "Expected (-1,-1), Got:(%d,%d)" % (before,after)

        # 3-+-+-2
        # |     |
        # + 8-7 +
        # | | | |
        # + 5-6 +
        # |     |
        # 0-+-+-1
        polygon = QgsGeometry.fromPolygon(
          [
            [ QgsPoint(0,0), QgsPoint(3,0), QgsPoint(3,3), QgsPoint(0,3), QgsPoint(0,0) ],
            [ QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(1,2), QgsPoint(1,1) ],
          ]
        )

        (before,after) = polygon.adjacentVertices(-100)
        assert before==-1 and after==-1, "Expected (-1,-1), Got:(%d,%d)" % (before,after)

        for i in range(0,8):
                (before,after) = polygon.adjacentVertices(i)

                if i==0 or i==4:
                        assert before==3 and after==1, "Expected (3,1), Got:(%d,%d)" % (before,after)
                elif i==5:
                        assert before==8 and after==6, "Expected (2,0), Got:(%d,%d)" % (before,after)
                else:
                        assert before==i-1 and after==i+1, "Expected (%d,%d), Got:(%d,%d)" % (i-1,i+1,before,after)

        (before,after) = polygon.adjacentVertices(100)
        assert before==-1 and after==-1, "Expected (-1,-1), Got:(%d,%d)" % (before,after)

        # 5-+-4 0-+-9
        # |   | |   |
        # | 2-3 1-2 |
        # | |     | |
        # 0-1     7-8
        polygon = QgsGeometry.fromMultiPolygon(
          [
            [ [ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(0,2), QgsPoint(0,0), ] ],
            [ [ QgsPoint(4,0), QgsPoint(5,0), QgsPoint(5,2), QgsPoint(3,2), QgsPoint(3,1), QgsPoint(4,1), QgsPoint(4,0), ] ]
          ]
        )

        (before,after) = polygon.adjacentVertices(-100)
        assert before==-1 and after==-1, "Expected (-1,-1), Got:(%d,%d)" % (before,after)

        for i in range(0,14):
                (before,after) = polygon.adjacentVertices(i)

                if i==0 or i==6:
                        assert before==5 and after==1, "Expected (5,1), Got:(%d,%d)" % (before,after)
                elif i==7 or i==13:
                        assert before==12 and after==8, "Expected (12,8), Got:(%d,%d)" % (before,after)
                else:
                        assert before==i-1 and after==i+1, "Expected (%d,%d), Got:(%d,%d)" % (i-1,i+1,before,after)

        (before,after) = polygon.adjacentVertices(100)
        assert before==-1 and after==-1, "Expected (-1,-1), Got:(%d,%d)" % (before,after)
Exemple #30
0
    def canvasReleaseEvent(self, event):

        if not self.mouse_clicked:
            return

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

            self.mouse_clicked = False

            # No pipe snapped: notify user
            if self.snapped_pipe_id is None:

                self.iface.messageBar().pushMessage(
                    Parameters.plug_in_name,
                    'You need to snap the cursor to a pipe to add a valve.',
                    QgsMessageBar.INFO, 5)

            # A pipe has been snapped
            else:

                request = QgsFeatureRequest().setFilterFid(
                    self.snapped_pipe_id)
                feats = self.params.pipes_vlay.getFeatures(request)
                features = [feat for feat in feats]
                if len(features) == 1:

                    # Check whether the pipe has a start and an end node
                    (start_node, end_node) = NetworkUtils.find_start_end_nodes(
                        self.params, features[0].geometry())

                    if not start_node or not end_node:
                        self.iface.messageBar().pushMessage(
                            Parameters.plug_in_name,
                            'The pipe is missing the start or end nodes.',
                            QgsMessageBar.WARNING, 5)  # TODO: softcode
                        return

                    # Find endnode closest to valve position
                    dist_1 = start_node.geometry().distance(
                        QgsGeometry.fromPoint(self.snapped_vertex))
                    dist_2 = end_node.geometry().distance(
                        QgsGeometry.fromPoint(self.snapped_vertex))

                    # Get the attributes of the closest junction
                    (start_node, end_node) = NetworkUtils.find_start_end_nodes(
                        self.params, features[0].geometry(), False, True, True)
                    if dist_1 < dist_2:
                        closest_junction_ft = start_node
                    else:
                        closest_junction_ft = end_node

                    # Create the valve
                    diameter = features[0].attribute(Pipe.field_name_diameter)
                    # diameter = self.data_dock.txt_valve_diameter.text()
                    minor_loss = self.data_dock.txt_valve_minor_loss.text()
                    selected_type = self.data_dock.cbo_valve_type.itemData(
                        self.data_dock.cbo_valve_type.currentIndex())
                    if selected_type != Valve.type_gpv:
                        setting = self.data_dock.txt_valve_setting.text()
                    else:
                        valve_curve = self.data_dock.cbo_valve_curve.itemData(
                            self.data_dock.cbo_valve_curve.currentIndex())
                        if valve_curve is not None:
                            setting = valve_curve.id
                        else:
                            setting = None

                    # Pump status
                    valve_status = self.data_dock.cbo_valve_status.itemData(
                        self.data_dock.cbo_valve_status.currentIndex())

                    # Valve description
                    valve_desc = self.data_dock.txt_valve_desc.text()

                    # Valve tag
                    valve_tag = self.data_dock.cbo_valve_tag.currentText()

                    try:
                        LinkHandler.create_new_pumpvalve(
                            self.params, self.data_dock, features[0],
                            closest_junction_ft, self.snapped_vertex,
                            self.params.valves_vlay, {
                                Valve.field_name_diameter: diameter,
                                Valve.field_name_minor_loss: minor_loss,
                                Valve.field_name_setting: setting,
                                Valve.field_name_type: selected_type,
                                Valve.field_name_status: valve_status,
                                Valve.field_name_description: valve_desc,
                                Valve.field_name_tag: valve_tag
                            })

                    except PumpValveCreationException as ex:
                        self.iface.messageBar().pushMessage(
                            Parameters.plug_in_name, ex.message,
                            QgsMessageBar.INFO, 5)

        elif event.button() == Qt.RightButton:

            self.mouse_clicked = False

            # Check whether it clicked on a valve vertex
            if len(
                    NetworkUtils.find_adjacent_links(
                        self.params, self.snapped_vertex)['valves']) == 0:
                return

            menu = QMenu()
            diameter_action = menu.addAction(
                'Change diameter...')  # TODO: softcode
            invert_action = menu.addAction(
                'Flip orientation')  # TODO: softcode
            action = menu.exec_(self.iface.mapCanvas().mapToGlobal(
                QPoint(event.pos().x(),
                       event.pos().y())))

            request = QgsFeatureRequest().setFilterFid(self.snapped_pipe_id)
            feats = self.params.pipes_vlay.getFeatures(request)
            features = [feat for feat in feats]
            if len(features) == 1:
                adj_links = NetworkUtils.find_links_adjacent_to_link(
                    self.params, self.params.pipes_vlay, features[0], True,
                    True, False)

                for valve_ft in adj_links['valves']:

                    if action == diameter_action:
                        old_diam = valve_ft.attribute(
                            Valve.field_name_diameter)
                        self.diameter_dialog = DiameterDialog(
                            self.iface.mainWindow(), self.params, old_diam)
                        self.diameter_dialog.exec_(
                        )  # Exec creates modal dialog
                        new_diameter = self.diameter_dialog.get_diameter()
                        if new_diameter is None:
                            return

                        # Update valve diameter
                        vector_utils.update_attribute(
                            self.params.valves_vlay, valve_ft,
                            Valve.field_name_diameter, new_diameter)

                        # Modify pipes diameters
                        adj_pipes_fts = NetworkUtils.find_links_adjacent_to_link(
                            self.params, self.params.valves_vlay, valve_ft,
                            False, True, True)

                        if adj_pipes_fts:

                            for adj_pipe_ft in adj_pipes_fts['pipes']:

                                vector_utils.update_attribute(
                                    self.params.pipes_vlay, adj_pipe_ft,
                                    Pipe.field_name_diameter, new_diameter)

                            self.iface.messageBar().pushMessage(
                                Parameters.plug_in_name,
                                'Diameters of pipes adjacent to valve updated.',
                                QgsMessageBar.INFO, 5)  # TODO: softcode

                    elif action == invert_action:

                        request = QgsFeatureRequest().setFilterFid(
                            self.snapped_pipe_id)
                        feats = self.params.pipes_vlay.getFeatures(request)
                        features = [feat for feat in feats]
                        if len(features) == 1:
                            adj_links = NetworkUtils.find_links_adjacent_to_link(
                                self.params, self.params.pipes_vlay,
                                features[0], True, True, False)

                            for adj_link in adj_links['valves']:
                                adj_link_pts = adj_link.geometry().asPolyline()
                                for adj_link_pt in adj_link_pts:
                                    if NetworkUtils.points_overlap(
                                            adj_link_pt, self.snapped_vertex,
                                            self.params.tolerance):

                                        geom = adj_link.geometry()

                                        if geom.wkbType(
                                        ) == QGis.WKBMultiLineString:
                                            nodes = geom.asMultiPolyline()
                                            for line in nodes:
                                                line.reverse()
                                            newgeom = QgsGeometry.fromMultiPolyline(
                                                nodes)
                                            self.params.valves_vlay.changeGeometry(
                                                adj_link.id(), newgeom)

                                        if geom.wkbType(
                                        ) == QGis.WKBLineString:
                                            nodes = geom.asPolyline()
                                            nodes.reverse()
                                            newgeom = QgsGeometry.fromPolyline(
                                                nodes)
                                            self.params.valves_vlay.changeGeometry(
                                                adj_link.id(), newgeom)

                                        self.iface.mapCanvas().refresh()

                                        break
def find_changes(line_layer, buf_layer, line_id_col, buf_id_col, writer,
                 remain_fields):
    """
    Find the geometry difference of the line_layer and the buf_layer,
    line_layer features that fall outside of the buf_layer are copied into the
    output layer.

    If part of a feature is within the buffer but part of it is not, the
    feature is split and only the part that outside of the buffer is copied.

    If the output feature happens to be multipart, EACH part of the feature
    is compared against the length tolerance. Only parts exceed the tolerance
    are kept. Then all parts are merged back into one feature.

    So in the output layer, features maybe of singleparts or multipart.
    @param  line_layer:        Layer
    @type   line_layer:        QgsVectorLayer
    @param  buf_layer:         Buffer Layer
    @type   buf_layer:         QgsVectorLayer
    @param  line_id_col:       Line id column name
    @type   line_id_col:       string
    @param  buf_id_col:        Buffer id column name
    @type   buf_id_col:        string
    @param  writer:            Writer of layer
    @type   writer:            QgsVectorFileWriter
    @param  remain_fields:     List of fields
    @type   remain_fields:     list

    @return:    Resulting ids
    @rtype:     list
    """
    result_ids = []
    out_feat = QgsFeature()

    for line_feat in line_layer.getFeatures():

        if line_feat[line_id_col] != 0:

            expr = QgsExpression('{} = {}'.format(buf_id_col,
                                                  line_feat[line_id_col]))
            for buf_feat in buf_layer.getFeatures(QgsFeatureRequest(expr)):

                if not line_feat.geometry().within(buf_feat.geometry()):

                    diff_geom = line_feat.geometry().difference(
                        buf_feat.geometry())

                    if diff_geom.isMultipart():

                        geom_multi = diff_geom.asMultiPolyline()
                        updated_geom_multi = []

                        for i in geom_multi:

                            geom_single = QgsGeometry.fromPolyline(i)
                            if geom_single.length() >= 50:
                                updated_geom_multi.append(i)

                        if updated_geom_multi:
                            out_feat.setGeometry(
                                QgsGeometry.fromMultiPolyline(
                                    updated_geom_multi))
                            attrs = ["large change", "Not Checked", ""]
                            for remain_field in remain_fields:
                                attrs.append(line_feat[remain_field])
                            out_feat.setAttributes(attrs)
                            writer.addFeature(out_feat)
                            result_ids.append(int(line_feat[line_id_col]))
                    else:

                        if diff_geom.length() >= 50:
                            out_feat.setGeometry(diff_geom)
                            attrs = ["large change", "Not Checked", ""]
                            for remain_field in remain_fields:
                                attrs.append(line_feat[remain_field])
                            out_feat.setAttributes(attrs)
                            writer.addFeature(out_feat)
                            result_ids.append(int(line_feat[line_id_col]))
    return result_ids
Exemple #32
0
    def processAlgorithm(self, parameters, context, feedback):
        layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)
        hSpacing = self.getParameterValue(self.HSPACING)
        vSpacing = self.getParameterValue(self.VSPACING)

        if hSpacing <= 0 or vSpacing <= 0:
            raise GeoAlgorithmExecutionException(
                self.tr('Invalid grid spacing: {0}/{1}').format(hSpacing, vSpacing))

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.fields(), layer.wkbType(), layer.crs(),
                                                                     context)

        features = QgsProcessingUtils.getFeatures(layer, context)
        total = 100.0 / QgsProcessingUtils.featureCount(layer, context)

        for current, f in enumerate(features):
            geom = f.geometry()
            geomType = geom.wkbType()

            if geomType == QgsWkbTypes.Point:
                points = self._gridify([geom.asPoint()], hSpacing, vSpacing)
                newGeom = QgsGeometry.fromPoint(points[0])
            elif geomType == QgsWkbTypes.MultiPoint:
                points = self._gridify(geom.aMultiPoint(), hSpacing, vSpacing)
                newGeom = QgsGeometry.fromMultiPoint(points)
            elif geomType == QgsWkbTypes.LineString:
                points = self._gridify(geom.asPolyline(), hSpacing, vSpacing)
                if len(points) < 2:
                    QgsMessageLog.logMessage(self.tr('Failed to gridify feature with FID {0}').format(f.id()), self.tr('Processing'), QgsMessageLog.INFO)
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromPolyline(points)
            elif geomType == QgsWkbTypes.MultiLineString:
                polyline = []
                for line in geom.asMultiPolyline():
                    points = self._gridify(line, hSpacing, vSpacing)
                    if len(points) > 1:
                        polyline.append(points)
                if len(polyline) <= 0:
                    QgsMessageLog.logMessage(self.tr('Failed to gridify feature with FID {0}').format(f.id()), self.tr('Processing'), QgsMessageLog.INFO)
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromMultiPolyline(polyline)

            elif geomType == QgsWkbTypes.Polygon:
                polygon = []
                for line in geom.asPolygon():
                    points = self._gridify(line, hSpacing, vSpacing)
                    if len(points) > 1:
                        polygon.append(points)
                if len(polygon) <= 0:
                    QgsMessageLog.logMessage(self.tr('Failed to gridify feature with FID {0}').format(f.id()), self.tr('Processing'), QgsMessageLog.INFO)
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromPolygon(polygon)
            elif geomType == QgsWkbTypes.MultiPolygon:
                multipolygon = []
                for polygon in geom.asMultiPolygon():
                    newPolygon = []
                    for line in polygon:
                        points = self._gridify(line, hSpacing, vSpacing)
                        if len(points) > 2:
                            newPolygon.append(points)

                    if len(newPolygon) > 0:
                        multipolygon.append(newPolygon)

                if len(multipolygon) <= 0:
                    QgsMessageLog.logMessage(self.tr('Failed to gridify feature with FID {0}').format(f.id()), self.tr('Processing'), QgsMessageLog.INFO)
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromMultiPolygon(multipolygon)

            if newGeom is not None:
                feat = QgsFeature()
                feat.setGeometry(newGeom)
                feat.setAttributes(f.attributes())
                writer.addFeature(feat)

            feedback.setProgress(int(current * total))

        del writer
Exemple #33
0
    def processAlgorithm(self, progress):
        layer = dataobjects.getObjectFromUri(
            self.getParameterValue(self.INPUT))
        index = self.getParameterValue(self.TYPE)

        splitNodes = False
        if index == 0:
            newType = QgsWkbTypes.Point
        elif index == 1:
            newType = QgsWkbTypes.Point
            splitNodes = True
        elif index == 2:
            newType = QgsWkbTypes.LineString
        elif index == 3:
            newType = QgsWkbTypes.MultiLineString
        elif index == 4:
            newType = QgsWkbTypes.Polygon
        else:
            newType = QgsWkbTypes.Point

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            layer.fields(), newType, layer.crs())

        features = vector.features(layer)
        total = 100.0 / len(features)

        for current, f in enumerate(features):
            geom = f.geometry()
            geomType = geom.wkbType()

            if geomType in [QgsWkbTypes.Point, QgsWkbTypes.Point25D]:
                if newType == QgsWkbTypes.Point:
                    writer.addFeature(f)
                else:
                    raise GeoAlgorithmExecutionException(
                        self.tr('Cannot convert from %s to %s', geomType, newType))
            elif geomType in [QgsWkbTypes.MultiPoint, QgsWkbTypes.MultiPoint25D]:
                if newType == QgsWkbTypes.Point and splitNodes:
                    points = geom.asMultiPoint()
                    for p in points:
                        feat = QgsFeature()
                        feat.setAttributes(f.attributes())
                        feat.setGeometry(QgsGeometry.fromPoint(p))
                        writer.addFeature(feat)
                elif newType == QgsWkbTypes.Point:
                    feat = QgsFeature()
                    feat.setAttributes(f.attributes())
                    feat.setGeometry(geom.centroid())
                    writer.addFeature(feat)
                else:
                    raise GeoAlgorithmExecutionException(
                        self.tr('Cannot convert from %s to %s', geomType, newType))
            elif geomType in [QgsWkbTypes.LineString, QgsWkbTypes.LineString25D]:
                if newType == QgsWkbTypes.Point and splitNodes:
                    points = geom.asPolyline()
                    for p in points:
                        feat = QgsFeature()
                        feat.setAttributes(f.attributes())
                        feat.setGeometry(QgsGeometry.fromPoint(p))
                        writer.addFeature(feat)
                elif newType == QgsWkbTypes.Point:
                    feat = QgsFeature()
                    feat.setAttributes(f.attributes())
                    feat.setGeometry(geom.centroid())
                    writer.addFeature(feat)
                elif newType == QgsWkbTypes.LineString:
                    writer.addFeature(f)
                else:
                    raise GeoAlgorithmExecutionException(
                        self.tr('Cannot convert from %s to %s', geomType, newType))
            elif geomType in [QgsWkbTypes.MultiLineString, QgsWkbTypes.MultiLineString25D]:
                if newType == QgsWkbTypes.Point and splitNodes:
                    lines = geom.asMultiPolyline()
                    for line in lines:
                        for p in line:
                            feat = QgsFeature()
                            feat.setAttributes(f.attributes())
                            feat.setGeometry(QgsGeometry.fromPoint(p))
                            writer.addFeature(feat)
                elif newType == QgsWkbTypes.Point:
                    feat = QgsFeature()
                    feat.setAttributes(f.attributes())
                    feat.setGeometry(geom.centroid())
                    writer.addFeature(feat)
                elif newType == QgsWkbTypes.LineString:
                    lines = geom.asMultiPolyline()
                    for line in lines:
                        feat = QgsFeature()
                        feat.setAttributes(f.attributes())
                        feat.setGeometry(QgsGeometry.fromPolyline(line))
                        writer.addFeature(feat)
                elif newType == QgsWkbTypes.MultiLineString:
                    writer.addFeature(f)
                else:
                    raise GeoAlgorithmExecutionException(
                        self.tr('Cannot convert from %s to %s', geomType, newType))
            elif geomType in [QgsWkbTypes.Polygon, QgsWkbTypes.Polygon25D]:
                if newType == QgsWkbTypes.Point and splitNodes:
                    rings = geom.asPolygon()
                    for ring in rings:
                        for p in ring:
                            feat = QgsFeature()
                            feat.setAttributes(f.attributes())
                            feat.setGeometry(QgsGeometry.fromPoint(p))
                            writer.addFeature(feat)
                elif newType == QgsWkbTypes.Point:
                    feat = QgsFeature()
                    feat.setAttributes(f.attributes())
                    feat.setGeometry(geom.centroid())
                    writer.addFeature(feat)
                elif newType == QgsWkbTypes.MultiLineString:
                    rings = geom.asPolygon()
                    feat = QgsFeature()
                    feat.setAttributes(f.attributes())
                    feat.setGeometry(QgsGeometry.fromMultiPolyline(rings))
                    writer.addFeature(feat)
                elif newType == QgsWkbTypes.Polygon:
                    writer.addFeature(f)
                else:
                    raise GeoAlgorithmExecutionException(
                        self.tr('Cannot convert from %s to %s', geomType, newType))
            elif geomType in [QgsWkbTypes.MultiPolygon, QgsWkbTypes.MultiPolygon25D]:
                if newType == QgsWkbTypes.Point and splitNodes:
                    polygons = geom.asMultiPolygon()
                    for polygon in polygons:
                        for line in polygon:
                            for p in line:
                                feat = QgsFeature()
                                feat.setAttributes(f.attributes())
                                feat.setGeometry(QgsGeometry.fromPoint(p))
                                writer.addFeature(feat)
                elif newType == QgsWkbTypes.Point:
                    feat = QgsFeature()
                    feat.setAttributes(f.attributes())
                    feat.setGeometry(geom.centroid())
                    writer.addFeature(feat)
                elif newType == QgsWkbTypes.LineString:
                    polygons = geom.asMultiPolygon()
                    for polygons in polygons:
                        feat = QgsFeature()
                        feat.setAttributes(f.attributes())
                        feat.setGeometry(QgsGeometry.fromPolyline(polygon))
                        writer.addFeature(feat)
                elif newType == QgsWkbTypes.Polygon:
                    polygons = geom.asMultiPolygon()
                    for polygon in polygons:
                        feat = QgsFeature()
                        feat.setAttributes(f.attributes())
                        feat.setGeometry(QgsGeometry.fromPolygon(polygon))
                        writer.addFeature(feat)
                elif newType in [QgsWkbTypes.MultiLineString, QgsWkbTypes.MultiPolygon]:
                    writer.addFeature(f)
                else:
                    raise GeoAlgorithmExecutionException(
                        self.tr('Cannot convert from %s to %s', geomType, newType))

            progress.setPercentage(int(current * total))

        del writer
Exemple #34
0
    def testBoundingBox(self):
        # 2-+-+-+-+-3
        # |         |
        # + 6-+-+-7 +
        # | |     | |
        # + + 9-+-8 +
        # | |       |
        # ! 5-+-+-+-4 !
        # |
        # 1-+-+-+-+-0 !
        points = [ QgsPoint(5,0), QgsPoint(0,0), QgsPoint(0,4), QgsPoint(5,4), QgsPoint(5,1), QgsPoint(1,1), QgsPoint(1,3), QgsPoint(4,3), QgsPoint(4,2), QgsPoint(2,2) ]
        polyline = QgsGeometry.fromPolyline(points)
        expbb = QgsRectangle(0,0,5,4)
        bb = polyline.boundingBox()
        assert expbb == bb, "Expected:\n%s\nGot:\n%s\n" % (expbb.toString(), bb.toString())

        #   2-3 6-+-7
        #   | | |   |
        # 0-1 4 5   8-9
        points = [
            [ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,0), ],
            [ QgsPoint(3,0), QgsPoint(3,1), QgsPoint(5,1), QgsPoint(5,0), QgsPoint(6,0), ]
          ]
        polyline = QgsGeometry.fromMultiPolyline(points)
        expbb = QgsRectangle(0,0,6,1)
        bb = polyline.boundingBox()
        assert expbb == bb, "Expected:\n%s\nGot:\n%s\n" % (expbb.toString(), bb.toString())

        # 5---4
        # |   |
        # | 2-3
        # | |
        # 0-1
        points = [[
            QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(0,2), QgsPoint(0,0),
          ]]
        polygon = QgsGeometry.fromPolygon(points)
        expbb = QgsRectangle(0,0,2,2)
        bb = polygon.boundingBox()
        assert expbb == bb, "Expected:\n%s\nGot:\n%s\n" % (expbb.toString(), bb.toString())

        # 3-+-+-2
        # |     |
        # + 8-7 +
        # | | | |
        # + 5-6 +
        # |     |
        # 0-+-+-1
        points = [
            [ QgsPoint(0,0), QgsPoint(3,0), QgsPoint(3,3), QgsPoint(0,3), QgsPoint(0,0) ],
            [ QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(1,2), QgsPoint(1,1) ],
          ]
        polygon = QgsGeometry.fromPolygon(points)
        expbb = QgsRectangle(0,0,3,3)
        bb = polygon.boundingBox()
        assert expbb == bb, "Expected:\n%s\nGot:\n%s\n" % (expbb.toString(), bb.toString())

        # 5-+-4 0-+-9
        # |   | |   |
        # | 2-3 1-2 |
        # | |     | |
        # 0-1     7-8
        points = [
            [ [ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(0,2), QgsPoint(0,0), ] ],
            [ [ QgsPoint(4,0), QgsPoint(5,0), QgsPoint(5,2), QgsPoint(3,2), QgsPoint(3,1), QgsPoint(4,1), QgsPoint(4,0), ] ]
          ]

        polygon = QgsGeometry.fromMultiPolygon(points)
        expbb = QgsRectangle(0,0,5,2)
        bb = polygon.boundingBox()
        assert expbb == bb, "Expected:\n%s\nGot:\n%s\n" % (expbb.toString(), bb.toString())
Exemple #35
0
    def onFinishSketch(self):
        '''
        Slot raised upon selecting to finish drawing the sketch spatial unit.
        '''
        stdmLayer = self.currentVectorLayer()
        layerWKBType = stdmLayer.wkbType()

        feature = QgsFeature(stdmLayer.fields())

        if self._mode == CAPTURE_POINT:
            feature.setGeometry(self._geometry)

        elif self._mode == CAPTURE_LINE or self._mode == CAPTURE_POLYGON:
            # Delete temporary rubber band
            if self._tempRubberBand != None:
                self.canvas.scene().removeItem(self._tempRubberBand)
                del self._tempRubberBand
                self._tempRubberBand = None

            # Validate geometries using number of points
            if self._mode == CAPTURE_LINE and len(self._captureList) < 2:
                self.stopCapturing()
                return

            if self._mode == CAPTURE_POLYGON and len(self._captureList) < 3:
                self.stopCapturing()
                return

            if self._mode == CAPTURE_LINE:
                if layerWKBType == QgsWkbTypes.LineString or layerWKBType == QgsWkbTypes.LineString25D:
                    self._geometry = QgsGeometry.fromPolyline(
                        self._captureList)

                elif layerWKBType == QgsWkbTypes.MultiLineString or layerWKBType == QgsWkbTypes.MultiLineString25D:
                    self._geometry = QgsGeometry.fromMultiPolyline(
                        self._captureList)

                else:
                    QMessageBox.critical(self.iface.mainWindow(), \
                                         QApplication.translate("StdmMapToolCreateFeature", "WKB Type Error"), \
                                         QApplication.translate("StdmMapToolCreateFeature",
                                                                "Cannot add feature. Unknown WKB type"))
                    return

                feature.setGeometry(self._geometry)

            # Polygon
            else:
                if layerWKBType == QgsWkbTypes.Polygon or layerWKBType == QgsWkbTypes.Polygon25D:
                    self._geometry = QgsGeometry.fromPolygon(
                        [self._captureList])

                elif layerWKBType == QgsWkbTypes.MultiPolygon or layerWKBType == QgsWkbTypes.MultiPolygon25D:
                    self._geometry = QgsGeometry.fromMultiPolygon(
                        [self._captureList])

                else:
                    QMessageBox.critical(self.iface.mainWindow(), \
                                         QApplication.translate("StdmMapToolCreateFeature", "WKB Type Error"), \
                                         QApplication.translate("StdmMapToolCreateFeature",
                                                                "Cannot add feature. Unknown WKB type"))
                    return

                feature.setGeometry(self._geometry)

                avoidIntersectionsReturn = feature.geometry(
                ).avoidIntersections()

                if avoidIntersectionsReturn == 3:
                    QMessageBox.critical(self.iface.mainWindow(), \
                                         QApplication.translate("StdmMapToolCreateFeature", "Error"), \
                                         QApplication.translate("StdmMapToolCreateFeature",
                                                                "An error was reported during intersection removal"))

                polyWkb = feature.geometry().asWkb()

                if polyWkb == None:
                    reason = ""
                    if avoidIntersectionsReturn != 2:
                        reason = QApplication.translate(
                            "StdmMapToolCreateFeature",
                            "The feature cannot be added because it's geometry is empty"
                        )
                    else:
                        reason = QApplication.translate(
                            "StdmMapToolCreateFeature",
                            "The feature cannot be added because it's geometry collapsed due to intersection avoidance"
                        )

                    QMessageBox.critical(self.iface.mainWindow(), \
                                         QApplication.translate("StdmMapToolCreateFeature", "Error"), \
                                         reason)

                    self.stopCapturing()
                    del feature
                    self._resetGeometry()
                    return

        stdmLayer.beginEditCommand(
            QApplication.translate("StdmMapToolCreateFeature",
                                   "Feature Added"))

        if self.addFeature(stdmLayer, feature):
            stdmLayer.endEditCommand()

        else:
            del feature
            self._resetGeometry()
            stdmLayer.destroyEditCommand()

        self.stopCapturing()

        self.canvas.refresh()
Exemple #36
0
    def processAlgorithm(self, parameters, context, feedback):
        layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)
        hSpacing = self.getParameterValue(self.HSPACING)
        vSpacing = self.getParameterValue(self.VSPACING)

        if hSpacing <= 0 or vSpacing <= 0:
            raise GeoAlgorithmExecutionException(
                self.tr('Invalid grid spacing: {0}/{1}').format(hSpacing, vSpacing))

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.fields(), layer.wkbType(), layer.crs(),
                                                                     context)

        features = QgsProcessingUtils.getFeatures(layer, context)
        total = 100.0 / layer.featureCount() if layer.featureCount() else 0

        for current, f in enumerate(features):
            geom = f.geometry()
            geomType = geom.wkbType()

            if geomType == QgsWkbTypes.Point:
                points = self._gridify([geom.asPoint()], hSpacing, vSpacing)
                newGeom = QgsGeometry.fromPoint(points[0])
            elif geomType == QgsWkbTypes.MultiPoint:
                points = self._gridify(geom.aMultiPoint(), hSpacing, vSpacing)
                newGeom = QgsGeometry.fromMultiPoint(points)
            elif geomType == QgsWkbTypes.LineString:
                points = self._gridify(geom.asPolyline(), hSpacing, vSpacing)
                if len(points) < 2:
                    QgsMessageLog.logMessage(self.tr('Failed to gridify feature with FID {0}').format(f.id()), self.tr('Processing'), QgsMessageLog.INFO)
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromPolyline(points)
            elif geomType == QgsWkbTypes.MultiLineString:
                polyline = []
                for line in geom.asMultiPolyline():
                    points = self._gridify(line, hSpacing, vSpacing)
                    if len(points) > 1:
                        polyline.append(points)
                if len(polyline) <= 0:
                    QgsMessageLog.logMessage(self.tr('Failed to gridify feature with FID {0}').format(f.id()), self.tr('Processing'), QgsMessageLog.INFO)
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromMultiPolyline(polyline)

            elif geomType == QgsWkbTypes.Polygon:
                polygon = []
                for line in geom.asPolygon():
                    points = self._gridify(line, hSpacing, vSpacing)
                    if len(points) > 1:
                        polygon.append(points)
                if len(polygon) <= 0:
                    QgsMessageLog.logMessage(self.tr('Failed to gridify feature with FID {0}').format(f.id()), self.tr('Processing'), QgsMessageLog.INFO)
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromPolygon(polygon)
            elif geomType == QgsWkbTypes.MultiPolygon:
                multipolygon = []
                for polygon in geom.asMultiPolygon():
                    newPolygon = []
                    for line in polygon:
                        points = self._gridify(line, hSpacing, vSpacing)
                        if len(points) > 2:
                            newPolygon.append(points)

                    if len(newPolygon) > 0:
                        multipolygon.append(newPolygon)

                if len(multipolygon) <= 0:
                    QgsMessageLog.logMessage(self.tr('Failed to gridify feature with FID {0}').format(f.id()), self.tr('Processing'), QgsMessageLog.INFO)
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromMultiPolygon(multipolygon)

            if newGeom is not None:
                feat = QgsFeature()
                feat.setGeometry(newGeom)
                feat.setAttributes(f.attributes())
                writer.addFeature(feat, QgsFeatureSink.FastInsert)

            feedback.setProgress(int(current * total))

        del writer
Exemple #37
0
 def _polygon_outline(self, graph, builder):
     lines = [tocoordinates(e.feature.geometry()) for e in graph.edges]
     multiline = QgsGeometry.fromMultiPolyline(lines)
     return multiline.buffer(0.5, 8)
def processLine(layer, writerLines, discardVertices, isProcessing):
    layercrs = layer.crs()    
    if layercrs != epsg4326:
        transto4326 = QgsCoordinateTransform(layercrs, epsg4326)
        transfrom4326 = QgsCoordinateTransform(epsg4326, layercrs)
    
    wkbtype = layer.wkbType()
    iterator = layer.getFeatures()
    num_features = 0
    num_bad = 0
    maxseglen = settings.maxSegLength*1000.0
    maxSegments = settings.maxSegments
    for feature in iterator:
        num_features += 1
        try:
            if wkbtype == QGis.WKBLineString:
                seg = [feature.geometry().asPolyline()]
            else:
                seg = feature.geometry().asMultiPolyline()
            numseg = len(seg)
            if numseg < 1 or len(seg[0]) < 2:
                continue
            # Create a new Line Feature
            fline = QgsFeature()
            # If the input is not 4326 we need to convert it to that and then back to the output CRS
            if discardVertices:
                ptStart = QgsPoint(seg[0][0][0], seg[0][0][1])
                if layercrs != epsg4326: # Convert to 4326
                    ptStart = transto4326.transform(ptStart)
                pts = [ptStart]
                numpoints = len(seg[numseg-1])
                ptEnd = QgsPoint(seg[numseg-1][numpoints-1][0], seg[numseg-1][numpoints-1][1])
                if layercrs != epsg4326: # Convert to 4326
                    ptEnd = transto4326.transform(ptEnd)
                l = geod.InverseLine(ptStart.y(), ptStart.x(), ptEnd.y(), ptEnd.x())
                if l.s13 > maxseglen:
                    n = int(math.ceil(l.s13 / maxseglen))
                    if n > maxSegments:
                        n = maxSegments
                    seglen = l.s13 / n
                    for i in range(1,n):
                        s = seglen * i
                        g = l.Position(s, Geodesic.LATITUDE | Geodesic.LONGITUDE | Geodesic.LONG_UNROLL)
                        pts.append( QgsPoint(g['lon2'], g['lat2']) )
                pts.append(ptEnd)
                
                if layercrs != epsg4326: # Convert each point back to the output CRS
                    for x, pt in enumerate(pts):
                        pts[x] = transfrom4326.transform(pt)
                fline.setGeometry(QgsGeometry.fromPolyline(pts))
            else:
                if wkbtype == QGis.WKBLineString:
                    line = seg[0]
                    numpoints = len(line)
                    ptStart = QgsPoint(line[0][0], line[0][1])
                    if layercrs != epsg4326: # Convert to 4326
                        ptStart = transto4326.transform(ptStart)
                    pts = [ptStart]
                    for x in range(1,numpoints):
                        ptEnd = QgsPoint(line[x][0], line[x][1])
                        if layercrs != epsg4326: # Convert to 4326
                            ptEnd = transto4326.transform(ptEnd)
                        l = geod.InverseLine(ptStart.y(), ptStart.x(), ptEnd.y(), ptEnd.x())
                        n = int(math.ceil(l.s13 / maxseglen))
                        if l.s13 > maxseglen:
                            if n > maxSegments:
                                n = maxSegments
                            seglen = l.s13 / n
                            for i in range(1,n):
                                s = seglen * i
                                g = l.Position(s, Geodesic.LATITUDE | Geodesic.LONGITUDE | Geodesic.LONG_UNROLL)
                                pts.append( QgsPoint(g['lon2'], g['lat2']) )
                        pts.append(ptEnd)
                        ptStart = ptEnd
                
                    if layercrs != epsg4326: # Convert each point back to the output CRS
                        for x, pt in enumerate(pts):
                            pts[x] = transfrom4326.transform(pt)
                    fline.setGeometry(QgsGeometry.fromPolyline(pts))
                else: # MultiLineString
                    outseg = []
                    for line in seg:
                        numpoints = len(line)
                        ptStart = QgsPoint(line[0][0], line[0][1])
                        if layercrs != epsg4326: # Convert to 4326
                            ptStart = transto4326.transform(ptStart)
                        pts = [ptStart]
                        for x in range(1,numpoints):
                            ptEnd = QgsPoint(line[x][0], line[x][1])
                            if layercrs != epsg4326: # Convert to 4326
                                ptEnd = transto4326.transform(ptEnd)
                            l = geod.InverseLine(ptStart.y(), ptStart.x(), ptEnd.y(), ptEnd.x())
                            n = int(math.ceil(l.s13 / maxseglen))
                            if l.s13 > maxseglen:
                                if n > maxSegments:
                                    n = maxSegments
                                seglen = l.s13 / n
                                for i in range(1,n):
                                    s = seglen * i
                                    g = l.Position(s, Geodesic.LATITUDE | Geodesic.LONGITUDE | Geodesic.LONG_UNROLL)
                                    pts.append( QgsPoint(g['lon2'], g['lat2']) )
                            pts.append(ptEnd)
                            ptStart = ptEnd
                            
                        if layercrs != epsg4326: # Convert each point back to the output CRS
                            for x, pt in enumerate(pts):
                                pts[x] = transfrom4326.transform(pt)
                        outseg.append(pts)
                
                    fline.setGeometry(QgsGeometry.fromMultiPolyline(outseg))
                    
            fline.setAttributes(feature.attributes())
            if isProcessing:
                writerLines.addFeature(fline)
            else:
                writerLines.addFeatures([fline])
        except:
            num_bad += 1
            pass
            
    return num_bad
 def testFromMultiLine(self):
     myMultiPolyline = QgsGeometry.fromMultiPolyline(
         [[QgsPoint(0, 0),QgsPoint(1, 1)],[QgsPoint(0, 1), QgsPoint(2, 1)]])
     myMessage = ('Expected:\n%s\nGot:\n%s\n' %
                   (QGis.WKBMultiLineString, myMultiPolyline.type()))
     assert myMultiPolyline.wkbType() == QGis.WKBMultiLineString, myMessage
Exemple #40
0
    def processFeature(self, feature, feedback):
        if feature.hasGeometry():
            geom = feature.geometry()
            geomType = QgsWkbTypes.flatType(geom.wkbType())
            newGeom = None

            if geomType == QgsWkbTypes.Point:
                points = self._gridify([geom.asPoint()], self.h_spacing, self.v_spacing)
                newGeom = QgsGeometry.fromPoint(points[0])
            elif geomType == QgsWkbTypes.MultiPoint:
                points = self._gridify(geom.asMultiPoint(), self.h_spacing, self.v_spacing)
                newGeom = QgsGeometry.fromMultiPoint(points)
            elif geomType == QgsWkbTypes.LineString:
                points = self._gridify(geom.asPolyline(), self.h_spacing, self.v_spacing)
                if len(points) < 2:
                    feedback.reportError(self.tr('Failed to gridify feature with FID {0}').format(feature.id()))
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromPolyline(points)
            elif geomType == QgsWkbTypes.MultiLineString:
                polyline = []
                for line in geom.asMultiPolyline():
                    points = self._gridify(line, self.h_spacing, self.v_spacing)
                    if len(points) > 1:
                        polyline.append(points)
                if len(polyline) <= 0:
                    feedback.reportError(self.tr('Failed to gridify feature with FID {0}').format(feature.id()))
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromMultiPolyline(polyline)

            elif geomType == QgsWkbTypes.Polygon:
                polygon = []
                for line in geom.asPolygon():
                    points = self._gridify(line, self.h_spacing, self.v_spacing)
                    if len(points) > 1:
                        polygon.append(points)
                if len(polygon) <= 0:
                    feedback.reportError(self.tr('Failed to gridify feature with FID {0}').format(feature.id()))
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromPolygon(polygon)
            elif geomType == QgsWkbTypes.MultiPolygon:
                multipolygon = []
                for polygon in geom.asMultiPolygon():
                    newPolygon = []
                    for line in polygon:
                        points = self._gridify(line, self.h_spacing, self.v_spacing)
                        if len(points) > 2:
                            newPolygon.append(points)

                    if len(newPolygon) > 0:
                        multipolygon.append(newPolygon)

                if len(multipolygon) <= 0:
                    feedback.reportError(self.tr('Failed to gridify feature with FID {0}').format(feature.id()))
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromMultiPolygon(multipolygon)

            if newGeom is not None:
                feature.setGeometry(newGeom)
            else:
                feature.clearGeometry()
        return feature
Exemple #41
0
    def testClosestVertex(self):
        # 2-+-+-+-+-3
        # |         |
        # + 6-+-+-7 +
        # | |     | |
        # + + 9-+-8 +
        # | |       |
        # ! 5-+-+-+-4 !
        # |
        # 1-+-+-+-+-0 !
        polyline = QgsGeometry.fromPolyline(
          [ QgsPoint(5,0), QgsPoint(0,0), QgsPoint(0,4), QgsPoint(5,4), QgsPoint(5,1), QgsPoint(1,1), QgsPoint(1,3), QgsPoint(4,3), QgsPoint(4,2), QgsPoint(2,2) ]
        )

        (point, atVertex, beforeVertex, afterVertex, dist ) = polyline.closestVertex( QgsPoint(6,1) )
        self.assertEqual( point, QgsPoint(5,1) )
        self.assertEqual( beforeVertex, 3 )
        self.assertEqual( atVertex, 4 )
        self.assertEqual( afterVertex, 5 )
        self.assertEqual( dist, 1 )

        (dist,minDistPoint,afterVertex) = polyline.closestSegmentWithContext( QgsPoint(6,2) )
        self.assertEqual( dist, 1 )
        self.assertEqual( minDistPoint, QgsPoint(5,2) )
        self.assertEqual( afterVertex, 4)

        (point, atVertex, beforeVertex, afterVertex, dist ) = polyline.closestVertex( QgsPoint(6,0) )
        self.assertEqual( point, QgsPoint(5,0) )
        self.assertEqual( beforeVertex, -1 )
        self.assertEqual( atVertex, 0 )
        self.assertEqual( afterVertex, 1 )
        self.assertEqual( dist, 1 )

        (dist,minDistPoint,afterVertex) = polyline.closestSegmentWithContext( QgsPoint(6,0) )
        self.assertEqual( dist, 1 )
        self.assertEqual( minDistPoint, QgsPoint(5,0) )
        self.assertEqual( afterVertex, 1)

        (point, atVertex, beforeVertex, afterVertex, dist ) = polyline.closestVertex( QgsPoint(0,1) )
        self.assertEqual( point, QgsPoint(0,0) )
        self.assertEqual( beforeVertex, 0 )
        self.assertEqual( atVertex, 1 )
        self.assertEqual( afterVertex, 2 )
        self.assertEqual( dist, 1 )

        (dist,minDistPoint,afterVertex) = polyline.closestSegmentWithContext( QgsPoint(0,1) )
        self.assertEqual( dist, 0 )
        self.assertEqual( minDistPoint, QgsPoint(0,1) )
        self.assertEqual( afterVertex, 2)

        #   2-3 6-+-7 !
        #   | | |   |
        # 0-1 4 5   8-9
        polyline = QgsGeometry.fromMultiPolyline(
          [
            [ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,0), ],
            [ QgsPoint(3,0), QgsPoint(3,1), QgsPoint(5,1), QgsPoint(5,0), QgsPoint(6,0), ]
          ]
        )
        (point, atVertex, beforeVertex, afterVertex, dist ) = polyline.closestVertex( QgsPoint(6,1) )
        self.assertEqual( point, QgsPoint(5,1) )
        self.assertEqual( beforeVertex, 6 )
        self.assertEqual( atVertex, 7 )
        self.assertEqual( afterVertex, 8 )
        self.assertEqual( dist, 1 )

        (dist,minDistPoint,afterVertex) = polyline.closestSegmentWithContext( QgsPoint(7,0) )
        self.assertEqual( dist, 1 )
        self.assertEqual( minDistPoint, QgsPoint(6,0) )
        self.assertEqual( afterVertex, 9)

        # 5---4
        # |!  |
        # | 2-3
        # | |
        # 0-1
        polygon = QgsGeometry.fromPolygon(
          [[
            QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(0,2), QgsPoint(0,0),
          ]]
        )
        (point, atVertex, beforeVertex, afterVertex, dist ) = polygon.closestVertex( QgsPoint(0.7,1.1) )
        self.assertEqual( point, QgsPoint(1,1) )
        self.assertEqual( beforeVertex, 1 )
        self.assertEqual( atVertex, 2 )
        self.assertEqual( afterVertex, 3 )
        assert abs( dist - 0.1 ) < 0.00001, "Expected: %f; Got:%f" % (dist,0.1)

        (dist,minDistPoint,afterVertex) = polygon.closestSegmentWithContext( QgsPoint(0.7,1.1) )
        self.assertEqual( afterVertex, 2)
        self.assertEqual( minDistPoint, QgsPoint(1,1) )
        exp = 0.3**2 + 0.1**2
        assert abs( dist - exp ) < 0.00001, "Expected: %f; Got:%f" % (exp,dist)

        # 3-+-+-2
        # |     |
        # + 8-7 +
        # | |!| |
        # + 5-6 +
        # |     |
        # 0-+-+-1
        polygon = QgsGeometry.fromPolygon(
          [
            [ QgsPoint(0,0), QgsPoint(3,0), QgsPoint(3,3), QgsPoint(0,3), QgsPoint(0,0) ],
            [ QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(1,2), QgsPoint(1,1) ],
          ]
        )
        (point, atVertex, beforeVertex, afterVertex, dist ) = polygon.closestVertex( QgsPoint(1.1,1.9) )
        self.assertEqual( point, QgsPoint(1,2) )
        self.assertEqual( beforeVertex, 7 )
        self.assertEqual( atVertex, 8 )
        self.assertEqual( afterVertex, 9 )
        assert abs( dist - 0.02 ) < 0.00001, "Expected: %f; Got:%f" % (dist,0.02)

        (dist,minDistPoint,afterVertex) = polygon.closestSegmentWithContext( QgsPoint(1.2,1.9) )
        self.assertEqual( afterVertex, 8)
        self.assertEqual( minDistPoint, QgsPoint(1.2,2) )
        exp = 0.01
        assert abs( dist - exp ) < 0.00001, "Expected: %f; Got:%f" % (exp,dist)

        # 5-+-4 0-+-9
        # |   | |   |
        # 6 2-3 1-2!+
        # | |     | |
        # 0-1     7-8
        polygon = QgsGeometry.fromMultiPolygon(
          [
            [ [ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(0,2), QgsPoint(0,0), ] ],
            [ [ QgsPoint(4,0), QgsPoint(5,0), QgsPoint(5,2), QgsPoint(3,2), QgsPoint(3,1), QgsPoint(4,1), QgsPoint(4,0), ] ]
          ]
        )
        (point, atVertex, beforeVertex, afterVertex, dist ) = polygon.closestVertex( QgsPoint(4.1,1.1) )
        self.assertEqual( point, QgsPoint(4,1) )
        self.assertEqual( beforeVertex, 11 )
        self.assertEqual( atVertex, 12 )
        self.assertEqual( afterVertex, 13 )
        assert abs( dist - 0.02 ) < 0.00001, "Expected: %f; Got:%f" % (dist,0.02)

        (dist,minDistPoint,afterVertex) = polygon.closestSegmentWithContext( QgsPoint(4.1,1.1) )
        self.assertEqual( afterVertex, 12)
        self.assertEqual( minDistPoint, QgsPoint(4,1) )
        exp = 0.02
        assert abs( dist - exp ) < 0.00001, "Expected: %f; Got:%f" % (exp,dist)
Exemple #42
0
    def processAlgorithm(self, progress):
        layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT))
        hSpacing = self.getParameterValue(self.HSPACING)
        vSpacing = self.getParameterValue(self.VSPACING)

        if hSpacing <= 0 or vSpacing <= 0:
            raise GeoAlgorithmExecutionException(
                self.tr('Invalid grid spacing: %s/%s' % (hSpacing, vSpacing)))

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            layer.fields(), layer.wkbType(), layer.crs())

        features = vector.features(layer)
        total = 100.0 / len(features)

        for current, f in enumerate(features):
            geom = f.geometry()
            geomType = geom.wkbType()

            if geomType == QgsWkbTypes.Point:
                points = self._gridify([geom.asPoint()], hSpacing, vSpacing)
                newGeom = QgsGeometry.fromPoint(points[0])
            elif geomType == QgsWkbTypes.MultiPoint:
                points = self._gridify(geom.aMultiPoint(), hSpacing, vSpacing)
                newGeom = QgsGeometry.fromMultiPoint(points)
            elif geomType == QgsWkbTypes.LineString:
                points = self._gridify(geom.asPolyline(), hSpacing, vSpacing)
                if len(points) < 2:
                    ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
                                           self.tr('Failed to gridify feature with FID %s' % f.id()))
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromPolyline(points)
            elif geomType == QgsWkbTypes.MultiLineString:
                polyline = []
                for line in geom.asMultiPolyline():
                    points = self._gridify(line, hSpacing, vSpacing)
                    if len(points) > 1:
                        polyline.append(points)
                if len(polyline) <= 0:
                    ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
                                           self.tr('Failed to gridify feature with FID %s' % f.id()))
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromMultiPolyline(polyline)

            elif geomType == QgsWkbTypes.Polygon:
                polygon = []
                for line in geom.asPolygon():
                    points = self._gridify(line, hSpacing, vSpacing)
                    if len(points) > 1:
                        polygon.append(points)
                if len(polygon) <= 0:
                    ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
                                           self.tr('Failed to gridify feature with FID %s' % f.id()))
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromPolygon(polygon)
            elif geomType == QgsWkbTypes.MultiPolygon:
                multipolygon = []
                for polygon in geom.asMultiPolygon():
                    newPolygon = []
                    for line in polygon:
                        points = self._gridify(line, hSpacing, vSpacing)
                        if len(points) > 2:
                            newPolygon.append(points)

                    if len(newPolygon) > 0:
                        multipolygon.append(newPolygon)

                if len(multipolygon) <= 0:
                    ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
                                           self.tr('Failed to gridify feature with FID %s' % f.id()))
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromMultiPolygon(multipolygon)

            if newGeom is not None:
                feat = QgsFeature()
                feat.setGeometry(newGeom)
                feat.setAttributes(f.attributes())
                writer.addFeature(feat)

            progress.setPercentage(int(current * total))

        del writer
Exemple #43
0
    def canvasReleaseEvent(self, event):

        if not self.mouse_clicked:
            return

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

            self.mouse_clicked = False

            # No pipe snapped: notify user
            if self.snapped_pipe_id is None:

                self.iface.messageBar().pushMessage(
                    Parameters.plug_in_name,
                    'You need to snap the cursor to a pipe to add a pump.',
                    Qgis.Info, 5)

            # A pipe has been snapped
            else:

                request = QgsFeatureRequest().setFilterFid(
                    self.snapped_pipe_id)
                feats = self.params.pipes_vlay.getFeatures(request)
                features = [feat for feat in feats]
                if len(features) == 1:

                    # Check whether the pipe has a start and an end node
                    (start_node, end_node) = NetworkUtils.find_start_end_nodes(
                        self.params, features[0].geometry())

                    if not start_node or not end_node:
                        self.iface.messageBar().pushMessage(
                            Parameters.plug_in_name,
                            'The pipe is missing the start or end nodes.',
                            Qgis.Warning, 5)  # TODO: softcode
                        return

                    # Find endnode closest to pump position
                    dist_1 = start_node.geometry().distance(
                        QgsGeometry.fromPointXY(self.snapped_vertex))
                    dist_2 = end_node.geometry().distance(
                        QgsGeometry.fromPointXY(self.snapped_vertex))

                    # Get the attributes of the closest junction
                    (start_node, end_node) = NetworkUtils.find_start_end_nodes(
                        self.params, features[0].geometry(), False, True, True)
                    if dist_1 < dist_2:
                        closest_junction_ft = start_node
                    else:
                        closest_junction_ft = end_node

                    # Create the pump
                    pump_param = ''
                    pump_head = None
                    pump_power = None
                    pump_speed = 0
                    pump_speed_pattern = 0

                    # Head and curve
                    if self.data_dock.cbo_pump_param.itemText(
                            self.data_dock.cbo_pump_param.currentIndex(
                            )) == Pump.parameters_head:
                        pump_param = Pump.parameters_head
                        curve = self.data_dock.cbo_pump_head.itemData(
                            self.data_dock.cbo_pump_head.currentIndex())
                        if curve is not None:
                            pump_head = curve.id
                        else:
                            pump_head = None

                    # Power and value
                    elif self.data_dock.cbo_pump_param.itemText(
                            self.data_dock.cbo_pump_param.currentIndex(
                            )) == Pump.parameters_power:
                        pump_param = Pump.parameters_power
                        pump_power = float(
                            self.data_dock.txt_pump_power.text())

                    # Speed
                    pump_speed_s = self.data_dock.txt_pump_speed.text()
                    if pump_speed_s is None or pump_speed_s == '':
                        pump_speed = 0
                    else:
                        pump_speed = float(pump_speed_s)

                    # Speed pattern
                    pump_speed_pattern = self.data_dock.cbo_pump_speed_pattern.itemText(
                        self.data_dock.cbo_pump_speed_pattern.currentIndex())

                    # Pump status
                    pump_status = self.data_dock.cbo_pump_status.itemData(
                        self.data_dock.cbo_pump_status.currentIndex())

                    # Pump description
                    pump_desc = self.data_dock.txt_pump_desc.text()

                    # Pump tag
                    pump_tag = self.data_dock.cbo_pump_tag.currentText()

                    try:
                        LinkHandler.create_new_pumpvalve(
                            self.params, self.data_dock, features[0],
                            closest_junction_ft, self.snapped_vertex,
                            self.params.pumps_vlay, {
                                Pump.field_name_param: pump_param,
                                Pump.field_name_head: pump_head,
                                Pump.field_name_power: pump_power,
                                Pump.field_name_speed: pump_speed,
                                Pump.field_name_speed_pattern:
                                pump_speed_pattern,
                                Pump.field_name_status: pump_status,
                                Pump.field_name_description: pump_desc,
                                Pump.field_name_tag: pump_tag
                            })

                        if pump_param == Pump.parameters_head and pump_head is None:
                            self.iface.messageBar().pushMessage(
                                Parameters.plug_in_name,
                                'The pump was added, but with a NULL value.',
                                Qgis.Info, 5)

                    except PumpValveCreationException as ex:
                        self.iface.messageBar().pushMessage(
                            Parameters.plug_in_name, ', '.join(ex.args),
                            Qgis.Info, 5)

            self.iface.mapCanvas().refresh()

        elif event.button() == Qt.RightButton:

            self.mouse_clicked = False

            # Check whether it clicked on a valve vertex
            if len(
                    NetworkUtils.find_adjacent_links(self.params,
                                                     self.snapped_vertex)
                ['pumps']) == 0 or self.snapped_pipe_id is None:
                return

            menu = QMenu()
            invert_action = menu.addAction(
                'Flip orientation')  # TODO: softcode
            action = menu.exec_(self.iface.mapCanvas().mapToGlobal(
                QPoint(event.pos().x(),
                       event.pos().y())))
            if action == invert_action:

                request = QgsFeatureRequest().setFilterFid(
                    self.snapped_pipe_id)
                feats = self.params.pipes_vlay.getFeatures(request)
                features = [feat for feat in feats]
                if len(features) == 1:
                    adj_links = NetworkUtils.find_links_adjacent_to_link(
                        self.params, self.params.pipes_vlay, features[0], True,
                        False, True)

                    for adj_link in adj_links['pumps']:
                        adj_link_pts = adj_link.geometry().asPolyline()
                        for adj_link_pt in adj_link_pts:
                            if NetworkUtils.points_overlap(
                                    adj_link_pt, self.snapped_vertex,
                                    self.params.tolerance):

                                geom = adj_link.geometry()

                                if geom.wkbType(
                                ) == QgsWkbTypes.MultiLineString:
                                    nodes = geom.asMultiPolyline()
                                    for line in nodes:
                                        line.reverse()
                                    newgeom = QgsGeometry.fromMultiPolyline(
                                        nodes)
                                    self.params.pumps_vlay.changeGeometry(
                                        adj_link.id(), newgeom)

                                if geom.wkbType() == QgsWkbTypes.LineString:
                                    nodes = geom.asPolyline()
                                    nodes.reverse()
                                    newgeom = QgsGeometry.fromPolylineXY(nodes)
                                    self.params.pumps_vlay.changeGeometry(
                                        adj_link.id(), newgeom)

                                self.iface.mapCanvas().refresh()

                                break
Exemple #44
0
    def processAlgorithm(self, feedback):
        layer = dataobjects.getObjectFromUri(self.getParameterValue(
            self.INPUT))
        hSpacing = self.getParameterValue(self.HSPACING)
        vSpacing = self.getParameterValue(self.VSPACING)

        if hSpacing <= 0 or vSpacing <= 0:
            raise GeoAlgorithmExecutionException(
                self.tr('Invalid grid spacing: {0}/{1}').format(
                    hSpacing, vSpacing))

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            layer.fields(), layer.wkbType(), layer.crs())

        features = vector.features(layer)
        total = 100.0 / len(features)

        for current, f in enumerate(features):
            geom = f.geometry()
            geomType = geom.wkbType()

            if geomType == QgsWkbTypes.Point:
                points = self._gridify([geom.asPoint()], hSpacing, vSpacing)
                newGeom = QgsGeometry.fromPoint(points[0])
            elif geomType == QgsWkbTypes.MultiPoint:
                points = self._gridify(geom.aMultiPoint(), hSpacing, vSpacing)
                newGeom = QgsGeometry.fromMultiPoint(points)
            elif geomType == QgsWkbTypes.LineString:
                points = self._gridify(geom.asPolyline(), hSpacing, vSpacing)
                if len(points) < 2:
                    ProcessingLog.addToLog(
                        ProcessingLog.LOG_INFO,
                        self.tr(
                            'Failed to gridify feature with FID {0}').format(
                                f.id()))
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromPolyline(points)
            elif geomType == QgsWkbTypes.MultiLineString:
                polyline = []
                for line in geom.asMultiPolyline():
                    points = self._gridify(line, hSpacing, vSpacing)
                    if len(points) > 1:
                        polyline.append(points)
                if len(polyline) <= 0:
                    ProcessingLog.addToLog(
                        ProcessingLog.LOG_INFO,
                        self.tr(
                            'Failed to gridify feature with FID {0}').format(
                                f.id()))
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromMultiPolyline(polyline)

            elif geomType == QgsWkbTypes.Polygon:
                polygon = []
                for line in geom.asPolygon():
                    points = self._gridify(line, hSpacing, vSpacing)
                    if len(points) > 1:
                        polygon.append(points)
                if len(polygon) <= 0:
                    ProcessingLog.addToLog(
                        ProcessingLog.LOG_INFO,
                        self.tr(
                            'Failed to gridify feature with FID {0}').format(
                                f.id()))
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromPolygon(polygon)
            elif geomType == QgsWkbTypes.MultiPolygon:
                multipolygon = []
                for polygon in geom.asMultiPolygon():
                    newPolygon = []
                    for line in polygon:
                        points = self._gridify(line, hSpacing, vSpacing)
                        if len(points) > 2:
                            newPolygon.append(points)

                    if len(newPolygon) > 0:
                        multipolygon.append(newPolygon)

                if len(multipolygon) <= 0:
                    ProcessingLog.addToLog(
                        ProcessingLog.LOG_INFO,
                        self.tr(
                            'Failed to gridify feature with FID {0}').format(
                                f.id()))
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromMultiPolygon(multipolygon)

            if newGeom is not None:
                feat = QgsFeature()
                feat.setGeometry(newGeom)
                feat.setAttributes(f.attributes())
                writer.addFeature(feat)

            feedback.setProgress(int(current * total))

        del writer
Exemple #45
0
    def dataVectorReaderTool(self, iface, tool1, layer, pointstoDraw1):
        """
        compute the projected points
        return :
            self.buffergeom : the qgsgeometry of the buffer
            self.projectedpoints : [..., [(point caracteristics : )
                                          #index : descripion
            #0 : the pk of the projected point relative to line
            #1 : the x coordinate of the projected point
            #2 : the y coordinate of the projected point
            #3 : the lenght between original point and projected point else -1
                 if interpolated
            #4 : the segment of the polyline on which the point is projected
            #5 : the interp value if interpfield > -1, else None
            #6 : the x coordinate of the original point if the point is not
                 interpolated, else None
            #6 : the y coordinate of the original point if the point is not
                 interpolated, else None
            #6 : the feature the original point if the point is not interpolated
                 , else None],
                                           ...]
        Return a dictionnary : {"layer" : layer read,
                                "band" : band read,
                                "l" : array of computed lenght,
                                "z" : array of computed z

        """
        layercrs = layer.crs()
        mapcanvascrs = iface.mapCanvas().mapSettings().destinationCrs()

        projectedpoints = []
        buffergeom = None

        sourceCrs = QgsCoordinateReferenceSystem(
            iface.mapCanvas().mapSettings().destinationCrs())
        destCrs = QgsCoordinateReferenceSystem(layercrs)
        xform = QgsCoordinateTransform(sourceCrs, destCrs)
        xformrev = QgsCoordinateTransform(destCrs, sourceCrs)

        geom = QgsGeometry.fromPolyline(
            [QgsPoint(point[0], point[1]) for point in pointstoDraw1])
        geominlayercrs = qgis.core.QgsGeometry(geom)
        tempresult = geominlayercrs.transform(xform)

        buffergeom = geom.buffer(valbuffer, 12)
        buffergeominlayercrs = qgis.core.QgsGeometry(buffergeom)
        tempresult = buffergeominlayercrs.transform(xform)

        featsPnt = layer.getFeatures(QgsFeatureRequest().setFilterRect(
            buffergeominlayercrs.boundingBox()))

        for featPnt in featsPnt:
            # iterate preselected point features and perform exact check with
            # current polygon
            point3 = featPnt.geometry()
            distpoint = geominlayercrs.distance(point3)
            if distpoint <= valbuffer:
                distline = geominlayercrs.lineLocatePoint(point3)
                pointprojected = geominlayercrs.interpolate(distline)

                projectedpoints.append([
                    distline,
                    pointprojected.asPoint().x(),
                    pointprojected.asPoint().y(), distpoint, 0, None,
                    featPnt.geometry().asPoint().x(),
                    featPnt.geometry().asPoint().y(), featPnt
                ])

        projectedpoints = np.array(projectedpoints)

        # Perform postprocess computation

        if len(projectedpoints) > 0:
            # remove duplicates
            projectedpoints = self.removeDuplicateLenght(projectedpoints)
            # interpolate value at nodes of polyline
            projectedpoints = self.interpolateNodeofPolyline(
                geominlayercrs, projectedpoints)

        # Preparing return value
        profile = {}
        profile.update("layer", layer)
        profile.update(
            'l', [projectedpoint[0] for projectedpoint in projectedpoints])
        profile.update(
            'z', [projectedpoint[5] for projectedpoint in projectedpoints])
        profile.update(
            'x', [projectedpoint[1] for projectedpoint in projectedpoints])
        profile.update(
            'y', [projectedpoint[2] for projectedpoint in projectedpoints])

        multipoly = QgsGeometry.fromMultiPolyline([[
            xform.transform(QgsPoint(projectedpoint[1], projectedpoint[2]),
                            QgsCoordinateTransform.ReverseTransform),
            xform.transform(QgsPoint(projectedpoint[6], projectedpoint[7]),
                            QgsCoordinateTransform.ReverseTransform)
        ] for projectedpoint in projectedpoints])

        return profile, buffergeom, multipoly
Exemple #46
0
    def processAlgorithm(self, parameters, context, feedback):
        layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)
        index = self.getParameterValue(self.TYPE)

        splitNodes = False
        if index == 0:
            newType = QgsWkbTypes.Point
        elif index == 1:
            newType = QgsWkbTypes.Point
            splitNodes = True
        elif index == 2:
            newType = QgsWkbTypes.LineString
        elif index == 3:
            newType = QgsWkbTypes.MultiLineString
        elif index == 4:
            newType = QgsWkbTypes.Polygon
        else:
            newType = QgsWkbTypes.Point

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.fields(), newType, layer.crs(), context)

        features = QgsProcessingUtils.getFeatures(layer, context)
        total = 100.0 / layer.featureCount() if layer.featureCount() else 0

        for current, f in enumerate(features):
            geom = f.geometry()
            geomType = geom.wkbType()

            if geomType in [QgsWkbTypes.Point, QgsWkbTypes.Point25D]:
                if newType == QgsWkbTypes.Point:
                    writer.addFeature(f, QgsFeatureSink.FastInsert)
                else:
                    raise GeoAlgorithmExecutionException(
                        self.tr('Cannot convert from {0} to {1}').format(geomType, newType))
            elif geomType in [QgsWkbTypes.MultiPoint, QgsWkbTypes.MultiPoint25D]:
                if newType == QgsWkbTypes.Point and splitNodes:
                    points = geom.asMultiPoint()
                    for p in points:
                        feat = QgsFeature()
                        feat.setAttributes(f.attributes())
                        feat.setGeometry(QgsGeometry.fromPoint(p))
                        writer.addFeature(feat, QgsFeatureSink.FastInsert)
                elif newType == QgsWkbTypes.Point:
                    feat = QgsFeature()
                    feat.setAttributes(f.attributes())
                    feat.setGeometry(geom.centroid())
                    writer.addFeature(feat, QgsFeatureSink.FastInsert)
                else:
                    raise GeoAlgorithmExecutionException(
                        self.tr('Cannot convert from {0} to {1}').format(geomType, newType))
            elif geomType in [QgsWkbTypes.LineString, QgsWkbTypes.LineString25D]:
                if newType == QgsWkbTypes.Point and splitNodes:
                    points = geom.asPolyline()
                    for p in points:
                        feat = QgsFeature()
                        feat.setAttributes(f.attributes())
                        feat.setGeometry(QgsGeometry.fromPoint(p))
                        writer.addFeature(feat, QgsFeatureSink.FastInsert)
                elif newType == QgsWkbTypes.Point:
                    feat = QgsFeature()
                    feat.setAttributes(f.attributes())
                    feat.setGeometry(geom.centroid())
                    writer.addFeature(feat, QgsFeatureSink.FastInsert)
                elif newType == QgsWkbTypes.LineString:
                    writer.addFeature(f, QgsFeatureSink.FastInsert)
                else:
                    raise GeoAlgorithmExecutionException(
                        self.tr('Cannot convert from {0} to {1}').format(geomType, newType))
            elif geomType in [QgsWkbTypes.MultiLineString, QgsWkbTypes.MultiLineString25D]:
                if newType == QgsWkbTypes.Point and splitNodes:
                    lines = geom.asMultiPolyline()
                    for line in lines:
                        for p in line:
                            feat = QgsFeature()
                            feat.setAttributes(f.attributes())
                            feat.setGeometry(QgsGeometry.fromPoint(p))
                            writer.addFeature(feat, QgsFeatureSink.FastInsert)
                elif newType == QgsWkbTypes.Point:
                    feat = QgsFeature()
                    feat.setAttributes(f.attributes())
                    feat.setGeometry(geom.centroid())
                    writer.addFeature(feat, QgsFeatureSink.FastInsert)
                elif newType == QgsWkbTypes.LineString:
                    lines = geom.asMultiPolyline()
                    for line in lines:
                        feat = QgsFeature()
                        feat.setAttributes(f.attributes())
                        feat.setGeometry(QgsGeometry.fromPolyline(line))
                        writer.addFeature(feat, QgsFeatureSink.FastInsert)
                elif newType == QgsWkbTypes.MultiLineString:
                    writer.addFeature(f, QgsFeatureSink.FastInsert)
                else:
                    raise GeoAlgorithmExecutionException(
                        self.tr('Cannot convert from {0} to {1}').format(geomType, newType))
            elif geomType in [QgsWkbTypes.Polygon, QgsWkbTypes.Polygon25D]:
                if newType == QgsWkbTypes.Point and splitNodes:
                    rings = geom.asPolygon()
                    for ring in rings:
                        for p in ring:
                            feat = QgsFeature()
                            feat.setAttributes(f.attributes())
                            feat.setGeometry(QgsGeometry.fromPoint(p))
                            writer.addFeature(feat, QgsFeatureSink.FastInsert)
                elif newType == QgsWkbTypes.Point:
                    feat = QgsFeature()
                    feat.setAttributes(f.attributes())
                    feat.setGeometry(geom.centroid())
                    writer.addFeature(feat, QgsFeatureSink.FastInsert)
                elif newType == QgsWkbTypes.MultiLineString:
                    rings = geom.asPolygon()
                    feat = QgsFeature()
                    feat.setAttributes(f.attributes())
                    feat.setGeometry(QgsGeometry.fromMultiPolyline(rings))
                    writer.addFeature(feat, QgsFeatureSink.FastInsert)
                elif newType == QgsWkbTypes.Polygon:
                    writer.addFeature(f, QgsFeatureSink.FastInsert)
                else:
                    raise GeoAlgorithmExecutionException(
                        self.tr('Cannot convert from {0} to {1}').format(geomType, newType))
            elif geomType in [QgsWkbTypes.MultiPolygon, QgsWkbTypes.MultiPolygon25D]:
                if newType == QgsWkbTypes.Point and splitNodes:
                    polygons = geom.asMultiPolygon()
                    for polygon in polygons:
                        for line in polygon:
                            for p in line:
                                feat = QgsFeature()
                                feat.setAttributes(f.attributes())
                                feat.setGeometry(QgsGeometry.fromPoint(p))
                                writer.addFeature(feat, QgsFeatureSink.FastInsert)
                elif newType == QgsWkbTypes.Point:
                    feat = QgsFeature()
                    feat.setAttributes(f.attributes())
                    feat.setGeometry(geom.centroid())
                    writer.addFeature(feat, QgsFeatureSink.FastInsert)
                elif newType == QgsWkbTypes.LineString:
                    polygons = geom.asMultiPolygon()
                    for polygons in polygons:
                        feat = QgsFeature()
                        feat.setAttributes(f.attributes())
                        feat.setGeometry(QgsGeometry.fromPolyline(polygon))
                        writer.addFeature(feat, QgsFeatureSink.FastInsert)
                elif newType == QgsWkbTypes.Polygon:
                    polygons = geom.asMultiPolygon()
                    for polygon in polygons:
                        feat = QgsFeature()
                        feat.setAttributes(f.attributes())
                        feat.setGeometry(QgsGeometry.fromPolygon(polygon))
                        writer.addFeature(feat, QgsFeatureSink.FastInsert)
                elif newType in [QgsWkbTypes.MultiLineString, QgsWkbTypes.MultiPolygon]:
                    writer.addFeature(f, QgsFeatureSink.FastInsert)
                else:
                    raise GeoAlgorithmExecutionException(
                        self.tr('Cannot convert from {0} to {1}').format(geomType, newType))

            feedback.setProgress(int(current * total))

        del writer
Exemple #47
0
    def testVertexAt(self):
        # 2-+-+-+-+-3
        # |         |
        # + 6-+-+-7 +
        # | |     | |
        # + + 9-+-8 +
        # | |       |
        # ! 5-+-+-+-4 !
        # |
        # 1-+-+-+-+-0 !
        points = [ QgsPoint(5,0), QgsPoint(0,0), QgsPoint(0,4), QgsPoint(5,4), QgsPoint(5,1), QgsPoint(1,1), QgsPoint(1,3), QgsPoint(4,3), QgsPoint(4,2), QgsPoint(2,2) ]
        polyline = QgsGeometry.fromPolyline(points)

        for i in range(0, len(points)):
                assert points[i] == polyline.vertexAt(i), "Mismatch at %d" % i

        #   2-3 6-+-7
        #   | | |   |
        # 0-1 4 5   8-9
        points = [
            [ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,0), ],
            [ QgsPoint(3,0), QgsPoint(3,1), QgsPoint(5,1), QgsPoint(5,0), QgsPoint(6,0), ]
          ]
        polyline = QgsGeometry.fromMultiPolyline(points)

        p = polyline.vertexAt(-100)
        assert p==QgsPoint(0,0), "Expected 0,0, Got %s" % p.toString()

        p = polyline.vertexAt(100)
        assert p==QgsPoint(0,0), "Expected 0,0, Got %s" % p.toString()

        i = 0
        for j in range(0, len(points)):
                for k in range(0, len(points[j])):
                        assert points[j][k] == polyline.vertexAt(i), "Mismatch at %d / %d,%d" % (i,j,k)
                        i+=1

        # 5---4
        # |   |
        # | 2-3
        # | |
        # 0-1
        points = [[
            QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(0,2), QgsPoint(0,0),
          ]]
        polygon = QgsGeometry.fromPolygon(points)

        p = polygon.vertexAt(-100)
        assert p==QgsPoint(0,0), "Expected 0,0, Got %s" % p.toString()

        p = polygon.vertexAt(100)
        assert p==QgsPoint(0,0), "Expected 0,0, Got %s" % p.toString()

        i = 0
        for j in range(0, len(points)):
                for k in range(0, len(points[j])):
                        assert points[j][k] == polygon.vertexAt(i), "Mismatch at %d / %d,%d" % (i,j,k)
                        i+=1

        # 3-+-+-2
        # |     |
        # + 8-7 +
        # | | | |
        # + 5-6 +
        # |     |
        # 0-+-+-1
        points = [
            [ QgsPoint(0,0), QgsPoint(3,0), QgsPoint(3,3), QgsPoint(0,3), QgsPoint(0,0) ],
            [ QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(1,2), QgsPoint(1,1) ],
          ]
        polygon = QgsGeometry.fromPolygon(points)

        p = polygon.vertexAt(-100)
        assert p==QgsPoint(0,0), "Expected 0,0, Got %s" % p.toString()

        p = polygon.vertexAt(100)
        assert p==QgsPoint(0,0), "Expected 0,0, Got %s" % p.toString()

        i = 0
        for j in range(0, len(points)):
                for k in range(0, len(points[j])):
                        assert points[j][k] == polygon.vertexAt(i), "Mismatch at %d / %d,%d" % (i,j,k)
                        i+=1

        # 5-+-4 0-+-9
        # |   | |   |
        # | 2-3 1-2 |
        # | |     | |
        # 0-1     7-8
        points = [
            [ [ QgsPoint(0,0), QgsPoint(1,0), QgsPoint(1,1), QgsPoint(2,1), QgsPoint(2,2), QgsPoint(0,2), QgsPoint(0,0), ] ],
            [ [ QgsPoint(4,0), QgsPoint(5,0), QgsPoint(5,2), QgsPoint(3,2), QgsPoint(3,1), QgsPoint(4,1), QgsPoint(4,0), ] ]
          ]

        polygon = QgsGeometry.fromMultiPolygon(points)

        p = polygon.vertexAt(-100)
        assert p==QgsPoint(0,0), "Expected 0,0, Got %s" % p.toString()

        p = polygon.vertexAt(100)
        assert p==QgsPoint(0,0), "Expected 0,0, Got %s" % p.toString()

        i = 0
        for j in range(0, len(points)):
                for k in range(0, len(points[j])):
                        for l in range(0, len(points[j][k])):
                                p = polygon.vertexAt(i)
                                assert points[j][k][l] == p, "Got %s, Expected %s at %d / %d,%d,%d" % (p.toString(),points[j][k][l].toString(),i,j,k,l)
                                i+=1
Exemple #48
0
    def processFeature(self, feature, feedback):
        if feature.hasGeometry():
            geom = feature.geometry()
            geomType = QgsWkbTypes.flatType(geom.wkbType())
            newGeom = None

            if geomType == QgsWkbTypes.Point:
                points = self._gridify([geom.asPoint()], self.h_spacing, self.v_spacing)
                newGeom = QgsGeometry.fromPoint(points[0])
            elif geomType == QgsWkbTypes.MultiPoint:
                points = self._gridify(geom.asMultiPoint(), self.h_spacing, self.v_spacing)
                newGeom = QgsGeometry.fromMultiPoint(points)
            elif geomType == QgsWkbTypes.LineString:
                points = self._gridify(geom.asPolyline(), self.h_spacing, self.v_spacing)
                if len(points) < 2:
                    feedback.reportError(self.tr('Failed to gridify feature with FID {0}').format(feature.id()))
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromPolyline(points)
            elif geomType == QgsWkbTypes.MultiLineString:
                polyline = []
                for line in geom.asMultiPolyline():
                    points = self._gridify(line, self.h_spacing, self.v_spacing)
                    if len(points) > 1:
                        polyline.append(points)
                if len(polyline) <= 0:
                    feedback.reportError(self.tr('Failed to gridify feature with FID {0}').format(feature.id()))
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromMultiPolyline(polyline)

            elif geomType == QgsWkbTypes.Polygon:
                polygon = []
                for line in geom.asPolygon():
                    points = self._gridify(line, self.h_spacing, self.v_spacing)
                    if len(points) > 1:
                        polygon.append(points)
                if len(polygon) <= 0:
                    feedback.reportError(self.tr('Failed to gridify feature with FID {0}').format(feature.id()))
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromPolygon(polygon)
            elif geomType == QgsWkbTypes.MultiPolygon:
                multipolygon = []
                for polygon in geom.asMultiPolygon():
                    newPolygon = []
                    for line in polygon:
                        points = self._gridify(line, self.h_spacing, self.v_spacing)
                        if len(points) > 2:
                            newPolygon.append(points)

                    if len(newPolygon) > 0:
                        multipolygon.append(newPolygon)

                if len(multipolygon) <= 0:
                    feedback.reportError(self.tr('Failed to gridify feature with FID {0}').format(feature.id()))
                    newGeom = None
                else:
                    newGeom = QgsGeometry.fromMultiPolygon(multipolygon)

            if newGeom is not None:
                feature.setGeometry(newGeom)
            else:
                feature.clearGeometry()
        return feature
    def insert_line(self):
        layer = self.iface.activeLayer()
        if not isinstance(layer, QgsVectorLayer) or layer.geometryType() != QGis.Line:
            self.iface.messageBar().pushMessage(self.tr("ReconstructLine"),
                                    self.tr("Line can\'t be inserted! Select lines layer for inserting new geom!"),
                                    level=QgsMessageBar.WARNING,
                                    duration=5)
            return

        if not layer.isEditable():
            self.iface.messageBar().pushMessage(self.tr("ReconstructLine"),
                                    self.tr("Line can\'t be inserted! Layer is not editable!"),
                                    level=QgsMessageBar.WARNING,
                                    duration=5)
            return

        if not self._geom_buffer:
            self.iface.messageBar().pushMessage(self.tr("ReconstructLine"),
                        self.tr("Line can\'t be inserted! Copy points first!"),
                        level=QgsMessageBar.WARNING,
                        duration=5)
            return

        #show message
        self.iface.messageBar().clearWidgets()
        self.iface.messageBar().pushMessage(self.tr("ReconstructLine"),
                                            self.tr("Processing points. Please wait..."),
                                            level=QgsMessageBar.INFO
                                            )
        QgsApplication.setOverrideCursor(Qt.WaitCursor)
        QgsApplication.processEvents()
        QgsApplication.processEvents()
        QgsApplication.processEvents()

        try:
            # Create line

            # QGS geoms to np
            points = [(in_geom.x(), in_geom.y()) for in_geom in self._geom_buffer]
            data = np.array(points)

            # Make line
            som = SOM1d(data)
            result = som.connect()

            #np to QGS
            self._geom_buffer = [QgsPoint(out_geom[0], out_geom[1]) for out_geom in result]

            if layer.wkbType() == QGis.WKBMultiLineString:
                geom = QgsGeometry.fromMultiPolyline([self._geom_buffer])
            else:
                geom = QgsGeometry.fromPolyline(self._geom_buffer)

            # Check crs and reproject
            target_crs = layer.crs()
            if target_crs.srsid() != self._srid.srsid():
                transf = QgsCoordinateTransform(self._srid, target_crs)
                geom.transform(transf)

            # Insert feature
            feat = QgsFeature()
            feat.setFields(layer.dataProvider().fields())
            feat.setGeometry(geom)

            suppressForm = QSettings().value("/qgis/digitizing/disable_enter_attribute_values_dialog", type=bool, defaultValue=False)

            if suppressForm:
                # quite insert feature
                result = layer.addFeatures([feat])
            else:
                # show dialog
                QgsApplication.restoreOverrideCursor()
                attrDialog = QgsAttributeDialog(layer, feat, False)
                attrDialog.setIsAddDialog(True)
                result = attrDialog.exec_()

            # show message
            self.iface.messageBar().clearWidgets()
            if result:
                self.iface.messageBar().pushMessage(self.tr("ReconstructLine"),
                                                self.tr("One line was sucesfull added"),
                                                level=QgsMessageBar.INFO)
            else:
                self.iface.messageBar().pushMessage(self.tr("ReconstructLine"),
                                                self.tr("Line was not added"),
                                                level=QgsMessageBar.CRITICAL)

            self.iface.mapCanvas().refresh()
        finally:
            QgsApplication.restoreOverrideCursor()
Exemple #50
0
    def processAlgorithm(self, feedback):
        layer = dataobjects.getObjectFromUri(self.getParameterValue(
            self.INPUT))
        index = self.getParameterValue(self.TYPE)

        splitNodes = False
        if index == 0:
            newType = QgsWkbTypes.Point
        elif index == 1:
            newType = QgsWkbTypes.Point
            splitNodes = True
        elif index == 2:
            newType = QgsWkbTypes.LineString
        elif index == 3:
            newType = QgsWkbTypes.MultiLineString
        elif index == 4:
            newType = QgsWkbTypes.Polygon
        else:
            newType = QgsWkbTypes.Point

        writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(
            layer.fields(), newType, layer.crs())

        features = vector.features(layer)
        total = 100.0 / len(features)

        for current, f in enumerate(features):
            geom = f.geometry()
            geomType = geom.wkbType()

            if geomType in [QgsWkbTypes.Point, QgsWkbTypes.Point25D]:
                if newType == QgsWkbTypes.Point:
                    writer.addFeature(f)
                else:
                    raise GeoAlgorithmExecutionException(
                        self.tr('Cannot convert from {0} to {1}').format(
                            geomType, newType))
            elif geomType in [
                    QgsWkbTypes.MultiPoint, QgsWkbTypes.MultiPoint25D
            ]:
                if newType == QgsWkbTypes.Point and splitNodes:
                    points = geom.asMultiPoint()
                    for p in points:
                        feat = QgsFeature()
                        feat.setAttributes(f.attributes())
                        feat.setGeometry(QgsGeometry.fromPoint(p))
                        writer.addFeature(feat)
                elif newType == QgsWkbTypes.Point:
                    feat = QgsFeature()
                    feat.setAttributes(f.attributes())
                    feat.setGeometry(geom.centroid())
                    writer.addFeature(feat)
                else:
                    raise GeoAlgorithmExecutionException(
                        self.tr('Cannot convert from {0} to {1}').format(
                            geomType, newType))
            elif geomType in [
                    QgsWkbTypes.LineString, QgsWkbTypes.LineString25D
            ]:
                if newType == QgsWkbTypes.Point and splitNodes:
                    points = geom.asPolyline()
                    for p in points:
                        feat = QgsFeature()
                        feat.setAttributes(f.attributes())
                        feat.setGeometry(QgsGeometry.fromPoint(p))
                        writer.addFeature(feat)
                elif newType == QgsWkbTypes.Point:
                    feat = QgsFeature()
                    feat.setAttributes(f.attributes())
                    feat.setGeometry(geom.centroid())
                    writer.addFeature(feat)
                elif newType == QgsWkbTypes.LineString:
                    writer.addFeature(f)
                else:
                    raise GeoAlgorithmExecutionException(
                        self.tr('Cannot convert from {0} to {1}').format(
                            geomType, newType))
            elif geomType in [
                    QgsWkbTypes.MultiLineString, QgsWkbTypes.MultiLineString25D
            ]:
                if newType == QgsWkbTypes.Point and splitNodes:
                    lines = geom.asMultiPolyline()
                    for line in lines:
                        for p in line:
                            feat = QgsFeature()
                            feat.setAttributes(f.attributes())
                            feat.setGeometry(QgsGeometry.fromPoint(p))
                            writer.addFeature(feat)
                elif newType == QgsWkbTypes.Point:
                    feat = QgsFeature()
                    feat.setAttributes(f.attributes())
                    feat.setGeometry(geom.centroid())
                    writer.addFeature(feat)
                elif newType == QgsWkbTypes.LineString:
                    lines = geom.asMultiPolyline()
                    for line in lines:
                        feat = QgsFeature()
                        feat.setAttributes(f.attributes())
                        feat.setGeometry(QgsGeometry.fromPolyline(line))
                        writer.addFeature(feat)
                elif newType == QgsWkbTypes.MultiLineString:
                    writer.addFeature(f)
                else:
                    raise GeoAlgorithmExecutionException(
                        self.tr('Cannot convert from {0} to {1}').format(
                            geomType, newType))
            elif geomType in [QgsWkbTypes.Polygon, QgsWkbTypes.Polygon25D]:
                if newType == QgsWkbTypes.Point and splitNodes:
                    rings = geom.asPolygon()
                    for ring in rings:
                        for p in ring:
                            feat = QgsFeature()
                            feat.setAttributes(f.attributes())
                            feat.setGeometry(QgsGeometry.fromPoint(p))
                            writer.addFeature(feat)
                elif newType == QgsWkbTypes.Point:
                    feat = QgsFeature()
                    feat.setAttributes(f.attributes())
                    feat.setGeometry(geom.centroid())
                    writer.addFeature(feat)
                elif newType == QgsWkbTypes.MultiLineString:
                    rings = geom.asPolygon()
                    feat = QgsFeature()
                    feat.setAttributes(f.attributes())
                    feat.setGeometry(QgsGeometry.fromMultiPolyline(rings))
                    writer.addFeature(feat)
                elif newType == QgsWkbTypes.Polygon:
                    writer.addFeature(f)
                else:
                    raise GeoAlgorithmExecutionException(
                        self.tr('Cannot convert from {0} to {1}').format(
                            geomType, newType))
            elif geomType in [
                    QgsWkbTypes.MultiPolygon, QgsWkbTypes.MultiPolygon25D
            ]:
                if newType == QgsWkbTypes.Point and splitNodes:
                    polygons = geom.asMultiPolygon()
                    for polygon in polygons:
                        for line in polygon:
                            for p in line:
                                feat = QgsFeature()
                                feat.setAttributes(f.attributes())
                                feat.setGeometry(QgsGeometry.fromPoint(p))
                                writer.addFeature(feat)
                elif newType == QgsWkbTypes.Point:
                    feat = QgsFeature()
                    feat.setAttributes(f.attributes())
                    feat.setGeometry(geom.centroid())
                    writer.addFeature(feat)
                elif newType == QgsWkbTypes.LineString:
                    polygons = geom.asMultiPolygon()
                    for polygons in polygons:
                        feat = QgsFeature()
                        feat.setAttributes(f.attributes())
                        feat.setGeometry(QgsGeometry.fromPolyline(polygon))
                        writer.addFeature(feat)
                elif newType == QgsWkbTypes.Polygon:
                    polygons = geom.asMultiPolygon()
                    for polygon in polygons:
                        feat = QgsFeature()
                        feat.setAttributes(f.attributes())
                        feat.setGeometry(QgsGeometry.fromPolygon(polygon))
                        writer.addFeature(feat)
                elif newType in [
                        QgsWkbTypes.MultiLineString, QgsWkbTypes.MultiPolygon
                ]:
                    writer.addFeature(f)
                else:
                    raise GeoAlgorithmExecutionException(
                        self.tr('Cannot convert from {0} to {1}').format(
                            geomType, newType))

            feedback.setProgress(int(current * total))

        del writer
    def addAnyFeature(self, featureType, mapPointList, attributes, layer):
        geometryType = FeatureType.toGeometryType(featureType)

        # points: bail out if there is not exactly one vertex
        if (geometryType == QGis.Point and len(mapPointList) != 1):
            return False

        # segments: bail out if there are not exactly two vertices
        if (featureType == FeatureType.Segment and len(mapPointList) != 2):
            return False

        # lines: bail out if there are not at least two vertices
        if (featureType == FeatureType.Line and len(mapPointList) < 2):
            return False

        # polygons: bail out if there are not at least three vertices
        if (geometryType == QGis.Polygon and len(mapPointList) < 3):
            return False

        if (geometryType != layer.geometryType()):
            self.messageEmitted.emit(
                self.tr('Cannot add feature: Layer and Feature geometry type mismatch'), QgsMessageBar.CRITICAL)
            return False

        if (layer.type() != QgsMapLayer.VectorLayer):
            self.messageEmitted.emit(
                self.tr('Cannot add feature: Current layer not a vector layer'), QgsMessageBar.CRITICAL)
            return False

        if (not layer.isEditable()):
            self.messageEmitted.emit(self.tr('Cannot add feature: Current layer not editable'), QgsMessageBar.CRITICAL)
            return False

        provider = layer.dataProvider()
        if (not (provider.capabilities() & QgsVectorDataProvider.AddFeatures)):
            self.messageEmitted.emit(
                self.tr('Cannot add feature: Data provider does not support the addition of features.'),
                QgsMessageBar.CRITICAL)
            return False

        multiType = QGis.isMultiType(layer.wkbType())
        layerPoints = self._layerPoints(mapPointList, layer)
        feature = QgsFeature(layer.pendingFields(), 0)
        geometry = None

        if (geometryType == QGis.Point):
            if multiType:
                geometry = QgsGeometry.fromMultiPoint([layerPoints[0]])
            else:
                geometry = QgsGeometry(layerPoints[0])
        elif (geometryType == QGis.Line):
            if multiType:
                geometry = QgsGeometry.fromMultiPolyline([layerPoints])
            else:
                geometry = QgsGeometry.fromPolyline(layerPoints)
        elif (geometryType == QGis.Polygon):
            if multiType:
                geometry = QgsGeometry.fromMultiPolygon([layerPoints])
            else:
                geometry = QgsGeometry.fromPolygon([layerPoints])
        else:
            self.messageEmitted.emit(self.tr('Cannot add feature. Unknown geometry type'), QgsMessageBar.CRITICAL)
            return False

        if (geometry is None):
            self.messageEmitted.emit(self.tr('Cannot add feature. Invalid geometry'), QgsMessageBar.CRITICAL)
            return False
        feature.setGeometry(geometry)

        if (geometryType == QGis.Polygon):

            avoidIntersectionsReturn = feature.geometry().avoidIntersections()
            if (avoidIntersectionsReturn == 1):
                # not a polygon type. Impossible to get there
                pass
            elif (avoidIntersectionsReturn == 3):
                self.messageEmitted.emit(
                    self.tr('An error was reported during intersection removal'), QgsMessageBar.CRITICAL)

            if (not feature.geometry().asWkb()):  # avoid intersection might have removed the whole geometry
                reason = ''
                if (avoidIntersectionsReturn != 2):
                    reason = self.tr('The feature cannot be added because it\'s geometry is empty')
                else:
                    reason = self.tr(
                        'The feature cannot be added because it\'s geometry collapsed due to intersection avoidance')
                self.messageEmitted.emit(reason, QgsMessageBar.CRITICAL)
                return False

        featureSaved = self._addFeatureAction(feature, attributes, layer, False)

        if (featureSaved and geometryType != QGis.Point):
            # add points to other features to keep topology up-to-date
            topologicalEditing = Snapping.topologicalEditing()

            # use always topological editing for avoidIntersection.
            # Otherwise, no way to guarantee the geometries don't have a small gap in between.
            intersectionLayers = Snapping.intersectionLayers()
            avoidIntersection = len(intersectionLayers)
            if (avoidIntersection):  # try to add topological points also to background layers
                for intersectionLayer in intersectionLayers:
                    vl = QgsMapLayerRegistry.instance().mapLayer(str(intersectionLayer))
                    # can only add topological points if background layer is editable...
                    if (vl is not None and vl.geometryType() == QGis.Polygon and vl.isEditable()):
                        vl.addTopologicalPoints(feature.geometry())
            elif (topologicalEditing):
                self._layer.addTopologicalPoints(feature.geometry())

        self.canvas().refresh()

        return True
Exemple #52
0
    def insert_line(self, method):
        layer = self.iface.activeLayer()
        if not isinstance(layer,
                          QgsVectorLayer) or layer.geometryType() != QGis.Line:
            self.iface.messageBar().pushMessage(
                self.tr("ReconstructLine"),
                self.
                tr("Line can\'t be inserted! Select lines layer for inserting new geom!"
                   ),
                level=QgsMessageBar.WARNING,
                duration=5)
            return

        if not layer.isEditable():
            self.iface.messageBar().pushMessage(
                self.tr("ReconstructLine"),
                self.tr("Line can\'t be inserted! Layer is not editable!"),
                level=QgsMessageBar.WARNING,
                duration=5)
            return

        if not self._geom_buffer:
            self.iface.messageBar().pushMessage(
                self.tr("ReconstructLine"),
                self.tr("Line can\'t be inserted! Copy points first!"),
                level=QgsMessageBar.WARNING,
                duration=5)
            return

        #show message
        self.iface.messageBar().clearWidgets()
        self.iface.messageBar().pushMessage(
            self.tr("ReconstructLine"),
            self.tr("Processing points. Please wait..."),
            level=QgsMessageBar.INFO)
        QgsApplication.setOverrideCursor(Qt.WaitCursor)
        QgsApplication.processEvents()
        QgsApplication.processEvents()
        QgsApplication.processEvents()

        try:
            # Create line

            # QGS geoms to np
            points = [(in_geom.x(), in_geom.y())
                      for in_geom in self._geom_buffer]
            data = np.array(points)

            # Make line

            if method == 'MST':
                conn = MST(data)
                result = conn.connect()
            elif method == 'SOM':
                som = SOM1d(data)
                result = som.connect()
            else:
                raise ValueError

            #np to QGS
            lines = []
            for line in result:
                lines.append(
                    [QgsPoint(out_geom[0], out_geom[1]) for out_geom in line])

            geom_list = []
            if layer.wkbType() == QGis.WKBMultiLineString:
                geom_list.append(QgsGeometry.fromMultiPolyline(lines))
            else:
                for line in lines:
                    geom_list.append(QgsGeometry.fromPolyline(line))

            # Check crs and reproject
            target_crs = layer.crs()
            if target_crs.srsid() != self._srid.srsid():
                transf = QgsCoordinateTransform(self._srid, target_crs)
                for geom in geom_list:
                    geom.transform(transf)

            # Insert feature(s)
            features = []
            for geom in geom_list:
                feat = QgsFeature()
                feat.setFields(layer.dataProvider().fields())
                feat.setGeometry(geom)
                features.append(feat)

            default_suppress = (method == 'MST')
            suppressForm = QSettings().value(
                "/qgis/digitizing/disable_enter_attribute_values_dialog",
                type=bool,
                defaultValue=default_suppress)

            if suppressForm:
                # quite insert feature
                result = layer.addFeatures(features)
            else:
                # show dialog
                QgsApplication.restoreOverrideCursor()
                for feat in features:
                    attrDialog = QgsAttributeDialog(layer, feat, False)
                    attrDialog.setIsAddDialog(True)
                    result = attrDialog.exec_()

            # show message
            self.iface.messageBar().clearWidgets()
            if result:
                self.iface.messageBar().pushMessage(
                    self.tr("ReconstructLine"),
                    self.tr("%s line segment(s) was sucesfull added" %
                            (len(features))),
                    level=QgsMessageBar.INFO)
            else:
                self.iface.messageBar().pushMessage(
                    self.tr("ReconstructLine"),
                    self.tr("Line was not added"),
                    level=QgsMessageBar.CRITICAL)

            self.iface.mapCanvas().refresh()
        finally:
            QgsApplication.restoreOverrideCursor()
 def _polygon_outline(self, graph, builder):
     lines = [tocoordinates(e.feature.geometry()) for e in graph.edges]
     multiline = QgsGeometry.fromMultiPolyline(lines)
     return multiline.buffer(0.5, 8)