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()
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
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()
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)
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)
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()
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()
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 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
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)
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])
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 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)
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
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
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
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)
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()
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)
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
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
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
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())
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()
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
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
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 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)
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
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
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
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
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
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
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()
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
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()