¿Cómo aplicar el teorema de los cuatro colores en un mapa de polígonos en ArcGIS / ArcToolBox automáticamente?

18

Necesito aplicar el teorema de cuatro colores en una forma poligonal de una manera que no necesito elegir manualmente Cada color para poner en cada región. Deseo saber si hay alguna extensión, plug-in, script o base de datos que pueda usarse con ArcGIS y ArcToolBox para hacerlo matemáticamente o programáticamente, por lo que podría usarlo en cada mapa que venga a crear.

    
pregunta Please_Dont_Bully_Me_SO_Lords 10.03.2013 - 18:43

4 respuestas

11

En primer lugar, gracias por todas las respuestas y comentarios. Desafortunadamente, las herramientas existentes no eran totalmente compatibles con las últimas versiones de QGIS y ArcGIS. Por lo tanto, hice mi propia solución utilizando la herramienta indicada por @polygeo, el complemento QGIS de @Alexandre y el nombre del algoritmo (mapa de cuatro colores) de @Jens.

Aquí está mi código para los interesados (para ArcGIS, pero la segunda parte también se puede usar en 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", ("[email protected]","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)

Tenga en cuenta que el algoritmo no garantiza que solo se utilicen 4 colores: aunque se ha demostrado que la solución existe, la "fuerza bruta" es necesaria para lograrlo. En mi caso, tengo 7 colores lo suficientemente pequeños. La secuencia de comandos podría tener un bucle adicional hasta que se encuentre la solución, pero debo hacerlo para cientos de mapas y 7 colores está bien.

    
respondido por el radouxju 10.01.2014 - 22:04
4

Hay un VB6 muestra de desarrollador y herramienta de geoprocesamiento ArcGIS 9.x pero de los comentarios sobre esto Idea de ArcGIS no funcionan a partir de la 10.0+.

Tal vez alguien estaría interesado en portarlo.

Una solución QGIS llamada TopoColour se encuentra en los comentarios de esta pregunta relacionada: polígonos de color para que cada uno sea distinto de sus vecinos

    
respondido por el blah238 10.03.2013 - 19:22
3

Si está utilizando QGIS, creo que lo que necesita es el Colorear un complemento de mapa .

Desafortunadamente, el complemento solo está disponible para la versión QGIS 1.8, ¡pero siempre puedes descargar y ver cómo funciona el código!

    
respondido por el Alexandre Neto 08.01.2014 - 11:03
3

Esta es una adaptación de la respuesta de @ radouxju en una función. Agregará un campo de color a la capa de entidad de entrada y calculará. Debería funcionar independientemente de los finales de los nombres de campo de PolygonNeighbors (parecen ser diferentes para diferentes usuarios / entradas / versiones de 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, ('[email protected]','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')

    
respondido por el BERA 31.01.2018 - 13:07

Lea otras preguntas en las etiquetas