Seleccione y copie entidades en ArcMap usando la herramienta de complemento Python

8

Estoy tratando de agregar una herramienta a una barra de complementos para seleccionar entidades de una clase de entidad existente y copiarlas en otra clase de entidad. Necesito dos herramientas, una para un punto y otra para un rectángulo. Las herramientas de complemento solo manejan rectángulos, por lo que estoy tratando de generar la coordenada de punto del evento onMouseDown y simplemente uso los comentarios X e Y que obtengo. El problema es que parece que no puedo pasar estas coordenadas a nada útil para extraer las características. Intenté usar extensiones de entorno y luego hacer un simple CopyFeatures, pero eso no funciona, ya que copia todo el fc y no parece respetar la configuración del entorno que configuré.

¿Puedo pasar las coordenadas a la herramienta Seleccionar por ubicación de alguna manera o hay otra forma de pasar las coordenadas a algo para extraer en esa medida?

Esto es lo que tengo ahora:

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
fuente
1
Publique el código completo, no solo un fragmento. También para formatear fácilmente el código correctamente, selecciónelo en el editor del cuerpo de la pregunta y presione Ctrl-K.
blah238
¿Dónde se fcestablece? No se establece en nada más que una cadena vacía en este código. Además, la entrada SelectLayerByLocationdebe ser una referencia a un objeto de Capa o el nombre de una capa de entidades en el documento de mapa actual. ELAtemplatees una cadena que apunta a un archivo de forma.
blah238
1
fcse establece desde una selección de cuadro combinado. Así que lo hice global. ELAtemplatees un archivo de forma aquí, pero he intentado ejecutar esto en la ventana de Python como una capa, un archivo de forma o arrastrado desde el TOC y ninguno de ellos funciona.
MierMoto
En la ventana de Python (ArcMap) he usado lo siguiente, después de crear la geometría en pointGeom: de arcpy.MakeFeatureLayer_management("nsw_map_units","unit_layer")dónde nsw_map_unitsviene el TOC. Luego lo uso para correr arcpy.SelectLayerByLocation_management('unit_layer',"INTERSECT",pointGeom,"#","ADD_TO_SELECTION"), pero no obtengo ninguna selección. Incluso he intentado crear físicamente una capa de puntos.
MierMoto
No sé por qué eso no funcionaría a menos pointGeomque en realidad no se cruzara con nada unit_layer. ¿Quizás solo necesita actualizar la vista?
blah238

Respuestas:

4

Probablemente desee usar en onMouseDownMaplugar de hacerlo, onMouseDownya que esto devuelve la ubicación en las coordenadas del mapa, no en las coordenadas de la ventana.

Además, asegúrese de pasar un SpatialReferenceobjeto válido al PointGeometryconstructor, de lo contrario, lo más probable es que no funcione. En el siguiente ejemplo, uso la referencia espacial del marco de datos activo.

Por último, es posible que desee especificar un search_distanceen su SelectLayerByLocationpara que las características de punto y línea se puedan seleccionar sin hacer clic en ellas exactamente. En ArcObjects, normalmente usaría la tolerancia de selección de ArcMap en píxeles y expandiría el sobre de su punto en esa cantidad en las coordenadas del mapa. No pude encontrar una manera de acceder a la configuración de tolerancia de selección de ArcMap en arcpy, pero si desea ir con el valor predeterminado de 3 píxeles (o pasar el suyo), puede pasar la salida de la función en esta respuesta como un search_distance( en pulgadas) a 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
fuente
He hecho una pregunta sobre el problema de la tolerancia de selección que encontré al formular esta respuesta, espero que esto sea algo que se pueda hacer sin ArcObjects, pero tengo mis dudas: ¿Cómo amortiguar un punto en un complemento de Python mediante la tolerancia de selección de ArcMap?
blah238
Se agregó una solución parcial al problema de tolerancia de selección.
blah238
Saludos blah238 por la ayuda. Creo que ya casi estoy allí. No pensé en crear geometría. Debo admitir que todavía estoy en el módulo de mapeo, ya que he estado trabajando con 9.3.1 hasta ahora. Lo tengo todo abajo, excepto el SelectByLocation. Simplemente no se selecciona y creo que es el código lo que hace que mi complemento no muestre sus íconos (lo que indica un código incorrecto). No estoy usando una distancia de búsqueda, ya que es una intersección. Tengo curiosidad por saber por qué usaste una distancia de búsqueda. Estoy usando arcpy.SelectLayerByLocation_management ("unit_layer", "INTERSECT", pointGeom ,, "ADD_TO_SELECTION")
MierMoto
Esto es lo que estoy usando para la selección: ("unit_layer", "INTERSECT", pointGeom, "", "ADD_‌ TO_SELECTION") No estoy seguro de por qué no está seleccionando nada. Verifiqué las propiedades del objeto de punto para asegurarme de que tiene las coordenadas del núcleo y la referencia espacial y que la primera entrada es una capa de entidades.
MierMoto
No use comentarios para publicar el código. Edite su pregunta para incluir su código actual.
blah238
1

Supongo que está utilizando las técnicas descritas en la Respuesta a ¿Es posible obtener las coordenadas de un punto de clic del usuario en un MXD actual con ArcGIS 10.0 ArcPy? hoy temprano o algo similar.

Una vez que pueda crear su geometría de punto o polígono (rectángulo) usando algo como el código a continuación, debería poder usarlo como su select_features para Seleccionar capa por ubicación.

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

A partir de ahí, Copy Features debería obtener las características que busca.

PolyGeo
fuente
Saludos @PolyGeo Eso es lo que no pensé y está funcionando, pero ahora el guión falla en la selección. He usado la capa desde el TOC o como capa de entidades, pero no tuve suerte. Estoy usando INTERSECT con "#" como la distancia de búsqueda y ADD_TO_SELECTION. Simplemente no está seleccionando nada. Lo estoy ejecutando desde la ventana de Python sin alegría, pero funciona desde Toolbox.
MierMoto