import arcpy, sys, os
class Toolbox(object):
def __init__(self):
"""Define the toolbox (the name of the toolbox is the name of the
.pyt file)."""
self.label = "Location Map Toolbox"
self.alias = "Location Map"
# List of tool classes associated with this toolbox
self.tools = [FillTitleBlock]
class FillTitleBlock(object):
def __init__(self):
"""Define the tool (tool name is the name of the class)."""
self.label = "Fill Title Block"
self.description = "Fill Title Block"
self.canRunInBackground = False
# user project data input
def getParameterInfo(self):
"""Define parameter definitions"""
#params = None
#return params
ProjectNumber= arcpy.Parameter(
displayName= "Project Number",
name= "ProjectNumber",
datatype= "GPString",
parameterType= "Required",
direction= "Input")
ProjectTitle= arcpy.Parameter(
displayName= "Project Title",
name= "ProjectTitle",
datatype= "GPString",
parameterType= "Required",
direction= "Input")
ParcelID= arcpy.Parameter(
displayName= "Parcel ID",
name= "ParcelID",
datatype= "GPString",
parameterType= "Required",
direction= "Input")
parameters= [ProjectNumber, ProjectTitle, ParcelID]
return parameters
def isLicensed(self):
"""Set whether tool is licensed to execute."""
return True
def updateParameters(self, parameters):
"""Modify the values and properties of parameters before internal
validation is performed. This method is called whenever a parameter
has been changed."""
return
def updateMessages(self, parameters):
"""Modify the messages created by internal validation for each tool
parameter. This method is called after internal validation."""
return
def execute(self, parameters, messages):
"""The source code of the tool."""
#Layout and Table of Contents variables
mxd= arcpy.mapping.MapDocument(r"G:\PCM_Jorge\LOCATION_MAPS\0-MAPS\LocationMap.mxd")
df = arcpy.mapping.ListDataFrames(mxd, "Base Map")[0]
lyr= "GIS.GISADMIN.parcels"
TAZ= "GIS.GISADMIN.TAZ_LRTP2009_2035_371"
DIS= "CommissionDistrict"
#Parameters
ProjNum= parameters[0].valueAsText
ProjTit= parameters[1].valueAsText
ParcelID= parameters[2].valueAsText
#Input title block data
for txtelem in arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT"):
if txtelem.name == "PRJ_NUM":
txtelem.text = ProjNum
elif txtelem.name == "PRJ_TIT":
txtelem.text = ProjTit
elif txtelem.name == "PID":
txtelem.text = ParcelID
#Select parcel and zoom to it
selPID= "\"VPARCEL\" = '" + ParcelID + "'"
arcpy.SelectLayerByAttribute_management(lyr, "NEW_SELECTION", selPID)
#Here comes the problem
#df.zoomToSelectedFeatures(lyr) #option 1
#without lyr, it zooms to all selected layers (below). With this argument, I get TypeError: zoomToSelectedFeatures() takes exactly 1 argument (2 given)
df.panToExtent(lyr.getSelectedExtent()) #option 2
# I get AttributeError: 'str' object has no attribute 'getSelectedExtent'
df.scale = df.scale * 1.25
arcpy.RefreshActiveView() #This used to be at the end of the script, but I moved it here hoping the layer selections below would not get zoomed to: FAIL
#Input address, TAZ, and commission district
arcpy.MakeFeatureLayer_management(lyr, "ParSel", selPID)
parLyr= arcpy.SelectLayerByLocation_management(lyr,"ARE_IDENTICAL_TO","ParSel")
rows= arcpy.SearchCursor(parLyr)
row= rows.next()
lblAddress= arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "PRJ_ADD")[0]
if row.isNull("PHYSADDR") == True:
lblAddress.text= "None found."
else:
lblAddress.text= row.getValue("PHYSADDR")
#The ancillary layers
TAZLyr= arcpy.SelectLayerByLocation_management(TAZ,"INTERSECT","ParSel")
rows= arcpy.SearchCursor(TAZLyr)
row= rows.next()
lblTAZ= arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "TAZ")[0]
lblTAZ.text= row.getValue("ctyTAZ")
DISLyr= arcpy.SelectLayerByLocation_management(DIS,"INTERSECT","ParSel")
rows= arcpy.SearchCursor(DISLyr)
row= rows.next()
lblDIS= arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "DIS")[0]
lblDIS.text= row.getValue("COMMISSION")
## mxd.saveACopy(r"C:\TEMP\\" + ProjNum + ".mxd") #directory must exist
## arcpy.mapping.ExportToPDF(mxd, r"C:\TEMP\\" + ProjNum + ".pdf")
## mxd.save() ##this will overwrite the template
del mxd, row, rows, lblAddress, lblTAZ, lblDIS,
return
arcpy.SelectLayerByAttribute_management(DISLyr, "REMOVE_FROM_SELECTION", "")
I fixed it by deselecting right after reading the ancillary layers like this:arcpy.SelectLayerByAttribute_management(DISLyr, "REMOVE_FROM_SELECTION", "")
Smells like victory!
Jorge, thanks for posting this is exactly what I need to do, (well almost). If you consider yourself a beginner, then I guess I'm a complete neophyte/idiot, but I'm hoping I can get somewhere with your starting point. What I would like to do is to have the user input a parcel ID have the map pan to that parcel at a set scale and pull the owner name and quarter section from those two tables and put that into a title box.
Are you creating a toolbox with the code or did you just create Toolbox called Location Map Toolbox and then add a new script with that same name?
In the Class FillTitleBlock does the user fill out the parameters ProjectNumber, ProjectTitle, ParcelID? How does that work?
I'm also having a hard time figuring out where I need to make changes to variables other than the obivous ones such as the .mxd. Where you specify your lyr = "GIS.GISADMIN.parcels" and your other two layers, are those just your layer names in the table of contents?
And is the title block named "TEXT_ELEMENT" in you layout?
I know that is a ton of questions but I hope you could help me out.
Andy
Jorge, thanks for posting this is exactly what I need to do, (well almost). If you consider yourself a beginner, then I guess I'm a complete neophyte/idiot, but I'm hoping I can get somewhere with your starting point. What I would like to do is to have the user input a parcel ID have the map pan to that parcel at a set scale and pull the owner name and quarter section from those two tables and put that into a title box.
Are you creating a toolbox with the code or did you just create Toolbox called Location Map Toolbox and then add a new script with that same name?
In the Class FillTitleBlock does the user fill out the parameters ProjectNumber, ProjectTitle, ParcelID? How does that work?
I'm also having a hard time figuring out where I need to make changes to variables other than the obivous ones such as the .mxd. Where you specify your lyr = "GIS.GISADMIN.parcels" and your other two layers, are those just your layer names in the table of contents?
And is the title block named "TEXT_ELEMENT" in you layout?
I know that is a ton of questions but I hope you could help me out.
Also how does the select parcel line work? Where do you get the "\" VPARCEL\" from what does that mean/do? I'm assuming that ParcelID is your field for parcel IDs in your parcel attribute table?
import arcpy, sys, os
class Toolbox(object):
def __init__(self):
"""Define the toolbox (the name of the toolbox is the name of the
.pyt file)."""
self.label = "Location Map Toolbox"
self.alias = "Location Map"
# List of tool classes associated with this toolbox
self.tools = [FillTitleBlock]
class FillTitleBlock(object):
def __init__(self):
"""Define the tool (tool name is the name of the class)."""
self.label = "Fill Title Block"
self.description = "Fill Title Block"
self.canRunInBackground = False
# user project data input
def getParameterInfo(self):
"""Define parameter definitions"""
#params = None
#return params
ProjectNumber= arcpy.Parameter(
displayName= "Project Number",
name= "ProjectNumber",
datatype= "GPString",
parameterType= "Required",
direction= "Input")
ProjectTitle= arcpy.Parameter(
displayName= "Project Title",
name= "ProjectTitle",
datatype= "GPString",
parameterType= "Required",
direction= "Input")
ParcelID= arcpy.Parameter(
displayName= "Parcel ID",
name= "ParcelID",
datatype= "GPString",
parameterType= "Required",
direction= "Input")
parameters= [ProjectNumber, ProjectTitle, ParcelID]
return parameters
def isLicensed(self):
"""Set whether tool is licensed to execute."""
return True
def updateParameters(self, parameters):
"""Modify the values and properties of parameters before internal
validation is performed. This method is called whenever a parameter
has been changed."""
return
def updateMessages(self, parameters):
"""Modify the messages created by internal validation for each tool
parameter. This method is called after internal validation."""
return
def execute(self, parameters, messages):
"""The source code of the tool."""
#Layout and Table of Contents variables
mxd= arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd, "Base Map")[0]
lyr= "GIS.GISADMIN.parcels"
ZIP= "GIS.GISADMIN.Zipcodes"
TAZ= "GIS.GISADMIN.TAZ_LRTP2009_2035_371"
DIS= "CommissionDistrict"
#Parameters
ProjNum= parameters[0].valueAsText
ProjTit= parameters[1].valueAsText
ParcelID= parameters[2].valueAsText
#Input title block data
for txtelem in arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT"):
if txtelem.name == "PRJ_NUM":
txtelem.text = ProjNum
elif txtelem.name == "PRJ_TIT":
txtelem.text = ProjTit
elif txtelem.name == "PID":
txtelem.text = ParcelID
#Select parcel and zoom to it
selPID= "\"VPARCEL\" = '" + ParcelID + "'"
arcpy.SelectLayerByAttribute_management(lyr, "NEW_SELECTION", selPID)
df.zoomToSelectedFeatures() #option 1
# Without lyr, it zooms to all selected layers (below). With this argument, I get TypeError: zoomToSelectedFeatures() takes exactly 1 argument (2 given)
#df.panToExtent(lyr.getSelectedExtent()) #option 2
# I get AttributeError: 'str' object has no attribute 'getSelectedExtent'
df.scale = df.scale * 1.25
#arcpy.RefreshActiveView() #This used to be at the end of the script, but I moved it here hoping the layer selections below would not get zoomed too: FAIL
#Input address, TAZ, and commission district
arcpy.MakeFeatureLayer_management(lyr, "ParSel", selPID)
parLyr= arcpy.SelectLayerByLocation_management(lyr,"ARE_IDENTICAL_TO","ParSel")
rows= arcpy.SearchCursor(parLyr)
row= rows.next()
lblAddress= arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "PRJ_ADD")[0]
if row.isNull("PHYSADDR") == True:
lblAddress.text= "None found."
else:
lblAddress.text= row.getValue("PHYSADDR")
#Add zip code and city--this does not work well with some properties if adjacent or accross zip bounds
## CITLyr= arcpy.SelectLayerByLocation_management(ZIP,"INTERSECT","ParSel")
## rows= arcpy.SearchCursor(CITLyr)
## row= rows.next()
## lblCIT= arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "PRJ_CIT")[0]
## lblCIT.text= row.getValue("CITY")
## arcpy.SelectLayerByAttribute_management(CITLyr, "REMOVE_FROM_SELECTION", "")
##
## ZIPLyr= arcpy.SelectLayerByLocation_management(ZIP,"INTERSECT","ParSel")
## rows= arcpy.SearchCursor(ZIPLyr)
## row= rows.next()
## lblZIP= arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "PRJ_ZIP")[0]
## lblZIP.text= row.getValue("ZIPCODE")
## arcpy.SelectLayerByAttribute_management(ZIPLyr, "REMOVE_FROM_SELECTION", "")
TAZLyr= arcpy.SelectLayerByLocation_management(TAZ,"INTERSECT","ParSel")
list= []
lblTAZ= arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "TAZ")[0]
rows= arcpy.SearchCursor(TAZLyr)
row= rows.next()
while row:
ParTAZ= row.getValue("ctyTAZ")
list.append(ParTAZ)
row= rows.next()
lblTAZ.text= str(list).translate(None, '[]')
arcpy.SelectLayerByAttribute_management(TAZLyr, "REMOVE_FROM_SELECTION", "")
DISLyr= arcpy.SelectLayerByLocation_management(DIS,"INTERSECT","ParSel")
rows= arcpy.SearchCursor(DISLyr)
row= rows.next()
lblDIS= arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "COM")[0]
lblDIS.text= row.getValue("DISTRICT")
arcpy.SelectLayerByAttribute_management(DISLyr, "REMOVE_FROM_SELECTION", "")
arcpy.RefreshActiveView()
mxd.saveACopy(r"G:\PCM_Jorge\LOCATION_MAPS\0-MAPS\\" + ProjNum + ".mxd") #directory must exist
arcpy.mapping.ExportToPDF(mxd, r"G:\PCM_Jorge\LOCATION_MAPS\0-MAPS\PDF\\" + ProjNum + ".pdf")
## mxd.save() ##this will overwrite the template
del mxd, row, rows, lblAddress, lblTAZ, lblDIS,
return