Bagaimana cara menerapkan teorema empat warna dalam peta poligon di ArcGIS / ArcToolBox secara otomatis?

19

Saya perlu menerapkan teorema empat warna dalam bentuk poligonal sehingga saya tidak perlu memilih secara manual setiap warna untuk diletakkan di setiap wilayah. Saya ingin tahu apakah ada ekstensi, plug-in, skrip, atau basis data yang dapat digunakan dengan ArcGIS dan ArcToolBox untuk melakukannya secara matematis atau terprogram, sehingga saya dapat menggunakannya untuk saat ini dengan setiap peta yang saya buat.

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini

Please_Dont_Bully_Me_SO_Lords
sumber
1
Saya juga ingin tahu apakah ada fungsi ini di sistem lain selain ArcGIS, seperti QuantumGIS ...
Please_Dont_Bully_Me_SO_Lords
2
Saya memposting solusi suboptimal pada GIS (dengan Rkode kerja ) dan solusi optimal (yang akan menggunakan tiga atau bahkan dua warna jika mereka dapat ditemukan berfungsi) di Mathematica . Solusi itu bersifat rekursif; yang membalas posting saya memberikan solusi pemrograman linear. Manifold GIS telah lama memiliki algoritma lima warna yang terintegrasi. (Empat warna sulit dilakukan; lima warna relatif mudah dicapai.)
whuber
Jika Anda tidak memiliki "kode sejauh ini" rekomendasi ArcGIS untuk Desktop saya akan mulai dengan alat Polygon Neighbors untuk mendapatkan tabel yang mencantumkan semua tetangga dari setiap poligon.
PolyGeo
@ PolyGeo: terima kasih atas alat-alatnya (saya tidak tahu itu) tapi saya tidak bisa menggunakannya untuk menyelesaikan masalah saya
radouxju

Jawaban:

12

Pertama-tama, terima kasih atas semua jawaban dan komentar. Sayangnya, alat yang ada tidak sepenuhnya kompatibel dengan versi terbaru QGIS dan ArcGIS. Oleh karena itu saya membuat solusi sendiri menggunakan alat yang ditunjukkan oleh @polygeo, plugin QGIS dari @Alexandre dan nama algoritme (peta empat warna) dari @Jens.

Berikut ini adalah kode saya untuk mereka yang tertarik (untuk ArcGIS tetapi bagian kedua juga dapat digunakan di QGIS).

arcpy.MakeFeatureLayer_management(fc, fc[:-4]+ "_lyr" )
try:
    arcpy.AddField_management(fc[:-4] + "_lyr", "color", "SHORT")
except:
    print "field alread exists"   
arcpy.CalculateField_management(fc[:-4] + "_lyr", "color",  "10" , "PYTHON")

arcpy.PolygonNeighbors_analysis(fc[:-4] + "_lyr", fc[:-4] + "_tb.dbf" )
graph = []
cursor=arcpy.da.SearchCursor( fc[:-4] + "_tb.dbf" , ("src_FID","nbr_FID") )
for row in cursor:
    graph.append(row)


pols = arcpy.da.UpdateCursor(fc[:-4] + "_lyr", ("OID@","color"))
colored = []
for pol in pols:
    nbrs = [ second for first, second in graph if first == pol[0]]
    usedcolors = []
    for nbr in nbrs:
        usedcolors += [second for first, second in colored if first == nbr]
    pol[1]=[color for color in range(10) if color not in usedcolors][0]
    colored.append(pol)
    pols.updateRow(pol)

Perhatikan bahwa algoritme tidak menjamin bahwa hanya 4 warna yang digunakan: meskipun telah terbukti bahwa solusinya ada, "kekuatan kasar" diperlukan untuk mencapainya. Dalam kasus saya, saya mendapat 7 warna yang cukup kecil. Script bisa memiliki loop tambahan hingga solusinya ditemukan, tetapi saya perlu melakukannya untuk ratusan peta dan 7 warna OK.

radouxju
sumber
2
Ini luar biasa - terima kasih banyak sudah berbagi. Saya perhatikan di ArcGIS 10.2 nama bidang pada tabel output PolygonNeighbors telah sedikit berubah - bidang sekarang disebut src_OBJECT dan nbr_OBJECT
Stephen Lead
Apakah skrip ini optimal yaitu apakah ini memastikan bahwa warna minimum akan digunakan?
Di bawah Radar
1
Sejauh yang saya mengerti, kekuatan mentah diperlukan. Seperti yang disebutkan dalam posting saya, Anda harus menjalankannya beberapa kali untuk memiliki kesempatan untuk mencapai 4 warna.
radouxju
Masih bekerja dengan baik! Mungkin nama bidang src_ * dan nbr_ * bergantung pada tipe input. Saya menjalankannya sekarang dengan input geodatabase fc dan Desktop 10.5 dan mereka diberi nama src_OBJECTID dan nbr_OBJECTID. Skrip dapat disesuaikan untuk mencantumkan bidang yang dimulai dengan src dan nbr sehingga jenis input (atau versi ArcGIS) tidak masalah.
BERA
3

Jika Anda menggunakan QGIS, saya percaya bahwa yang Anda butuhkan adalah plugin Coloring a map .

Sayangnya, plugin ini hanya tersedia untuk versi QGIS 1.8, tetapi Anda selalu dapat mengunduh dan melihat bagaimana kodenya bekerja!

Alexandre Neto
sumber
3

Ini adalah adaptasi dari jawaban @ radouxju ke dalam suatu fungsi. Ini akan menambahkan bidang warna ke lapisan fitur input dan menghitung. Ini harus bekerja terlepas dari akhiran nama bidang PolygonNeighbors (mereka tampaknya berbeda untuk versi pengguna / input / arcgis yang berbeda (?))

def color_me(feature_layer):
    import arcpy
    try:
        arcpy.AddField_management(feature_layer, 'color', 'SHORT')
    except:
        print 'field alread exists'   

    arcpy.CalculateField_management(feature_layer, 'color',  '10' , 'PYTHON')

    arcpy.PolygonNeighbors_analysis(feature_layer, r'in_memory\neighbor_table' )
    graph = []
    neighbor_fields = [f.name for f in arcpy.ListFields(r'in_memory\neighbor_table') if f.name.startswith(('src', 'nbr'))]
    cursor=arcpy.da.SearchCursor(r'in_memory\neighbor_table' , neighbor_fields)
    for row in cursor:
        graph.append(row)

    pols = arcpy.da.UpdateCursor(feature_layer, ('OID@','color'))
    colored = []

    for pol in pols:
        nbrs = [ second for first, second in graph if first == pol[0]]
        usedcolors = []
        for nbr in nbrs:
            usedcolors += [second for first, second in colored if first == nbr]
        pol[1]=[color for color in range(10) if color not in usedcolors][0]
        colored.append(pol)
        pols.updateRow(pol)
    arcpy.Delete_management(r'in_memory\neighbor_table')

masukkan deskripsi gambar di sini

BERA
sumber