Wählen Sie Features in ArcMap mit dem Python-Add-In-Tool aus und kopieren Sie sie

8

Ich versuche, einer Add-In-Symbolleiste ein Tool hinzuzufügen, um Features aus einer vorhandenen Feature-Class auszuwählen und in eine andere Feature-Class zu kopieren. Ich brauche zwei Werkzeuge, eines für einen Punkt und eines für ein Rechteck. Add-In-Tools verarbeiten nur Rechtecke. Daher versuche ich, die Punktkoordinate aus dem onMouseDown-Ereignis zu generieren und einfach das X- und Y-Feedback zu verwenden, das ich erhalte. Das Problem ist, dass ich diese Koordinaten scheinbar nicht an irgendetwas Nützliches übergeben kann, um die Features zu extrahieren. Ich habe versucht, Umgebungsbereiche zu verwenden und dann einfache CopyFeatures auszuführen, aber das funktioniert nicht, da es den gesamten fc kopiert und die von mir festgelegten Umgebungseinstellungen nicht zu berücksichtigen scheint.

Kann ich Koordinaten irgendwie an das Werkzeug Nach Standort auswählen übergeben, oder gibt es eine andere Möglichkeit, Koordinaten an etwas zu übergeben, das in diesem Umfang extrahiert werden kann?

Das habe ich jetzt:

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
quelle
1
Veröffentlichen Sie den vollständigen Code, nicht nur einen Ausschnitt. Um den Code einfach korrekt zu formatieren, wählen Sie ihn im Fragenkörper-Editor aus und drücken Sie Strg-K.
blah238
Wo ist fceingestellt? In diesem Code ist nichts anderes als eine leere Zeichenfolge festgelegt. Außerdem muss die Eingabe SelectLayerByLocationein Verweis auf ein Ebenenobjekt oder der Name eines Feature-Layers im aktuellen Kartendokument sein. ELAtemplateist eine Zeichenfolge, die auf ein Shapefile zeigt.
blah238
1
fcwird aus einer Kombinationsfeldauswahl festgelegt. Also habe ich das global gemacht. ELAtemplateist hier ein Shapefile, aber ich habe versucht, dies im Python-Fenster als Ebene, Shapefile oder aus dem Inhaltsverzeichnis gezogen auszuführen, und keines davon funktioniert.
MierMoto
Im Python - Fenstern (ArcMap) Ich habe die folgende, nach dem Erstellen der Geometrie in verwendet pointGeom: arcpy.MakeFeatureLayer_management("nsw_map_units","unit_layer")wo nsw_map_unitsaus dem TOC kommt. Ich benutze das dann, um zu laufen arcpy.SelectLayerByLocation_management('unit_layer',"INTERSECT",pointGeom,"#","ADD_TO_SELECTION"), aber ich bekomme keine Auswahl. Ich habe sogar versucht, eine Punktebene physisch zu erstellen.
MierMoto
Ich weiß nicht, warum das nicht funktionieren würde, wenn pointGeomsich nichts darin überschneidet unit_layer. Vielleicht müssen Sie nur die Ansicht aktualisieren?
blah238

Antworten:

4

Sie möchten wahrscheinlich onMouseDownMapeher verwenden, als dass onMouseDowndies die Position in Kartenkoordinaten zurückgibt, nicht in Fensterkoordinaten.

Stellen Sie außerdem sicher, dass Sie ein gültiges SpatialReferenceObjekt an den PointGeometryKonstruktor übergeben, da es sonst höchstwahrscheinlich nicht funktioniert. Im folgenden Beispiel verwende ich den Raumbezug des aktiven Datenrahmens.

Zuletzt möchten Sie möglicherweise ein search_distanceauf Ihrem angeben, SelectLayerByLocationdamit Punkt- und Linien-Features ausgewählt werden können, ohne genau darauf zu klicken. In ArcObjects würden Sie normalerweise ArcMap die Verwendung Auswahl Toleranz in Pixel und Ihre Punkt des Umschlags um diesen Betrag in Kartenkoordinaten erweitern. Ich konnte in arcpy keine Möglichkeit finden, auf die Auswahltoleranzeinstellung von ArcMap zuzugreifen. Wenn Sie jedoch die Standardeinstellung von 3 Pixel verwenden möchten (oder Ihre eigenen übergeben möchten), können Sie die Ausgabe der Funktion in dieser Antwort als search_distance(übergeben) in Zoll) zu 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
quelle
Ich habe eine Frage zu dem Problem mit der Auswahltoleranz gestellt, auf das ich bei der Formulierung dieser Antwort gestoßen bin. Hoffentlich ist dies ohne ArcObjects möglich, aber ich habe meine Zweifel: Wie kann ein Punkt in einem Python-Add-In durch die Auswahltoleranz von ArcMap gepuffert werden?
blah238
Es wurde eine Teillösung für das Problem der Auswahltoleranz hinzugefügt .
blah238
Prost blah238 für die Hilfe. Ich denke ich bin fast da. Ich habe nicht daran gedacht, Geometrie zu erstellen. Ich muss zugeben, dass ich immer noch im Mapping-Modul bin, da ich bis jetzt mit 9.3.1 gearbeitet habe. Ich habe alles außer dem SelectByLocation. Es wird einfach nicht ausgewählt und ich denke, es ist der Code, der dazu führt, dass mein Add-In seine Symbole nicht anzeigt (was auf falschen Code hinweist). Ich verwende keine Suchentfernung, da es sich um eine Kreuzung handelt. Ich bin gespannt, warum Sie einen Suchabstand verwendet haben. Ich benutze arcpy.SelectLayerByLocation_management ("unit_layer", "INTERSECT", pointGeom ,, "ADD_TO_SELECTION")
MierMoto
Dies ist, was ich für die Auswahl verwende: ("unit_layer", "INTERSECT", pointGeom, "", "ADD_‌ TO_SELECTION") Ich bin mir nicht sicher, warum ich nichts auswähle. Ich habe die Eigenschaften des Punktobjekts überprüft, um sicherzustellen, dass es die richtigen Koordinaten und den räumlichen Bezug hat und die erste Eingabe eine Feature-Ebene ist.
MierMoto
Verwenden Sie keine Kommentare zum Posten der Vorwahl. Bearbeiten Sie Ihre Frage, um Ihren aktuellen Code aufzunehmen.
blah238
1

Ich gehe davon aus, dass Sie die in Antwort auf Beschriebenen Techniken verwenden. Ist es mit ArcGIS 10.0 ArcPy möglich, die Koordinaten eines vom Benutzer angeklickten Punkts in einer aktuellen MXD abzurufen? früher heute oder so ähnlich.

Sobald Sie in der Lage sind, Ihre Punkt- oder Polygongeometrie (Rechteck) mit dem folgenden Code zu erstellen, sollten Sie diese als select_features für Select Layer By Location verwenden können.

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

Von dort aus sollten Kopierfunktionen die Funktionen erhalten, nach denen Sie suchen.

PolyGeo
quelle
Cheers @PolyGeo Das ist das, woran ich nicht gedacht habe und es funktioniert, aber jetzt schlägt das Skript bei der Auswahl fehl. Ich habe die Ebene entweder aus dem Inhaltsverzeichnis oder als Feature-Ebene verwendet, aber kein Glück. Ich verwende INTERSECT mit "#" als Suchabstand und ADD_TO_SELECTION. Es geht einfach nicht darum, etwas auszuwählen. Ich starte es ohne Freude aus dem Python-Fenster, aber es funktioniert über die Toolbox.
MierMoto