Làm cách nào để áp dụng định lý bốn màu trong bản đồ đa giác trong ArcGIS / ArcToolBox tự động?


19

Tôi cần áp dụng định lý bốn màu theo hình đa giác theo cách mà tôi không cần phải chọn thủ công từng màu để đặt vào từng vùng. Tôi muốn biết liệu có bất kỳ tiện ích mở rộng, trình cắm, tập lệnh hoặc cơ sở dữ liệu nào có thể được sử dụng với ArcGIS và ArcToolBox để thực hiện theo cách toán học hoặc lập trình hay không, vì vậy tôi có thể sử dụng nó ngay bây giờ với mọi bản đồ tôi tạo.

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây


1
Tôi cũng muốn biết liệu có chức năng này trong các hệ thống khác ngoài ArcGIS hay không, như
QuantumGIS

2
Tôi đã đăng một giải pháp tối ưu trên GIS (với Rmã làm việc ) và một giải pháp tối ưu (sẽ sử dụng ba hoặc thậm chí hai màu nếu chúng có thể hoạt động) trên Mathematica . Giải pháp đó là đệ quy; các trả lời cho bài viết của tôi đưa ra một giải pháp quy hoạch tuyến tính. Manifold GIS từ lâu đã có một thuật toán năm màu được tích hợp. (Bốn màu rất khó thực hiện; năm màu tương đối đơn giản để đạt được.)
whuber

Nếu bạn không có "mã cho đến nay", khuyến nghị ArcGIS for Desktop của tôi sẽ bắt đầu với công cụ Hàng xóm đa giác để lấy bảng liệt kê tất cả các hàng xóm của mỗi đa giác.
PolyGeo

@PolyGeo: cảm ơn vì các công cụ (tôi không biết) nhưng tôi không thể sử dụng nó để giải quyết vấn đề của mình
radouxju

Câu trả lời:


12

Trước hết, cảm ơn tất cả các câu trả lời và ý kiến. Thật không may, các công cụ hiện có không tương thích hoàn toàn với các phiên bản mới nhất của QGIS và ArcGIS. Do đó, tôi đã thực hiện giải pháp của riêng mình bằng công cụ được chỉ định bởi @polygeo, plugin QGIS từ @Alexandre và tên của thuật toán (bản đồ bốn màu) từ @Jens.

Đây là mã của tôi cho những người quan tâm (đối với ArcGIS nhưng phần thứ hai cũng có thể được sử dụng trong 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)

Lưu ý rằng thuật toán không đảm bảo rằng chỉ có 4 màu được sử dụng: mặc dù đã được chứng minh rằng giải pháp tồn tại, "lực lượng vũ phu" là cần thiết để đạt được nó. Trong trường hợp của tôi, tôi có 7 màu đủ nhỏ. Kịch bản có thể có một vòng lặp bổ sung cho đến khi tìm thấy giải pháp, nhưng tôi cần thực hiện nó cho hàng trăm bản đồ và 7 màu là OK.


2
Điều này thật tuyệt vời - cảm ơn rất nhiều vì đã chia sẻ nó. Tôi nhận thấy tại ArcGIS 10.2, các tên trường trên bảng đầu ra PolygonNeighbor đã thay đổi một chút - các trường hiện được gọi là src_OB DỰ ÁNnbr_OB DỰ ÁN
Stephen Lead

Tập lệnh này có tối ưu không, có đảm bảo rằng sẽ sử dụng tối thiểu màu sắc không?
Bên dưới Radar

1
Theo tôi hiểu, lực lượng thô là cần thiết. Như đã đề cập trong bài viết của tôi, bạn phải chạy nó nhiều lần để có cơ hội đạt được 4 màu.
radouxju

Vẫn hoạt động tuyệt vời! Có thể tên trường src_ * và nbr_ * phụ thuộc vào loại đầu vào. Tôi đã chạy nó ngay bây giờ với đầu vào fc cơ sở dữ liệu địa lý và Máy tính để bàn 10.5 và chúng được đặt tên là src_OBJECTID và nbr_OB ProjectID. Tập lệnh có thể được điều chỉnh để liệt kê các trường bắt đầu bằng src và nbr để loại đầu vào (hoặc phiên bản ArcGIS) không thành vấn đề.
BERA


3

Nếu bạn đang sử dụng QGIS, tôi tin rằng thứ bạn cần là plugin Tô màu bản đồ .

Thật không may, plugin chỉ có sẵn cho phiên bản QGIS 1.8, nhưng bạn luôn có thể tải xuống và xem cách mã hoạt động!


3

Đây là bản chuyển thể của câu trả lời của @ radouxju thành một hàm. Nó sẽ thêm một trường màu vào lớp tính năng đầu vào và tính toán. Nó nên hoạt động bất kể kết thúc tên trường của PolygonNeighbor (chúng dường như khác nhau đối với các phiên bản người dùng / đầu vào / arcgis khác nhau (?))

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

nhập mô tả hình ảnh ở đây

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.