Uzyskiwanie zasięgu każdego wielokąta w pliku kształtu za pomocą ArcPy?

20

W ArcGIS 10 i Python chcę uzyskać informacje o zasięgu (xmax, ymax, xmin, ymin) każdego z wielokątów w pliku kształtu.

Mogę uzyskać zasięg całego pliku shapefile

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

394551.52085039532

Ale nie potrafię wymyślić, jak uzyskać te same informacje dla każdego wiersza w zestawie danych.

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

drukuje 31 wierszy w zestawie danych, ale

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

daje błąd.

Błąd czasu wykonania: Obiekt: Opisz wartość wejściową niepoprawnego typu

Zastanawiałem się nad dodaniem wartości zasięgu do tabeli za pomocą „obliczania geometrii”, ale daje to tylko środek ciężkości. Więc chyba możemy użyć czegoś takiego jak row.GetValue („xmax”).

Biorąc to pod uwagę, wiem, że możemy stworzyć X / Y, max / min za pomocą funkcji z http://www.ian-ko.com/free/free_arcgis.htm, ale najlepiej byłoby, gdybyśmy mogli uniknąć konieczności dodawania pola, szczególnie jeśli ArcPy może uzyskać te wartości.

Zasadniczo muszę pobrać zakresy do narzędzia do wycinania, aby wyciąć 30 obszarów danych (zgodnie z arkuszami mapy 1: 100 000) do geoprzetwarzania, ponieważ narzędzie Podziel nie działa z powodu dużego rozmiaru zestawu danych (zobacz Dlaczego przecięcie daje BŁĄD 999999: Błąd wykonywania funkcji Nieprawidłowa topologia [Zbyt wiele punktów końcowych lineseg]? ). Chcę to zautomatyzować, ponieważ jest powtarzane w wielu zestawach danych.

=== działający skrypt ===

# 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
źródło
2
Nie musisz zapisywać funkcji klipu na dysku, po prostu użyj wielokąta w pamięci, np .: polygon = arcpy.Polygon (array) arcpy.Clip_analysis (in_features, polygon, out_feature_class, xy_tolerance)
user2856
tks. Masz pomysł, jak wyeksportować wiersz do nowego pliku kształtu, aby go użył, a nie tylko jego rozmiar? Jest tak, aby mógł obsługiwać również klipsy nie prostokątne.
GeorgeC,
1
Cóż, jeśli chcesz po prostu przyciąć tę funkcję w tym samym skrypcie, po prostu użyj obiektu funkcji. Ponownie nie ma potrzeby eksportowania do pliku kształtu, np .: arcpy.Clip_analysis (in_features, feat, out_feature_class, xy_tolerance)
user2856 10.11.11
Dla pliku kształtu lub dla każdego wielokąta w pliku kształtu? Wygląda na to, że mówisz tutaj o dwóch osobnych sprawach.
Rayner
czy w twoim pliku kształtu jest tylko jeden obiekt wielokąta? jeśli nie, użyj pętli for dla zasięgu obiektów.
Aragonia

Odpowiedzi:

26

Umieść obiekt kształtu w kursorze i uzyskaj dostęp do jego właściwości zakresu. Zobacz Pomoc ArcGIS Praca z geometrią w Pythonie :

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
użytkownik2856
źródło
1
Dzięki, Luke. To działało świetnie. Zmodyfikuję moje pytanie, aby uzyskać nowy działający kod, jeśli ktoś chce użyć narzędzia, które - Korzysta z zestawu narzędzi Klip, aby wycinać prostokątne obszary dużej klasy obiektów. Emuluje funkcjonalność narzędzia do dzielenia informacji łuku bez awarii z zestawami danych tak dużymi, jak 10 GB FGDB i 100 milionów rekordów.
GeorgeC,
Jedno - musiałem zakodować na stałe nazwę kolumny, aby uzyskać ekwiwalent Nazwa = wiersz.Name_1, próbując atrybutu name jako; NameField = „Name_1”; Nazwa = wiersz.NameField; lub Name = wiersz + "." + NameField gdzie NameField = arcpy.GetParameterAsText (2), a nazwa jest przechowywana w kolumnie Name_1. Jakieś pomysły? Uwaga I; użyłem „;” oznaczać nową linię.
GeorgeC,
1
wymyśliłem powyższy wiersz - GetValue (xxx) z gis.stackexchange.com/questions/16586/…
GeorgeC
7

Zestaw narzędzi Bounding Container robi dokładnie to, co chcesz. Jeśli chcesz tylko fragmentów kodu, sprawdź funkcje w skryptach, jeden dotyczy wyraźnie zakresu.

EDYTOWAĆ

Powinienem dodać, że skrypt doda wartości do pola Lewo, Prawo, Góra i Dół w utworzonym pliku wyjściowym, którego można użyć do dalszego przetwarzania


źródło
dzięki. Sprawdzę to. Mam nadzieję, że mogę używać kodu w moich skryptach / modelach Pythona.
GeorgeC,
2

Właśnie wypróbowałem minimalną geometrię graniczną (obwiednię) (w zarządzaniu danymi) w ArcGIS 10 i wydaje się, że robi dokładnie to samo, dla wszystkich pól.

Sid
źródło
1

Innym sposobem byłoby wykonanie SearchCursor () na pliku shapefile, a następnie można użyć row.shape.extent:

rows = arcpy.SearchCursor(shapefileName)

for row in rows:
   extent = row.shape.extent
   ...
   ...
Litość
źródło
1

Jak opisano w Wyodrębnianie współrzędnych wierzchołków wielokąta w ArcMap? możesz uzyskać wierzchołki wielokąta, a następnie dodać współrzędne xiy każdego wierzchołka jako pola w tabeli atrybutów. Ma to ograniczenie polegające na nie dołączaniu współrzędnych maks./min. Bezpośrednio do każdego wielokąta, ale można to osiągnąć na kilka sposobów.

Najbardziej znaną mi metodą jest odczytanie pól xiy na listy python przy użyciu modułu pyshp , który można następnie posortować w celu znalezienia maksymalnych i minimalnych wartości dla każdego wielokąta. Pyshp można następnie wykorzystać do otwarcia klasy pisarza, aby dodać nowe pola do oryginalnych wielokątów i zapisać te wartości maksymalne i minimalne we właściwym wielokącie.

Wydaje mi się, że można to zrobić za pomocą arcpy, ale miałem wiele problemów z pisaniem do plików shapefiles w 9.3 za pomocą geoprocesora, więc wolę metodę pyshp, jednak nie jestem pewien, czy moduł arcpy rozwiązał te problemy.

sgrieve
źródło
0

Czy próbowałeś używać litery „M” w „XMax”? Myślę, że to powinno być:

print desc.extent.XMax

zamiast

print desc.extent.Xmax

zgodnie z dokumentacją . Oczywiście zastanawiam się, jak działał twój pierwszy fragment kodu. Tak czy inaczej, spróbuj!

dmahr
źródło