Minimizar o número de páginas dinâmicas para mapear pontos dispersos usando o ArcGIS Desktop?

10

De tempos em tempos eu tenho que produzir um livro de mapas para mostrar pontos de interesse. Primeiro passo para criar páginas, usando malha regular:

insira a descrição da imagem aqui

Não gosto da solução porque: a) há algumas páginas com pontos únicos (por exemplo, página 25) na borda eb) muitas páginas.

É fácil corrigir o primeiro problema usando o código, - mova o retângulo da extensão da página para o centro da extensão dos pontos relevantes:

insira a descrição da imagem aqui

Ainda não gosto, parece muito lotado porque o número de páginas permanece o mesmo. Lembre-se, todos eles acabam sendo páginas em papel A3 reais em várias cópias do relatório!

Então, eu criei um código que reduz o número de páginas. Neste exemplo, de 45 a 34.

insira a descrição da imagem aqui

Não tenho certeza se esse é o melhor resultado que pode ser alcançado,

Qual é a melhor estratégia (pseudo-código, publicação, biblioteca Python) para embaralhar os pontos, a fim de minimizar o número de retângulos de determinado tamanho e capturar todos os pontos? Certamente, alguém o descobriu na teoria dos jogos, arte militar ou indústria pesqueira

Esta é a atualização para a pergunta original:

Isso mostra a extensão real e o tamanho da página necessários:

insira a descrição da imagem aqui

Zoom mais próximo mostrando 10 de 164 páginas:

insira a descrição da imagem aqui

Classe de recurso de ponto de amostra

O tamanho do retângulo pode mudar assim que permanecer dentro dos limites, ou seja, menor é bom.

FelixIP
fonte
2
Na minha opinião, a malha regular é a melhor opção. Os leitores de mapas estão esperando algo assim porque estão acostumados. As outras opções estão lotadas e, na minha opinião, confusas. Certamente existem algoritmos de otimização que farão o que você deseja, mas não acho que seu público os aprecie. +1, porque eu aprecio o que você está tentando fazer. Finalmente, uma maneira de reduzir o número de páginas é alterar a escala.
Fezter
Eu concordo principalmente com Fezter. Há casos em que um livro de mapas não contínuo tem seu lugar e eu estou interessado em ver respostas (até mesmo seu código atual, se você deseja compartilhar). Por exemplo, um livro de trilhas em que você deseja cada trilha em seu próprio mapa e não se preocupa em mostrar as outras (embora você ainda possa querer um mapa único de menor escala mostrando todas elas em posição relativa). Basta olhar para suas imagens de exemplo Eu acho que neste caso você iria querer uma cobertura contínua entre as páginas, mesmo que isso signifique extras, a menos que os pontos têm uma propriedade agrupamento inerente.
Chris W
@Fezter, malha regular funciona quando o tamanho da página é comparável à extensão total, tanto isso e mudança de escala não é o caso aqui
FelixIP
1
@ MichaelMiles-Stimson, o que eu fiz usando o Avenue é factível em Python. Antigo usado porque em jogos de geometria o antigo ainda é superior. Escolha o ponto, encontre o vizinho mais próximo de Manhattan, crie multipontos, obtenha extensão. Saia se estiver em extensão. Removido agrupado da lista original, continue com o restante. Eu pensei que a ordem de classificação era importante, tentei mudar. Muito pouca diferença ...
FelixIP
1
Sim, é possível em python com um esforço significativo. Ao lidar com geometrias, prefiro ArcObjects em C #. Como Chris disse, eles já parecem bastante mínimos, por que não ficar com o que você tem e chamar de pronto?
22615 Michael Stimson

Respostas:

4

Esta não é a resposta, eu apenas pensei em postar uma solução Python para quem se interessasse:

# ---------------------------------------------------------------------------
# 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()

aplicou-o recentemente para o planejamento de pesquisas:

insira a descrição da imagem aqui

ATUALIZAR:

Parece que, para alguns padrões, lidar primeiro com pontos "perdidos" é o caminho a percorrer. Eu usei a casca 'casco convexo' para identificá-los, ideia de whuber, não consigo encontrar post, desculpe.

insira a descrição da imagem aqui

FelixIP
fonte
Não é esta a postagem de @whuber que você estava procurando? gis.stackexchange.com/a/161855/115
PolyGeo
Sim, ele é. Eu costumava classificar pontos antes do início da "caça". Vou atualizar minha própria resposta amanhã. Não é fácil, sem área de trabalho
FelixIP
2

Parece uma versão geométrica do problema de cobertura máxima, que está intimamente relacionada ao problema de cobertura de conjunto , e esses dois são NP-Complete.

Então, para resolvê-lo, pode-se usar aproximação. Eu tentaria o seguinte algoritmo e parece funcionar perfeitamente. Embora, devido à complexidade do problema, não possamos encontrar a melhor resposta.

  1. O ponto Foreach gera N = 10 retângulos em distâncias aleatórias; apenas para garantir que o retângulo cubra o ponto (cada retângulo possui pelo menos um ponto e pertence a pelo menos um retângulo)
  2. Repita até que todos os pontos estejam cobertos: obtenha um retângulo cobrindo o número máximo de pontos descobertos. Marque os pontos como cobertos.

uma implementação desse algoritmo, apenas para circle, está aqui: http://jsfiddle.net/nwvao72r/3/

Farid Cheraghi
fonte
1
Você pode estar interessado em gis.stackexchange.com/q/227344/115 se ainda não o viu.
PolyGeo