3

I am trying to create a tool that creates lines from selected point features. I am able to select the point features and create a search cursor to curse through them. I can message box attributes from each point. I am having trouble creating an array of points by getting the XY coordinates from each row in the search cursor.

Below is the code:

import arcpy
import pythonaddins

import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")
layers = mapping.ListLayers(mxd)
# for lyr in layers:
    # print(lyr.name)

class ToolClass2(object):
    """Implementation for Fishnet_addin.tool (Tool)"""
    def __init__(self):
        self.enabled = True
        self.cursor = 3
        self.shape = 'Rectangle'
    def onMouseDown(self, x, y, button, shift):
        pass
    def onMouseDownMap(self, x, y, button, shift):
        pass
    def onMouseUp(self, x, y, button, shift):
        pass
    def onMouseUpMap(self, x, y, button, shift):
        pass
    def onMouseMove(self, x, y, button, shift):
        pass
    def onMouseMoveMap(self, x, y, button, shift):
        pass
    def onDblClick(self):
        pass
    def onKeyDown(self, keycode, shift):
        pass
    def onKeyUp(self, keycode, shift):
        pass
    def deactivate(self):
        pass
    def onCircle(self, circle_geometry):
        pass
    def onLine(self, line_geometry):
        pass
    def onRectangle(self, rectangle_geometry):
      """Occurs when the rectangle is drawn and the mouse button is released.
    The rectangle is a extent object."""

  extent = rectangle_geometry
  mxd = mapping.MapDocument("CURRENT")
  df = arcpy.mapping.ListDataFrames(mxd)[0]
  layer = mapping.ListLayers(mxd)[0]
  # Select the first layer in the project, the point layer.



  # Create a fishnet with 1 row and 1 column.
  if arcpy.Exists(r'in_memory\fishnet'):
      arcpy.Delete_management(r'in_memory\fishnet')
  fishnet = arcpy.CreateFishnet_management(r'in_memory\fishnet',
                          '%f %f' %(extent.XMin, extent.YMin),
                          '%f %f' %(extent.XMin, extent.YMax),
                          0, 0, 1, 1,
                          '%f %f' %(extent.XMax, extent.YMax),'NO_LABELS',
                          '%f %f %f %f' %(extent.XMin, extent.YMin, extent.XMax, extent.YMax), 'POLYGON')
  fishnet.visible = False
  # Select by location the point layer that intersects the fishnet    
  arcpy.SelectLayerByLocation_management(layer, "INTERSECT", fishnet, "", "NEW_SELECTION", "NOT_INVERT")
  #  Count the number of points selected
  selectionCount = arcpy.GetCount_management(layer)
  count = int(selectionCount.getOutput(0))
  # if 2 points are selected create a search cursor for them 
  if (count == 2):
      pointCursor = arcpy.SearchCursor(layer, ["SHAPE@XY", "NAVD88"])

      messageResult = pythonaddins.MessageBox(selectionCount,"Points Selected Event",3)
      array = []
      for row in pointCursor:
        NAVD = row.getValue("NAVD88")            
        messageResult = pythonaddins.MessageBox(NAVD,row,3)
        # attempt to build an array of points from the points in the search cursor.  This is the part that does not work.  Comment this line and uncomment the array code below and it works.
        array.add(arcpy.Point(row.getPart(0)))

  # This is an empty line layer with one field called "slope"  I manually start editing on this layer before using the tool.
  fc = r"E:\ArcGIS\Working.gdb\testLines"
  #  Create an insert cursor to add the line feature to the line layer.
  cursor = arcpy.da.InsertCursor(fc, ["SHAPE@","slope"])

  #  The commented code below works.  What I am trying to do is to build this 'array' from the XY coordinates of the points in the search cursor.
  # array = arcpy.Array([arcpy.Point(-82.226344, 26.915444),
                 # arcpy.Point(-82.226499, 26.915005)])

  spatial_reference = arcpy.SpatialReference(4326)
  polyline = arcpy.Polyline(array, spatial_reference)

  theslope = 2.08

  cursor.insertRow([polyline,theslope])

  # arcpyRefreshTOC()
  arcpy.RefreshActiveView()
  return fishnet
  • Please reformat your code indentation, look at the onRectangle method – Alex Tereshenkov Apr 25 '18 at 18:03
1

SHAPE@XY returns a tuple [x, y] whereas a Point geometry generated from the arcpy command takes a numeric sequence (x, y) with options for z and m added if desired (not necessary in this case).

I'd also recommend using the da.SearchCursor object in order to facilitate getting the X and Y values from each row, per the code snippet below. This has been updated to account for a different projection in the input layer.

pointCursor = arcpy.da.SearchCursor(layer, ["SHAPE@XY", "NAVD88"])  ##This is updated slightly
messageResult = pythonaddins.MessageBox(selectionCount,"Points Selected Event",3)
array = []
from_sr = arcpy.Describe(layer).spatialReference  ##Get the spatial reference of "layer" - for use in reconverting points
for row in pointCursor:
        NAVD = row[1]  ##This is updated for the da cursor object          
        messageResult = pythonaddins.MessageBox(NAVD,row,3)
        # attempt to build an array of points from the points in the search cursor.  This is the part that does not work.  Comment this line and uncomment the array code below and it works.
        pt = arcpy.PointGeometry(arcpy.Point(row[0][0], row[0][1]), from_sr).projectAs(arcpy.SpatialReference(4326))  ##Create projected pt geometry - can be used like an in-memory layer as input for geoprocessing

        array.append(pt)

        ###If you want to visualize your points or export as their own layer, uncomment the following line:
        #arcpy.CopyFeatures_management(array, 'in_memory\points_output')
  • Thank you AlecZ. That seems to have worked however the coordinates that were brought back don't seem to be in latitude and longitude. It seems more like meters (-9153403,3112904) The line doesn't populate in the line layer. The line layer and the data frame are in WGS84 Do I need to convert this from meters to Decimal Degrees? – Kevin Edwards Apr 26 '18 at 17:39
  • See the updated code - this will account for the different coordinate system in your "layer" geometry, and should resolve any geoprocessing issues. – AlecZ Apr 26 '18 at 19:17
  • I got the code to work. I had to add to the search cursor pointCursor = arcpy.da.SearchCursor(layer, ["SHAPE@XY", "NAVD88"], spatial_reference=arcpy.SpatialReference("WGS 1984")) – Kevin Edwards Apr 27 '18 at 13:06
  • Thank you, I didn't get a chance to test your code for projecting because I found the projection of the cursor first but I am sure I will be able to use it in the future. Thanks again – Kevin Edwards Apr 27 '18 at 13:11
  • @KevinEdwards if AlecZ's answer helped you I think you should upvote and probably also Accept it. That is how we say thanks and many thanks here. – PolyGeo May 8 '18 at 20:52

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.