Come applicare il teorema dei quattro colori in una mappa poligonale in ArcGIS / ArcToolBox automaticamente?


19

Devo applicare il teorema dei quattro colori in una forma poligonale in modo da non dover scegliere manualmente ciascun colore da inserire in ciascuna regione. Vorrei sapere se ci sono estensioni, plug-in, script o basi di dati che possono essere usati con ArcGIS e ArcToolBox per farlo matematicamente o programmaticamente, quindi potrei usarlo per ora su ogni mappa che vengo a creare.

inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine inserisci qui la descrizione dell'immagine


1
Vorrei anche sapere se esiste questa funzionalità in altri sistemi diversi da ArcGIS, come QuantumGIS ...
Please_Dont_Bully_Me_SO_Lords

2
Ho pubblicato una soluzione non ottimale su GIS (con Rcodice funzionante ) e una soluzione ottimale (che utilizzerà tre o anche due colori se si può trovare che funzioni) su Mathematica . Quella soluzione è ricorsiva; la risposta al mio post offre una soluzione di programmazione lineare. Il collettore GIS ha da tempo incorporato un algoritmo a cinque colori. (Quattro colori è difficile da fare; cinque colori è relativamente semplice da ottenere.)
whuber

Se non hai ancora un "codice" il mio consiglio ArcGIS per desktop sarebbe di iniziare con lo strumento Poligoni vicini per ottenere una tabella che elenchi tutti i vicini di ciascun poligono.
PolyGeo

@PolyGeo: grazie per gli strumenti (non lo sapevo) ma non ho potuto usarlo per risolvere il mio problema
radouxju

Risposte:


12

Prima di tutto, grazie per tutte le risposte e i commenti. Sfortunatamente, gli strumenti esistenti non erano completamente compatibili con le ultime versioni di QGIS e ArcGIS. Pertanto ho creato la mia soluzione utilizzando lo strumento indicato da @polygeo, il plug-in QGIS di @Alexandre e il nome dell'algoritmo (mappa a quattro colori) di @Jens.

Ecco il mio codice per chi è interessato (per ArcGIS ma la seconda parte potrebbe essere usata anche in 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)

Si noti che l'algoritmo non garantisce che vengano utilizzati solo 4 colori: sebbene sia stata dimostrata l'esistenza della soluzione, la "forza bruta" è necessaria per raggiungerla. Nel mio caso, ho ottenuto 7 colori che sono abbastanza piccoli. Lo script potrebbe avere un ciclo aggiuntivo fino a quando non viene trovata la soluzione, ma ho bisogno di farlo per centinaia di mappe e 7 colori è OK.


2
Questo è geniale, grazie mille per averlo condiviso. Ho notato ad ArcGIS 10.2 che i nomi dei campi nella tabella di output di PolygonNeighbors sono leggermente cambiati - i campi sono ora chiamati src_OBJECT e nbr_OBJECT
Stephen Lead

Questo script è ottimale, ovvero garantisce che venga utilizzato un minimo di colori?
Sotto il radar,

1
Per quanto ho capito, è necessaria la forza grezza. Come accennato nel mio post, è necessario eseguirlo più volte per avere la possibilità di raggiungere i 4 colori.
Radouxju,

Funziona ancora alla grande! Forse i nomi dei campi src_ * e nbr_ * dipendono dal tipo di input. L'ho eseguito ora con un input di geodatabase fc e Desktop 10.5 e sono stati chiamati src_OBJECTID e nbr_OBJECTID. Lo script potrebbe essere modificato per elencare i campi che iniziano con src e nbr, quindi il tipo di input (o versione di ArcGIS) non ha importanza.
BERA,


3

Se stai usando QGIS, credo che ciò di cui hai bisogno sia il plugin Colorare una mappa .

Sfortunatamente, il plug-in è disponibile solo per la versione QGIS 1.8, ma puoi sempre scaricare e vedere come funziona il codice!


3

Questo è un adattamento della risposta di @ radouxju in una funzione. Aggiungerà un campo colore al livello della funzione di input e lo calcolerà. Dovrebbe funzionare indipendentemente dalla fine del nome del campo di PolygonNeighbors (sembrano diversi per utenti / input / versioni arcgis diversi (?))

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

inserisci qui la descrizione dell'immagine

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.