arcpy基础篇(3)-处理空间数据

ArcPy的数据访问模块arcpy.da,可以控制会话、编辑操作、游标、表或要素类与NumPy数组之间相互转换的函数以及对版本化和复本工作流的支持。

1.使用游标访问数据

游标是一个数据库术语,它主要用于访问表格中的每一行记录或者向表中插入新的记录。在ArcGIS中,游标通常用于从表中或向表中按按行读取或写入新几何结构。
游标有三种:搜索、插入和更新。这三种游标的功能如下:
a)搜索游标可用于检索行
b)插入游标可用于向表或要素类中插入行。
c)更新游标可用于根据位置更新和删除行。

每种类型的游标均由arcpy.da模块中对应的ArcPy函数(SearchCursor、InsertCusor和UpdateCursor)创建。所有这三种游标可以在表、表格试图、要素类或要素图层上进行操作。全部三个游标函数均可创建用于访问每一行记录的游标对象。游标对象支持的方法取决于游标的类型。
在这里插入图片描述
游标只能向前导航。如果脚本需要多轮次遍历数据,应用程序必须重新执行游标函数。搜索或更新游标可以通过for循环或者while循环,并使用游标的next方法遍历每一行记录。如果要在游标上使用next方法来检索行数为n的表中所有记录,脚本必须反复调用next方法n次。当游标遍历到最后一行是,再次调用next函数会出现一个StopIteration异常。
这三种游标都有两个必选参数:输入表和字段名称列表。搜索和更新游标还有几个可选参数。调用三个游标的语法如下:

arcpy.da.InsertCursor(in_table, field_name)
arcpy.da.SearchCursor(in_table, field_name, {where_clause}, {spatial_reference}, {explore_to_points})
arcpy.da.UpdateCursor(in_table, field_name, {where_clause}, {spatial_reference}, {explore_to_points})

通过游标搜索得到的记录将会输出到一个字段列表中,列表内字段的顺序和函数中field_name参数内字段值的顺序一致。
下面是一个使用搜索游标遍历表中所有记录,并输出指定字段的例子。

import arcpy
fc = "C:/Data/study.gdb/roads"
cursor = arcpy.da.SearchCursor(fc, {"STREETNAME"})
for row in cursor:
	print "Streetname = {0}".format(row[0])

2.1.with语句

搜索和更新游标还支持with'语句。使用with语句可以保证数据库锁的关闭和释放,并充值迭代。

import arcpy
fc = "C:/Data/study.gdb/roads"
with arcpy.da.SearchCursor(fc, {"STREETNAME"}) as cursor:
	for row in cursor:
		print "Streetname = {0}".format(row[0])

2.2插入对象

使用InsertCursor函数创建一个游标对象,然后使用insertRow函数在新的一行中插入数据。

import arcpy
fc = "C:/Data/study.gdb/roads"
cursor = arcpy.da.InsertCursor(fc, {"STREETNAME"})
cursor.insertRow(["NEW STREET"])

默认情况下,新插入的数据位于表末尾。表中游标没有遍历到的字段会分配为默认值,通常为“null”。

2.3更新对象

更新游标可根据游标的位置更新和删除行。updateRow方法用于对行对象进行更新。
下面的例子中,游标对象通过UpdateCursor函数创建。在for循环中,一个字段(Acres)的值会根据另一个字段(Shape_Area)的值进行更新。

import arcpy
fc = "C:/Data/study.gdb/roads"
cursor = arcpy.da.UpdateCursor(fc, {"ACRES", "SHAPE_AREA"})
for row in cursor:
	row[0] = row[1] / 43560
	cursor.updateRow([row])	

2.4删除对象

deleteRow方法用于删除UpdateCursor当前位置所在的行对象。提取行对象后,可在游标上调用deleteRow方法删除行,代码如下

import arcpy
fc = "C:/Data/study.gdb/roads"
cursor = arcpy.da.UpdateCursor(fc, ["STREETNAME"])
for row in cursor:
	if row[0] == "MAIN ST":
		cursor.deleteRow()

2.5删除排他锁

在这里插入图片描述
使用del语句可以删除游标对象,以便释放该游标对象设置在数据集上的排他锁。
例如:

import arcpy
fc = "C:/Data/study.gdb/roads"
cursor = arcpy.da.UpdateCursor(fc, ["STREETNAME"])
for row in cursor:
	if row[0] == "MAIN ST":
		cursor.deleteRow()
del row 
del cursor

使用with语句可以保证数据锁的关闭和释放。因此使用了with’语句后,就不需要在使用del语句。

3.在Python中使用SQL

在地理处理中,经常需要使用结构化查询语言(SQL)查询数据。ArcMap里的按属性选择功能就需要使用SQL,ArcToolBox里面的很多工具也需要用到SQL。
在Python中使用SearchCursor函数可以执行SQL查询语句。SearchCursor的语法如下:

SearchCursor(in_table, field_name, {where_clause}, {spatial_reference}, {fields}, {explode_to_points})

其中可选参数where_clause表示一个SQL表达式。查询不同的数据集,where_clause参数中的SQL语句会存在细微差别,但是都遵循SQL的语法规则。
下面是一段使用SQL表达式的代码:

import arcpy
fc = “C:/Data/study.grd/roads”

cursor = arcpy.da.SearchCursor(fc, ["NAME", "CLASSCODE"],  ' "CLASSCODE" = 1 ')
for row in cursor:
	print row[0]
del row
del cursor

3.1AddFieldDelimiters

**SQL的语法是比较繁琐,因为针对不同格式的要素,会有不同的语法。**例如,shapefile和文件地理数据库中要素类的字段分隔符是两个引号(“”),个人地理数据库的字段分隔符是中括号([]),ArcSDE地理数据库中要素类没有分隔符。为了防止混淆并确保分隔符的准确性,可以使用AddFieldDelimiters函数,其语法如下:

AddFieldDelimiters(datssource, field)

该函数可以识别正在使用的数据集类型,然后添加正确的分隔符。

import arcpy
fc = "C:/Data/zipcodes.shp"
fieldname = "CITY"
delimfield = arcpy.AddFieldDelimiters(fc, fieldname)
cursor = arcpy.da.SearchCursor(fc, ["NAME", "CLASSCODE"], delimfield + '' = 'LONGWOOD' ")
for row in cursor:
	print row[0]
def row
del cursor

3.2 Select_analysis

SQL表达式在其他函数中也很常见。很多内置工具也使用SQL语句,例如Select工具。

Select_analysis(in_features, out_feature_class, where_clause)

下面的例子使用了AddFieldDelimiters函数:

import arcpy
infc = "C:/Data/zipcodes.shp"
fieldname = "CITY"
outfc = "C:/Data/zip_select.shp"
delimfield = arcpy.da.AddFieldDlimiters(infc, fieldname)
arcpy.Select_analysis(infc, outfc, delimfield + " = 'LonGWOOD' ")

4.处理表和字段名

在处理不同的数据集时,要确保每个属性表和字段都有一个有效且唯一的名称,特别是在处理地理数据库中创建数据时。

4.1ValidateTableName

ValidateTableName函数可以用来确定某个表明在给定的工作空间中是否有效,函数语法如下:

ValidateTableName(name, {workspace})

函数的参数是一个表名和一个工作空间路径,函数将为该工作返回一个有效的表名。如果表名原本就是有效的,那么函数就会返回原始的表名。如果表名是无效的那么无效的字符都用下划线(__)代替。
例如,下面的代码用于确定在一个名为study的文件地理数据库中,表名all roads是否有效。

import arcpy
tablename = arcpy.ValidateTableName("all roads", "C:/Data/study.gdb")
print tablename

在这个例子中,all_roads作为表名返回。下划线(__)被添加到表名中,因为表名不可以包含空格。

下面的代码使用CopyFeature工具将所有的shapefile从文件夹转移到地理数据库中。首先通过basename属性吧”.shp“文件扩展名从文件名中移除,随后验证文件名,并将shapefile拷贝到地理数据库的要素中。代码如下:

import arcpy
import os
from arcpy import env
env.workspace = "C:/Data"
outworkspace = "C:/Data/test/study.gdb"
fclist = arcpy.ListFeatureClasses()
for shapefile infclist:
	fcname = arcpy.Describe(shapefile).basename
	newfcname = arcpy.ValidateTableName(fcname)
	outfc = os.path.join(outworkspace, newfcname)
	arcpy.CopyFeatures_mangagement(shapefile, outfc)

4.2ValidateFieldName

可以使用ValidateFieldName函数对字段名进行类似的操作。只要在字段名有效的情况下,才能添加字段。因为需要先验证字段名是否有效,否则脚本可能会报错。函数语法如下:

ValidateFieldName(name, {workspace})

下面的代码将验证新字段名称的有效性,并通过AddField工具将有效字段添加到数据中。所有无效字符都会被下划线代替。

import arcpy
fc = "C:/Data/roads.shp"
fieldname = arcpy.ValidateFieldName("NEW%^")
arcpy.AddField_management(fc, fieldname, "TEXT", "", "", 12)

在这个例子中,字符串”NEW^%“被”NEW_“代替。

4.3CreateUniqueName

CreateUniqueName函数通过在输入名称后追加数字的方式指定工作空间创建唯一名称,该数字会不断增大,直到名称是唯一的为止。该函数仅可以在工作空间内创建唯一的表名,而无法处理字段名。应用该函数代码如下:

import arcpy
from arcpy import env
env.workspace = "C:/Data"
unique_name = arcpy.CreateUniqueName("buffer.shp")
arcpy.Buffer_analysis("roads.shp", unique_name, "100 FEET")

代码第一次运行时,文件buffer,shp不存在,得到的要素名称为buffer.shp,第二次运行时,buffer.shp存在,得到的要素名称为buffer0.shp。

5.解析属性表和字段名

ArcGIS中的地理处理环境经常需要设置成要素或属性表的全限定名。ParseTableName函数可以将数据集中的全限定名称分割为不同的组成部分。该函数的语法如下:

ParseTableName(name, {workspace})

ParseTableName函数返回一个逗号隔开,并含有数据库名、所有者名以及表名的字符串。下面的代码使用ParseTableName函数将一个要素类的全限定名分割开来,并将每个部分存入到列表中:

import arcpy
from arcpy import env
env.workspace = "C:/Data/study.gdb"
fc = "roads"
fullname = arcpy.ParseTableName(fc)
namelist = fullname.split(", ")
databasename = namelist[0]
ownername = namelist[1]
fcname = namelist[2]
print databasename
print ownername
print fcname

与ParseTableName函数类似,ParseFieldName函数可以将表中某个字段的全限定名分割成不同的部分。该函数将返回一个由逗号隔开,并含有数据库名、所有者表名以及字段名的字符串。

6.处理文本文件

Python可以读取文本文件的内容,并提供给ArcGIS使用。使用open函数打开文件,语法如下:

open(name, {mode}, {buffering})

open函数仅有一个必选参数,即文件名,该函数将会返回一个对象。下面的代码从磁盘上打开了一个现有的文件:

f = open("c:/Data/sample.txt")

只使用文件名作为参数只能返回一个只读的文件对象。如果想做其他操作,必须明确指定一张访问模式。最常见的访问模式由如下几种:
在这里插入图片描述
缓存文件参数可以决定是否需要进行缓存。默认情况下不进行缓存,当缓存参数设置为true时,Python使用内存代替磁盘来提高读写速率,对于数据量不大的文件,一般不需要设置缓存参数。
还有几种处理文件的函数分别是write、read、close,其示例如下:

f = open("c:/Data/mytext.txt", "w")
f.write("Geographic Information System")
f.close()

运行上面的代码会创建一个新的文件对象,如果文件已存在就会重写这个已有的文件。write函数用来写入字符串,close函数用来关闭文件并保存文件内容。
读取文件的代码如下:

f = open("C:/Data/mytext.txt")
f.read()

read函数可以读取文件内容,没有设置参数时,默认读取整个文件的内容,也可以通过设置一个值来限定读取字符的个数,例如:

f = open("C:/Data/mytext.txt")
f.read(3)

文件被打开后,读取其中的字符串是单向进行的。当再次使用read函数时,脚本会从上次读取结束的位置继续读取。
可以通过seek函数来设置当前读取文件的位置,从而不需要再重新打开这个文件。例如:

f.seek(0)
f.read(10)

6.1 readline和readlines

使用readline方法,每次读取一行并以字符串形式返回。继续调用readline函数会读取下一行,该函数通用会返回分隔符(\n)。
使用readlines方法可以读取所有行,并以列表的形式返回。

6.2writelines

write和writelines可以创建一个多行的文件。添加新行时,需要使用分隔符(\n)。

f = open("C:/Data/tintext.txt", "w")
f.write("Triangulated\nIrregular\nNode")
f.close()

writelines方法可以用来修改字符串中指定的某一行。

6.3遍历文件

可以通过read或者readlin方法遍历,例如:
``

f = open("C:/Data/mytext.txt")
while True:
	line = f.readline()
	if not line: breadl
	<function>
f.close()

<function>表示对每一个字符进行相关处理.
使用read或readlines方法会占用相当多的内存。此时可以while循环下使用read,也可以使用fileinput模块代替open函数。该模块可以将文件中的内容创建成一个对象,然后就可以使用for循环迭代处理该对象内每一行的内容,例如:

import fileinput
for line in fileinput.input("C:/Data/mytext.txt")
	<function>

下面的脚本首先以read模式打开一个已有的文件,然后write模式中创建了一个新的文件,for循环用来迭代每一行,replace方法调用删除指定的字符串,处理后的结果输出到新的文件中。

input = open("C:/Data/coordinates.txt")
output = open("C:/Data/coordinates_clean.txt","w")
for line in input:
	str = line.replace("ID: ", "")
	output = write(str)
input.close()
output.close()

``

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值