Select to view content in your preferred language

Pyhton: Create Layer from Selected Features?

2898
7
Jump to solution
07-27-2012 07:52 AM
MikeMacRae
Frequent Contributor
I'm wondering if there is a python method/workflow model that will allow me to do the same thing as right clicking on a layer in ArcMap and going to Selection-->Create Layer from Selected Features? I've tried to create a model using select by attribute --> Make layer File --> Save to Layer File, but this doesn't work. The symbology for all feature still persist. I doubt this is doable, but I thought I'd throw it out there.

Thanks,
Mike
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
ChristopherThompson
Frequent Contributor
Ok, here is the code I promised.. this is an example of how to accomplish this, you'd have to tweak it to be specific to your data:

def make_paz_layer(keyhole):                paz_units = []                SelPaz = arcpy.SelectLayerByLocation_management (PAZ_lyr, 'Intersect', keyhole)                rows = arcpy.SearchCursor(SelPaz," \"POWERPLANT\" = 'North Anna Power Station'", "", "PAZ;PAZ_NUM;PAZ_ALPHA","PAZ_NUM A;PAZ_ALPHA A")                for row in rows:                    unit = str(row.PAZ)                    unum = "'" + unit + "'"                    paz_units.append(unum)                txt_paz = ','.join(paz_units)                paz_list = '(' + txt_paz + ')'                paz_qry = ' "POWERPLANT" = '+ station_name + ' AND "PAZ" in ' + paz_list                new_paz = arcpy.MakeFeatureLayer_management(paz, keyhole + '_paz', paz_qry)                arcpy.SaveToLayerFile_management(new_paz, outfolder + '\\' + keyhole + '_paz.lyr')

A couple of notes:

  • This is a function that accepts a layer as an argument - the layer could be a .lyr file on disk or one created in-memory


  • PAZ_lyr (in the SelectByLocation line) references an already created layer using MakeFeatureLayer_management


  • the line unum = "'" + unit + "'" is needed if your unique values are strings/text... this isn't necessary if those values are numeric

Let me know if this helps, you have questions or if i can help more.

View solution in original post

0 Kudos
7 Replies
ChristopherThompson
Frequent Contributor
Well, in my humble opinon and experience the 'Create Layer from Selected Features' tool has created more problems than has resolved. But understanding what you want to do here, I've been able to 'emulate' this behavior with the end result being a layer created from a selection but which has a properly defined selection query so you don't see all the other features. Is this the sort of thing you want to do?
0 Kudos
MikeMacRae
Frequent Contributor
Yes, this sounds like what I want to do. Basically, I have point feature class in a template mxd, properly symbolized using Unique Values, many Fields. The points lie within one of 5 polygons from a polygon feature class. I want to select the points that lie in the first polygon (so a select by location, not a select by attribute like I mentioned below) and then save only the selected points in a layer file exactly how the right click on layer-->Selection-->Create Layer from Selected Features does so that the layer only retains the symbology for the selected features.

What was your method?

Thanks,
Mike
0 Kudos
ChristopherThompson
Frequent Contributor
I want to select the points that lie in the first polygon (so a select by location, not a select by attribute like I mentioned below) and then save only the selected points in a layer


This is exactly the scenario that I was thinking about.  I'm away from my office today but on Monday I'll post the code that I used so you can see an example.  Basically, the strategy is follows these steps:


  • make your polygon selection


  • select by location which gives you basically a selection set


  • use a search cursor to collect some sort of ID value from the selected features into a python list


  • use the python list to create a string list of values that can be used in a definition query of the form "select from <fc> where <ID> in ('values from python list')"


  • Make a feature layer from your original unselected point data using the sql query


  • save the feature layer to a .lyr file on disk using arcpy.SaveToFeatureLayer


  • once you've done this, you'll probably want to work with the arcpy.mapping module to add that layer to your map and use the UpdateLayer function to apply symbology to that layer from your existing symbolized point layer.

0 Kudos
ChristopherThompson
Frequent Contributor
Ok, here is the code I promised.. this is an example of how to accomplish this, you'd have to tweak it to be specific to your data:

def make_paz_layer(keyhole):                paz_units = []                SelPaz = arcpy.SelectLayerByLocation_management (PAZ_lyr, 'Intersect', keyhole)                rows = arcpy.SearchCursor(SelPaz," \"POWERPLANT\" = 'North Anna Power Station'", "", "PAZ;PAZ_NUM;PAZ_ALPHA","PAZ_NUM A;PAZ_ALPHA A")                for row in rows:                    unit = str(row.PAZ)                    unum = "'" + unit + "'"                    paz_units.append(unum)                txt_paz = ','.join(paz_units)                paz_list = '(' + txt_paz + ')'                paz_qry = ' "POWERPLANT" = '+ station_name + ' AND "PAZ" in ' + paz_list                new_paz = arcpy.MakeFeatureLayer_management(paz, keyhole + '_paz', paz_qry)                arcpy.SaveToLayerFile_management(new_paz, outfolder + '\\' + keyhole + '_paz.lyr')

A couple of notes:

  • This is a function that accepts a layer as an argument - the layer could be a .lyr file on disk or one created in-memory


  • PAZ_lyr (in the SelectByLocation line) references an already created layer using MakeFeatureLayer_management


  • the line unum = "'" + unit + "'" is needed if your unique values are strings/text... this isn't necessary if those values are numeric

Let me know if this helps, you have questions or if i can help more.
0 Kudos
MikeMacRae
Frequent Contributor
Christopher, thanks for you contribution and persistence in getting me an answer. Your script took me in a little different direction than I was on. Specifically, building a list and converting to string to be used in a definition query. I wasn't even thinking definition query, but then again, I haven't used them much in the past.

This also resolved the issue with creating a second layer. I don't need to do that now because I can edit the current layer in the map. Basically, I have a map template with template layers. I can now edit the template layer by using the definition query and saveACopy of the mxd elsewhere.

I'm going to attempt to use this script in a python addin button in the template, so that the user can just select a polygon and press the button to update the layer. Something like that anyways.

Here is my script so far, for those who are interested:

mxd = arcpy.mapping.MapDocument("CURRENT")

df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]

for lyr in arcpy.mapping.ListLayers(mxd):
    if lyr.name == "Point":
        lyr.definitionQuery = ""
        Point = lyr
    if lyr.name == "Polygon":
        Polygon = lyr

arcpy.SelectLayerByAttribute_management(Polygon, "NEW_SELECTION", "\"SITE\" = 'Pad 1'")
arcpy.SelectLayerByLocation_management(Point, "WITHIN", Polygon, "", "NEW_SELECTION")

pointList = []

for row in arcpy.SearchCursor(Point):
    strrow = str(row.OBJECTID)
    soilList.append(strrow)    

txt_row = ','.join(soilList)
row_list = '(' + txt_row + ')'
row_qry = ' "OBJECTID" in ' + row_list

for lyr in arcpy.mapping.ListLayers(mxd):
    if lyr.name == "Point":
        lyr.definitionQuery = row_qry

arcpy.SelectLayerByAttribute_management(Point, "CLEAR_SELECTION")
arcpy.SelectLayerByAttribute_management(Polygon, "CLEAR_SELECTION")

arcpy.RefreshActiveView()
arcpy.RefreshTOC()            

mxd.save()

0 Kudos
ChristopherThompson
Frequent Contributor
Hey, glad to help! I'll be interested to know how your project works out.
0 Kudos
MikeMacRae
Frequent Contributor
Thanks again Chris.

I installed the addin as a "Button". I also discovered that the script will honor any selections in the "CURRENT" MapDocument, so I commented out the 'SelectByAttribute' syntax (which was used to select a polygon to be used in the 'SelectByLocation" syntax). Now, I manually select a polygon, click the button and it does all the processing to update only the points that lie within the selected polygon. Some nice success on my first python addin attempt!
0 Kudos