自定义pygeoapi:插件

在本节中,我们将解释pygeoapi如何为数据提供者、格式化程序和进程提供插件架构。

插件开发需要了解如何用Python编程以及Python的包/模块系统。

概述

pygeoapi提供了一个健壮的插件架构,使开发人员能够扩展功能。事实上,pygeoapi本身实现了许多格式、数据提供者和过程功能作为插件。

pygeoapi体系结构支持以下子系统:

  • 数据提供者

  • 输出格式

  • 过程

核心pygeoapi插件注册表位于 pygeoapi.plugin.PLUGINS .

每个插件类型实现其相关基类作为API协定:

  • 数据提供程序: pygeoapi.provider.base

  • 输出格式: pygeoapi.formatter.base

  • 过程: pygeoapi.process.base

待处理

将插件链接到API文档

插件可以在pygeoapi代码库之外开发,并通过pygeoapi配置动态加载。这使您的自定义插件可以在pygeoapi之外运行,以便于软件更新的维护。

注解

建议将pygeoapi插件存储在pygeoapi之外,以便于软件更新和包管理

示例:自定义pygeoapi矢量数据提供程序

让我们考虑向量数据提供程序插件的步骤(源代码位于: 供应商

Python代码

下面的模板提供了一个最小的示例(让我们调用该文件 mycoolvectordata.py

from pygeoapi.provider.base import BaseProvider

class MyCoolVectorDataProvider(BaseProvider):
    """My cool vector data provider"""

    def __init__(self, provider_def):
        """Inherit from parent class"""

        BaseProvider.__init__(self, provider_def)

    def get_fields(self):

        # open dat file and return fields and their datatypes
        return {
            'field1': 'string',
            'field2': 'string'
        }

    def query(self,startindex=0, limit=10, resulttype='results',
              bbox=[], datetime_=None, properties=[], sortby=[],
              select_properties=[], skip_geometry=False):

        # open data file (self.data) and process, return
        return {
            'type': 'FeatureCollection',
            'features': [{
                'type': 'Feature',
                'id': '371',
                'geometry': {
                    'type': 'Point',
                    'coordinates': [ -75, 45 ]
                },
                'properties': {
                    'stn_id': '35',
                    'datetime': '2001-10-30T14:24:55Z',
                    'value': '89.9'
                }
            }]
        }

为了简洁起见,上面的代码将始终返回数据集的单个特性。实际上,插件开发人员将连接到具有运行查询和返回相关结果集的功能的数据源,并实现 get 相应的方法。只要插件实现了它的基本提供者的API契约,所有其他功能都留给提供者实现。

每个基类记录实现所需的函数、参数和返回类型。

连接到pygeoapi

以下方法是将插件连接到pygeoapi的选项:

选项1 :在核心pygeoapi中更新:

  • 复制 mycoolvectordata.py 进入之内 pygeoapi/provider

  • 在中更新插件注册表 pygeoapi/plugin.py:PLUGINS['provider'] 使用插件的短名称(比如 MyCoolVectorData )以及通往课堂的虚线(即。 pygeoapi.provider.mycoolvectordata.MyCoolVectorDataProvider

  • 在数据集提供程序配置中指定,如下所示:

providers:
    - type: feature
      name: MyCoolVectorData
      data: /path/to/file
      id_field: stn_id

方案2 :在pygeoapi外部实现并添加到配置(推荐)

  • 创建 mycoolvectordata.py 模块(参见 Cookiecutter 例如)

  • 将Python包安装到系统中 (python setup.py install ). 此时,您的新包应该在 PYTHONPATH 你的pygeoapi安装

  • 在数据集提供程序配置中指定,如下所示:

providers:
    - type: feature
      name: mycooldatapackage.mycoolvectordata.MyCoolVectorDataProvider
      data: /path/to/file
      id_field: stn_id

BEGIN

示例:自定义pygeoapi栅格数据提供程序

让我们考虑栅格数据提供程序插件的步骤(源代码位于: 供应商

Python代码

下面的模板提供了一个最小的示例(让我们调用该文件 mycoolrasterdata.py

from pygeoapi.provider.base import BaseProvider

class MyCoolRasterDataProvider(BaseProvider):
    """My cool raster data provider"""

    def __init__(self, provider_def):
        """Inherit from parent class"""

        BaseProvider.__init__(self, provider_def)
        self.num_bands = 4
        self.axes = ['Lat', 'Long']

    def get_coverage_domainset(self):
        # return a CIS JSON DomainSet

    def get_coverage_rangetype(self):
        # return a CIS JSON RangeType

    def query(self, bands=[], subsets={}, format_='json'):
        # process bands and subsets parameters
        # query/extract coverage data
        if format_ == 'json':
            # return a CoverageJSON representation
            return {'type': 'Coverage', ...}  # trimmed for brevity
        else:
            # return default (likely binary) representation
            return bytes(112)

为了简洁起见,上面的代码对于元数据总是JSON,对于数据总是二进制或CoverageJSON。实际上,插件开发人员将连接到一个具有运行查询和返回相关结果集功能的数据源,只要插件实现其基本提供者的API契约,所有其他功能都留给提供者实现。

每个基类记录实现所需的函数、参数和返回类型。

END

示例:自定义pygeoapi格式化程序

Python代码

下面的模板提供了一个最小的示例(让我们调用该文件 mycooljsonformat.py

import json
from pygeoapi.formatter.base import BaseFormatter

class MyCoolJSONFormatter(BaseFormatter):
    """My cool JSON formatter"""

    def __init__(self, formatter_def):
        """Inherit from parent class"""

        BaseFormatter.__init__(self, {'name': 'cooljson', 'geom': None})
        self.mimetype = 'text/json; subtype:mycooljson'

    def write(self, options={}, data=None):
        """custom writer"""

        out_data {'rows': []}

        for feature in data['features']:
            out_data.append(feature['properties'])

        return out_data

正在处理插件

处理插件遵循OGC API-进程开发。鉴于规范正在开发中,在 pygeoapi/process/hello_world.py 暂时提供了一个合适的例子。