使用ArcGIS Desktop将动态页面的数量减至最少以映射散点?


10

我有时会制作地图册以显示兴趣点。使用常规网格创建页面的第一步:

在此处输入图片说明

我不喜欢该解决方案,因为a)有些页面上的单点(例如第25页)位于边缘,并且b)太多的页面。

第一个问题很容易使用代码来解决,-将页面范围的矩形移动到相关点范围的中心:

在此处输入图片说明

我仍然不喜欢它,因为页面数保持不变,所以看起来非常拥挤。请记住,它们最终都是多份报告!的实际A3纸页。

因此,我编写了减少页数的代码。在此示例中,从45到34。

在此处输入图片说明

我不确定这是否可以达到最佳结果,

什么是最好的策略(伪代码,出版物,Python库),请通过点排序以最小化给定大小的矩形以捕获所有点的数量?当然,有人在游戏理论,军事艺术或捕鱼业中发现了它

这是原始问题的更新:

这显示了所需的实际范围和页面大小:

在此处输入图片说明

放大显示164页中的10页:

在此处输入图片说明

采样点要素类

矩形大小只要保持在限制范围内即可更改,即可以较小。


2
在我看来,常规网格是最佳选择。地图读者期待这样的事情,因为他们已经习惯了。我认为其他选择比较拥挤,令人困惑。当然,有优化的算法可以满足您的需求,但是我认为您的听众不会欣赏它们。但是+1是因为我感谢您正在尝试做的事情。最后,减少页数的一种方法是更改​​缩放比例。
Fezter

我大都同意Fezter。在某些情况下,非连续的地图册会占据一席之地,我很想知道答案(即使您要共享也可以查看当前代码)。例如,一本足迹书,您希望每个足迹都在其自己的地图上并且不关心显示其他足迹(尽管您可能仍希望使用较小比例的单个地图,以相对位置显示所有足迹)。只是看着你的示例图像,我认为在这种情况下,你希望页面之间的连续覆盖,即使这意味着演员,除非该点具有内在的分组特性。
克里斯·W

@Fezter,当页面大小与总范围相当时,常规网格有效,此处和比例更改都不是这种情况
FelixIP

1
@ MichaelMiles-Stimson,我使用Avenue完成的操作在Python中是可行的。之所以使用前者,是因为在几何游戏中前者仍然优越。选择点,找到最近的曼哈顿距离邻居,创建多点,获取范围。如果超出范围则退出。已从原始列表中删除分组,其余部分继续进行。我认为排序顺序很重要,因此尝试更改。差别不大...
FelixIP

1
是的,它在Python中花费了大量精力才是可行的。在处理几何时,我更喜欢C#中的ArcObjects。正如克里斯所说,他们看上去已经非常微不足道了,为什么不坚持自己所拥有的并称之为完成。
Michael Stimson

Answers:


4

这不是答案,我只是想为那些有兴趣的人发布Python解决方案:

# ---------------------------------------------------------------------------
# PAGE MAKER
# 
# ---------------------------------------------------------------------------
# Import arcpy module
import arcpy, traceback, os, sys
from arcpy import env

width=650
height=500

try:
    def showPyMessage():
            arcpy.AddMessage(str(time.ctime()) + " - " + message)
    mxd = arcpy.mapping.MapDocument("CURRENT")
    points = arcpy.mapping.ListLayers(mxd,"points")[0]
    pgons = arcpy.mapping.ListLayers(mxd,"pages")[0]

    g=arcpy.Geometry()
    geometryList=arcpy.CopyFeatures_management(points,g)
    geometryList=[p.firstPoint for p in geometryList]
    curT = arcpy.da.InsertCursor(pgons,"SHAPE@")
    while True:
        nPoints=len(geometryList)
        small=[geometryList.pop(0)]
        for p in geometryList:
            small.append(p)
            mPoint=arcpy.Multipoint(arcpy.Array(small))
            ext=mPoint.extent
            cHeight=ext.height
            cWidth=ext.width
            if cHeight>height or cWidth>width:
                small.remove(p)
        mPoint=arcpy.Multipoint(arcpy.Array(small))
        ext=mPoint.extent
        xC=(ext.XMin+ext.XMax)/2
        yC=(ext.YMin+ext.YMax)/2
        LL=arcpy.Point (xC-width/2,yC-height/2)
        UL=arcpy.Point (xC-width/2,yC+height/2)
        UR=arcpy.Point (xC+width/2,yC+height/2)
        LR=arcpy.Point (xC+width/2,yC-height/2)
        pgon=arcpy.Polygon(arcpy.Array([LL,UL,UR,LR]))
        curT.insertRow((pgon,))
        short=filter(lambda x: x not in small,geometryList)
        arcpy.AddMessage('Grabbed %i points, %i to go' %(len(small),len(short)))
        if len(short)==0: break
        geometryList=short[:]
    del mxd
except:
    message = "\n*** PYTHON ERRORS *** "; showPyMessage()
    message = "Python Traceback Info: " + traceback.format_tb(sys.exc_info()[2])[0]; showPyMessage()
    message = "Python Error Info: " +  str(sys.exc_type)+ ": " + str(sys.exc_value) + "\n"; showPyMessage()

最近将其应用于调查计划:

在此处输入图片说明

更新:

对于某些处理“杂散”点的模式而言,似乎首先要走的路。我用过“凸包”果皮来识别它们,不好意思,找不到帖子,对不起。

在此处输入图片说明


这是您正在寻找的@whuber的帖子吗? gis.stackexchange.com/a/161855/115
PolyGeo

是的。我曾经在“狩猎”开始之前对点进行排序。我明天将更新我自己的答案。没有台式机并不容易
FelixIP'2

2

这看起来像是“ 最大覆盖率问题”的几何版本,它与“ 设置覆盖率问题”密切相关,并且这两个是NP-完全。

因此,要解决该问题,可以使用近似值。我会尝试以下算法,它似乎可以正常工作。尽管由于问题的复杂性,我们找不到最佳答案。

  1. Foreach点以随机距离生成N = 10个矩形;只是要确保矩形覆盖该点(每个矩形至少有一个点属于该点,而每个点至少属于一个矩形)
  2. 重复直到所有点都被覆盖:获得覆盖最大未覆盖点数的矩形。将点标记为已覆盖。

仅适用于圆形的此算法的实现位于:http : //jsfiddle.net/nwvao72r/3/


1
如果您没有看到它,可能会对gis.stackexchange.com/q/227344/115感兴趣。
PolyGeo
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.