ArcGIS 中的 Apache Arrow

Apache Arrow 是一种在内存中跨平台、跨语言的分栏式开源数据表达,允许您在资源之间有效地传输数据。 大量的大数据工程与 Arrow 连接,其已成为跨语言和平台的读写分栏列文件格式的便捷选项。 有关详细信息,请参阅有关使用案例使用 Apache Arrow 的工程和产品Apache Arrow 文档。

Arrow 中的主要表格数据表达形式为 Arrow 表格。 Arrow 表是二维表格表达形式,其中列是 Arrow 分块数组。 PythonArrow 的界面为 PyArrow。 有关详细信息,请参阅 Apache ArrowPyArrow 库文档。

表和要素数据

您可以使用数据访问 (arcpy.da) 模块中的 TableToArrowTable 函数将表和要素类转换为 Arrow 表。

基于要素类创建 Arrow 表。

import arcpy

infc = r'C:\data\usa.gdb\cities'
arrow_table = arcpy.da.TableToArrowTable(infc)

要将 Arrow 表转换为表或要素类,使用复制行复制要素工具。

基于 Arrow 表创建要素类。

outfc = arcpy.management.CopyFeatures(arrow_table, r'C:\data\usa.gdb\cities_new')

Arrow 表可以用作任何接受表或要素类的地理处理工具的输入,但修改输入的工具除外,如计算字段工具。 尽管地理处理工具可以接受 Arrow 表作为输入,但是输出不会是 Arrow 表,而是表或要素类。

方案

箭头表必须遵循特定模式才可供地理处理工具识别。 该模式由字段名称、其数据类型和随附的元数据组成。 元数据存储为 JSON 编码的对象。

对象 ID 字段的数据类型必须为 PyArrow int64,并具有以下元数据键/值对:

{
    'esri.oid': 'esri.int64'
}

定义包含对象 ID 的字段的示例。

pyarrow.field(
    "OBJECTID",
    pyarrow.int64(),
    metadata={'esri.oid': 'esri.int64'}
)

几何列的数据类型必须为 PyArrow binarystring,具体取决于几何数据的编码。 几何编码在元数据的 esri.encoding 键下指定。 支持以下几何编码:

  • EsriShape 和熟知二进制 (WKB)(针对 binary 字段)
  • EsriJSON、GeoJSON 和熟知文本 (WKT)(针对 string 字段)

此外,几何坐标系必须使用 esri.sr_wkt 键进行指定,其值必须为 WKT 坐标系字符串。 如果坐标系未知,将字符串留空。 元数据的常规结构如下:

{
    'esri.encoding': '<EsriShape, EsriJSON, GeoJSON, WKB, or WKT>',
    'esri.sr_wkt': '<a WKT coordinate system string>'
}

使用空间参考 GCS 北美 1983 定义包含 Esri Shape 二进制几何的几何字段的示例。

f = pyarrow.field(
    "SHAPE",
    pyarrow.binary(),
    metadata={
        'esri.encoding': 'EsriShape',
        'esri.sr_wkt': '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]];-400 -400 1000000000;-100000 10000;'         \
        '-100000 10000;8.98315284119521E-09;0.001;0.001;IsHighPrecision'
    }
)

当使用 Arrow 表作为需要要素类或要素图层的地理处理工具的输入时,几何列必须正确指定,地理处理工具才能识别几何数据。 如果未正确指定,该工具将失败。 在几何类型为 EsriShape 这一特殊情况中,可以忽略 esri.encoding 键。 尽管支持不同的几何格式,但是为了实现无损几何传输和最佳性能,建议使用 EsriShape。 对象 ID 字段为可选字段。 由于无法在 Arrow 表中保证列值的唯一性,因此当在地理处理工具中使用表时,新 ID 将覆盖任何现有对象 ID 字段值。 如果 Arrow 表中没有对象 ID 字段,则将在地理处理期间自动生成对象 ID 字段。 要检查 Arrow 表的当前模式,使用表的 schema 属性。

可以使用模式知识汇集与地理处理工具兼容的箭头表,或者根据需要从外部源调整现有数据以用于地理处理工具。

从头开始创建 Arrow 表,然后将其转换为地理数据库表。

import arcpy
import pyarrow as pa

# Get spatial reference
sr = arcpy.SpatialReference(3857)  #WGS 1984 Web Mercator (auxiliary sphere)

# Specify fields for schema
fields = [

    pa.field("SHAPE", pa.string(), metadata={'esri.encoding': 'WKT', 'esri.sr_wkt': sr.exportToString()}),
    pa.field('NAME', pa.string()),
    pa.field('STATE', pa.string()),
    pa.field('POP2010', pa.int32()),
]
# Specify data (smallest and largest major US city)
arrays = [

    pa.array([
        'POINT (-8238770.1834999993 4969744.1656000018)', 
        'POINT (-8078649.3640999999 5506675.5481000021)',
    ]),
    pa.array(['New York City', 'Montpelier']),
    pa.array(['NY', 'VT']),
    pa.array([8175133,  7855]),
]

# Create Arrow table from data and schema
patable = pa.Table.from_arrays(
    arrays=arrays,
    schema=pa.schema(fields)
)

# Convert Arrow table to geodatabase table
cities = arcpy.management.CopyRows(
    patable, r'C:\data\usa.gdb\smallest_largest_city')

类型转换

使用 TableToArrowTable 函数将表或要素类转换为 Arrow 表时,创建的 Arrow 表列(pyarrow.ChunkedArray 对象)的数据类型由输入表或要素类的字段类型确定。 此外,无法使用 geometry_encoding 参数在输出 Arrow 表的几何列中指定几何编码。

字段类型PyArrow 数据类型PyArrow 元数据

短整型

int16

长整型

int32

大整数

int64

浮点型

float

双精度

double

文本

string

日期

timestamp[ms]

仅日期

date64[ms]

仅时间

time32[ms]

时间戳偏移

string

{b'esri.interop.type': b'esri.timestamp_offset'}

GUID

string

{b'esri.interop.type': b'esri.guid'}

Global ID

string not null

{b'esri.interop.type': b'esri.global_id'}

对象 ID

int64

{b'esri.oid': b'esri.int64'}

Blob

binary

b'esri.interop.type': b'esri.blob'

几何

binarystring

{b'esri.encoding': b'EsriShape', b'WKB', b'EsriJSON', b'GeoJSON', or b'WKT'>, b'esri.sr_wkt: b'<Spatial Reference WKT>'}

不会转换上面没有列出的其他字段类型,并且会将这些类型删除。

注:

在转换为 Arrow 表时,文本字段将修剪为 5,000 个字符。

注:

由于无法在 Arrow 表中保证列值的唯一性,因此将由用户和接收数据库负责确保在全局 ID 字段中存储的值唯一。 使用 preserveGlobalIds 环境设置控制如何在目标数据库中处理全局 ID值。

使用地理处理工具将 Arrow 表转换为表或要素类时,输出表或要素类的字段类型取决于输入 Arrow 表列的数据类型。 对象 ID 字段将自动添加至输出表或要素类(如果尚不存在)。

PyArrow 数据类型PyArrow 元数据字段类型

bool

短整型(小整数)

int8

短整型(小整数)

int16

短整型(小整数)

int32

长整型(整数)

int64

大整数

uint8

短整型(小整数)

uint16

长整型(整数)

uint32

大整数

uint64

双精度

float32

浮点型(单精度)

float64

双精度

string

文本(字符串)

utf8

文本(字符串)

timestamp

日期

date32

仅日期

date64

仅日期

time32

仅时间

time64

仅时间

int64

b'esri.oid': b'esri.int64'

对象 ID

binary

b'esri.interop.type': b'esri.blob'

Blob

binary

{'esri.encoding': <b'EsriShape' or b'WKB'>, b'esri.sr_wkt: b'<Spatial Reference WKT>'}

几何

string

{'esri.encoding': <b'EsriJSON', b'GeoJSON', or b'WKT'>, b'esri.sr_wkt: b'<Spatial Reference WKT>'}

几何

以上未列出的任何 Arrow 数据类型将不会被转换,并将删除。