Select to view content in your preferred language

Python "attribute information tool for xy location"  HELP!  IM A BEGINNER!

1845
24
09-13-2012 01:53 PM
ChristiNelson1
Deactivated User
A co-worker of mine has a couple of web applications that need to call a Geoprocessing Tool.

The tool creation has been assigned to me - but I am a  novice Python programmer. The tool is supposed to act like the 'i' (identify) button on ArcGIS desktop, but instead of returning info about one feature class, it needs to return only one specific attriburte from many feature classes. 

Specifically, it should return city, county, basemap and other feature layer information for a given coordinate. She has requested such a function be created by using Python in ArcMap. The input values are: cooidinate_east, cooidinate_north. The output values are: city_name, county_nm, bmap_code.


Is this possible?  Suggestions?
Christi
Tags (2)
0 Kudos
24 Replies
ChristiNelson1
Deactivated User
Got it to work:  for even a single set of coords, set up a pointlist (replace with your own coords and path)... How do I attach this correctly to the previous code and then use as a variable?

pointList = [[6044782.84206, 2142068.46912]]
point = arcpy.Point()
pointGeometryList = []
for pt in pointList:
     point.X = pt[0]
     point.Y = pt[1]
     pointGeometry = arcpy.PointGeometry(point)
     pointGeometryList.append(pointGeometry)
arcpy.CopyFeatures_management(pointGeometryList, "H:\Projects\LocationDetector\Test.gdb\points")
0 Kudos
JakeSkinner
Esri Esteemed Contributor
Glad you got it to work!  I originally tested this with 10.1, but could not get it working.  I tried 10.0 and it worked.  This may be a bug with 10.1.
0 Kudos
ChristiNelson1
Deactivated User
Hmmm. Now how do i bring this back into the tool to get the tool to work? Im getting an error:

>>> import arcpy, os, tempfile
... import win32clipboard as w
... ##import win32con
...
... input = arcpy.GetParameterAsText(0)
...
... temp_table = tempfile.mktemp(suffix='.txt')
...
... output = open(temp_table, "w")
...
... cur = arcpy.SearchCursor(input)
...
... for row in cur:
... geom = row.Shape
... X = geom.centroid.X
... Y = geom.centroid.Y
... output.write(XY)
...
... ##output.close()
...
... output = open(temp_table, "r")
... XY = output.read()
... pointList = [XY]
... point = arcpy.Point()
... pointGeometryList = []
... for pt in pointList:
... point.X = pt[0]
... point.Y = pt[1]
... pointGeometry = arcpy.PointGeometry(point)
... pointGeometryList.append(pointGeometry)
... arcpy.CopyFeatures_management(pointGeometryList, "H:\Projects\LocationDetector\Test.gdb\points")
...
Runtime error <type 'exceptions.RuntimeError'>: Point: Input value is not numeric
0 Kudos
JakeSkinner
Esri Esteemed Contributor
Take a look at my previous example.  Instead of writing the output to a shapefile you can easily write it to a feature class instead.
0 Kudos
ChristiNelson1
Deactivated User
I was able to get this working if I wrote the PointGeometry to a shapefile rather than an IN_MEMORY feature, or a feature class.  Here's an example:

import arcpy
arcpy.env.overwriteOutput = 1
input = arcpy.GetParameterAsText(0)

rows = arcpy.SearchCursor(input)
for row in rows:
    geom = row.shape
    X = geom.centroid.X
    Y = geom.centroid.Y

point = arcpy.Point(X, Y)
ptGeometry = arcpy.PointGeometry(point)

arcpy.CopyFeatures_management(ptGeometry, r"C:\temp\python\POINT.shp")

arcpy.MakeFeatureLayer_management(r"C:\temp\python\POINT.shp", "point")

mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd)[0]
for layer in arcpy.mapping.ListLayers(mxd, '', df):
    if layer.name.lower() == "cities":
        arcpy.MakeFeatureLayer_management(layer, "cities_lyr")
        arcpy.SelectLayerByLocation_management("cities_lyr", "INTERSECT", "point", "30 FEET", "NEW_SELECTION")
        rows = arcpy.SearchCursor("cities_lyr")
        for row in rows:
            arcpy.AddMessage(row.NAME)
            print row.NAME
        del row, rows

arcpy.Delete_management(r"C:\temp\python\POINT.shp")


You can add more 'if' statements for the other layers you would like to identify, and alter the 'arcpy.AddMessage' to display the info you would like to show.  The info will be reported to the GP windows, or to the 'Results' window > Messages.  I couldn't find a way to display the info to the Python window at 10.0, but this works using an add-in at 10.1.

Also, I believe since I used a shapefile the XY coordinates were slightly different when trying to identify a point feature class.  I had to adjust the search distance to around 30 feet in the Select Layer by Location function to identify the correct point (city in the above example).


I missed this post some how!  I will test ths out now.  Thank you!
0 Kudos
ChristiNelson1
Deactivated User
First off, I want to say thank you for all of your help.  This has been a very positive and encouraging experience for me using Python.  🙂

I do have a question about the final code sample.  Will this end up creating a bunch of new shapefiles (or feature classes) and layer files in the geodatabase, or are these somehow temporary and go away at the end of the process?

What to do if they don't go away?  I imagine users will be randomly wanting information from a variety of locations...

Cheers and thanks again,
Christi
0 Kudos
JakeSkinner
Esri Esteemed Contributor
In the above example, the script creates a shapefile and then removes it at the end using the 'arcpy.Delete_management' function.  However, you can create an IN_MEMORY feature class.  This is a temporary feature class.  You would need to update the following lines:

arcpy.CopyFeatures_management(ptGeometry, r"C:\temp\python\POINT.shp")

arcpy.MakeFeatureLayer_management(r"C:\temp\python\POINT.shp", "point")


to:

arcpy.CopyFeatures_management(ptGeometry, "IN_MEMORY/POINT")

arcpy.MakeFeatureLayer_management("IN_MEMORY/POINT", "point")


The reason I used a shapefile was the problem with the bug mentioned before.  At 10.0, using an IN_MEMORY feature class should work.  More information about IN_MEMORY feature classes can be found here.
0 Kudos
ChristiNelson1
Deactivated User
Happy Friday!

Im thinking that rather than putting the results in the python window, I may need to write them to a text file or table of some sort.  This may be easier for a programmer to call the results into a pop up window. 


Thoughts?
0 Kudos
JakeSkinner
Esri Esteemed Contributor
You can easily write the output to a text file.  Take a look at the examples here.  Also, here is an updated example of the script posted earlier:

logpath = r"C:\temp\python\file.txt"
if os.path.exists(logpath):
    os.remove(logpath)

f = open(logpath, "w")

mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd)[0]
for layer in arcpy.mapping.ListLayers(mxd, '', df):
    if layer.name.lower() == "cities":
        arcpy.MakeFeatureLayer_management(layer, "cities_lyr")
        arcpy.SelectLayerByLocation_management("cities_lyr", "INTERSECT", "point", "30 FEET", "NEW_SELECTION")
        rows = arcpy.SearchCursor("cities_lyr")
        for row in rows:
            f.write(row.NAME)
        del row, rows

f.close()


Note:  Be sure to import the 'os' module if you are going to check if the file already exists.
0 Kudos
ChristiNelson1
Deactivated User
Hi there,

I have a question about this part of the code:   if layer.name.lower() == "cities":

why do you put ".name.lower()"  what does .lower mean?  The lowest layer in the dataframe toc?  Is it necessary to write this?  I will have more than one layer in mine..

Thanks for clarifying.
Christi
0 Kudos