Como aplicar o teorema das quatro cores em um mapa poligonal no ArcGIS / ArcToolBox automaticamente?

19

Eu preciso aplicar o teorema das quatro cores em uma forma poligonal de uma maneira que não precise escolher manualmente cada cor para colocar em cada região. Desejo saber se existe alguma extensão, plug-in, script ou banco de dados que possa ser usado com o ArcGIS e o ArcToolBox para fazê-lo matematicamente ou programaticamente, para que eu possa usá-lo agora em todos os mapas que venho criar.

insira a descrição da imagem aqui insira a descrição da imagem aqui insira a descrição da imagem aqui

Please_Dont_Bully_Me_SO_Lords
fonte
1
Eu também gostaria de saber se existe essa funcionalidade em outros que não sejam ArcGIS, como QuantumGIS sistemas ...
Please_Dont_Bully_Me_SO_Lords
2
Publiquei uma solução abaixo do ideal no GIS (com Rcódigo ativo) e uma solução ótima (que usará três ou até duas cores, se puderem funcionar) no Mathematica . Essa solução é recursiva; a resposta ao meu post fornece uma solução de programação linear. GIS Manifold há muito tempo tem um algoritmo de cinco cores construído em (Four-coloração é difícil de fazer; cinco coloração é relativamente simples de conseguir.).
whuber
Se você não possui "código até o momento", minha recomendação do ArcGIS for Desktop seria começar com a ferramenta Polygon Neighbors para obter uma tabela listando todos os vizinhos de cada polígono.
PolyGeo
@PolyGeo: obrigado pelas ferramentas (eu não sabia), mas eu não poderia usá-lo para resolver o meu problema
radouxju

Respostas:

12

Primeiro de tudo, obrigado por todas as respostas e comentários. Infelizmente, as ferramentas existentes não eram totalmente compatíveis com as versões mais recentes do QGIS e ArcGIS. Portanto, criei minha própria solução usando a ferramenta indicada por @polygeo, o plug-in QGIS de @Alexandre e o nome do algoritmo (mapa de quatro cores) de @Jens.

Aqui está o meu código para os interessados ​​(para o ArcGIS, mas a segunda parte também pode ser usada no 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)

Observe que o algoritmo não garante que apenas 4 cores sejam usadas: embora tenha sido comprovado que a solução existe, a "força bruta" é necessária para alcançá-la. No meu caso, eu tenho 7 cores que são pequenas o suficiente. O script pode ter um loop adicional até que a solução seja encontrada, mas eu preciso fazer isso por centenas de mapas e 7 cores.

radouxju
fonte
2
Isso é brilhante - muito obrigado por compartilhá-lo. Notei no ArcGIS 10.2 nomes de campo na tabela de saída PolygonNeighbors ter mudado um pouco - os campos são agora chamados src_OBJECT e nbr_OBJECT
Stephen Chumbo
Esse script é ideal, ou seja, garante que um mínimo de cores seja usado?
Abaixo do radar
1
Tanto quanto eu entendi, é necessária força bruta. Como mencionado no meu post, você deve executá-lo várias vezes para ter a chance de atingir as 4 cores.
Radouxju
Ainda funciona muito bem! Talvez os nomes dos campos src_ * e nbr_ * dependam do tipo de entrada. Eu o executei agora com uma entrada de geodatabase fc e o Desktop 10.5 e eles foram nomeados src_OBJECTID e nbr_OBJECTID. O script pode ser ajustado para listar os campos que começam com src e nbr, para que o tipo de entrada (ou versão do ArcGIS) não importe.
BERA
3

Se você estiver usando o QGIS, acredito que você precisa do plugin Colorir um mapa .

Infelizmente, o plug-in está disponível apenas para a versão QGIS 1.8, mas você sempre pode fazer o download e ver como o código funciona!

Alexandre Neto
fonte
3

Esta é uma adaptação da resposta de @ radouxju em uma função. Ele adicionará um campo de cor à camada do recurso de entrada e calculará. Ele deve funcionar independentemente das terminações de nome de campo de PolygonNeighbors (elas parecem ser diferentes para diferentes versões de usuários / entradas / 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')

insira a descrição da imagem aqui

BERA
fonte