Gabungkan Fitur-Fitur Spasial Bertepatan di Kelas Fitur yang Sama

8

Saya perlu cara untuk menggabungkan sel-sel kisi secara terprogram (poligon 15x15 m) yang secara langsung berada di atas satu sama lain dan menambahkan bersama beberapa atribut mereka.

Saya bekerja di ArcGIS 10.1 dengan data disimpan sebagai kelas fitur poligon.

Data tersebut adalah hasil survei pejalan kaki melintasi kisi yang telah ditentukan sebelumnya. Kadang-kadang orang-orang yang melakukan survei pejalan kaki keluar jalur dan merekam sesuatu di kolom atau baris yang berdekatan dengan tempat mereka bekerja (atau posisi GPS mengembara). Ini menghasilkan dua set data yang direkam untuk setiap sel ketika data dari beberapa unit GPS ditambahkan ke kelas fitur tunggal. Saya perlu cara untuk memeriksa setiap sel, periksa untuk melihat apakah ada fitur duplikat, jika ada kemudian menggabungkan atribut mereka (beberapa integer, beberapa teks), dan kemudian menghapus satu fitur yang tidak mendapatkan data yang digabungkan.

Alat 'Delete Identical' dan 'Find Identical' tidak melakukan apa yang saya cari - dan melakukannya secara manual bukanlah suatu pilihan karena kelas fitur sering memiliki lebih dari 10.000 fitur di dalamnya.

Saya tahu cara mengulangi kelas fitur menggunakan python dan memeriksa untuk menentukan apakah ada fitur duplikat di lokasi itu. Apa yang saya tidak tahu bagaimana melakukannya adalah berurusan dengan menggabungkan fitur dan memperbarui atribut. Jika ada yang bisa memberikan arahan tentang bagaimana mencapai ini saya akan sangat menghargainya.

EDIT - Keterangan Lebih Lanjut Sebelum / Setelah Status: Pada gambar di bawah ini ada dua fitur yang dipilih - poligon persegi 15x15 meter yang identik, saya perlu menambahkan bersama semua bidang bilangan bulat (yang dengan TOT_ sebagai awalan) dan menambahkan GPS_UNIT, INITIALS , dan REC_DATE bidang string.

Sulit untuk ditampilkan karena fitur langsung tumpang tindih.

masukkan deskripsi gambar di sini

EDIT 2: Saya telah menemukan bahwa saya dapat dengan mudah mengidentifikasi fitur yang digandakan dengan menghitung pusat XY mereka, menggabungkannya menjadi bidang string sebagai [X] & ',' & [Y] kemudian membuka database dalam akses dan menggunakan kueri Find Duplicates. untuk mengidentifikasi sel mana yang telah diduplikasi. Namun saya belum bisa menemukan cara yang baik untuk menggabungkan atribut untuk masing-masing sel menjadi satu baris. Bantuan dengan cara melakukan itu, baik dalam python atau dalam lingkungan basis data, akan sangat diterima!

Kevin
sumber
1
Bisakah Anda memposting area sampel kecil dengan status "sebelum dan sesudah koreksi"?
blah238

Jawaban:

2

Karena Anda tahu cara mengulang dan menemukan fitur yang ingin Anda gabungkan, saya akan membangun sebuah fungsi untuk melakukan penggabungan yang mungkin bisa menjadi arcpy.Dissovle_management (). Lakukan pembubaran dan Anda mungkin dapat menggunakan parameter agregasi untuk menggabungkan atribut kemudian menghapus fitur-fitur dari yang asli dan memperbarui data kembali dengan memasukkan kursor.

Bagaimana Anda mengidentifikasi fitur mana yang perlu digabungkan?

Justin
sumber
Sejauh ini cara terbaik untuk menggabungkan fitur ID adalah dengan beralih melalui dan melakukan pemilihan dengan lokasi menggunakan fitur yang dipilih sebagai sumber dan lapisan sebagai target. Lalu, saya menggunakan arcpy.getCount untuk melihat berapa banyak fitur yang dipilih, jika lebih dari satu, maka saya perlu menggabungkan atribut semua fitur yang dipilih menjadi satu dan menghapus yang lainnya.
Kevin
2

Saya akhirnya menyelesaikan masalah ini setelah saya pindah ke Postgres dan memiliki beberapa alat yang lebih kuat. Solusi saya adalah menghapus fitur-fitur tambahan dengan bidang GEOM yang identik - meninggalkan satu saja, dan kemudian menghitung kembali nilai-nilai dari data lain yang dikumpulkan selama kerja lapangan. Ini memberi saya dataset tanpa fitur spasial dan total akurat dalam tabel atribut. Kode PHP lengkap yang saya gunakan adalah di bawah ini; Saya yakin hal yang sama dapat dicapai dengan Python tetapi PHP adalah rute termudah bagi saya pada saat itu.

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
    <title>TRU Recalculation</title>
</head>

<body>
    <!-- Progress bar holder -->
    <div id="progress" style="width:500px;border:1px solid #ccc;"></div>
    <!-- Progress information -->
    <div id="information" style="width"></div>

    <?php
        $tot_deb = 0;
        $mfr_tool = 0;
        $tot_ltool = 0;
        $tot_gs = 0;
        $tot_cerl = 0;
        $tot_cern = 0;
        $tot_fcr = 0;
        $tot_pfeat = 0;
        $tot_hist = 0;
        $tot_hfeat = 0;
        $tot_art = 0;

        $dbconn = pg_connect("host=localhost port=54321 dbname=sixksurvey user=postgres password=password");

        $TRU_set = pg_query($dbconn, "select gid, east, north, tot_deb, mfr_tool, tot_ltool, tot_gs, tot_cerl, tot_cern, tot_fcr, tot_pfeat, tot_hist, tot_hfeat, comment, tot_art, surf_sed, visibility, hdop, sats, gps_unit, initials, rec_date from trutest_full order by north asc");

        $total = pg_num_rows($TRU_set);
        $i = 1; //Just a counter for the progress bar

        if (pg_num_rows($TRU_set) > 0)
        {
            while($current_TRU = pg_fetch_row($TRU_set))
            {

                if ($current_TRU) 
                {
                    // Calculate the percent
                    $percent = intval($i/$total * 100)."%";

                    // Javascript for updating the progress bar and information
                    echo '<script language="javascript">
                    document.getElementById("progress").innerHTML="<div style=\"width:'.$percent.';background-color:#2CA25F;\">&nbsp;</div>";
                    document.getElementById("information").innerHTML="'.$i.' TRU Cells Recalculated.";
                    </script>';

                    // Select all the LITHICS within the current TRU and count them up according to their types, then assign the new count to the relevant total variable.
                    $ALL_Lithics = pg_query($dbconn,"SELECT type, art_count FROM lithic join trutest_full ON ST_CONTAINS(trutest_full.geom, lithic.geom) WHERE trutest_full.gid = " . $current_TRU[0]);
                    while($current_LITHIC = pg_fetch_row($ALL_Lithics))
                    {
                        //If statement for tot_deb
                        if ($current_LITHIC[0] == 'Angular Debris' or $current_LITHIC[0] == 'Biface Thinning Flake' or $current_LITHIC[0] == 'Hammer stone')
                        {
                            $tot_deb += $current_LITHIC[1];
                        }

                        //If statement for mfr_tool
                        if ($current_LITHIC[0] == 'Test Nod/Core' or $current_LITHIC[0] == 'Reduced Core' or $current_LITHIC[0] == 'Core Red. Flake')
                        {
                            $mfr_tool += $current_LITHIC[1];
                        }
                        //If statement for tot_ltool
                        if ($current_LITHIC[0] == 'Scraper' or $current_LITHIC[0] == 'Uniface' or $current_LITHIC[0] == 'Retouched Tool' or
                            $current_LITHIC[0] == 'Proj. Point' or $current_LITHIC[0] == 'Biface' or $current_LITHIC == 'Other')
                        {
                            $tot_ltool += $current_LITHIC[1];
                        }
                    }


                    // Select all the CERAMICS within the current TRU and count them up according to their types, then assign the new count to the relevant total variable.
                    $ALL_Ceramics = pg_query($dbconn,"SELECT type, art_count FROM ceramic JOIN trutest_full ON ST_CONTAINS(trutest_full.geom, ceramic.geom) WHERE trutest_full.gid = " . $current_TRU[0]);
                    while($current_CERAMIC = pg_fetch_row($ALL_Ceramics))
                    {
                        // Calculate new total for Local Ceramics
                        if ($current_CERAMIC[0] == 'EP Brown' or $current_CERAMIC[0] == 'EP brownware' or $current_CERAMIC[0] == 'EP Poly' or $current_CERAMIC[0] == 'EP Decorated' or $current_CERAMIC[0] == 'EP UB' or $current_CERAMIC[0] == 'Jornada Brown' or $current_CERAMIC[0] == 'EP Bichrome')
                        {
                            $tot_cerl += $current_CERAMIC[1];
                        }

                        // Calculate new total for Non-Local Ceramics
                        else
                        {
                            $tot_cern += $current_CERAMIC[1];
                        }
                    }
                    // Select all the FCR within the current TRU and count them up according to their types, then assign the new count to the relevant total variable.
                    $ALL_fcr = pg_query($dbconn,"SELECT art_count FROM fcr JOIN trutest_full ON ST_CONTAINS(trutest_full.geom, fcr.geom) WHERE trutest_full.gid = " . $current_TRU[0]);
                    while($current_FCR = pg_fetch_row($ALL_fcr))
                    {
                        $tot_fcr += $current_FCR[0];
                    }               

                    // Select all the FEATURES within the current TRU and count them up 
                    $ALL_features = pg_query($dbconn,"SELECT type FROM fcr JOIN trutest_full ON ST_CONTAINS(trutest_full.geom, fcr.geom) WHERE trutest_full.gid = " . $current_TRU[0]);
                    while($current_Feat = pg_fetch_row($ALL_features))
                    {
                        // Test the type of the feature to identify the historic features (I started here because there are fewer types, this is faster).  Rather than try to count the rows,
                        // I just add 1 to each total for each feature that is being tested
                        if ($current_Feat[0] == 'Historic Artifact Conc.' or $current_Feat[0] == 'Historic Water Feature' or $current_Feat[0] == 'Historic Structure')
                        {
                            $tot_hfeat += 1;    
                        }
                        else
                        {
                            $tot_pfeat += 1;
                        }
                    }
                    // Select all the GS within the current TRU and count them up 
                    $ALL_gs = pg_query($dbconn,"SELECT art_count FROM gs JOIN trutest_full ON ST_CONTAINS(trutest_full.geom, gs.geom) WHERE trutest_full.gid = " . $current_TRU[0]);
                    while($current_GS = pg_fetch_row($ALL_gs))
                    {
                        $tot_gs += $current_GS[0];
                    }   

                    // Select all the HISTORIC within the current TRU and count them up according to their types, then assign the new count to the relevant total variable.
                    $ALL_historic = pg_query($dbconn,"SELECT art_count FROM historic JOIN trutest_full ON ST_CONTAINS(trutest_full.geom, historic.geom) WHERE trutest_full.gid = " . $current_TRU[0]);
                    while($current_HISTORIC = pg_fetch_row($ALL_historic))
                    {
                        $tot_hist += $current_HISTORIC[0];
                    }   

                    // Count all the artifacts and assign to TOT_ART
                    $tot_art = $tot_deb + $mfr_tool + $tot_ltool + $tot_cerl + $tot_cern + $tot_fcr + $tot_hist + $tot_gs;

                    // Something here to merge initials/date recorded/surface/visibiilty/etc into the comments for merged cells
                    // This code isn't the place to do this...  //Not dealing with duplicates here, just every cell in the set...


                    // Send the updated counts back to the database.
                    $result = pg_query($dbconn,"UPDATE trutest_full SET tot_deb = " . $tot_deb . ", mfr_tool = " . $mfr_tool . ", tot_ltool = " . $tot_ltool . ", tot_gs = " . $tot_gs . ", tot_cerl = " . $tot_cerl . ", tot_cern = " . $tot_cern . ", tot_fcr = " . $tot_fcr . ", tot_pfeat = " . $tot_pfeat . ", tot_hist = " . $tot_hist . ", tot_hfeat = " . $tot_hfeat . ", tot_art = " . $tot_art . " WHERE trutest_full.gid = " . $current_TRU[0]);

                    // This is for the buffer achieve the minimum size in order to flush data
                    echo str_repeat(' ',1024*64);

                    // Send output to browser immediately
                    flush();

                    if (!$result)
                    {
                        echo 'Update Query Failed in TRU.gid = ' . $current_TRU[0];
                    }

                    // Zero out all the hoppers for the next go-round
                    $tot_deb = 0;
                    $mfr_tool = 0;
                    $tot_ltool = 0;
                    $tot_gs = 0;
                    $tot_cerl = 0;
                    $tot_cern = 0;
                    $tot_fcr = 0;
                    $tot_pfeat = 0;
                    $tot_hist = 0;
                    $tot_hfeat = 0;
                    $tot_art = 0;

                    $i += 1;
                }
            }
        }
        echo 'TRU Recalculate Done';
    ?>

</body>
</html>
Kevin
sumber
0

Karena Anda hanya ingin menggabungkan atribut untuk sel (sebenarnya poligon) yang identik maka saya akan menggunakan Union dan menyimpan semua atribut. Dengan begitu Anda dapat mengulangi melalui semua poligon (sel) yang dihasilkan dan memiliki akses ke kedua set atribut asli untuk menulis nilai baru apa pun yang Anda inginkan. Jika nama atribut yang sama digunakan oleh kedua kelas fitur asli, Anda mungkin perlu melakukan beberapa penamaan ulang bidang sebelum Union sehingga keduanya tetap tersedia.

Sebenarnya, membaca kembali pertanyaan Anda dengan cepat memberi tahu saya bahwa Anda hanya memiliki satu kelas fitur masukan. Union mungkin masih berguna karena dapat berjalan melawan satu kelas fitur seperti yang dijelaskan di sini .

PolyGeo
sumber
Saya tidak berpikir untuk menggunakan Union daripada menambahkan ketika menggabungkan data dari masing-masing unit GPS ... Melakukan itu akan menghilangkan masalah tumpang tindih spasial dan kemudian saya hanya harus berurusan dengan yang lebih mudah. Adakah pemikiran tentang masalah yang mungkin muncul saat menggabungkan 20 kelas fitur secara bersamaan?
Kevin
Hanya bahwa Anda mungkin perlu memiliki lisensi Advanced (ArcInfo) jika Anda ingin melakukannya sekaligus. Dengan Dasar dan Standar, Anda harus melakukan Serikat pekerja berpasangan dan mengagregasi hasilnya.
PolyGeo