Select to view content in your preferred language

Create a search with user GetParameterAsText using arcpy.da.SearchCursor

4687
9
05-20-2015 07:57 AM
CCWeedcontrol
Frequent Contributor

I am trying to create a script tool to do a search but i am having a little trouble putting it together and i am not sure if i am going about it the right way. I would like to have a script tool that can search for a subdivision name inside arcmap in the toolbox. I have attached my python code i have and working with, one other thing i would like this script to do is use a wildcard. For example say a subdivision that i am searching for attribute is "County Side Estates" but I would like to just enter "County" and select all subs with "County" but i am not sure how to accomplish this. Any help would be gratefully appreciated.

Thanks.

The error i am getting with my current code.

Traceback (most recent call last):

  File "C:\GIS\Python Scripts\ZoomToParcelScript6Eb.py", line 9, in <module>

    for row in cursor:

RuntimeError: Underlying DBMS error [[Microsoft][SQL Server Native Client 10.0][SQL Server]Incorrect syntax near 'ACRES'.] [vector.DBO.Subdivision_boundaries]

Failed to execute (ZoomToSubScript).

import arcpy

mxd = arcpy.mapping.MapDocument('CURRENT')
df = arcpy.mapping.ListDataFrames(mxd, "Layers") [0]
lyr = arcpy.mapping.ListLayers(mxd, "Subdivision Boundaries")[0] 

whereClause = arcpy.GetParameterAsText(0)
with arcpy.da.SearchCursor(lyr, ("PLAT_NAME"), whereClause) as cursor:
    for row in cursor:
        query_str = whereClause #= '{0}'.format(row[1])
        arcpy.SelectLayerByAttribute_management(lyr, "NEW_SELECTION", query_str) 
        df.extent = row[0].extent
        df.scale = df.scale * 5

        arcpy.RefreshActiveView()
        #arcpy.mapping.ExportToPDF(mxd, "C:/test/" + fc + "_" + str(row[1]) + "_" +  str(row[2]) + ".pdf") 

Here are my script parameters.

Tags (1)
0 Kudos
9 Replies
TomSellsted
MVP Regular Contributor

Greetings,

It looks like your whereclause is incomplete.  Try:

whereClause = "PLAT_NAME LIKE '%" + arcpy.GetParameterAsText(0) + "%'"

Regards,

Tom

CCWeedcontrol
Frequent Contributor

I made the following adjustments, When i type in Rolling Hills #3, i get the following error.

Traceback (most recent call last):

  File "C:\GIS\Python Scripts\ZoomToParcelScript6Eb.py", line 9, in <module>

    for row in cursor:

RuntimeError: Underlying DBMS error [[Microsoft][SQL Server Native Client 10.0][SQL Server]Incorrect syntax near 'HILLS'.] [vector.DBO.Subdivision_boundaries]

Failed to execute (ZoomToSubScript).

If i type in just Rolling i get this error.

Traceback (most recent call last):

  File "C:\GIS\Python Scripts\ZoomToParcelScript6Eb.py", line 9, in <module>

    for row in cursor:

RuntimeError: Underlying DBMS error [[Microsoft][SQL Server Native Client 10.0][SQL Server]An expression of non-boolean type specified in a context where a condition is expected, near ')'.] [vector.DBO.Subdivision_boundaries]

Failed to execute (ZoomToSubScript).

here is the current code with your suggestions. i am assuming that the syntax is incorrect still.

I am lost...

import arcpy

mxd = arcpy.mapping.MapDocument('CURRENT')
df = arcpy.mapping.ListDataFrames(mxd, "Layers") [0]
lyr = arcpy.mapping.ListLayers(mxd, "Subdivision Boundaries")[0] 

whereClause = arcpy.GetParameterAsText(0)
with arcpy.da.SearchCursor(lyr, ("PLAT_NAME"), whereClause) as cursor:
    for row in cursor:
        query_str = "PLAT_NAME LIKE '%" + whereClause + "%'"
        arcpy.SelectLayerByAttribute_management(lyr, "NEW_SELECTION", query_str) 
        df.extent = row[0].extent
        df.scale = df.scale * 5

        arcpy.RefreshActiveView()
        #arcpy.mapping.ExportToPDF(mxd, "C:/test/" + fc + "_" + str(row[1]) + "_" +  str(row[2]) + ".pdf") 
0 Kudos
TomSellsted
MVP Regular Contributor

Greetings,

It looks like you are doing another selection which you have already done using your search cursor so that you can zoom to the extent of the plat.  There are always many ways to do things.  Here is a suggestion.  I have removed the section selection and added the shape field to your search cursor.

import arcpy 

mxd = arcpy.mapping.MapDocument('CURRENT') 
df = arcpy.mapping.ListDataFrames(mxd, "Layers") [0] 
lyr = arcpy.mapping.ListLayers(mxd, "Subdivision Boundaries")[0] 

whereClause = "PLAT_NAME LIKE '%" + arcpy.GetParameterAsText(0) + "%'" 
with arcpy.da.SearchCursor(lyr, ("SHAPE@", "PLAT_NAME"), whereClause) as cursor: 
    for row in cursor: 
        df.extent = row[0].extent 
        df.scale = df.scale * 5 

        arcpy.RefreshActiveView() 
        #arcpy.mapping.ExportToPDF(mxd, "C:/test/" + fc + "_" + str(row[1]) + "_" +  str(row[2]) + ".pdf")

Regards,

Tom

CCWeedcontrol
Frequent Contributor

I wasn't sure if this was the best way to do the search, if there is a better FASTER way please let me know.

The reason i had that the arcpy.SelectLayerByAttribute_management was to actually make the selection on the Layer, I ran the code that you posted and it took me to the area but did not highlight the sub that i searched for. Once i added the arcpy.SelectLayerByAttribute_management back it zoomed to the location and the search sub was highlighted.

I do noticed something strange with the zoom though, if i search by Quail it selects the subs with Quail but zooms to each one, one by one. I would like to just zoom to all of them one time. is this a function of how the arcpy.da.SearchCursor works?

0 Kudos
TomSellsted
MVP Regular Contributor

Greetings,

Certainly!  Here is a completely alternative way to accomplish what you are trying to do:

import arcpy  
  
mxd = arcpy.mapping.MapDocument('CURRENT')  
df = arcpy.mapping.ListDataFrames(mxd, "Layers") [0]  
lyr = arcpy.mapping.ListLayers(mxd, "Subdivision Boundaries")[0] 
  
whereClause = "PLAT_NAME LIKE '%" + arcpy.GetParameterAsText(0) + "%'"
lyr.definitionQuery = whereClause
df.extent = lyr.getExtent(True)
arcpy.RefreshActiveView()

Regards,

Tom

0 Kudos
CCWeedcontrol
Frequent Contributor

The lyr.definitionQuery worked but after running the script to search for "Quail" the features were not highlight and i noticed that when i open the Sub layer attributes only those attributes in the table, what happened to the rest of the subdivision features? How do you rest the Sub layer to show all of the subdivision in the attribute table. I would like to keep all the subdivision features and only select the features that i search for.

0 Kudos
TomSellsted
MVP Regular Contributor

Greetings,

I have done a couple of similar projects where I am doing a search like you are trying to do.  I add a second instance of the layer  to the dataframe that I want to use for the search as described above.  That way I can set the symbology and label the selected features too.  That way when a search is performed they can better see the results of their search. 

Again, there are many ways to do things.  Use what best works for your situation!

Regards,

Tom

0 Kudos
DarrenWiens2
MVP Honored Contributor

You can move your select statement before creating the search cursor. Otherwise, you execute a select statement for each feature in the cursor. The cursor only considers selected features, so you don't need to filter with a where clause. The following selection where clause is hardcoded, but you can sub that out for GetParameterAsText.

>>> import arcpy 
... mxd = arcpy.mapping.MapDocument('CURRENT') 
... df = arcpy.mapping.ListDataFrames(mxd, "Layers") [0] 
... lyr = arcpy.mapping.ListLayers(mxd, "bc_geoname_albers")[0] 
... whereClause = "GEONAME LIKE '%Fraser%' "
... arcpy.SelectLayerByAttribute_management(lyr, "NEW_SELECTION", whereClause )
... with arcpy.da.SearchCursor(lyr, ["SHAPE@","GEONAME"]) as cursor: 
...    for row in cursor:
...        df.extent = row[0].extent 
...        df.scale = df.scale * 5 
...        arcpy.RefreshActiveView() 
curtvprice
MVP Esteemed Contributor

Don't want to be picky, but I like to recommend using Python string formatting. MUCH easier to write and debug.

search_string = arcpy.GetParameterAsText(0) 
whereClause = "GEONAME LIKE '%{}%'".format(search_string)