分享

搜罗全网!ArcGIS二次开发Python(arcpy)指南(六):从坐标系到空间参考再到投影

 GIS荟 2021-10-27

前言:正确的坐标系是开展一切工作的前提,我们从坐标系到空间参考类、工厂代码,再到各种投影方法,为你详解 ArcPy 有关坐标系的一切(大部分)...

1.从坐标系到空间参考类

1.1什么是坐标系

坐标系分为地理坐标系和投影坐标系。

地理坐标系 (GCS) 使用三维球面来定义地球上的位置,基于模拟真实地球的球体或旋转椭球体;投影坐标系在二维平面中进行定义,基于地理坐标系。

1.2什么是空间参考

ArcGIS 空间参考包括以下几个方面的设置:

  • 坐标系

  • 存储坐标时使用的坐标精度(通常称为坐标分辨率)

  • 处理容差(如拓扑容差)

  • 数据集覆盖的空间或地图范围(通常称为空间域)

所以说坐标系是空间参考的子集,也是我们最常用于描述数据坐标系和相关容差精度的单位。

1.3空间参考类

空间参考的每一部分都具有多个属性,特别是坐标系,它定义了哪些地图投影选项用于定义水平坐标,比如基准面、投影的方位角、投影的东(北)偏移量等。

而如此多的信息不适合使用字符串来表示,所以就有了空间参考类(英文:SpatialReference),实际上这是一个包含多个属性的 Python 对象。用户不仅可以自己创建一个空间参考类,也可以通过描述数据集访问到空间参考类。

Note:总结一下,坐标系是空间参考的子集,空间参考类是 arcpy 中用于描述空间参考各种属性的 Python 对象。

2.空间参考类的访问和创建

该小节的示例代码见 ../Chapter6/code1_spatialReference.py

2.1访问现有空间参考类

对于 shp 格式的矢量数据来说,判断有没有坐标系直接看有没有 .prj 后缀的文件即可;栅格数据的话需要在 ArcGIS 中打开查看源数据(查看头文件)才能知道。

只有存在坐标系(投影系)的矢量数据或者栅格数据集才能正确的访问空间参考类。

在 arcpy 中通过描述数据集 Describe.spatialReference 可以访问数据的空间参考类:

# -*- coding:utf-8 -*-import arcpyimport osarcpy.env.overwriteOutput = Truearcpy.env.workspace = os.path.abspath("../SHP")lyr = "../SHP/Boroughs.shp"lyr_no_prj = "../SHP/Boroughs_no_prj.shp"raster_lyr = "../Raster/N31E107.tif"sr = arcpy.Describe(lyr).spatialReference # 2263sr_raster = arcpy.Describe(raster_lyr).spatialReference # 4326

sr 和 sr_raster 分别指向返回的空间参考类对象。

2.2创建空间参考类

可以使用 SpatialReference 类直接创建空间参考类,有三种创建方法:

第一种(推荐):

使用工厂代码 WKID(Well-Konwn ID) 创建,也叫 factory code,是一个编号系统,用于索引各种地理坐标系和投影坐标系。

投影坐标和地理坐标都有一个唯一标识码,相当于是身份证。这套标识码身份证在不同的组织机构有不同的名字,比如 EPSG、SRID、WKID,所幸的是对不同参考系的标识码是一致的,所以 3857 不管在那套系统中都表示墨卡托椭球投影。

new_create_sr = arcpy.SpatialReference(3857)

第二种(推荐):

使用现有的投影文件。

prj_file = "../SHP/Boroughs.prj"new_create_sr1 = arcpy.SpatialReference(prj_file)

第三种:

使用投影的名称。

(不推荐使用名称,容易出错,正确名字查找求证麻烦)

new_create_sr2 = arcpy.SpatialReference("Hawaii Albers Equal Area Conic")
Note:用于访问数据空间参考类的方法是 Describe.spatialReference,而创建空间参考类的方法是SpatialReference(首字母大写)。

关于如何查找 WKID:

在投影的下方有详细信息,其中就有 WKID。

平时工作常用CGCS2000 3 Degree GK Zone 35 坐标系,俗称中国2000大地坐标系,其WKID码为4523。

或者查询以下文件或网站:

WKID 查询文件

  • https://desktop./zh-cn/arcmap/10.3/analyze/python/pdf/geographic_coordinate_systems.pdf

  • https://desktop./zh-cn/arcmap/10.3/analyze/python/pdf/projected_coordinate_systems.pdf

EPSG 查询网站(推荐)

  • http:///

2.3值得使用的空间参考类的属性

空间参考类的属性非常多,这里只保留在工作流中使用较多的属性。

一般情况下使用的较多的属性有三个:可以分别获取到工厂代码、参考系名称、坐标系类型(地理坐标系还是投影坐标系)。

print sr_no_prj.nameprint sr_raster.factoryCodeprint sr_raster.nameprint sr_raster.typeprint new_create_sr.factoryCodeprint new_create_sr.nameprint new_create_sr.type

结果输出:

Unknown4326GCS_WGS_1984Geographic3857WGS_1984_Web_Mercator_Auxiliary_SphereProjected

name 属性可用于判断数据有否有坐标系,没有的话会输出 Unknown(最基本的功能还是输出坐标系的名称);

factoryCode 属性用于获取当前参考系的工厂代码(WKID);

type 属性可以用于判断数据时地理坐标系还是投影坐标系。

空间参考类的完整属性和方法:

  • https://desktop./zh-cn/arcmap/10.3/analyze/arcpy-classes/spatialreference.htm

该小节的全部示例代码见 ../Chapter6/code1_spatialReference.py

3. 定义投影、重投影

shapefile 格式是没有坐标系的,Ersi 公司在制定标准的时候是通过添加一个后缀文件 .prj 来实现的,这样在程序读取文件的时候就可以读取 .prj 文件中的信息来确定矢量文件的具体坐标系。

当然这是从侧面解决 shapefile 没有参考系信息的问题,同时这也是 shapefile 格式饱受诟病的原因之一,各种额外的文件。

这里不讨论格式的好坏,shapefile 现在依然是使用最广泛的空间矢量交换格式,就算不喜欢也得无奈接受。

简单来说,直接看有没有 .prj 就可以知道 shp 文件是否需要定义投影(有的可能存在 .prj 文件,但是坐标系错误,所以也需要重新定义正确的坐标系)。

3.1 定义投影

对于不知道坐标系或者坐标系错误的数据我们需要指定正确的坐标系,这一步就叫做定义投影,定义投影不会改变几何。

arcpy 中有专门的定义投影工具,并且该工具同时支持栅格数据和矢量数据

语法:

arcpy.DefineProjection_management(in_dataset=None, coor_system=None)

in_dataset:要定义投影的数据集或要素类;

coor_system:空间参考类、 .prj 文件或者坐标系的字符串表达形式(包括工厂代码)。

由于坐标系支持多种输入方法,所以有多种不同的定义投影写法。代码可见于文件:../Chapter6/code2_DefineProj.py

# -*- coding:utf-8 -*-import arcpyimport osarcpy.env.overwriteOutput = Truearcpy.env.workspace = os.path.abspath("../SHP")lyr = "../SHP/Boroughs.shp"lyr_no_prj = "../SHP/Boroughs_no_prj.shp"# 方法1sr = arcpy.SpatialReference(2263)arcpy.DefineProjection_management(lyr_no_prj, sr)# 方法2arcpy.DefineProjection_management(lyr_no_prj, 2263)# 方法3prj_file = "../SHP/Boroughs.prj"arcpy.DefineProjection_management(lyr_no_prj, prj_file)# 方法4sr_strings = arcpy.SpatialReference(2263).exportToString()arcpy.DefineProjection_management(lyr_no_prj, sr_strings)# 方法5new_sr = arcpy.CreateSpatialReference_management(2263)arcpy.DefineProjection_management(lyr_no_prj, new_sr)

方法1:

使用空间参考类。

方法2:

直接使用工厂代码。

方法3:

使用 .prj 后缀文件。

方法4:

不推荐。

使用空间参考的字符串表示形式。

方法5:

不推荐,目前和坐标系相关的方法已经够用了,不必了解这个。

使用 CreateSpatialReference_management 方法。

3.2 重投影

将数据从一种投影变换到另一种投影。针对矢量数据和栅格数据分别有两种投影方法。

投影栅格&语法:

arcpy.ProjectRaster_management(in_raster, out_raster, out_coor_system,)

in_raster:输入栅格数据集;

out_raster:要创建的输出栅格数据集。

out_coor_system:目标坐标系,同样的有多种选择,具体写法参考定义投影小节。

(仅保留了必要参数)

投影矢量&语法:

arcpy.Project_management(in_dataset, out_dataset, out_coor_system,)

in_dataset:要投影的要素类、要素图层或要素数据集;

out_dataset:将要写入结果的输出数据集;

out_coor_system:同上。

(仅保留了必要参数)

3.3总结

不管是定义投影、投影栅格还是投影矢量方法,指定坐标系或者说空间参考都有多种方法,灵活使用。

  • 使用创建的空间参考类对象(创建空间参考类也有多种方法);

  • 使用工厂代码;

  • 使用 .prj 文件;

  • 使用空间参考的字符串表达式;

  • 使用 CreateSpatialReference_management 方法。

投影栅格和投影矢量官方文档:

  • https://desktop./zh-cn/arcmap/10.5/tools/data-management-toolbox/project-raster.htm

  • https://desktop./zh-cn/arcmap/10.5/tools/data-management-toolbox/project.htm

4.创建要素类

在单独创建要素类的时候可以指定坐标系。

语法:

arcpy.CreateFeatureclass_management(out_path, out_name,spatial_reference)

out_path:创建要素类的文件夹或数据库(文件夹和数据库必须已存在);

out_name:要创建的要素类的名称。;

spatial_reference:空间参考类、 .prj 文件、其他要素类文件或者坐标系的字符串表达形式(包括工厂代码)。

(仅保留了必要参数)

代码可见于文件:../Chapter6/code3_Createfc.py

# -*- coding:utf-8 -*-import arcpyimport osarcpy.env.overwriteOutput = Truewk = os.path.abspath("../SHP")arcpy.env.workspace = wklyr = "../SHP/Boroughs.shp"lyr_no_prj = "../SHP/Boroughs_no_prj.shp"cf_m = arcpy.CreateFeatureclass_management# 方法1cf_m(wk, "blank", "Polygon", spatial_reference=2263)# 方法2sr = arcpy.SpatialReference(2263)cf_m(wk, "blank", "Polygon", spatial_reference=sr)# 方法3prj_file = "../SHP/Boroughs.prj"cf_m(wk, "blank", "Polygon", spatial_reference=prj_file)# 方法4sr_strings = arcpy.SpatialReference(2263).exportToString()cf_m(wk, "blank", "Polygon", spatial_reference=sr_strings)# 方法5new_sr = arcpy.CreateSpatialReference_management(2263)cf_m(wk, "blank", "Polygon", spatial_reference=new_sr)# 方法6cf_m(wk, "blank", "Polygon", spatial_reference=lyr)

同定义投影、投影栅格、投影矢量这三种方法一样,空间参考均可以通过多种方式指定。

但是不同的是新增方法6:你可以输入一个要素类对象,将要素类对象的空间参考作为新建要素类的空间参考。

创建要素类官方文档:

  • https://desktop./zh-cn/arcmap/10.3/tools/data-management-toolbox/create-feature-class.htm

5.数据框坐标系

ArcGIS 软件是动态投影的,参考标准是数据框投影。

右击最左边的内容列表中的图层(实际这个应该叫数据框)。

右击“图层”

可以打开数据框属性选项卡,其中坐标系中显示的即为当前地图文档的数据框坐标系。

在 arcpy 中,有专门管理数据框中各项属性的 dataframe 类,从这里我们可以获得数据框的空间参考类对象。

# -*- coding:utf-8 -*-import arcpymxd = arcpy.mapping.MapDocument(r"C:\Project\Project.mxd")df = arcpy.mapping.ListDataFrames(mxd)[0]sr = df.spatialReference

6.结束语

看完本章节,你可以知道:

  1. 坐标系与空间参考以及空间参考类的关系;

  2. 使用工厂代码、prj 文件、名称创建空间参考;

  3. 定义投影、投影栅格、投影矢量三种方法在指定空间参考的多种方式;

  4. 创建要素类方法中的用于指定空间参考的方法除上面的几种方法外,还可以直接输入要素类,从而获得输入要素类的空间参考;

  5. 获取、修改数据框的空间参考。

使用版本:

  • Windows 10

  • PyCharm 2021.2.3

  • ArcGIS 10.3

  • Python 2.7.8

源代码、教学文档离线小册子下载:

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多