Eksportujesz tylko niektóre kolumny do pliku CSV w ArcGIS na komputery?

15

Napisałem skrypt Pythona za pomocą arcpy, który wyświetla klasę wielokątów w Geobazie Pliku. Dodałem funkcję eksportowania atrybutów do osobnego pliku CSV. Używam kodu, który znalazłem w tym poście, który działa idealnie. Jednak ten kod eksportuje każdą kolumnę w klasie elementów. Chcę tylko, aby wyeksportować pól, które nie mają następujące nazwy: OBJECTID, Shape, lub Shape_Length.

Mój plik CSV generuje się pomyślnie i poprawnie nie zawiera pól OBJECTIDlub Shape_Length. Jednak Shapepole jest zapisywane w pliku. Przykładowa wartość zapisana w tym polu to:

<geoprocessing describe geometry object object at 0x28CB90A0>

Dodałem wiersz, aby wydrukować nazwy pól podczas ich iteracji i, co zaskakujące, Shapenie jest drukowany. To tak, jakby ArcGIS ukrywa go lub nadaje mu inną nazwę.

Kod mojej funkcji znajduje się poniżej:

def exportToTable():
    """ 
        Exports the final outputs to a CSV File.
    """

    # Create path to CSV File (note the varialbe outputPath is declared elsewhere).
    CSVFile = outputPath+'\\FinalOutput.csv'
    arcpy.AddMessage("Created CSV File: %s" %CSVFile)

    # Get all fields in FinalOutput feature class and remove unwanted fields.
    fields = arcpy.ListFields('FinalOutput')
    for field in fields:
        arcpy.AddMessage("Field.name is:"+field.name) #not printing 'Shape' field name
        if field.name in (['OBJECTID', 'Shape', 'Shape_Length']):
            fields.remove(field)

    i = 1
    f=open(CSVFile, 'w')
    for field in fields:
        #--write the wanted field names to the output file
        if i < len(fields):
            f.write('%s,' % field.name)
            i += 1
        else:
            f.write('%s\n' % field.name)

    # Use a search cursor to iterate through the rows of the table and write them to the CSV file.
    rows = arcpy.SearchCursor('FinalOutput')
    for row in rows:
        i = 1
        for field in fields:
            if i < len(fields):
                f.write('%s,' % row.getValue(field.name))
                i += 1
            else:
                f.write('%s\n' % row.getValue(field.name))
    del rows
    f.close()

Czy ktoś wie, co się tutaj dzieje?


Zmodyfikowałem swój kod, aby postępować zgodnie z radą @sgrieve i nadal pisałem to Shapepole. Jeśli dodać linię do wydrukowania nazwy pól jak to iteracje przez nich, to wymienia wszystkie pola z wyjątkiem tej Shapedziedzinie, a mimo to nadal zapisuje do pliku CSV. Dodano także współrzędne X i Y wielokąta jako dwie nowe kolumny, a kolumny nie są już wyrównane z nazwami kolumn.

Zmodyfikowałem wiersz, w którym @sgrieve deklaruje następujące pola:

fields = [f.name for f in arcpy.ListFields('FinalCadastre') if f.type <> 'Geometry']

Nowy kod działa dobrze, ale nadal nie jestem pewien, na czym polegał problem. Czy ktoś wie, co się działo? O co chodzi z Shapepolem?

Fezter
źródło
Czy potrzebujesz tutaj użyć Pythona? Bardzo łatwo ukryć niepotrzebne pola za pomocą karty Pola właściwości warstwy. Następnie z otwartej tabeli atrybutów Eksportuj dane do formatu pliku tekstowego (czyli CSV), aby uzyskać tylko te pola, które chcesz.
PolyGeo
Tak, chcę to dodać do mojego skryptu. To wymóg klienta.
Fezter
Czy ktoś jeszcze wie, co się tutaj dzieje? Czy ktoś wie, dlaczego Shapepole zostało zapisane do pliku? Chociaż kod @ sgrieve prawdopodobnie poprawił mój kod, nie rozwiązał problemu.
Fezter
1
Moje podejście do tego byłoby użycie MakeTableView, a następnie TableToTable . Jeśli twoje podejście się nie uda, może to być inny sposób na „utratę” pola kształtu.
PolyGeo

Odpowiedzi:

14

Uprościłem twój kod i poprawiłem błąd, używając modułu da wprowadzonego w 10.1. Znacznie usprawnia odczytywanie danych za pomocą kursorów i używany w połączeniu z withpoleceniem ten kod powinien być bardziej stabilny, niż gdyby używał starszej metody dostępu do plików.

Działa, tworząc listę wszystkich pól, a następnie usuwając pola, których nie chcesz z listy. Można to zrobić w ramach listy, ale byłoby to dość niechlujne i pozbawione pythonów. Po utworzeniu listy żądanych pól jest ona używana z modułem da do odczytu wszystkich danych z tych pól do kursora. Następnie można go zapętlić i zapisać w pliku, używając innego zrozumienia listy, aby połączyć wszystkie pola. Ma to tę zaletę, że działa dla dowolnej liczby pól większych niż 0.

import arcpy

fc = 'C:\\antenna_shp\\cables.shp'
CSVFile = 'C:\\antenna_shp\\FinalOutput.csv'

fields = [f.name for f in arcpy.ListFields(fc)]

for i,f in enumerate(fields):
    if f == 'Shape' or f == 'Shape_Length' or f == 'OBJECTID':
        del fields[i]

with open(CSVFile, 'w') as f:
    f.write(','.join(fields)+'\n') #csv headers
    with arcpy.da.SearchCursor(fc, fields) as cursor:
        for row in cursor:
            f.write(','.join([str(r) for r in row])+'\n')
sgrieve
źródło
Dzięki @sgrieve. Skopiowałem opublikowany kod i otrzymuję plik CSV, który jest prawie tym, czego chcę. Ale jest kilka problemów. 1. Nazwa Shapepola wciąż jest zapisywana, ale wartości Kształt nie. 2. Istnieją teraz dwie nowe kolumny, które zostały dodane na początku tabeli, skutecznie przesuwając kolumny w prawo. Kolumny wydają się być współrzędnymi X i Y wielokąta.
Fezter
3
Ok, chyba to wypracowałem. Coś działo się z Shapepolem - może dlatego, że jest to typ geometrii. Zmodyfikowałem więc linię, w której deklarujesz, fieldsże jest następująca: fields = [f.name for f in arcpy.ListFields('FinalCadastre') if f.type <> 'Geometry'] to załatwiło sprawę. Nie jestem jednak pewien, dlaczego to nie działałoby.
Fezter
2

Myślę, że napotkałem ten sam problem i odkryłem powód, dla którego twoje pole „Kształt” nie zostało usunięte. Podczas korzystania z tej pętli:

if field.name in (['OBJECTID', 'Shape', 'Shape_Length']):
    fields.remove(field)

Odkryłem, że w rzeczywistości usuwa tylko każde inne pole. Więc najpierw przejdzie przez pętlę, usunie „OBJECTID”, a następnie pole „Shape” przejdzie do miejsca zajmowanego poprzednio przez „OBJECTID” na liście, więc przejdzie do następnego, którym będzie wówczas „Shape_Length”.

Tak więc to nie geometria kształtu uniemożliwiała jego usunięcie, tylko fakt, że usuwa on każde inne pole podczas używania tego skryptu.

Sara Flecher
źródło
Dobry pomysł, w którym to przypadku utworzenie wielu instrukcji if (nie elifs) może rozwiązać problem.
Sleep6
Mutowanie listy w pętli nie jest dobrym pomysłem. Możesz uzyskać nieoczekiwane wyniki. Zobacz ten post na podobny problem, który miałem.
Fezter
0

Kluczem do jednego aspektu tego jest określenie właściwej nazwy dla nieokreślonych przez użytkownika pól identyfikatora i geometrii obiektu. Typ pola geometrii to Double, co w tym przypadku jest nieprzydatne. Za pomocą funkcji opisu można określić poprawną nazwę dla tych pól dla różnych typów plików (np. Shapefile v plik gdb itp.; Złagodzenie wielu smutków, ponieważ oid zmieni się nawet w obrębie tego samego typu pliku czasami ...).

fc = 'path to my featureclass'
desc = arcpy.Describe(fc)
fields = [f.name for f in arcpy.ListFields(fc) if f.name not in (desc.OIDFieldName, desc.areaFieldName, desc.lengthFieldName), desc.shapeFieldName)]
David Richey
źródło