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

日期

2013/04/04

作者

托马斯堡

联系

thomas.bonfort@gmail.com

作者

斯蒂芬梅尔

联系

stephan@meissl.name

状态

采用

版本

MAPCACHE 1.2

1。概述

此RFC建议在mapcache中添加时间维度支持。这允许mapcache应答WMT和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例

假设为切片集指定的数据库包含时间戳 2011-12-152012-01-15 ,以及 2012-02-15 也就是说,在12月15日、1月和2月捕获了三个不同的数据集。

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

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

  • 地图缓存创建一个请求,该请求将请求垂直合并具有两个不同 TIME 尺寸标注

  • 属性的切片在缓存中查询 2012-01-15 尺寸。如果在缓存中找不到磁贴,则将向给定的元数据传递 TIME=2012-01-15 URL参数。

  • 属性的切片在缓存中查询 2012-02-15 尺寸标注。

  • mapcache组装了这两个图块

  • MapCach向客户端返回单个切片,该切片由两个切片的垂直组合组成,因此包含 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>

备注

由地图缓存管理员提供正确解释Start_Time和End_Time值的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中的相应操作可能会变得计算繁重,因为将有大量图像块需要获取、解码并合并到最终生成的图像中。虽然这可能会导致在地图缓存服务器上拒绝服务,但为了提供正确的结果,这被认为是正常行为。服务器管理员可以通过添加 ORDER BY ttt LIMIT xxx 子句,代价是响应将丢失条目。

5.错误ID

6。投票历史

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