Creating multiple points with mouse click

1706
13
08-23-2017 01:56 AM
PaulinaR
New Contributor

Hi,

I am quite a beginner with Python, thus I will be grateful for your help .  I want to create multiple points on my map. I managed to do that but unfortunately my attribute table is not updating (it is always only one row even I added multiple points). Could you take a look at my code at tell me where is the problem? For any help thank you so much!

class Obstacle(object):
    """Implementation for new_addin.tool (Tool)"""
    def __init__(self):
        self.enabled = True
        self.shape = "circle" # Can set to "Line", "Circle" or "Rectangle" for interactive shape drawing and to activate the onLine/Polygon/Circle event sinks.
    def onMouseDown(self, x, y, button, shift):
        pass
    def onMouseDownMap(self, x, y, button, shift):
        #workspace = r"\\\\abc\\home\\xxx\\Documents\\ArcGIS\\Default.gdb"  
        #adding points to the map
        mxd = arcpy.mapping.MapDocument ("CURRENT")
        sr = mxd.activeDataFrame.spatialReference
        pntFc = r"\\abc\home\xxx\Documents\ArcGIS\treepoints"
        pt = arcpy.Point()
        pt.X = float(x)
        pt.Y = float(y)
        ptGeoms = [arcpy.Geometry ("POINT", pt, sr)]
        if not arcpy.Exists (pntFc):
            arcpy.CopyFeatures_management(ptGeoms, pntFc)
        else:
            with arcpy.da.InsertCursor (pntFc, "SHAPE@") as iCurs:
                iCurs.insertRow (ptGeoms)
            arcpy.RefreshActiveView ()

Best,

Paulina

0 Kudos
13 Replies
DanPatterson_Retired
MVP Emeritus

just by looking at your line 22, it appears to add all the geometry objects all at once, effectively creating a multipoint shape.  Perhaps you want to cycle through those points individually rather than all at once (ie you need to use insertrow with each point rather than the collected geometry

0 Kudos
PaulinaR
New Contributor

Yes, indeed. I would like to "cycle through those points individually" . Could you give me some example how to do that?

0 Kudos
DanPatterson_Retired
MVP Emeritus
with arcpy.da.InsertCursor (pntFc, "SHAPE@") as iCurs:
    for pnt in ptGeoms:
        iCurs.insertRow (pt)

guessing wildly

0 Kudos
LukeWebb
Occasional Contributor III

Im interested too learn how you capture multiple points at a time with this code?

onMouseDown will return 1 event per click with an xy, which should then run your code snippet and insert the geometry.

How does ptGeoms get populated with more than a single point?

UNLESS you mean when you use the tool multiple times

  • The tool may crash second time round due to locking or something, try running it with the 'python' window open inside ArcGIS as you click points, which will show if any crashes happen.
  • whilst looking at the attribute table - the table wont refresh by itself, you need to close it and reopen it to see the changes, or see this thread for some other tips:

Refreshing open attribute table in ArcMap using ArcPy rather than ArcObjects? - Geographic Informati... 

0 Kudos
PaulinaR
New Contributor

Yes, you are right. I am using the add-in and I press the 'point location"button every time I want to locate it. I tried to use RefreshActiveView but unfortunately I do not get the rows. My goal is to locate the trees on map. Each tree must have lat and long in the attribute table. Hope that you can help me to point where I am making mistake in the code. Thank you so much for previous tips!

def onMouseDownMap(self, x, y, button, shift):
        #adding points to the map
        mxd = arcpy.mapping.MapDocument ("CURRENT")
        sr = mxd.activeDataFrame.spatialReference
        pntFc = r"\\abc\home\xxx\Documents\ArcGIS\treepoints"
        pt = arcpy.Point(x,y)
        x = float(x)
        y = float(y)
        ptGeoms = [arcpy.Geometry ("POINT", pt, sr)]
        if not arcpy.Exists (pntFc):
            arcpy.CopyFeatures_management(ptGeoms, pntFc)
        else:
            with arcpy.da.InsertCursor (pntFc, ["TreeId", "SHAPE@XY"]) as iCurs: #create insert cursor
            #insert row
                for pt in ptGeoms:
                    row=iCurs.insertRow()
                    row.setValue("Lat", float(x))
                    row.setValue("Long", float(y))
                    iCurs.insertRow(row)
            arcpy.RefreshActiveView()
        print "Complete"
0 Kudos
LukeWebb
Occasional Contributor III

1) Did you try closing and reopening the table to see if the rows are there now?
(It wont refresh even with .refreshActiveView()  .... see the thread I linked.)

2) Did you try having the python window open to see any crashes?

Its not a problem with your script....the cursor will never have multiple rows as theres no way for it to do that 

for pt in ptGeoms:

Will always only have 1 geometry...as the event runs when you click the mouse and gives 1 point to the script...

Im pretty sure its all working perfect, your just not seeing the updates inside the table.

0 Kudos
PaulinaR
New Contributor

Hi! Thank you for tips. 1) Yes I try and 2) Yes, I have python window open to see any crashes. The problem is that I have an existing shapefile with attribute table with trees and I would like to update it with new rows. When I am clicking on map to place new tree all other trees are disappearing from map and table.  The fields (ID, Shape, Tree number, Lat and Long) are also not in the table. 

Is it any way I can add multiple new rows without removing others? I also followed the steps from link you provided and I don't see the updated in the table.

Thanks a lot for help!

0 Kudos
LukeWebb
Occasional Contributor III

EDIT - It looks like you are mixing cursor syntax between the new .da cursors, and the old Insertcursors.

simple fix attached below using old style cursors I am familiar with:

def onMouseDownMap(self, x, y, button, shift):
    #adding points to the map
    mxd = arcpy.mapping.MapDocument ("CURRENT")
    sr = mxd.activeDataFrame.spatialReference
    pntFc = r"\\abc\home\xxx\Documents\ArcGIS\treepoints"
    pt = arcpy.Point(x,y)
    x = float
    y = float(y)
    ptGeom = [arcpy.Geometry ("POINT", pt, sr)]
    if not arcpy.Exists (pntFc):
        arcpy.CopyFeatures_management(ptGeom, pntFc)
    else:
        icursor = arcpy.InsertCursor(pntFc)
        row = icursor.newRow()
        row.setValue("Lat", float(x))
        row.setValue("Long", float(y))
        row.setValue('Shape', ptGeom)

        icursor.insertRow(row)

        arcpy.RefreshActiveView()
    print "Complete"
0 Kudos
PaulinaR
New Contributor

Thanks a lot Luke for your help! Unfortunately,after using the code you provided, the result is the same as earlier

0 Kudos