0

I want to add points to a shapefile interactively using pythonaddins and display them over map. Points are added to shapefile but not to display. Please suggest how to fix this discrepancy.

class AddPoints(object):
   """Implementation for points_addin.tool1 (Tool)"""
   def __init__(self):
       self.enabled = False
       self.shape = 3

   def onMouseDownMap(self, x, y, button, shift):
       xy = (x,y)
       cursor = arcpy.da.InsertCursor(r'C:/temp/points.shp', ("SHAPE@XY"))
       cursor.insertRow([xy])

       arcpy.RefreshTOC()
       arcpy.RefreshActiveView()
  • Do they show after refresh manually or next time opening? – Michael Stimson Jun 20 '14 at 4:17
  • Wait, it worked. I restarted my machine and now it is displaying points :) – Ibe Jun 20 '14 at 4:29
  • Were there any points in there to start with? Odd things can happen with new feature class when you first add feature, it has to do with the extent starting from nothing and becoming something, sometimes the feature is not picked up. – Michael Stimson Jun 20 '14 at 4:36
  • A new shapefile is created every time before running above tool. Points are then added. It was somehow storing the points whenever I clicked on map but was not displaying it. – Ibe Jun 20 '14 at 4:39
  • 2
    I think you might need to delete the cursor to flush it. This releases locks also. Perhaps a with statement would solve it, otherwise del cursor before arcpy.RefreshTOC(). – Michael Stimson Jun 20 '14 at 5:15
2

When using an insert cursor the inserted object may not be written to the feature class as soon as you call insertRow, Python is based on C and C uses filestream objects with windows buffering and aren't flushed until the OFstream::flush(); is called.. this means little from the Python point of view but still needs to be understood. It is best to dismiss the cursor, which will call the flush in its destructor.

Two methods can be used for this, first the with method (see Python with):

def onMouseDownMap(self, x, y, button, shift):
    xy = (x,y)
    with arcpy.da.InsertCursor(r'C:/temp/points.shp', ("SHAPE@XY")) as cursor:
        cursor.insertRow([xy])
    arcpy.RefreshTOC()
    arcpy.RefreshActiveView()

the older (to me anyway) method is the del statement (see Python del):

def onMouseDownMap(self, x, y, button, shift):
   xy = (x,y)
   cursor = arcpy.da.InsertCursor(r'C:/temp/points.shp', ("SHAPE@XY"))
   cursor.insertRow([xy])
   del cursor

   arcpy.RefreshTOC()
   arcpy.RefreshActiveView()

Either way will force your point to show and update the extent of the shapefile.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.