Минимизировать количество динамических страниц для отображения рассеянных точек с помощью ArcGIS Desktop?

10

Время от времени мне приходится составлять карту, чтобы показать достопримечательности. Первый шаг для создания страниц, используя обычную сетку:

введите описание изображения здесь

Мне не нравится решение, потому что а) есть несколько страниц с одиночными точками (например, страница 25), расположенными по краю, и б) слишком много страниц.

Первую проблему легко исправить с помощью кода, - переместите прямоугольник экстента страницы в центр экстента соответствующих точек:

введите описание изображения здесь

Мне все еще не нравится это, это выглядит очень переполненным, потому что число страниц остается тем же самым. Помните, что все они в конечном итоге становятся настоящими бумажными страницами формата А3 в нескольких экземплярах отчета!

Итак, я приготовил код, который уменьшает количество страниц. В этом примере от 45 до 34.

введите описание изображения здесь

Я не уверен, что это лучший результат, который может быть достигнут,

Какова наилучшая стратегия (псевдокод, публикация, библиотека Python) для перемещения по точкам, чтобы минимизировать количество прямоугольников заданного размера для захвата всех точек? Конечно, кто-то открыл это в теории игр, военного искусства или рыбной промышленности.

Это обновление к оригинальному вопросу:

Это показывает реальный экстент и необходимый размер страницы:

введите описание изображения здесь

Увеличение масштаба изображения, показывающее 10 из 164 страниц:

введите описание изображения здесь

Класс объектов точки выборки

Размер прямоугольника может измениться, как только он останется в пределах, то есть меньше - это хорошо.

FelixIP
источник
2
На мой взгляд, регулярная сетка - лучший вариант. Читатели карт ожидают чего-то подобного, потому что они к этому привыкли. Другие варианты переполнены и, на мой взгляд, сбивают с толку. Конечно, есть оптимизирующие алгоритмы, которые будут делать то, что вы хотите, но я не думаю, что ваша аудитория их оценит. +1, хотя, потому что я ценю то, что вы пытаетесь сделать. Наконец, один из способов уменьшить количество страниц - это изменить масштаб.
Фезтер
Я в основном согласен с Фезтером. Бывают случаи, когда в книге непостоянных карт есть место, и мне будет интересно посмотреть ответы (даже ваш текущий код, если вы хотите поделиться). Например, книга следов, где вы хотите, чтобы каждый след находился на отдельной карте, и вам не нужно показывать другие (хотя вам может понадобиться карта меньшего масштаба, показывающая их все в относительном положении). Просто глядя на ваш пример изображения , которые я думаю , что в этом случае вы бы хотели непрерывный охват между страницами, даже если это означает дополнительные услуги, если очки не имеют неотъемлемое свойство группирования.
Крис Вт,
@Fezter, обычная сетка работает, когда размер страницы сопоставим по общему объему, и это, и изменение масштаба здесь не так
FelixIP
1
@ MichaelMiles-Stimson, то, что я сделал с помощью Avenue, выполнимо в Python. Используется бывший, потому что в играх с геометрией бывший все еще превосходит. Выберите точку, найдите ближайший сосед Манхэттена, создайте мультиточку, получите экстент. Выйти, если чрезмерно. Удалены сгруппированы из исходного списка, перейдите к оставшимся. Я думал, что порядок сортировки важен, пытался изменить. Очень маленькая разница ...
FelixIP
1
Да, это возможно в Python со значительными усилиями. При работе с геометрией я предпочитаю ArcObjects в C #. Как сказал Крис, они уже выглядят довольно минималистично, почему бы не придерживаться того, что у вас есть, и назвать это готовым.
Майкл Стимсон,

Ответы:

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, не могу найти пост, извините.

введите описание изображения здесь

FelixIP
источник
Это сообщение от @whuber, которое вы искали? gis.stackexchange.com/a/161855/115
PolyGeo
Да, это так. Я привык сортировать точки перед началом «охоты». Я обновлю свой ответ завтра. Нелегко без рабочего стола
FelixIP
2

Это похоже на геометрическую версию проблемы максимального покрытия, которая тесно связана с проблемой покрытия покрытия , и эти два NP-Complete.

Таким образом, чтобы решить это, можно использовать приближение. Я бы попробовал следующий алгоритм, и он, кажется, работает отлично. Хотя из-за сложности проблемы, мы не можем найти лучший ответ.

  1. В каждой точке генерируется N = 10 прямоугольников на случайных расстояниях; просто чтобы убедиться, что прямоугольник покрывает точку (каждому прямоугольнику принадлежит хотя бы одна точка, и каждая точка принадлежит хотя бы одному прямоугольнику)
  2. Повторяйте, пока все точки не будут покрыты: получите прямоугольник, покрывающий максимальное количество непокрытых точек. Отметьте точки как покрытые.

реализация этого алгоритма, только для круга, находится здесь: http://jsfiddle.net/nwvao72r/3/

Фарид Чераги
источник
1
Возможно, вас заинтересует gis.stackexchange.com/q/227344/115, если вы его еще не видели.
PolyGeo