Wie wende ich den Vier-Farben-Satz in einer Polygon-Map in ArcGIS / ArcToolBox automatisch an?

19

Ich muss das Vier-Farben-Theorem in einer polygonalen Form so anwenden , dass ich nicht jede Farbe manuell auswählen muss, um sie in die einzelnen Bereiche einzufügen. Ich möchte wissen, ob es Erweiterungen, Plug-Ins, Skripte oder Datenbanken gibt, die mit ArcGIS und ArcToolBox mathematisch oder programmatisch verwendet werden können, sodass ich sie jetzt für jede Karte verwenden kann, die ich erstellen möchte.

Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben Bildbeschreibung hier eingeben

Please_Dont_Bully_Me_SO_Lords
quelle
1
Ich würde auch gerne wissen, ob es diese Funktionalität in anderen Systemen als ArcGIS gibt, wie QuantumGIS ...
Please_Dont_Bully_Me_SO_Lords
2
Ich habe eine suboptimale Lösung für GIS (mit RArbeitscode) und eine optimale Lösung (die drei oder sogar zwei Farben verwendet, wenn sie funktionieren) für Mathematica veröffentlicht . Diese Lösung ist rekursiv; Die Antwort auf meinen Beitrag gibt eine lineare Programmierlösung. In Manifold GIS ist seit langem ein Fünf-Farben-Algorithmus integriert. (Vierfarben sind schwierig,
Fünffarben
Wenn Sie noch keinen "Code" haben, besteht meine Empfehlung für ArcGIS for Desktop darin, mit dem Werkzeug " Polygon-Nachbarn" zu beginnen, um eine Tabelle mit allen Nachbarn jedes Polygons zu erhalten.
PolyGeo
@PolyGeo: Danke für die Tools (ich wusste es nicht), aber ich konnte es nicht verwenden, um mein Problem zu lösen
radouxju

Antworten:

12

Zunächst einmal vielen Dank für alle Antworten und Kommentare. Leider waren die vorhandenen Tools nicht vollständig mit den neuesten Versionen von QGIS und ArcGIS kompatibel. Aus diesem Grund habe ich meine eigene Lösung mit dem von @polygeo angegebenen Tool, dem QGIS-Plugin von @Alexandre und dem Namen des Algorithmus (vierfarbige Karte) von @Jens erstellt.

Hier ist mein Code für Interessenten (für ArcGIS, aber der zweite Teil könnte auch in QGIS verwendet werden).

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)

Beachten Sie, dass der Algorithmus nicht garantiert, dass nur 4 Farben verwendet werden: obwohl nachgewiesen wurde, dass die Lösung existiert, ist die "rohe Kraft" erforderlich, um dies zu erreichen. In meinem Fall habe ich 7 Farben, was klein genug ist. Das Skript könnte eine zusätzliche Schleife haben, bis die Lösung gefunden ist, aber ich muss es für Hunderte von Karten und 7 Farben tun, ist OK.

radouxju
quelle
2
Das ist großartig - vielen Dank für das Teilen. Ich bemerkte in ArcGIS 10.2 die Feldnamen auf der PolygonNeighbors Ausgabetabelle geändert haben leicht - die Felder jetzt genannt werden src_OBJECT und nbr_OBJECT
Stephen Blei
Ist dieses Skript optimal, dh stellt es sicher, dass ein Minimum an Farben verwendet wird?
Unter dem Radar
1
Soweit ich verstanden habe, ist rohe Kraft erforderlich. Wie in meinem Post erwähnt, musst du es mehrmals ausführen, um die 4 Farben zu erreichen.
Radouxju
Funktioniert immer noch super! Möglicherweise hängen die Feldnamen src_ * und nbr_ * vom Eingabetyp ab. Ich habe es jetzt mit einer Geodatabase-fc-Eingabe und Desktop 10.5 ausgeführt. Die Namen lauten src_OBJECTID und nbr_OBJECTID. Das Skript könnte angepasst werden, um die Felder aufzulisten, die mit src und nbr beginnen, sodass der Eingabetyp (oder die Version von ArcGIS) keine Rolle spielt.
BERA
3

Wenn Sie QGIS verwenden, brauchen Sie meines Erachtens das Coloring a map-Plugin .

Leider ist das Plugin nur für die QGIS 1.8-Version verfügbar, aber Sie können es jederzeit herunterladen und sehen, wie der Code funktioniert!

Alexandre Neto
quelle
3

Dies ist eine Anpassung von @ radouxjus Antwort in eine Funktion. Es wird ein Farbfeld zum Eingabe-Feature-Layer hinzugefügt und berechnet. Es sollte unabhängig von den Feldnamenendungen von PolygonNeighbors funktionieren (sie scheinen für verschiedene Benutzer / Eingaben / arcgis-Versionen unterschiedlich zu sein (?))

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

Bildbeschreibung hier eingeben

BERA
quelle