Selecione e copie recursos no ArcMap usando a ferramenta de suplemento Python

8

Estou tentando adicionar uma ferramenta a um toobar de suplemento para selecionar recursos de uma classe de recurso existente e copiá-los para outra classe de recurso. Preciso de duas ferramentas, uma para um ponto e outra para um retângulo. As ferramentas de suplemento lidam apenas com retângulos, então estou tentando gerar a coordenada do ponto fora do evento onMouseDown e simplesmente usar o feedback X e Y que recebo. O problema é que não consigo passar essas coordenadas para algo útil para extrair os recursos. Eu tentei usar extensões de ambiente e, em seguida, executar um CopyFeatures simples, mas isso não está funcionando, pois copia todo o fc e parece não respeitar as configurações de ambiente definidas.

Posso passar coordenadas para a ferramenta Selecionar por local de alguma forma ou existe outra maneira de passar coordenadas para algo a ser extraído nessa extensão?

Isto é o que eu tenho agora:

import arcpy
import pythonaddins
arcpy.overWriteOutput = True

# Replace this with the SDE layer once it's available.
global ELAtemplate, fc
ELAtemplate = r'C:\Data\nsw_map_units.shp'
fc = ""

class DefineUnitsbyPoint(object):
    """Implementation for DefineUnitsbyPoint.tool (Tool)"""
    def __init__(self):
        self.enabled = True
        self.shape = "Rectangle" # Use onMouseDown to get initial extent of the rectangle.
    def onMouseDownMap(self, x, y, button, shift):
        # fc can be assigned from a combo box selection in another class
        global ELAtemplate, fc
        if fc == "":
            pythonaddins.MessageBox('Choose a layer to select from.', 'Choose a Layer', 0)
        else:
            mxd = arcpy.mapping.MapDocument("CURRENT")
            pointGeom = arcpy.PointGeometry(arcpy.Point(x,y), mxd.activeDataFrame.spatialReference)
            arcpy.SelectLayerByLocation_management(ELAtemplate, "INTERSECT", pointGeom, "", "ADD_TO_SELECTION")
            arcpy.CopyFeatures(ELAtemplate, fc)
MierMoto
fonte
1
Poste o código completo, não apenas um trecho. Além disso, para formatar facilmente o código corretamente, selecione-o no editor do corpo da pergunta e pressione Ctrl-K.
blah238
Onde está fcdefinido? Não está definido para nada além de uma sequência vazia neste código. Além disso, a entrada SelectLayerByLocationdeve ser uma referência a um objeto Camada ou o nome de uma camada de feição no documento de mapa atual. ELAtemplateé uma string apontando para um shapefile.
blah238
1
fcé definido a partir de uma seleção de caixa de combinação. Então, eu fiz isso global. ELAtemplateé um shapefile aqui, mas tentei executá-lo na janela do Python como uma camada, shapefile ou arrastada do sumário e nenhum deles funciona.
MierMoto
Na janela Python (ArcMap), usei o seguinte, depois de criar a geometria em pointGeom: de arcpy.MakeFeatureLayer_management("nsw_map_units","unit_layer")onde nsw_map_unitsvem o sumário. Eu então uso isso para executar arcpy.SelectLayerByLocation_management('unit_layer',"INTERSECT",pointGeom,"#","ADD_TO_SELECTION"), mas não tenho seleção. Eu até tentei criar fisicamente uma camada de pontos.
MierMoto
Não sei por que isso não funcionaria, a menos pointGeomque não cruze nada unit_layer. Talvez você precise apenas atualizar a exibição?
blah238

Respostas:

4

Você provavelmente desejará usar, em onMouseDownMapvez de onMouseDownretornar a localização nas coordenadas do mapa, não nas coordenadas da janela.

Além disso, certifique-se de passar um SpatialReferenceobjeto válido para o PointGeometryconstrutor, caso contrário, provavelmente não funcionará. No exemplo abaixo, uso a referência espacial do quadro de dados ativo.

Por fim, convém especificar um search_distanceno seu, SelectLayerByLocationpara que os recursos de ponto e linha possam ser selecionados sem clicar exatamente neles. No ArcObjects, você normalmente usaria a tolerância de seleção do ArcMap em pixels e expandiria o envelope do seu ponto por esse valor nas coordenadas do mapa. Não consegui encontrar uma maneira de acessar a configuração de tolerância de seleção do ArcMap no arcpy, mas se você quiser usar o padrão de 3 pixels (ou passar por conta própria), poderá passar a saída da função nesta resposta como um search_distance( em polegadas) para SelectLayerByLocation.

def onMouseDownMap(self, x, y, button, shift):
    mxd = arcpy.mapping.MapDocument("CURRENT")
    pointGeom = arcpy.PointGeometry(arcpy.Point(x, y), mxd.activeDataFrame.spatialReference)
    searchdistance = getSearchDistanceInches(mxd.activeDataFrame.scale)
    lyr = arcpy.mapping.ListLayers(mxd)[0] # assumes you want to select features from 1st layer in TOC
    arcpy.SelectLayerByLocation_management(lyr, "INTERSECT", pointGeom, "%d INCHES" % searchdistance)
    arcpy.RefreshActiveView()
blah238
fonte
Eu fiz uma pergunta sobre o problema de tolerância de seleção que encontrei ao formular esta resposta, espero que isso seja algo que possa ser feito sem o ArcObjects, mas tenho minhas dúvidas: Como armazenar um ponto em um suplemento Python pela tolerância de seleção do ArcMap?
blah238
Foi adicionada uma solução parcial para o problema de tolerância de seleção.
precisa saber é o seguinte
Felicidades blah238 pela ajuda. Eu acho que estou quase lá. Não pensei em criar geometria. Devo admitir que ainda estou entrando no módulo de mapeamento, pois tenho trabalhado com a 9.3.1 até agora. Eu entendi tudo, exceto o SelectByLocation. Apenas não seleciona e acho que é o código que está fazendo com que meu suplemento não exiba seus ícones (indicando código incorreto). Não estou usando uma distância de pesquisa, pois é um cruzamento. Estou curioso para saber por que você usou uma distância de pesquisa. Estou usando arcpy.SelectLayerByLocation_management ("unit_layer", "INTERSECT", pointGeom ,, "ADD_TO_SELECTION")
MierMoto 13/02/2013
Isto é o que estou usando para o select: ("unit_layer", "INTERSECT", pointGeom, "", "ADD_‌ TO_SELECTION") Não sei por que não está selecionando nada. Eu verifiquei as propriedades do objeto de ponto para ter certeza de que ele tem as coordenadas do corpo e a referência espacial e a primeira entrada é uma camada de recurso.
MierMoto 13/02/2013
Não use comentários para postar código. Edite sua pergunta para incluir seu código atual.
blah238
1

Suponho que você esteja usando as técnicas descritas em Resposta a É possível obter as coordenadas de um ponto clicado pelo usuário em um MXD atual com o ArcGIS 10.0 ArcPy? hoje cedo ou algo semelhante.

Depois de criar sua geometria de ponto ou polígono (retângulo) usando algo como o código abaixo, você poderá usá-lo como recursos selecionados para Selecionar camada por local.

pt=arcpy.PointGeometry(arcpy.Point(x,y))

A partir daí, os Recursos de cópia devem obter os recursos que você procura.

PolyGeo
fonte
Felicidades @PolyGeo Essa é a parte em que eu não pensei e está funcionando, mas agora o script está falhando na seleção. Eu usei a camada do sumário ou como uma camada de recurso, mas sem sorte. Estou usando INTERSECT com "#" como a distância de pesquisa e ADD_TO_SELECTION. Apenas não está selecionando nada. Estou executando-o na janela do Python sem alegria, mas funciona a partir da Caixa de Ferramentas.
MierMoto