Mehr

PyQGIS-Version des Arcgis-Werkzeugwürfels

PyQGIS-Version des Arcgis-Werkzeugwürfels


Ich verwende QGIS und habe einige große Features, die in Features mit weniger Scheitelpunkten zerlegt werden müssen.

Wenn ich arcGIS verwenden würde, könnte ich das Würfelwerkzeug verwenden

Wenn mich nur Leitungen interessieren, könnte ich hier die Lösung von mapplus einbinden

Gibt es ein gleichwertiges Werkzeug, das ich in pyQGIS schreiben könnte?


Jawohl. Hier ist eine Python-Funktion, die ich geschrieben habe, die die Arbeit erledigt. Die Funktion verwendet als Eingaben: einen zu zerlegenden Layer, den Namen für den Ausgabe-Layer und die maximale Anzahl von Stützpunkten für jedes Feature. Die Ausgabe-Features behalten dann auch ihre übergeordneten Attribute und keine Features im Ausgabe-Layer haben eine größere Anzahl von Stützpunkten als der an die Funktion übergebene Grenzwert.

Dies wurde nicht auf Geschwindigkeit optimiert und enthält einige Ineffizienzen, funktioniert jedoch für Polygon-Layer und für Polylinien-Layer. Sie müssen "mehrere" Ebenen konvertieren, bevor Sie sie ausführen.

Es wurde getestet, dass es sowohl auf Polygon- als auch auf Linien-Layern funktioniert.

def dice(input_layer,destination_title,max_vertices): import numpy from PyQt4.QtCore import * my_WkbType = { 'WKBUnknown': 0, 'WKBPoint':1, 'WKBLineString':2, 'WKBPolygon':3,''WKBMultiPoint':3,''WKBMultiPoint' , 'WKBMultiLineString':5, 'WKBMultiPolygon':6, 'WKBNoGeometry':7, 'WKBPoint25D':8, 'WKBLineString25D':9, 'WKBPolygon25D':10, 'WKBMultiPoint25D':11, 'WK'B':12Line 'WK'B WKBMultiPolygon25D':13 } my_rev_WkbType = {v:k for k, v in my_WkbType.items()} QGisWKBType=input_layer.dataProvider().geometryType() dice_safe_type=False wenn QGisWKBType==3: dice_safe_type=True : dice_safe_type=True, wenn nicht dice_safe_type: raise ValueError("Sie haben eine Ebene "+my_rev_WkbType[QGisWKBType][3:]+" bereitgestellt und diese Funktion funktioniert nur auf Polygon- oder LineString-Ebenen") layerQGisType = my_rev_WkbType[QGisWKBType][3: EPSG_code=int(input_layer.dataProvider().crs().authid().split(":")[1]) destination_layer=QgsVectorLayer(my_rev_WkbType[QGisWKBType][3:]+'?crs=epsg:'+str (EPSG_code)+'&index=yes',destination_t itle,'memory') #QgsMapLayerRegistry.instance().addMapLayer(destination_layer) wenn nicht destination_layer.isValid(): raise("Fehler beim Erstellen der Speicherschicht") #Add input_layer Attributfelder input_layer_attrib_names = input_layer.dataProvider().fields( ) oldattributeList = input_layer.dataProvider().fields().toList() newattributeList=[] für Attribut in oldattributeList: if destination_layer.fieldNameIndex(attrib.name())==-1: newattributeList.append(QgsField(attrib.name .) (),attrib.type())) destination_layer.dataProvider().addAttributes(newattributeList) destination_layer.updateFields() destination_layer_attribute_list=destination_layer.dataProvider().fields().toList() #Features in die neue Speicherschicht kopieren destination_layer.startEditing() cfeatures=[] xfeatures = input_layer.getFeatures() für xfeature in xfeatures: gorzirras=[] diced=[] dice_this_feature=Falsch xgeometry = xfeature.geometry() Slices=1 if QGisWKBType==2: line_as_list xgeometry.asPolyline() if len(line_as_list)>max_verti ces: gorzirras.append(xgeometry) else: diced.append(xgeometry) while len(gorzirras)>0: gorzirra=gorzirras.pop() line_as_list = gorzirra.asPolyline() dice_left_geometry=QgsGeometry.fromPolyline(line_as_list[:max_vertices]) diced.append(dice_left_geometry) dice_right_geometry=QgsGeometry.fromPolyline(line_as_list[(max_vertices-1):]) if len(line_as_list)-max_vertices+1>max_vertices: gorzirras.append(KWZirras.append(KWzirras ==3: Ringe = xgeometry.asPolygon() no_vertices=0 für Ring in Ringen: no_vertices = no_vertices+len(ring) if no_vertices>max_vertices: gorzirras.append(xgeometry) else: diced.append(xgeometry) while len(gorzirras )>0: Slices+=1 gorzirra=gorzirras.pop() #Bestimme die längere Dimension zum Teilen bbox_rectangle=gorzirra.boundingBox() xmax=bbox_rectangle.xMaximum() ymax=bbox_rectangle.yMaximum() xmin=bbox_rectangle.xMinimum() ymin= bbox_rectangle.yMinimum() dice_X=True if (ymax-ymin)>(xmax-xmin): dice_X=False #Locate median Vertex v Wert der langen Dimension ring_list=gorzirra.asPolygon() val_list=[] für Ring in ring_list: für Scheitelpunkt im Ring: if dice_X: val_list.append(vertex.x()) else: val_list.append(vertex.y()) median_val=numpy.median(numpy.array(val_list)) if dice_X: dice_left_geometry=QgsGeometry.fromPolygon( [ [  QgsPoint(xmin,ymin), QgsPoint(xmin,ymax),  QgsPoint(median_val,ymax), QgsPoint (median_val,ymin) ] ] ) dice_right_geometry=QgsGeometry.fromPolygon( [ [  QgsPoint(median_val,ymin), QgsPoint(median_val,ymax),  QgsPoint(xmax,ymax), QgsPoint(xmax,ymin) ] ] ) sonst: dice_left_geometry=QgsGeometry.fromPolygon( [ [  QgsPoint(xmin,ymin), QgsPoint(xmin,median_val),  QgsPoint(xmax,median_val), QgsPoint(xmax,ymin) ] ] ) dice_right_geometry=Qgs(Geometry.fromPolygon) [ [  QgsPoint(xmin,median_val), QgsPoint(xmin,ymax),  QgsPoint(xmax,ymax), QgsPoint(xmax,median_val) ] ] ) #Schnittpunkte ausführen left_diced=(gorzirra.intersection(dice_left_geometry)) .asGeometryCollection() right_diced=(gorzirra.interse ction(dice_right_geometry)).asGeometryCollection() diced_list=left_diced+right_diced für gewürfelte_Geometrie in diced_list:ringe = diced_geometry.asPolygon() no_vertices=0 für Ring in Ringen: no_vertices = no_vertices+len(ring) if no_verrasticappes:>end_zirverrasticappes:> (diced_geometry) else: #wenn nicht diced_geometry.isGeosEmpty(): diced.append(diced_geometry) #Erzeuge Ziel-Features für ngeometry in diced: #print ngeometry.area() cfeature = QgsFeature() cfeature.setGeometry(ngeometry) #Populate feature mit Attributen cfeature_Attributes=[] für destination_QGSfield in destination_layer_attribute_list: attribute_field=destination_QGSfield.name() attr_still_to_append=True #Alten Attributwert holen und idx = input_layer.fieldNameIndex(attribute_field) if idx>=0: cfeature. )[idx]) attr_still_to_append=False #Füge eine Null an alle nicht gefundenen Attribute an, wenn attr_still_to_append: cfeature_Attributes.append(None) cfeature.setAttributes(cfeature_Attribut es) cfeatures.append(cfeature) destination_layer.dataProvider().addFeatures(cfeatures) destination_layer.commitChanges() destination_layer.updateExtents() QgsMapLayerRegistry.instance().addMapLayer(destination_layer) return destination_layer

Einfaches Beispiel, das die Verwendung dieses pyQGIS-Würfelwerkzeugs zeigt:

import os shape_path="/path/to/my/shape/file.shp" gorzirra_layer = QgsVectorLayer(shape_path, "Gorzirra_layer", "ogr") QgsMapLayerRegistry.instance().addMapLayer(gorzirra_layer) diced_title="Diced Layer" vertex_limit= 255 diced_layer=dice(gorzirra_layer,diced_title,vertex_limit)

Schau das Video: Python: Map Automation in ArcGIS Pro