I need Help on any Python script that can clip a data frame to a selected feature

7002
27
Jump to solution
08-10-2012 06:02 PM
OLANIYANOLAKUNLE
Occasional Contributor II
I am in bear need of any python script that can clip the data frame extent to a selected feature, a script different from the clipping under the geoprocesssing tool?
Tags (2)
0 Kudos
27 Replies
OLANIYANOLAKUNLE
Occasional Contributor II
Thanks i got a work around for it, all i need now is a custom form to select a particular plot_no from a parcel layer in my data frame and create pdfs using the plot_no from a field called plot_no so that the name of my pdfs changes with different plot_nos. How can i also display a message such as the 1 below without using a script tool, Any suggestions? Thanks

# Report a success message
  arcpy.AddMessage("All done!")

except:
  # Report an error messages
  arcpy.AddError("Could not complete the selection")

  # Report any error messages that the selection tool might have generated
  arcpy.AddMessage(arcpy.GetMessages())
0 Kudos
BruceBacia
Occasional Contributor
this should work for you.  I tested it with grouped layers and with SDE layers.  It will operate only on the layers in the first data frame (if you have multiple data frames in your MXD) and if you have grouped layers, there can be no spaces in the group name. 

Requirements
ArcGIS 10
Saved MXD with one data frame
no spaces in group names

#ClipToExtent.py
#Clips all feature layers to the extent of your current mxd
#author: Bruce Bacia, 
#8/12/2012
import arcpy,os,gc,time

#set map document to the current open mxd
mxd = arcpy.mapping.MapDocument("CURRENT")
path = mxd.filePath

#get the root path of the mxd
path = path.replace(os.path.basename(path),"")

#set the dataframe as a polygon
df = arcpy.mapping.ListDataFrames(mxd)[0]
dfAsFeature = arcpy.Polygon(arcpy.Array([df.extent.lowerLeft, df.extent.lowerRight, df.extent.upperRight, df.extent.upperLeft]),df.spatialReference)

#list the layers in the dataFrame
lyrs = arcpy.mapping.ListLayers(mxd,"",df)

#clip the layer to the dataframe extent polygon
#send the output feature class to the same folder as the mxd
exportLayers = []
for lyr in lyrs:
    if lyr.isFeatureLayer == True:
        layerRplc = lyr.longName
        replace = [".","\\"]
        for item in replace:
            layerRplc = layerRplc.replace(item,"_")
        outFC = os.path.join(path,layerRplc + "_Clip" + ".shp")
        exportLayers.append(outFC)
        if arcpy.Exists(outFC):
           arcpy.Delete_management(outFC)
        arcpy.AddMessage("Clipping..... " + outFC)
        arcpy.Clip_analysis(lyr,dfAsFeature,outFC)
for layer in sorted(exportLayers):
    addLayer = arcpy.mapping.Layer(layer)
    arcpy.mapping.AddLayer(df, addLayer, "TOP")
del mxd
del df
gc.collect()
0 Kudos
OLANIYANOLAKUNLE
Occasional Contributor II
Thanks Bruce Bacia, you have really improved my python script writing skills. Can you help me with this please;

i want to generate a pdf output by using the arcpy.exporttopdf function, i want the final output to use this nomenclature for naming the pdf output (plot_no.pdf); the plot_no would be derived from an attribute value under the field named plot_no in the attribute table. Please do you have any suggestions. Thanks
0 Kudos
RichardFairhurst
MVP Honored Contributor
Getting back to the original question of this thread, by using suggestions from Leo Donahue I have found a way to create a C# ArcMap Console Application using Visual Studio 2010 that can be triggered by Python to change the data frame clip geometry.  This should work for ArcGIS 10.0 and above and the C# code should compile in Visual Studio 2010 express and above.

While there are a number of ways to obtain the geometry for use in updating the data frame, I designed my routine to use a single polygon feature obtained from a map layer.  I can set up Python to execute the console application and pass string parameters that provide the console application with the mxd name, the data frame name, and the layer name that will be used as the feature geometry of the data frame clip shape.  Normally prior to running this code arcpy would set a Definition Query filter on the layer to restrict it to a single polygon feature.  The code also assumes that the layer is found in the same data frame that is to be clipped. 

It should be possible to adapt this code to use a graphic in a layout, or a geometrybag combination of multple polygon features as the clipping geometry instead of, or in addition to, a single feature's geometry, but this does what I wanted.

Here is the Python code to call the Console Application:

from subprocess import check_call # format is check_call([ConsoleApp_Path_and_Name, MXD_Name, Data_Frame_Name, Layer_Name]) check_call(["SetFrameClipGeometry.exe", "Collision_Segment_Diagram2.mxd", "Bottom_Split", "Bottom Clip Shape Left"]) # perform a refresh of the data frame using arcpy after setting the data frame geometry.


Here is the Code I used in the C# ArcMap Desktop Console Application:

using System; using System.Collections.Generic; using System.Text; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.Framework; using ESRI.ArcGIS.ArcMapUI; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.ADF; using ESRI.ArcGIS.Geometry;  namespace SetFrameClipGeometry {     class Program     {         private static LicenseInitializer m_AOLicenseInitializer = new SetFrameClipGeometry.LicenseInitializer();              [STAThread()]         static int Main(string[] args)         {             //ESRI License Initializer generated code.             if (!m_AOLicenseInitializer.InitializeApplication(new esriLicenseProductCode[] { esriLicenseProductCode.esriLicenseProductCodeArcView, esriLicenseProductCode.esriLicenseProductCodeArcEditor, esriLicenseProductCode.esriLicenseProductCodeArcInfo },             new esriLicenseExtensionCode[] { }))             {                 System.Console.WriteLine(m_AOLicenseInitializer.LicenseMessage());                 System.Console.WriteLine("This application could not initialize with the correct ArcGIS license and will shutdown.");                 m_AOLicenseInitializer.ShutdownApplication();                 return 1;             }             //ESRI License Initializer generated code.             String mxdName = null;             String dfName = null;             String layerName = null;              if (args.Length < 3)             {                 System.Console.WriteLine("Insufficient parameters.  Expected Three Strings");                 return 1;             }             else             {                 mxdName = args[0];                 dfName = args[1];                 layerName = args[2];             }             try             {                 IAppROT aprot = new AppROT();                 if (aprot.Count == 0)                 {                     System.Console.WriteLine("No ArcMap application is open");                     return 1;                 }                 IApplication application = null;                 IMxDocument mxd = null;                 for (int a = 0; a < aprot.Count; a++)                 {                     application = aprot.get_Item(a);                     System.Console.WriteLine("Search Application Title: " + application.Document.Title);                     if (application.Document.Title == mxdName)                     {                         System.Console.WriteLine("Found Open ArcMap Document Named: " + mxdName);                         mxd = application.Document as IMxDocument;                         break;                     }                 }                 IMap pMap = null;                 IMaps pMaps = null;                 if (mxd == null)                 {                     System.Console.WriteLine("No ArcMap Document Named " + mxdName + " Was Found");                     return 1;                 }                 pMaps = mxd.Maps;                 for (int i = 0; i <= pMaps.Count - 1; i++)                 {                     pMap = pMaps.get_Item(i);                     if (pMap.Name == dfName)                     {                         Console.WriteLine("Found Data Frame Named: " + pMap.Name);                         break;                     }                 }                 if (pMap == null)                 {                     System.Console.WriteLine("No DataFrame Exists In " + mxdName);                     return 1;                 }                 if (pMap.Name != dfName)                 {                     System.Console.WriteLine("No Data Frame Named " + dfName + " Was Found");                     return 1;                 }                 if (pMap.LayerCount == 0)                 {                     return 1;                 }                 // Fetch all the feature layers in the focus map                 // to determine if at least one is selectable.                 UIDClass uid = new UIDClass();                 uid.Value = "{40A9E885-5533-11d0-98BE-00805F7CED21}";                 IEnumLayer pEnumLayer = pMap.get_Layers(uid, true);                 pEnumLayer.Reset();                 ILayer pLayer = pEnumLayer.Next();                 while (pLayer != null)                 {                     if (pLayer.Name == layerName)                     {                         Console.WriteLine("Found Layer Named: " + pLayer.Name);                         break;                     }                     pLayer = pEnumLayer.Next();                 }                 if (pLayer == null)                 {                     System.Console.WriteLine("No Layer Named " + layerName + " Was Found");                     return 1;                 }                 using (ComReleaser comReleaser = new ComReleaser())                 {                     IFeatureLayer pFLayer = pLayer as IFeatureLayer;                     IFeatureCursor pFCursor = pFLayer.Search(null, false);                     comReleaser.ManageLifetime(pFCursor);                     IFeature pFeat = null;                     IGeometry pGeom = null;                     while ((pFeat = pFCursor.NextFeature()) != null)                     {                         pGeom = (IGeometry)pFeat.Shape;                     }                     if (pGeom == null)                     {                         System.Console.WriteLine("No Feature Geometry Was Found!");                         return 1;                     }                     pMap.ClipGeometry = pGeom;                     System.Console.WriteLine("Feature Geometry Set!");                 }             }             catch (Exception e)             {                 Console.WriteLine("{0} Exception caught.", e);                 System.Console.ReadLine();                 return 1;             }             //System.Console.ReadLine();  // Uncomment this line if you want to pause the Console application before it closes.             //Do not make any call to ArcObjects after ShutDownApplication()             m_AOLicenseInitializer.ShutdownApplication();             return 0;         }     } }
0 Kudos
RichardFairhurst
MVP Honored Contributor
I spoke too soon.  While the script and console application work perfectly when I run the Python script from Idle, it hangs when I run the same code from within a script tool.  The Console application window opens, but the parameters never get read when the script tool runs the code.

Anyway, I know how to get the Data Frame Clip Geometry updated from the ArcObjects side, but I still need to find a way to connect it automatically to the Python code at runtime.
0 Kudos
OLANIYANOLAKUNLE
Occasional Contributor II
rfairhur24
Thanks for the nugget of information, my question is can you create a custom form using C# and then use python scripts as code behind a button that when clicked would fire some events with a given mxd and return the output? The created custom form would act as a combo box from here a plot would be selected and upon this single selection the events behind the button(python scripts) would act and generate the final output? Thanks
0 Kudos
OLANIYANOLAKUNLE
Occasional Contributor II
Can you help me with this please?
I am trying to generate a create a folder and the name of this folder would be derived from an attribute value by using the searchCursor and at the same time generate a pdf output which name would also be derived from an attribute valve using the search cursor. This my code below, ive been having serious issues with the folder path as the application claims my output destination does not exist.

arcpy.SelectLayerByLocation_management("Parcels", "COMPLETELY_WITHIN", "ClipFeature", "", "NEW_SELECTION")
fc = "Parcels"
field = "LGA"
cursor = arcpy.SearchCursor(fc)
for row in cursor:
    row.getValue(field)
val = row.getValue(field)
field = "District"
cursor = arcpy.SearchCursor(fc)
for row in cursor:
    row.getValue(field)
val1 = row.getValue(field)
field = "Block_No"
cursor = arcpy.SearchCursor(fc)
for row in cursor:
    row.getValue(field)
val2 = row.getValue(field)
field = "Plot_No"
cursor = arcpy.SearchCursor(fc)
for row in cursor:
    row.getValue(field)
val3 = row.getValue(field)
outName = str(val) + "LGA" 
outName = "Block" + str(val) + "Plot_" + str(val2)
outName1 = "Block_" + str(val2) + "Plot_" + str(val3) + str(val1) + "Area of" + str(val) + "_LGA" + ".pdf"
outName2 = str(val1) + "AREA" 
outName3 = "Block" + str(val2) #+ "Plot_" + str(val3)
outName4 = "Plot_" + str(val3)
arcpy.CreateFolder_management("C:\ETE_STATE",outName,outName2,outName3,outName4)
arcpy.mapping.ExportToPDF(mxd,"C:\ETE_STATE", outName+outName2+outName3+outName4+ outName1)


Please your suggestions would be appreciated. Thanks (Ive also included my script as an attachment)
0 Kudos
ArminMueller
New Contributor III
I spoke too soon.  While the script and console application work perfectly when I run the Python script from Idle, it hangs when I run the same code from within a script tool.  The Console application window opens, but the parameters never get read when the script tool runs the code.

Anyway, I know how to get the Data Frame Clip Geometry updated from the ArcObjects side, but I still need to find a way to connect it automatically to the Python code at runtime.


rfairhur24
i have the same problem. Starting a console app with IAppRot freeze when running from a script tool. Just tested with ArcGIS 10.1 SP1 but even the same.
Have you found a solution for this problem in the meantime?

Armin
0 Kudos