ArcGIS for Desktop'ta CSV dosyasına yalnızca belirli sütunlar dışa aktarılsın mı?


15

File Geodatabase içine bir çokgen özelliği sınıfı çıktılar arcpy kullanarak bir python komut dosyası yazdım. Öznitelikleri ayrı bir CSV dosyasına vermek için bir işlev ekledim. Mükemmel çalışan bu yazıda bulduğum kodu kullanıyorum . Ancak, bu kod özellik sınıfındaki her sütunu dışa aktarır. : Ben yalnızca aşağıdaki adları yok alanları vermek istiyorsanız OBJECTID, Shapeya Shape_Length.

Benim CSV dosyası başarıyla oluşturur ve doğru değildir içerir OBJECTIDveya Shape_Lengthalanları. Ancak, Shapesaha olan dosyaya yazılır. Bu alana yazılan bir örnek değer:

<geoprocessing describe geometry object object at 0x28CB90A0>

Alan adlarını yineleyerek yazdırmak için bir satır ekledim ve şaşırtıcı bir şekilde Shapeyazdırılmadı. ArcGIS onu gizliyor ya da farklı bir isim veriyor gibi.

Benim fonksiyonumun kodu aşağıdadır:

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

Burada neler olduğunu bilen var mı?


@Sgrieve tavsiyesini takip etmek için kodumu değiştirdim ve hala Shapealan yazıyordu . Onlara arasında dolaşır gibi alan adlarını yazdırmak için bir satır eklerseniz, tüm alanları listeler hariçShape alanda, henüz hala CSV yazar. Ayrıca çokgenin X ve Y koordinatlarını iki yeni sütun olarak ekledi ve sütunlar artık sütun adlarıyla hizalanmadı.

@Sgrieve alanların aşağıdaki gibi olduğunu bildiren satırı değiştirdim:

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

Yeni kod iyi çalışıyor, ancak hala sorunun ne olduğundan emin değilim. Neler olup bittiğini bilen var mı? ShapeSaha ile olan anlaşma nedir ?


Burada Python kullanmanız mı gerekiyor? Katman Özellikleri katmanının Alanlar sekmesini kullanarak istemediğiniz alanları gizlemek çok kolaydır. Ardından, açık nitelik tablosundan Verileri Metin Dosyası (CSV biçiminde) biçiminde dışa aktarın ve yalnızca istediğiniz alanları elde edin.
PolyGeo

Evet, betiğimin eklenmesini istiyorum. Bu bir müşteri gereksinimi.
Fezter

Burada neler olduğunu bilen var mı? ShapeAlanın dosyaya neden yazıldığını bilen var mı ? @ Sgrieve kodu muhtemelen kodumu geliştirirken, sorunu çözmedi.
Fezter

1
Bunu benim yaklaşım MakeTableView sonra TableToTable kullanmak olacaktır . Yaklaşımınız oraya ulaşmazsa bu, Şekil alanınızı "kaybetmenin" başka bir yolu olabilir.
PolyGeo

Yanıtlar:


14

10.1'de tanıtılan da modülünü kullanarak kodunuzu basitleştirdim ve hatayı düzelttim . İmleçleri kullanarak verilerin okunmasını büyük ölçüde kolaylaştırır ve withkomutla birlikte kullanılan bu kod, daha eski dosya erişim yöntemini kullanmasından daha kararlı olmalıdır.

Tüm alanların bir listesini yapıp sonra istemediğiniz alanları listeden kaldırarak çalışır. Bu liste kavrayışı içinde yapılabilir, ancak oldukça dağınık ve pythonic olurdu. İstenen alanların listesi oluşturulduktan sonra, bu alanlardaki tüm verileri imlece okumak için da modülüyle birlikte kullanılır. Bu, daha sonra tüm alanlara katılmak için başka bir liste kavrayışı kullanılarak döngüye sokulabilir ve dosyaya yazılabilir. Bunun, 0'dan büyük herhangi bir alanda çalışma avantajı vardır.

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')

Teşekkürler @sgrieve. Gönderdiğiniz kodu kopyaladım ve neredeyse istediğim bir CSV dosyası aldım. Ancak birkaç sorun var. 1. ShapeAlan adı hala yazılıyor, ancak Shape değerleri yazılmıyor. 2. Tablonun başına, sütunları etkin bir şekilde sağa kaydıran iki yeni sütun eklenmiştir. Sütunlar çokgenin X ve Y koordinatları gibi görünür.
Fezter

3
Tamam, sanırım ben hallettim. ShapeAlanda bir şeyler vardı - belki de bir geometri türü olduğu için. Yani, fieldsaşağıdaki olduğunu beyan ettiğiniz satırı değiştirdim : fields = [f.name for f in arcpy.ListFields('FinalCadastre') if f.type <> 'Geometry'] hile yaptı. O olmasa da neden işe yaramadığından emin değilim.
Fezter

2

Aynı problemle karşılaştığımı ve "Şekil" alanınızın kaldırılmamasının nedenini keşfettiğimi düşünüyorum. Bu döngüyü kullanırken:

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

Aslında sadece diğer alanların kaldırıldığını keşfettim. Bu yüzden önce 'OBJECTID' öğesini kaldırır, daha sonra 'Shape' alanı daha önce listede 'OBJECTID' tarafından tutulan yere gider, böylece bir sonrakine geçer ve daha sonra 'Shape_Length' olur.

Bu nedenle, kaldırılmasını engelleyen özel olarak Şekil geometrisi değildi, sadece bu komut dosyasını kullanırken diğer tüm alanları kaldırmasıydı.


İyi fikir, bu durumda birden fazla if ifadesi (elif değil) oluşturmak sorunu çözebilir.
6

Bir listeyi döngü halinde değiştirmek iyi bir fikir değildir. Beklenmedik sonuçlar alabilirsiniz. Ben de benzer bir konuda bu yazı bakın .
Fezter

0

Bunun bir yönünün anahtarı, nesne kimliği ve geometrisinin kullanıcı tanımlı olmayan alanları için doğru adı belirlemektir. Geometri alanının türü, bu durumda yararsız olan Çift'tir. Tanımlama işlevini kullanarak, dosya türleri arasında bu alanlar için doğru ad belirlenebilir (ör. Shapefile v file gdb, vb; oid olarak çok fazla keder hafifletmek bazen aynı dosya türü içinde bile değişecektir ...).

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)]
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.