Arcpy开发基础知识点总结

标签: Arcgis 分类: Gis 创建时间:2019-08-19 01:07:32 更新时间:2024-11-15 10:49:42

前言

作为一个GIS开放人员,不会ArcGIS,真的不是一件好事。还记得谁说过,能学会ArcGIS中20%的知识,你就是一个大牛了。可见ArcGIS包含的内容之丰富,工具之广泛,原理之深入,是其他GIS软件都没法比拟的,也正是如此,ArcGIS才能常年占据地理信息系统市场的半壁江山,甚至可以说是80%的市场。因为项目需要,也是为了拓展自己的知识面,现在开始学习用Arcpy。“ArcPy 是一个 Python 站点包,可提供以实用高效的方式通过 Python 执行地理数据分析、数据转换、数据管理和地图自动化。该包提供了丰富纯正的 Python 体验,具有代码完成功能(输入关键字和点即可获得该关键字所支持的属性和方法的弹出列表;从中选择一个属性或方法即可将其插入),并针对每个函数、模块和类提供了参考文档。使用 ArcPy 的另一个主要原因是,Python 是一种通用的编程语言。它是一种支持动态输入的解释型语言,适用于交互操作以及一次性程序(即脚本)快速原型制作,同时具有编写大型应用程序的强大功能。用 ArcPy 编写的 ArcGIS 应用程序的优势在于,可以使用由多个不同领域的 GIS 专业人员和程序员组成的众多 Python 小群体开发的附加模块。”

ArcPy3.0

启动方式(显示的所有路径假定按计算机(所有用户)安装 ArcGIS Pro。 如果已为当前用户安装 ArcGIS Pro,请将 %LOCALAPPDATA% 替换为 %PROGRAMFILES%。):
(1) 要从命令提示符运行 Python 脚本(可在 .py 文件后添加参数),请键入以下内容:

1
"C:\Program Files\ArcGIS\Pro\bin\Python\Scripts\propy" myscript.py

或者是将 “C:\Program Files\ArcGIS\Pro\bin\Python\Scripts” 加入Path环境变量,这样就可以直接从命令行中,使用 propy 命令来启用 ArcPy 了。

(2) 从批处理文件启动
要从 .bat 文件运行 Python 脚本,请在 propy 上使用 call:

1
2
3
@echo Run my Python script
call "%PROGRAMFILES%\ArcGIS\Pro\bin\Python\Scripts\propy" myscript.py
@echo Finished

(3) 作为计划任务启动
如果作为计划任务运行 Python 脚本,程序或脚本应为 C:\PROGRA~1\ArcGIS\Pro\bin\Python\Scripts\propy,并且参数应包含 Python 脚本的完整路径。

参考文章:
1.ArcGIS Pro 中的 Python ArcPy的官方教程
2.如何使用ArcPy

Conda

ArcGIS Pro 提供大量 Python 软件包的访问权限。 为了支持 Python 包,ArcGIS Pro 包含一个包管理系统,名为 conda。 ArcGIS Pro 将 conda 与包管理器页面相集成。 也可以从命令提示符访问 conda。启动 ArcGIS Pro Python 3 conda 环境:

1
"%PROGRAMFILES%\ArcGIS\Pro\bin\Python\Scripts\proenv"

可从命令提示符使用 conda 命令访问 conda 功能。 活动 Python 环境通过在当前目录之前的提示符中以括号括起指示。 使用 Python 命令提示符快捷方式可打开使用 ArcGIS Pro 的活动 conda 环境初始化的命令提示符窗口。

参考文章:
1.包管理器

问题

(1) The current user does not have write permissions to the target environment

1.Arcpy调用地理处理工具

脚本中所有可用的地理处理工具都被定义为arcpy对象的动态函数(dynamic function)。脚本中执行的每一个工具都必须遵循特定的语法规则,首先需要定义工具名称,之后紧跟一个下划线(_)和工具箱的别名。在我们的示例中,Buffer工具位于Analysis Tools工具箱中,该工具箱的别名为analysis。使用别名是因为可能有多个工具的名称相同。使用<toolname>_<toolbox_alias>的语句规则实现对每个工具的唯一引用。

2.自动生成线段编号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#!/usr/bin/python
# -*- coding: UTF-8 -*-

import os
import arcpy

shp = r'D:\zlc\hdxs\geodata\pipeline_20190821_0859.shp'
numberList=[]
## 获取全部的线段编号
with arcpy.da.SearchCursor(shp,["Number"]) as cursor:
for uniquerow in cursor:
if uniquerow[0] not in numberList:
numberList.append(uniquerow[0])
## 遍历每个线段编号,然后为子线段进行编号
for number in numberList:
query='"Number"='+str(number)
count=0
cursor_line = arcpy.UpdateCursor(shp, query, "", "SubNumber", "Number")
for row_line in cursor_line:
count+=1
row_line.setValue("SubNumber", count)
cursor_line.updateRow(row_line)
del row_line
del cursor_line
print 'done'
参考文章:
1.利用arcpy实现自动编号 (主要就是参考的这里的代码)
2.【Arcpy】shp的读取与创建
3.da.UpdateCursor
4.UpdateCursor (da.UpdateCursor和UpdateCursor是不一样的)
5.python自动给数字前面补0的方法

3.字段自动编号

在字段计算器中,选择Python脚本,选择“Show codeblock 显示代码块”,代码块的内容如下:

1
2
3
4
5
6
7
8
9
10
rec=0
def autoIncrement():
global rec
pStart=1
pInterval=1
if(rec==0):
rec=pStart
else:
rec=rec+pInterval
return rec

在下面的等于框中写上 autoIncrement(), 调用该函数

(2) 自动补零
除了编号之外,还需要进行自动补零,然后加上前缀,可以使用VB代码如下,这里就是将字段编号为:“前缀0001”、“前缀0002”、“前缀0003”…..

1
"前缀" & left("0000",4-len( [FID]+1)) & ([FID] +1)

使用python语言就是

1
2
3
4
'前缀' + (str(autoIncrement())).zfill(5)

## 如果是某一个字段比如test3自段
' !test3!' + (str(autoIncrement())).zfill(5)

4.浮点数精度问题

使用arcgis字段计算器的时候,想要将获取到的地理坐标面积,进行四舍五入并保留两位小数存入MJ属性中,借助于python的round函数,可以进行四舍五入计算,但是总是会出现问题,就是 125396883.690809 进行四舍五入之后,只剩下了 12539600,就算是乘以100,最后还是零而不是883,使用了多种方法都不行。这个 MJ 属性,是浮点型数据,相对应的mj0之所以有两位小数,是因为它是文本型字段,这样就比较清晰了,是因为浮点型精度问题。

【解决方法】
浮点型数字有效位数只有7位,需要换成双精度的数据。因为是位的有效位,所以就可以看出为什么后面的883等数字。

参考文章:
1.计算字段示例 使用pythong脚本的介绍
2.为何float有效位数只有7位? 因为单精度数的尾数用23位存储,加上默认的小数点前的1位1,2^(23+1) = 16777216。因为 10^7 < 16777216 < 10^8,所以说单精度浮点数的有效位数是7位
3.为何float有效位数为7位?

5.将GDB转为geojson

esri的json和标准的geojson还是有区别的。我尝试了很多的方法,做了很多的工作,真是浪费了很多的时间。其实关键的就是 FeaturesToJSON 方法,传入一个geojson参数。还有ChatGPT提供的 arcpy.FeaturesToJSON_conversion 这个方法,其实并不是非常的正确,这个转为json,还需要自己去解析。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import arcpy
import os

# 设置工作空间
arcpy.env.workspace = r"C:\work\TRGF.gdb"
out_folder = r"C:\work\output"

# 获取 GDB 中所有的要素类
feature_classes = arcpy.ListFeatureClasses()

for fc in feature_classes:
# 构造输出文件名
out_json_file = os.path.join(out_folder, fc + ".geojson")
print(f"Exporting {fc} to {out_json_file}")

# 导出要素类为 GeoJSON 格式
arcpy.conversion.FeaturesToJSON(fc, out_json_file, geoJSON=True)

根据ChatGPT的说法,arcpy.FeaturesToJSON_conversion 和 arcpy.conversion.FeaturesToJSON 都是用来将 ArcGIS 地理数据转换为 JSON 或 GeoJSON 格式的函数,主要区别在于前者是一个函数,而后者是一个工具。

参考文章:
1.arcmap批量导出shp和geojson数据(包含自定义文件名)
2.python json loads遇到中文的情况分析。 json.loads(dataJsonStr, encoding=”GB2312”)
3.Features To JSON (Conversion) Converts features to Esri JSON or GeoJSON format. The fields, geometry, and spatial reference of features will be converted to their corresponding JSON representation and written to a file with a .json or .geojson extension.
4.Outputting geoJSON with arcpy.FeaturesToJSON_conversion tool of ArcGIS Pro?
5.ArcPy 函数概述
6.通过 Python 使用工具

6.将geojson转为shape

代码其实很简单,就是需要一个正确的geojson格式的文件,才可以。

1
2
3
4
5
6
7
8
9
10
import arcpy

# GeoJSON 文件路径
json_file = r"data/output.geojson"
# Shapefile 文件输出路径
shp_file = r"data/output.shp"

# 使用 json_to_features 工具将 GeoJSON 转为 Shapefile
arcpy.JSONToFeatures_conversion(json_file, shp_file)

问题

(1) Polygons and MultiPolygons should follow the right-hand rule
在geojson验证网站 上,验证一段geojson代码,出现了上面的问题:Polygons and MultiPolygons should follow the right-hand rule。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
{
"type": "Polygon",
"coordinates": [
[
[
120.252240976,
30.397120046
],
[
120.25224893,
30.397123254
],
[
120.252257108,
30.397126008
],
[
120.252265474,
30.397128297
],
[
120.252273995,
30.397130111
],
[
120.252282632,
30.397131442
],
[
120.252240976,
30.397120046
]

]
]
}

【解决方案】
这个问题解决方法,就是换了一个网站进行geojson的验证,使用geojson 进行验证就好了,这个网站不挑是不是右手坐标系。

参考文章:
1.Solution: Polygons and MultiPolygons should follow the right-hand rule
2.mapstertech/mapster-right-hand-rule-fixer
3.Polygons and MultiPolygons should follow the right-hand rule My old GeoJSON worked with Google Maps, Leaflet, OpenLayers, Mapbox, Bing Maps, etc. however failed geojsonlint.com validate.I have to use another website to validate: http://geojson.io。这里也提供了python解决方案:This can be fixed very easily in Python using geojson-rewind.
4.如何检测Geojson,Geojson下载
5.Polygons and MultiPolygons should follow the right-hand rule
6.GeoJSON三分钟入门教程 这里也有对各个类型的图形进行了说明和示例。

(2) arcgisscripting.ExecuteError: ERROR 999999: Something unexpected caused the tool to fail
这个问题主要出在坐标不正确的情况下,比如面的坐标系不同。

【解决方案】
按照标准的geojson进行生成,面的第一个点和最后一个点要重叠。

参考文章:
1.GeoJSON格式规范说明
2.geojson 格式说明(格式详解) 这里有不同的类型的示例
3.Error: ERROR 999999 Something unexpected caused the tool to fail This error is displayed when the existing enterprise geodatabase connection in the ArcGIS Pro project has the versioning type set to Traditional instead of Branch in the Geodatabase Connection Properties window.
小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。