MS RFC 96:MapCache TileSets中的时间维度支持

日期

2013/04/04

作者

托马斯堡

联系方式

thomas.bonfort@gmail.com

作者

斯蒂芬梅尔

联系方式

stephan@meissl.name

状态

采用

版本

MAPCACHE 1.2

1。概述

此RFC建议在mapcache中添加时间维度支持。这允许mapcache应答WMT和WMS请求,包括时间戳或时间间隔的时间参数。

其中一个令人鼓舞的用例是通过 WMTS 和 WMS 有效地为潜在的大型地球观测数据档案服务。每个传感器或卫星只需配置一层,使用时间参数中的采集时间仍可以选择单次采集:

...&TIME=2010-07-22T10:16:01Z&...
../../_images/mapcache-time-point.png

同样,也可以在给定的时间间隔内查看所有采集:

...&TIME=2010-07/2010-08&...
../../_images/mapcache-time-interval.png

对于服务提供商来说,在配置的源中可用时,能够向缓存中添加新的采集,而无需重新启动Web服务器,这一点也很重要。

2。建议的解决方案

要获得上一段中详细描述的行为,需要对mapcache进行扩展,以支持给定tileset的时间戳概念:

  • 某种类型的数据库用于查询tileset的可用时间戳。此数据库的实际填充不由mapcache管理,只要向源数据添加新的时间戳,就会留给服务器管理员。

  • 给定一个带有指定 TIME=xxx 组件,mapcache必须能够查询所述数据库以提取单个时间戳条目。一旦提取了时间戳,处理过程就是垂直地组装与各个时间戳对应的图块,以便将单个组合图块返回给客户机。

注解

此功能将仅激活并可用于WMS和WMTS请求。其他规范没有规定尺寸的使用。

2.1例

假设为tileset提供的数据库包含时间戳 2011-12-152012-01-152012-02-15 也就是说,在12月15日、1月15日和2月15日捕获的数据集有三种。

对于包含时间维度的请求 TIME=2012 ,以下是完成的步骤:

  • 在数据库中查询跨越的时间戳 2012-01-012012-12-31 . 数据库返回两个有效的时间戳 2012-01-152012-02-15

  • mapcache创建一个请求,请求将tileset与两个不同的 TIME 维度联系在一起。

  • mapcache使用 2012-01-15 的维度。如果在缓存中找不到磁贴,则<source>将呈现给定的元磁贴 TIME=2012-01-15 URL参数。

  • mapcache使用 2012-02-15 的维度。

  • mapcache组装了这两个图块

  • mapcache将单个tile返回给客户机,由两个tile的垂直组合组成,因此包含 2012 时间序列。

2.2存储和检索时间戳条目

虽然可以在mapcache.xml配置文件中提供tileset的可用时间戳,但对于定期添加数据集的动态情况,这是不实际的,因为它需要重新启动服务器。

初始实现将在给定的时间间隔内查询SQLite数据库中的可用时间戳。将来可能会添加额外的数据库后端,代码是用传统的mapcache结构继承编写的,这种继承允许将来的扩展性。

为了保持通用性,所提供的sqlite数据库的架构没有强制执行,由mapcache管理员决定:

  • 提供用于给定tileset的sqlite文件的路径

  • 提供应该运行的sqlite查询,以便在给定的时间间隔内获得各个时间戳。在绑定了一个或多个 :tileset:start_timestamp:end_timestamp 给定当前请求的值。

这里提供了一个配置条目示例:

<timedimension type="sqlite" default="2010">
  <dbfile>/path/to/mapcache-time.sqlite</dbfile>
  <query>
    select
      strftime('%Y-%m-%dT%H:%M:%SZ',start_time)||'/'||strftime('%Y-%m-%dT%H:%M:%SZ',end_time)
    from
      time
    where
      source_id=:tileset
      and
      start_time&gt;=datetime(:start_timestamp,'unixepoch')
      and
      end_time&lt;=datetime(:end_timestamp,'unixepoch')
    order by
      end_time
  </query>
</timedimension>

注解

由mapcache管理员提供一个正确解释开始时间和结束时间值的sqlite查询, and 返回文本形式的时间戳,在传入 TIME=xxx getmap请求中的url参数。

2.3解释时间格式

mapcache将接受具有以下两种格式之一的时间维度的请求:

  • 格式为 time=<timestamp>,例如 time=2012-01-01

  • 格式为: time=<timestamp_start>/<timestamp_end>,例如 time=2012-01-01/2012-12-31

<timestamp>的格式符合ISO 8601:2000“扩展”格式:最多14位数字,指定世纪、年、月、日、时、分和秒,并使用非数字字符分隔每一段:

ccyy-mm-ddThh:mm:ssZ

<timestamp>可以缩写为低分辨率,mapcache将了解以下格式的时间戳:

  • %y-%m-%dt%h:%m:%sz(最佳分辨率)

  • %y-%m-%dt%h:%mz(给定分钟的所有时间戳)

  • %y-%m-%dt%hz(给定小时的所有时间戳)

  • %y-%m-%d(给定日期的所有时间戳)

  • %y-%m(给定月份的所有时间戳)

  • %Y(给定年份的所有时间戳)

警告

ISO8601:2000允许时间分辨率降至毫秒,即 ccyy-mm-ddThh:mm:ss.sssZ . 目前MapCache不支持这些功能。

警告

ISO8601:2000允许将时区指定为时间戳的最后一个字母。mapcache不支持这种情况,它希望时间戳使用UTC(后缀z,zulu)

警告

OGC WMS规范允许指定时间戳或间隔的列表。目前MapCache不支持这些功能。

警告

OGC WMS规范允许在时间间隔结束时添加分辨率,例如 TIME=2012-01-01/2012-02-01/P1D . 它被mapcache忽略,因为它在当前设置中没有任何意义。

将使用strptime添加一个新函数,该函数将根据请求URL中提供的时间维度计算时间间隔。

总而言之,下面是mapcache的有效时间戳的完整列表:

  • 2012

  • 2012-01

  • 2012-01-01

  • 2012-01-01T12Z

  • 2012年1月1日t12:01z

  • 2012年1月1日12:01:01Z

下面是一个有效时间URL参数的示例列表,其中时间戳也可以按间隔使用(分辨率不 need 要匹配,尽管建议这样做),例如:

  • 时间=2012

  • 时间=2012-01-01

  • 时间=2012-01-01T12Z

  • 时间=2012/2013

  • 时间=2012-01-01T12Z/2012-01-02T12Z

  • 时间=2012/2013-01-02T12Z(不推荐)

警告

OGC WMTS规范不允许为时间维度指定间隔。但是,mapcache将解释其kvp接口中的间隔,但REST接口不支持这些间隔(因为存在不明确的“/”)。

2.4处理给定时间戳的不完整tileset

尽管与此RFC没有严格的关系,但mapcache中的时间维度支持将根据时间戳支持跨越不同范围的tileset。如果tile set设置为<readonly>,则给定时间戳的缓存中丢失的tile不会导致错误或从<source>请求,但会被视为“空”。

为了说明这一点,卫星运行对应于一个特定的时间(戳间隔),并且跨越地球上的一个有限区域。不需要在本次运行所跨越的范围之外生成切片,但是仍然可以请求在给定(更大)时间间隔内合成所有卫星运行的马赛克。

三。实施细节

3.1概述

将添加表示时间数据库的结构,并由特定于sqlite的实现进行子类化。

typedef enum {
  MAPCACHE_TIMEDIMENSION_ASSEMBLY_STACK,
  MAPCACHE_TIMEDIMENSION_ASSEMBLY_ANIMATE /* for future use */
} mapcache_timedimension_assembly_type;

typedef enum {
  MAPCACHE_TIMEDIMENSION_SOURCE_SQLITE
  /* for future use */
} mapcache_timedimension_source_type;

apr_array_header_t* mapcache_timedimension_get_entries_for_value(
  mapcache_context *ctx,
  mapcache_timedimension *timedimension,
  mapcache_tileset *tileset,
  const char *value
);

struct mapcache_timedimension {
  mapcache_timedimension_assembly_type assembly_type; /* for future use */
  void (*configuration_parse_xml)(
    mapcache_context *context,
    mapcache_timedimension *dim,
    ezxml_t node);
  apr_array_header_t* (*get_entries_for_interval)(
    mapcache_context *ctx,
    mapcache_timedimension *dim,
    mapcache_tileset *tileset,
    time_t start,
    time_t end);
  apr_array_header_t* (*get_all_entries)(
    mapcache_context *ctx,
    mapcache_timedimension *dim,
    mapcache_tileset *tileset);
  char *default_value;
  char *key;
};

struct mapcache_timedimension_sqlite {
  mapcache_timedimension timedimension;
  char *dbfile;
  char *query;
};

结构提供两个公共函数,一个用于获取所有有效值(以便构造功能文档和演示界面),另一个用于返回给定间隔的有效时间戳。

3.2受影响的文件

  • mapcache.h

  • 配置xml.c(解析器)

  • dimension.c(sqlite时间戳提取)

  • service_demo.c(向demo界面添加有效的时间戳)

  • service_wms.c,service_wmts.c(URL参数解析,时间戳数据库查询)

  • tileset.c(克隆和创建函数)

  • mapcache_seed.c(播种时的时间戳规范)

3.3向后兼容性问题

不需要,新功能

4。性能影响

当在请求URL中提供与数据库中的大量时间条目相对应的时间范围时,mapcache中的相应操作可能会变得计算量大,因为将有许多图像块来获取、解码和合并到最终生成的图像中。虽然这可能会导致在mapcache服务器上拒绝服务,但为了提供正确的结果,它被认为是正常的行为。服务器管理员可以通过添加 ORDER BY ttt LIMIT xxx 在它们的sqlite查询中使用子句,以丢失条目的响应为代价。

5.错误ID

6。投票历史

托马斯布、米克斯、汤克、杰夫姆、丹尼尔、史蒂文、奥利维埃、史蒂文和佩林。