ArcGIS / ArcToolBoxのポリゴンマップに4色の定理を自動的に適用する方法は?


19

各色を手動で選択して各領域に配置する必要がないように、4色の定理を多角形に適用する必要があります。ArcGISおよびArcToolBoxで使用して数学またはプログラムで実行できる拡張機能、プラグイン、スクリプト、またはデータベースがあるかどうかを知りたいので、今後作成するすべてのマップで使用できます。

ここに画像の説明を入力してください ここに画像の説明を入力してください ここに画像の説明を入力してください


1
また、QuantumGISなど、ArcGIS以外の他のシステムにこの機能があるかどうかも知りたいと思います...
Please_Dont_Bully_Me_SO_Lords

2
私はGISに次善のソリューション(作業Rコード付き)とMathematicaに最適なソリューション(機能することがわかった場合は3色または2色さえ使用します)を投稿しました。その解決策は再帰的です。私の投稿へ返信は、線形プログラミングソリューションを提供します。マニホールドGISには、以前から5色アルゴリズムが組み込まれていました(4色は簡単に実行できません。5色は比較的簡単に実現できます。)
whuber

「これまでのコード」がない場合、ArcGIS for Desktopの推奨事項は、Polygon Neighborsツールから開始して、各ポリゴンのすべてのネイバーをリストするテーブルを取得することです。
PolyGeo

@PolyGeo:ツールのおかげで(知りませんでした)、問題を解決するために使用できませんでした
radouxju 14年

回答:


12

まず第一に、すべての回答とコメントをありがとう。残念ながら、既存のツールはQGISおよびArcGISの最新バージョンと完全に互換性がありませんでした。したがって、@ polygeoで示されるツール、@ AlexandreのQGISプラグイン、および@Jensのアルゴリズム名(4色マップ)を使用して、独自のソリューションを作成しました。

興味のある人向けのコードを次に示します(ArcGIS向けですが、QGISでも2番目の部分を使用できます)。

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
これは素晴らしいです-それを共有してくれてありがとう。私はPolygonNeighbors出力テーブル上のフィールド名は若干変更されているのArcGIS 10.2で気づいた-フィールドは、今と呼ばれsrc_OBJECTnbr_OBJECT
スティーブン鉛

このスクリプトは最適ですか?つまり、最小限の色が使用されるようにしますか?
レーダーの下

1
私の知る限り、生の力が必要です。私の投稿で述べたように、4色に到達する機会を得るには、何度か実行する必要があります。
radouxju

それでもうまくいきます!たぶん、src_ *およびnbr_ *フィールド名は入力タイプに依存します。ジオデータベースのfc入力とDesktop 10.5を使用して実行し、src_OBJECTIDおよびnbr_OBJECTIDという名前が付けられました。スクリプトは、srcおよびnbrで始まるフィールドをリストするように調整できるため、入力タイプ(またはArcGISのバージョン)は重要ではありません。
ベラ

4

ありVB6開発者のサンプルのArcGIS 9.xのジオプロセシングツールは、この上のコメントからのArcGISアイデア彼らは10.0+で仕事をしません。

おそらく誰かがそれを移植することに興味があるでしょう。

TopoColourと呼ばれるQGISソリューションは、この関連する質問のコメントに記載されています。ポリゴンを色付けして、それぞれが隣接するものと区別されるようにします



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

ここに画像の説明を入力してください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.