├── Add_Ins
├── Add_Ins.esriaddin
├── Images
│ ├── Database 1.png
│ ├── LayoutIcon.png
│ ├── LayoutToolbar.png
│ ├── PDFexport.png
│ ├── Textbox.png
│ ├── Thumbs.db
│ ├── button_grey_record.png
│ ├── restoreLayout.png
│ └── world.png
├── Install
│ └── Add_Ins_addin.py
├── README.md
├── README.txt
├── config.xml
└── makeaddin.py
├── Annotation
├── Annotation.esriaddin
├── Images
│ ├── Thumbs.db
│ ├── bw-annotate.png
│ ├── glyphicons-100-vector-path-all.png
│ └── letterA.png
├── Install
│ └── Annotation_addin.py
├── README.txt
├── config.xml
├── makeaddin.py
└── py
│ ├── TiledAnno.py
│ ├── dataFrameExtentPolygons.py
│ └── dataFrameExtentPolygons_SinglePage.py
├── Annotation_Stand_Alone
├── Annotation_Cmd-SingleDF.py
└── Annotation_Cmd.py
├── Cycle_Drives
├── Cycle_Drives.esriaddin
├── Images
│ ├── cycle.png
│ └── switch.png
├── Install
│ └── Cycle_Drives_addin.py
├── README.txt
├── config.xml
└── makeaddin.py
├── Dynamic_Elements
├── Dynamic_Elements.esriaddin
├── Images
│ ├── Textbox.png
│ └── eye-chart.png
├── Install
│ ├── Dynamic_Elements_addin.py
│ └── svaBoxSizing.py
├── README.txt
├── config.xml
└── makeaddin.py
├── Functions
├── adjustElementsFunctions.py
├── clearAllQueries.py
├── clearSelectedLayerQuery.py
├── genericCmdPrompt.py
├── getSelectionSet.py
└── querySelection.py
├── Layers
├── Images
│ ├── 45.png
│ ├── 45_1.png
│ ├── Thumbs.db
│ ├── computerscreen5.png
│ ├── dropdown.gif
│ └── maps-and-geolocation-layers-icon.png
├── Install
│ ├── Layers_addin.py
│ ├── __init__.py
│ ├── autoPath.py
│ └── createDefaultLyrs.py
├── Layers.esriaddin
├── README.txt
├── config.xml
└── makeaddin.py
├── PDF_Export_Addin
├── Images
│ ├── Thumbs.db
│ ├── cmyk.png
│ ├── cube-128.png
│ ├── draftIcon.png
│ ├── pdf-icon.png
│ └── rgb.png
├── Install
│ └── PDF_Export_Addin_addin.py
├── PDF_Export_Addin.esriaddin
├── README.txt
├── config.xml
└── makeaddin.py
├── PDF_Export_Stand_Alone
└── PDF_Export_Cmd.py
├── Page Layout Table
├── PageLayoutElements.cpg
├── PageLayoutElements.dbf.xml
└── info
│ └── arc.dir
├── Python
├── AnnoQuery.py
├── BrokenDataSources.py
├── ExtentBoxexRemovePts.py
├── RepairBrokenLayers.py
├── SDE_to_FGDB_BuiltInList.py
├── SelectCommunities.py
├── SelectPointsInTargetED.py
├── StripDataFromMXD.py
├── _template.py
├── batchRename.py
├── dataFrameExtentPolygons.py
├── dataFrameExtentPolygonsModified.py
├── dataframePolygon.cpg
├── dataframePolygon.dbf
├── dataframePolygon.sbn
├── dataframePolygon.sbx
├── dataframePolygon.shp
├── dataframePolygon.shp.xml
├── dataframePolygon.shx
├── dataframePolygonsY_sq.cpg
├── dataframePolygonsY_sq.dbf
├── dataframePolygonsY_sq.sbn
├── dataframePolygonsY_sq.sbx
├── dataframePolygonsY_sq.shp
├── dataframePolygonsY_sq.shp.xml
├── dataframePolygonsY_sq.shx
├── dfScaleMatch.py
├── nameElements.py
├── orginalGetSettings.py
└── writeScaleRotation.py
├── QuerySelection
├── Images
│ ├── ClearQueryCube.png
│ ├── EDHighlight.png
│ ├── Thumbs.db
│ └── spatialQuery.png
├── Install
│ ├── QuerySelection_addin.py
│ ├── clearAllQueries.py
│ ├── clearSelectedLayerQuery.py
│ ├── getSelectionSet.py
│ └── querySelected.py
├── QuerySelection.esriaddin
├── README.txt
├── config.xml
└── makeaddin.py
├── README.md
├── SDE_Replication
└── ReplicateSDE.py
├── SQL
├── PrelimReport87EDs_web.dbf
├── PrelimReport87EDs_web.prj
├── PrelimReport87EDs_web.shp
├── PrelimReport87EDs_web.shx
├── createViewSDE.sql
└── tcn_road_type_QUERY.txt
├── XY
└── shpToTxtCoords.py
└── addin-wizard
├── .hgtags
├── AddinMaker.wxg
├── LICENSE
├── README.md
├── addin.py
├── addin_assistant.pyw
├── addin_ui.py
├── i18n.py
├── images
├── AddInDesktop.ico
├── AddInDesktop48.png
├── AddInDesktop64.png
└── Thumbs.db
├── packaging
├── README.txt
└── makeaddin.py
├── resources
└── resource_strings.json
└── setup.py
/Add_Ins/Add_Ins.esriaddin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Add_Ins/Add_Ins.esriaddin
--------------------------------------------------------------------------------
/Add_Ins/Images/Database 1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Add_Ins/Images/Database 1.png
--------------------------------------------------------------------------------
/Add_Ins/Images/LayoutIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Add_Ins/Images/LayoutIcon.png
--------------------------------------------------------------------------------
/Add_Ins/Images/LayoutToolbar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Add_Ins/Images/LayoutToolbar.png
--------------------------------------------------------------------------------
/Add_Ins/Images/PDFexport.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Add_Ins/Images/PDFexport.png
--------------------------------------------------------------------------------
/Add_Ins/Images/Textbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Add_Ins/Images/Textbox.png
--------------------------------------------------------------------------------
/Add_Ins/Images/Thumbs.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Add_Ins/Images/Thumbs.db
--------------------------------------------------------------------------------
/Add_Ins/Images/button_grey_record.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Add_Ins/Images/button_grey_record.png
--------------------------------------------------------------------------------
/Add_Ins/Images/restoreLayout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Add_Ins/Images/restoreLayout.png
--------------------------------------------------------------------------------
/Add_Ins/Images/world.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Add_Ins/Images/world.png
--------------------------------------------------------------------------------
/Add_Ins/README.md:
--------------------------------------------------------------------------------
1 | # Arcpy
2 | ESRI Arcpy scripts.
3 |
--------------------------------------------------------------------------------
/Add_Ins/README.txt:
--------------------------------------------------------------------------------
1 | This is a stub project created by the ArcGIS Desktop Python AddIn Wizard.
2 |
3 | MANIFEST
4 | ========
5 |
6 | README.txt : This file
7 |
8 | makeaddin.py : A script that will create a .esriaddin file out of this
9 | project, suitable for sharing or deployment
10 |
11 | config.xml : The AddIn configuration file
12 |
13 | Images/* : all UI images for the project (icons, images for buttons,
14 | etc)
15 |
16 | Install/* : The Python project used for the implementation of the
17 | AddIn. The specific python script to be used as the root
18 | module is specified in config.xml.
19 |
--------------------------------------------------------------------------------
/Add_Ins/config.xml:
--------------------------------------------------------------------------------
1 | Content & Layout Helper {cbf16477-d233-4a5d-b9bc-b57c11874d8c} DDP layout helper tools 1.0 Images\LayoutIcon.png James Stephaniuk Elections BC 12/11/2015
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/Add_Ins/makeaddin.py:
--------------------------------------------------------------------------------
1 | import os
2 | import re
3 | import zipfile
4 |
5 | current_path = os.path.dirname(os.path.abspath(__file__))
6 |
7 | out_zip_name = os.path.join(current_path,
8 | os.path.basename(current_path) + ".esriaddin")
9 |
10 | BACKUP_FILE_PATTERN = re.compile(".*_addin_[0-9]+[.]py$", re.IGNORECASE)
11 |
12 | def looks_like_a_backup(filename):
13 | return bool(BACKUP_FILE_PATTERN.match(filename))
14 |
15 | with zipfile.ZipFile(out_zip_name, 'w', zipfile.ZIP_DEFLATED) as zip_file:
16 | for filename in ('config.xml', 'README.txt', 'makeaddin.py'):
17 | zip_file.write(os.path.join(current_path, filename), filename)
18 | dirs_to_add = ['Images', 'Install']
19 | for directory in dirs_to_add:
20 | for (path, dirs, files) in os.walk(os.path.join(current_path,
21 | directory)):
22 | archive_path = os.path.relpath(path, current_path)
23 | found_file = False
24 | for file in (f for f in files if not looks_like_a_backup(f)):
25 | archive_file = os.path.join(archive_path, file)
26 | print archive_file
27 | zip_file.write(os.path.join(path, file), archive_file)
28 | found_file = True
29 | if not found_file:
30 | zip_file.writestr(os.path.join(archive_path,
31 | 'placeholder.txt'),
32 | "(Empty directory)")
33 |
--------------------------------------------------------------------------------
/Annotation/Annotation.esriaddin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Annotation/Annotation.esriaddin
--------------------------------------------------------------------------------
/Annotation/Images/Thumbs.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Annotation/Images/Thumbs.db
--------------------------------------------------------------------------------
/Annotation/Images/bw-annotate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Annotation/Images/bw-annotate.png
--------------------------------------------------------------------------------
/Annotation/Images/glyphicons-100-vector-path-all.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Annotation/Images/glyphicons-100-vector-path-all.png
--------------------------------------------------------------------------------
/Annotation/Images/letterA.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Annotation/Images/letterA.png
--------------------------------------------------------------------------------
/Annotation/Install/Annotation_addin.py:
--------------------------------------------------------------------------------
1 | import arcpy
2 | import os
3 | import pythonaddins
4 |
5 | class ExtentBoxes(object):
6 | """Implementation for Annotation_addin.extentBoxes (Button)"""
7 | def __init__(self):
8 | self.enabled = True
9 | self.checked = False
10 | def onClick(self):
11 | import arcpy
12 | import os
13 | import pythonaddins
14 |
15 | # Restore Page Layout (from PageLayoutElements table) before running this script.
16 | mxd = arcpy.mapping.MapDocument('CURRENT')
17 | ddp = mxd.dataDrivenPages
18 | pageName = str(ddp.pageRow.getValue(ddp.pageNameField.name))
19 | df_lst = arcpy.mapping.ListDataFrames(mxd)
20 | onMapDFs = []
21 | # List of data frames on the current page.
22 | for df in df_lst:
23 | if (df.elementPositionX > 0 and df.elementPositionX < mxd.pageSize[0] and df.elementPositionY > 0 and df.elementPositionY < mxd.pageSize[1]):
24 | onMapDFs.append(df)
25 |
26 | feature_info = []
27 | for df in onMapDFs:
28 | # Only creates geometry for data frames on the page. Also creates FGDB.
29 | XMin = df.extent.XMin
30 | YMin = df.extent.YMin
31 | XMax = df.extent.XMax
32 | YMax = df.extent.YMax
33 | # A list of features and coordinate pairs
34 | df_info = [[XMin, YMin],[XMax, YMin],[XMax, YMax],[XMin, YMax]]
35 | feature_info.append(df_info)
36 |
37 | # A list that will hold each of the Polygon objects
38 | features = []
39 | for feature in feature_info:
40 | # Create a Polygon object based on the array of points
41 | # Append to the list of Polygon objects
42 | features.append(arcpy.Polygon(arcpy.Array([arcpy.Point(*coords) for coords in feature])))
43 |
44 |
45 | # Persist a copy of the Polygon objects using CopyFeatures
46 | poly_filename = "DF_Polygons_{}".format(pageName)
47 | parentDir = os.path.abspath(os.path.join(os.path.dirname(mxd.filePath), os.pardir))
48 | edDir = os.path.join(parentDir, pageName)
49 | if not os.path.exists(edDir):
50 | os.makedirs(edDir)
51 | outDir = os.path.join(edDir, "anno_fgdb")
52 | if not os.path.exists(outDir):
53 | os.makedirs(outDir)
54 | workspace = arcpy.env.workspace = outDir
55 |
56 | arcpy.CopyFeatures_management(features, poly_filename)
57 |
58 | # Create FGDB(s).
59 | for df in onMapDFs:
60 | arcpy.CreateFileGDB_management(workspace, "{}_{}_{}_extentBoxes".format(pageName, df.name, str(int(round(df.scale)))), "CURRENT")
61 |
62 | del coords, feature_info, features, feature, poly_filename, outDir, mxd, df_lst, df_info, df, XMax, XMin, YMax, YMin, ddp, pageName
63 |
64 | class GenerateTiledAnno(object):
65 | """Implementation for Annotation_addin.tiledAnno (Button)"""
66 | def __init__(self):
67 | self.enabled = True
68 | self.checked = False
69 | def onClick(self):
70 | import arcpy
71 | import os
72 |
73 | mxd = arcpy.mapping.MapDocument("CURRENT")
74 | ddp = mxd.dataDrivenPages
75 | pageName = str(ddp.pageRow.getValue(ddp.pageNameField.name))
76 | df_lst = arcpy.mapping.ListDataFrames(mxd)
77 | onMapDFs = []
78 | # List of data frames on the current page.
79 | for df in df_lst:
80 | if (df.elementPositionX > 0 and df.elementPositionX < mxd.pageSize[0] and df.elementPositionY > 0 and df.elementPositionY < mxd.pageSize[1]):
81 | onMapDFs.append(df)
82 |
83 | GroupAnno = "GroupAnno"
84 | anno_suffix = "Anno"
85 | indexLyrName = "DF_Polygons_{}".format(pageName)
86 | tileIndexPoly = arcpy.mapping.ListLayers(mxd, indexLyrName)[0]
87 |
88 | parentDir = os.path.abspath(os.path.join(os.path.dirname(mxd.filePath), os.pardir))
89 | workspace = arcpy.env.workspace = os.path.join(parentDir, pageName, "anno_fgdb")
90 |
91 | for df in onMapDFs:
92 | # arcpy.activeView = df.name
93 | try:
94 | fgdb = os.path.join(workspace, "{}_{}_{}_extentBoxes.gdb".format(pageName, str(df.name), int(round(df.scale))))
95 | if os.path.exists(fgdb):
96 | arcpy.TiledLabelsToAnnotation_cartography(
97 | mxd.filePath,
98 | str(df.name),
99 | tileIndexPoly,
100 | fgdb,
101 | GroupAnno + str(df.name) + "_",
102 | anno_suffix,
103 | round(df.scale),
104 | feature_linked="STANDARD",
105 | generate_unplaced_annotation="GENERATE_UNPLACED_ANNOTATION")
106 | except Exception as e:
107 | print e
108 |
109 | # Turn off all labels.
110 | for lyr in arcpy.mapping.ListLayers(mxd):
111 | if lyr.supports("LABELCLASSES"):
112 | lyr.showLabels = False
113 |
114 | for df in df_lst:
115 | # Remove DF Polygons.
116 | for lyr in arcpy.mapping.ListLayers(mxd,"", df):
117 | if lyr.name.lower().startswith("df_polygons"):
118 | arcpy.mapping.RemoveLayer(df, lyr)
119 |
120 | # Remove empty annotation groups.
121 | groupLayers = [x for x in arcpy.mapping.ListLayers(mxd) if x.isGroupLayer and GroupAnno in x.name]
122 | for group in groupLayers:
123 | count = 0
124 | for item in group:
125 | count += 1
126 | if count == 0:
127 | arcpy.mapping.RemoveLayer(df, group)
128 |
129 | del anno_suffix, ddp, df, df_lst, fgdb, GroupAnno, indexLyrName, lyr, mxd, onMapDFs, pageName, parentDir, tileIndexPoly, groupLayers
--------------------------------------------------------------------------------
/Annotation/README.txt:
--------------------------------------------------------------------------------
1 | This is a stub project created by the ArcGIS Desktop Python AddIn Wizard.
2 |
3 | MANIFEST
4 | ========
5 |
6 | README.txt : This file
7 |
8 | makeaddin.py : A script that will create a .esriaddin file out of this
9 | project, suitable for sharing or deployment
10 |
11 | config.xml : The AddIn configuration file
12 |
13 | Images/* : all UI images for the project (icons, images for buttons,
14 | etc)
15 |
16 | Install/* : The Python project used for the implementation of the
17 | AddIn. The specific python script to be used as the root
18 | module is specified in config.xml.
19 |
--------------------------------------------------------------------------------
/Annotation/config.xml:
--------------------------------------------------------------------------------
1 | Annotation {ce0c5f3a-82f6-4160-8eb9-ab41f45ec2ef} Generate tiled annotation for data driven pages and insets. 1.0 Images\letterA.png James Stephaniuk EBC 12/11/2015
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Annotation/makeaddin.py:
--------------------------------------------------------------------------------
1 | import os
2 | import re
3 | import zipfile
4 |
5 | current_path = os.path.dirname(os.path.abspath(__file__))
6 |
7 | out_zip_name = os.path.join(current_path,
8 | os.path.basename(current_path) + ".esriaddin")
9 |
10 | BACKUP_FILE_PATTERN = re.compile(".*_addin_[0-9]+[.]py$", re.IGNORECASE)
11 |
12 | def looks_like_a_backup(filename):
13 | return bool(BACKUP_FILE_PATTERN.match(filename))
14 |
15 | with zipfile.ZipFile(out_zip_name, 'w', zipfile.ZIP_DEFLATED) as zip_file:
16 | for filename in ('config.xml', 'README.txt', 'makeaddin.py'):
17 | zip_file.write(os.path.join(current_path, filename), filename)
18 | dirs_to_add = ['Images', 'Install']
19 | for directory in dirs_to_add:
20 | for (path, dirs, files) in os.walk(os.path.join(current_path,
21 | directory)):
22 | archive_path = os.path.relpath(path, current_path)
23 | found_file = False
24 | for file in (f for f in files if not looks_like_a_backup(f)):
25 | archive_file = os.path.join(archive_path, file)
26 | print archive_file
27 | zip_file.write(os.path.join(path, file), archive_file)
28 | found_file = True
29 | if not found_file:
30 | zip_file.writestr(os.path.join(archive_path,
31 | 'placeholder.txt'),
32 | "(Empty directory)")
33 |
--------------------------------------------------------------------------------
/Annotation/py/TiledAnno.py:
--------------------------------------------------------------------------------
1 | import arcpy
2 | import os
3 |
4 | mxd = arcpy.mapping.MapDocument("CURRENT")
5 | ddp = mxd.dataDrivenPages
6 | pageName = ddp.pageRow.getValue(ddp.pageNameField.name)
7 | df_lst = arcpy.mapping.ListDataFrames(mxd)
8 | onMapDFs = []
9 | # List of data frames on the current page.
10 | for df in df_lst:
11 | if (df.elementPositionX > 0 and df.elementPositionX < mxd.pageSize[0] and df.elementPositionY > 0 and df.elementPositionY < mxd.pageSize[1]):
12 | onMapDFs.append(df)
13 |
14 | GroupAnno = "GroupAnno"
15 | anno_suffix = "Anno"
16 | indexLyrName = "DF_Polygons_{}".format(pageName)
17 | tileIndexPoly = arcpy.mapping.ListLayers(mxd, indexLyrName)[0]
18 |
19 | parentDir = os.path.abspath(os.path.join(os.path.dirname(mxd.filePath), os.pardir))
20 | workspace = arcpy.env.workspace = os.path.join(parentDir, "anno_fgdb")
21 |
22 | for df in onMapDFs:
23 | # arcpy.activeView = df.name
24 | try:
25 | fgdb = os.path.join(workspace, "{}_{}_{}.gdb".format(pageName, str(df.name), int(round(df.scale))))
26 | if os.path.exists(fgdb):
27 | arcpy.TiledLabelsToAnnotation_cartography(mxd.filePath, str(df.name), tileIndexPoly, fgdb, GroupAnno + str(df.name) + "_", anno_suffix, round(df.scale), "", "", "", "", "STANDARD", "GENERATE_UNPLACED_ANNOTATION")
28 | except Exception as e:
29 | print e
30 |
31 | # Turn off all labels.
32 | for lyr in arcpy.mapping.ListLayers(mxd):
33 | if lyr.supports("LABELCLASSES"):
34 | lyr.showLabels = False
35 |
36 | # Remove DF Polygons.
37 | for df in df_lst:
38 | for lyr in arcpy.mapping.ListLayers(mxd,"", df):
39 | if lyr.name.lower().startswith("df_polygons"):
40 | arcpy.mapping.RemoveLayer(df, lyr)
41 |
42 | del anno_suffix, ddp, df, df_lst, fgdb, GroupAnno, indexLyrName, lyr, mxd, onMapDFs, pageName, parentDir, tileIndexPoly
--------------------------------------------------------------------------------
/Annotation/py/dataFrameExtentPolygons.py:
--------------------------------------------------------------------------------
1 | import arcpy, json, os, sys
2 |
3 | #Function that arranges data frames based on the field info within the PageLayoutElements table
4 | def arrangeDFs(row, dfName):
5 | rowInfo = json.loads(row.getValue(dfName))
6 | try:
7 | df = arcpy.mapping.ListDataFrames(mxd, dfName)[0]
8 | df.elementPositionX = rowInfo[0]
9 | df.elementPositionY = rowInfo[1]
10 | df.elementWidth = rowInfo[2]
11 | df.elementHeight = rowInfo[3]
12 | newExtent = df.extent
13 | newExtent.XMin = rowInfo[4]
14 | newExtent.YMin = rowInfo[5]
15 | newExtent.XMax = rowInfo[6]
16 | newExtent.YMax = rowInfo[7]
17 | df.extent = newExtent
18 | df.scale = rowInfo[8]
19 | df.rotation = rowInfo[9]
20 | except IndexError:
21 | pass
22 |
23 | ################################################################################
24 |
25 | mxd = arcpy.mapping.MapDocument('CURRENT')
26 | ddp = mxd.dataDrivenPages
27 | inset = "Inset" + "1" # Change value to '1', '2', '3', or '4' to control which inset polygons are made for.
28 | df_lst = arcpy.mapping.ListDataFrames(mxd, inset)
29 |
30 | feature_info = []
31 |
32 | # Determine page orientation to append to output filename. Fallback to DDP count.
33 | if mxd.pageSize.width > mxd.pageSize.height:
34 | orient = "_L_"
35 | elif mxd.pageSize.width < mxd.pageSize.height:
36 | orient = "_P_"
37 | else:
38 | orient = "square"
39 |
40 | # Loop each DDP.
41 | for page in range(1, ddp.pageCount + 1):
42 | ddp.currentPageID = page
43 | # ArrangeDFs.
44 | pageName = ddp.pageRow.getValue(ddp.pageNameField.name)
45 | pageLayoutTable = arcpy.mapping.ListTableViews(mxd, "PageLayoutElements")[0] #Reference pageLayoutTable
46 | #Move all data frames off the layout and into their default positions
47 | pageLayoutCursor = arcpy.SearchCursor(pageLayoutTable.dataSource, "District = '" + pageName + "'")
48 | pageLayoutRow = pageLayoutCursor.next()
49 |
50 | for df in df_lst:
51 | arrangeDFs(pageLayoutRow, df.name)
52 | # Only creates geometry for data frames on the page.
53 | if (df.elementPositionX > 0 and df.elementPositionX < 11 and
54 | df.elementPositionY > 0 and df.elementPositionY < 8.5):
55 | XMin = df.extent.XMin
56 | YMin = df.extent.YMin
57 | XMax = df.extent.XMax
58 | YMax = df.extent.YMax
59 | # A list of features and coordinate pairs
60 | df_info = [[XMin, YMin],[XMax, YMin],[XMax, YMax],[XMin, YMax]]
61 | feature_info.append(df_info)
62 |
63 | # A list that will hold each of the Polygon objects
64 | features = []
65 |
66 | for feature in feature_info:
67 | # Create a Polygon object based on the array of points
68 | # Append to the list of Polygon objects
69 | features.append(
70 | arcpy.Polygon(
71 | arcpy.Array([arcpy.Point(*coords) for coords in feature])))
72 |
73 | # Persist a copy of the Polygon objects using CopyFeatures
74 | outDir = r"P:\15045 - ED Redistribution - Event Specific\R2015\21-Electoral_Boundaries_Commission_Support_Doc\WBS 8 - Geography\James\DataFrame_Polygon_Boxes"
75 | poly_filename = outDir + r"/dataframePolygons" + orient + inset + ".shp"
76 | if os.path.exists(poly_filename):
77 | os.remove(poly_filename)
78 | arcpy.CopyFeatures_management(features, poly_filename)
79 |
80 | del coords, feature_info, features, feature, poly_filename, outDir, mxd, df_lst, df_info, df, inset, XMax, XMin, YMax, YMin, page, orient, ddp, pageName, pageLayoutCursor, pageLayoutTable, pageLayoutRow
--------------------------------------------------------------------------------
/Annotation/py/dataFrameExtentPolygons_SinglePage.py:
--------------------------------------------------------------------------------
1 | import arcpy
2 | import os
3 | import pythonaddins
4 |
5 | # Restore Page Layout (from PageLayoutElements table) before running this script.
6 |
7 | mxd = arcpy.mapping.MapDocument('CURRENT')
8 | ddp = mxd.dataDrivenPages
9 | pageName = ddp.pageRow.getValue(ddp.pageNameField.name)
10 | df_lst = arcpy.mapping.ListDataFrames(mxd)
11 | onMapDFs = []
12 | # List of data frames on the current page.
13 | for df in df_lst:
14 | if (df.elementPositionX > 0 and df.elementPositionX < mxd.pageSize[0] and df.elementPositionY > 0 and df.elementPositionY < mxd.pageSize[1]):
15 | onMapDFs.append(df)
16 |
17 | feature_info = []
18 | for df in onMapDFs:
19 | # Only creates geometry for data frames on the page. Also creates FGDB.
20 | XMin = df.extent.XMin
21 | YMin = df.extent.YMin
22 | XMax = df.extent.XMax
23 | YMax = df.extent.YMax
24 | # A list of features and coordinate pairs
25 | df_info = [[XMin, YMin],[XMax, YMin],[XMax, YMax],[XMin, YMax]]
26 | feature_info.append(df_info)
27 |
28 | # A list that will hold each of the Polygon objects
29 | features = []
30 | for feature in feature_info:
31 | # Create a Polygon object based on the array of points
32 | # Append to the list of Polygon objects
33 | features.append(arcpy.Polygon(arcpy.Array([arcpy.Point(*coords) for coords in feature])))
34 |
35 |
36 | # Persist a copy of the Polygon objects using CopyFeatures
37 | poly_filename = "DF_Polygons_{}".format(pageName)
38 | parentDir = os.path.abspath(os.path.join(os.path.dirname(mxd.filePath), os.pardir))
39 | outDir = os.path.join(parentDir, "anno_fgdb")
40 | if not os.path.exists(outDir):
41 | os.makedirs(outDir)
42 | workspace = arcpy.env.workspace = outDir
43 |
44 | arcpy.CopyFeatures_management(features, poly_filename)
45 |
46 | # Create FGDB(s).
47 | for df in onMapDFs:
48 | arcpy.CreateFileGDB_management(workspace, "{}_{}_{}".format(pageName, df.name, str(int(round(df.scale)))), "CURRENT")
49 |
50 | del coords, feature_info, features, feature, poly_filename, outDir, mxd, df_lst, df_info, df, XMax, XMin, YMax, YMin, ddp, pageName
51 |
52 |
--------------------------------------------------------------------------------
/Annotation_Stand_Alone/Annotation_Cmd-SingleDF.py:
--------------------------------------------------------------------------------
1 | #############################################################################
2 | # The MIT License (MIT)
3 | #
4 | # Copyright (c) 2015 James Stephaniuk
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | # SOFTWARE.
23 | #
24 | #############################################################################
25 | # Usage: Run this script from the command line.
26 | # Navigate to this script's folder in the command line and type:
27 | # python [script name] "[mxd path]".
28 | #
29 | ##############################################################################
30 |
31 | import arcpy
32 | import datetime
33 | import getpass
34 | import glob
35 | import logging
36 | import logging.handlers
37 | import os
38 | import shutil
39 | import sys
40 | import time
41 |
42 |
43 | def query_yes_no(question, default="no"):
44 | """Ask a yes/no question via raw_input() and return their answer.
45 |
46 | "question" is a string that is presented to the user.
47 | "default" is the presumed answer if the user just hits .
48 | It must be "yes" (the default), "no" or None (meaning
49 | an answer is required of the user).
50 |
51 | The "answer" return value is one of "yes" or "no".
52 | """
53 | valid = {"yes": "yes", "y": "yes", "ye": "yes",
54 | "no": "no", "n": "no"}
55 | if default is None:
56 | prompt = " [y/n] "
57 | elif default == "yes":
58 | prompt = " [Y/n] "
59 | elif default == "no":
60 | prompt = " [y/N] "
61 | else:
62 | raise ValueError("invalid default answer: '%s'" % default)
63 |
64 | while 1:
65 | sys.stdout.write(question + prompt)
66 | choice = raw_input().lower()
67 | if default is not None and choice == '':
68 | return default
69 | elif choice in valid.keys():
70 | return valid[choice]
71 | else:
72 | sys.stdout.write("Please respond with 'yes' or 'no' "
73 | "(or 'y' or 'n').\n")
74 |
75 |
76 | def removeFGDBs(ws):
77 | """Remove existing FGDB(s) in workspace."""
78 | for gdb in arcpy.ListFiles("*.gdb"):
79 | gdb_path = os.path.join(ws, gdb)
80 | shutil.rmtree(gdb_path)
81 |
82 |
83 | def createFGDBs(onMapDFs, workspace):
84 | """Create FGDB(s) to store annotation for each dataframe."""
85 | for df in onMapDFs:
86 | fgdb = os.path.join(workspace, "{}_{}_{}.gdb".format(pageName, df.name, str(int(round(df.scale)))))
87 | if os.path.exists(fgdb):
88 | shutil.rmtree(fgdb)
89 | arcpy.CreateFileGDB_management(workspace, "{}_{}_{}".format(pageName, df.name, str(int(round(df.scale)))), "CURRENT")
90 | log.info("FGDB created: {}".format(fgdb))
91 |
92 |
93 | def createExtentBoxes(mxdPath):
94 | try:
95 | # Restore Page Layout (from PageLayoutElements table) before running this script.
96 | mxd = arcpy.mapping.MapDocument(mxdPath)
97 | ddp = mxd.dataDrivenPages
98 | pageName = str(ddp.pageRow.getValue(ddp.pageNameField.name))
99 | df_lst = arcpy.mapping.ListDataFrames(mxd)
100 |
101 | # Set the main dataframe variable.
102 | try:
103 | MDF = arcpy.mapping.ListDataFrames(mxd, "MDF")[0]
104 | except IndexError:
105 | MDF = arcpy.mapping.ListDataFrames(mxd)[0]
106 |
107 | log.info("MXD path: {}".format(mxd.filePath))
108 | log.info("Page Name: {}".format(pageName))
109 |
110 | onMapDFs = []
111 | # List of data frames on the current page.
112 | for df in df_lst:
113 | if (df.elementPositionX > 0 and df.elementPositionX < mxd.pageSize[0] and df.elementPositionY > 0 and df.elementPositionY < mxd.pageSize[1]):
114 | onMapDFs.append(df)
115 |
116 | feature_info = []
117 |
118 | XMin = MDF.extent.XMin
119 | YMin = MDF.extent.YMin
120 | XMax = MDF.extent.XMax
121 | YMax = MDF.extent.YMax
122 | # A list of features and coordinate pairs
123 | df_info = [[XMin, YMin], [XMax, YMin], [XMax, YMax], [XMin, YMax]]
124 | feature_info.append(df_info)
125 |
126 | # A list that will hold each of the Polygon objects
127 | features = []
128 | for feature in feature_info:
129 | # Create a Polygon object based on the array of points
130 | # Append to the list of Polygon objects
131 | features.append(arcpy.Polygon(arcpy.Array([arcpy.Point(*coords) for coords in feature])))
132 |
133 | # Persist a copy of the Polygon objects using CopyFeatures
134 | poly_filename = "DF_Polygons_{}".format(pageName)
135 | parentDir = os.path.abspath(os.path.join(os.path.dirname(mxd.filePath), os.pardir))
136 | edDir = os.path.join(parentDir, pageName)
137 | outDir = os.path.join(edDir, "anno_fgdb")
138 | if not os.path.exists(outDir):
139 | os.makedirs(outDir)
140 | workspace = arcpy.env.workspace = outDir
141 | log.info("Output directory set to {}".format(outDir))
142 |
143 | poly_shp = os.path.join(workspace, poly_filename)
144 | for filename in glob.glob(poly_shp + "*"):
145 | os.remove(filename)
146 |
147 | arcpy.CopyFeatures_management(features, poly_filename)
148 |
149 | removeFGDBs(workspace)
150 | createFGDBs(onMapDFs, workspace)
151 |
152 | del coords, feature_info, features, feature, poly_filename, outDir, mxd, df_info, XMax, XMin, YMax, YMin, ddp, pageName
153 | except Exception as e:
154 | log.info("An error occured: {}".format(e))
155 |
156 |
157 | def generateTiledAnno(mxdPath):
158 | mxd = arcpy.mapping.MapDocument(mxdPath)
159 | ddp = mxd.dataDrivenPages
160 | pageName = str(ddp.pageRow.getValue(ddp.pageNameField.name))
161 | df_lst = arcpy.mapping.ListDataFrames(mxd)
162 |
163 | # List of data frames on the current page.
164 | onMapDFs = []
165 | for df in df_lst:
166 | if (df.elementPositionX > 0 and df.elementPositionX < mxd.pageSize[0] and df.elementPositionY > 0 and df.elementPositionY < mxd.pageSize[1]):
167 | onMapDFs.append(df)
168 |
169 | parentDir = os.path.abspath(os.path.join(os.path.dirname(mxd.filePath), os.pardir))
170 | workspace = arcpy.env.workspace = os.path.join(parentDir, pageName, "anno_fgdb")
171 |
172 | indexFC = arcpy.ListFeatureClasses("DF_Polygons*")[0]
173 | tileIndexPoly = os.path.join(workspace, indexFC)
174 | GroupAnno = "GroupAnno"
175 | anno_suffix = "Anno"
176 |
177 | for df in onMapDFs:
178 | # arcpy.activeView = df.name
179 | try:
180 | fgdb = os.path.join(workspace, "{}_{}_{}.gdb".format(pageName, str(df.name), int(round(df.scale))))
181 | if os.path.exists(fgdb):
182 | arcpy.TiledLabelsToAnnotation_cartography(
183 | mxd.filePath,
184 | str(df.name),
185 | str(tileIndexPoly),
186 | fgdb,
187 | GroupAnno + str(df.name) + "_",
188 | anno_suffix,
189 | round(df.scale),
190 | feature_linked="STANDARD",
191 | generate_unplaced_annotation="NOT_GENERATE_UNPLACED_ANNOTATION")
192 | log.info("Tiled Annotation Created at {}".format(fgdb))
193 | else:
194 | log.info("{} DOES NOT EXIST".format(fgdb))
195 |
196 | except Exception as e:
197 | log.info(e)
198 |
199 |
200 | def formatTime(x):
201 | minutes, seconds_rem = divmod(x, 60)
202 | if minutes >= 60:
203 | hours, minutes_rem = divmod(minutes, 60)
204 | return "%02d:%02d:%02d" % (hours, minutes_rem, seconds_rem)
205 | else:
206 | minutes, seconds_rem = divmod(x, 60)
207 | return "00:%02d:%02d" % (minutes, seconds_rem)
208 |
209 |
210 | def getPageName(mxdPath):
211 | mxd = arcpy.mapping.MapDocument(mxdPath)
212 | ddp = mxd.dataDrivenPages
213 | pageName = ddp.pageRow.getValue(ddp.pageNameField.name)
214 | return str(pageName)
215 |
216 | ##############################################################################
217 |
218 | if __name__ == "__main__":
219 | startTime = time.time()
220 | now = datetime.datetime.now()
221 |
222 | ############################ USER VARIABABLES ################################
223 | mxd = sys.argv[1]
224 |
225 | pageName = getPageName(mxd)
226 |
227 | # Log files folder will be created in the ddp edabbr folder.
228 | curDirPath = os.path.dirname(mxd)
229 | parDirPath = os.path.abspath(os.path.join(curDirPath, os.pardir))
230 | logPath = os.path.join(parDirPath, pageName, "Logfiles-Anno")
231 | if not os.path.exists(logPath):
232 | os.makedirs(logPath)
233 |
234 | # Make a global logging object.
235 | logName = os.path.join(logPath, (getpass.getuser() + now.strftime("_%Y-%m-%d_%H-%M.log")))
236 |
237 | log = logging.getLogger("script_log")
238 | log.setLevel(logging.INFO)
239 |
240 | h1 = logging.FileHandler(logName)
241 | h2 = logging.StreamHandler()
242 |
243 | f = logging.Formatter("[%(levelname)s] [%(asctime)s] [%(lineno)d] - %(message)s", '%m/%d/%Y %I:%M:%S %p')
244 |
245 | h1.setFormatter(f)
246 | h2.setFormatter(f)
247 |
248 | h1.setLevel(logging.INFO)
249 | h2.setLevel(logging.INFO)
250 |
251 | log.addHandler(h1)
252 | log.addHandler(h2)
253 |
254 | log.info('----------------------------------------------------')
255 | log.info('Script: {0}'.format(os.path.basename(sys.argv[0])))
256 | log.info('----------------------------------------------------')
257 |
258 | try:
259 | ########################### Function calls ###########################
260 | confirm = query_yes_no("Are you sure you want to create new annotation? Existing FGDB(s) will be overwritten.")
261 |
262 | if confirm.lower() in ("y", "ye", "yes"):
263 | createExtentBoxes(mxd)
264 | generateTiledAnno(mxd)
265 |
266 | except Exception as e:
267 | log.exception(e)
268 |
269 | totalTime = formatTime((time.time() - startTime))
270 | log.info('----------------------------------------------------')
271 | log.info("Script Completed After: {0}".format(totalTime))
272 | log.info('----------------------------------------------------')
273 |
--------------------------------------------------------------------------------
/Annotation_Stand_Alone/Annotation_Cmd.py:
--------------------------------------------------------------------------------
1 | #############################################################################
2 | # The MIT License (MIT)
3 | #
4 | # Copyright (c) 2015 James Stephaniuk
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | # SOFTWARE.
23 | #
24 | #############################################################################
25 | # Usage: Run this script from the command line.
26 | # Navigate to this script's folder in the command line and type:
27 | # python [script name] "[mxd path]".
28 | #
29 | ##############################################################################
30 |
31 | import arcpy
32 | import datetime
33 | import getpass
34 | import glob
35 | import logging
36 | import logging.handlers
37 | import os
38 | import shutil
39 | import sys
40 | import time
41 |
42 |
43 | def createExtentBoxes(mxdPath):
44 | try:
45 | # Restore Page Layout (from PageLayoutElements table) before running this script.
46 | mxd = arcpy.mapping.MapDocument(mxdPath)
47 | ddp = mxd.dataDrivenPages
48 | pageName = str(ddp.pageRow.getValue(ddp.pageNameField.name))
49 | df_lst = arcpy.mapping.ListDataFrames(mxd)
50 |
51 | log.info("MXD path: {}".format(mxd.filePath))
52 | log.info("Page Name: {}".format(pageName))
53 |
54 |
55 | onMapDFs = []
56 | # List of data frames on the current page.
57 | for df in df_lst:
58 | if (df.elementPositionX > 0 and df.elementPositionX < mxd.pageSize[0] and df.elementPositionY > 0 and df.elementPositionY < mxd.pageSize[1]):
59 | onMapDFs.append(df)
60 |
61 | feature_info = []
62 | for df in onMapDFs:
63 | # Only creates geometry for data frames on the page. Also creates FGDB.
64 | XMin = df.extent.XMin
65 | YMin = df.extent.YMin
66 | XMax = df.extent.XMax
67 | YMax = df.extent.YMax
68 | # A list of features and coordinate pairs
69 | df_info = [[XMin, YMin],[XMax, YMin],[XMax, YMax],[XMin, YMax]]
70 | feature_info.append(df_info)
71 |
72 | # A list that will hold each of the Polygon objects
73 | features = []
74 | for feature in feature_info:
75 | # Create a Polygon object based on the array of points
76 | # Append to the list of Polygon objects
77 | features.append(arcpy.Polygon(arcpy.Array([arcpy.Point(*coords) for coords in feature])))
78 |
79 |
80 | # Persist a copy of the Polygon objects using CopyFeatures
81 | poly_filename = "DF_Polygons_{}".format(pageName)
82 | parentDir = os.path.abspath(os.path.join(os.path.dirname(mxd.filePath), os.pardir))
83 | edDir = os.path.join(parentDir, pageName)
84 | outDir = os.path.join(edDir, "anno_fgdb")
85 | if not os.path.exists(outDir):
86 | os.makedirs(outDir)
87 | workspace = arcpy.env.workspace = outDir
88 | log.info("Output directory set to {}".format(outDir))
89 |
90 | poly_shp = os.path.join(workspace, poly_filename)
91 | for filename in glob.glob(poly_shp + "*"):
92 | os.remove(filename)
93 |
94 | arcpy.CopyFeatures_management(features, poly_filename)
95 | log.info("'{}' saved to: {}".format(poly_filename, outDir))
96 |
97 | # Remove existing FGDB(s).
98 | for gdb in arcpy.ListFiles("*.gdb"):
99 | gdb_path = os.path.join(workspace, gdb)
100 | shutil.rmtree(gdb_path)
101 | # Create FGDB(s).
102 | for df in onMapDFs:
103 | fgdb = os.path.join(workspace, "{}_{}_{}.gdb".format(pageName, df.name, str(int(round(df.scale)))))
104 | if os.path.exists(fgdb):
105 | shutil.rmtree(fgdb)
106 | arcpy.CreateFileGDB_management(workspace, "{}_{}_{}".format(pageName, df.name, str(int(round(df.scale)))), "CURRENT")
107 | log.info("FGDB created: {}".format(fgdb))
108 |
109 | del coords, feature_info, features, feature, poly_filename, outDir, mxd, df_lst, df_info, df, XMax, XMin, YMax, YMin, ddp, pageName
110 | except Exception as e:
111 | log.info("An error occured: {}".format(e))
112 |
113 | def generateTiledAnno(mxdPath):
114 |
115 | mxd = arcpy.mapping.MapDocument(mxdPath)
116 | ddp = mxd.dataDrivenPages
117 | pageName = str(ddp.pageRow.getValue(ddp.pageNameField.name))
118 | df_lst = arcpy.mapping.ListDataFrames(mxd)
119 |
120 | # List of data frames on the current page.
121 | onMapDFs = []
122 | for df in df_lst:
123 | if (df.elementPositionX > 0 and df.elementPositionX < mxd.pageSize[0] and df.elementPositionY > 0 and df.elementPositionY < mxd.pageSize[1]):
124 | onMapDFs.append(df)
125 |
126 | parentDir = os.path.abspath(os.path.join(os.path.dirname(mxd.filePath), os.pardir))
127 | workspace = arcpy.env.workspace = os.path.join(parentDir, pageName, "anno_fgdb")
128 |
129 | indexFC = arcpy.ListFeatureClasses("DF_Polygons*")[0]
130 | tileIndexPoly = os.path.join(workspace, indexFC)
131 | GroupAnno = "GroupAnno"
132 | anno_suffix = "Anno"
133 |
134 | for df in onMapDFs:
135 | # arcpy.activeView = df.name
136 | try:
137 | fgdb = os.path.join(workspace, "{}_{}_{}.gdb".format(pageName, str(df.name), int(round(df.scale))))
138 | if os.path.exists(fgdb):
139 | arcpy.TiledLabelsToAnnotation_cartography(
140 | mxd.filePath,
141 | str(df.name),
142 | # r"C:\Users\jastepha\Desktop\EDVA Maps\VMP\anno_fgdb\DF_Polygons_VMP.shp",
143 | str(tileIndexPoly),
144 | fgdb,
145 | GroupAnno + str(df.name) + "_",
146 | anno_suffix,
147 | round(df.scale),
148 | feature_linked="STANDARD",
149 | generate_unplaced_annotation="NOT_GENERATE_UNPLACED_ANNOTATION")
150 | log.info("Tiled Annotation Created at {}".format(fgdb))
151 | else:
152 | log.info("{} DOES NOT EXIST".format(fgdb))
153 |
154 | except Exception as e:
155 | log.info(e)
156 |
157 | # Turn off all labels. Uncomment mxd.save() below too. Turned off to improve script run time.
158 | # for lyr in arcpy.mapping.ListLayers(mxd):
159 | # if lyr.supports("LABELCLASSES"):
160 | # lyr.showLabels = False
161 | # log.info("All labels have been turned off.")
162 |
163 | # for df in df_lst:
164 | # # Remove DF Polygons.
165 | # for lyr in arcpy.mapping.ListLayers(mxd,"", df):
166 | # if lyr.name.lower().startswith("df_polygons"):
167 | # arcpy.mapping.RemoveLayer(df, lyr)
168 |
169 | # # Remove empty annotation groups.
170 | # groupLayers = [x for x in arcpy.mapping.ListLayers(mxd) if x.isGroupLayer and GroupAnno in x.name]
171 | # for group in groupLayers:
172 | # count = 0
173 | # for item in group:
174 | # count += 1
175 | # if count == 0:
176 | # arcpy.mapping.RemoveLayer(df, group)
177 |
178 | # mxd.save()
179 |
180 | # del anno_suffix, ddp, df, df_lst, fgdb, GroupAnno, mxd, onMapDFs, pageName, parentDir, tileIndexPoly
181 |
182 | def formatTime(x):
183 | minutes, seconds_rem = divmod(x, 60)
184 | if minutes >= 60:
185 | hours, minutes_rem = divmod(minutes, 60)
186 | return "%02d:%02d:%02d" % (hours, minutes_rem, seconds_rem)
187 | else:
188 | minutes, seconds_rem = divmod(x, 60)
189 | return "00:%02d:%02d" % (minutes, seconds_rem)
190 |
191 | def getPageName(mxdPath):
192 | mxd = arcpy.mapping.MapDocument(mxdPath)
193 | ddp = mxd.dataDrivenPages
194 | pageName = ddp.pageRow.getValue(ddp.pageNameField.name)
195 | return str(pageName)
196 |
197 | ##############################################################################
198 |
199 | if __name__ == "__main__":
200 | startTime = time.time()
201 | now = datetime.datetime.now()
202 |
203 | ############################ USER VARIABABLES ################################
204 | mxd = sys.argv[1]
205 |
206 | pageName = getPageName(mxd)
207 |
208 | # Log files folder will be created in the ddp edabbr folder.
209 | curDirPath = os.path.dirname(mxd)
210 | parDirPath = os.path.abspath(os.path.join(curDirPath, os.pardir))
211 | logPath = os.path.join(parDirPath, pageName, "Logfiles-Anno")
212 | if not os.path.exists(logPath):
213 | os.makedirs(logPath)
214 |
215 | # Make a global logging object.
216 | logName = os.path.join(logPath,(getpass.getuser() + now.strftime("_%Y-%m-%d_%H-%M.log")) )
217 |
218 | log = logging.getLogger("script_log")
219 | log.setLevel(logging.INFO)
220 |
221 | h1 = logging.FileHandler(logName)
222 | h2 = logging.StreamHandler()
223 |
224 | f = logging.Formatter("[%(levelname)s] [%(asctime)s] [%(lineno)d] - %(message)s",'%m/%d/%Y %I:%M:%S %p')
225 |
226 | h1.setFormatter(f)
227 | h2.setFormatter(f)
228 |
229 | h1.setLevel(logging.INFO)
230 | h2.setLevel(logging.INFO)
231 |
232 | log.addHandler(h1)
233 | log.addHandler(h2)
234 |
235 | log.info('----------------------------------------------------')
236 | log.info('Script: {0}'.format(os.path.basename(sys.argv[0])))
237 | log.info('----------------------------------------------------')
238 |
239 | try:
240 | ########################### Function calls ###########################
241 | createExtentBoxes(mxd)
242 | generateTiledAnno(mxd)
243 |
244 | except Exception as e:
245 | log.exception(e)
246 |
247 | totalTime = formatTime((time.time() - startTime))
248 | log.info('----------------------------------------------------')
249 | log.info("Script Completed After: {0}".format(totalTime))
250 | log.info('----------------------------------------------------')
251 |
--------------------------------------------------------------------------------
/Cycle_Drives/Cycle_Drives.esriaddin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Cycle_Drives/Cycle_Drives.esriaddin
--------------------------------------------------------------------------------
/Cycle_Drives/Images/cycle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Cycle_Drives/Images/cycle.png
--------------------------------------------------------------------------------
/Cycle_Drives/Images/switch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Cycle_Drives/Images/switch.png
--------------------------------------------------------------------------------
/Cycle_Drives/Install/Cycle_Drives_addin.py:
--------------------------------------------------------------------------------
1 | import arcpy
2 | import itertools
3 | import os
4 | import pythonaddins
5 |
6 | mxd = arcpy.mapping.MapDocument("CURRENT")
7 | # List of drives to cycle between.
8 | drives = [r"P:\15030_32_EBC_Digital_Mapping\Utilities\Scripts\Python\Replication\Replicated_P.gdb", \
9 | r"C:\Users\jastepha\Desktop\testrep\Replicated_P.gdb"]
10 | # Function to cycle drive list.
11 | cycleDrives = itertools.cycle(drives).next
12 |
13 | class ToggleDataSource(object):
14 | """Implementation for Cycle_Drives_addin.toggleDataSource (Button)"""
15 | def __init__(self):
16 | self.enabled = True
17 | self.checked = False
18 | def onClick(self):
19 | path = cycleDrives()
20 | # Replace sources in MXD. Validate set to True: workspace will only be updated if the 'replace workspace path' value is valid.
21 | mxd.findAndReplaceWorkspacePaths("",path, True)
22 |
23 | print "Resourced to {}".format(path)
24 |
25 | # Testing. Prints out all layer data source paths.
26 | # for lyr in arcpy.mapping.ListLayers(mxd):
27 | # if lyr.supports("DATASOURCE"):
28 | # print lyr.dataSource
--------------------------------------------------------------------------------
/Cycle_Drives/README.txt:
--------------------------------------------------------------------------------
1 | This is a stub project created by the ArcGIS Desktop Python AddIn Wizard.
2 |
3 | MANIFEST
4 | ========
5 |
6 | README.txt : This file
7 |
8 | makeaddin.py : A script that will create a .esriaddin file out of this
9 | project, suitable for sharing or deployment
10 |
11 | config.xml : The AddIn configuration file
12 |
13 | Images/* : all UI images for the project (icons, images for buttons,
14 | etc)
15 |
16 | Install/* : The Python project used for the implementation of the
17 | AddIn. The specific python script to be used as the root
18 | module is specified in config.xml.
19 |
--------------------------------------------------------------------------------
/Cycle_Drives/config.xml:
--------------------------------------------------------------------------------
1 | Cycle Drives {ba1aab9f-9911-4315-9592-b5da07445693} Cycle/toggle data source of layers of MXD to predefined paths. 0.1 Images\cycle.png James Stephaniuk EBC 12/23/2015
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Cycle_Drives/makeaddin.py:
--------------------------------------------------------------------------------
1 | import os
2 | import re
3 | import zipfile
4 |
5 | current_path = os.path.dirname(os.path.abspath(__file__))
6 |
7 | out_zip_name = os.path.join(current_path,
8 | os.path.basename(current_path) + ".esriaddin")
9 |
10 | BACKUP_FILE_PATTERN = re.compile(".*_addin_[0-9]+[.]py$", re.IGNORECASE)
11 |
12 | def looks_like_a_backup(filename):
13 | return bool(BACKUP_FILE_PATTERN.match(filename))
14 |
15 | with zipfile.ZipFile(out_zip_name, 'w', zipfile.ZIP_DEFLATED) as zip_file:
16 | for filename in ('config.xml', 'README.txt', 'makeaddin.py'):
17 | zip_file.write(os.path.join(current_path, filename), filename)
18 | dirs_to_add = ['Images', 'Install']
19 | for directory in dirs_to_add:
20 | for (path, dirs, files) in os.walk(os.path.join(current_path,
21 | directory)):
22 | archive_path = os.path.relpath(path, current_path)
23 | found_file = False
24 | for file in (f for f in files if not looks_like_a_backup(f)):
25 | archive_file = os.path.join(archive_path, file)
26 | print archive_file
27 | zip_file.write(os.path.join(path, file), archive_file)
28 | found_file = True
29 | if not found_file:
30 | zip_file.writestr(os.path.join(archive_path,
31 | 'placeholder.txt'),
32 | "(Empty directory)")
33 |
--------------------------------------------------------------------------------
/Dynamic_Elements/Dynamic_Elements.esriaddin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Dynamic_Elements/Dynamic_Elements.esriaddin
--------------------------------------------------------------------------------
/Dynamic_Elements/Images/Textbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Dynamic_Elements/Images/Textbox.png
--------------------------------------------------------------------------------
/Dynamic_Elements/Images/eye-chart.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Dynamic_Elements/Images/eye-chart.png
--------------------------------------------------------------------------------
/Dynamic_Elements/Install/Dynamic_Elements_addin.py:
--------------------------------------------------------------------------------
1 | import arcpy
2 | import pythonaddins
3 |
4 | def svaBoxAdjust():
5 | # Author: James Stephaniuk
6 | # October 19, 2015
7 | #
8 | # Populates and aligns a graphic box with data from an shapefile attribute table.
9 |
10 | mxd = arcpy.mapping.MapDocument("CURRENT")
11 | ddp = mxd.dataDrivenPages
12 | pageName = ddp.pageRow.getValue(ddp.pageNameField.name) # e.g. VMP
13 | pageNameField = ddp.pageNameField.name # edabbr
14 |
15 | # Feature class name.
16 | mapLyr = arcpy.mapping.ListLayers(mxd,"SVAs")[0]
17 |
18 | # SVA container (graphic box) name. Match this name to the SVA Box element name in ArcMap.
19 | svaBox = "svaBox"
20 |
21 | # Graphic box layout settings.
22 | padding = 0.2 # Distance (in inches) around edge of box to inner elements.
23 | spacer = 0.1 # Distance (in inches) between inner elements.
24 |
25 | # SVA source feature class field names. Add the field names from the layer that you want to populate the SVA Table.
26 | svaTxtField = "va"
27 | facilityName = "sectname"
28 | addrNo = "bldgstart"
29 | addrName = "stdaddr"
30 | city = "city_1"
31 | fieldLst = [svaTxtField, facilityName, addrNo, addrName, city]
32 |
33 | # SVA text element names. Match these names to the element names in ArcMap.
34 | SVATitleText = "SVATitle"
35 | svaTitleElem0 = "SVA_TitleElem0"
36 | svaTitleElem1 = "SVA_TitleElem1"
37 | svaTitleElem2 = "SVA_TitleElem2"
38 | svaTitleElem3 = "SVA_TitleElem3"
39 | svaTxtElem0 = "SVA_textElem0"
40 | svaTxtElem1 = "SVA_textElem1"
41 | svaTxtElem2 = "SVA_textElem2"
42 | svaTxtElem3 = "SVA_textElem3"
43 |
44 | mainTitle = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", SVATitleText)[0]
45 | svaTitle = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", svaTitleElem0)[0]
46 | facTitle = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", svaTitleElem1)[0]
47 | addrTitle = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", svaTitleElem2)[0]
48 | cityTitle = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", svaTitleElem3)[0]
49 | svaTxtElem = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", svaTxtElem0)[0]
50 | facTxtElem = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", svaTxtElem1)[0]
51 | addrTxtElem = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", svaTxtElem2)[0]
52 | cityTxtElem = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", svaTxtElem3)[0]
53 |
54 | elemLst = [svaTxtElem, facTxtElem, addrTxtElem, cityTxtElem]
55 |
56 | # Captions cannot be empty therefore a single char. Set all font sizes to same.
57 | for elem in elemLst:
58 | elem.text = " "
59 |
60 | # Populate columns.
61 | whereClause = "ed = "+ "'" + pageName + "'"
62 | rows = sorted(arcpy.da.SearchCursor(mapLyr.dataSource, fieldLst, whereClause))
63 |
64 | for row in rows:
65 | svaTxtElem.text += "{}\n".format(row[0])
66 | facTxtElem.text += "{}\n".format(row[1])
67 | addrTxtElem.text += "{} ".format(row[2])
68 | addrTxtElem.text += "{}\n".format(row[3])
69 | cityTxtElem.text += "{}\n".format(row[4])
70 |
71 | # Slice off leading space char.
72 | for elem in elemLst:
73 | elem.text = elem.text[1:]
74 | elem.text = '\n'.join(' '.join(line.split()) for line in elem.text.split('\n')) # Removes two or more spaces. Splits text into lines. Then splits each line by whitespace and rejoins with single spaces. Then rejoins the lines.
75 |
76 | svaBox = arcpy.mapping.ListLayoutElements(mxd, "GRAPHIC_ELEMENT", svaBox)[0]
77 |
78 | # Position main title elem.
79 | mainTitle.elementPositionX = svaBox.elementPositionX + padding
80 | mainTitle.elementPositionY = svaBox.elementPositionY - padding
81 |
82 | # Position the titles and text elements relative to main title and each other.
83 | # Col 1
84 | widthCol1 = max(svaTitle.elementWidth, svaTxtElem.elementWidth)
85 | svaTitle.elementPositionX = svaTxtElem.elementPositionX = mainTitle.elementPositionX
86 | svaTitle.elementPositionY = mainTitle.elementPositionY - svaTitle.elementHeight - padding # Uses padding instead of spacer to give main title more room.
87 | svaTxtElem.elementPositionY = svaTitle.elementPositionY - svaTitle.elementHeight
88 | # Col 2
89 | widthCol2 = max(facTitle.elementWidth, facTxtElem.elementWidth)
90 | facTitle.elementPositionY = svaTitle.elementPositionY
91 | facTxtElem.elementPositionY = svaTxtElem.elementPositionY
92 | facTitle.elementPositionX = svaTitle.elementPositionX + widthCol1 + spacer
93 | facTxtElem.elementPositionX = svaTxtElem.elementPositionX + widthCol1 + spacer
94 | # Col 3
95 | widthCol3 = max(addrTitle.elementWidth, addrTxtElem.elementWidth)
96 | addrTitle.elementPositionY = facTitle.elementPositionY
97 | addrTxtElem.elementPositionY = facTxtElem.elementPositionY
98 | addrTitle.elementPositionX = facTitle.elementPositionX + widthCol2 + spacer
99 | addrTxtElem.elementPositionX = facTxtElem.elementPositionX + widthCol2 + spacer
100 | # Col 4
101 | widthCol4 = max(cityTitle.elementWidth, cityTxtElem.elementWidth)
102 | cityTitle.elementPositionY = addrTitle.elementPositionY
103 | cityTxtElem.elementPositionY = addrTxtElem.elementPositionY
104 | cityTitle.elementPositionX = addrTitle.elementPositionX + widthCol3 + spacer
105 | cityTxtElem.elementPositionX = addrTxtElem.elementPositionX + widthCol3 + spacer
106 |
107 | # Set the svaBox height and width derived from text elements heights and widths.
108 | tallestTxtElem = max(svaTxtElem.elementHeight, facTxtElem.elementHeight, addrTxtElem.elementHeight, cityTxtElem.elementHeight)
109 | tallestTitleElem = max(svaTitle.elementHeight, facTitle.elementHeight, addrTitle.elementHeight, cityTitle.elementHeight)
110 | colsWidths = widthCol1 + widthCol2 + widthCol3 + widthCol4
111 | textWidth = colsWidths + (spacer * 3)
112 | svaBox.elementHeight = tallestTxtElem + tallestTitleElem + mainTitle.elementHeight + (padding * 2) + spacer # Height of all elements, spacers, and padding.
113 | svaBox.elementWidth = max(textWidth, mainTitle.elementWidth) + (padding * 2) # Width of all elements, spacers, and padding.
114 |
115 | # Centre the main title.
116 | if mainTitle.elementWidth > textWidth:
117 | mainTitle.elementPositionX = svaTxtElem.elementPositionX
118 | else:
119 | mainTitle.elementPositionX = svaTxtElem.elementPositionX + (textWidth / 2) - (mainTitle.elementWidth / 2 )
120 |
121 | # Contrived way to remove duplicates from SVA text column. If you have a better way I'd like to see it.
122 | splitLst = svaTxtElem.text.split()
123 | setSplititLst = list(set(svaTxtElem.text.split()))
124 | for i, item in enumerate(splitLst):
125 | if item in setSplititLst:
126 | setSplititLst.remove(item)
127 | else:
128 | splitLst[i] = splitLst[i].replace(splitLst[i], len(splitLst[i]) * " ")
129 | joinedText = "\n".join(splitLst)
130 | svaTxtElem.text = joinedText
131 |
132 | class SVA_BoxSizing_Btn(object):
133 | """Implementation for Dynamic_Elements_addin.svaButton (Button)"""
134 | def __init__(self):
135 | self.enabled = True
136 | self.checked = False
137 | def onClick(self):
138 | svaBoxAdjust()
139 | arcpy.RefreshActiveView()
140 |
141 | class SVA_Box_Sizing(object):
142 | """Implementation for Dynamic_Elements_addin.DynElem_Ext (Extension)"""
143 | def __init__(self):
144 | # For performance considerations, please remove all unused methods in this class.
145 | self.enabled = True
146 | def pageIndexExtentChanged(self, new_id):
147 | svaBoxAdjust()
--------------------------------------------------------------------------------
/Dynamic_Elements/Install/svaBoxSizing.py:
--------------------------------------------------------------------------------
1 | import arcpy
2 |
3 | # Author: James Stephaniuk
4 | # October 19, 2015
5 | #
6 | # Populates and aligns a graphic box with data from an shapefile attribute table.
7 |
8 | mxd = arcpy.mapping.MapDocument("CURRENT")
9 | ddp = mxd.dataDrivenPages
10 | pageName = ddp.pageRow.getValue(ddp.pageNameField.name) # e.g. VMP
11 | pageNameField = ddp.pageNameField.name # edabbr
12 |
13 | # Feature class name.
14 | mapLyr = arcpy.mapping.ListLayers(mxd,"SVAs")[0]
15 |
16 | # SVA container (graphic box) name. Match this name to the SVA Box element name in ArcMap.
17 | svaBox = "svaBox"
18 |
19 | # Graphic box layout settings.
20 | padding = 0.2 # Distance (in inches) around edge of box to inner elements.
21 | spacer = 0.1 # Distance (in inches) between inner elements.
22 |
23 | # SVA source feature class field names. Add the field names from the layer that you want to populate the SVA Table.
24 | svaTxtField = "va"
25 | facilityName = "sectname"
26 | addrNo = "bldgstart"
27 | addrName = "stdaddr"
28 | city = "city_1"
29 | fieldLst = [svaTxtField, facilityName, addrNo, addrName, city]
30 |
31 | # SVA text element names. Match these names to the element names in ArcMap.
32 | SVATitleText = "SVATitle"
33 | svaTitleElem0 = "SVA_TitleElem0"
34 | svaTitleElem1 = "SVA_TitleElem1"
35 | svaTitleElem2 = "SVA_TitleElem2"
36 | svaTitleElem3 = "SVA_TitleElem3"
37 | svaTxtElem0 = "SVA_textElem0"
38 | svaTxtElem1 = "SVA_textElem1"
39 | svaTxtElem2 = "SVA_textElem2"
40 | svaTxtElem3 = "SVA_textElem3"
41 |
42 | mainTitle = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", SVATitleText)[0]
43 | svaTitle = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", svaTitleElem0)[0]
44 | facTitle = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", svaTitleElem1)[0]
45 | addrTitle = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", svaTitleElem2)[0]
46 | cityTitle = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", svaTitleElem3)[0]
47 | svaTxtElem = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", svaTxtElem0)[0]
48 | facTxtElem = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", svaTxtElem1)[0]
49 | addrTxtElem = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", svaTxtElem2)[0]
50 | cityTxtElem = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", svaTxtElem3)[0]
51 |
52 | elemLst = [svaTxtElem, facTxtElem, addrTxtElem, cityTxtElem]
53 |
54 | # Captions cannot be empty therefore a single char. Set all font sizes to same.
55 | for elem in elemLst:
56 | elem.text = " "
57 |
58 | # Populate columns.
59 | whereClause = "ed = "+ "'" + pageName + "'"
60 | rows = sorted(arcpy.da.SearchCursor(mapLyr.dataSource, fieldLst, whereClause))
61 |
62 | for row in rows:
63 | svaTxtElem.text += "{}\n".format(row[0])
64 | facTxtElem.text += "{}\n".format(row[1])
65 | addrTxtElem.text += "{} ".format(row[2])
66 | addrTxtElem.text += "{}\n".format(row[3])
67 | cityTxtElem.text += "{}\n".format(row[4])
68 |
69 | # Slice off leading space char.
70 | for elem in elemLst:
71 | elem.text = elem.text[1:]
72 | elem.text = '\n'.join(' '.join(line.split()) for line in elem.text.split('\n')) # Removes two or more spaces. Splits text into lines. Then splits each line by whitespace and rejoins with single spaces. Then rejoins the lines.
73 |
74 | svaBox = arcpy.mapping.ListLayoutElements(mxd, "GRAPHIC_ELEMENT", svaBox)[0]
75 |
76 | # Position main title elem.
77 | mainTitle.elementPositionX = svaBox.elementPositionX + padding
78 | mainTitle.elementPositionY = svaBox.elementPositionY - padding
79 |
80 | # Position the titles and text elements relative to main title and each other.
81 | # Col 1
82 | widthCol1 = max(svaTitle.elementWidth, svaTxtElem.elementWidth)
83 | svaTitle.elementPositionX = svaTxtElem.elementPositionX = mainTitle.elementPositionX
84 | svaTitle.elementPositionY = mainTitle.elementPositionY - svaTitle.elementHeight - padding # Uses padding instead of spacer to give main title more room.
85 | svaTxtElem.elementPositionY = svaTitle.elementPositionY - svaTitle.elementHeight
86 | # Col 2
87 | widthCol2 = max(facTitle.elementWidth, facTxtElem.elementWidth)
88 | facTitle.elementPositionY = svaTitle.elementPositionY
89 | facTxtElem.elementPositionY = svaTxtElem.elementPositionY
90 | facTitle.elementPositionX = svaTitle.elementPositionX + widthCol1 + spacer
91 | facTxtElem.elementPositionX = svaTxtElem.elementPositionX + widthCol1 + spacer
92 | # Col 3
93 | widthCol3 = max(addrTitle.elementWidth, addrTxtElem.elementWidth)
94 | addrTitle.elementPositionY = facTitle.elementPositionY
95 | addrTxtElem.elementPositionY = facTxtElem.elementPositionY
96 | addrTitle.elementPositionX = facTitle.elementPositionX + widthCol2 + spacer
97 | addrTxtElem.elementPositionX = facTxtElem.elementPositionX + widthCol2 + spacer
98 | # Col 4
99 | widthCol4 = max(cityTitle.elementWidth, cityTxtElem.elementWidth)
100 | cityTitle.elementPositionY = addrTitle.elementPositionY
101 | cityTxtElem.elementPositionY = addrTxtElem.elementPositionY
102 | cityTitle.elementPositionX = addrTitle.elementPositionX + widthCol3 + spacer
103 | cityTxtElem.elementPositionX = addrTxtElem.elementPositionX + widthCol3 + spacer
104 |
105 | # Set the svaBox height and width derived from text elements heights and widths.
106 | tallestTxtElem = max(svaTxtElem.elementHeight, facTxtElem.elementHeight, addrTxtElem.elementHeight, cityTxtElem.elementHeight)
107 | tallestTitleElem = max(svaTitle.elementHeight, facTitle.elementHeight, addrTitle.elementHeight, cityTitle.elementHeight)
108 | colsWidths = widthCol1 + widthCol2 + widthCol3 + widthCol4
109 | textWidth = colsWidths + (spacer * 3)
110 | svaBox.elementHeight = tallestTxtElem + tallestTitleElem + mainTitle.elementHeight + (padding * 2) + spacer # Height of all elements, spacers, and padding.
111 | svaBox.elementWidth = max(textWidth, mainTitle.elementWidth) + (padding * 2) # Width of all elements, spacers, and padding.
112 |
113 | # Centre the main title.
114 | if mainTitle.elementWidth > textWidth:
115 | mainTitle.elementPositionX = svaTxtElem.elementPositionX
116 | else:
117 | mainTitle.elementPositionX = svaTxtElem.elementPositionX + (textWidth / 2) - (mainTitle.elementWidth / 2 )
118 |
119 | # Contrived way to remove duplicates from SVA text column. If you have a better way I'd like to see it.
120 | splitLst = svaTxtElem.text.split()
121 | setSplititLst = list(set(svaTxtElem.text.split()))
122 | for i, item in enumerate(splitLst):
123 | if item in setSplititLst:
124 | setSplititLst.remove(item)
125 | else:
126 | splitLst[i] = splitLst[i].replace(splitLst[i], len(splitLst[i]) * " ")
127 | joinedText = "\n".join(splitLst)
128 | svaTxtElem.text = joinedText
--------------------------------------------------------------------------------
/Dynamic_Elements/README.txt:
--------------------------------------------------------------------------------
1 | This is a stub project created by the ArcGIS Desktop Python AddIn Wizard.
2 |
3 | MANIFEST
4 | ========
5 |
6 | README.txt : This file
7 |
8 | makeaddin.py : A script that will create a .esriaddin file out of this
9 | project, suitable for sharing or deployment
10 |
11 | config.xml : The AddIn configuration file
12 |
13 | Images/* : all UI images for the project (icons, images for buttons,
14 | etc)
15 |
16 | Install/* : The Python project used for the implementation of the
17 | AddIn. The specific python script to be used as the root
18 | module is specified in config.xml.
19 |
--------------------------------------------------------------------------------
/Dynamic_Elements/config.xml:
--------------------------------------------------------------------------------
1 | Dynamic_Elements {e4528db6-a9cd-4b6f-a805-360334312963} Dynamically size and position map elements. 1.0 Images\eye-chart.png James Stephaniuk EBC 11/09/2015
2 |
3 | SVA_Box_Sizing
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Dynamic_Elements/makeaddin.py:
--------------------------------------------------------------------------------
1 | import os
2 | import re
3 | import zipfile
4 |
5 | current_path = os.path.dirname(os.path.abspath(__file__))
6 |
7 | out_zip_name = os.path.join(current_path,
8 | os.path.basename(current_path) + ".esriaddin")
9 |
10 | BACKUP_FILE_PATTERN = re.compile(".*_addin_[0-9]+[.]py$", re.IGNORECASE)
11 |
12 | def looks_like_a_backup(filename):
13 | return bool(BACKUP_FILE_PATTERN.match(filename))
14 |
15 | with zipfile.ZipFile(out_zip_name, 'w', zipfile.ZIP_DEFLATED) as zip_file:
16 | for filename in ('config.xml', 'README.txt', 'makeaddin.py'):
17 | zip_file.write(os.path.join(current_path, filename), filename)
18 | dirs_to_add = ['Images', 'Install']
19 | for directory in dirs_to_add:
20 | for (path, dirs, files) in os.walk(os.path.join(current_path,
21 | directory)):
22 | archive_path = os.path.relpath(path, current_path)
23 | found_file = False
24 | for file in (f for f in files if not looks_like_a_backup(f)):
25 | archive_file = os.path.join(archive_path, file)
26 | print archive_file
27 | zip_file.write(os.path.join(path, file), archive_file)
28 | found_file = True
29 | if not found_file:
30 | zip_file.writestr(os.path.join(archive_path,
31 | 'placeholder.txt'),
32 | "(Empty directory)")
33 |
--------------------------------------------------------------------------------
/Functions/adjustElementsFunctions.py:
--------------------------------------------------------------------------------
1 | def adjustScaleElements():
2 | """Function to place each scale element to a predefined location (bottom left) within its parent dataframe."""
3 | mxd = arcpy.mapping.MapDocument("CURRENT")
4 | df_lst = arcpy.mapping.ListDataFrames(mxd)[1:]
5 | scaleTextLst = arcpy.mapping.ListLayoutElements(mxd, "MAPSURROUND_ELEMENT", "*Scale text*")
6 | scaleBarLst = arcpy.mapping.ListLayoutElements(mxd, "MAPSURROUND_ELEMENT", "*Scale bar*")
7 | scaleNorth = scaleTextLst + scaleBarLst
8 |
9 | # Reset inset data frames.
10 | for index, df in enumerate(df_lst):
11 | for i, elem in enumerate(scaleTextLst):
12 | if hasattr(elem, 'parentDataFrameName') and elem.parentDataFrameName == df.name:
13 | if elem.parentDataFrameName == df.name:
14 | elem.elementPositionX = df.elementPositionX + 0.25
15 | elem.elementPositionY = df.elementPositionY + 0.70
16 | for i, elem in enumerate(scaleBarLst):
17 | if hasattr(elem, 'parentDataFrameName') and elem.parentDataFrameName == df.name:
18 | if elem.parentDataFrameName == df.name:
19 | elem.elementPositionX = df.elementPositionX + 0.25
20 | elem.elementPositionY = df.elementPositionY + 0.25
21 |
22 |
23 |
24 | # Puts graphical north arrow elements (with center anchor points) to the top right of inset dataframes with 1/4 inch padding.
25 | def adjustNorthElements():
26 | """Function to place each north arrow element to a predefined location (bottom left) within its parent dataframe."""
27 | mxd = arcpy.mapping.MapDocument("CURRENT")
28 | insetLst = arcpy.mapping.ListDataFrames(mxd)[1:]
29 | northArrowLst = arcpy.mapping.ListLayoutElements(mxd, wildcard="*north*")
30 |
31 | # Reset inset data frames.
32 | for index, df in enumerate(insetLst):
33 | northArrowLst[index].elementHeight = 0.5666
34 | northArrowLst[index].elementWidth = 0.272
35 | northArrowLst[index].elementPositionY = df.elementPositionY + df.elementHeight - (northArrowLst[index].elementHeight / 2) - 0.25
36 | northArrowLst[index].elementPositionX = df.elementPositionX + df.elementWidth - (northArrowLst[index].elementWidth / 2) - 0.25
37 |
38 |
39 | # Print number of scale bars, scale texts, and data frames. Should be 17 for all.
40 | print "Number of Scale Bars: {}".format(len(arcpy.mapping.ListLayoutElements(arcpy.mapping.MapDocument("CURRENT"), wildcard="*scale bar*")))
41 | print "Number of Scale Texts: {}".format(len(arcpy.mapping.ListLayoutElements(arcpy.mapping.MapDocument("CURRENT"), wildcard="*scale text*")))
42 | print "Number of North Arrows: {}".format(len(arcpy.mapping.ListLayoutElements(arcpy.mapping.MapDocument("CURRENT"), wildcard="*north*")))
43 | print "Number of Data Frames: {}".format(len(arcpy.mapping.ListDataFrames(arcpy.mapping.MapDocument("CURRENT"))))
--------------------------------------------------------------------------------
/Functions/clearAllQueries.py:
--------------------------------------------------------------------------------
1 | def clearAllQueries():
2 | """Removes all definition queries from layers in T.O.C."""
3 | for lyr in arcpy.mapping.ListLayers(arcpy.mapping.MapDocument("CURRENT")):
4 | if lyr.supports("DEFINITIONQUERY"):
5 | lyr.definitionQuery = ""
6 | print "Definition query for '{}'' layer cleared.".format(lyr.name)
7 | arcpy.RefreshActiveView()
--------------------------------------------------------------------------------
/Functions/clearSelectedLayerQuery.py:
--------------------------------------------------------------------------------
1 | def clearSelectedLayerQuery():
2 | """Clear definition query from the layer selected in the T.O.C."""
3 | import pythonaddins
4 | lyr = pythonaddins.GetSelectedTOCLayerOrDataFrame()
5 | lyr.definitionQuery = ""
6 | print "Definition query for '{}'' layer cleared.".format(lyr.name)
7 | arcpy.RefreshActiveView()
--------------------------------------------------------------------------------
/Functions/genericCmdPrompt.py:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 |
4 | def query_yes_no(question, default="yes"):
5 | """Ask a yes/no question via raw_input() and return their answer.
6 |
7 | "question" is a string that is presented to the user.
8 | "default" is the presumed answer if the user just hits .
9 | It must be "yes" (the default), "no" or None (meaning
10 | an answer is required of the user).
11 |
12 | The "answer" return value is one of "yes" or "no".
13 | """
14 | valid = {"yes": "yes", "y": "yes", "ye": "yes",
15 | "no": "no", "n": "no"}
16 | if default is None:
17 | prompt = " [y/n] "
18 | elif default == "yes":
19 | prompt = " [Y/n] "
20 | elif default == "no":
21 | prompt = " [y/N] "
22 | else:
23 | raise ValueError("invalid default answer: '%s'" % default)
24 |
25 | while 1:
26 | sys.stdout.write(question + prompt)
27 | choice = raw_input().lower()
28 | if default is not None and choice == '':
29 | return default
30 | elif choice in valid.keys():
31 | return valid[choice]
32 | else:
33 | sys.stdout.write("Please respond with 'yes' or 'no' "
34 | "(or 'y' or 'n').\n")
35 |
--------------------------------------------------------------------------------
/Functions/getSelectionSet.py:
--------------------------------------------------------------------------------
1 | def getSelectionSet():
2 | """Returns a layer's selection as a Python set of feature IDs the layer's name, the data frame object, and the OID field name.
3 | Provides an easy way to retrieve the layer's current selection.
4 | """
5 | try:
6 | mxd = arcpy.mapping.MapDocument("CURRENT")
7 | df = mxd.activeDataFrame
8 | lyrLst = arcpy.mapping.ListLayers(mxd, "*", df) # Only list first dataframe to avoid identically named layers, where all would get selected.
9 | fidLst = []
10 | lyrName = ""
11 | for lyr in lyrLst:
12 | try:
13 | desc = arcpy.Describe(lyr)
14 | if desc.FIDSet:
15 | fidLst.append(desc.FIDSet)
16 | lyrName = desc.nameString
17 | except:
18 | pass
19 |
20 | # Check for multiple layers selected.
21 | if len(fidLst) > 1:
22 | raise TypeError("Please select features from a single layer.")
23 |
24 | # Convert list string items to integers.
25 | fidLst = fidLst[0].split(";")
26 | fidLst = map(int, fidLst)
27 |
28 | OIDFieldName = desc.fieldInfo.getfieldname(0)
29 |
30 | # Return list of selected feature IDs, the selected layer name, the data frame it is in, and the OID field name.
31 | return fidLst, lyrName, df, OIDFieldName
32 | except IndexError as ie:
33 | import pythonaddins
34 | pythonaddins.MessageBox("{}. Please make a selection.".format(str(ie).capitalize()), "Selection Error")
35 | except Exception as e:
36 | pythonaddins.MessageBox(e, "Error")
--------------------------------------------------------------------------------
/Functions/querySelection.py:
--------------------------------------------------------------------------------
1 | def querySelection():
2 | """Builds a definition query to display only the currently
3 | selected features for that layer.
4 | """
5 | # sys.path.append(os.path.dirname(__file__)) # Add this script to system path. Used to separate main script from other code packages.
6 | import .getSelectionSet
7 | mxd = arcpy.mapping.MapDocument("CURRENT")
8 | ids, name, df, oid = getSelectionSet()
9 | lyr = arcpy.mapping.ListLayers(mxd, name, df)[0]
10 |
11 | # Build SQL clause to use in definition query.
12 | whereClause = "{} in ({})".format(oid, ','.join(str(id) for id in ids))
13 |
14 | # Apply the definition query.
15 | lyr.definitionQuery = whereClause
16 |
17 | arcpy.RefreshActiveView()
--------------------------------------------------------------------------------
/Layers/Images/45.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Layers/Images/45.png
--------------------------------------------------------------------------------
/Layers/Images/45_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Layers/Images/45_1.png
--------------------------------------------------------------------------------
/Layers/Images/Thumbs.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Layers/Images/Thumbs.db
--------------------------------------------------------------------------------
/Layers/Images/computerscreen5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Layers/Images/computerscreen5.png
--------------------------------------------------------------------------------
/Layers/Images/dropdown.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Layers/Images/dropdown.gif
--------------------------------------------------------------------------------
/Layers/Images/maps-and-geolocation-layers-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Layers/Images/maps-and-geolocation-layers-icon.png
--------------------------------------------------------------------------------
/Layers/Install/Layers_addin.py:
--------------------------------------------------------------------------------
1 | import arcpy
2 | import os
3 | import pythonaddins
4 | import sys
5 |
6 | sys.path.append(os.path.dirname(__file__)) # Add this script to system path. Used to separate main script from other code packages.
7 | from autoPath import autoPath
8 |
9 | class LayerHelper(object):
10 | """Implementation for Layers_addin.layerHelper_1 (Extension)"""
11 | def __init__(self):
12 | # For performance considerations, please remove all unused methods in this class.
13 | self.enabled = True
14 | def pageIndexExtentChanged(self, new_id):
15 | restoreLyrs = RestoreLayers()
16 | restoreLyrs.onClick()
17 |
18 | class ResetLayers(object):
19 | """Implementation for Layers_addin.resetLayers (Button)"""
20 | def __init__(self):
21 | self.enabled = True
22 | self.checked = False
23 | def onClick(self):
24 | parentDir = os.path.abspath(os.path.join(autoPath(), os.pardir))
25 | defaultLayersWorkspace = os.path.join(parentDir, "z_Default_Layers")
26 | arcpy.env.workspace = defaultLayersWorkspace
27 | mxd = arcpy.mapping.MapDocument("CURRENT")
28 |
29 | # Create Default Layers directory if none exists.
30 | if not os.path.exists(defaultLayersWorkspace):
31 | os.makedirs(defaultLayersWorkspace)
32 | pythonaddins.MessageBox("Default layers yet not created.\nRun createDefaultLyrs.py inside the interactive python window of this MXD.", "Layers Not Created", 0)
33 |
34 | # Load Default Layers.
35 | dfLst = arcpy.mapping.ListDataFrames(mxd)
36 |
37 | # Initialize empty lists for MessageBox.
38 | lyrsReset, lyrsNotReset = [], []
39 |
40 | # Iterate features and dataframes. Replace with default layer file. NOTE: Make sure feature class names are unique.
41 | for df in dfLst:
42 | for lyr in arcpy.mapping.ListLayers(mxd, "*", df):
43 | if isinstance(lyr, arcpy.mapping.Layer) and not lyr.isGroupLayer:
44 | lyrString = "default_%s.lyr" % (lyr.name)
45 | if lyrString in arcpy.ListFiles("*.lyr"):
46 | ref_layer = arcpy.mapping.ListLayers(mxd, lyr.name, df)[0]
47 | insert_layer = arcpy.mapping.Layer("%s\\%s" % (defaultLayersWorkspace, lyrString))
48 | arcpy.mapping.InsertLayer(df, ref_layer,insert_layer, "AFTER")
49 | arcpy.mapping.RemoveLayer(df, ref_layer)
50 | # Add swapped layers to list and show user with pythonaddins.MessageBox().
51 | lyrsReset.append("{} - {}".format(lyrString, df.name))
52 | else:
53 | lyrsNotReset.append("{} - {}".format(lyrString, df.name))
54 | pythonaddins.MessageBox("Layers Reset:\n{} \n\nLayers NOT Reset:\n{}".format(lyrsReset, lyrsNotReset),"Layer Reset Summary", 0)
55 |
56 | class RestoreLayers(object):
57 | """Implementation for Layers_addin.RestoreLayers (Button)"""
58 | def __init__(self):
59 | self.enabled = True
60 | self.checked = False
61 | def onClick(self):
62 | try:
63 | # Create an instance of the ResetLayers class.
64 | reset = ResetLayers()
65 | # Call ResetLayers onClick method.
66 | reset.onClick()
67 |
68 | workspace = autoPath()
69 | os.chdir(workspace)
70 |
71 | mxd = arcpy.mapping.MapDocument("CURRENT")
72 | ddp = mxd.dataDrivenPages
73 | pageName = ddp.pageRow.getValue(ddp.pageNameField.name)
74 | dfLst = arcpy.mapping.ListDataFrames(mxd)
75 | layers = arcpy.mapping.ListLayers(mxd)
76 |
77 | # Add description to layers if blank.
78 | for layer in arcpy.mapping.ListLayers(mxd):
79 | if layer.description == "":
80 | layer.description = "This is a default description for the '%s' layer. Feel free to change or update this description." % (layer.name)
81 |
82 | # Initialize empty list for MessageBox.
83 | lyrsRestored = []
84 | # Iterate features and dataframes. Replace if layerfile exists for feature.
85 | for df in dfLst:
86 | for lyr in arcpy.mapping.ListLayers(mxd,"*", df):
87 | if isinstance(lyr, arcpy.mapping.Layer) and not lyr.isGroupLayer:
88 | lyrString = "%s_%s_%s.lyr" % (pageName, lyr.name, df.name)
89 | if lyrString in arcpy.ListFiles("*.lyr"):
90 | ref_layer = arcpy.mapping.ListLayers(mxd, lyr.name, df)[0]
91 | insert_layer = arcpy.mapping.Layer("%s\\%s" % (workspace, lyrString))
92 | arcpy.mapping.InsertLayer(df, ref_layer,insert_layer, "AFTER")
93 | arcpy.mapping.RemoveLayer(df, ref_layer)
94 | lyrsRestored.append(lyrString + df.name)
95 |
96 | pythonaddins.MessageBox("Layers Restored:\n%s" % lyrsRestored,"Restored Layers Summary", 0)
97 | except Exception as e:
98 | pythonaddins.MessageBox(e, "Error")
99 |
100 | class SaveLayers(object):
101 | def __init__(self):
102 | self.enabled = True
103 | self.checked = False
104 | def onClick(self):
105 | try:
106 | workspace = autoPath()
107 | mxd = arcpy.mapping.MapDocument("CURRENT")
108 | ddp = mxd.dataDrivenPages
109 | dfLst = arcpy.mapping.ListDataFrames(mxd)
110 | pageName = ddp.pageRow.getValue(ddp.pageNameField.name)
111 |
112 | # Set data frame name to credits field (can change to description field) for use in lyrString.
113 | for df in dfLst:
114 | for lyr in arcpy.mapping.ListLayers(mxd, "*", df):
115 | if isinstance(lyr, arcpy.mapping.Layer) and not lyr.isGroupLayer:
116 | lyr.credits = df.name
117 |
118 | lyr = pythonaddins.GetSelectedTOCLayerOrDataFrame()
119 | if not isinstance(lyr, arcpy.mapping.Layer) or lyr.isGroupLayer:
120 | pythonaddins.MessageBox('Please select one (1) layer (not a group or data frame or multiple layers) in the Table Of Contents', 'Layer Selection Error', 0)
121 | else:
122 | lyrString = "%s_%s_%s.lyr" % (pageName, lyr.name, lyr.credits)
123 | arcpy.SaveToLayerFile_management(lyr, workspace + "\\" + lyrString, "ABSOLUTE")
124 | pythonaddins.MessageBox("%s layer saved to:\n\n%s\n\nas:\n\n%s" % (lyr.name, workspace, lyrString), "Layer Saved", 0)
125 | except Exception as e:
126 | pythonaddins.MessageBox(e, "Error")
--------------------------------------------------------------------------------
/Layers/Install/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Layers/Install/__init__.py
--------------------------------------------------------------------------------
/Layers/Install/autoPath.py:
--------------------------------------------------------------------------------
1 | def autoPath(folderName="z_layer_files"):
2 | """Returns a workspace path one level above the MXD's current directory,
3 | and sets the current workspace to that directory. Creates a folder with
4 | name equal to parameter, if it does not already exist.
5 | Parameters: Folder name. Default parameter is 'Layerfiles'.
6 | """
7 | import arcpy
8 | import os
9 | # Create a 'folderName' folder in parent folder.
10 | mxd = arcpy.mapping.MapDocument('CURRENT')
11 | currentDir = os.path.dirname(os.path.realpath(mxd.filePath))
12 | parentDir = os.path.abspath(os.path.join(currentDir, os.pardir))
13 | layersPath = os.path.join(parentDir, folderName)
14 | if not os.path.exists(layersPath):
15 | os.makedirs(layersPath)
16 |
17 | arcpy.env.overwriteOutput = True
18 | arcpy.env.workspace = layersPath
19 | workspace = arcpy.env.workspace
20 |
21 | return workspace
--------------------------------------------------------------------------------
/Layers/Install/createDefaultLyrs.py:
--------------------------------------------------------------------------------
1 | import arcpy
2 | import os
3 | import pythonaddins
4 |
5 | sys.path.append(os.path.dirname(__file__)) # Add this script to system path. Used to separate main script from other code packages.
6 | from autoPath import autoPath
7 |
8 | arcpy.env.overwriteOutput = True
9 | parentDir = os.path.abspath(os.path.join(autoPath(), os.pardir))
10 | workspace = os.path.join(parentDir, "z_Default_Layers")
11 | if not os.path.exists(workspace):
12 | os.makedirs(workspace)
13 |
14 | arcpy.env.workspace = workspace
15 |
16 |
17 | mxd = arcpy.mapping.MapDocument("CURRENT")
18 | df = arcpy.mapping.ListDataFrames(mxd)[0]
19 |
20 | annoLst = []
21 | for lyr in arcpy.mapping.ListLayers(mxd,data_frame=arcpy.mapping.ListDataFrames(mxd)[0]):
22 | if lyr.supports("DATASOURCE"):
23 | arcpy.env.workspace = os.path.dirname(lyr.dataSource)
24 | annoLst.append(arcpy.ListFeatureClasses(feature_type="Annotation"))
25 |
26 | # Create layerfile for layers in TOC that support layerfile creation.
27 | for lyr in [item for item in arcpy.mapping.ListLayers(mxd, data_frame=df) if item not in annoLst]:
28 | if isinstance(lyr, arcpy.mapping.Layer) and not lyr.isGroupLayer and "index" not in lyr.name and lyr.supports("DATASETNAME") and not lyr.isBroken:
29 | lyrString = "default_%s.lyr" % (lyr.name)
30 | try:
31 | arcpy.SaveToLayerFile_management(lyr,workspace + "\\" + lyrString, "ABSOLUTE")
32 | except Exception as e:
33 | print e
34 |
--------------------------------------------------------------------------------
/Layers/Layers.esriaddin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Layers/Layers.esriaddin
--------------------------------------------------------------------------------
/Layers/README.txt:
--------------------------------------------------------------------------------
1 | This is a stub project created by the ArcGIS Desktop Python AddIn Wizard.
2 |
3 | MANIFEST
4 | ========
5 |
6 | README.txt : This file
7 |
8 | makeaddin.py : A script that will create a .esriaddin file out of this
9 | project, suitable for sharing or deployment
10 |
11 | config.xml : The AddIn configuration file
12 |
13 | Images/* : all UI images for the project (icons, images for buttons,
14 | etc)
15 |
16 | Install/* : The Python project used for the implementation of the
17 | AddIn. The specific python script to be used as the root
18 | module is specified in config.xml.
19 |
--------------------------------------------------------------------------------
/Layers/config.xml:
--------------------------------------------------------------------------------
1 | Layer Helper {7b8a5584-52b0-47d1-83c2-d1616f399131} Layer Helper 0.1 Images\maps-and-geolocation-layers-icon.png James Stephaniuk 12/11/2015
2 |
3 | Reset all layers to default properties, symbology, visibility, definition query and, transparency.
4 | Upon altering an attribute of any layer, press this button to save the changes to a layer file.
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Layers/makeaddin.py:
--------------------------------------------------------------------------------
1 | import os
2 | import re
3 | import zipfile
4 |
5 | current_path = os.path.dirname(os.path.abspath(__file__))
6 |
7 | out_zip_name = os.path.join(current_path,
8 | os.path.basename(current_path) + ".esriaddin")
9 |
10 | BACKUP_FILE_PATTERN = re.compile(".*_addin_[0-9]+[.]py$", re.IGNORECASE)
11 |
12 | def looks_like_a_backup(filename):
13 | return bool(BACKUP_FILE_PATTERN.match(filename))
14 |
15 | with zipfile.ZipFile(out_zip_name, 'w', zipfile.ZIP_DEFLATED) as zip_file:
16 | for filename in ('config.xml', 'README.txt', 'makeaddin.py'):
17 | zip_file.write(os.path.join(current_path, filename), filename)
18 | dirs_to_add = ['Images', 'Install']
19 | for directory in dirs_to_add:
20 | for (path, dirs, files) in os.walk(os.path.join(current_path,
21 | directory)):
22 | archive_path = os.path.relpath(path, current_path)
23 | found_file = False
24 | for file in (f for f in files if not looks_like_a_backup(f)):
25 | archive_file = os.path.join(archive_path, file)
26 | print archive_file
27 | zip_file.write(os.path.join(path, file), archive_file)
28 | found_file = True
29 | if not found_file:
30 | zip_file.writestr(os.path.join(archive_path,
31 | 'placeholder.txt'),
32 | "(Empty directory)")
33 |
--------------------------------------------------------------------------------
/PDF_Export_Addin/Images/Thumbs.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/PDF_Export_Addin/Images/Thumbs.db
--------------------------------------------------------------------------------
/PDF_Export_Addin/Images/cmyk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/PDF_Export_Addin/Images/cmyk.png
--------------------------------------------------------------------------------
/PDF_Export_Addin/Images/cube-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/PDF_Export_Addin/Images/cube-128.png
--------------------------------------------------------------------------------
/PDF_Export_Addin/Images/draftIcon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/PDF_Export_Addin/Images/draftIcon.png
--------------------------------------------------------------------------------
/PDF_Export_Addin/Images/pdf-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/PDF_Export_Addin/Images/pdf-icon.png
--------------------------------------------------------------------------------
/PDF_Export_Addin/Images/rgb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/PDF_Export_Addin/Images/rgb.png
--------------------------------------------------------------------------------
/PDF_Export_Addin/Install/PDF_Export_Addin_addin.py:
--------------------------------------------------------------------------------
1 | import arcpy
2 | import os
3 | import pythonaddins
4 |
5 | def exporter(colorspace, dpi):
6 | try:
7 | mxd = arcpy.mapping.MapDocument('CURRENT')
8 | ddp = mxd.dataDrivenPages
9 | pageName = str(ddp.pageRow.getValue(ddp.pageNameField.name))
10 |
11 | curDirPath = os.path.dirname(mxd.filePath)
12 | parDirPath = os.path.abspath(os.path.join(curDirPath, os.pardir))
13 | outDir = os.path.join(parDirPath, pageName, "PDF_Draft_Exports")
14 | if not os.path.exists(outDir):
15 | os.makedirs(outDir)
16 |
17 | # Logic to determine orientation of page.
18 | if mxd.pageSize.width == 72.0 and mxd.pageSize.height == 72.0:
19 | orient = "4sheet"
20 | elif mxd.pageSize.width == 36.0 and mxd.pageSize.height == 36.0:
21 | orient = "1sheet"
22 | elif mxd.pageSize.width == 72.0 and mxd.pageSize.height == 36.0:
23 | orient = "2sheet_horizontal"
24 | elif mxd.pageSize.width == 36.0 and mxd.pageSize.height == 72.0:
25 | orient = "2sheet_vertical"
26 | else :
27 | orient = "{}x{}".format(str(mxd.pageSize[0]), str(mxd.pageSize[1]))
28 |
29 | # Join output directory with formatted file name.
30 | PathOut = os.path.join(outDir,"{}_{}_{}_{}".format(pageName,str(dpi),colorspace,orient))
31 |
32 | # Export.
33 | arcpy.mapping.ExportToPDF(mxd, PathOut, resolution=dpi,image_quality="BEST",colorspace=colorspace, convert_markers=True)
34 |
35 | pythonaddins.MessageBox("Saved to \n{}\n as\n {}".format(outDir, os.path.split(PathOut)[1]),"Save Location")
36 |
37 | del mxd, ddp, pageName, outDir, orient, dpi, colorspace
38 | except Exception as e:
39 | pythonaddins.MessageBox(e, "Error Message")
40 | print e
41 | class CMYK(object):
42 | """Implementation for PDF_Export_Addin_addin.cmyk (Button)"""
43 | def __init__(self):
44 | self.enabled = True
45 | self.checked = False
46 | def onClick(self):
47 | # Call to exporter function.
48 | exporter("CMYK", 144)
49 |
50 | class RGB(object):
51 | """Implementation for PDF_Export_Addin_addin.rgb (Button)"""
52 | def __init__(self):
53 | self.enabled = True
54 | self.checked = False
55 | def onClick(self):
56 | # Call to exporter function.
57 | exporter("RGB", 144)
--------------------------------------------------------------------------------
/PDF_Export_Addin/PDF_Export_Addin.esriaddin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/PDF_Export_Addin/PDF_Export_Addin.esriaddin
--------------------------------------------------------------------------------
/PDF_Export_Addin/README.txt:
--------------------------------------------------------------------------------
1 | MANIFEST
2 | ========
3 |
4 | README.txt : This file
5 |
6 | makeaddin.py : A script that will create a .esriaddin file out of this
7 | project, suitable for sharing or deployment. Double-click
8 | this file to make the .esriaddin file. Then, double-click
9 | the .esriaddin file to install to ArcMap.
10 |
11 | config.xml : The AddIn configuration file
12 |
13 | Images/* : all UI images for the project (icons, images for buttons,
14 | etc)
15 |
16 | Install/* : The Python project used for the implementation of the
17 | AddIn. The specific python script to be used as the root
18 | module is specified in config.xml.
19 |
--------------------------------------------------------------------------------
/PDF_Export_Addin/config.xml:
--------------------------------------------------------------------------------
1 | PDF Exporter {e1c9e822-9d68-447f-a1ce-e810cb6f8e31} Exports PDFs 1.0 Images\pdf-icon.png James Stephaniuk EBC 12/11/2015
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/PDF_Export_Addin/makeaddin.py:
--------------------------------------------------------------------------------
1 | import os
2 | import re
3 | import zipfile
4 |
5 | current_path = os.path.dirname(os.path.abspath(__file__))
6 |
7 | out_zip_name = os.path.join(current_path,
8 | os.path.basename(current_path) + ".esriaddin")
9 |
10 | BACKUP_FILE_PATTERN = re.compile(".*_addin_[0-9]+[.]py$", re.IGNORECASE)
11 |
12 | def looks_like_a_backup(filename):
13 | return bool(BACKUP_FILE_PATTERN.match(filename))
14 |
15 | with zipfile.ZipFile(out_zip_name, 'w', zipfile.ZIP_DEFLATED) as zip_file:
16 | for filename in ('config.xml', 'README.txt', 'makeaddin.py'):
17 | zip_file.write(os.path.join(current_path, filename), filename)
18 | dirs_to_add = ['Images', 'Install']
19 | for directory in dirs_to_add:
20 | for (path, dirs, files) in os.walk(os.path.join(current_path,
21 | directory)):
22 | archive_path = os.path.relpath(path, current_path)
23 | found_file = False
24 | for file in (f for f in files if not looks_like_a_backup(f)):
25 | archive_file = os.path.join(archive_path, file)
26 | print archive_file
27 | zip_file.write(os.path.join(path, file), archive_file)
28 | found_file = True
29 | if not found_file:
30 | zip_file.writestr(os.path.join(archive_path,
31 | 'placeholder.txt'),
32 | "(Empty directory)")
33 |
--------------------------------------------------------------------------------
/PDF_Export_Stand_Alone/PDF_Export_Cmd.py:
--------------------------------------------------------------------------------
1 | #############################################################################
2 | # The MIT License (MIT)
3 | #
4 | # Copyright (c) 2015 James Stephaniuk
5 | #
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy
7 | # of this software and associated documentation files (the "Software"), to deal
8 | # in the Software without restriction, including without limitation the rights
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | # copies of the Software, and to permit persons to whom the Software is
11 | # furnished to do so, subject to the following conditions:
12 | #
13 | # The above copyright notice and this permission notice shall be included in
14 | # all copies or substantial portions of the Software.
15 | #
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 | # SOFTWARE.
23 | #
24 | #############################################################################
25 | # Usage: Run this script from the command line.
26 | # Navigate to this script's folder in the command line and type:
27 | # python [script name] "[mxd path]" [integer(for dpi)].
28 | #
29 | ##############################################################################
30 |
31 | import arcpy
32 | import datetime
33 | import getpass
34 | import logging
35 | import logging.handlers
36 | import os
37 | import shutil
38 | import sys
39 | import time
40 |
41 | ########################### User defined functions ###########################
42 |
43 | def exporter(mxdPath, user_dpi):
44 | log = logging.getLogger("script_log")
45 | try:
46 | mxd = arcpy.mapping.MapDocument(mxdPath)
47 | dpi = user_dpi
48 | colorspace = "CMYK"
49 | ddp = mxd.dataDrivenPages
50 | pageName = str(ddp.pageRow.getValue(ddp.pageNameField.name))
51 |
52 | log.info("MXD path: {}".format(mxd.filePath))
53 | log.info("DPI: {}".format(str(dpi)))
54 | log.info("Colorspace: {}".format(colorspace))
55 | log.info("Page Name: {}".format(pageName))
56 |
57 | curDirPath = os.path.dirname(mxd.filePath)
58 | parDirPath = os.path.abspath(os.path.join(curDirPath, os.pardir))
59 | outDir = os.path.join(parDirPath, pageName, "PDF_Draft_Exports")
60 | if not os.path.exists(outDir):
61 | os.makedirs(outDir)
62 | log.info("Output directory set to {}".format(outDir))
63 |
64 | # Logic to determine orientation of page.
65 | if mxd.pageSize.width == 72.0 and mxd.pageSize.height == 72.0:
66 | orient = "4sheet"
67 | elif mxd.pageSize.width == 36.0 and mxd.pageSize.height == 36.0:
68 | orient = "1sheet"
69 | elif mxd.pageSize.width == 72.0 and mxd.pageSize.height == 36.0:
70 | orient = "2sheet_horizontal"
71 | elif mxd.pageSize.width == 36.0 and mxd.pageSize.height == 72.0:
72 | orient = "2sheet_vertical"
73 | else :
74 | orient = "{}x{}".format(str(mxd.pageSize[0]), str(mxd.pageSize[1]))
75 |
76 | log.info("MXD page size: {} x {}. Orient set to: {}".format(mxd.pageSize.width, mxd.pageSize.height, orient))
77 |
78 | # Join output directory with formatted file name.
79 | PathOut = os.path.join(outDir,"{}_{}_{}_{}".format(pageName,str(dpi),colorspace,orient))
80 |
81 | # Export
82 | log.info("")
83 | log.info("PDF being created...")
84 | arcpy.mapping.ExportToPDF(mxd, PathOut, resolution=dpi,image_quality="BEST",colorspace=colorspace, convert_markers=True)
85 | log.info("PDF saved to: {}".format(PathOut))
86 |
87 | del mxd, ddp, pageName, outDir, orient, dpi, colorspace
88 | except Exception as e:
89 | log.info("An error occured: {}".format(e))
90 |
91 |
92 | def formatTime(x):
93 | minutes, seconds_rem = divmod(x, 60)
94 | if minutes >= 60:
95 | hours, minutes_rem = divmod(minutes, 60)
96 | return "%02d:%02d:%02d" % (hours, minutes_rem, seconds_rem)
97 | else:
98 | minutes, seconds_rem = divmod(x, 60)
99 | return "00:%02d:%02d" % (minutes, seconds_rem)
100 |
101 | def getPageName(mxdPath):
102 | mxd = arcpy.mapping.MapDocument(mxdPath)
103 | ddp = mxd.dataDrivenPages
104 | pageName = ddp.pageRow.getValue(ddp.pageNameField.name)
105 | return str(pageName)
106 |
107 | ##############################################################################
108 |
109 |
110 | if __name__ == "__main__":
111 | startTime = time.time()
112 | now = datetime.datetime.now()
113 |
114 | ############################ USER VARIABABLES ################################
115 | mxd = sys.argv[1]
116 | user_dpi = sys.argv[2]
117 |
118 | pageName = getPageName(mxd)
119 |
120 | # Log files folder will be created in the ddp edabbr folder.
121 | curDirPath = os.path.dirname(mxd)
122 | parDirPath = os.path.abspath(os.path.join(curDirPath, os.pardir))
123 | logPath = os.path.join(parDirPath, pageName, "Logfiles-PDF_Export")
124 | if not os.path.exists(logPath):
125 | os.makedirs(logPath)
126 |
127 | # Make a global logging object.
128 | logName = os.path.join(logPath,(getpass.getuser() + now.strftime("_%Y-%m-%d_%H-%M.log")) )
129 |
130 | log = logging.getLogger("script_log")
131 | log.setLevel(logging.INFO)
132 |
133 | h1 = logging.FileHandler(logName)
134 | h2 = logging.StreamHandler()
135 |
136 | f = logging.Formatter("[%(levelname)s] [%(asctime)s] [%(lineno)d] - %(message)s",'%m/%d/%Y %I:%M:%S %p')
137 |
138 | h1.setFormatter(f)
139 | h2.setFormatter(f)
140 |
141 | h1.setLevel(logging.INFO)
142 | h2.setLevel(logging.INFO)
143 |
144 | log.addHandler(h1)
145 | log.addHandler(h2)
146 |
147 | log.info('----------------------------------------------------')
148 | log.info('Script: {0}'.format(os.path.basename(sys.argv[0])))
149 | log.info('----------------------------------------------------')
150 |
151 | try:
152 | ########################### Function calls ###########################
153 | exporter(mxd, user_dpi)
154 |
155 | except Exception as e:
156 | log.exception(e)
157 |
158 | totalTime = formatTime((time.time() - startTime))
159 | log.info('----------------------------------------------------')
160 | log.info("Script Completed After: {0}".format(totalTime))
161 | log.info('----------------------------------------------------')
--------------------------------------------------------------------------------
/Page Layout Table/PageLayoutElements.cpg:
--------------------------------------------------------------------------------
1 | UTF-8
--------------------------------------------------------------------------------
/Page Layout Table/PageLayoutElements.dbf.xml:
--------------------------------------------------------------------------------
1 |
2 | 20140904 16150300 1.0 FALSE EDLI_Index 002 0.000 file://\\cygnusa\PUBLIC\15030 - Electoral Geography\30 - Geography Data\Spatial Data Project Work\DDP_Multiplie_Insets\DDP_Index.gdb Local Area Network Projected GCS_North_American_1983 Linear Unit: Meter (1.000000) Canada_Albers_Equal_Area_Conic <ProjectedCoordinateSystem xsi:type='typens:ProjectedCoordinateSystem' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xs='http://www.w3.org/2001/XMLSchema' xmlns:typens='http://www.esri.com/schemas/ArcGIS/10.1'><WKT>PROJCS["Canada_Albers_Equal_Area_Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Albers"],PARAMETER["False_Easting",1000000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-126.0],PARAMETER["Standard_Parallel_1",58.5],PARAMETER["Standard_Parallel_2",50.0],PARAMETER["Latitude_Of_Origin",45.0],UNIT["Meter",1.0]]</WKT><XOrigin>-13239300</XOrigin><YOrigin>-8610100</YOrigin><XYScale>10000</XYScale><ZOrigin>-100000</ZOrigin><ZScale>10000</ZScale><MOrigin>-100000</MOrigin><MScale>10000</MScale><XYTolerance>0.001</XYTolerance><ZTolerance>0.001</ZTolerance><MTolerance>0.001</MTolerance><HighPrecision>true</HighPrecision></ProjectedCoordinateSystem> FeatureClassToFeatureClass GPL0 C:\Temp\DDP_InsetTest Scale_test.shp # "uniq_id "uniq_id" true true false 4 Long 0 10 ,First,#,GPL0,uniq_id,-1,-1;edname "edname" true true false 100 Text 0 0 ,First,#,GPL0,edname,-1,-1;edabbr "edabbr" true true false 3 Text 0 0 ,First,#,GPL0,edabbr,-1,-1;regcode "regcode" true true false 10 Text 0 0 ,First,#,GPL0,regcode,-1,-1;edeffctved "edeffctved" true true false 36 Date 0 0 ,First,#,GPL0,edeffctvedt,-1,-1;edexpirydt "edexpirydt" true true false 36 Date 0 0 ,First,#,GPL0,edexpirydt,-1,-1;ed_spare1 "ed_spare1" true true false 10 Text 0 0 ,First,#,GPL0,ed_spare1,-1,-1;ed_spare2 "ed_spare2" true true false 10 Text 0 0 ,First,#,GPL0,ed_spare2,-1,-1;SE_Area_bo "SE_Area_bo" false true true 0 Double 0 0 ,First,#,GPL0,SE_Area(boundary_linework),-1,-1;SE_Length_ "SE_Length_" false true true 0 Double 0 0 ,First,#,GPL0,SE_Length(boundary_linework),-1,-1" # AddField C:\Temp\DDP_InsetTest\Scale_test.shp scale FLOAT # # # # NULLABLE NON_REQUIRED # AddScale C:\Temp\DDP_InsetTest\EDLI_Template_DDP_Inset.mxd C:\Temp\DDP_InsetTest\Scale_test.shp CalculateField Scale_test Scale_1 [scale] VB # CalculateField Scale_test Rotation [Orient] VB # CalculateField PageLayoutElements Name [edname] VB # CalculateField PageLayoutElements Name [edabbr] VB # CalculateField PageLayoutElements MAINDF "" PYTHON_9.3 # CalculateField PageLayoutElements INSET1 "" PYTHON_9.3 # CalculateField PageLayoutElements INSET2 "" PYTHON_9.3 # CalculateField PageLayoutElements TITLE_NORT "" PYTHON_9.3 # CalculateField PageLayoutElements DISTRICT "" PYTHON_9.3 # DeleteRows PageLayoutElements 20140904 16131800 20140904 16131800 Microsoft Windows 7 Version 6.1 (Build 7601) Service Pack 1; Esri ArcGIS 10.2.1.3497 EDLI_Index File Geodatabase Feature Class 0.000 dataset 0 Simple FALSE 0 TRUE FALSE EDLI_Index Feature Class 0 OBJECTID OBJECTID OID 4 0 0 Internal feature number. Esri Sequential unique whole numbers that are automatically generated. Shape Shape Geometry 0 0 0 Feature geometry. Esri Coordinates defining the features. edname edname String 100 0 0 edabbr edabbr String 3 0 0 ed_spare1 ed_spare1 String 10 0 0 ed_spare2 ed_spare2 String 10 0 0 scale scale Single 4 0 0 Rotation Rotation Double 8 0 0 Orient Orient String 10 0 0 MainDF MainDF String 100 0 0 Inset1 Inset1 String 100 0 0 Inset2 Inset2 String 100 0 0 Inset3 Inset3 String 100 0 0 Inset4 Inset4 String 100 0 0 Inset5 Inset5 String 100 0 0 Inset6 Inset6 String 100 0 0 Inset7 Inset7 String 100 0 0 Inset8 Inset8 String 100 0 0 Name Name String 50 0 0 Title_Nort Title_Nort String 50 0 0 Shape_Length Shape_Length Double 8 0 0 Length of feature in internal units. Esri Positive real numbers that are automatically generated. Shape_Area Shape_Area Double 8 0 0 Area of feature in internal units squared. Esri Positive real numbers that are automatically generated. 20140904
3 |
--------------------------------------------------------------------------------
/Page Layout Table/info/arc.dir:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Page Layout Table/info/arc.dir
--------------------------------------------------------------------------------
/Python/AnnoQuery.py:
--------------------------------------------------------------------------------
1 |
2 | def Anno():
3 | """Turns on the annotation for only the current DDP."""
4 | import arcpy
5 | import collections
6 |
7 | mxd = arcpy.mapping.MapDocument("current") #CURRENT.
8 | try:
9 | ddp = mxd.dataDrivenPages
10 | except:
11 | print "Data Driven Pages in not enabled on this map document"
12 | try:
13 | annoLyr = arcpy.mapping.ListLayers(mxd,"Annotation")[0]
14 | except:
15 | print "No layer named 'Annotation'"
16 |
17 | pageName = ddp.pageRow.getValue(ddp.pageNameField.name)
18 |
19 | for lyr in annoLyr:
20 | if lyr.supports("DATASOURCE"):
21 | tableCount = collections.Counter(row[0] for row in arcpy.da.SearchCursor(lyr, "TileID"))
22 | if tableCount:
23 | if str(arcpy.da.SearchCursor(lyr, "TileID").next()[0]) == str(pageName):
24 | lyr.visible = True
25 | else:
26 | lyr.visible = False
27 | else:
28 | lyr.visible = False
29 | arcpy.RefreshTOC()
30 | del lyr
31 | del annoLyr
32 | del tableCount
33 | del pageName
34 | del mxd
35 | del ddp
36 |
37 | # for lyr in annoLyr:
38 | # if lyr.supports("DATASOURCE"):
39 | # TileID = arcpy.da.SearchCursor(lyr,"TileID", "Name = '" + pageName + "'")
40 | # print pageName
41 |
42 |
43 | # #set pageName
44 |
45 | # # 1) Loop the Annotation Layer
46 | # # 2) if layer supports "DATASOURCE" (Or whatever) continue. Change this to check for NONE type.
47 | # # 3) if layer field of TileID= pageName
48 | # # 4) set visible to true.
49 |
50 |
51 | # mxd = arcpy.mapping.MapDocument("current") #CURRENT.
52 | # ddp = mxd.dataDrivenPages
53 |
54 | # annoLyr = arcpy.mapping.ListLayers(mxd,"Annotation")[0]
55 | # pageName = ddp.pageRow.getValue(ddp.pageNameField.name)
56 | # for lyr in annoLyr: #Loop each feature in Annotation.
57 | # if arcpy.management.GetCount(lyr)[0] == "0":
58 | # with arcpy.da.SearchCursor(lyr, "TileID") as cursor:
59 | # for row in cursor:
60 | # if str(row[0]) == str(pageName):
61 | # lyr.visible = True
62 | # else:
63 | # lyr.visible = False
64 | # arcpy.RefreshTOC()
65 | # _____________________________________________________________________________________________________________
66 |
67 | # annoLyr = arcpy.mapping.ListLayers(mxd,"Annotation")[0]
68 | # pageName = ddp.pageRow.getValue(ddp.pageNameField.name)
69 |
70 | # for lyr in annoLyr: # Loop Annotation layers.
71 | # if lyr.supports("DATASOURCE"): # Check to avoid sub layer (usually called 'Default').
72 | # # Check for empty table.
73 | # tileID = arcpy.da.SearchCursor(lyr,"TileID")
74 | # if str(tileID) == str(pageName):
75 | # lyr.visible = True
76 | # else:
77 | # lyr.visible = False
78 | # break
79 |
80 | # arcpy.RefreshTOC()
81 |
82 |
83 | # _____________________________________________________________________________________________________________
84 |
--------------------------------------------------------------------------------
/Python/BrokenDataSources.py:
--------------------------------------------------------------------------------
1 | import arcpy.mapping as mapping, os
2 | path = r"C:"
3 | f = open(r"C:\Users\jastepha\Desktop\BrokenDataList.txt",'w')
4 | for root,dirs,files in os.walk(path):
5 | for filename in files:
6 | basename, extension = os.path.splitext(filename)
7 | if extension == ".mxd":
8 | fullPath = os.path.join(path,filename)
9 | mxd = mapping.MapDocument(fullPath)
10 | f.write("MXD: " + filename + "\n")
11 | brknList = mapping.ListBrokenDataSources(mxd)
12 | for brknItem in brknList:
13 | f.write("\t" + brknItem.name + "\n")
14 | f.close()
15 |
16 |
--------------------------------------------------------------------------------
/Python/ExtentBoxexRemovePts.py:
--------------------------------------------------------------------------------
1 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""
2 | # ExtentBoxexRemovePts.py
3 | # Remove specific points from Inset Extent boxes.
4 | #
5 | #
6 | # Assumptions:
7 | # Main map (the one with the extent boxes) is first in TOC
8 | #
9 |
10 | """""""""""""""""""""""""""""""""""""""""""""""""""""""""""
11 | import arcpy
12 |
13 | # Adds this script to system path. Used for separation of main script from other code packages.
14 | sys.path.append(os.path.dirname(__file__))
15 |
16 | from poiDict import poiLyrDict
17 | import clearAllFuncs
18 |
19 | # Reference current mxd.
20 | mxd = arcpy.mapping.MapDocument("CURRENT")
21 | # Create list of all data frames (df's).
22 | dfLst = arcpy.mapping.ListDataFrames(mxd)
23 | # Reference main df.
24 | mainDF = dfLst[0]
25 | # Create list of inset df's.
26 | insetLst = dfLst[1:]
27 |
28 |
29 | # # Create list of Points of Interest layers.
30 | # poiLst = []
31 | # lyrLst = arcpy.mapping.ListLayers(mxd, "*", mainDF)
32 | # for lyr in lyrLst:
33 | # if lyr.name in poiLyrDict:
34 |
35 |
36 | # # Skeleton code to access dict key/value pairs.
37 | # # for key in poiLyrDict:
38 | # # print key + " has the values of: "
39 | # # for item in poiLyrDict[key]:
40 | # # print item
41 |
42 | #########################################
43 | ############### Extents #################
44 | #########################################
45 |
46 | # Create list of all data frames (df's).
47 | dfLst = arcpy.mapping.ListDataFrames(mxd)
48 | # Create list of inset df's.
49 | insetLst = dfLst[1:]
50 | # Create dictionary for extent(s) of box(es)/inset(s). Extent format: XMin, XMax, YMin, YMax (as tuple).
51 | insetExtentDict = {}
52 | for x in range(len(insetLst)):
53 | insetExtentDict["Inset{0}".format(x)] = insetLst[x].extent.XMin, insetLst[x].extent.XMax, insetLst[x].extent.YMin, insetLst[x].extent.YMax
54 | # insetExtentDict["Inset{0}".format(x)] = insetLst[x].extent # Dict populated with extent object instead of extent values.
55 |
56 | lyrLst = arcpy.mapping.ListLayers(mxd, "*", mainDF)
57 | for lyr in lyrLst:
58 | if lyr.name in poiLyrDict:
59 | # Select by location (extents)
60 |
61 | # Remove points in target extent box.
62 | # Select specific points in extent box (from extentDict)
63 | # if XMin < point.x < XMax and YMin < point.y < YMax:
64 | # Apply queries.
--------------------------------------------------------------------------------
/Python/RepairBrokenLayers.py:
--------------------------------------------------------------------------------
1 | import arcpy
2 | import os
3 |
4 | mxd = arcpy.mapping.MapDocument('CURRENT')
5 |
6 | lyrLst = arcpy.mapping.ListLayers(mxd)
7 |
8 | # Change to location of your geodatabase.
9 | gdbPath = r"P:\15030_32_EBC_Digital_Mapping\MapData\2015 By Election Data\Replicate.gdb"
10 |
11 | for lyr in lyrLst:
12 | if lyr.isBroken:
13 | if lyr.supports("DATASETNAME"):
14 | mxd.findAndReplaceWorkspacePaths(lyr.workspacePath, gdbPath + lyr.datasetName, False)
15 | print "Layer {} repaired.".format(lyr.name)
16 |
17 | arcpy.RefreshTOC()
--------------------------------------------------------------------------------
/Python/SDE_to_FGDB_BuiltInList.py:
--------------------------------------------------------------------------------
1 | """Module docstring.
2 | creat_FGDB_from_FCs.PY
3 | Long Usage:
4 | This scripts takes files from a SDE database and copies it to a local file geodatabase.
5 |
6 | change dir to the output directory location
7 | change input_source to the SDE connection file'
8 | change fc_list to point to a text file that contains feature names you want copied.
9 | change arcgis_version to the output FGDB output version
10 | """
11 |
12 | import arcpy
13 | import os
14 | import shutil
15 | import sys
16 |
17 | #set output location for FGDB
18 | outDir = r"C:\Users\jastepha\Desktop\test"
19 |
20 | #set input location (sde connection file)
21 | #the pre-defined SDE connection file for input SOURCE
22 | input_source = r"C:\Users\jastepha\AppData\Roaming\ESRI\Desktop10.2\ArcCatalog\Connection to indeaprod2.sde"
23 |
24 | #set the list of FCs you want to copy to FGDB
25 | fc_list = ['indea:genmaint.idm_eds_std', 'indea:genmaint.cart_point_vas_std', 'indea:genmaint.idm_ebc_buildings']
26 |
27 | arcgis_version = "10.0"
28 |
29 | # set the Source Feature Class you want to bring over in a txt file list for looping - this will create one FGDB for every FC
30 | #(list of SCHEMA.TABLENAMES)
31 | for input_fc in fc_list:
32 | print input_fc
33 | input_fc.split(".", 2)
34 | input_table = input_fc.split(".")[1]
35 | print input_table
36 |
37 | arcpy.env.workspace = outDir + "\\" + input_table + ".gdb"
38 |
39 | #set the output location
40 | outWorkspace = arcpy.env.workspace
41 | output = outWorkspace + "\\" + input_table
42 |
43 | # if FGDB exists then delete it.. (without prompt)
44 | if os.path.exists(outWorkspace):
45 | print "already exists so deleting FGDB first: " + outWorkspace
46 | shutil.rmtree(outWorkspace)
47 |
48 | input = input_source + "\\" + input_fc
49 | print "input: " + input
50 |
51 | # set some defaults
52 | arcpy.env.extent = arcpy.Extent(200000,200000,1900000,1900000)
53 | schemaType = "NO_TEST"
54 | fieldMappings = ""
55 | subtype = ""
56 |
57 | #set the projection to BC Albers.
58 | arcpy.env.outputCoordinateSystem = arcpy.SpatialReference(3005)
59 |
60 | # print the environment list
61 | environments = arcpy.ListEnvironments()
62 |
63 | for environment in environments:
64 | # Use Python's eval function to evaluate an environment's value
65 | envSetting = eval("arcpy.env." + environment)
66 | # Format and print each environment and its current setting
67 | print "%-30s: %s" % (environment, envSetting)
68 |
69 |
70 | #do it.
71 | try:
72 | print "creating FGDB"
73 | #create a FGDB in v10 based on table name (you could parameterized the diretory)
74 | arcpy.CreateFileGDB_management(outDir, input_table,arcgis_version)
75 |
76 | #set the output location
77 | output = outWorkspace + "\\" + input_table
78 |
79 | print "creating feature class using FCtoFC_conversion function: " + output
80 | print "input " + input
81 | print "output " + output
82 |
83 | arcpy.FeatureClassToFeatureClass_conversion(input, outWorkspace, input_table)
84 |
85 | except:
86 | # If an error occurred while running a tool print the messages
87 | print arcpy.GetMessages()
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/Python/SelectCommunities.py:
--------------------------------------------------------------------------------
1 | import arcpy
2 |
3 | mxd = arcpy.mapping.MapDocument("CURRENT")
4 | ddp = mxd.dataDrivenPages
5 | pageName = ddp.pageRow.getValue(ddp.pageNameField.name) # ED NAME
6 | pageNameField = ddp.pageNameField.name # DIST_NAME
7 |
8 | EDLyr = ddp.indexLayer
9 | targetED = pageName
10 | communitiesLyr = arcpy.mapping.ListLayers(mxd, "indea_background_ebc_communities_active")[0]
11 | commLyr_fieldname = "featname"
12 |
13 |
14 | # Select target ED.
15 | arcpy.SelectLayerByAttribute_management(EDLyr, "NEW_SELECTION","{0} = '{1}'".format(pageNameField, targetED))
16 | # Select points within target ED.
17 | arcpy.SelectLayerByLocation_management(communitiesLyr,"COMPLETELY_WITHIN", EDLyr, 0, "NEW_SELECTION")
18 |
19 | # Create list of selected points.
20 | commLst = []
21 | for row in arcpy.da.SearchCursor(communitiesLyr, commLyr_fieldname):
22 | commLst.append(row[0])
23 |
24 | # Build query from list.
25 | query = "{0} IN ({1})".format(commLyr_fieldname, ', '.join("'" + comm + "'" for comm in commLst))
26 |
27 | # Apply definition query to communities layer.
28 | communitiesLyr.definitionQuery = query
29 |
30 | # Clear the selections.
31 | # arcpy.SelectLayerByAttribute_management(EDLyr, "CLEAR_SELECTION")
32 | # arcpy.SelectLayerByAttribute_management(communitiesLyr, "CLEAR_SELECTION")
33 |
--------------------------------------------------------------------------------
/Python/SelectPointsInTargetED.py:
--------------------------------------------------------------------------------
1 | if __name__ == "__main__":
2 | import arcpy
3 |
4 | mxd = arcpy.mapping.MapDocument("CURRENT")
5 | ddp = mxd.dataDrivenPages
6 | pageName = ddp.pageRow.getValue(ddp.pageNameField.name) # ED NAME
7 | pageNameField = ddp.pageNameField.name # DIST_NAME
8 |
9 | EDLyr = ddp.indexLayer
10 | targetED = pageName
11 |
12 | # # Function to clear all queries.
13 | def clearAllQueries():
14 | for lyr in arcpy.mapping.ListLayers(arcpy.mapping.MapDocument("CURRENT")):
15 | if lyr.supports("DEFINITIONQUERY"):
16 | lyr.definitionQuery = ""
17 | print "Query for {0} layer cleared.".format(lyr.name)
18 | arcpy.RefreshActiveView()
19 |
20 | def clearAllSelections():
21 | for lyr in arcpy.mapping.ListLayers(arcpy.mapping.MapDocument("CURRENT")):
22 | arcpy.SelectLayerByAttribute_management(lyr, "CLEAR_SELECTION")
23 |
24 | clearAllQueries()
25 | clearAllSelections()
26 |
27 |
28 | # Dictionary of the point layers (keys) and their building use codes (values).
29 | # poiLyrDict = {
30 | # "Airports": [
31 | # r'%Aero_Air%',
32 | # r'%Aero_Water%'
33 | # ],
34 | # "Fire Hall": [
35 | # r'%Fire%'
36 | # ],
37 | # "Golf Course": [
38 | # r'%Rec_Golf%'
39 | # ],
40 | # "Hall": [
41 | # r'%Civ_CommHall%',
42 | # r'%Com_Church%',
43 | # r'%Com_Centre%'
44 | # ],
45 | # "Hospital": [
46 | # r'%Hosp_Care%',
47 | # r'%Hosp_Ext%',
48 | # r'%Hosp_Hosp%'
49 | # ],
50 | # "School": [
51 | # r'%PostSec_Acad%',
52 | # r'%PostSec_Coll%',
53 | # r'%PostSec_Inst%',
54 | # r'%PostSec_PSec%',
55 | # r'%PostSec_Univ%',
56 | # r'%Sch_Std%'
57 | # ]
58 | # }
59 |
60 | # Select target ED.
61 | arcpy.SelectLayerByAttribute_management(EDLyr, "NEW_SELECTION","{0} = '{1}'".format(pageNameField, targetED))
62 | # Select points within target ED.
63 | for key in poiLyrDict:
64 | poiLyr = arcpy.mapping.ListLayers(mxd, key)[0]
65 | arcpy.SelectLayerByLocation_management(poiLyr, "COMPLETELY_WITHIN", EDLyr, 0, "ADD_TO_SELECTION")
66 |
67 |
68 | for key, values in poiLyrDict.iteritems():
69 | oidLst = [] # Create list for selected points OIDs.
70 | poiLyr = arcpy.mapping.ListLayers(mxd, key)[0]
71 | bldgQuery = " OR ".join('"bldguses" LIKE %s' % "'" + value + "'" for value in values)
72 | for row in arcpy.da.SearchCursor(poiLyr, "OID@"):
73 | oidLst.append(row[0])
74 | if oidLst:
75 | ptQuery = '\"{0}\" IN ({1})'.format("FID", ', '.join(str(oid) for oid in oidLst)) # Build query from list. May need to change FID.
76 | arcpy.mapping.ListLayers(mxd, key)[0].definitionQuery = ptQuery #+ " AND " + bldgQuery# Apply definition query to layer.
77 | else:
78 | ptQuery = '\"{0}\" IN (-1)'.format("FID") # Build query for empty set. May need to change FID.
79 | arcpy.mapping.ListLayers(mxd, key)[0].definitionQuery = ptQuery #+ " AND " + bldgQuery# Apply definition query to layer.
80 |
81 |
82 | arcpy.RefreshActiveView()
83 |
84 | # Clear the selections.
85 | arcpy.SelectLayerByAttribute_management(EDLyr, "CLEAR_SELECTION")
86 |
87 | # Delete variables.
88 | # del mxd, ddp, pageName, pageNameField, EDLyr, targetED, key, oidLst, poiLyr, row
89 |
90 |
91 |
92 | # "bldguses" LIKE '%Aero_Air%' OR bldguses LIKE '%Aero_Water%'
93 |
--------------------------------------------------------------------------------
/Python/StripDataFromMXD.py:
--------------------------------------------------------------------------------
1 | import arcpy
2 | mxdPath = "C:\Users\jastepha\Desktop\EDVA Maps\MXD_templates\EDVA_Map_Template_4Sheet.mxd"
3 | mxd = arcpy.mapping.MapDocument(mxdPath)
4 | dfLst = arcpy.mapping.ListDataFrames(mxd)
5 | for df in dfLst:
6 | for lyr in arcpy.mapping.ListLayers(mxd, data_frame=df):
7 | if lyr.supports("DATASOURCE"):
8 | if not "Index" in lyr.dataSource:
9 | arcpy.mapping.RemoveLayer(df, lyr)
10 |
11 | mxdSave = mxdPath.split(".")[0] + "_No_Layers.mxd"
12 | mxd.saveACopy(mxdSave)
--------------------------------------------------------------------------------
/Python/_template.py:
--------------------------------------------------------------------------------
1 | # Copyright: (c) company name
2 | # ArcGIS Version: 10
3 | # Python Version: 2.6
4 | #--------------------------------
5 | import arcpy
6 | import os
7 | import sys
8 |
9 | def do_analysis(*argv):
10 | """TODO: Add documentation about this function here"""
11 | try:
12 | #TODO: Add analysis here
13 | pass
14 | except arcpy.ExecuteError:
15 | print arcpy.GetMessages(2)
16 | except Exception as e:
17 | print e.args[0]
18 |
19 |
20 |
21 | # This test allows the script to be used from the operating
22 | # system command prompt (stand-alone), in a Python IDE,
23 | # as a geoprocessing script tool, or as a module imported in
24 | # another script.
25 | if __name__ == '__main__':
26 | # Arguments are optional
27 | argv = tuple(arcpy.GetParameterAsText(i)
28 | for i in range(arcpy.GetArgumentCount()))
29 | do_analysis(*argv)
--------------------------------------------------------------------------------
/Python/batchRename.py:
--------------------------------------------------------------------------------
1 | import arcpy
2 | from arcpy import env
3 |
4 | env.workspace = r"P:\15045 - ED Redistribution - Event Specific\R2015\21-Electoral_Boundaries_Commission_Support_Doc\WBS 8 - Geography\Mapping\local_shp\Anno GDBs\MDF Anno GDBs\D2_MDF_147250.gdb" # copy and paste directory between quotation marks.
5 |
6 | oldScale = "147250" # e.g. "119500"
7 | newScale = "666" # e.g. "_100000"
8 |
9 | for fc in arcpy.ListFeatureClasses():
10 | arcpy.Rename_management(fc, fc.replace(oldScale, newScale))
11 |
--------------------------------------------------------------------------------
/Python/dataFrameExtentPolygons.py:
--------------------------------------------------------------------------------
1 | import arcpy, json, os, sys
2 |
3 | #Function that arranges data frames based on the field info within the PageLayoutElements table
4 | def arrangeDFs(row, dfName):
5 | rowInfo = json.loads(row.getValue(dfName))
6 | try:
7 | df = arcpy.mapping.ListDataFrames(mxd, dfName)[0]
8 | df.elementPositionX = rowInfo[0]
9 | df.elementPositionY = rowInfo[1]
10 | df.elementWidth = rowInfo[2]
11 | df.elementHeight = rowInfo[3]
12 | newExtent = df.extent
13 | newExtent.XMin = rowInfo[4]
14 | newExtent.YMin = rowInfo[5]
15 | newExtent.XMax = rowInfo[6]
16 | newExtent.YMax = rowInfo[7]
17 | df.extent = newExtent
18 | df.scale = rowInfo[8]
19 | df.rotation = rowInfo[9]
20 | except IndexError:
21 | pass
22 |
23 | ################################################################################
24 |
25 | mxd = arcpy.mapping.MapDocument('CURRENT')
26 | ddp = mxd.dataDrivenPages
27 | inset = "Inset" + "1" # Change value to '1', '2', '3', or '4' to control which inset polygons are made for.
28 | df_lst = arcpy.mapping.ListDataFrames(mxd, inset)
29 |
30 | feature_info = []
31 |
32 | # Determine page orientation to append to output filename. Fallback to DDP count.
33 | if mxd.pageSize.width > mxd.pageSize.height:
34 | orient = "_L_"
35 | elif mxd.pageSize.width < mxd.pageSize.height:
36 | orient = "_P_"
37 | else:
38 | orient = "square"
39 |
40 | # Loop each DDP.
41 | for page in range(1, ddp.pageCount + 1):
42 | ddp.currentPageID = page
43 | # ArrangeDFs.
44 | pageName = ddp.pageRow.getValue(ddp.pageNameField.name)
45 | pageLayoutTable = arcpy.mapping.ListTableViews(mxd, "PageLayoutElements")[0] #Reference pageLayoutTable
46 | #Move all data frames off the layout and into their default positions
47 | pageLayoutCursor = arcpy.SearchCursor(pageLayoutTable.dataSource, "District = '" + pageName + "'")
48 | pageLayoutRow = pageLayoutCursor.next()
49 |
50 | for df in df_lst:
51 | arrangeDFs(pageLayoutRow, df.name)
52 | # Only creates geometry for data frames on the page.
53 | if (df.elementPositionX > 0 and df.elementPositionX < 11 and
54 | df.elementPositionY > 0 and df.elementPositionY < 8.5):
55 | XMin = df.extent.XMin
56 | YMin = df.extent.YMin
57 | XMax = df.extent.XMax
58 | YMax = df.extent.YMax
59 | # A list of features and coordinate pairs
60 | df_info = [[XMin, YMin],[XMax, YMin],[XMax, YMax],[XMin, YMax]]
61 | feature_info.append(df_info)
62 |
63 | # A list that will hold each of the Polygon objects
64 | features = []
65 |
66 | for feature in feature_info:
67 | # Create a Polygon object based on the array of points
68 | # Append to the list of Polygon objects
69 | features.append(
70 | arcpy.Polygon(
71 | arcpy.Array([arcpy.Point(*coords) for coords in feature])))
72 |
73 | # Persist a copy of the Polygon objects using CopyFeatures
74 | outDir = r"P:\15045 - ED Redistribution - Event Specific\R2015\21-Electoral_Boundaries_Commission_Support_Doc\WBS 8 - Geography\James\DataFrame_Polygon_Boxes"
75 | poly_filename = outDir + r"/dataframePolygons" + orient + inset + ".shp"
76 | if os.path.exists(poly_filename):
77 | os.remove(poly_filename)
78 | arcpy.CopyFeatures_management(features, poly_filename)
79 |
80 | del coords, feature_info, features, feature, poly_filename, outDir, mxd, df_lst, df_info, df, inset, XMax, XMin, YMax, YMin, page, orient, ddp, pageName, pageLayoutCursor, pageLayoutTable, pageLayoutRow
--------------------------------------------------------------------------------
/Python/dataFrameExtentPolygonsModified.py:
--------------------------------------------------------------------------------
1 | import arcpy, os, sys
2 |
3 | mxd = arcpy.mapping.MapDocument('CURRENT')
4 | ddp = mxd.dataDrivenPages
5 | df_lst = arcpy.mapping.ListDataFrames(mxd)
6 | inset_lst = arcpy.mapping.ListDataFrames(mxd)[1:]
7 |
8 | feature_info = []
9 |
10 | # A list that will hold each of the Polygon objects
11 | features = []
12 |
13 | # Determine page orientation to append to output filename. Fallback to DDP count.
14 | if mxd.pageSize.width > mxd.pageSize.height:
15 | orient = "_L"
16 | elif mxd.pageSize.width < mxd.pageSize.height:
17 | orient = "_P"
18 | else:
19 | orient = "_sq"
20 |
21 | for df in inset_lst:
22 | # Only creates geometry for data frames on the page.
23 | if (df.elementPositionX > 0 and df.elementPositionX < mxd.pageSize[0] and
24 | df.elementPositionY > 0 and df.elementPositionY < mxd.pageSize[1]):
25 | XMin = df.extent.XMin
26 | YMin = df.extent.YMin
27 | XMax = df.extent.XMax
28 | YMax = df.extent.YMax
29 | # A list of features and coordinate pairs
30 | df_info = [[XMin, YMin],[XMax, YMin],[XMax, YMax],[XMin, YMax]]
31 | feature_info.append(df_info)
32 |
33 |
34 |
35 | for feature in feature_info:
36 | # Create a Polygon object based on the array of points
37 | # Append to the list of Polygon objects
38 | features.append(
39 | arcpy.Polygon(
40 | arcpy.Array([arcpy.Point(*coords) for coords in feature])))
41 |
42 | # Persist a copy of the Polygon objects using CopyFeatures
43 | outDir = r"P:\15045 - ED Redistribution - Event Specific\R2015\21-Electoral_Boundaries_Commission_Support_Doc\WBS 8 - Geography\James\py" # TODO: Change out location.
44 | poly_filename = outDir + r"/dataframePolygon.shp"
45 | if os.path.exists(poly_filename):
46 | os.remove(poly_filename)
47 | arcpy.CopyFeatures_management(features, poly_filename)
48 |
49 | del coords, feature_info, features, feature, poly_filename, outDir, mxd, df_lst, df_info, df, XMax, XMin, YMax, YMin, orient, ddp
--------------------------------------------------------------------------------
/Python/dataframePolygon.cpg:
--------------------------------------------------------------------------------
1 | UTF-8
--------------------------------------------------------------------------------
/Python/dataframePolygon.dbf:
--------------------------------------------------------------------------------
1 | s A Id N
0
--------------------------------------------------------------------------------
/Python/dataframePolygon.sbn:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Python/dataframePolygon.sbn
--------------------------------------------------------------------------------
/Python/dataframePolygon.sbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Python/dataframePolygon.sbx
--------------------------------------------------------------------------------
/Python/dataframePolygon.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Python/dataframePolygon.shp
--------------------------------------------------------------------------------
/Python/dataframePolygon.shp.xml:
--------------------------------------------------------------------------------
1 |
2 | 20150615 14565600 1.0 FALSE dataframePolygon 002 0.000 file://\\cygnusa\PUBLIC\15045 - ED Redistribution - Event Specific\R2015\21-Electoral_Boundaries_Commission_Support_Doc\WBS 8 - Geography\James\py\dataframePolygon.shp Local Area Network CopyFeatures in_memory\f67BF43B9_C5A6_47E5_BC7F_4B655E672577 "P:\15045 - ED Redistribution - Event Specific\R2015\21-Electoral_Boundaries_Commission_Support_Doc\WBS 8 - Geography\James\py\dataframePolygon.shp" # 0 0 0 20150615 14565600 20150615 14565600 Microsoft Windows 7 Version 6.1 (Build 7601) Service Pack 1; Esri ArcGIS 10.2.1.3497 dataframePolygon Shapefile 0.000 dataset 0 Simple FALSE 0 FALSE FALSE dataframePolygon Feature Class 0 FID FID OID 4 0 0 Internal feature number. Esri Sequential unique whole numbers that are automatically generated. Shape Shape Geometry 0 0 0 Feature geometry. Esri Coordinates defining the features. Id Id Integer 6 6 0 20150615
3 |
--------------------------------------------------------------------------------
/Python/dataframePolygon.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Python/dataframePolygon.shx
--------------------------------------------------------------------------------
/Python/dataframePolygonsY_sq.cpg:
--------------------------------------------------------------------------------
1 | UTF-8
--------------------------------------------------------------------------------
/Python/dataframePolygonsY_sq.dbf:
--------------------------------------------------------------------------------
1 | s A Id N
0
--------------------------------------------------------------------------------
/Python/dataframePolygonsY_sq.sbn:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Python/dataframePolygonsY_sq.sbn
--------------------------------------------------------------------------------
/Python/dataframePolygonsY_sq.sbx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Python/dataframePolygonsY_sq.sbx
--------------------------------------------------------------------------------
/Python/dataframePolygonsY_sq.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Python/dataframePolygonsY_sq.shp
--------------------------------------------------------------------------------
/Python/dataframePolygonsY_sq.shp.xml:
--------------------------------------------------------------------------------
1 |
2 | 20150611 15295700 1.0 FALSE dataframePolygonsY_sq 002 0.000 file://\\cygnusa\PUBLIC\15045 - ED Redistribution - Event Specific\R2015\21-Electoral_Boundaries_Commission_Support_Doc\WBS 8 - Geography\James\py\dataframePolygonsY_sq.shp Local Area Network CopyFeatures in_memory\fAAAA2CBB_6FA6_4D33_88C2_AC28129D0F38 "P:\15045 - ED Redistribution - Event Specific\R2015\21-Electoral_Boundaries_Commission_Support_Doc\WBS 8 - Geography\James\py\dataframePolygonsY_sq.shp" # 0 0 0 20150611 15295700 20150611 15295700 Microsoft Windows 7 Version 6.1 (Build 7601) Service Pack 1; Esri ArcGIS 10.2.1.3497 dataframePolygonsY_sq Shapefile 0.000 dataset 0 Simple FALSE 0 FALSE FALSE dataframePolygonsY_sq Feature Class 0 FID FID OID 4 0 0 Internal feature number. Esri Sequential unique whole numbers that are automatically generated. Shape Shape Geometry 0 0 0 Feature geometry. Esri Coordinates defining the features. Id Id Integer 6 6 0 20150611
3 |
--------------------------------------------------------------------------------
/Python/dataframePolygonsY_sq.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/Python/dataframePolygonsY_sq.shx
--------------------------------------------------------------------------------
/Python/dfScaleMatch.py:
--------------------------------------------------------------------------------
1 | import arcpy
2 | import collections
3 | import re
4 |
5 | mxd = arcpy.mapping.MapDocument("current") #CURRENT.
6 | ddp = mxd.dataDrivenPages
7 | df = arcpy.mapping.ListDataFrames(mxd, "MainDF")[0]
8 | dfScale = int(df.scale)
9 | annoLyr = arcpy.mapping.ListLayers(mxd,"Anno*")[0]
10 |
11 | for lyr in annoLyr:
12 | if lyr.supports("DATASOURCE"): # Weeds out 'default' sub-layer.
13 | lyrScale = int(re.match('.*?([0-9]+)$', str(lyr.name)).group(1)) # Matches digits at end of string.
14 | if lyrScale:
15 | if lyrScale == dfScale:
16 | lyr.visible = True
17 | else:
18 | lyr.visible = False
19 | else:
20 | lyr.visible = False
21 | arcpy.RefreshTOC()
22 | del lyr, annoLyr, mxd, ddp, df, dfScale, lyrScale
--------------------------------------------------------------------------------
/Python/nameElements.py:
--------------------------------------------------------------------------------
1 | import arcpy
2 |
3 | mxd = arcpy.mapping.MapDocument("CURRENT")
4 |
5 | dfs_lst = arcpy.mapping.ListDataFrames(mxd) # List of all dataframes. MainDF and Insets.
6 | mainDF = arcpy.mapping.ListDataFrames(mxd)[0] # Assumes main data frame is first in TOC.
7 | insetDF_lst = arcpy.mapping.ListDataFrames(mxd, "*Inset*")
8 | mapElem_lst = arcpy.mapping.ListLayoutElements(mxd,"MAPSURROUND_ELEMENT", "*SCALE*") + arcpy.mapping.ListLayoutElements(mxd, "GRAPHIC_ELEMENT", "*NORTH*")
9 |
10 | def nameMapElements(elementList):
11 | """Append parent data frame name to map elements."""
12 | for index, elem in enumerate(elementList):
13 | if type(elem) in ["MAPSURROUND_ELEMENT", "LEGEND_ELEMENT", "TEXT_ELEMENT"]:
14 | elem.name = elem.name + elem.parentDataFrameName
15 |
16 | nameMapElements(mapElem_lst)
17 | nameMapElements(insetDF_lst) # Won't do anything because they are of type "DATAFRAME_ELEMENT".
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Python/orginalGetSettings.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | # Create an output location variable
4 | outputDirectory = r"C:\temp"
5 |
6 | # Open a text file to append info to
7 | insetTxt = outputDirectory + r"\insetInfo.txt"
8 | FILE = open(insetTxt, "a")
9 |
10 | try:
11 | mxd = arcpy.mapping.MapDocument("current")
12 | df = arcpy.mapping.ListDataFrames(mxd, "Inset*")[0]
13 | ddp = mxd.dataDrivenPages
14 | infoList = []
15 | infoList.append("\n")
16 | # The following is information you would like to record
17 | # The text is written so it can be pasted directly into your script
18 | # This example assumes that 'pgIndex' is the variable for the current page id
19 | # and that 'dataFrame' is the variable for the data frame containing the inset map
20 | infoList.append("if (pgIndex == " + str(ddp.currentPageID) + "):\n")
21 | infoList.append("\tdataFrame.elementPositionX = " + str(df.elementPositionX) + "\n")
22 | infoList.append("\tdataFrame.elementPositionY = " + str(df.elementPositionY) + "\n")
23 | infoList.append("\tdataFrame.elementHeight = " + str(df.elementHeight) + "\n")
24 | infoList.append("\tdataFrame.elementWidth = " + str(df.elementWidth) + "\n")
25 | infoList.append("\tinsetExtent_" + str(ddp.currentPageID) + " = arcpy.Extent(" +
26 | str(df.extent.XMin) + ", " + str(df.extent.YMin) + ", " +
27 | str(df.extent.XMax) + ", " + str(df.extent.YMax) + ")" + "\n")
28 | infoList.append("\tdataFrame.extent = insetExtent_" + str(ddp.currentPageID) + "\n")
29 |
30 | FILE.writelines(infoList)
31 | except:
32 | print "Writing to file failed"
33 |
34 | # Close the text file
35 | FILE.close()
--------------------------------------------------------------------------------
/Python/writeScaleRotation.py:
--------------------------------------------------------------------------------
1 | # Start of write scale/rotation to Index table feature.
2 | indexTable = arcpy.mapping.ListLayers(mxd,"Index Layer")[0]
3 | fieldNames = ["scale", "rotation"]
4 | sqlClause = "\"District\" = '" + pageName + "'"
5 |
6 | # Assign first (i.e. zeroth) dataframe to variable. Should be 'MainDF'.
7 | df = arcpy.mapping.ListDataFrames(mxd)[0]
8 |
9 | # Create an Update Cursor object on the DDP Index Layer for the current page row.
10 | scaleRotationUpdateCursor = arcpy.da.UpdateCursor(indexTable, fieldNames, sqlClause)
11 | scaleRotationUpdateRow = scaleRotationUpdateCursor.next()
12 |
13 | # Set Index Layer scale field equal to MainD
14 | scaleRotationUpdateRow[0] = df.scale
15 | scaleRotationUpdateRow[1] = df.rotation
16 | scaleRotationUpdateCursor.updateRow(scaleRotationUpdateRow)
17 |
18 | del scaleRotationUpdateRow, scaleRotationUpdateCursor # End of scale/rotation feature
--------------------------------------------------------------------------------
/QuerySelection/Images/ClearQueryCube.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/QuerySelection/Images/ClearQueryCube.png
--------------------------------------------------------------------------------
/QuerySelection/Images/EDHighlight.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/QuerySelection/Images/EDHighlight.png
--------------------------------------------------------------------------------
/QuerySelection/Images/Thumbs.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/QuerySelection/Images/Thumbs.db
--------------------------------------------------------------------------------
/QuerySelection/Images/spatialQuery.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/QuerySelection/Images/spatialQuery.png
--------------------------------------------------------------------------------
/QuerySelection/Install/QuerySelection_addin.py:
--------------------------------------------------------------------------------
1 | import arcpy
2 | import pythonaddins
3 | import os
4 | import sys
5 |
6 |
7 | sys.path.append(os.path.dirname(__file__)) # Add this script to system path. Used to separate main script from other code packages.
8 | import clearSelectedLayerQuery
9 | import getSelectionSet
10 | import querySelected
11 |
12 | class ClearSelection(object):
13 | """Implementation for QuerySelection_addin.clearSelection (Button)"""
14 | def __init__(self):
15 | self.enabled = True
16 | self.checked = False
17 | def onClick(self):
18 | clearSelectedLayerQuery.clearSelectedLayerQuery()
19 |
20 | class QuerySelection(object):
21 | """Implementation for QuerySelection_addin.querySelection (Button)"""
22 | def __init__(self):
23 | self.enabled = True
24 | self.checked = False
25 | def onClick(self):
26 | querySelected.querySelected()
--------------------------------------------------------------------------------
/QuerySelection/Install/clearAllQueries.py:
--------------------------------------------------------------------------------
1 | def clearAllQueries():
2 | """Removes all definition queries from layers in T.O.C."""
3 | for lyr in arcpy.mapping.ListLayers(arcpy.mapping.MapDocument("CURRENT")):
4 | if lyr.supports("DEFINITIONQUERY"):
5 | lyr.definitionQuery = ""
6 | print "Definition query for '{}'' layer cleared.".format(lyr.name)
7 | arcpy.RefreshActiveView()
--------------------------------------------------------------------------------
/QuerySelection/Install/clearSelectedLayerQuery.py:
--------------------------------------------------------------------------------
1 | def clearSelectedLayerQuery():
2 | """Clear definition query from the layer selected in the T.O.C."""
3 | try:
4 | import arcpy, pythonaddins
5 | lyr = pythonaddins.GetSelectedTOCLayerOrDataFrame()
6 | lyr.definitionQuery = ""
7 | print "Definition query for '{}'' layer cleared.".format(lyr.name)
8 | arcpy.RefreshActiveView()
9 | except AttributeError as e:
10 | pythonaddins.MessageBox("Please select a layer in the T.O.C to clear it's query", "Error")
11 | print e
--------------------------------------------------------------------------------
/QuerySelection/Install/getSelectionSet.py:
--------------------------------------------------------------------------------
1 | def getSelectionSet():
2 | """Returns a layer's selection as a Python set of feature IDs the layer's name, the data frame object, and the OID field name.
3 | Provides an easy way to retrieve the layer's current selection.
4 | """
5 | try:
6 | import arcpy
7 | mxd = arcpy.mapping.MapDocument("CURRENT")
8 | df = mxd.activeDataFrame
9 | lyrLst = arcpy.mapping.ListLayers(mxd, "*", df) # Only list first dataframe to avoid identically named layers, where all would get selected.
10 | fidLst = []
11 | lyrName = ""
12 | for lyr in lyrLst:
13 | try:
14 | if not lyr.isGroupLayer:
15 | desc = arcpy.Describe(lyr)
16 | if hasattr(desc, 'FIDSet'):
17 | if desc.FIDSet:
18 | fidLst.append(desc.FIDSet)
19 | lyrName = desc.nameString.split("\\")[-1] # Handles case of layers nested in groups. Gets lyr name minus the group name(s).
20 | OIDFieldName = desc.OIDFieldName
21 | except RuntimeError, TypeError:
22 | pass
23 |
24 | # Check for multiple layers selected.
25 | if len(fidLst) > 1:
26 | raise TypeError("Please select features from a single layer.")
27 |
28 | # Convert list string items to integers.
29 | fidLst = fidLst[0].split(";")
30 | fidLst = map(int, fidLst)
31 |
32 | # Return list of selected feature IDs, the selected layer name, the data frame it is in, and the OID field name.
33 | return fidLst, lyrName, df, OIDFieldName
34 | except IndexError as ie:
35 | import pythonaddins
36 | pythonaddins.MessageBox("{}. Please make a selection.".format(str(ie).capitalize()), "Selection Error")
37 | except Exception as e:
38 | import pythonaddins
39 | pythonaddins.MessageBox(e, "Error")
--------------------------------------------------------------------------------
/QuerySelection/Install/querySelected.py:
--------------------------------------------------------------------------------
1 | def querySelected():
2 | """Builds a definition query to display only the currently
3 | selected features for that layer.
4 | """
5 | import arcpy, os, sys
6 | sys.path.append(os.path.dirname(__file__)) # Add this script to system path. Used to separate main script from other code packages.
7 | import getSelectionSet
8 | mxd = arcpy.mapping.MapDocument("CURRENT")
9 | ids, name, df, oid = getSelectionSet.getSelectionSet()
10 | lyr = arcpy.mapping.ListLayers(mxd, name, df)[0]
11 |
12 | # Build SQL clause to use in definition query.
13 | whereClause = "{} in ({})".format(oid, ','.join(str(id) for id in ids))
14 |
15 | # Apply the definition query.
16 | lyr.definitionQuery = whereClause
17 |
18 | arcpy.RefreshActiveView()
--------------------------------------------------------------------------------
/QuerySelection/QuerySelection.esriaddin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/QuerySelection/QuerySelection.esriaddin
--------------------------------------------------------------------------------
/QuerySelection/README.txt:
--------------------------------------------------------------------------------
1 | This is a stub project created by the ArcGIS Desktop Python AddIn Wizard.
2 |
3 | MANIFEST
4 | ========
5 |
6 | README.txt : This file
7 |
8 | makeaddin.py : A script that will create a .esriaddin file out of this
9 | project, suitable for sharing or deployment
10 |
11 | config.xml : The AddIn configuration file
12 |
13 | Images/* : all UI images for the project (icons, images for buttons,
14 | etc)
15 |
16 | Install/* : The Python project used for the implementation of the
17 | AddIn. The specific python script to be used as the root
18 | module is specified in config.xml.
19 |
--------------------------------------------------------------------------------
/QuerySelection/config.xml:
--------------------------------------------------------------------------------
1 | Query Selection {da067a95-0738-424f-9e01-1186d722d31f} Query Selection Addin 1.0 Images\EDHighlight.png James Stephaniuk EBC 12/11/2015
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/QuerySelection/makeaddin.py:
--------------------------------------------------------------------------------
1 | import os
2 | import re
3 | import zipfile
4 |
5 | current_path = os.path.dirname(os.path.abspath(__file__))
6 |
7 | out_zip_name = os.path.join(current_path,
8 | os.path.basename(current_path) + ".esriaddin")
9 |
10 | BACKUP_FILE_PATTERN = re.compile(".*_addin_[0-9]+[.]py$", re.IGNORECASE)
11 |
12 | def looks_like_a_backup(filename):
13 | return bool(BACKUP_FILE_PATTERN.match(filename))
14 |
15 | with zipfile.ZipFile(out_zip_name, 'w', zipfile.ZIP_DEFLATED) as zip_file:
16 | for filename in ('config.xml', 'README.txt', 'makeaddin.py'):
17 | zip_file.write(os.path.join(current_path, filename), filename)
18 | dirs_to_add = ['Images', 'Install']
19 | for directory in dirs_to_add:
20 | for (path, dirs, files) in os.walk(os.path.join(current_path,
21 | directory)):
22 | archive_path = os.path.relpath(path, current_path)
23 | found_file = False
24 | for file in (f for f in files if not looks_like_a_backup(f)):
25 | archive_file = os.path.join(archive_path, file)
26 | print archive_file
27 | zip_file.write(os.path.join(path, file), archive_file)
28 | found_file = True
29 | if not found_file:
30 | zip_file.writestr(os.path.join(archive_path,
31 | 'placeholder.txt'),
32 | "(Empty directory)")
33 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Arcpy AddIns & Command Line Tools
2 | ESRI Arcpy scripts for ArcGIS.
3 |
4 | A collection of add-in and command line tools for map production and automation.
5 |
6 | Add_Ins
7 |
8 | Contains tools to record, restore, and reset layouts of data driven page (DDP) enabled mxds.
9 | Records layout position, size, and extents of north arrows, scale bars/text, and data frames.
10 | Saves data to a `.dbf` with specific name, which can be changed.
11 |
12 |
13 | Annotation & Annotation_Stand_Alone
14 |
15 | ExtentBoxes Tool to create bounding boxes (polygons) of ddp dataframe extents of on-map dfs. Used for index polygon for Tiled Annotation creation.
16 | GenerateTiledAnno Automation of `TiledLabelsToAnnotation_cartography` tool that uses above generated boxes as index polygons.
17 | Stand-alone script is the same tool as above but is run from the command line with syntax `python NAME_OF_SCRIPT.py`. Doesn't need ArcMap GUI and is therefore much fasterthan the above tools.
18 |
19 |
20 | Layers
21 |
22 | A method of programmatically saving and restoring layer symbology for a given ddp.
23 | Saves layerfiles to a specific location named as `pageName_layerName_dataframeName.lyr`.
24 |
25 |
26 | PDF_Export_Addin & PDF_Export_Stand_Alone
27 |
28 | Buttons to automate pdf export with pre-defined parameters. Can be easily altered to allow different params.
29 | Generates pdf name in the form `pageName_dpi_colorspace_orientation`.
30 | Stand-alone script is the same tool as above but is run from the command line with syntax `python NAME_OF_SCRIPT.py DPI` where DPI is and integer representing the dots per inch of the exported pdf. Doesn't need ArcMap GUI and is therefore much faster than the above tools.
31 |
32 |
33 | QuerySelection
34 |
35 | On button press genterates definition query for layer of selected features. Simply select features you want to display for one layer, and press the button.
36 | Select layer in table of contents and press clear selection button to clear the query for that layer.
37 |
38 |
39 | ReplicateSD (Command Line Tool)
40 |
41 | An automated way to replicate ArcSDE connected database to a local FGDB to improve performance.
42 | Uses a list (`layerNameLst`) to control which files are copied. Can easily be altered to include all files on SDE.
43 | Change databaseConnection variable to your .sde connection file.
44 | Can be run by a task scheduler at regular intervals to keep data up-to-date.
45 |
46 |
--------------------------------------------------------------------------------
/SDE_Replication/ReplicateSDE.py:
--------------------------------------------------------------------------------
1 | import arcpy
2 | import datetime
3 | import logging
4 | import logging.handlers
5 | import os
6 | import shutil
7 | import sys
8 | import time
9 |
10 | ########################### User defined functions ###########################
11 |
12 | def getDatabaseItemCount(workspace):
13 | log = logging.getLogger("script_log")
14 | """returns the item count in provided database"""
15 | arcpy.env.workspace = workspace
16 | feature_classes = []
17 | log.info("Compiling a list of items in {0} and getting count.".format(workspace))
18 | for dirpath, dirnames, filenames in arcpy.da.Walk(workspace,datatype="Any",type="Any"):
19 | for filename in filenames:
20 | feature_classes.append(os.path.join(dirpath, filename))
21 | log.info("There are a total of {0} items in the database".format(len(feature_classes)))
22 | return feature_classes, len(feature_classes)
23 |
24 | def replicateDatabase(dbConnection, targetGDB):
25 | log = logging.getLogger("script_log")
26 | startTime = time.time()
27 |
28 | if arcpy.Exists(dbConnection):
29 | featSDE,cntSDE = getDatabaseItemCount(dbConnection)
30 | log.info("Geodatabase being copied: %s -- Feature Count: %s" %(dbConnection, cntSDE))
31 | if arcpy.Exists(targetGDB):
32 | # Archive old geodatabase with timestamp.
33 | # shutil.copytree(targetGDB, os.path.join(os.path.dirname(__file__), str(now.strftime("%Y-%m-%d_%H-%M.gdb")))) # TODO: Release Locking
34 | featGDB,cntGDB = getDatabaseItemCount(targetGDB)
35 | log.info("Old Target Geodatabase: %s -- Feature Count: %s" %(targetGDB, cntGDB))
36 | try:
37 | shutil.rmtree(targetGDB)
38 | log.info("Deleted Old %s" %(os.path.split(targetGDB)[-1]))
39 | except Exception as e:
40 | log.info(e)
41 |
42 | GDB_Path, GDB_Name = os.path.split(targetGDB)
43 | log.info("Now Creating New %s" %(GDB_Name))
44 | arcpy.CreateFileGDB_management(GDB_Path, GDB_Name)
45 |
46 | arcpy.env.workspace = dbConnection
47 |
48 | # try:
49 | # datasetList = [arcpy.Describe(a).name for a in arcpy.ListDatasets()]
50 | # except Exception as e:
51 | # datasetList = []
52 | # log.info(e)
53 | try:
54 | featureClasses = layerNameLst
55 | except Exception as e:
56 | featureClasses = []
57 | log.info(e)
58 | # try:
59 | # tables = [arcpy.Describe(a).name for a in arcpy.ListTables()]
60 | # except Exception as e:
61 | # tables = []
62 | # log.info(e)
63 |
64 | #Compiles a list of the previous three lists to iterate over
65 | allDbData = featureClasses # + datasetList + tables
66 |
67 | for sourcePath in allDbData:
68 | targetName = sourcePath.split('.')[-1]
69 | targetPath = os.path.join(targetGDB, targetName)
70 | if not arcpy.Exists(targetPath):
71 | try:
72 | log.info("Attempting to Copy %s to %s" %(targetName, targetPath))
73 | arcpy.Copy_management(sourcePath, targetPath)
74 | log.info("Finished copying %s to %s" %(targetName, targetPath))
75 | except Exception as e:
76 | log.info("Unable to copy %s to %s" %(targetName, targetPath))
77 | log.info(e)
78 | else:
79 | log.info("%s already exists....skipping....." %(targetName))
80 |
81 | featGDB,cntGDB = getDatabaseItemCount(targetGDB)
82 | log.info("Completed replication of %s -- Feature Count: %s" %(dbConnection, cntGDB))
83 |
84 | else:
85 | log.info("{0} does not exist or is not supported! \
86 | Please check the database path and try again.".format(dbConnection))
87 |
88 | def formatTime(x):
89 | minutes, seconds_rem = divmod(x, 60)
90 | if minutes >= 60:
91 | hours, minutes_rem = divmod(minutes, 60)
92 | return "%02d:%02d:%02d" % (hours, minutes_rem, seconds_rem)
93 | else:
94 | minutes, seconds_rem = divmod(x, 60)
95 | return "00:%02d:%02d" % (minutes, seconds_rem)
96 |
97 | ################################# Layer List #################################
98 | # Layer name list. Controls which features will be replicated.
99 | layerNameLst = [
100 | 'indea:mdwilkie.indea_bs10_covlines_view_active',
101 | 'indea:mdwilkie.indea_background_ebc_greenspace_active',
102 | 'indea:mdwilkie.indea_background_ebc_usa_poly_active',
103 | 'indea:mdwilkie.indea_background_ebc_communities_active',
104 | 'indea:genmaint.idm_ebc_roads',
105 | 'indea:mdwilkie.indea_road_segments_active',
106 | 'indea:mdwilkie.indea_background_ebc_railways_active',
107 | 'indea:genmaint.idm_ebc_municipalities_ebc_indian_reserves',
108 | 'indea:mdwilkie.indea_background_ebc_canada_poly_active',
109 | 'indea:mdwilkie.indea_background_ebc_water_features_streams_active',
110 | 'indea:mdwilkie.indea_background_ebc_water_features_areal_active',
111 | 'indea:genmaint.cart_ebc_buildings',
112 | 'indea:mdwilkie.indea_background_ebc_ocean_active',
113 | 'indea:mdwilkie.indea_background_ebc_islands_active',
114 | 'indea:mdwilkie.indea_background_ebc_parks_active',
115 | 'indea:genmaint.cart_ebc_water_features_streams_tab',
116 | 'indea:genmaint.indea_background_ebc_external_transparency_active'
117 | ]
118 |
119 | if __name__ == "__main__":
120 | startTime = time.time()
121 | now = datetime.datetime.now()
122 |
123 | ############################# User variables #############################
124 | # Change this variable to the target database location (SDE connection).
125 | databaseConnection = "PATH_TO_YOUR_SDE_CONNECTION"
126 |
127 | # Log files folder will be created at same directory level as script.
128 | logPath = os.path.join(os.path.dirname(os.path.realpath(__file__)), "replicateSDE_Logfiles")
129 | if not os.path.exists(logPath):
130 | os.makedirs(logPath)
131 |
132 | # Replicated FGDB will be created at same directory level as script.
133 | targetGDB = os.path.join(os.path.dirname(os.path.realpath(__file__)), "Replicated.gdb")
134 |
135 | ############################## Logging items #############################
136 |
137 | # Make a global logging object.
138 | logName = os.path.join(logPath,(now.strftime("%Y-%m-%d_%H-%M.log")))
139 |
140 | log = logging.getLogger("script_log")
141 | log.setLevel(logging.INFO)
142 |
143 | h1 = logging.FileHandler(logName)
144 | h2 = logging.StreamHandler()
145 |
146 | f = logging.Formatter("[%(levelname)s] [%(asctime)s] [%(lineno)d] - %(message)s",'%m/%d/%Y %I:%M:%S %p')
147 |
148 | h1.setFormatter(f)
149 | h2.setFormatter(f)
150 |
151 | h1.setLevel(logging.INFO)
152 | h2.setLevel(logging.INFO)
153 |
154 | log.addHandler(h1)
155 | log.addHandler(h2)
156 |
157 | log.info('----------------------------------------------------')
158 | log.info('Script: {0}'.format(os.path.basename(sys.argv[0])))
159 | log.info('----------------------------------------------------')
160 |
161 | try:
162 | ########################### Function calls ###########################
163 |
164 | replicateDatabase(databaseConnection, targetGDB)
165 |
166 | ######################################################################
167 | except Exception as e:
168 | log.exception(e)
169 |
170 | totalTime = formatTime((time.time() - startTime))
171 | log.info('----------------------------------------------------')
172 | log.info("Script Completed After: {0}".format(totalTime))
173 | log.info('----------------------------------------------------')
--------------------------------------------------------------------------------
/SQL/PrelimReport87EDs_web.dbf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/SQL/PrelimReport87EDs_web.dbf
--------------------------------------------------------------------------------
/SQL/PrelimReport87EDs_web.prj:
--------------------------------------------------------------------------------
1 | PROJCS["Canada_Albers_Equal_Area_Conic",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Albers"],PARAMETER["False_Easting",1000000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",-126.0],PARAMETER["Standard_Parallel_1",58.5],PARAMETER["Standard_Parallel_2",50.0],PARAMETER["Latitude_Of_Origin",45.0],UNIT["Meter",1.0]]
--------------------------------------------------------------------------------
/SQL/PrelimReport87EDs_web.shp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/SQL/PrelimReport87EDs_web.shp
--------------------------------------------------------------------------------
/SQL/PrelimReport87EDs_web.shx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/SQL/PrelimReport87EDs_web.shx
--------------------------------------------------------------------------------
/SQL/createViewSDE.sql:
--------------------------------------------------------------------------------
1 | CREATE VIEW ed_bs10_view
2 | AS SELECT *
3 | FROM indea:mdwilkie.indea_edvas_active ed
4 | WHERE ed.emp_id = "10";
5 |
6 |
7 | # Grant privileges
8 | GRANT SELECT
9 | ON ed_bs10_view
10 | TO USER dispatch_mgr WITH GRANT OPTION;
11 |
12 |
13 | -- http://resources.arcgis.com/en/help/main/10.2/index.html#//002m000000rs000000
14 |
15 |
16 |
17 | -- Table
18 | indea:mdwilkie.indea_edvas_active
19 | -- BS Field
20 | ebc_bdy_set_id
21 | -- View name
22 | edvas_active_bs10_v_
23 |
24 |
25 |
26 | -- Arcpy
27 | INPUT_DATABASE = "C:\Users\jastepha\AppData\Roaming\ESRI\Desktop10.2\ArcCatalog\Connection to indeaprod2.sde"
28 | VIEW_DEFINITION = "SELECT * FROM indea:mdwilkie.indea_edvas_active WHERE ebc_bdy_set_id='10'"
29 | VIEW_NAME = "edvas_active_bs10_v_"
30 | arcpy.CreateDatabaseView_management(INPUT_DATABASE, VIEW_NAME, VIEW_DEFINITION)
--------------------------------------------------------------------------------
/SQL/tcn_road_type_QUERY.txt:
--------------------------------------------------------------------------------
1 | -- Combination for mapping purposes.
2 | tcn_road_type IN ( 'arterial' , 'collector' , 'freeway' , 'highway' , 'Highway' ) AND road_generation = 'e' AND is_standard IN ('T','t') AND boundary_set_id = 8
3 |
4 | -- Minor Roads. 'boundary_set_id' removes NULL values, roads outside of BC (e.g. Yukon)
5 | tcn_road_type IN ( 'lane', 'local', 'recreation', 'resource', 'strata', 'service') AND is_standard IN ('T', 't') AND boundary_set_id = 8
6 |
7 | -- Major Roads
8 | tcn_road_type IN ( 'arterial', 'collector', 'ramp') AND is_standard IN ('T', 't') AND boundary_set_id = 8
9 |
10 | -- Highways
11 | tcn_road_type IN ( 'highway', 'freeway') AND is_standard IN ('T', 't') AND boundary_set_id = 8
12 |
--------------------------------------------------------------------------------
/XY/shpToTxtCoords.py:
--------------------------------------------------------------------------------
1 | """******************************************************************
2 | shpToTxtCoords.py
3 | Version: ArcGIS 10.2.1
4 |
5 | Description: Writes the X and Y coordinates of a polygon shapefile's
6 | verticies with a descriptive label to a text file.
7 |
8 | Author: James Stephaniuk
9 |
10 | Date: April 23, 2015
11 | ******************************************************************"""
12 |
13 | import arcpy
14 |
15 | # Map document - MXD.
16 | mxd = arcpy.mapping.MapDocument('CURRENT')
17 | # Polygon feature class. Target feature must be the first item in TOC.
18 | fc = arcpy.mapping.ListLayers(mxd)[0]
19 |
20 | # Create 'describe' object.
21 | desc = arcpy.Describe(fc)
22 | # Get shape field name and layer name of feature class.
23 | if hasattr(desc, "ShapeFieldName") and hasattr(desc, "baseName"):
24 | ShapeFieldName = desc.ShapeFieldName
25 | layerName = desc.baseName
26 |
27 | # Output save path for text file.
28 | outDir = r"P:\\15045 - ED Redistribution - Event Specific\\R2015\21-Electoral_Boundaries_Commission_Support_Doc\\WBS 8 - Geography\\James\\XY\\"
29 |
30 | # Column of shapefile for text file label.
31 | inField = "DIST_NAM_1"
32 |
33 | # Create update cursor on feature class.
34 | uCursor = arcpy.UpdateCursor(fc)
35 |
36 | # Open text file with overwrite permissions (w). Creates a text file if one does not exist already.
37 | # f = open(r"P:\\15045 - ED Redistribution - Event Specific\\R2015\21-Electoral_Boundaries_Commission_Support_Doc\\WBS 8 - Geography\\James\\XY\\Melnick_Final.txt", 'w')
38 | f = open("{}{}.txt".format(outDir, layerName), 'w')
39 | for shp in uCursor:
40 | polygon = shp.getValue(ShapeFieldName)
41 | for point in polygon:
42 | for p in point:
43 | # Convert x-y coordinates to strings for file writing.
44 | x = str(p.X)
45 | y = str(p.Y)
46 | # Write inField, x, y to text file.
47 | f.write(shp.getValue(inField) + ",")
48 | f.write(x + ",")
49 | f.write(y + "\n")
50 | # Close text file.
51 | f.close()
52 |
--------------------------------------------------------------------------------
/addin-wizard/.hgtags:
--------------------------------------------------------------------------------
1 | d2c510239e37de29c20718cbbbfc53e94de59e0c 10.2-wizard
2 |
--------------------------------------------------------------------------------
/addin-wizard/LICENSE:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/addin-wizard/LICENSE
--------------------------------------------------------------------------------
/addin-wizard/README.md:
--------------------------------------------------------------------------------
1 | # Python Add-In Wizard
2 |
3 | This is the application linked to in the help for creating Python Add-Ins in ArcGIS 10.1/10.2. It's a simple wxPython app bundled with py2exe, so it should act as a good example to learn from for doing that, too.
4 |
5 | This app does not require ArcGIS in any way to function, nor does it import or use arcpy/arcgisscripting in any way. It's just a UI to make boilerplate `.xml`/`.py` files.
6 |
7 | ## Licensing
8 | Copyright 2013 Esri
9 |
10 | Licensed under the Apache License, Version 2.0 (the "License");
11 | you may not use this file except in compliance with the License.
12 | You may obtain a copy of the License at
13 |
14 | http://www.apache.org/licenses/LICENSE-2.0
15 |
16 | Unless required by applicable law or agreed to in writing, software
17 | distributed under the License is distributed on an "AS IS" BASIS,
18 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 | See the License for the specific language governing permissions and
20 | limitations under the License.
21 |
22 | A copy of the license is available in the repository's license.txt file.
23 |
24 | [](Esri: ArcGIS Python Add-In Wizard)
25 | [](Esri Language: Python)
26 |
--------------------------------------------------------------------------------
/addin-wizard/addin_ui.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding: utf-8 -*-
3 | # generated by wxGlade 0.6.3 on Mon Sep 19 12:33:19 2011
4 |
5 | import wx
6 |
7 | # begin wxGlade: extracode
8 | _msize = wx.Size(700, 550)
9 | _msize = wx.Size(700, 550)
10 | # end wxGlade
11 |
12 |
13 |
14 | class AddinMakerWindow(wx.Frame):
15 | def __init__(self, *args, **kwds):
16 | # begin wxGlade: AddinMakerWindow.__init__
17 | kwds["style"] = wx.DEFAULT_FRAME_STYLE
18 | wx.Frame.__init__(self, *args, **kwds)
19 | self.full_app_panel = wx.Panel(self, -1)
20 | self.bottom_buttons_pane = wx.Panel(self.full_app_panel, -1)
21 | self.propsheet_panel = wx.Panel(self.full_app_panel, -1)
22 | self.tabs_notebook = wx.Notebook(self.propsheet_panel, -1, style=0)
23 | self.project_items_pane = wx.Panel(self.tabs_notebook, -1)
24 | self.item_property_panel = wx.Panel(self.project_items_pane, -1)
25 | self.project_settings_pane = wx.Panel(self.tabs_notebook, -1)
26 | self.logo_panel = wx.Panel(self.propsheet_panel, -1)
27 | self.properties_rows_holder_staticbox = wx.StaticBox(self.project_settings_pane, -1, "Project Properties:")
28 | self.title_panel = wx.Panel(self.full_app_panel, -1)
29 | self.title_label = wx.StaticText(self.title_panel, -1, "Python Add-In Wizard", style=wx.ALIGN_RIGHT)
30 | self.title_divider_line = wx.StaticLine(self.full_app_panel, -1)
31 | self.logo_bitmap = wx.StaticBitmap(self.logo_panel, -1, wx.Bitmap("images\\AddInDesktop64.png", wx.BITMAP_TYPE_ANY))
32 | self.folder_label = wx.StaticText(self.project_settings_pane, -1, "Working Folder:", style=wx.ALIGN_RIGHT)
33 | self.folder_button = wx.Button(self.project_settings_pane, -1, "Select Folder...")
34 | self.product_label = wx.StaticText(self.project_settings_pane, -1, "Select Product:", style=wx.ALIGN_RIGHT)
35 | self.product_combo_box = wx.ComboBox(self.project_settings_pane, -1, choices=["ArcMap", "ArcGlobe", "ArcScene", "ArcCatalog"], style=wx.CB_DROPDOWN|wx.CB_READONLY)
36 | self.static_line_1 = wx.StaticLine(self.project_settings_pane, -1)
37 | self.project_name_label = wx.StaticText(self.project_settings_pane, -1, "Name*:", style=wx.ALIGN_RIGHT)
38 | self.project_name = wx.TextCtrl(self.project_settings_pane, -1, "")
39 | self.project_version_label = wx.StaticText(self.project_settings_pane, -1, "Version*:", style=wx.ALIGN_RIGHT)
40 | self.project_version = wx.TextCtrl(self.project_settings_pane, -1, "")
41 | self.project_company_label = wx.StaticText(self.project_settings_pane, -1, "Company:", style=wx.ALIGN_RIGHT)
42 | self.project_company = wx.TextCtrl(self.project_settings_pane, -1, "")
43 | self.project_description_label = wx.StaticText(self.project_settings_pane, -1, "Description:", style=wx.ALIGN_RIGHT)
44 | self.project_description = wx.TextCtrl(self.project_settings_pane, -1, "")
45 | self.project_author_label = wx.StaticText(self.project_settings_pane, -1, "Author:", style=wx.ALIGN_RIGHT)
46 | self.project_author = wx.TextCtrl(self.project_settings_pane, -1, "")
47 | self.image_section_divider = wx.StaticLine(self.project_settings_pane, -1)
48 | self.project_image_label = wx.StaticText(self.project_settings_pane, -1, "Image:", style=wx.ALIGN_RIGHT)
49 | self.select_project_image = wx.Button(self.project_settings_pane, -1, "Select Image...")
50 | self.icon_bitmap = wx.StaticBitmap(self.project_settings_pane, -1, wx.Bitmap("images\\AddInDesktop48.png", wx.BITMAP_TYPE_ANY), style=wx.SIMPLE_BORDER)
51 | self.contents_tree = wx.TreeCtrl(self.project_items_pane, -1, style=wx.TR_HAS_BUTTONS|wx.TR_LINES_AT_ROOT|wx.TR_HIDE_ROOT|wx.TR_DEFAULT_STYLE|wx.RAISED_BORDER)
52 | self.bottom_buttons_spacer_panel = wx.Panel(self.bottom_buttons_pane, -1)
53 | self.open_folder = wx.Button(self.bottom_buttons_pane, -1, "Open Folder")
54 | self.save_button = wx.Button(self.bottom_buttons_pane, -1, "Save")
55 |
56 | self.__set_properties()
57 | self.__do_layout()
58 |
59 | self.Bind(wx.EVT_BUTTON, self.SelectFolder, self.folder_button)
60 | self.Bind(wx.EVT_COMBOBOX, self.ComboBox, self.product_combo_box)
61 | self.Bind(wx.EVT_TEXT_ENTER, self.ProjectNameText, self.project_name)
62 | self.Bind(wx.EVT_TEXT, self.ProjectNameText, self.project_name)
63 | self.Bind(wx.EVT_TEXT_ENTER, self.ProjectVersionText, self.project_version)
64 | self.Bind(wx.EVT_TEXT, self.ProjectVersionText, self.project_version)
65 | self.Bind(wx.EVT_TEXT_ENTER, self.ProjectCompanyText, self.project_company)
66 | self.Bind(wx.EVT_TEXT, self.ProjectCompanyText, self.project_company)
67 | self.Bind(wx.EVT_TEXT_ENTER, self.ProjectDescriptionText, self.project_description)
68 | self.Bind(wx.EVT_TEXT, self.ProjectDescriptionText, self.project_description)
69 | self.Bind(wx.EVT_TEXT_ENTER, self.ProjectAuthorText, self.project_author)
70 | self.Bind(wx.EVT_TEXT, self.ProjectAuthorText, self.project_author)
71 | self.Bind(wx.EVT_BUTTON, self.SelectProjectImage, self.select_project_image)
72 | self.Bind(wx.EVT_TREE_BEGIN_DRAG, self.BeginDrag, self.contents_tree)
73 | self.Bind(wx.EVT_TREE_END_DRAG, self.EndDrag, self.contents_tree)
74 | self.Bind(wx.EVT_TREE_DELETE_ITEM, self.DeleteItem, self.contents_tree)
75 | self.Bind(wx.EVT_TREE_SEL_CHANGED, self.SelChanged, self.contents_tree)
76 | self.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGING, self.ChangeTab, self.tabs_notebook)
77 | self.Bind(wx.EVT_BUTTON, self.OpenFolder, self.open_folder)
78 | self.Bind(wx.EVT_BUTTON, self.SaveProject, self.save_button)
79 | # end wxGlade
80 |
81 | def __set_properties(self):
82 | # begin wxGlade: AddinMakerWindow.__set_properties
83 | self.SetTitle("ArcGIS Python Add-In Wizard")
84 | self.SetMinSize(_msize)
85 | self.title_label.SetFont(wx.Font(16, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, ""))
86 | self.title_panel.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DHIGHLIGHT))
87 | self.product_combo_box.SetSelection(0)
88 | self.project_name_label.SetMinSize((72, 16))
89 | self.project_version_label.SetMinSize((72, 16))
90 | self.project_company_label.SetMinSize((72, 16))
91 | self.project_description_label.SetMinSize((72, 16))
92 | self.project_author_label.SetMinSize((72, 16))
93 | self.project_image_label.SetMinSize((72, 16))
94 | self.contents_tree.SetMinSize((200, 484))
95 | # end wxGlade
96 |
97 | def __do_layout(self):
98 | # begin wxGlade: AddinMakerWindow.__do_layout
99 | full_window_sizer = wx.BoxSizer(wx.HORIZONTAL)
100 | main_sizer = wx.BoxSizer(wx.VERTICAL)
101 | bottom_buttons_sizer = wx.BoxSizer(wx.HORIZONTAL)
102 | content_sizer = wx.BoxSizer(wx.HORIZONTAL)
103 | splitter_sizer = wx.BoxSizer(wx.HORIZONTAL)
104 | items_sizer = wx.BoxSizer(wx.HORIZONTAL)
105 | item_property_sizer = wx.BoxSizer(wx.VERTICAL)
106 | fields_sizer = wx.BoxSizer(wx.VERTICAL)
107 | properties_rows_holder = wx.StaticBoxSizer(self.properties_rows_holder_staticbox, wx.VERTICAL)
108 | project_bitmap_display_sizer = wx.BoxSizer(wx.HORIZONTAL)
109 | properties_rows = wx.BoxSizer(wx.VERTICAL)
110 | project_image_sizer = wx.BoxSizer(wx.HORIZONTAL)
111 | project_author_sizer = wx.BoxSizer(wx.HORIZONTAL)
112 | project_description_sizer = wx.BoxSizer(wx.HORIZONTAL)
113 | project_company_sizer = wx.BoxSizer(wx.HORIZONTAL)
114 | project_version_sizer = wx.BoxSizer(wx.HORIZONTAL)
115 | project_name_sizer = wx.BoxSizer(wx.HORIZONTAL)
116 | product_sizer = wx.BoxSizer(wx.HORIZONTAL)
117 | folder_sizer = wx.BoxSizer(wx.HORIZONTAL)
118 | logo_sizer = wx.BoxSizer(wx.HORIZONTAL)
119 | title_sizer = wx.BoxSizer(wx.HORIZONTAL)
120 | title_sizer.Add(self.title_label, 0, wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_HORIZONTAL, 8)
121 | self.title_panel.SetSizer(title_sizer)
122 | main_sizer.Add(self.title_panel, 0, wx.EXPAND|wx.ALIGN_RIGHT, 0)
123 | main_sizer.Add(self.title_divider_line, 0, wx.EXPAND, 0)
124 | logo_sizer.Add(self.logo_bitmap, 0, wx.TOP, 8)
125 | self.logo_panel.SetSizer(logo_sizer)
126 | splitter_sizer.Add(self.logo_panel, 0, wx.EXPAND, 0)
127 | folder_sizer.Add(self.folder_label, 0, wx.ALIGN_CENTER_VERTICAL, 8)
128 | folder_sizer.Add(self.folder_button, 1, wx.EXPAND, 8)
129 | fields_sizer.Add(folder_sizer, 0, wx.ALL|wx.EXPAND, 4)
130 | product_sizer.Add(self.product_label, 0, wx.ALIGN_CENTER_VERTICAL, 3)
131 | product_sizer.Add(self.product_combo_box, 0, 0, 3)
132 | fields_sizer.Add(product_sizer, 0, wx.ALL|wx.EXPAND, 4)
133 | fields_sizer.Add(self.static_line_1, 0, wx.ALL|wx.EXPAND, 8)
134 | project_name_sizer.Add(self.project_name_label, 0, wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 2)
135 | project_name_sizer.Add(self.project_name, 1, wx.EXPAND, 0)
136 | properties_rows.Add(project_name_sizer, 1, wx.EXPAND, 0)
137 | project_version_sizer.Add(self.project_version_label, 0, wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 2)
138 | project_version_sizer.Add(self.project_version, 1, wx.EXPAND, 0)
139 | properties_rows.Add(project_version_sizer, 1, wx.EXPAND, 0)
140 | project_company_sizer.Add(self.project_company_label, 0, wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 2)
141 | project_company_sizer.Add(self.project_company, 1, wx.EXPAND, 0)
142 | properties_rows.Add(project_company_sizer, 1, wx.EXPAND, 0)
143 | project_description_sizer.Add(self.project_description_label, 0, wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 2)
144 | project_description_sizer.Add(self.project_description, 1, wx.EXPAND, 0)
145 | properties_rows.Add(project_description_sizer, 1, wx.EXPAND, 0)
146 | project_author_sizer.Add(self.project_author_label, 0, wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 2)
147 | project_author_sizer.Add(self.project_author, 1, wx.EXPAND, 0)
148 | properties_rows.Add(project_author_sizer, 1, wx.EXPAND, 0)
149 | properties_rows.Add(self.image_section_divider, 0, wx.ALL|wx.EXPAND, 2)
150 | project_image_sizer.Add(self.project_image_label, 0, wx.ALL|wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL, 2)
151 | project_image_sizer.Add(self.select_project_image, 0, 0, 0)
152 | properties_rows.Add(project_image_sizer, 1, wx.EXPAND, 3)
153 | properties_rows_holder.Add(properties_rows, 0, wx.EXPAND, 0)
154 | project_bitmap_display_sizer.Add(self.icon_bitmap, 0, wx.TOP, 3)
155 | properties_rows_holder.Add(project_bitmap_display_sizer, 1, wx.LEFT|wx.EXPAND, 80)
156 | fields_sizer.Add(properties_rows_holder, 0, wx.EXPAND, 0)
157 | self.project_settings_pane.SetSizer(fields_sizer)
158 | items_sizer.Add(self.contents_tree, 0, wx.EXPAND, 0)
159 | self.item_property_panel.SetSizer(item_property_sizer)
160 | items_sizer.Add(self.item_property_panel, 1, wx.EXPAND, 0)
161 | self.project_items_pane.SetSizer(items_sizer)
162 | self.tabs_notebook.AddPage(self.project_settings_pane, "Project Settings")
163 | self.tabs_notebook.AddPage(self.project_items_pane, "Add-In Contents")
164 | splitter_sizer.Add(self.tabs_notebook, 1, wx.EXPAND, 4)
165 | content_sizer.Add(splitter_sizer, 1, wx.EXPAND, 4)
166 | self.propsheet_panel.SetSizer(content_sizer)
167 | main_sizer.Add(self.propsheet_panel, 1, wx.EXPAND, 0)
168 | bottom_buttons_sizer.Add(self.bottom_buttons_spacer_panel, 1, wx.EXPAND, 0)
169 | bottom_buttons_sizer.Add(self.open_folder, 0, wx.ALL, 2)
170 | bottom_buttons_sizer.Add(self.save_button, 0, wx.ALL, 2)
171 | self.bottom_buttons_pane.SetSizer(bottom_buttons_sizer)
172 | main_sizer.Add(self.bottom_buttons_pane, 0, wx.EXPAND, 4)
173 | self.full_app_panel.SetSizer(main_sizer)
174 | full_window_sizer.Add(self.full_app_panel, 1, wx.ALL|wx.EXPAND, 1)
175 | self.SetSizer(full_window_sizer)
176 | full_window_sizer.Fit(self)
177 | self.Layout()
178 | self.Centre()
179 | # end wxGlade
180 |
181 | def SelectFolder(self, event): # wxGlade: AddinMakerWindow.
182 | print "Event handler `SelectFolder' not implemented!"
183 | event.Skip()
184 |
185 | def ComboBox(self, event): # wxGlade: AddinMakerWindow.
186 | print "Event handler `ComboBox' not implemented!"
187 | event.Skip()
188 |
189 | def ProjectNameText(self, event): # wxGlade: AddinMakerWindow.
190 | print "Event handler `ProjectNameText' not implemented!"
191 | event.Skip()
192 |
193 | def ProjectVersionText(self, event): # wxGlade: AddinMakerWindow.
194 | print "Event handler `ProjectVersionText' not implemented!"
195 | event.Skip()
196 |
197 | def ProjectCompanyText(self, event): # wxGlade: AddinMakerWindow.
198 | print "Event handler `ProjectCompanyText' not implemented!"
199 | event.Skip()
200 |
201 | def ProjectDescriptionText(self, event): # wxGlade: AddinMakerWindow.
202 | print "Event handler `ProjectDescriptionText' not implemented!"
203 | event.Skip()
204 |
205 | def ProjectAuthorText(self, event): # wxGlade: AddinMakerWindow.
206 | print "Event handler `ProjectAuthorText' not implemented!"
207 | event.Skip()
208 |
209 | def SelectProjectImage(self, event): # wxGlade: AddinMakerWindow.
210 | print "Event handler `SelectProjectImage' not implemented!"
211 | event.Skip()
212 |
213 | def BeginDrag(self, event): # wxGlade: AddinMakerWindow.
214 | print "Event handler `BeginDrag' not implemented!"
215 | event.Skip()
216 |
217 | def EndDrag(self, event): # wxGlade: AddinMakerWindow.
218 | print "Event handler `EndDrag' not implemented!"
219 | event.Skip()
220 |
221 | def DeleteItem(self, event): # wxGlade: AddinMakerWindow.
222 | print "Event handler `DeleteItem' not implemented!"
223 | event.Skip()
224 |
225 | def SelChanged(self, event): # wxGlade: AddinMakerWindow.
226 | print "Event handler `SelChanged' not implemented!"
227 | event.Skip()
228 |
229 | def ChangeTab(self, event): # wxGlade: AddinMakerWindow.
230 | print "Event handler `ChangeTab' not implemented!"
231 | event.Skip()
232 |
233 | def OpenFolder(self, event): # wxGlade: AddinMakerWindow.
234 | print "Event handler `OpenFolder' not implemented!"
235 | event.Skip()
236 |
237 | def SaveProject(self, event): # wxGlade: AddinMakerWindow.
238 | print "Event handler `SaveProject' not implemented!"
239 | event.Skip()
240 |
241 | # end of class AddinMakerWindow
242 |
243 |
244 | if __name__ == "__main__":
245 | app = wx.PySimpleApp(0)
246 | wx.InitAllImageHandlers()
247 | addin_window = AddinMakerWindow(None, -1, "")
248 | app.SetTopWindow(addin_window)
249 | addin_window.Show()
250 | app.MainLoop()
251 |
--------------------------------------------------------------------------------
/addin-wizard/i18n.py:
--------------------------------------------------------------------------------
1 | __all__ = ['_']
2 |
3 | import json
4 | import os
5 |
6 | try:
7 | translations_dict = json.loads(open(os.path.join('resources', 'resource_strings.json'), 'rb').read().decode('utf-8'))
8 | except:
9 | print "Can't load translation strings file."
10 |
11 | def _(the_text):
12 | return translations_dict.get(the_text, the_text)
13 |
--------------------------------------------------------------------------------
/addin-wizard/images/AddInDesktop.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/addin-wizard/images/AddInDesktop.ico
--------------------------------------------------------------------------------
/addin-wizard/images/AddInDesktop48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/addin-wizard/images/AddInDesktop48.png
--------------------------------------------------------------------------------
/addin-wizard/images/AddInDesktop64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/addin-wizard/images/AddInDesktop64.png
--------------------------------------------------------------------------------
/addin-wizard/images/Thumbs.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jstep/Arcpy/1cf1c68de1d598069d1e98ad4de68c8273fd9792/addin-wizard/images/Thumbs.db
--------------------------------------------------------------------------------
/addin-wizard/packaging/README.txt:
--------------------------------------------------------------------------------
1 | This is a stub project created by the ArcGIS Desktop Python AddIn Wizard.
2 |
3 | MANIFEST
4 | ========
5 |
6 | README.txt : This file
7 |
8 | makeaddin.py : A script that will create a .esriaddin file out of this
9 | project, suitable for sharing or deployment
10 |
11 | config.xml : The AddIn configuration file
12 |
13 | Images/* : all UI images for the project (icons, images for buttons,
14 | etc)
15 |
16 | Install/* : The Python project used for the implementation of the
17 | AddIn. The specific python script to be used as the root
18 | module is specified in config.xml.
19 |
20 | NOTE TO ADD-IN AUTHORS: Please edit this file to be relevant documentation
21 | for your project or delete it before distributing.
22 |
--------------------------------------------------------------------------------
/addin-wizard/packaging/makeaddin.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | import os
3 | import re
4 | import zipfile
5 |
6 | current_path = os.path.dirname(os.path.abspath(__file__))
7 |
8 | out_zip_name = os.path.join(current_path,
9 | os.path.basename(current_path) + ".esriaddin")
10 |
11 | BACKUP_FILE_PATTERN = re.compile(".*_addin_[0-9]+[.]py$", re.IGNORECASE)
12 |
13 | def looks_like_a_backup(filename):
14 | return bool(BACKUP_FILE_PATTERN.match(filename))
15 |
16 | with zipfile.ZipFile(out_zip_name, 'w', zipfile.ZIP_DEFLATED) as zip_file:
17 | for filename in ('config.xml', 'README.txt', 'makeaddin.py'):
18 | full_filename = os.path.join(current_path, filename)
19 | if os.path.exists(full_filename):
20 | zip_file.write(full_filename, filename)
21 | dirs_to_add = ['Images', 'Install']
22 | for directory in dirs_to_add:
23 | for (path, dirs, files) in os.walk(os.path.join(current_path,
24 | directory)):
25 | archive_path = os.path.relpath(path, current_path)
26 | found_file = False
27 | for file in (f for f in files if not looks_like_a_backup(f)):
28 | archive_file = os.path.join(archive_path, file)
29 | print archive_file
30 | zip_file.write(os.path.join(path, file), archive_file)
31 | found_file = True
32 | if not found_file:
33 | zip_file.writestr(os.path.join(archive_path,
34 | 'placeholder.txt'),
35 | "(Empty directory)")
36 |
--------------------------------------------------------------------------------
/addin-wizard/resources/resource_strings.json:
--------------------------------------------------------------------------------
1 | {
2 |
3 | "**** THIS STRING RESOURCE FILE IS EXPECTED TO BE ENCODED IN UTF-8 ***": "(Do not translate this string)",
4 | "It is arranged into ORIGINAL: TRANSLATION pairs.": "(Do not translate this string)",
5 |
6 | "Add-In Contents": "Add-In Contents",
7 | "ArcGIS Python Add-In Wizard": "ArcGIS Python Add-In Wizard",
8 | "Author:": "Author:",
9 | "Button": "Button",
10 | "Caption": "Caption",
11 | "Choose a directory to use as an Add-In project root:": "Choose a directory to use as an Add-In project root:",
12 | "Class Name": "Class Name",
13 | "Column Count": "Column Count",
14 | "Company:": "Company:",
15 | "Description": "Description",
16 | "Description:": "Description:",
17 | "EXTENSIONS": "EXTENSIONS",
18 | "Extension": "Extension",
19 | "Extensions": "Extensions",
20 | "Has Separator": "Has Separator",
21 | "Help Content": "Help Content",
22 | "Help Heading": "Help Heading",
23 | "Hint Text": "Hint Text",
24 | "ID (Variable Name)": "ID (Variable Name)",
25 | "Image for Control": "Image for Control",
26 | "Image for control:": "Image for control:",
27 | "Image:": "Image:",
28 | "Is Shortcut Menu": "Is Shortcut Menu",
29 | "Load Automatically": "Load Automatically",
30 | "MENUS": "MENUS",
31 | "Menu": "Menu",
32 | "Menu Style": "Menu Style",
33 | "Message": "Message",
34 | "Methods to Implement": "Methods to Implement",
35 | "Name": "Name",
36 | "Name*:": "Name*:",
37 | "New Extension": "New Extension",
38 | "New Menu": "New Menu",
39 | "Open Folder": "Open Folder",
40 | "Project Properties:": "Project Properties:",
41 | "Project Settings": "Project Settings",
42 | "Python Add-In Wizard": "Python Add-In Wizard",
43 | "Save": "Save",
44 | "Save before exiting?": "Save before exiting?",
45 | "Save your changes before exiting?": "Save your changes before exiting?",
46 | "Select Folder...": "Select Folder...",
47 | "Select Image...": "Select Image...",
48 | "Select Product:": "Select Product:",
49 | "Show Initially": "Show Initially",
50 | "TOOLBARS": "TOOLBARS",
51 | "Toolbar": "Toolbar",
52 | "Toolbars": "Toolbars",
53 | "Tooltip": "Tooltip",
54 | "Toplevel Menus": "Toplevel Menus",
55 | "Version*:": "Version*:",
56 | "Working Folder:": "Working Folder:"
57 | }
58 |
--------------------------------------------------------------------------------
/addin-wizard/setup.py:
--------------------------------------------------------------------------------
1 | from distutils.core import setup
2 | import py2exe
3 | import glob
4 |
5 | setup(windows=[
6 | {'script': 'addin_assistant.pyw',
7 | 'icon_resources': [(1, "images\\AddInDesktop.ico")]
8 | }
9 | ],
10 | options={ "py2exe": { "dll_excludes": ["MSVCP90.dll"] }},
11 | data_files=[('images', glob.glob("images\\*.png") +
12 | glob.glob("images\\*.ico")),
13 | ('packaging', glob.glob("packaging\\*.*")),
14 | ('resources', glob.glob("resources\\*.*"))]
15 | )
16 |
--------------------------------------------------------------------------------