0
点赞
收藏
分享

微信扫一扫

『基于ArcGIS的Python编程秘籍(第2版)』书本源码

主要摘录一些在学书籍上的源码,方便学习查阅~~~

ArcPy学习

第1章 面向ArcGIS的Python编程语言的基础

第2章 管理地图文档和图层

  • 引用当前的地图文档
  • 引用磁盘上的地图文档
  • 获取地图文档的图层列表
  • 限制图层列表
  • 缩放至所选要素
  • 改变地图范围
  • 添加图层到地图文档
  • 插入图层到地图文档
  • 更新图层的符号系统
  • 更新图层属性
  • 操作数据框中的启用时间的图层
  1. 引用当前的地图文档2.2-28

import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT") # 引用当前活动的地图文档
print(mxd.title)
mxd.title = "Copy of Crime Project"
mxd.saveACopy("c:/ArcpyBook/Ch2/crime_copy.mxd")

  1. 引用磁盘上的地图文档2.3-30

import arcpy.mapping as mapping
mxd = mapping.MapDocument("c:/ArcpyBook/Ch2/crime_copy.mxd")
print(mxd.title)

  1. 获取地图文档的图层列表2.4-31

import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")
layers = mapping.ListLayers(mxd)
for lyr in layers:
print(lyr.name)

  1. 限制图层列表2.5-33

import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")
for df in mapping.ListDataFrames(mxd):
if (df.name == 'Crime'):
layers = mapping.ListLayers(mxd,"Burg*",df)
for layer in layers:
print(layer.name)

  1. 缩放至所选要素2.6-35

import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")
df = mapping.ListDataFrames(mxd,"Crime")[0]
layer = mapping.ListLayers(mxd,"Burglaries*",df)[0]
df.extent = layer.getSelectedExtent()

  1. 改变地图范围2.7-37

import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")
for df in mapping.ListDataFrames(mxd):
if (df.name == 'Crime'):
layers = mapping.ListLayers(mxd,'Crime Density by School District',df)
for layer in layers:
query = '"NAME" = \'Lackland ISD\''
layer.definitionQuery = query
df.extent = layer.getExtent()

  1. 添加图层到地图文档2.8-39

import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")
df = mapping.ListDataFrames(mxd)[0]
layer = mapping.Layer(r"C:\ArcpyBook\data\School_Districts.lyr")
mapping.AddLayer(df,layer,"AUTO_ARRANGE")

  1. 插入图层到地图文档2.9-42

import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")
df = mapping.ListDataFrames(mxd, "Crime")[0]
refLayer = mapping.ListLayers(mxd, "Burglaries*", df)[0]
insertLayer = mapping.Layer(r"C:\ArcpyBook\data\CityOfSanAntonio.gdb\Crimes2009")
mapping.InsertLayer(df,refLayer,insertLayer,"BEFORE")

  1. 更新图层的符号系统2.10-45

import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")
df = mapping.ListDataFrames(mxd, "Crime")[0]
updateLayer = mapping.ListLayers(mxd,"Crime Density by School District",df)[0]
sourceLayer = mapping.Layer(r"C:\ArcpyBook\data\CrimeDensityGradSym.lyr")
mapping.UpdateLayer(df,updateLayer,sourceLayer,True)

  1. 更新图层属性2.11-48

import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")
df = mapping.ListDataFrames(mxd, "Crime")[0]
updateLayer = mapping.ListLayers(mxd,"Crimes2009",df)[0]
sourceLayer = mapping.Layer(r"C:\ArcpyBook\data\BurglariesNoForcedEntry.lyr")
mapping.UpdateLayer(df,updateLayer,sourceLayer,False)

  1. 操作数据框中的启用时间的图层2.12-53

import arcpy.mapping as mapping, os
mxd = mapping.MapDocument("CURRENT")
df = mapping.ListDataFrames(mxd, "Crime")[0]
dft = df.time
dft.currentTime = dft.startTime

while dft.currentTime <= dft.endTime:
fileName = str(dft.currentTime).split(" ")[0] + ".pdf"
mapping.ExportToPDF(mxd,os.path.join(r"C:\ArcpyBook\Ch2", fileName))
print("Exported " + fileName)
dft.currentTime = dft.currentTime + dft.timeStepInterval

第3章 查找和修复丢失的数据链接

  • 查找地图文档和图层文件中丢失的数据源
  • 使用MapDocument.findAndReplaceWorkspacePaths()方法修复丢失的数据源
  • 使用MapDocument.replaceWorkspaces()方法修复对视的数据源
  • 使用replaceDataSource()方法修复单个图层和表对象
  • 查找文件夹中所有地图文档内丢失的数据源
  1. 查找地图文档和图层文件中丢失的数据源3.2-60

import arcpy.mapping as mapping
mxd = mapping.MapDocument(r"c:\ArcpyBook\Ch3\Crime_BrokenDataLinks.mxd")
listBrokenDS = mapping.ListBrokenDataSources(mxd)
for layer in listBrokenDS:
print(layer.name)

  1. 使用MapDocument.findAndReplaceWorkspacePaths()方法修复丢失的数据源3.3-62

import arcpy.mapping as mapping
mxd = mapping.MapDocument(r"c:\ArcpyBook\Ch3\Crime_BrokenDataLinks.mxd")
mxd.findAndReplaceWorkspacePaths(r"C:\ArcpyBook\Ch3\Data\OldData\CityOfSanAntonio.gdb", r"C:\ArcpyBook\Data\CityOfSanAntonio.gdb")
mxd.saveACopy(r"C:\ArcpyBook\Ch3\Crime_DataLinksFixed.mxd")

  1. 使用MapDocument.replaceWorkspaces()方法修复对视的数据源3.4-65

import arcpy.mapping as mapping
mxd = mapping.MapDocument(r"c:\ArcpyBook\Ch3\Crime_DataLinksFixed.mxd")
mxd.replaceWorkspaces(r"c:\ArcpyBook\data\CityOfSanAntonio.gdb", "FILEGDB_WORKSPACE",r"c:\ArcpyBook\new_data\CityOfSanAntonio_Personal.mdb","ACCESS_WORKSPACE")
mxd.saveACopy(r"c:\ArcpyBook\Ch3\Crime_DataLinksUpdated.mxd")

  1. 使用replaceDataSource()方法修复单个图层和表对象3.5-68

import arcpy.mapping as mapping
mxd = mapping.MapDocument(r"c:\ArcpyBook\Ch3\Crime_DataLinksLayer.mxd")
df = mapping.ListDataFrames(mxd,"Crime")[0]
lyr = mapping.ListLayers(mxd,"Burglary",df)[0]
lyr.replaceDataSource(r"c:\ArcpyBook\data","SHAPEFILE_WORKSPACE","Burglaries_2009")
mxd.saveACopy(r"c:\ArcpyBook\Ch3\Crime_DataLinksNewLayer.mxd")

  1. 查找文件夹中所有地图文档内丢失的数据源3.6-72

import arcpy.mapping as mapping, os
f = open('BrokenDataList.txt', 'w')
for root, dirs, files in os.walk("c:\ArcpyBook"):
for name in files:
filename = os.path.join(root, name)
if ".mxd" in filename:
mxd = mapping.MapDocument(filename)
f.write("MXD: " + filename + "\n")
brknList = mapping.ListBrokenDataSources(mxd)
for brknItem in brknList:
print("Broken data item: " + brknItem.name + " in " + filename)
f.write("\t" + brknItem.name + "\n")
print("All done")
f.close()

第4章 自动化地图制图和打印

  • 创建布局元素的python列表
  • 为布局元素指定唯一的名称
  • 使用ListLayoutElements()函数限制返回的布局元素
  • 更新布局元素的属性
  • 获取可用打印机的列表
  • 使用PrintMap()函数打印地图
  • 导出地图为PDF文件
  • 导出地图为图像文件
  • 导出报表
  • 使用数据驱动页面和ArcPy制图模块构建地图册
  • 将地图文档发布为ArcGIS Server服务
  1. 创建布局元素的python列表4.2-77

import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")
for el in mapping.ListLayoutElements(mxd):
if el.name != "":
print el.name

  1. 为布局元素指定唯一的名称4.3-79

None

  1. 使用ListLayoutElements()函数限制返回的布局元素4.4-83

import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")
for el in mapping.ListLayoutElements(mxd,"LEGEND_ELEMENT","*Crime*"):
print el.name

  1. 更新布局元素的属性4.5-84

import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")
elLeg = mapping.ListLayoutElements(mxd, "LEGEND_ELEMENT","*Crime*")[0]
elLeg.title = "Crimes by School District"
for item in elLeg.listLegendItemLayers():
print item.name

  1. 获取可用打印机的列表4.6-87

import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")
for printerName in mapping.ListPrinterNames():
print printerName

  1. 使用PrintMap()函数打印地图4.7-88

import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")
for df in mapping.ListDataFrames(mxd):
if df.name == "Test_Performance":
mapping.PrintMap(mxd,"",df)

  1. 导出地图为PDF文件4.8-90

import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")
mapping.ExportToPDF(mxd,r"c:\ArcpyBook\Ch4\Map_PageLayout.pdf")

import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")
for df in mapping.ListDataFrames(mxd):
if df.name == "Crime":
df.referenceScale = df.scale
mapping.ExportToPDF(mxd,r"c:\ArcpyBook\Ch4\DataFrameCrime.pdf",df)

  1. 导出地图为图像文件4.9-92

import arcpy.mapping as mapping
mxd = mapping.MapDocument("CURRENT")
for df in mapping.ListDataFrames(mxd):
if df.name == "Crime":
mapping.ExportToJPEG(mxd,r"c:\ArcpyBook\Ch4\DataFrameCrime.jpg",df)

  1. 导出报表4.10-93

import arcpy
import os

path = os.getcwd()

#Create PDF and remove if it already exists
pdfPath = path + r"\CrimeReport.pdf"
if os.path.exists(pdfPath):
os.remove(pdfPath)
pdfDoc = arcpy.mapping.PDFDocumentCreate(pdfPath)

districtList = ["Harlandale", "East Central", "Edgewood", "Alamo Heights", "South San Antonio", "Southside", "Ft Sam Houston","North East", "Northside", "Lackland", "Southwest", "Judson", "San Antonio"]

mxd = arcpy.mapping.MapDocument(path + r"\Crime_Ch4.mxd")
df = arcpy.mapping.ListDataFrames(mxd)[0]
lyr = arcpy.mapping.ListLayers(mxd, "Crime Density by School District")[0]

pageCount = 1
for district in districtList:
#Generate image for each district
whereClause = "\"NAME\" = '" + district + " ISD'"
lyr.definitionQuery = whereClause
arcpy.SelectLayerByAttribute_management(lyr, "NEW_SELECTION", whereClause)
df.extent = lyr.getSelectedExtent()
arcpy.SelectLayerByAttribute_management(lyr, "CLEAR_SELECTION")
arcpy.mapping.ExportToBMP(mxd, path + "\DistrictPicture.bmp", df) #single file

#Generate report
print("Generating report for: " + district + " ISD")
arcpy.mapping.ExportReport(report_source=lyr,report_layout_file=path + r"\CrimeLayout.rlf",output_file=path + r"\temp" + str(pageCount) + ".pdf", starting_page_number=pageCount)

#Append pages into final output
print("Appending page: " + str(pageCount))
pdfDoc.appendPages(path + r"\temp" + str(pageCount) + ".pdf")
os.remove(path + r"\temp" + str(pageCount) + ".pdf")
pageCount = pageCount + 1

pdfDoc.saveAndClose()
del mxd

  1. 使用数据驱动页面和ArcPy制图模块构建地图册4.11-98

import arcpy
import os

# Create an output directory variable
outDir = r"C:\ArcpyBook\Ch4"

# Create a new, empty pdf document in the specified output directory
finalpdf_filename = outDir + r"\MapBook.pdf"
if os.path.exists(finalpdf_filename):
os.remove(finalpdf_filename)
finalPdf = arcpy.mapping.PDFDocumentCreate(finalpdf_filename)

# Add the title page to the pdf
print("Adding the title page \n")
finalPdf.appendPages(outDir + r"\TitlePage.pdf")

# Add the index map to the pdf
print "Adding the index page \n"
finalPdf.appendPages(outDir + r"\MapIndex.pdf")

# Export the Data Driven Pages to a temporary pdf and then add it to the
# final pdf. Alternately, if your Data Driven Pages have already been
# exported, simply append that document to the final pdf.
mxdPath = outDir + r"\Topographic.mxd"
mxd = arcpy.mapping.MapDocument(mxdPath)
print("Creating the data driven pages \n")
ddp = mxd.dataDrivenPages
temp_filename = outDir + r"\tempDDP.pdf"

if os.path.exists(temp_filename):
os.remove(temp_filename)
ddp.exportToPDF(temp_filename, "ALL")
print("Appending the map series \n")
finalPdf.appendPages(temp_filename)

# Update the properties of the final pdf
finalPdf.updateDocProperties(pdf_open_view="USE_THUMBS",
pdf_layout="SINGLE_PAGE")

# Save your result
finalPdf.saveAndClose()

# remove the temporary data driven pages file
if os.path.exists(temp_filename):
print("Removing the temporary map series file")
os.remove(temp_filename)

# Delete variables
#del finalPdf, mxd, ddp

  1. 将地图文档发布为ArcGIS Server服务4.12-102

import arcpy.mapping as mapping
wrkspc = r'c:\ArcpyBook\ch4'
mxd = mapping.MapDocument(wrkspc + r"\Crime.mxd")

service = 'Crime'
sddraft = wrkspc + service + '.sddraft'
mapping.CreateMapSDDraft(mxd, sddraft, service)
analysis = mapping.AnalyzeForSD(wrkspc + "Crime.sddraft")

for key in ('messages', 'warnings', 'errors'):
print("----" + key.upper() + "----")
vars = analysis[key]
for ((message, code), layerlist) in vars.iteritems():
print " ", message, " (CODE %i)" % code
print(" applies to:")
for layer in layerlist:
print(layer.name)

第5章 使用脚本执行地理处理工具

  • 查找地理处理工具
  • 查看工具箱别名
  • 使用脚本执行地理处理工具
  • 讲一个工具的输出作为另一个工具的输入
  1. 查找地理处理工具5.2-110

None

  1. 查看工具箱别名5.3-114

None

  1. 使用脚本执行地理处理工具5.4-116

import arcpy
in_features = "c:/ArcpyBook/data/CityOfSanAntonio.gdb/Burglary"
clip_features = "c:/ArcpyBook/Ch5/EdgewoodSD.shp"
out_feature_class = "c:/ArcpyBook/Ch5/ClpBurglary.shp"
arcpy.Clip_analysis(in_features,clip_features,out_feature_class)

  1. 讲一个工具的输出作为另一个工具的输入5.5-119

import arcpy
arcpy.env.workspace = "c:/ArcpyBook/data/TravisCounty"
try:
# Buffer areas of impact around major roads
streams = "Streams.shp"
streamsBuffer = "StreamsBuffer"
distance = "2640 Feet"
schools2mile = "Schools.shp"
schoolsLyrFile = 'Schools2Mile_lyr'

arcpy.Buffer_analysis(streams, streamsBuffer, distance,'FULL','ROUND','ALL')

# Make a layer
arcpy.MakeFeatureLayer_management(schools2mile, schoolsLyrFile)
arcpy.SelectLayerByLocation_management(schoolsLyrFile, 'intersect', streamsBuffer)
except Exception as e:
print e.message

第6章 创建自定义地理处理工具

  • 创建自定义地理处理工具
  • 创建Python工具箱
  1. 创建自定义地理处理工具6.2-123

#Script to Import data to a feature class within a geodatabase
import arcpy, os
try:
outputFC = arcpy.GetParameterAsText(0)
fClassTemplate = arcpy.GetParameterAsText(1)
f = open(arcpy.GetParameterAsText(2),'r')
arcpy.CreateFeatureclass_management(os.path.split(outputFC)[0], os.path.split(outputFC)[1],"point",fClassTemplate)
lstFires = f.readlines()
with arcpy.da.InsertCursor(outputFC) as cur:
cntr = 1
for fire in lstFires:
if 'Latitude' in fire:
continue
vals = fire.split(",")
latitude = float(vals[0])
longitude = float(vals[1])
confid = int(vals[2])
pnt = arcpy.Point(longitude, latitude)
feat = cur.newRow()
feat.shape = pnt
feat.setValue("CONFIDENCEVALUE", confid)
cur.insertRow(feat)
arcpy.AddMessage("Record number" + str(cntr) + "written to feature class")
cntr = cntr + 1
except:
print arcpy.GetMessages()
finally:
f.close()

  1. 创建Python工具箱6.3-139

import arcpy
import requests
import json

class Toolbox(object):
def __init__(self):
"""Define the toolbox (the name of the toolbox is the name of the
.pyt file)."""
self.label = "Toolbox"
self.alias = ""

# List of tool classes associated with this toolbox
self.tools = [USGSDownload]


class USGSDownload(object):
def __init__(self):
"""Define the tool (tool name is the name of the class)."""
self.label = "USGS Download"
self.description = "Download from USGS ArcGIS Server instance"
self.canRunInBackground = False

def getParameterInfo(self):

"""Define parameter definitions"""
# First parameter
param0 = arcpy.Parameter(
displayName="ArcGIS Server Wildfire URL",
name="url",
datatype="GPString",
parameterType="Required",
direction="Input")
param0.value = "http://wildfire.cr.usgs.gov/arcgis/rest/services/geomac_dyn/MapServer/0/query"

# Second parameter
param1 = arcpy.Parameter(
displayName="Output Feature Class",
name="out_fc",
datatype="DEFeatureClass",
parameterType="Required",
direction="Input")

params = [param0, param1]
return params

def isLicensed(self):
"""Set whether tool is licensed to execute."""
return True

def updateParameters(self, parameters):
"""Modify the values and properties of parameters before internal
validation is performed. This method is called whenever a parameter
has been changed."""
return

def updateMessages(self, parameters):
"""Modify the messages created by internal validation for each tool
parameter. This method is called after internal validation."""
return

def execute(self, parameters, messages):
inFeatures = parameters[0].valueAsText
outFeatureClass = parameters[1].valueAsText

agisurl = inFeatures

payload = { 'where': 'acres > 5','f': 'pjson', 'outFields': 'latitude,longitude,fire_name,acres'}

r = requests.get(inFeatures, params=payload)
decoded = json.loads(r.text)

with arcpy.da.InsertCursor(outFeatureClass, ("SHAPE@XY", "NAME", "ACRES")) as cur:
cntr = 1
for rslt in decoded['features']:
fireName = rslt['attributes']['fire_name']
latitude = rslt['attributes']['latitude']
longitude = rslt['attributes']['longitude']
acres = rslt['attributes']['acres']
cur.insertRow([(longitude,latitude),fireName, acres])
arcpy.AddMessage("Record number: " + str(cntr) + " written to feature class")
cntr = cntr + 1

第7章 查询和选择数据

  • 构造正确的属性查询语句
  • 创建要素图层和表现层
  • 使用Select Layer by Attribute 工具选择要素和行
  • 使用Select Layer by Location 工具选择要素
  • 结合空间查询和属性选择要素
  1. 构造正确的属性查询语句7.2-149

None

  1. 创建要素图层和表现层7.3-154

import arcpy
arcpy.env.workspace = "c:/ArcpyBook/data/CityOfSanAntonio.gdb"
try:
tView = arcpy.MakeTableView_management("Crime2009Table","Crime2009TView")
except Exception as e:
print e.message

  1. 使用Select Layer by Attribute 工具选择要素和行7.4-158

import arcpy
arcpy.env.workspace = "c:/ArcpyBook/data/CityOfSanAntonio.gdb"
try:
qry = '"SVCAREA" = \'North\''
flayer = arcpy.MakeFeatureLayer_management("Burglary","Burglary_Layer")
arcpy.SelectLayerByAttribute_management(flayer, "NEW_SELECTION", qry)
cnt = arcpy.GetCount_management(flayer)
print "The number of selected records is: " + str(cnt)
except Exception as e:
print e.message

  1. 使用Select Layer by Location 工具选择要素7.5-161

import arcpy
arcpy.env.workspace = "c:/ArcpyBook/data/CityOfSanAntonio.gdb"
try:
flayer = arcpy.MakeFeatureLayer_management("Burglary","Burglary_Layer")
arcpy.SelectLayerByLocation_management(flayer, "COMPLETELY_WITHIN", "c:/ArcpyBook/Ch7/EdgewoodSD.shp")
cnt = arcpy.GetCount_management(flayer)
print("The number of selected records is: " + str(cnt))
except Exception as e:
print(e.message)

import arcpy
arcpy.env.workspace = "c:/ArcpyBook/data/CityOfSanAntonio.gdb"
try:
flayer = arcpy.MakeFeatureLayer_management("Burglary","Burglary_Layer")
arcpy.SelectLayerByLocation_management (flayer, "WITHIN_A_DISTANCE", "c:/ArcpyBook/Ch7/EdgewoodSD.shp","1 MILES")
cnt = arcpy.GetCount_management(flayer)
print("The number of selected records is: " + str(cnt))
except Exception as e:
print(e.message)

import arcpy
arcpy.env.workspace = "c:/ArcpyBook/data/CityOfSanAntonio.gdb"
try:
flayer = arcpy.MakeFeatureLayer_management("Burglary","Burglary_Layer")
arcpy.SelectLayerByLocation_management (flayer, "WITHIN_A_DISTANCE", "c:/ArcpyBook/Ch7/EdgewoodSD.shp","1 MILES")
arcpy.CopyFeatures_management(flayer, "c:/ArcpyBook/Ch7/EdgewoodBurglaries.shp")
##cnt = arcpy.GetCount_management(flayer)
##print "The number of selected records is: " + str(cnt)
except Exception as e:
print(e.message)

  1. 结合空间查询和属性选择要素7.6-165

import arcpy
arcpy.env.workspace = "c:/ArcpyBook/data/CityOfSanAntonio.gdb"
try:
qry = '"DOW" = \'Mon\''
flayer = arcpy.MakeFeatureLayer_management("Burglary","Burglary_Layer")
arcpy.SelectLayerByLocation_management (flayer, "COMPLETELY_WITHIN", "c:/ArcpyBook/Ch7/EdgewoodSD.shp")
arcpy.SelectLayerByAttribute_management(flayer, "SUBSET_SELECTION", qry)
cnt = arcpy.GetCount_management(flayer)
print("The total number of selected records is: " + str(cnt))
except Exception as e:
print(e.message)

第8章 在要素类和表中使用ArcPy数据访问模块

  • 使用SearchCursor检索要素类中的要素
  • 使用where字句筛选记录
  • 使用几何令爱改进游标性能
  • 使用InsertCursor插入行
  • 使用UpdateCursor更新行
  • 使用UpdateCursor删除行
  • 在编辑会话中插入和更新行
  • 读取要素类中的几何信息
  • 使用Walk()遍历目录
  1. 使用SearchCursor检索要素类中的要素8.2-171

import arcpy.da
arcpy.env.workspace = "c:/ArcpyBook/Ch8"
with arcpy.da.SearchCursor("Schools.shp",("Facility","Name")) as cursor:
for row in sorted(cursor):
print("High school name: " + row[1])

  1. 使用where字句筛选记录8.3-173

import arcpy.da
arcpy.env.workspace = "c:/ArcpyBook/Ch8"
with arcpy.da.SearchCursor("Schools.shp",("Facility","Name"), '"FACILITY" = \'HIGH SCHOOL\'') as cursor:
for row in sorted(cursor):
print("School name: " + row[1])

  1. 使用几何令爱改进游标性能8.4-174

import arcpy.da
import time
arcpy.env.workspace = "c:/ArcpyBook/Ch8"
start = time.clock()
with arcpy.da.SearchCursor("coa_parcels.shp",("PY_FULL_OW","SHAPE@XY")) as cursor:
for row in cursor:
print("Parcel owner: {0} has a location of: {1}".format(row[0], row[1]))
elapsed = (time.clock() - start)
print("Execution time: " + str(elapsed))

  1. 使用InsertCursor插入行8.5-178

import arcpy
import os

arcpy.env.workspace = "C:/ArcpyBook/Ch8/WildfireData/WildlandFires.mdb"
f = open("C:/ArcpyBook/Ch8/WildfireData/NorthAmericaWildfires_2007275.txt","r")
lstFires = f.readlines()
try:
with arcpy.da.InsertCursor("FireIncidents",("SHAPE@XY","CONFIDENCEVALUE")) as cur:
cntr = 1
for fire in lstFires:
if 'Latitude' in fire:
continue
vals = fire.split(",")
latitude = float(vals[0])
longitude = float(vals[1])
confid = int(vals[2])
rowValue = [(latitude,longitude),confid]
cur.insertRow(rowValue)
print("Record number " + str(cntr) + " written to feature class")
cntr = cntr + 1
except Exception as e:
print(e.message)
finally:
f.close()

  1. 使用UpdateCursor更新行8.6-183

import arcpy

arcpy.env.workspace = "C:/ArcpyBook/Ch8/WildfireData/WildlandFires.mdb"
try:
#create a new field to hold the values
arcpy.AddField_management("FireIncidents","CONFID_RATING","TEXT","10")
print("CONFID_RATING field added to FireIncidents")
with arcpy.da.UpdateCursor("FireIncidents",("CONFIDENCEVALUE","CONFID_RATING")) as cursor:
cntr = 1
for row in cursor:
# update the confid_rating field
if row[0] <= 40:
row[1] = 'POOR'
elif row[0] > 40 and row[0] <= 60:
row[1] = 'FAIR'
elif row[0] > 60 and row[0] <= 85:
row[1] = 'GOOD'
else:
row[1] = 'EXCELLENT'
cursor.updateRow(row)
print("Record number " + str(cntr) + " updated")
cntr = cntr + 1
except Exception as e:
print(e.message)

  1. 使用UpdateCursor删除行8.7-187

import arcpy
import os

arcpy.env.workspace = "C:/ArcpyBook/Ch8/WildfireData/WildlandFires.mdb"
try:
with arcpy.da.UpdateCursor("FireIncidents",("CONFID_RATING"),'[CONFID_RATING] = \'POOR\'') as cursor:
cntr = 1
for row in cursor:
cursor.deleteRow()
print("Record number " + str(cntr) + " deleted")
cntr = cntr + 1
except Exception as e:
print(e.message)

  1. 在编辑会话中插入和更新行8.8-189

import arcpy
import os

arcpy.env.workspace = "C:/ArcpyBook/Ch8/WildfireData/WildlandFires.mdb"
try:
edit = arcpy.da.Editor('C:/ArcpyBook/Ch8/WildfireData/WildlandFires.mdb')
edit.startEditing(True)
with arcpy.da.UpdateCursor("FireIncidents",("CONFIDENCEVALUE","CONFID_RATING")) as cursor:
cntr = 1
for row in cursor:
# update the confid_rating field
if row[0] > 40 and row[0] <= 60:
row[1] = 'GOOD'
elif row[0] > 60 and row[0] <= 85:
row[1] = 'BETTER'
else:
row[1] = 'BEST'
cursor.updateRow(row)
print("Record number " + str(cntr) + " updated")
cntr = cntr + 1
edit.stopEditing(True)
except Exception as e:
print(e.message)

  1. 读取要素类中的几何信息8.9-193

import arcpy
infc = "c:/ArcpyBook/data/CityOfSanAntonio.gdb/SchoolDistricts"
# Enter for loop for each feature
for row in arcpy.da.SearchCursor(infc, ["OID@", "SHAPE@"]):
# Print the current multipoint's ID
print("Feature {0}:".format(row[0]))
partnum = 0

# Step through each part of the feature
#
for part in row[1]:
# Print the part number
#
print("Part {0}:".format(partnum))

# Step through each vertex in the feature
#
for pnt in part:
if pnt:
# Print x,y coordinates of current point
#
print("{0}, {1}".format(pnt.X, pnt.Y))
else:
# If pnt is None, this represents an interior ring
#
print("Interior Ring:")
partnum += 1

  1. 使用Walk()遍历目录8.10-195

import arcpy.da as da
import os

print("os walk")

for dirpath, dirnames, filenames in os.walk(os.getcwd()):
for filename in filenames:
print(filename)

print("arcpy da walk")

for dirpath, dirnames, filenames in da.Walk(os.getcwd(),datatype="FeatureClass"):
for filename in filenames:
print(os.path.join(dirpath, filename))

第9章 获取GIS数据的列表和描述

  • 使用ArcPy列表函数
  • 获取要素类或表中的字段列表
  • 使用Describe()函数返回要素类的描述性信息
  • 使用Describe()函数返回栅格图像的描述性信息
  1. 使用ArcPy列表函数9.2-199

import arcpy
arcpy.env.workspace = "C:/ArcpyBook/data/CityOfSanAntonio.gdb"
fcList = arcpy.ListFeatureClasses()
for fc in fcList:
print(fc)

import arcpy
arcpy.env.workspace = "C:/ArcpyBook/data/CityOfSanAntonio.gdb"
fcList = arcpy.ListFeatureClasses("C*")
for fc in fcList:
print(fc)

import arcpy
arcpy.env.workspace = "C:/ArcpyBook/data/CityOfSanAntonio.gdb"
fcList = arcpy.ListFeatureClasses("C*","polygon")
for fc in fcList:
print(fc)

  1. 获取要素类或表中的字段列表9.3-202

import arcpy

arcpy.env.workspace = "C:/ArcpyBook/data/CityOfSanAntonio.gdb"
try:
fieldList = arcpy.ListFields("Burglary")
for fld in fieldList:
print("%s is a type of %s with a length of %i" % (fld.name, fld.type, fld.length))
except Exception as e:
print(e.message)

  1. 使用Describe()函数返回要素类的描述性信息9.4-204

import arcpy
arcpy.env.workspace = "c:/ArcpyBook/data/CityOfSanAntonio.gdb"
try:
descFC = arcpy.Describe("Burglary")
print("The shape type is: " + descFC.ShapeType)
flds = descFC.fields
for fld in flds:
print("Field: " + fld.name)
print("Type: " + fld.type)
print("Length: " + str(fld.length))
ext = descFC.extent
print("XMin: %f" % (ext.XMin))
print("YMin: %f" % (ext.YMin))
print("XMax: %f" % (ext.XMax))
print("YMax: %f" % (ext.YMax))
except:
print(arcpy.GetMessages())

  1. 使用Describe()函数返回栅格图像的描述性信息9.5-208

import arcpy
arcpy.env.workspace = "c:/ArcpyBook/data"
try:
descRaster = arcpy.Describe("AUSTIN_EAST_NW.sid")
ext = descRaster.extent
print("XMin: %f" % (ext.XMin))
print("YMin: %f" % (ext.YMin))
print("XMax: %f" % (ext.XMax))
print("YMax: %f" % (ext.YMax))

sr = descRaster.SpatialReference
print(sr.name)
print(sr.type)
except Exception as e:
print e.message

第10章 使用Add-in定制ArcGIS界面

  • 下载并安装Python Add-in Wizard
  • 创建按钮加载项和使用Python加载项模块
  • 安装和测试加载项
  • 创建工具加载项
  1. 下载并安装Python Add-in Wizard10.2-212

None

  1. 创建按钮加载项和使用Python加载项模块10.3-214

import arcpy
import pythonaddins

class ButtonClassImportWildfires(object):
"""Implementation for Wildfire_addin.button (Button)"""
def __init__(self):
self.enabled = True
self.checked = False

def onClick(self):
layer_files = pythonaddins.OpenDialog('Select Layers to Add', True, r'C:\ArcpyBook\data\Wildfires', 'Add')
mxd = arcpy.mapping.MapDocument('current')
df = pythonaddins.GetSelectedTOCLayerOrDataFrame()
if not isinstance(df, arcpy.mapping.Layer):
for layer_file in layer_files:
layer = arcpy.mapping.Layer(layer_file)
arcpy.mapping.AddLayer(df, layer)
else:
pythonaddins.MessageBox('Select a data frame', 'INFO', 0)

  1. 安装和测试加载项10.4-223

None

  1. 创建工具加载项10.5-228

import arcpy
import pythonaddins

def __init__(self):
self.enabled = True
self.cursor = 3
self.shape = 'Rectangle'

def onRectangle(self, rectangle_geometry):
extent = rectangle_geometry
arcpy.env.workspace = r'c:\ArcpyBook\Ch10'
if arcpy.Exists('randompts.shp'):
arcpy.Delete_management('randompts.shp')
randompts = arcpy.CreateRandomPoints_management(arcpy.env.workspace,'randompts.shp',"",rectangle_geometry)
arcpy.RefreshActiveView()
return randompts

第11章 异常识别和错误处理

  • 默认的Python错误消息
  • 添加Python异常处理结构(try/except/else)
  • 使用GetMessages()函数获取工具消息
  • 根据严重性级别筛选工具消息
  • 测试和响应特定的错误消息
  1. 默认的Python错误消息11.2-235

import arcpy
arcpy.env.workspace = "c:/ArcpyBook/data"
arcpy.Buffer_analysis("Streams.shp","Streams_Buff.shp")

  1. 添加Python异常处理结构(try/except/else)11.3-236

import arcpy
try:
arcpy.env.workspace = "c:/ArcpyBook/data"
arcpy.Buffer_analysis("Streams.shp","Streams_Buff.shp")
except:
print("Error")

  1. 使用GetMessages()函数获取工具消息11.4-238

import arcpy
try:
arcpy.env.workspace = "c:/ArcpyBook/data"
arcpy.Buffer_analysis("Streams.shp","Streams_Buff.shp")
except:
print(arcpy.GetMessages())

  1. 根据严重性级别筛选工具消息11.5-240

import arcpy
try:
arcpy.env.workspace = "c:/ArcpyBook/data"
arcpy.Buffer_analysis("Streams.shp","Streams_Buff.shp")
except:
print(arcpy.GetMessages(2))

  1. 测试和响应特定的错误消息116-241

import arcpy
try:
arcpy.env.workspace = "c:/ArcpyBook/data"
arcpy.Buffer_analysis("Streams.shp", "Streams_Buff.shp")
except:
print("Error found in Buffer tool \n")
errCode = arcpy.GetReturnCode(3)
if str(errCode) == "735":
print("Distance value not provided \n")
print("Running the buffer again with a default value \n")
defaultDistance = "100 Feet"
arcpy.Buffer_analysis("Streams.shp", "Streams_Buff", defaultDistance)
print("Buffer complete")

第12章 使用Python实现ArcGIS的高级功能

  • ArcGIS REST API入门
  • 使用Python构建HTTP请求并解析响应
  • 使用ArcGIS REST API和Python获取图层信息
  • 使用ArcGIS REST API和Python导出地图
  • 使用ArcGIS REST API和Python查询地图服务
  • 使用ESRI World Geocoding Service镜像地理编码
  • 使用FieldMap和FieldMappings
  • 使用ValueTable将多值输入到工具中
  1. ArcGIS REST API入门12.2-245

None

  1. 使用Python构建HTTP请求并解析响应12.3-250

import requests
import json

agisurl = "http://server.arcgisonline.com/arcgis/rest/services?f=pjson"
r = requests.get(agisurl)
decoded = json.loads(r.text)
print(decoded)
#print(r.text)

  1. 使用ArcGIS REST API和Python获取图层信息12.4-254

import requests
import json

agisurl = "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/1"
payload = { 'where': 'STATE_FIPS = \'48\' and CNTY_FIPS = \'021\'','returnCountyOnly': 'false',
'returnIdsOnly': 'false', 'returnGeometry': 'false',
'f': 'pjson'}

r = requests.get(agisurl, params=payload)
#r = requests.get(agisurl)
#print(r.text)

decoded = json.loads(r.text)
print("The layer name is: " + decoded['name'])
print("The xmin: " + str(decoded['extent']['xmin']))
print("The xmax: " + str(decoded['extent']['xmax']))
print("The ymin: " + str(decoded['extent']['ymin']))
print("The ymax: " + str(decoded['extent']['xmax']))
print("The fields in this layer: ")
for rslt in decoded['fields']:
print(rslt['name'])

  1. 使用ArcGIS REST API和Python导出地图12.5-257

import requests
import json

agisurl = "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StateCityHighway_USA/MapServer/export"


payload = { 'bbox': '-115.8,30.4,-85.5,50.5','size': '800,600', \
'imageSR': '102004', 'format': 'gif', 'transparent':'false', \
'f': 'pjson'}

r = requests.get(agisurl, params=payload)
print(r.text)

  1. 使用ArcGIS REST API和Python查询地图服务12.6-260

import requests
import json

agisurl = "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/1/query"
payload = { 'where': 'STATE_FIPS = \'48\' and CNTY_FIPS = \'021\'','returnCountyOnly': 'false',
'returnIdsOnly': 'false', 'returnGeometry': 'false', 'outFields':'POP2000,POP2007,BLKGRP',
'f': 'pjson'}


r = requests.get(agisurl, params=payload)
#print(r.text)

decoded = json.loads(r.text)
#print(decoded)


for rslt in decoded['features']:
print("Block Group: " + str(rslt['attributes']['BLKGRP']))
print("Population 2000: " + str(rslt['attributes']['POP2000']))
print("Population 2007: " + str(rslt['attributes']['POP2007']))

  1. 使用ESRI World Geocoding Service镜像地理编码12.7-264

import requests
import json

agisurl = "http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/find"

payload = { 'text': '1202 Sand Wedge, San Antonio, TX, 78258', 'f': 'pjson'}

r = requests.get(agisurl, params=payload)

decoded = json.loads(r.text)
print("The geocoded address: " + decoded['locations'][0]['name'])
print("The longitude: " + str(decoded['locations'][0]['feature']['geometry']['x']))
print("The latitude: " + str(decoded['locations'][0]['feature']['geometry']['y']))
print("The geocode score: " + str(decoded['locations'][0]['feature']['attributes']['Score']))
print("The address type: " + decoded['locations'][0]['feature']['attributes']['Addr_Type'])

  1. 使用FieldMap和FieldMappings12.8-266

import arcpy

try:
# Local variables

arcpy.env.workspace = r"c:\ArcpyBook\data"
outFeatureClass = r"c:\ArcpyBook\data\AllTracts.shp"

# Create a fieldmappings adding the three new fields
fieldmappings = arcpy.FieldMappings()
fldmap_STFIPS = arcpy.FieldMap()
fldmap_COFIPS = arcpy.FieldMap()
fldmap_TRACT = arcpy.FieldMap()

# List all feature classes that start with 'County' and type Polygon
fclss = arcpy.ListFeatureClasses("County*", "Polygon")

# Create a value table with the FC to merge
vTab = arcpy.ValueTable()
for fc in fclss:
fieldmappings.addTable(fc)
fldmap_STFIPS.addInputField(fc, "STFID")
fldmap_COFIPS.addInputField(fc, "STFID")
fldmap_TRACT.addInputField(fc, "STFID")
vTab.addRow(fc)

# Set Starting and ending point from the input as well as the name of the output fields

# STFIPS field
for x in range(0, fldmap_STFIPS.inputFieldCount):
fldmap_STFIPS.setStartTextPosition(x, 0)
fldmap_STFIPS.setEndTextPosition(x, 1)

fld_STFIPS = fldmap_STFIPS.outputField
fld_STFIPS.name = "STFIPS"
fldmap_STFIPS.outputField = fld_STFIPS

# COFIPS field
for x in range(0, fldmap_COFIPS.inputFieldCount):
fldmap_COFIPS.setStartTextPosition(x, 2)
fldmap_COFIPS.setEndTextPosition(x, 4)

fld_COFIPS = fldmap_COFIPS.outputField
fld_COFIPS.name = "COFIPS"
fldmap_COFIPS.outputField = fld_COFIPS

# TRACT field
for x in range(0, fldmap_TRACT.inputFieldCount):
fldmap_TRACT.setStartTextPosition(x, 5)
fldmap_TRACT.setEndTextPosition(x, 12)

fld_TRACT = fldmap_TRACT.outputField
fld_TRACT.name = "TRACT"
fldmap_TRACT.outputField = fld_TRACT

# Add fieldmaps into the fieldmappings object
fieldmappings.addFieldMap(fldmap_STFIPS)
fieldmappings.addFieldMap(fldmap_COFIPS)
fieldmappings.addFieldMap(fldmap_TRACT)

# Run the merge tool
arcpy.Merge_management(vTab, outFeatureClass, fieldmappings)

print("Merge completed")

except Exception as e:
print(e.message)

  1. 使用ValueTable将多值输入到工具中12.9-273

import arcpy
try:

arcpy.env.workspace = r'c:\ArcpyBook\data'

vTab = arcpy.ValueTable()

vTab.setRow (0, "5")
vTab.setRow (1, "10")
vTab.setRow (2, "20")

inFeature = 'Hospitals.shp'
outFeature = 'HospitalMBuff.shp'
dist = vTab
bufferUnit = "meters"

arcpy.MultipleRingBuffer_analysis(inFeature,outFeature,dist,bufferUnit, '', 'ALL')
print("Multi-Ring Buffer Complete")
except Exception as e:
print(e.message)

附录A 自动化Python脚本

  • 在命令行中运行Python脚本
  • 使用sys.argv[]捕获命令行的输入
  • 添加Python脚本到批处理文件
  • 在规定的时间运行批处理文件
  1. 在命令行中运行Python脚本A.2-283

None

  1. 使用sys.argv[]捕获命令行的输入A.3-289

import arcpy

arcpy.env.workspace = "C:/ArcpyBook/data/CityOfSanAntonio.gdb"
try:
fieldList = arcpy.ListFields("Burglary")
for fld in fieldList:
print "%s is a type of %s with a length of %i" % (fld.name, fld.type, fld.length)
except Exception as e:
print(e.message)

import arcpy
import sys

wkspace = sys.argv[1]
fc = sys.argv[2]
try:
arcpy.env.workspace = wkspace
fields = arcpy.ListFields(fc)
for fld in fields:
print(fld.name)
except Exception as e:
print(e.message)

  1. 添加Python脚本到批处理文件A.4-290

cd c:\ArcpyBook\Appendix1
python ListFields.py c:\ArcpyBook\data Burglaries_2009.shp

  1. 在规定的时间运行批处理文件A.5-292

None

附录B GIS程序员不可不知的5个Python功能

  • 读取带分隔符的文本文件
  • 发送电子邮件
  • 检索FTP服务中的文件
  • 创建ZIP文件
  • 读取XML文件
  1. 读取带分隔符的文本文件B.2-298

f = open('c:/ArcpyBook/data/N_America.A2007275.txt','r')
for fire in f:
lstValues = fire.split(',')
latitude = float(lstValues[0])
longitude = float(lstValues[1])
confid = int(lstValues[8])
print("The latitude is: " + str(latitude) + " The longitude is: " + str(longitude) + " The confidence value is: " + str(confid))
f.close()

  1. 发送电子邮件B.3-301

import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email import Encoders
import os

gmail_user = "<username>"
gmail_pwd = "<password>"

def mail(to, subject, text, attach):
msg = MIMEMultipart()

msg['From'] = gmail_user
msg['To'] = to
msg['Subject'] = subject

msg.attach(MIMEText(text))

part = MIMEBase('application', 'octet-stream')
part.set_payload(open(attach, 'rb').read())
Encoders.encode_base64(part)
part.add_header('Content-Disposition',
'attachment; filename="%s"' % os.path.basename(attach))
msg.attach(part)

mailServer = smtplib.SMTP("smtp.gmail.com", 587)
mailServer.ehlo()
mailServer.starttls()
mailServer.ehlo()
mailServer.login(gmail_user, gmail_pwd)
mailServer.sendmail(gmail_user, to, msg.as_string())
mailServer.close()

mail("<email to send to>",
"Hello from python!",
"This is an email sent with python",
"bc_pop1996.csv")

  1. 检索FTP服务中的文件B.4-306

import ftplib
import os
import socket

HOST = 'ftp.nifc.gov'
DIRN = '/Incident_Specific_Data/2012 HISTORIC/ROCKY_MTN/Arapaho/GIS/20120629'
FILE = '20120629_0600_Arapaho_PIO_0629_8x11_land.pdf'

try:
f = ftplib.FTP(HOST)
except (socket.error, socket.gaierror), e:
print('ERROR: cannot reach "%s"' % HOST)
print('*** Connected to host "%s"' % HOST)

try:
f.login()
except ftplib.error_perm:
print('ERROR: cannot login anonymously')
f.quit()
print('*** Logged in as "anonymous"')

try:
f.cwd(DIRN)
except ftplib.error_perm:
print('ERROR: cannot CD to "%s"' % DIRN)
f.quit()
print('*** Changed to "%s" folder' % DIRN)

try:
f.retrbinary('RETR %s' % FILE,
open(FILE, 'wb').write)
except ftplib.error_perm:
print('ERROR: cannot read file "%s"' % FILE)
os.unlink(FILE)
else:
print('*** Downloaded "%s" to CWD' % FILE)
f.quit()

  1. 创建ZIP文件B.5-310

import os
import zipfile

#create the zip file
zfile = zipfile.ZipFile("shapefiles2.zip", "w", zipfile.ZIP_STORED)
files = os.listdir("c:/ArcpyBook/data")

for f in files:
if f.endswith("shp") or f.endswith("dbf") or f.endswith(".shx"):
zfile.write("C:/ArcpyBook/data/" + f)

#list files in the archive
for f in zfile.namelist():
print("Added %s" % f)

zfile.close()

import os
import zipfile

#create the zip file
zfile = zipfile.ZipFile("shapefiles2.zip", "w", zipfile.ZIP_DEFLATED)
files = os.listdir("c:/ArcpyBook/data")

for f in files:
if f.endswith("shp") or f.endswith("dbf") or f.endswith(".shx"):
zfile.write("C:/ArcpyBook/data/" + f)

#list files in the archive
for f in zfile.namelist():
print("Added %s" % f)

zfile.close()

  1. 读取XML文件B.6-313

from xml.dom import minidom

xmldoc = minidom.parse("WitchFireResidenceDestroyed.xml")

childNodes = xmldoc.childNodes

eList = childNodes[0].getElementsByTagName("fire")
for e in eList:
if e.hasAttribute("address"):
print e.getAttribute("address")

箴言:因为这些东西是非常简单的。不要抱怨自己学不会,那是因为你没有足够用心。



举报

相关推荐

0 条评论