Inputs for the script are the feature class to check, the maximum scale desired in Layout View (for example, 1:2000 is input as 2000), the percent margin (corresponding to the percent margin in the Data Driven Pages setup window), the new feature class name and the new feature class location, and finally the map document you'll be using the new Data Driven Pages feature class with.
Here's an example of the output, with California's Bay Area divided into regions:
The input is the green features, and the output is the purple-bordered polygons. Smaller features of the input have been replaced by rectangular features at the maximum scale.
Using the output feature class to drive our Data Driven Pages, the maps created won't zoom in closer than desired, even on the smaller features:
#----------------------------# #-------- User Inputs -------# #----------------------------# #Feature class used to generate DDP DataDrivenPageFeature = r"C:\Users\e1b8\Desktop\E1B8\Blog\BlogData.gdb\Input" #Maximum scale MaxScale = 20000 #Percent margin map extent MMEx = 125 #New feature class name NewDDPFeat = "DDP_Ref_Output" #New feature class GDB location NewFeatGDB = r"C:\Users\e1b8\Desktop\E1B8\Blog\BlogData.gdb" #Map document MXDoc = r"C:\Users\e1b8\Desktop\E1B8\Blog\DdpMaxScale.mxd" #----------------------------# #---- End of User Inputs ----# #----------------------------# import arcpy import os arcpy.env.overwriteOutput = True mxd = arcpy.mapping.MapDocument(MXDoc) df = arcpy.mapping.ListDataFrames(mxd)[0] mxd.activeView = "PAGE_LAYOUT" #Data drive page feature type fcShapeType = arcpy.Describe (DataDrivenPageFeature).shapeType #Create temp feature class DDPFeature = os.path.join ("in_memory", "tempFc") if fcShapeType == "Polygon": print "Copying feature class to memory" arcpy.CopyFeatures_management (DataDrivenPageFeature, DDPFeature) else: #Create minimum bounding rectangles print "Converting features to minimum bounding rectangles" arcpy.MinimumBoundingGeometry_management (DataDrivenPageFeature, DDPFeature, "ENVELOPE") #Create layer for selection arcpy.MakeFeatureLayer_management (DDPFeature, "DDPlyr") #Get values for new features at maximum scale df.scale = MaxScale / ((float(MMEx) / 100)) XAdjust = ((df.extent.XMax) - (df.extent.XMin)) / 2 YAdjust = ((df.extent.YMax) - (df.extent.YMin)) / 2 #Create new feature class print print "Creating new feature class" print NewFeat = os.path.join (NewFeatGDB, NewDDPFeat) sr = arcpy.Describe(DDPFeature).SpatialReference arcpy.CreateFeatureclass_management (NewFeatGDB, NewDDPFeat, "POLYGON", DDPFeature, "", "", sr) #List fields copyFeatureOIDList = [] shpFld = arcpy.Describe(DDPFeature).shapeFieldName fieldNameList = [fld.name for fld in arcpy.ListFields (DDPFeature) if fld.editable and fld.name != shpFld] #Create cursor object cursor = arcpy.da.SearchCursor(DDPFeature, ["SHAPE@", "SHAPE@TRUECENTROID", "OID@"] + fieldNameList) FeatureCount = 0 for row in cursor: df.extent = row[0].extent #Check if scale is larger than maximum if df.scale * (float(MMEx) / 100) >= MaxScale: #Add OID of feature to list if feature is large enough copyFeatureOIDList.append(str(row[2])) continue FeatureCount += 1 print "Creating new feature", FeatureCount #Make x,y for four corners of extent array = arcpy.Array() FeatPnt1 = (row[1][0] + XAdjust, row[1][1] + YAdjust) FeatPnt2 = (row[1][0] + XAdjust, row[1][1] - YAdjust) FeatPnt3 = (row[1][0] - XAdjust, row[1][1] - YAdjust) FeatPnt4 = (row[1][0] - XAdjust, row[1][1] + YAdjust) pointList = [FeatPnt1, FeatPnt2, FeatPnt3, FeatPnt4] #Create each point and add to array for point in pointList: pnt = arcpy.Point(point[0], point[1]) array.add(pnt) #Add first point to array to close polygon array.add(array.getObject(0)) #Create a new polygon from array newPolygon = arcpy.Polygon(array) #Add polygon to new feature class arcpy.Append_management (newPolygon, NewFeat, "NO_TEST") #Update new feature with values oidFld = arcpy.Describe (NewFeat).OIDFieldName delimOidFld = arcpy.AddFieldDelimiters (NewFeat, oidFld) sql = "{0} = {1}".format (delimOidFld, FeatureCount) with arcpy.da.UpdateCursor(NewFeat, ["OID@", "SHAPE@", "SHAPE@TRUECENTROID"] + fieldNameList, sql) as updateCursor: for udrow in updateCursor: #Populate fields if fieldNameList: udrow[3:] = row[3:] #Shift new rectangle from centroid #(center of gravity) to spatial center FeatmidpointX = (row[0].extent.XMin + row[0].extent.XMax) / 2 FeatmidpointY = (row[0].extent.YMin + row[0].extent.YMax) / 2 NewmidpointX = (udrow[1].extent.XMin + udrow[1].extent.XMax) / 2 NewmidpointY = (udrow[1].extent.YMin + udrow[1].extent.YMax) / 2 DiffX = NewmidpointX - FeatmidpointX DiffY = NewmidpointY - FeatmidpointY udrow[2] = udrow[2][0] - DiffX, udrow[2][1] - DiffY updateCursor.updateRow(udrow) del updateCursor del row del cursor #Select all features in list if copyFeatureOIDList: if len(copyFeatureOIDList) == 1: print "Copying feature" else: print "Copying features" oidStr = ", ".join (map (str, copyFeatureOIDList)) oidFld = arcpy.Describe("DDPlyr").OIDFieldName sql = "{0} IN ({1})".format (oidFld, oidStr) arcpy.SelectLayerByAttribute_management ("DDPlyr", "", sql) #Copy selection if arcpy.Describe("DDPlyr").FIDSet: arcpy.Append_management ("DDPlyr", NewFeat) #delete temp feature arcpy.Delete_management (DDPFeature) print "Created:", NewFeat print "Done"
Hi Emil.. Im a novice at coding - trying to get your code to work on my data - getting
ReplyDeleteRuntime error
Traceback (most recent call last):
File "", line 36, in
AttributeError: DescribeData: Method shapeType does not exist
any chance you can tell me how to fix this?
btw - Im using 10.2.2
ReplyDelete