Abrufen der Ausdehnung jedes Polygons in Shapefile mithilfe von ArcPy?

20

In ArcGIS 10 und Python möchte ich die Informationen zum Umfang (xmax, ymax, xmin, ymin) der einzelnen Polygone in einem Shapefile abrufen.

Ich kann das Ausmaß des gesamten Shapefiles mit ermitteln

file=r"D:\SCRATCH\ARCGIS\100k_trc_tiles_TVM.shp"
desc=arcpy.Describe(file)
print desc.extent.Xmax

394551.52085039532

Aber ich kann nicht scheinen, herauszufinden, wie man die gleichen Informationen für jede Zeile im Datensatz erhält.

rows = arcpy.SearchCursor("100k_trc_tiles_TVM")
for row in rows:
 print row

druckt die 31 Zeilen im Datensatz aber aus

for row in rows:
 desc=arcpy.Describe(row)
 print desc.extent.Xmax

gibt einen Fehler.

Laufzeitfehler: Objekt: Beschreibe Eingabewert ist ungültiger Typ

Ich dachte daran, die Extent-Werte mithilfe von "Geometrie berechnen" zur Tabelle hinzuzufügen, aber dies gibt nur den Schwerpunkt an. Dann können wir so etwas wie row.GetValue ("xmax") verwenden.

Davon abgesehen weiß ich, dass wir das X / Y, max / min mit der Funktion von http://www.ian-ko.com/free/free_arcgis.htm erstellen können, aber es wäre am besten, wenn wir vermeiden könnten, hinzufügen zu müssen Felder, insbesondere wenn ArcPy diese Werte abrufen kann.

Grundsätzlich muss ich die Extents in das Clip-Tool einspeisen, um 30 Datenbereiche (gemäß den 1: 100.000 Kartenblättern) für die Geoverarbeitung auszuschneiden, da das Split-Tool aufgrund der Größe des Datasets fehlschlägt (siehe Warum Intersect gibt) FEHLER 999999: Fehler beim Ausführen der Funktion Ungültige Topologie [Zu viele Linienseg-Endpunkte]? ). Ich möchte dies automatisieren, da es für eine Reihe von Datensätzen wiederholt wird.

=== Arbeitsskript ===

# Emulates Arc Info SPLIT tool by using Clip but
# Requires a FC from which each row is used as the input clip feature.
# Each row must be rectangular.
# Used on 12GB FGDB with 100 million records.


#Licence: Creative Commons
#Created by: George Corea; [email protected], [email protected]
import arcpy, string

#inFrame=arcpy.GetParameterAsText(0) # Input dataframe FC
#inFile=arcpy.GetParameterAsText(1) # Input FC for splitting
#outDir=arcpy.GetParameterAsText(2) # Output FGDB

inFrame=r"D:\SCRATCH\ARCGIS\100k_trc_tiles_TVM.shp"
inFile=r"c:\junk\106\data\7_Merge.gdb\FullRez_m2b"
outDir=r"D:\SCRATCH\Projects\206\datasplit\test_slaasp.gdb"
#NameField="Name_1"

#arcpy.env.workspace = r"C:/Workspace"
arcpy.env.overwriteOutput = True

rows = arcpy.SearchCursor(inFrame)
shapeName = arcpy.Describe(inFrame).shapeFieldName
for row in rows:
    feat = row.getValue(shapeName)
    Name = row.Name_1
    print "Executing clip on: "+str(Name)
    extent = feat.extent
    #print extent.XMin,extent.YMin,extent.XMax,extent.YMax
# Create an in_memory polygon
    XMAX = extent.XMax
    XMIN = extent.XMin
    YMAX = extent.YMax
    YMIN = extent.YMin
    pnt1 = arcpy.Point(XMIN, YMIN)
    pnt2 = arcpy.Point(XMIN, YMAX)
    pnt3 = arcpy.Point(XMAX, YMAX)
    pnt4 = arcpy.Point(XMAX, YMIN)
    array = arcpy.Array()
    array.add(pnt1)
    array.add(pnt2)
    array.add(pnt3)
    array.add(pnt4)
    array.add(pnt1)
    polygon = arcpy.Polygon(array)
    ShapeFile = outDir+"\\temp_poly"
    arcpy.CopyFeatures_management(polygon, ShapeFile)

    #print Name
### Set local variables
    in_features = inFile
    clip_features = ShapeFile
    out_feature_class = outDir+"\\"+Name
    xy_tolerance = "0.22"

    # Execute Clip

    try:
        arcpy.Clip_analysis(in_features, clip_features, out_feature_class, xy_tolerance)
        print "Completed: "+str(Name)
    except:
        error = arcpy.GetMessages()
        print "Failed on: "+str(Name)+" due to "+str(error)
GeorgeC
quelle
2
Sie haben nicht den Clip - Funktion auf die Festplatte schreiben müssen, verwenden Sie nur die im Speicher Polygon, zB: Polygon = arcpy.Polygon (Array) arcpy.Clip_analysis (in_features, Polygon, out_feature_class, xy_tolerance)
user2856
tks. Hast du eine Idee, wie ich die Zeile in eine neue Formdatei exportieren kann, damit sie verwendet wird, anstatt nur die Ausdehnung der Zeile? Auf diese Weise können auch nicht rechteckige Clips bearbeitet werden.
GeorgeC
1
Nun, wenn Sie nur nach dieser Funktion schneiden möchten, verwenden Sie im selben Skript einfach das Funktionsobjekt. Auch hier muss keine Formdatei exportiert werden, z. B .: arcpy.Clip_analysis (in_features, feat, out_feature_class, xy_tolerance)
user2856 10.11.11
Für ein Shapefile oder für jedes Polygon in einem Shapefile? Sieht so aus, als sprichst du hier über zwei verschiedene Dinge.
Rayner
Befindet sich nur ein Polygonobjekt in Ihrem Shapefile? Wenn nicht, verwenden Sie die for-Schleife für die Ausdehnung Ihrer Objekte.
Aragonien

Antworten:

26

Holen Sie sich das Shape-Objekt in Ihren Cursor und greifen Sie auf dessen Extent-Eigenschaft zu. Weitere Informationen finden Sie in der ArcGIS-Hilfe. Arbeiten mit Geometrie in Python :

shapeName = arcpy.Describe(inFeatures).shapeFieldName
for row in rows:
    feat = row.getValue(shapeName)
    extent = feat.extent
    print extent.XMin,extent.YMin,extent.XMax,extent.YMax
user2856
quelle
1
Vielen Dank, Luke. Das hat super funktioniert. Ich bearbeite meine Frage, um den neuen Arbeitscode zu erhalten, wenn jemand ein Tool verwenden möchte, das - das Toolset "Ausschneiden" iterativ verwendet, um rechteckige Bereiche einer großen Feature-Class auszuschneiden. Emuliert die Funktionalität des Werkzeugs zum Teilen von Bogeninformationen, ohne bei Datensätzen mit einer Größe von 10 GB FGDB und 100 Millionen Datensätzen zum Absturz zu führen.
GeorgeC
Eine Sache - Ich musste den Namen der Spalte hart codieren, um das Äquivalent von Name = row.Name_1 zu erhalten, indem ich das Attribut name als probierte. NameField = "Name_1"; Name = row.NameField; oder Name = Zeile + "." + NameField wobei NameField = arcpy.GetParameterAsText (2) und der Name in der Spalte Name_1 enthalten ist. Irgendwelche Ideen? Beachten Sie, dass ich ";" eine neue Zeile bezeichnen.
GeorgeC
1
fand den obigen out - row.GetValue (xxx) von gis.stackexchange.com/questions/16586/…
GeorgeC
7

Das Bounding Container-Toolset macht genau das, was Sie wollen. Wenn Sie nur Code-Schnipsel wollen, untersuchen Sie die Funktionen in den Skripten, man befasst sich explizit mit Umfang.

BEARBEITEN

Ich sollte hinzufügen, dass das Skript Werte zu den Feldern Links, Rechts, Oben und Unten in der erstellten Ausgabedatei hinzufügt, die für die nachfolgende Verarbeitung verwendet werden können


quelle
Vielen Dank. Werde es überprüfen. Hoffentlich kann ich den Code in meinen Python-Skripten / Modellen verwenden.
GeorgeC
2

Ich habe gerade die minimale Begrenzungsgeometrie (Envelope) (in Data Management) in ArcGIS 10 ausprobiert und es scheint für alle Felder genau dasselbe zu tun.

Sid
quelle
1

Eine andere Möglichkeit wäre, einen SearchCursor () für das Shapefile zu erstellen. Dann können Sie row.shape.extent verwenden:

rows = arcpy.SearchCursor(shapefileName)

for row in rows:
   extent = row.shape.extent
   ...
   ...
Ruth
quelle
1

Wie in Extrahieren von Koordinaten von Polygonscheitelpunkten in ArcMap beschrieben? Sie können die Eckpunkte eines Polygons abrufen und dann die x- und y-Koordinaten jedes Eckpunkts als Felder in der Attributtabelle hinzufügen. Dies hat die Einschränkung, dass die Max / Min-Koordinaten nicht direkt an jedes Polygon angehängt werden. Dies kann jedoch auf verschiedene Arten erreicht werden.

Die mir am besten bekannte Methode besteht darin, die x- und y-Felder mit dem pyshp-Modul in Python-Listen einzulesen , die dann sortiert werden können, um die Maximal- und Minimalwerte für jedes Polygon zu ermitteln. Mit Pyshp kann dann eine Writer-Klasse geöffnet werden, um den ursprünglichen Polygonen neue Felder hinzuzufügen und diese Max- und Min-Werte in das richtige Polygon zu schreiben.

Ich glaube, dass dies mit Arcpy möglich ist, aber ich hatte viele Probleme beim Schreiben in Shapefiles in 9.3 mit dem Geoprozessor. Daher bevorzuge ich die pyshp-Methode. Ich bin mir jedoch nicht sicher, ob das Arcpy-Modul diese Probleme gelöst hat.

Trauer
quelle
0

Haben Sie versucht, das "M" in "XMax" groß zu schreiben? Ich denke, es soll sein:

print desc.extent.XMax

anstatt

print desc.extent.Xmax

gemäß der Dokumentation . Natürlich frage ich mich, wie Ihr erstes Code-Snippet funktioniert hat. Wie auch immer, probieren Sie es aus!

dmahr
quelle