Як автоматично застосувати теорему про чотири кольори у полігоновій карті в ArcGIS / ArcToolBox?


19

Мені потрібно застосувати теорему про чотири кольори в полігональній формі таким чином, що мені не потрібно вручну вибирати кожен колір, який слід розмістити в кожній області. Я хотів би знати, чи є розширення, плагін, скрипт або база даних, які можуть використовуватися з ArcGIS і ArcToolBox, щоб зробити це математично або програмно, тому я можу зараз використовувати його для кожної карти, яку я створюю.

введіть тут опис зображення введіть тут опис зображення введіть тут опис зображення


1
Я також хотів би знати, чи є така функціональність в інших системах, крім ArcGIS, як QuantumGIS ...
Please_Dont_Bully_Me_SO_Lords

2
Я розмістив субоптимальне рішення на ГІС (з робочим Rкодом) та оптимальне рішення (яке використовуватиме три чи навіть два кольори, якщо їх можна буде знайти) на Mathematica . Це рішення є рекурсивним; відповідь на мій пост дає лінійне рішення програмування. Колекторний ГІС вже давно вбудований п'ятиколірний алгоритм (
чотириколірний

Якщо у вас поки що немає «коду», моя рекомендація ArcGIS for Desktop буде починати з інструменту « Сусіди полігону », щоб отримати таблицю з переліком усіх сусідів кожного багатокутника.
PolyGeo

@PolyGeo: дякую за інструменти (я цього не знав), але я не міг використовувати його для вирішення своєї проблеми
radouxju

Відповіді:


12

Перш за все, дякую за всі відповіді та коментарі. На жаль, існуючі інструменти не були повністю сумісні з останніми версіями QGIS та ArcGIS. Тому я зробив власне рішення, використовуючи інструмент, вказаний @polygeo, плагін QGIS від @Alexandre та ім'я алгоритму (чотири кольорової карти) від @Jens.

Ось мій код для зацікавлених (для ArcGIS, але друга частина може бути використана і в 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)

Зауважте, що алгоритм не гарантує використання лише 4 кольорів: хоча це було доведено, що рішення існує, для його досягнення необхідна "груба сила". У моєму випадку я отримав 7 кольорів, що досить мало. Сценарій може мати додатковий цикл, поки рішення не знайдеться, але мені потрібно зробити це для сотень карт і 7 кольорів.


2
Це геніально - дуже дякую, що поділилися ним. Я помітив на ArcGIS 10.2 імена полів у вихідній таблиці PolygonNeighbors трохи змінилися - поля тепер називаються src_OBJECT, а nbr_OBJECT
Stephen Lead

Чи цей сценарій є оптимальним, тобто чи гарантує використання мінімуму кольорів?
Нижче

1
Наскільки я зрозумів, потрібна сира сила. Як згадувалося в моєму дописі, ви повинні запустити його кілька разів, щоб мати можливість досягти 4 кольорів.
radouxju

Ще чудово працює! Можливо, назви полів src_ * та nbr_ * залежать від типу введення. Я запустив це зараз із введенням fc geodatabase та Desktop 10.5, і вони отримали назву src_OBJECTID та nbr_OBJECTID. Сценарій може бути скоригований так, щоб перелічити поля, які починаються з src та nbr, тому тип введення (або версія ArcGIS) не має значення.
БЕРА

4

Існує зразок розробника VB6 та інструмент для геообробки ArcGIS 9.x, але з коментарів до цієї ідеї ArcGIS вони не працюють на 10.0+.

Можливо, комусь було б цікаво передати його.

Рішення QGIS під назвою TopoColour наведено в коментарях до цього пов'язаного питання: Колір полігонів, так що кожен відрізняється від своїх сусідів


3

Якщо ви використовуєте QGIS, я вважаю, що вам потрібен плагін Coloring a map .

На жаль, плагін доступний лише для версії QGIS 1.8, але ви завжди можете завантажити та подивитися, як працює код!


3

Це адаптація відповіді @ radouxju у функції. Це додасть кольорове поле до вхідного шару функції та обчислить. Він повинен працювати незалежно від закінчень назви поля PolygonNeighbors (вони здаються різними для різних користувачів / входів / версій arcgis (?))

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

введіть тут опис зображення

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.